- 더미 데이터 → React Query + 실제 API 호출로 전환 - 상세 페이지 → 모달 다이얼로그로 변경 - 무한 스크롤 페이징 (useInfiniteQuery + react-virtual) - 내부 스크롤 적용 (전체 페이지 스크롤 제거) - 보내는 분/받는 분 정보 표시 - 삭제 확인 커스텀 다이얼로그 - DB 타임존 KST 설정 (dateStrings) - 백엔드 페이징 API 추가 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
69 lines
2 KiB
JavaScript
69 lines
2 KiB
JavaScript
import { useQuery } from "@tanstack/react-query";
|
|
import dayjs from "dayjs";
|
|
import StatusBadge from "./StatusBadge";
|
|
import { fetchCarriers } from "@/api/parcels";
|
|
|
|
function ParcelCard({ parcel, onClick }) {
|
|
const { data: carriers = [] } = useQuery({
|
|
queryKey: ["carriers"],
|
|
queryFn: fetchCarriers,
|
|
staleTime: 1000 * 60 * 60,
|
|
});
|
|
|
|
const carrier = carriers.find((c) => c.id === parcel.carrier_id);
|
|
|
|
return (
|
|
<div
|
|
onClick={onClick}
|
|
className="bg-white rounded-xl shadow-sm cursor-pointer hover:shadow-md transition-shadow flex items-center gap-3 lg:gap-4 p-3.5 lg:p-4"
|
|
>
|
|
<CarrierLogo carrier={carrier} />
|
|
|
|
<div className="flex-1 min-w-0 space-y-1.5 lg:space-y-2">
|
|
<div className="flex items-center gap-1.5 text-xs lg:text-sm text-gray-400">
|
|
<span>{parcel.carrier_name}</span>
|
|
<span>|</span>
|
|
<span className="tracking-letter-spacing">
|
|
{parcel.tracking_number}
|
|
</span>
|
|
</div>
|
|
|
|
<p className="font-semibold text-sm lg:text-base text-gray-900 truncate">
|
|
{parcel.label || parcel.tracking_number}
|
|
</p>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-xs lg:text-sm text-gray-400">
|
|
{dayjs(parcel.created_at).format("YYYY.MM.DD")}
|
|
</span>
|
|
<StatusBadge status={parcel.status} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function CarrierLogo({ carrier }) {
|
|
if (!carrier) return <div className="w-7 h-7 lg:w-8 lg:h-8 shrink-0" />;
|
|
|
|
if (carrier.logo_url) {
|
|
return (
|
|
<img
|
|
src={carrier.logo_url}
|
|
alt={carrier.name}
|
|
className="w-7 h-7 lg:w-8 lg:h-8 rounded-full object-contain shrink-0"
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<span
|
|
className="inline-flex items-center justify-center w-7 h-7 lg:w-8 lg:h-8 rounded-full text-white text-[10px] lg:text-[11px] font-bold shrink-0"
|
|
style={{ backgroundColor: carrier.color }}
|
|
>
|
|
{carrier.short_name?.slice(0, 2)}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export default ParcelCard;
|