import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { AnimatePresence, motion } from "framer-motion"; import { X, Trash2, RefreshCw, Pencil, Check, Loader2, Copy } from "lucide-react"; import { useState } from "react"; import useToastStore from "@/stores/useToastStore"; import dayjs from "dayjs"; import { fetchParcel, deleteParcel, updateParcel, refreshParcel, } from "@/api/parcels"; import TrackingTimeline from "./TrackingTimeline"; import StatusBadge from "./StatusBadge"; function ParcelDialog({ parcelId, onClose }) { const queryClient = useQueryClient(); const [editing, setEditing] = useState(false); const [editLabel, setEditLabel] = useState(""); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const showToast = useToastStore((s) => s.show); const { data: parcel, isLoading } = useQuery({ queryKey: ["parcel", parcelId], queryFn: () => fetchParcel(parcelId), enabled: !!parcelId, }); const deleteMutation = useMutation({ mutationFn: () => deleteParcel(parcelId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["parcels"] }); queryClient.invalidateQueries({ queryKey: ["parcels-count-all"] }); queryClient.invalidateQueries({ queryKey: ["parcels-count-active"] }); queryClient.invalidateQueries({ queryKey: ["parcels-count-delivered"] }); showToast("택배가 삭제되었습니다"); onClose(); }, }); const updateMutation = useMutation({ mutationFn: (label) => updateParcel(parcelId, { label }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["parcel", parcelId] }); queryClient.invalidateQueries({ queryKey: ["parcels"] }); setEditing(false); }, }); const refreshMutation = useMutation({ mutationFn: () => refreshParcel(parcelId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["parcel", parcelId] }); queryClient.invalidateQueries({ queryKey: ["parcels"] }); }, }); const handleDelete = () => { setShowDeleteConfirm(true); }; const confirmDelete = () => { deleteMutation.mutate(); setShowDeleteConfirm(false); }; const handleEditStart = () => { setEditLabel(parcel?.label || ""); setEditing(true); }; const handleEditSave = () => { updateMutation.mutate(editLabel); }; return ( <> {parcelId && ( <> e.stopPropagation()} > {isLoading || !parcel ? ( ) : ( <> {/* 헤더 */} {editing ? ( setEditLabel(e.target.value)} className="h-full border-0 border-b-2 border-primary bg-transparent px-0 text-lg lg:text-xl font-semibold text-gray-900 flex-1 focus:outline-none focus:border-primary-dark placeholder:text-gray-300" placeholder="별칭을 입력하세요" autoFocus onKeyDown={(e) => e.key === "Enter" && handleEditSave() } /> setEditing(false)} className="text-gray-400 hover:text-gray-600 shrink-0 p-1" > ) : ( {parcel.label || parcel.tracking_number} )} {parcel.carrier_name} | { navigator.clipboard.writeText(parcel.tracking_number); showToast("운송장 번호가 복사되었습니다"); }} className="flex items-center gap-1 tracking-letter-spacing hover:text-primary transition-colors" > {parcel.tracking_number} {(parcel.sender_name || parcel.recipient_name) && ( {parcel.sender_name && ( 보내는 분: {parcel.sender_name} )} {parcel.recipient_name && ( 받는 분: {parcel.recipient_name} )} )} {/* 배송 추적 - 내부 스크롤 */} 배송 추적 refreshMutation.mutate()} disabled={refreshMutation.isPending} className="text-primary hover:text-primary-dark transition-colors disabled:opacity-50" > {parcel.last_checked_at && ( {dayjs(parcel.last_checked_at).format("MM.DD HH:mm")} 조회 )} {parcel.events?.length > 0 ? ( ) : ( 배송 정보가 아직 없습니다 )} > )} > )} {showDeleteConfirm && ( <> setShowDeleteConfirm(false)} /> setShowDeleteConfirm(false)} > e.stopPropagation()} > 이 택배를 삭제할까요? setShowDeleteConfirm(false)} className="flex-1 px-4 py-2 text-sm text-gray-500 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" > 취소 삭제 > )} > ); } export default ParcelDialog;
배송 정보가 아직 없습니다
이 택배를 삭제할까요?