+
Issues
+ {loading &&
Loading...
}
+ {error &&
{error.message}
}
+ {issues && issues.length === 0 &&
No issues yet.
}
+ {issues && issues.length > 0 && (
+
+ {issues.map((issue) => (
+
+
+
+
{issue.title}
+ {issue.description && (
+
+ {issue.description}
+
+ )}
+
+
+
+ {issue.priority}
+
+
+
+
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/ui/src/pages/Projects.tsx b/ui/src/pages/Projects.tsx
new file mode 100644
index 00000000..a94350a6
--- /dev/null
+++ b/ui/src/pages/Projects.tsx
@@ -0,0 +1,35 @@
+import { useCallback } from "react";
+import { projectsApi } from "../api/projects";
+import { useApi } from "../hooks/useApi";
+import { formatDate } from "../lib/utils";
+
+export function Projects() {
+ const fetcher = useCallback(() => projectsApi.list(), []);
+ const { data: projects, loading, error } = useApi(fetcher);
+
+ return (
+
+
Projects
+ {loading &&
Loading...
}
+ {error &&
{error.message}
}
+ {projects && projects.length === 0 &&
No projects yet.
}
+ {projects && projects.length > 0 && (
+
+ {projects.map((project) => (
+
+
+
+
{project.name}
+ {project.description && (
+
{project.description}
+ )}
+
+
{formatDate(project.createdAt)}
+
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
new file mode 100644
index 00000000..9c2b135f
--- /dev/null
+++ b/ui/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "target": "ES2023",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "jsx": "react-jsx",
+ "strict": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true
+ },
+ "include": ["src"]
+}
diff --git a/ui/vite.config.ts b/ui/vite.config.ts
new file mode 100644
index 00000000..fa143a56
--- /dev/null
+++ b/ui/vite.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import tailwindcss from "@tailwindcss/vite";
+
+export default defineConfig({
+ plugins: [react(), tailwindcss()],
+ server: {
+ port: 5173,
+ proxy: {
+ "/api": "http://localhost:3100",
+ },
+ },
+});
diff --git a/ui/vitest.config.ts b/ui/vitest.config.ts
new file mode 100644
index 00000000..9f6250a3
--- /dev/null
+++ b/ui/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vitest/config";
+
+export default defineConfig({
+ test: {
+ environment: "jsdom",
+ },
+});