2025-12-23 21:13:07 +09:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 작업일지 모달
|
|
|
|
|
*
|
|
|
|
|
* - 헤더: sam-design 작업일지 스타일
|
|
|
|
|
* - 내부 문서: 스크린샷 기준 작업일지 양식
|
2026-01-14 15:39:07 +09:00
|
|
|
* - API 연동 완료 (2025-01-14)
|
2025-12-23 21:13:07 +09:00
|
|
|
*/
|
|
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
import { useState, useEffect } from 'react';
|
|
|
|
|
import { Printer, X, Loader2 } from 'lucide-react';
|
2025-12-23 21:13:07 +09:00
|
|
|
import {
|
|
|
|
|
Dialog,
|
|
|
|
|
DialogContent,
|
|
|
|
|
DialogTitle,
|
|
|
|
|
} from '@/components/ui/dialog';
|
|
|
|
|
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
|
|
|
|
|
import { Button } from '@/components/ui/button';
|
2026-01-05 18:59:04 +09:00
|
|
|
import { printArea } from '@/lib/print-utils';
|
2026-01-14 15:39:07 +09:00
|
|
|
import { getWorkOrderById } from '../WorkOrders/actions';
|
|
|
|
|
import type { WorkOrder, WorkOrderItem } from '../WorkOrders/types';
|
|
|
|
|
import { ITEM_STATUS_LABELS } from '../WorkOrders/types';
|
2025-12-23 21:13:07 +09:00
|
|
|
|
|
|
|
|
interface WorkLogModalProps {
|
|
|
|
|
open: boolean;
|
|
|
|
|
onOpenChange: (open: boolean) => void;
|
2026-01-14 15:39:07 +09:00
|
|
|
workOrderId: string | null;
|
2025-12-23 21:13:07 +09:00
|
|
|
}
|
|
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
// 작업 통계 타입
|
|
|
|
|
interface WorkStats {
|
|
|
|
|
orderQty: number;
|
|
|
|
|
completedQty: number;
|
|
|
|
|
inProgressQty: number;
|
|
|
|
|
waitingQty: number;
|
|
|
|
|
progress: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 품목 데이터에서 작업 통계 계산
|
|
|
|
|
function calculateWorkStats(items: WorkOrderItem[]): WorkStats {
|
|
|
|
|
const orderQty = items.length;
|
|
|
|
|
const completedQty = items.filter(i => i.status === 'completed').length;
|
|
|
|
|
const inProgressQty = items.filter(i => i.status === 'in_progress').length;
|
|
|
|
|
const waitingQty = items.filter(i => i.status === 'waiting').length;
|
|
|
|
|
const progress = orderQty > 0 ? Math.round((completedQty / orderQty) * 100) : 0;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
orderQty,
|
|
|
|
|
completedQty,
|
|
|
|
|
inProgressQty,
|
|
|
|
|
waitingQty,
|
|
|
|
|
progress,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function WorkLogModal({ open, onOpenChange, workOrderId }: WorkLogModalProps) {
|
|
|
|
|
const [order, setOrder] = useState<WorkOrder | null>(null);
|
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
// 모달 열릴 때 데이터 fetch
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (open && workOrderId) {
|
|
|
|
|
setIsLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
|
|
|
|
|
getWorkOrderById(workOrderId)
|
|
|
|
|
.then((result) => {
|
|
|
|
|
if (result.success && result.data) {
|
|
|
|
|
setOrder(result.data);
|
|
|
|
|
} else {
|
|
|
|
|
setError(result.error || '데이터를 불러올 수 없습니다.');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
setError('서버 오류가 발생했습니다.');
|
|
|
|
|
})
|
|
|
|
|
.finally(() => {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
});
|
|
|
|
|
} else if (!open) {
|
|
|
|
|
// 모달 닫힐 때 상태 초기화
|
|
|
|
|
setOrder(null);
|
|
|
|
|
setError(null);
|
|
|
|
|
}
|
|
|
|
|
}, [open, workOrderId]);
|
|
|
|
|
|
2025-12-23 21:13:07 +09:00
|
|
|
const handlePrint = () => {
|
2026-01-05 18:59:04 +09:00
|
|
|
printArea({ title: '작업일지 인쇄' });
|
2025-12-23 21:13:07 +09:00
|
|
|
};
|
|
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
if (!workOrderId) return null;
|
|
|
|
|
|
|
|
|
|
// 로딩 상태
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
return (
|
|
|
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
|
|
|
<DialogContent className="sm:max-w-5xl max-h-[90vh] overflow-y-auto p-0 gap-0 bg-gray-100">
|
|
|
|
|
<VisuallyHidden>
|
|
|
|
|
<DialogTitle>작업일지 로딩 중</DialogTitle>
|
|
|
|
|
</VisuallyHidden>
|
|
|
|
|
<div className="flex items-center justify-center h-64">
|
|
|
|
|
<Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
|
|
|
|
|
</div>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 에러 상태
|
|
|
|
|
if (error || !order) {
|
|
|
|
|
return (
|
|
|
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
|
|
|
<DialogContent className="sm:max-w-5xl max-h-[90vh] overflow-y-auto p-0 gap-0 bg-gray-100">
|
|
|
|
|
<VisuallyHidden>
|
|
|
|
|
<DialogTitle>작업일지 오류</DialogTitle>
|
|
|
|
|
</VisuallyHidden>
|
|
|
|
|
<div className="flex flex-col items-center justify-center h-64 gap-4">
|
|
|
|
|
<p className="text-muted-foreground">{error || '데이터를 불러올 수 없습니다.'}</p>
|
|
|
|
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
|
|
|
닫기
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-12-23 21:13:07 +09:00
|
|
|
|
|
|
|
|
const today = new Date().toLocaleDateString('ko-KR', {
|
|
|
|
|
year: 'numeric',
|
|
|
|
|
month: '2-digit',
|
|
|
|
|
day: '2-digit',
|
|
|
|
|
}).replace(/\. /g, '-').replace('.', '');
|
|
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
const documentNo = `WL-${order.processCode.toUpperCase().slice(0, 3)}`;
|
2025-12-23 21:13:07 +09:00
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
// 품목 데이터
|
|
|
|
|
const items = order.items || [];
|
2025-12-23 21:13:07 +09:00
|
|
|
|
2026-01-14 15:39:07 +09:00
|
|
|
// 작업 통계 계산
|
|
|
|
|
const workStats = calculateWorkStats(items);
|
|
|
|
|
|
|
|
|
|
// 주 담당자
|
|
|
|
|
const primaryAssignee = order.assignees?.find(a => a.isPrimary)?.name || order.assignee || '-';
|
2025-12-23 21:13:07 +09:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
|
|
|
<DialogContent className="sm:max-w-5xl max-h-[90vh] overflow-y-auto p-0 gap-0 bg-gray-100">
|
|
|
|
|
{/* 접근성을 위한 숨겨진 타이틀 */}
|
|
|
|
|
<VisuallyHidden>
|
2026-01-14 15:39:07 +09:00
|
|
|
<DialogTitle>작업일지 - {order.workOrderNo}</DialogTitle>
|
2025-12-23 21:13:07 +09:00
|
|
|
</VisuallyHidden>
|
2026-01-05 18:59:04 +09:00
|
|
|
{/* 모달 헤더 - sam-design 스타일 (인쇄 시 숨김) */}
|
|
|
|
|
<div className="print-hidden flex items-center justify-between px-6 py-4 border-b bg-white sticky top-0 z-10">
|
2025-12-23 21:13:07 +09:00
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<span className="font-semibold text-lg">작업일지</span>
|
|
|
|
|
<span className="text-sm text-muted-foreground">
|
2026-01-14 15:39:07 +09:00
|
|
|
{order.processName} 생산부서
|
2025-12-23 21:13:07 +09:00
|
|
|
</span>
|
|
|
|
|
<span className="text-sm text-muted-foreground">
|
|
|
|
|
({documentNo})
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<Button variant="outline" size="sm" onClick={handlePrint}>
|
|
|
|
|
<Printer className="w-4 h-4 mr-1.5" />
|
|
|
|
|
인쇄
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
className="h-8 w-8"
|
|
|
|
|
onClick={() => onOpenChange(false)}
|
|
|
|
|
>
|
|
|
|
|
<X className="w-4 h-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-01-05 18:59:04 +09:00
|
|
|
{/* 문서 본문 (인쇄 시 이 영역만 출력) */}
|
|
|
|
|
<div className="print-area m-6 p-6 bg-white rounded-lg shadow-sm">
|
2025-12-23 21:13:07 +09:00
|
|
|
{/* 문서 헤더: 로고 + 제목 + 결재라인 */}
|
|
|
|
|
<div className="flex justify-between items-start mb-6 border border-gray-300">
|
|
|
|
|
{/* 좌측: 로고 영역 */}
|
|
|
|
|
<div className="w-24 border-r border-gray-300 flex flex-col items-center justify-center p-3">
|
|
|
|
|
<span className="text-2xl font-bold">KD</span>
|
|
|
|
|
<span className="text-xs text-gray-500">정동기업</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 중앙: 문서 제목 */}
|
|
|
|
|
<div className="flex-1 flex flex-col items-center justify-center p-3 border-r border-gray-300">
|
|
|
|
|
<h1 className="text-xl font-bold tracking-widest mb-1">작 업 일 지</h1>
|
|
|
|
|
<p className="text-xs text-gray-500">{documentNo}</p>
|
2026-01-14 15:39:07 +09:00
|
|
|
<p className="text-sm font-medium mt-1">{order.processName} 생산부서</p>
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 우측: 결재라인 */}
|
|
|
|
|
<div className="shrink-0 text-xs">
|
2025-12-26 15:48:08 +09:00
|
|
|
<table className="border-collapse">
|
|
|
|
|
<tbody>
|
|
|
|
|
{/* 첫 번째 행: 결재 + 작성/검토/승인 */}
|
|
|
|
|
<tr>
|
|
|
|
|
<td rowSpan={3} className="w-8 text-center font-medium bg-gray-100 border-r border-b border-gray-300 align-middle">
|
|
|
|
|
<div className="flex flex-col items-center">
|
|
|
|
|
<span>결</span>
|
|
|
|
|
<span>재</span>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td className="w-16 p-2 text-center font-medium bg-gray-100 border-r border-b border-gray-300">작성</td>
|
|
|
|
|
<td className="w-16 p-2 text-center font-medium bg-gray-100 border-r border-b border-gray-300">검토</td>
|
|
|
|
|
<td className="w-16 p-2 text-center font-medium bg-gray-100 border-b border-gray-300">승인</td>
|
|
|
|
|
</tr>
|
|
|
|
|
{/* 두 번째 행: 이름 + 날짜 */}
|
|
|
|
|
<tr>
|
|
|
|
|
<td className="w-16 p-2 text-center border-r border-b border-gray-300">
|
2026-01-14 15:39:07 +09:00
|
|
|
<div>{primaryAssignee}</div>
|
2025-12-26 15:48:08 +09:00
|
|
|
<div className="text-[10px] text-gray-500">
|
|
|
|
|
{new Date().toLocaleDateString('ko-KR', { month: '2-digit', day: '2-digit' }).replace('. ', '/').replace('.', '')}
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td className="w-16 p-2 text-center border-r border-b border-gray-300"></td>
|
|
|
|
|
<td className="w-16 p-2 text-center border-b border-gray-300"></td>
|
|
|
|
|
</tr>
|
|
|
|
|
{/* 세 번째 행: 부서 */}
|
|
|
|
|
<tr>
|
|
|
|
|
<td className="w-16 p-2 text-center bg-gray-50 border-r border-gray-300">판매/전진</td>
|
|
|
|
|
<td className="w-16 p-2 text-center bg-gray-50 border-r border-gray-300">생산</td>
|
|
|
|
|
<td className="w-16 p-2 text-center bg-gray-50">품질</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 기본 정보 테이블 */}
|
|
|
|
|
<div className="border border-gray-300 mb-6">
|
|
|
|
|
{/* Row 1 */}
|
|
|
|
|
<div className="grid grid-cols-2 border-b border-gray-300">
|
|
|
|
|
<div className="flex border-r border-gray-300">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
|
|
|
|
발주처
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">{order.client}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
|
|
|
|
현장명
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">{order.projectName}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Row 2 */}
|
|
|
|
|
<div className="grid grid-cols-2 border-b border-gray-300">
|
|
|
|
|
<div className="flex border-r border-gray-300">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
|
|
|
|
작업일자
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">{today}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
|
|
|
|
LOT NO.
|
|
|
|
|
</div>
|
2026-01-14 15:39:07 +09:00
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">{order.lotNo}</div>
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Row 3 */}
|
|
|
|
|
<div className="grid grid-cols-2">
|
|
|
|
|
<div className="flex border-r border-gray-300">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
|
|
|
|
납기일
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">
|
2026-01-14 15:39:07 +09:00
|
|
|
{order.dueDate !== '-' ? new Date(order.dueDate).toLocaleDateString('ko-KR', {
|
2025-12-23 21:13:07 +09:00
|
|
|
year: 'numeric',
|
|
|
|
|
month: '2-digit',
|
|
|
|
|
day: '2-digit',
|
2026-01-14 15:39:07 +09:00
|
|
|
}).replace(/\. /g, '-').replace('.', '') : '-'}
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex">
|
|
|
|
|
<div className="w-24 bg-gray-100 p-3 text-sm font-medium border-r border-gray-300 flex items-center">
|
2026-01-14 15:39:07 +09:00
|
|
|
작업지시번호
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
2026-01-14 15:39:07 +09:00
|
|
|
<div className="flex-1 p-3 text-sm flex items-center">{order.workOrderNo}</div>
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 품목 테이블 */}
|
|
|
|
|
<div className="border border-gray-300 mb-6">
|
|
|
|
|
{/* 테이블 헤더 */}
|
|
|
|
|
<div className="grid grid-cols-12 border-b border-gray-300 bg-gray-100">
|
|
|
|
|
<div className="col-span-1 p-2 text-sm font-medium text-center border-r border-gray-300">No</div>
|
|
|
|
|
<div className="col-span-4 p-2 text-sm font-medium text-center border-r border-gray-300">품목명</div>
|
2026-01-14 15:39:07 +09:00
|
|
|
<div className="col-span-2 p-2 text-sm font-medium text-center border-r border-gray-300">층/부호</div>
|
2025-12-23 21:13:07 +09:00
|
|
|
<div className="col-span-2 p-2 text-sm font-medium text-center border-r border-gray-300">규격</div>
|
|
|
|
|
<div className="col-span-1 p-2 text-sm font-medium text-center border-r border-gray-300">수량</div>
|
|
|
|
|
<div className="col-span-2 p-2 text-sm font-medium text-center">상태</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 테이블 데이터 */}
|
2026-01-14 15:39:07 +09:00
|
|
|
{items.length > 0 ? (
|
|
|
|
|
items.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={item.id}
|
|
|
|
|
className={`grid grid-cols-12 ${index < items.length - 1 ? 'border-b border-gray-300' : ''}`}
|
|
|
|
|
>
|
|
|
|
|
<div className="col-span-1 p-2 text-sm text-center border-r border-gray-300">{item.no}</div>
|
|
|
|
|
<div className="col-span-4 p-2 text-sm border-r border-gray-300">{item.productName}</div>
|
|
|
|
|
<div className="col-span-2 p-2 text-sm text-center border-r border-gray-300">{item.floorCode}</div>
|
|
|
|
|
<div className="col-span-2 p-2 text-sm text-center border-r border-gray-300">{item.specification}</div>
|
|
|
|
|
<div className="col-span-1 p-2 text-sm text-center border-r border-gray-300">{item.quantity}</div>
|
|
|
|
|
<div className="col-span-2 p-2 text-sm text-center">{ITEM_STATUS_LABELS[item.status]}</div>
|
|
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
|
|
|
|
<div className="p-4 text-center text-muted-foreground text-sm">
|
|
|
|
|
등록된 품목이 없습니다.
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
2026-01-14 15:39:07 +09:00
|
|
|
)}
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 작업내역 */}
|
|
|
|
|
<div className="border border-gray-300 mb-6">
|
|
|
|
|
{/* 검정 헤더 */}
|
|
|
|
|
<div className="bg-gray-800 text-white p-2.5 text-sm font-medium text-center">
|
2026-01-14 15:39:07 +09:00
|
|
|
{order.processName} 작업내역
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 수량 및 진행률 */}
|
2026-01-14 15:39:07 +09:00
|
|
|
<div className="grid grid-cols-6 border-b border-gray-300">
|
2025-12-23 21:13:07 +09:00
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">지시수량</div>
|
|
|
|
|
<div className="p-2 text-sm border-r border-gray-300 text-center">{workStats.orderQty} EA</div>
|
|
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">완료수량</div>
|
|
|
|
|
<div className="p-2 text-sm border-r border-gray-300 text-center">{workStats.completedQty} EA</div>
|
|
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">진행률</div>
|
|
|
|
|
<div className="p-2 text-sm text-center font-medium text-blue-600">{workStats.progress}%</div>
|
|
|
|
|
</div>
|
2026-01-14 15:39:07 +09:00
|
|
|
|
|
|
|
|
{/* 상세 상태 */}
|
|
|
|
|
<div className="grid grid-cols-6">
|
|
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">대기</div>
|
|
|
|
|
<div className="p-2 text-sm border-r border-gray-300 text-center">{workStats.waitingQty} EA</div>
|
|
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">작업중</div>
|
|
|
|
|
<div className="p-2 text-sm border-r border-gray-300 text-center">{workStats.inProgressQty} EA</div>
|
|
|
|
|
<div className="p-2 text-sm bg-gray-100 border-r border-gray-300 text-center font-medium">완료</div>
|
|
|
|
|
<div className="p-2 text-sm text-center">{workStats.completedQty} EA</div>
|
|
|
|
|
</div>
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 특이 사항 */}
|
|
|
|
|
<div className="border border-gray-300">
|
|
|
|
|
<div className="bg-gray-800 text-white p-2.5 text-sm font-medium text-center">
|
|
|
|
|
특이사항
|
|
|
|
|
</div>
|
|
|
|
|
<div className="p-4 min-h-[60px] text-sm">
|
2026-01-14 15:39:07 +09:00
|
|
|
{order.note || '-'}
|
2025-12-23 21:13:07 +09:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
}
|