Skip to content
Open
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
18 changes: 15 additions & 3 deletions app/components/CreateMindMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,31 @@ import CreateMindMapForm from "./CreateMindMapForm";
import Credits from "./Credits";
import RetroGrid from "@/components/ui/retro-grid";
import { useEffect } from "react";
import FileUpload from "./FileUpload";

interface CreateMindMapProps {
fetchMindMap: (topic: string) => void;
setMindMapData: (data: any) => void;
}

const CreateMindMap = ({ fetchMindMap }: CreateMindMapProps) => {
const CreateMindMap = ({
fetchMindMap,
setMindMapData,
}: CreateMindMapProps) => {
return (
<Suspense fallback={<div>Loading...</div>}>
<CreateMindMapContent fetchMindMap={fetchMindMap} />
<CreateMindMapContent
fetchMindMap={fetchMindMap}
setMindMapData={setMindMapData}
/>
</Suspense>
);
};

const CreateMindMapContent = ({ fetchMindMap }: CreateMindMapProps) => {
const CreateMindMapContent = ({
fetchMindMap,
setMindMapData,
}: CreateMindMapProps) => {
const searchParams = useSearchParams();
const error = searchParams.get("error") === "true";

Expand All @@ -45,6 +56,7 @@ const CreateMindMapContent = ({ fetchMindMap }: CreateMindMapProps) => {
transition={{ duration: 0.8, ease: "easeOut" }}
>
<CreateMindMapForm onSubmit={fetchMindMap} />
<FileUpload handleUploadJson={setMindMapData} />
</motion.div>
</div>
<RetroGrid />
Expand Down
23 changes: 23 additions & 0 deletions app/components/FileUpload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// FileUpload.tsx
import React from "react";
import { Input } from "@/components/ui/input";

interface FileUploadProps {
handleUploadJson: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

const FileUpload: React.FC<FileUploadProps> = ({ handleUploadJson }) => {
return (
<div className="mt-4 w-full max-w-sm mx-auto p-4 bg-white rounded-lg">
<label
htmlFor="file-upload"
className="block text-sm font-medium text-gray-700 cursor-pointer"
>
Or import an existing JSON
</label>
<Input id="file-upload" type="file" onChange={handleUploadJson} />
</div>
);
};

export default FileUpload;
18 changes: 15 additions & 3 deletions app/components/MindMapContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,29 @@ import CreateMindMap from "./CreateMindMap";
import { useRouter } from "next/navigation";

export default function MindMapContainer() {
const { data, isLoading, error, fetchMindMap, expandMap } = useMindMapData();
const { data, isLoading, error, fetchMindMap, setMindMapData, expandMap } =
useMindMapData();
const router = useRouter();

if (isLoading) return <LoadingMindMap />;

if (error) {
router.push("/?error=true");
return <CreateMindMap fetchMindMap={fetchMindMap} />;
return (
<CreateMindMap
fetchMindMap={fetchMindMap}
setMindMapData={setMindMapData}
/>
);
}

if (!data) return <CreateMindMap fetchMindMap={fetchMindMap} />;
if (!data)
return (
<CreateMindMap
fetchMindMap={fetchMindMap}
setMindMapData={setMindMapData}
/>
);

return (
<div className="w-full h-full">
Expand Down
20 changes: 19 additions & 1 deletion app/hooks/useMindMapData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { uploadJson } from "@/lib/utils";
import { useState } from "react";
import { toast } from "sonner";
import { MindMapData, Subtopic } from "../lib/schemas";

export function useMindMapData() {
Expand All @@ -27,6 +29,22 @@ export function useMindMapData() {
}
};

const setMindMapData = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) return;

uploadJson(file)
.then((data) => {
setData(data);
setIsLoading(false);
})
.catch((_error) => {
toast.error(
"There was an error uploading your mind map, please try again."
);
});
};

const mergeExpandedData = (
existingData: MindMapData,
expandedData: MindMapData,
Expand Down Expand Up @@ -122,5 +140,5 @@ export function useMindMapData() {
return topic || data.topic;
};

return { data, isLoading, error, fetchMindMap, expandMap };
return { data, isLoading, error, fetchMindMap, setMindMapData, expandMap };
}
19 changes: 17 additions & 2 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { MindMapData, Subtopic, Link } from "@/app/lib/schemas";
import { Link, MindMapData, Subtopic, SubtopicSchema } from "@/app/lib/schemas";
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
import { SubtopicSchema } from "@/app/lib/schemas";

export const cn = (...inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
Expand Down Expand Up @@ -47,6 +46,22 @@ export function downloadJson(data: MindMapData, filename: string) {
URL.revokeObjectURL(url);
}

export async function uploadJson(file: File): Promise<MindMapData> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
try {
const json = JSON.parse(event.target?.result as string);
resolve(json as MindMapData);
} catch (error) {
reject(error);
}
};
reader.onerror = (error) => reject(error);
reader.readAsText(file);
});
}

const isValidUrl = (url: string): boolean => {
try {
new URL(url);
Expand Down
Loading