src/views/Pages.tsx
import { useQuery } from "@tanstack/react-query";
import { createNewPage, deletePage, getPages } from "../db/draw";
import { Card, CardContent, CardTitle } from "@/components/ui/card";
import { toast } from "sonner";
import Loader from "@/components/Loader";
import NoData from "./NoData";
import { Button } from "@/components/ui/button";
import dayjs from "dayjs";
import { useNavigate } from "@tanstack/react-router";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Trash2 } from "lucide-react";
import TitleBar from "@/components/TitleBar";
function NewPageOptionDropdown({
createPageFn,
createMermaidPageFn,
}: {
createPageFn: () => void;
createMermaidPageFn: () => void;
}) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="font-semibold">
+ New Page
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={createPageFn}>Plain Page</DropdownMenuItem>
<DropdownMenuItem onClick={createMermaidPageFn}>
Mermaid Syntax Diagram
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
export default function Pages() {
const navigate = useNavigate();
const {
data,
isLoading,
refetch: refetchPages,
} = useQuery({
queryKey: ["pages"],
queryFn: getPages,
refetchOnMount: true,
refetchOnWindowFocus: true,
});
if (data?.error) {
toast(data.error.message);
}
if (isLoading) return <Loader />;
function goToPage(id: string) {
navigate({ to: "/page/$id", params: { id: id } });
}
async function createPage() {
const data = await createNewPage();
if (data.data && data.data[0]?.page_id) {
goToPage(data.data[0].page_id);
toast("Successfully created a new page!");
}
if (data.error) {
toast("An error occured", {
description: `Error: ${data.error.message}`,
});
}
}
async function createMermaidPage() {
navigate({ to: "/mermaid" });
}
async function handlePageDelete(id: string) {
const data = await deletePage(id);
if (data.data === null) {
toast("Successfully deleted the page!");
refetchPages();
}
if (data.error) {
toast("An error occured", {
description: `Error: ${data.error.message}`,
});
}
}
return (
<div className="h-full w-full">
<TitleBar
title="PAGES"
extra={
<NewPageOptionDropdown
createPageFn={createPage}
createMermaidPageFn={createMermaidPage}
/>
}
/>
<div className="flex flex-wrap gap-3 py-1">
{data?.data && data.data.length > 0 ? (
data?.data?.map((page) => (
<Card
key={page.page_id}
className="group w-fit max-w-72 cursor-pointer p-1 px-2 pt-2 max-h-28 h-fit"
>
<div onClick={() => goToPage(page.page_id)}>
<CardContent className="flex w-full flex-col justify-end gap-3 py-2 text-sm">
<CardTitle className="font-virgil line-clamp-1">{page.name}</CardTitle>
<h1 className="font-medium">
Last updated on:{" "}
{dayjs(page.updated_at).format("MMM DD, YYYY")}
</h1>
</CardContent>
</div>
<div className="flex w-full items-end justify-end p-0.5">
<Trash2
className="invisible h-4 w-4 cursor-pointer rounded-lg text-gray-600 transition-all hover:bg-gray-100 hover:text-red-500 group-hover:visible hover:dark:bg-gray-900"
strokeWidth={3}
onClick={() => handlePageDelete(page.page_id)}
/>
</div>
</Card>
))
) : (
<NoData name="Pages" />
)}
</div>
</div>
);
}