summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-11-28 14:13:46 +0900
committerjoonhoekim <26rote@gmail.com>2025-11-28 14:13:46 +0900
commit24e0b8c83f7d68156e5a63ba85a541c04036f00b (patch)
treedeac3a6385b959ced9abed7de134938a609cd68f /app
parent9cda8482660a87fd98c9ee43f507d75ff75b4e23 (diff)
(김준회) dolce: API 추가건 대응 처리(상세도면 및 파일 삭제 기능-Standby 상태)
Diffstat (limited to 'app')
-rw-r--r--app/[lng]/partners/(partners)/document-list-ship/dolce-upload-page-v2.tsx120
-rw-r--r--app/[lng]/partners/(partners)/document-list-ship/page.tsx5
2 files changed, 108 insertions, 17 deletions
diff --git a/app/[lng]/partners/(partners)/document-list-ship/dolce-upload-page-v2.tsx b/app/[lng]/partners/(partners)/document-list-ship/dolce-upload-page-v2.tsx
index f7ddfde6..555b921c 100644
--- a/app/[lng]/partners/(partners)/document-list-ship/dolce-upload-page-v2.tsx
+++ b/app/[lng]/partners/(partners)/document-list-ship/dolce-upload-page-v2.tsx
@@ -15,6 +15,12 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
import { InfoIcon, RefreshCw, Search, Upload, Plus, Loader2 } from "lucide-react";
import { toast } from "sonner";
import { useTranslation } from "@/i18n/client";
@@ -27,6 +33,7 @@ import {
fetchVendorProjects,
fetchDetailDwgReceiptList,
fetchFileInfoList,
+ deleteFileInfo,
} from "@/lib/dolce/actions";
import { DrawingListTableV2 } from "@/lib/dolce/table/drawing-list-table-v2";
import { drawingListColumns } from "@/lib/dolce/table/drawing-list-columns";
@@ -39,6 +46,16 @@ import { B4BulkUploadDialogV3 } from "@/lib/dolce/dialogs/b4-bulk-upload-dialog-
// import { B4BulkUploadDialog } from "@/lib/dolce/dialogs/b4-bulk-upload-dialog";
import { AddAndModifyDetailDrawingDialog } from "@/lib/dolce/dialogs/add-and-modify-detail-drawing-dialog";
import { UploadFilesToDetailDialog } from "@/lib/dolce/dialogs/upload-files-to-detail-dialog";
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "@/components/ui/alert-dialog";
interface DolceUploadPageV2Props {
searchParams: { [key: string]: string | string[] | undefined };
@@ -89,6 +106,10 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
const [dialogMode, setDialogMode] = useState<"add" | "edit">("add");
const [editingDetail, setEditingDetail] = useState<DetailDwgReceiptItem | null>(null);
const [uploadFilesDialogOpen, setUploadFilesDialogOpen] = useState(false);
+
+ // 파일 삭제 상태
+ const [fileToDelete, setFileToDelete] = useState<FileInfoItem | null>(null);
+ const [isDeletingFile, setIsDeletingFile] = useState(false);
// 초기 데이터 로드
const loadInitialData = useCallback(async () => {
@@ -317,6 +338,33 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
setAddDialogOpen(true);
};
+ // 파일 삭제 클릭 핸들러
+ const handleDeleteFileClick = (file: FileInfoItem) => {
+ setFileToDelete(file);
+ };
+
+ // 파일 삭제 확인 핸들러
+ const handleConfirmDeleteFile = async () => {
+ if (!fileToDelete) return;
+
+ try {
+ setIsDeletingFile(true);
+ await deleteFileInfo({
+ fileId: fileToDelete.FileId,
+ uploadId: fileToDelete.UploadId,
+ });
+
+ toast.success("File deleted successfully");
+ loadFiles();
+ } catch (error) {
+ console.error("파일 삭제 실패:", error);
+ toast.error("Failed to delete file");
+ } finally {
+ setIsDeletingFile(false);
+ setFileToDelete(null);
+ }
+ };
+
// 필터된 도면 목록 (클라이언트 사이드 필터링)
const filteredDrawings = useMemo(() => {
let result = drawings.filter((drawing) => {
@@ -382,7 +430,13 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
(vendorInfo.drawingKind === "B4" && selectedDrawing && 'DrawingMoveGbn' in selectedDrawing && selectedDrawing.DrawingMoveGbn === "도면입수")
);
- const fileColumns = createFileListColumns({ onDownload: handleDownload, lng });
+ const canDeleteFile = selectedDetail?.Status === "Standby";
+
+ const fileColumns = createFileListColumns({
+ onDownload: handleDownload,
+ onDelete: canDeleteFile ? handleDeleteFileClick : undefined,
+ lng
+ });
if (isLoading) {
return (
@@ -575,9 +629,9 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
</Card>
{/* 하단: 상세도면리스트 + 파일리스트 - 항상 렌더링 */}
- <div className="grid grid-cols-1 lg:grid-cols-[60fr_40fr] gap-4 flex-shrink-0 min-h-[45vh]">
+ <div className="grid grid-cols-1 2xl:grid-cols-[60fr_40fr] gap-4 flex-shrink-0 min-h-[45vh]">
{/* 좌측: 상세도면 리스트 */}
- <Card className="flex flex-col min-h-0 h-full lg:h-auto">
+ <Card className="flex flex-col min-h-0 h-full 2xl:h-auto min-w-0">
<CardHeader className="flex-row items-center justify-between py-3 flex-shrink-0">
<CardTitle className="text-base">
{t("detailDialog.detailListTitle")}
@@ -639,7 +693,7 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
</Card>
{/* 우측: 첨부파일 리스트 */}
- <Card className="flex flex-col min-h-0 h-full lg:h-auto">
+ <Card className="flex flex-col min-h-0 h-full 2xl:h-auto min-w-0">
<CardHeader className="flex-row items-center justify-between py-3 flex-shrink-0">
<CardTitle className="text-base">
{t("detailDialog.fileListTitle")}
@@ -659,14 +713,29 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
<RefreshCw className={`h-4 w-4 ${isLoadingFiles ? "animate-spin" : ""}`} />
</Button>
{selectedDetail && canAddDetailDrawing && (
- <Button
- variant="default"
- size="sm"
- onClick={() => setUploadFilesDialogOpen(true)}
- >
- <Upload className="h-4 w-4 mr-2" />
- {t("detailDialog.uploadFilesButton")}
- </Button>
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger asChild>
+ <div className="inline-block">
+ <Button
+ variant="default"
+ size="sm"
+ onClick={() => setUploadFilesDialogOpen(true)}
+ // Status check: only allow upload if status is 'Standby'
+ disabled={selectedDetail.Status !== "Standby"}
+ >
+ <Upload className="h-4 w-4 mr-2" />
+ {t("detailDialog.uploadFilesButton")}
+ </Button>
+ </div>
+ </TooltipTrigger>
+ {selectedDetail.Status !== "Standby" && (
+ <TooltipContent>
+ <p>{t("detailDialog.uploadRestrictedStandby")}</p>
+ </TooltipContent>
+ )}
+ </Tooltip>
+ </TooltipProvider>
)}
</div>
</CardHeader>
@@ -741,6 +810,33 @@ export default function DolceUploadPageV2({ searchParams }: DolceUploadPageV2Pro
lng={lng}
/>
)}
+
+ {/* 파일 삭제 확인 다이얼로그 */}
+ <AlertDialog open={!!fileToDelete} onOpenChange={(open) => !open && setFileToDelete(null)}>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete File</AlertDialogTitle>
+ <AlertDialogDescription>
+ Are you sure you want to delete this file? This action cannot be undone.
+ {fileToDelete && (
+ <div className="mt-2 p-2 bg-muted rounded-md text-sm font-medium">
+ {fileToDelete.FileName}
+ </div>
+ )}
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel disabled={isDeletingFile}>Cancel</AlertDialogCancel>
+ <AlertDialogAction
+ onClick={handleConfirmDeleteFile}
+ disabled={isDeletingFile}
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+ >
+ {isDeletingFile ? "Deleting..." : "Delete"}
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
</div>
);
}
diff --git a/app/[lng]/partners/(partners)/document-list-ship/page.tsx b/app/[lng]/partners/(partners)/document-list-ship/page.tsx
index 9ce7c6c6..46800a77 100644
--- a/app/[lng]/partners/(partners)/document-list-ship/page.tsx
+++ b/app/[lng]/partners/(partners)/document-list-ship/page.tsx
@@ -4,11 +4,6 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
import DolceUploadPageV2 from "./dolce-upload-page-v2";
import { Shell } from "@/components/shell";
-export const metadata = {
- title: "조선 벤더문서 업로드(DOLCE) V2",
- description: "조선 설계문서 업로드 및 관리 - 분할 레이아웃",
-};
-
// ============================================================================
// 로딩 스켈레톤
// ============================================================================