From 845f606dded5443a582199ad0c9d7c685f18163d Mon Sep 17 00:00:00 2001 From: Oliver Bryan <04oliverbryan@gmail.com> Date: Sat, 13 Dec 2025 22:20:26 +0000 Subject: [PATCH] super basic table --- packages/frontend/package.json | 1 + packages/frontend/src/Index.tsx | 106 ++++++---- .../frontend/src/components/ui/select.tsx | 188 ++++++++++++++++++ packages/frontend/src/components/ui/table.tsx | 114 +++++++++++ 4 files changed, 371 insertions(+), 38 deletions(-) create mode 100644 packages/frontend/src/components/ui/select.tsx create mode 100644 packages/frontend/src/components/ui/table.tsx diff --git a/packages/frontend/package.json b/packages/frontend/package.json index fd5981f..dbad93c 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@issue/shared": "workspace:*", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", "@tauri-apps/api": "^2", diff --git a/packages/frontend/src/Index.tsx b/packages/frontend/src/Index.tsx index 0bfc631..f85bd01 100644 --- a/packages/frontend/src/Index.tsx +++ b/packages/frontend/src/Index.tsx @@ -1,55 +1,85 @@ -import { CloudSync, RefreshCw } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { Button } from "@/components/ui/button"; -import { IssueRecord } from "@issue/shared"; +import type { IssueRecord, ProjectRecord } from "@issue/shared"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; -function Issue({ issue }: { issue: IssueRecord }) { +function IssueRow({ issue }: { issue: IssueRecord }) { return ( -
- [{issue.id}] {issue.title} -
+ + {issue.id} + {issue.title} + {issue.description} + ); } function Index() { + const [projects, setProjects] = useState([]); + const projectsRef = useRef(false); + + useEffect(() => { + if (projectsRef.current) return; + projectsRef.current = true; + + fetch("http://localhost:3000/projects/all") + .then((res) => res.json()) + .then((data: ProjectRecord[]) => { + setProjects(data); + console.log("fetched projects:", data); + }) + .catch((err) => { + console.error("error fetching projects:", err); + }); + }, []); + const [issues, setIssues] = useState([]); + const issuesRef = useRef(false); const serverURL = import.meta.env.SERVER_URL?.trim() || "http://localhost:3000"; - async function getIssues() { - const res = await fetch(`${serverURL}/issues/all`); - const data = await res.json(); - setIssues(data); - } + useEffect(() => { + if (issuesRef.current) return; + issuesRef.current = true; + + fetch(`${serverURL}/issues/all`) + .then((res) => res.json()) + .then((data: IssueRecord[]) => { + setIssues(data); + console.log("fetched issues:", data); + }) + .catch((err) => { + console.error("error fetching issues:", err); + }); + }, []); return ( -
-

Issue Project Manager

- -
- - +
+
+ + All Issues + + + a + a + a + a + + + + {issues.map((issue) => ( + + ))} + +
- - {issues.length > 0 && ( -
-                    {JSON.stringify(issues, null, 2)}
-                
- )}
); } diff --git a/packages/frontend/src/components/ui/select.tsx b/packages/frontend/src/components/ui/select.tsx new file mode 100644 index 0000000..b8aab97 --- /dev/null +++ b/packages/frontend/src/components/ui/select.tsx @@ -0,0 +1,188 @@ +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Select({ + ...props +}: React.ComponentProps) { + return +} + +function SelectGroup({ + ...props +}: React.ComponentProps) { + return +} + +function SelectValue({ + ...props +}: React.ComponentProps) { + return +} + +function SelectTrigger({ + className, + size = "default", + children, + ...props +}: React.ComponentProps & { + size?: "sm" | "default" +}) { + return ( + + {children} + + + + + ) +} + +function SelectContent({ + className, + children, + position = "item-aligned", + align = "center", + ...props +}: React.ComponentProps) { + return ( + + + + + {children} + + + + + ) +} + +function SelectLabel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SelectItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function SelectSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SelectScrollUpButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function SelectScrollDownButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, +} diff --git a/packages/frontend/src/components/ui/table.tsx b/packages/frontend/src/components/ui/table.tsx new file mode 100644 index 0000000..5513a5c --- /dev/null +++ b/packages/frontend/src/components/ui/table.tsx @@ -0,0 +1,114 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Table({ className, ...props }: React.ComponentProps<"table">) { + return ( +
+ + + ) +} + +function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { + return ( + + ) +} + +function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { + return ( + + ) +} + +function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { + return ( + tr]:last:border-b-0", + className + )} + {...props} + /> + ) +} + +function TableRow({ className, ...props }: React.ComponentProps<"tr">) { + return ( + + ) +} + +function TableHead({ className, ...props }: React.ComponentProps<"th">) { + return ( +
[role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> + ) +} + +function TableCell({ className, ...props }: React.ComponentProps<"td">) { + return ( + [role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> + ) +} + +function TableCaption({ + className, + ...props +}: React.ComponentProps<"caption">) { + return ( +
+ ) +} + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +}