101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { CheckCircle2, Clock, AlertCircle, Calendar } from "lucide-react";
|
|
|
|
interface Task {
|
|
id: number;
|
|
title: string;
|
|
description: string;
|
|
status: string;
|
|
priority: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
interface TaskDetailDialogProps {
|
|
task: Task | null;
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
}
|
|
|
|
const statusConfig: Record<string, { label: string; icon: React.ReactNode; variant: "default" | "secondary" | "destructive" | "outline" }> = {
|
|
pending: { label: "Pending", icon: <Clock className="w-4 h-4" />, variant: "secondary" },
|
|
in_progress: { label: "In Progress", icon: <AlertCircle className="w-4 h-4" />, variant: "default" },
|
|
completed: { label: "Completed", icon: <CheckCircle2 className="w-4 h-4" />, variant: "outline" },
|
|
};
|
|
|
|
const priorityColors: Record<string, string> = {
|
|
low: "bg-green-500/20 text-green-400 border-green-500/30",
|
|
medium: "bg-yellow-500/20 text-yellow-400 border-yellow-500/30",
|
|
high: "bg-red-500/20 text-red-400 border-red-500/30",
|
|
};
|
|
|
|
export function TaskDetailDialog({ task, open, onOpenChange }: TaskDetailDialogProps) {
|
|
if (!task) return null;
|
|
|
|
const status = statusConfig[task.status] || statusConfig.pending;
|
|
const formatDate = (dateString: string) => {
|
|
return new Date(dateString).toLocaleDateString("en-US", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-[500px]">
|
|
<DialogHeader>
|
|
<DialogTitle className="text-xl">{task.title}</DialogTitle>
|
|
<DialogDescription>Task #{task.id}</DialogDescription>
|
|
</DialogHeader>
|
|
<div className="space-y-6 py-4">
|
|
<div className="flex gap-3">
|
|
<Badge variant={status.variant} className="flex items-center gap-1">
|
|
{status.icon}
|
|
{status.label}
|
|
</Badge>
|
|
<Badge className={priorityColors[task.priority] || priorityColors.medium}>
|
|
{task.priority.charAt(0).toUpperCase() + task.priority.slice(1)} Priority
|
|
</Badge>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<h4 className="text-sm font-medium text-muted-foreground">Description</h4>
|
|
<p className="text-sm">
|
|
{task.description || "No description provided."}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="space-y-1">
|
|
<h4 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
|
|
<Calendar className="w-4 h-4" />
|
|
Created
|
|
</h4>
|
|
<p className="text-sm">{formatDate(task.createdAt)}</p>
|
|
</div>
|
|
<div className="space-y-1">
|
|
<h4 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
|
|
<Calendar className="w-4 h-4" />
|
|
Last Updated
|
|
</h4>
|
|
<p className="text-sm">{formatDate(task.updatedAt)}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|