Skip to content

Commit

Permalink
feat: new file
Browse files Browse the repository at this point in the history
  • Loading branch information
yongenaelf committed Sep 1, 2024
1 parent 72d8536 commit 9fc169b
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 1 deletion.
9 changes: 9 additions & 0 deletions components/workspace/file-explorer-top-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import NewFile from "./new-file";

export function FileExplorerTopMenu() {
return (
<div className="flex justify-end">
<NewFile />
</div>
);
}
8 changes: 7 additions & 1 deletion components/workspace/file-explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Link from "next/link";
import { usePathname, useSearchParams } from "next/navigation";
import useSWR, { mutate } from "swr";
import { FileIcon } from "./file-icon";
import { FileExplorerTopMenu } from "./file-explorer-top-menu";

type TOCProps = {
toc: TreeViewElement[];
Expand Down Expand Up @@ -116,7 +117,12 @@ const FileExplorer = () => {

if (!toc) return <p>Loading...</p>;

return <TOC toc={toc} pathname={pathname} />;
return (
<>
<FileExplorerTopMenu />
<TOC toc={toc} pathname={pathname} />
</>
);
};

/**
Expand Down
91 changes: 91 additions & 0 deletions components/workspace/new-file-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";

import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { usePathname } from "next/navigation";
import { db } from "@/data/db";
import { Loader2 } from "lucide-react";
import { useRefreshFileExplorer } from "./file-explorer";

const FormSchema = z.object({
path: z.string(),
});

export function NewFileForm({
onSubmit,
}: {
onSubmit?: (path: string) => void;
}) {
const pathname = usePathname();
const refreshFileExplorer = useRefreshFileExplorer();

const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
path: "",
},
});

async function _onSubmit(data: z.infer<typeof FormSchema>) {
form.clearErrors();
try {
await db.files.add({
path: `${pathname}/${encodeURIComponent(data.path)}`,
contents: "",
});
await refreshFileExplorer();
onSubmit?.(data.path);
} catch (err) {
form.setError("path", { message: String(err) });
}
}

return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(_onSubmit)}
className="w-full space-y-6"
>
<FormField
control={form.control}
name="path"
render={({ field }) => (
<FormItem>
<FormLabel>Path</FormLabel>
<FormControl>
<Input className="w-full" placeholder="file path" {...field} />
</FormControl>
<FormDescription>
This is the path of your new file.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" disabled={form.formState.isSubmitting}>
{form.formState.isSubmitting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Please wait
</>
) : (
"Submit"
)}
</Button>
</form>
</Form>
);
}
37 changes: 37 additions & 0 deletions components/workspace/new-file.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use client";

import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";

import { useState } from "react";
import { FilePlus } from "lucide-react";
import { NewFileForm } from "./new-file-form";

export default function NewFile() {
const [isOpen, setIsOpen] = useState(false);

return (
<Dialog open={isOpen} onOpenChange={(open) => setIsOpen(open)}>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" onClick={() => setIsOpen(true)}>
<FilePlus className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>New File</DialogTitle>
<DialogDescription>
<NewFileForm onSubmit={() => setIsOpen(false)} />
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
);
}

0 comments on commit 9fc169b

Please sign in to comment.