feat: implement Story 1.1 — create and view diagrams
Add diagram/project DB schema, CRUD API, dashboard pages with grid/card/ empty state, create dialog with type selector, editor placeholder, and 26 schema validation tests. Includes code review fixes: soft-delete filter on GET /:id, error handling, keyboard accessibility, type-safe API response types, and error states on pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
"use client";
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Icons } from "@turbostarter/ui-web/icons";
|
||||
import { api } from "~/lib/api/client";
|
||||
|
||||
export default function DiagramEditorPage() {
|
||||
const params = useParams<{ id: string }>();
|
||||
|
||||
const { data, isLoading, isError } = useQuery({
|
||||
queryKey: ["diagram", params.id],
|
||||
queryFn: async () => {
|
||||
const res = await api.diagrams[":id"].$get({ param: { id: params.id } });
|
||||
return await res.json();
|
||||
},
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<Icons.Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-2 p-6">
|
||||
<Icons.AlertTriangle className="h-8 w-8 text-destructive" />
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Failed to load diagram. It may have been deleted or you don't have access.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-4 p-6">
|
||||
<Icons.LayoutDashboard className="h-16 w-16 text-muted-foreground/30" />
|
||||
<div className="text-center">
|
||||
<h1 className="text-xl font-semibold">{data?.data?.title ?? "Diagram"}</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
The diagram editor canvas will be implemented in Epic 2.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
33
apps/web/src/app/[locale]/dashboard/(user)/diagrams/page.tsx
Normal file
33
apps/web/src/app/[locale]/dashboard/(user)/diagrams/page.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Icons } from "@turbostarter/ui-web/icons";
|
||||
import { api } from "~/lib/api/client";
|
||||
import { DiagramGrid } from "~/modules/diagram/components/DiagramGrid";
|
||||
|
||||
export default function DiagramsPage() {
|
||||
const { data, isLoading, isError } = useQuery({
|
||||
queryKey: ["diagrams"],
|
||||
queryFn: async () => {
|
||||
const res = await api.diagrams.$get();
|
||||
return await res.json();
|
||||
},
|
||||
});
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
<div className="flex h-full flex-col items-center justify-center gap-2 p-6">
|
||||
<Icons.AlertTriangle className="h-8 w-8 text-destructive" />
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Failed to load diagrams. Please try again later.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="@container h-full p-6">
|
||||
<DiagramGrid diagrams={data?.data ?? []} isLoading={isLoading} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user