diff options
Diffstat (limited to 'components/project/ProjectDashboard.tsx')
| -rw-r--r-- | components/project/ProjectDashboard.tsx | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/components/project/ProjectDashboard.tsx b/components/project/ProjectDashboard.tsx index 5f8afb75..581b7b95 100644 --- a/components/project/ProjectDashboard.tsx +++ b/components/project/ProjectDashboard.tsx @@ -103,7 +103,9 @@ export function ProjectDashboard({ projectId }: ProjectDashboardProps) { // Dialog states const [addMemberOpen, setAddMemberOpen] = useState(false); const [transferOwnershipOpen, setTransferOwnershipOpen] = useState(false); + const [deleteProjectOpen, setDeleteProjectOpen] = useState(false); const [newOwnerId, setNewOwnerId] = useState(''); + const [deleteConfirmText, setDeleteConfirmText] = useState(''); // User selection related states const [availableUsers, setAvailableUsers] = useState<User[]>([]); @@ -256,6 +258,42 @@ export function ProjectDashboard({ projectId }: ProjectDashboardProps) { } }; + // Delete project + const handleDeleteProject = async () => { + if (deleteConfirmText !== 'DELETE') { + toast({ + title: 'Error', + description: 'Please type DELETE to confirm.', + variant: 'destructive', + }); + return; + } + + try { + const response = await fetch(`/api/projects/${projectId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + throw new Error('Failed to delete project'); + } + + toast({ + title: 'Success', + description: 'Project has been deleted.', + }); + + // 프로젝트 목록 페이지로 리다이렉트 + window.location.href = '/evcp/data-room'; + } catch (error) { + toast({ + title: 'Error', + description: 'Failed to delete project.', + variant: 'destructive', + }); + } + }; + const formatBytes = (bytes: number) => { if (bytes === 0) return '0 Bytes'; const k = 1024; @@ -457,7 +495,10 @@ export function ProjectDashboard({ projectId }: ProjectDashboardProps) { Permanently delete project and all files </p> </div> - <Button variant="destructive"> + <Button + variant="destructive" + onClick={() => setDeleteProjectOpen(true)} + > <Trash2 className="h-4 w-4 mr-2" /> Delete Project </Button> @@ -744,6 +785,66 @@ export function ProjectDashboard({ projectId }: ProjectDashboardProps) { </DialogFooter> </DialogContent> </Dialog> + + {/* Delete Project Dialog */} + <Dialog open={deleteProjectOpen} onOpenChange={(open) => { + setDeleteProjectOpen(open); + if (!open) setDeleteConfirmText(''); + }}> + <DialogContent> + <DialogHeader> + <DialogTitle className="text-red-600">Delete Project</DialogTitle> + <DialogDescription> + This action cannot be undone. This will permanently delete the project and all associated files. + </DialogDescription> + </DialogHeader> + + <div className="space-y-4"> + <div className="rounded-lg bg-red-50 border border-red-200 p-4"> + <h4 className="font-semibold text-red-800 mb-2">Warning</h4> + <ul className="text-sm text-red-700 space-y-1 list-disc list-inside"> + <li>All files will be permanently deleted</li> + <li>All project members will lose access</li> + <li>All sharing links will be invalidated</li> + <li>This action cannot be reversed</li> + </ul> + </div> + + <div className="space-y-2"> + <Label htmlFor="delete-confirm"> + Type <span className="font-mono font-bold">DELETE</span> to confirm + </Label> + <Input + id="delete-confirm" + placeholder="DELETE" + value={deleteConfirmText} + onChange={(e) => setDeleteConfirmText(e.target.value)} + className="font-mono" + /> + </div> + </div> + + <DialogFooter> + <Button + variant="outline" + onClick={() => { + setDeleteProjectOpen(false); + setDeleteConfirmText(''); + }} + > + Cancel + </Button> + <Button + variant="destructive" + onClick={handleDeleteProject} + disabled={deleteConfirmText !== 'DELETE'} + > + <Trash2 className="h-4 w-4 mr-2" /> + Delete Project + </Button> + </DialogFooter> + </DialogContent> + </Dialog> </div> ); }
\ No newline at end of file |
