Basdat/web/js/components/ItemCard.js
2025-12-20 00:01:08 +07:00

189 lines
6.5 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// web/js/components/ItemCard.js
const ItemCard = ({
item,
onViewDetail,
onClaim,
onEdit,
onDelete,
onManualClaim,
currentUserId,
showActions = true,
isManager = false,
}) => {
const isOwnItem = currentUserId && item.reporter_id === currentUserId;
// ✅ FIX: Status logic yang lebih akurat
const isCaseClosed = item.status === "case_closed";
const isExpired = item.status === "expired";
const isVerified = item.status === "verified" || item.status === "completed";
const isPendingClaim = item.status === "pending_claim";
const isUnclaimed = item.status === "unclaimed";
// ✅ User hanya bisa claim jika unclaimed DAN bukan barang sendiri
const canClaim = isUnclaimed && !isOwnItem;
// ✅ Edit/Delete logic
let canEditOrDelete = false;
if (!isCaseClosed) {
if (isManager) {
canEditOrDelete = true;
} else {
canEditOrDelete = !isExpired;
}
}
const showEditButton = (isOwnItem || isManager) && canEditOrDelete;
// ✅ Improved status display text
const getStatusText = (status) => {
const statusMap = {
unclaimed: "Belum Diklaim",
pending_claim: "Sedang Diklaim",
verified: "Sudah Diklaim",
completed: "Selesai",
case_closed: "Kasus Ditutup",
expired: "Kadaluarsa",
};
return statusMap[status] || status;
};
return (
<div
className={`bg-gradient-to-br from-slate-800 to-slate-900 border-2 rounded-xl overflow-hidden hover:shadow-2xl transition-all cursor-pointer ${
isExpired
? "border-red-500/50 hover:border-red-500"
: "border-slate-700 hover:border-blue-500 hover:shadow-blue-500/20 hover:-translate-y-1"
}`}
>
{/* Expired Banner */}
{isExpired && (
<div className="absolute top-0 left-0 right-0 bg-red-600/90 text-white text-center py-1 text-xs font-bold z-10">
EXPIRED - Manager Only View
</div>
)}
{/* Completed Banner - TAMBAHKAN INI */}
{isVerified && (
<div className="absolute top-0 left-0 right-0 bg-green-600/90 text-white text-center py-1 text-xs font-bold z-10">
SUDAH DIKLAIM
</div>
)}
<img
src={
item.photo_url || "https://via.placeholder.com/280x200?text=No+Image"
}
alt={item.name}
className={`w-full h-48 object-cover ${isExpired ? "opacity-50" : ""} ${
isVerified ? "opacity-80" : ""
}`}
onClick={() => onViewDetail && onViewDetail(item)}
onError={(e) =>
(e.target.src = "https://via.placeholder.com/280x200?text=No+Image")
}
/>
<div className="p-4">
<h3 className="text-lg font-semibold text-white mb-2">{item.name}</h3>
<div className="flex flex-col gap-1 text-sm text-slate-400 mb-3">
<span>📍 {item.location}</span>
<span>📅 {Helpers.formatDate(item.date_found)}</span>
</div>
<div className="flex items-center justify-between mb-3">
<span
className={`px-3 py-1 rounded-full text-xs font-semibold ${Helpers.getStatusBadgeClass(
item.status
)}`}
>
{getStatusText(item.status)} {/* ✅ Better display */}
</span>
{isOwnItem && (
<span className="px-3 py-1 bg-green-500/20 text-green-400 text-xs font-semibold rounded-full border border-green-500/50">
Barang Anda
</span>
)}
</div>
{showActions && (
<div className="flex gap-2 flex-wrap">
{/* Detail Button */}
{onViewDetail && (
<button
onClick={(e) => {
e.stopPropagation();
onViewDetail(item);
}}
className="flex-1 px-3 py-2 bg-gradient-to-r from-blue-600 to-blue-700 text-white text-sm rounded-lg hover:from-blue-700 hover:to-blue-800 transition shadow-lg"
>
Detail
</button>
)}
{/* Manual Claim (Manager) */}
{onManualClaim && isUnclaimed && (
<button
onClick={(e) => {
e.stopPropagation();
onManualClaim(item);
}}
className="flex-1 px-3 py-2 bg-gradient-to-r from-green-600 to-green-700 text-white text-sm rounded-lg hover:from-green-700 hover:to-green-800 transition shadow-lg"
>
🤝 Klaim
</button>
)}
{/* User Claim - ✅ HANYA SHOW JIKA UNCLAIMED */}
{onClaim && canClaim && (
<button
onClick={(e) => {
e.stopPropagation();
onClaim(item);
}}
className="flex-1 px-3 py-2 bg-gradient-to-r from-green-600 to-green-700 text-white text-sm rounded-lg hover:from-green-700 hover:to-green-800 transition shadow-lg"
>
Klaim
</button>
)}
{/* Info untuk status pending */}
{isPendingClaim && !isOwnItem && (
<div className="flex-1 px-3 py-2 bg-yellow-600/20 text-yellow-400 text-xs rounded-lg border border-yellow-600/50 text-center">
Sedang diproses
</div>
)}
{/* Edit Button */}
{onEdit && showEditButton && (
<button
onClick={(e) => {
e.stopPropagation();
onEdit(item);
}}
className="flex-1 px-3 py-2 bg-gradient-to-r from-yellow-600 to-yellow-700 text-white text-sm rounded-lg hover:from-yellow-700 hover:to-yellow-800 transition shadow-lg"
>
Edit
</button>
)}
{/* Delete Button */}
{onDelete && canEditOrDelete && (
<button
onClick={(e) => {
e.stopPropagation();
if (confirm(`Yakin hapus "${item.name}"?`)) onDelete(item.id);
}}
className="px-3 py-2 bg-gradient-to-r from-red-600 to-red-700 text-white text-sm rounded-lg hover:from-red-700 hover:to-red-800 transition shadow-lg"
title="Hapus Barang"
>
🗑
</button>
)}
</div>
)}
</div>
</div>
);
};