Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI #152

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

UI #152

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions ui/components/CardTemplate/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { useIDL } from "@/context/IDL";
import { checkNFT } from "@/helpers";
import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";
import JSZip from "jszip";
import Image from "next/image"
import { FC } from "react";

const CardTemplate: FC<any> = ({ template, indexTemplate }) => {
const { IDL } = useIDL()
const { connection } = useConnection()
const wallet = useAnchorWallet();

const exportProject = async () => {
if (await checkNFT(connection, wallet)) {
const response = await fetch(`https://soda.shuttleapp.rs/get_project_files/${indexTemplate}`, {
method: "POST",
body: JSON.stringify({ idl: IDL })
})
const { files } = await response.json()
const zip = new JSZip();

// Iterate over each file in the response
files.forEach((file: any) => {
const { path, content } = file;

// Create folders and file in memory
const folders = path.split('/');
const fileName = folders.pop();

let folder = zip;
folders.forEach((folderName: any) => {
folder = folder.folder(folderName) as JSZip
});

// Set the content of the file
if (typeof content.String != "undefined") {
folder.file(fileName, content.String);
} else {
folder.file(fileName, content.Vec)
}
});

// Generate the zip file asynchronously
zip.generateAsync({ type: 'blob' }).then(blob => {
// Provide a way for the user to download the zip file
const url = URL.createObjectURL(blob);
// Example: Create a download link and trigger the click event
const downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = `${IDL.name || " "}.zip`;
downloadLink.click();

// Clean up the created URL object
URL.revokeObjectURL(url);
});
} else {
alert("need to be coneected with a wallet with the Soda NFT")
}
}

return (
<div className={` flex flex-col h-96 bg-backg p-5 w-52 rounded-3xl shadow-md shadow-black text-white gap-3 justify-between items-center`}>
<div className=" flex text-sm justify-between w-full">
<p>
{
!template?.price ?
"Free Template"
:
`${template?.price?.toString()} ${template.currency} `
}
</p>
<p>v{template?.version}</p>
</div>
<div className=" flex flex-col w-full items-center justify-around">
< Image className="h-20 w-20" width={5} height={2} src={template.image || "/soda.svg"} alt={template.name} />
<p className=" text-sm">{template.name}</p>
<p className=" text-xs overflow-y-auto h-">{template.description}</p>
</div>
{/* <div className="flex flex-col gap-2 ">
<p className=" text-sm">Brought to you by</p>

<div className="flex bg-[#183a5c] justify-center items-center h-10 w-full py-2 p-4 rounded-3xl">
<Image className="" src={template.icon || ""} alt={template.name} />
</div>
</div> */}
<button
className="text-white bg-[#387847] px-5 rounded-xl h-10"
onClick={exportProject}
>
Export
</button>
</div>
)
}

export default CardTemplate
29 changes: 0 additions & 29 deletions ui/components/ClassicEditor/card/index.tsx

This file was deleted.

214 changes: 89 additions & 125 deletions ui/components/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,141 +1,105 @@
import { FC, Fragment, useEffect, useState } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import {
Bars3Icon,
XMarkIcon
} from '@heroicons/react/24/outline'
import { readTextFile } from "@tauri-apps/api/fs";
import { open } from "@tauri-apps/api/dialog";
import { invoke } from "@tauri-apps/api/tauri";
import { emit, listen } from '@tauri-apps/api/event'
import { FC, useEffect, useState } from 'react'

import Image from 'next/image'
import { useIDL } from '@/context/IDL'
import { ArrowDownTrayIcon, FolderArrowDownIcon, FolderOpenIcon, PencilSquareIcon, PlusIcon } from '@heroicons/react/24/solid';
import { generateProjectFiles, openIDLFile, saveIDLFile, selectTemplateFolder, cleanProject } from "@/helpers";
import { useRouter } from 'next/router';
import { TauriEvent, listen } from '@tauri-apps/api/event';
import { useTemplates } from '@/context/templates';

const Layout: FC<any> = ({ children }) => {
const router = useRouter()
const {templateFolder} = useTemplates();
const { IDL, setIDL } = useIDL()
const openIDL = openIDLFile(setIDL);
const [baseFolder, setBaseFolder] = useState<any>(undefined);
const generateIDL = saveIDLFile(setBaseFolder, IDL.version, IDL.name, IDL.instructions, IDL.accounts, IDL.types, IDL.events, IDL.errors, IDL.metadata);
const newProject = cleanProject(setIDL);
const exportData = generateProjectFiles(IDL.name, setBaseFolder);
const handleTemplateFolder = selectTemplateFolder();

useEffect(() => {
(async () => {
const unlisten = await listen(TauriEvent.MENU, (event) => {
switch (event?.payload
) {
case "new_project":
newProject();
break;
case "open_idl":
openIDL();
break;
case "change_template":
handleTemplateFolder();
break;
case "generate_project":
exportData();
break;
case "generate_idl":
generateIDL();
break;
}
});
return () => {
unlisten();
};
})();
}, []);

function classNames(...classes: any) {
return classes.filter(Boolean).join(' ')
}

const Layout: FC<any> = ({ children, openIDL, newProject, generateIDL, handleTemplateFolder, exportData }) => {
const [sidebarOpen, setSidebarOpen] = useState(false)

const navigation = [
{
name: 'Open IDL file',
href: '#',
event: openIDL
},
{
name: 'New IDL',
href: '#',
event: newProject
},
{
name: 'Save IDL',
href: '#',
event: generateIDL
},
{
name: 'Select a template',
href: '#',
event: handleTemplateFolder
},
{
name: 'Create Project',
href: '#',
event: exportData
},
]

return (
<>
<div className='h-screen'>
<Transition.Root show={sidebarOpen} as={Fragment}>
<Dialog as="div" className="relative z-50" onClose={setSidebarOpen}>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
<div className='h-screen'>
<div className="sticky top-0 z-40 h-20 flex items-center justify-between gap-x-6 bg-backg shadow-sm px-6">
<div className="flex gap-8 justify-center items-center">
{
router.asPath === "/templates" &&
<button
type="button"
className="-m-2.5 p-2.5 text-chok text-sm inline-flex items-center gap-x-1.5 rounded-md border border-border hover:bg-inputs hover:shadow-md hover:shadow-green-custom hover:text-green-custom focus:bg-inputs active:outline-none active:ring active:ring-border"
onClick={() => {
router.push("/")
}}
>
<div className="fixed inset-0 bg-blue" />
</Transition.Child>

<div className="fixed inset-0 flex ">
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<Dialog.Panel className="relative mr-16 flex w-full max-w-xs flex-1">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute left-full top-0 flex w-16 justify-center pt-5">
<button type="button" className="-m-2.5 p-2.5" onClick={() => setSidebarOpen(false)}>
<span className="sr-only">Close sidebar</span>
<XMarkIcon className="h-6 w-6 text-chok" aria-hidden="true" />
</button>
</div>
</Transition.Child>
<div className="flex grow flex-col gap-y-5 overflow-y-auto bg-backg px-6 pb-2">

<div className="flex h-16 shrink-0 items-center">
</div>
<nav className="flex flex-1 flex-col">
<ul role="list" className="flex flex-1 flex-col gap-y-7">
<li>
<ul role="list" className="-mx-2 space-y-1">
{navigation.map((item) => (
<li
key={item.name}
onClick={item?.event}
>
<a
href={item.href}
className={'text-chok hover:text-chok hover:bg-sky group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold'}
>
{item.name}
</a>
</li>
))}
</ul>
</li>
</ul>
</nav>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
<PencilSquareIcon className="h-5oko w-5" aria-hidden="true" />Editor
</button>
}
<button
type="button"
className="-m-2.5 p-2.5 text-chok text-sm inline-flex items-center gap-x-1.5 rounded-md border border-border hover:bg-inputs hover:shadow-md hover:shadow-green-custom hover:text-green-custom focus:bg-inputs active:outline-none active:ring active:ring-border"
onClick={newProject}
>
<PlusIcon className="h-5 w-5" aria-hidden="true" />New
</button>
<input type="file" id="file" onChange={openIDL} className="hidden" />
<label
htmlFor="file"
className="-m-2.5 p-2.5 text-chok text-sm inline-flex items-center gap-x-1.5 rounded-md border border-border hover:bg-inputs hover:shadow-md hover:shadow-green-custom hover:text-green-custom focus:bg-inputs active:outline-none active:ring active:ring-border"
>
<FolderOpenIcon className="h-5 w-5" aria-hidden="true" /> Open
</label>

<div className="sticky top-0 z-40 flex items-center gap-x-6 bg-backg px-4 py-4 shadow-sm sm:px-6">
<button type="button" className="-m-2.5 p-2.5 text-white" onClick={() => setSidebarOpen(true)}>
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
<button
type="button"
className="-m-2.5 p-2.5 text-chok text-sm inline-flex items-center gap-x-1.5 rounded-md border border-border hover:bg-inputs hover:shadow-md hover:shadow-green-custom hover:text-green-custom focus:bg-inputs active:outline-none active:ring active:ring-border"
onClick={generateIDL}
>
<ArrowDownTrayIcon className="h-5 w-5" aria-hidden="true" /> Download IDL
</button>
<button
type="button"
className="-m-2.5 p-2.5 text-chok text-sm inline-flex items-center gap-x-1.5 rounded-md border border-border hover:bg-inputs hover:shadow-md hover:shadow-green-custom hover:text-green-custom focus:bg-inputs active:outline-none active:ring active:ring-border"
onClick={exportData}
>
<FolderArrowDownIcon className="h-5oko w-5" aria-hidden="true" />Export
</button>
</div>

<main className="pb-10 h-full bg-backg">
{children}
</main>
</div>
</div>
</>
<main className=" h-[calc(100%-5rem)] mini-scroll overflow-y-auto bg-backg">
{children}
</main>
</div>
)
}

Expand Down

This file was deleted.

Loading