diff --git a/apps/web/src/pages/TimeEntries.tsx b/apps/web/src/pages/TimeEntries.tsx new file mode 100644 index 0000000..5489a5a --- /dev/null +++ b/apps/web/src/pages/TimeEntries.tsx @@ -0,0 +1,146 @@ +import { useState } from "react" +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query" +import { api } from "../lib/api" +import { z } from "@rmpks/shared" + +export default function TimeEntries() { + const queryClient = useQueryClient() + const [formData, setFormData] = useState({ + description: "", + startTime: "", + endTime: "", + projectId: "" + }) + + const { data: entries, isLoading, isError } = useQuery({ + queryKey: ["time-entries"], + queryFn: () => api.listTimeEntries() + }) + + const createMutation = useMutation({ + mutationFn: (data: z.infer) => api.createTimeEntry(data), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["time-entries"] }) + setFormData({ description: "", startTime: "", endTime: "", projectId: "" }) + } + }) + + const deleteMutation = useMutation({ + mutationFn: (id: string) => api.deleteTimeEntry(id), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["time-entries"] }) + } + }) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + createMutation.mutate({ + description: formData.description, + startTime: new Date(formData.startTime).toISOString(), + endTime: new Date(formData.endTime).toISOString(), + projectId: formData.projectId + } as z.infer) + } + + if (isLoading) return
Loading entries...
+ if (isError) return
Error loading time entries.
+ + return ( +
+
+

Time Tracking

+

Manage your work logs and project hours

+
+ +
+

Log New Entry

+
+
+ + setFormData({ ...formData, description: e.target.value })} + placeholder="What did you work on?" + /> +
+
+ + setFormData({ ...formData, startTime: e.target.value })} + /> +
+
+ + setFormData({ ...formData, endTime: e.target.value })} + /> +
+
+ +
+
+
+ +
+ + + + + + + + + + + {entries?.length === 0 && ( + + + + )} + {entries?.map((entry: any) => ( + + + + + + + ))} + +
DescriptionStartEndActions
No entries found.
{entry.description} + {new Date(entry.startTime).toLocaleString()} + + {new Date(entry.endTime).toLocaleString()} + + +
+
+
+ ) +} \ No newline at end of file