- {task.completed ? (
-
- ) : (
-
- )}
+ {getStatusIcon(task.status)}
{task.title}
@@ -232,9 +326,10 @@ export default function Home() {
-
- {new Date(task.createdAt).toLocaleDateString()}
-
+
+ {getStatusBadge(task.status)}
+ {getPriorityBadge(task.priority)}
+
+
+ {new Date(task.createdAt).toLocaleDateString()}
+
))}
@@ -273,11 +371,7 @@ export default function Home() {
<>
- {viewTask.completed ? (
-
- ) : (
-
- )}
+ {getStatusIcon(viewTask.status)}
{viewTask.title}
@@ -292,25 +386,33 @@ export default function Home() {
{viewTask.description || "No description provided"}
-
+
- Status:
-
- {viewTask.completed ? "Completed" : "Pending"}
-
+
+ Status
+
+ {getStatusBadge(viewTask.status)}
+
+
+ Priority
+
+ {getPriorityBadge(viewTask.priority)}
+
+
+
Created:
{new Date(viewTask.createdAt).toLocaleString()}
+
+ Updated:
+
+ {new Date(viewTask.updatedAt).toLocaleString()}
+
+
diff --git a/frontend/src/components/ui/badge.tsx b/frontend/src/components/ui/badge.tsx
new file mode 100644
index 0000000..e0e2003
--- /dev/null
+++ b/frontend/src/components/ui/badge.tsx
@@ -0,0 +1,41 @@
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const badgeVariants = cva(
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
+ outline: "text-foreground",
+ success:
+ "border-transparent bg-green-500/20 text-green-400 hover:bg-green-500/30",
+ warning:
+ "border-transparent bg-yellow-500/20 text-yellow-400 hover:bg-yellow-500/30",
+ info: "border-transparent bg-blue-500/20 text-blue-400 hover:bg-blue-500/30",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+);
+
+export interface BadgeProps
+ extends React.HTMLAttributes,
+ VariantProps {}
+
+function Badge({ className, variant, ...props }: BadgeProps) {
+ return (
+
+ );
+}
+
+export { Badge, badgeVariants };
diff --git a/frontend/src/components/ui/select.tsx b/frontend/src/components/ui/select.tsx
new file mode 100644
index 0000000..482a1e1
--- /dev/null
+++ b/frontend/src/components/ui/select.tsx
@@ -0,0 +1,160 @@
+"use client";
+
+import * as React from "react";
+import * as SelectPrimitive from "@radix-ui/react-select";
+import { Check, ChevronDown, ChevronUp } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Select = SelectPrimitive.Root;
+
+const SelectGroup = SelectPrimitive.Group;
+
+const SelectValue = SelectPrimitive.Value;
+
+const SelectTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+ span]:line-clamp-1",
+ className
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+
+));
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
+
+const SelectScrollUpButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
+
+const SelectScrollDownButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollDownButton.displayName =
+ SelectPrimitive.ScrollDownButton.displayName;
+
+const SelectContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, position = "popper", ...props }, ref) => (
+
+
+
+
+ {children}
+
+
+
+
+));
+SelectContent.displayName = SelectPrimitive.Content.displayName;
+
+const SelectLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectLabel.displayName = SelectPrimitive.Label.displayName;
+
+const SelectItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+
+ {children}
+
+));
+SelectItem.displayName = SelectPrimitive.Item.displayName;
+
+const SelectSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
+
+export {
+ Select,
+ SelectGroup,
+ SelectValue,
+ SelectTrigger,
+ SelectContent,
+ SelectLabel,
+ SelectItem,
+ SelectSeparator,
+ SelectScrollUpButton,
+ SelectScrollDownButton,
+};
diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts
index 2099193..7b07911 100644
--- a/frontend/src/lib/api.ts
+++ b/frontend/src/lib/api.ts
@@ -2,8 +2,10 @@ export interface Task {
id: number;
title: string;
description: string;
- completed: boolean;
+ status: "pending" | "in-progress" | "completed";
+ priority: "low" | "medium" | "high";
createdAt: string;
+ updatedAt: string;
}
export interface APIResponse {
@@ -34,14 +36,16 @@ export async function getTask(id: number): Promise {
export async function createTask(
title: string,
- description: string
+ description: string,
+ status: string = "pending",
+ priority: string = "medium"
): Promise {
const res = await fetch(`${API_BASE}/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
- body: JSON.stringify({ title, description }),
+ body: JSON.stringify({ title, description, status, priority }),
});
const json: APIResponse = await res.json();
if (!json.success) {