diff --git a/src/hooks/use-projects.ts b/src/hooks/use-projects.ts index 7e2a772..fb60798 100644 --- a/src/hooks/use-projects.ts +++ b/src/hooks/use-projects.ts @@ -52,3 +52,18 @@ export function useDeleteProject() { }, }); } + +export function useImportProject() { + const utils = api.useUtils(); + return api.project.importProject.useMutation({ + onSuccess: (data) => { + invalidateProjectQueries(utils); + toast.success( + `Project imported successfully (${data.foldersCreated} folders, ${data.endpointsCreated} endpoints)`, + ); + }, + onError: (error) => { + toast.error(error.message || "Failed to import project"); + }, + }); +} diff --git a/src/modules/workspace/ui/components/sidebar/dialogs.tsx b/src/modules/workspace/ui/components/sidebar/dialogs.tsx index d38259f..ec88b49 100644 --- a/src/modules/workspace/ui/components/sidebar/dialogs.tsx +++ b/src/modules/workspace/ui/components/sidebar/dialogs.tsx @@ -227,3 +227,89 @@ export function CreateEndpointDialog({ ); } + +export function ImportProjectDialog({ + open, + onOpenChange, + onImport, + isImporting, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; + onImport: (data: unknown) => void; + isImporting: boolean; +}) { + const [jsonContent, setJsonContent] = useState(""); + const [error, setError] = useState(null); + + const handleFileChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + const reader = new FileReader(); + reader.addEventListener("load", (event) => { + const content = event.target?.result as string; + setJsonContent(content); + setError(null); + }); + reader.readAsText(file); + }; + + const handleSubmit = () => { + try { + setError(null); + const parsed = JSON.parse(jsonContent); + onImport(parsed); + } catch { + setError("Invalid JSON format. Please select or paste a valid exported project JSON."); + } + }; + + return ( + + + + Import Project + + +
+
+ + +
+ +
+ +