traeon/frontend/src/components/ParcelCard.jsx

70 lines
2 KiB
React
Raw Normal View History

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-9 h-9 lg:w-10 lg:h-10 shrink-0" />;
if (carrier.logo_url) {
return (
<img
src={carrier.logo_url}
alt={carrier.name}
className="w-9 h-9 lg:w-10 lg:h-10 rounded-full object-contain shrink-0"
/>
);
}
return (
<span
className="inline-flex items-center justify-center w-9 h-9 lg:w-10 lg:h-10 rounded-full text-white text-[11px] lg:text-xs font-bold shrink-0"
style={{ backgroundColor: carrier.color }}
>
{carrier.short_name?.slice(0, 2)}
</span>
);
}
export default ParcelCard;