diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-19 07:51:27 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-19 07:51:27 +0000 |
| commit | 9ecdfb23fe3df6a5df86782385002c562dfc1198 (patch) | |
| tree | 4188cb7e6bf2c862d9c86a59d79946bd41217227 /lib/vendor-document-list/plant/upload/components/history-dialog.tsx | |
| parent | b67861fbb424c7ad47ad1538f75e2945bd8890c5 (diff) | |
(대표님) rfq 히스토리, swp 등
Diffstat (limited to 'lib/vendor-document-list/plant/upload/components/history-dialog.tsx')
| -rw-r--r-- | lib/vendor-document-list/plant/upload/components/history-dialog.tsx | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/vendor-document-list/plant/upload/components/history-dialog.tsx b/lib/vendor-document-list/plant/upload/components/history-dialog.tsx new file mode 100644 index 00000000..9c4f160b --- /dev/null +++ b/lib/vendor-document-list/plant/upload/components/history-dialog.tsx @@ -0,0 +1,144 @@ +// lib/vendor-document-list/plant/upload/components/history-dialog.tsx +"use client" + +import * as React from "react" +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { Badge } from "@/components/ui/badge" +import { ScrollArea } from "@/components/ui/scroll-area" +import { + CheckCircle2, + XCircle, + Clock, + FileText, + User, + Calendar, + AlertCircle +} from "lucide-react" +import { StageSubmissionView } from "@/db/schema" +import { formatDateTime } from "@/lib/utils" + +interface HistoryDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + submission: StageSubmissionView +} + +export function HistoryDialog({ + open, + onOpenChange, + submission +}: HistoryDialogProps) { + const history = submission.submissionHistory || [] + + const getStatusIcon = (status: string, reviewStatus?: string) => { + if (reviewStatus === "APPROVED") { + return <CheckCircle2 className="h-4 w-4 text-success" /> + } + if (reviewStatus === "REJECTED") { + return <XCircle className="h-4 w-4 text-destructive" /> + } + if (status === "SUBMITTED") { + return <Clock className="h-4 w-4 text-primary" /> + } + return <AlertCircle className="h-4 w-4 text-muted-foreground" /> + } + + const getStatusBadge = (status: string, reviewStatus?: string) => { + const variant = reviewStatus === "APPROVED" ? "success" : + reviewStatus === "REJECTED" ? "destructive" : + status === "SUBMITTED" ? "default" : "secondary" + + return ( + <Badge variant={variant}> + {reviewStatus || status} + </Badge> + ) + } + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="max-w-3xl max-h-[80vh]"> + <DialogHeader> + <DialogTitle>Submission History</DialogTitle> + <DialogDescription> + View all submission history for this stage + </DialogDescription> + </DialogHeader> + + {/* Document Info */} + <div className="grid gap-2 p-4 bg-muted rounded-lg"> + <div className="flex items-center justify-between"> + <div className="flex items-center gap-2"> + <FileText className="h-4 w-4 text-muted-foreground" /> + <span className="text-sm font-medium">{submission.docNumber}</span> + <span className="text-sm text-muted-foreground"> + - {submission.documentTitle} + </span> + </div> + <Badge variant="outline">{submission.stageName}</Badge> + </div> + </div> + + {/* History Timeline */} + <ScrollArea className="h-[400px] pr-4"> + {history.length === 0 ? ( + <div className="text-center py-8 text-muted-foreground"> + No submission history available + </div> + ) : ( + <div className="space-y-4"> + {history.map((item, index) => ( + <div key={item.submissionId} className="relative"> + {/* Timeline line */} + {index < history.length - 1 && ( + <div className="absolute left-5 top-10 bottom-0 w-0.5 bg-border" /> + )} + + {/* Timeline item */} + <div className="flex gap-4"> + <div className="flex-shrink-0 w-10 h-10 rounded-full bg-background border-2 border-border flex items-center justify-center"> + {getStatusIcon(item.status, item.reviewStatus)} + </div> + + <div className="flex-1 pb-4"> + <div className="flex items-center gap-2 mb-2"> + <span className="font-medium">Revision {item.revisionNumber}</span> + {getStatusBadge(item.status, item.reviewStatus)} + {item.syncStatus && ( + <Badge variant="outline" className="text-xs"> + Sync: {item.syncStatus} + </Badge> + )} + </div> + + <div className="grid gap-1 text-sm text-muted-foreground"> + <div className="flex items-center gap-2"> + <User className="h-3 w-3" /> + <span>{item.submittedBy}</span> + </div> + <div className="flex items-center gap-2"> + <Calendar className="h-3 w-3" /> + <span>{formatDateTime(new Date(item.submittedAt))}</span> + </div> + <div className="flex items-center gap-2"> + <FileText className="h-3 w-3" /> + <span>{item.fileCount} file(s)</span> + </div> + </div> + </div> + </div> + </div> + ))} + </div> + )} + </ScrollArea> + </DialogContent> + </Dialog> + ) +}
\ No newline at end of file |
