Basdat/web/js/pages/user/tabs/MyLostItemsTab.js
2025-12-20 00:01:08 +07:00

322 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const MyLostItemsTab = ({ state, handlers }) => {
const { myLostItems, myClaims, loading } = state;
const lostItemsWithClaims = myLostItems.filter((item) => {
if (!item.direct_claim_id || !item.direct_claim_status) {
return false;
}
const excludedStatuses = ["completed", "resolved", "case_closed"];
if (excludedStatuses.includes(item.status)) {
return false;
}
if (excludedStatuses.includes(item.direct_claim_status)) {
return false;
}
const pendingStatuses = ["waiting_owner", "verified", "claimed", "pending"];
return pendingStatuses.includes(item.direct_claim_status);
});
const regularClaims = myClaims || [];
// UPDATED: Menambahkan parameter isMyLostItem (default true)
const getStatusBadge = (status, isMyLostItem = true) => {
const badges = {
active: { color: "bg-blue-500", text: "📍 Masih Hilang", emoji: "😢" },
claimed: {
color: "bg-yellow-500",
text: "⏳ Menunggu Persetujuan Anda",
emoji: "🤔",
},
found: { color: "bg-green-500", text: "✅ Ditemukan", emoji: "🎉" },
completed: {
color: "bg-purple-600",
text: "✅ Selesai - Barang Diterima",
emoji: "🎉",
},
resolved: {
color: "bg-purple-600",
text: "✅ Selesai - Dikembalikan",
emoji: "🎉",
},
pending: {
color: "bg-yellow-500",
text: "⏳ Menunggu Verifikasi",
emoji: "⏳",
},
approved: { color: "bg-green-500", text: "✅ Disetujui", emoji: "✅" },
rejected: { color: "bg-red-500", text: "❌ Ditolak", emoji: "❌" },
waiting_owner: {
color: "bg-orange-500",
// LOGIC FIX: Membedakan teks berdasarkan kepemilikan
text: isMyLostItem ? "⏳ Menunggu Anda" : "⏳ Menunggu Owner",
emoji: "👤",
},
verified: {
color: "bg-green-600",
text: "✅ Terverifikasi",
emoji: "✅",
},
};
return (
badges[status] || {
color: "bg-gray-500",
text: status,
emoji: "❓",
}
);
};
if (loading) {
return (
<div className="text-center py-12 text-slate-400">
<div className="animate-spin text-4xl mb-4"></div>
<p>Memuat data klaim...</p>
</div>
);
}
return (
<div className="space-y-8">
{/* Header Section */}
<div className="flex justify-between items-center bg-gradient-to-r from-blue-600 to-blue-700 rounded-xl p-4 shadow-lg">
<div>
<h3 className="text-xl font-bold text-white">
😢 Barang Hilang Saya
</h3>
<p className="text-blue-100 text-sm">
Kelola laporan kehilangan barang Anda
</p>
</div>
<button
onClick={() => state.setShowReportLostModal(true)}
className="px-6 py-3 bg-white text-blue-600 rounded-lg font-bold hover:bg-blue-50 transition shadow-xl hover:scale-105 transform flex items-center gap-2"
>
<span className="text-xl"></span>
Lapor Kehilangan
</button>
</div>
{/* SECTION 1: Barang Hilang Saya (Anda sebagai Owner) */}
{lostItemsWithClaims.length > 0 && (
<div className="bg-slate-800/50 backdrop-blur-sm rounded-2xl border border-slate-700 p-6">
<h3 className="text-2xl font-bold text-white mb-4 flex items-center gap-3">
<span className="text-3xl">😢</span>
Barang Hilang Saya
<span className="bg-orange-500/20 text-orange-400 text-sm px-3 py-1 rounded-full border border-orange-500/30">
{lostItemsWithClaims.length} item dengan klaim pending
</span>
</h3>
<p className="text-slate-400 mb-6">
Ada yang menemukan barang Anda! Silakan approve atau reject klaim
mereka.
</p>
<div className="space-y-4">
{lostItemsWithClaims.map((lostItem) => {
// Context: True (Ini barang saya)
const statusBadge = getStatusBadge(
lostItem.direct_claim_status || lostItem.status,
true
);
const isWaitingOwner =
lostItem.direct_claim_status === "waiting_owner";
const isVerified =
lostItem.direct_claim_status === "verified" ||
lostItem.status === "found";
return (
<div
key={lostItem.id}
className={`bg-slate-900/80 rounded-xl border ${
isWaitingOwner
? "border-orange-500/50 shadow-lg shadow-orange-500/20"
: "border-slate-700"
} p-6 hover:shadow-xl transition-all`}
>
<div className="flex justify-between items-start mb-4">
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<h4 className="text-xl font-bold text-white">
{lostItem.name}
</h4>
<span
className={`${statusBadge.color} text-white text-xs px-3 py-1 rounded-full font-medium`}
>
{statusBadge.emoji} {statusBadge.text}
</span>
</div>
<div className="space-y-1 text-sm text-slate-400">
<p>
<span className="font-medium">📦 Kategori:</span>{" "}
{lostItem.category}
</p>
{lostItem.color && (
<p>
<span className="font-medium">🎨 Warna:</span>{" "}
{lostItem.color}
</p>
)}
<p>
<span className="font-medium">📍 Lokasi Hilang:</span>{" "}
{lostItem.location}
</p>
<p>
<span className="font-medium">
📅 Tanggal Hilang:
</span>{" "}
{new Date(lostItem.date_lost).toLocaleDateString(
"id-ID"
)}
</p>
<p className="mt-2">
<span className="font-medium">📝 Deskripsi:</span>{" "}
{lostItem.description}
</p>
</div>
</div>
</div>
{isWaitingOwner && (
<div className="bg-orange-900/30 border border-orange-500/30 rounded-lg p-4 mt-4">
<p className="text-orange-300 font-semibold mb-3 flex items-center gap-2">
<span className="text-2xl">🔔</span>
Ada yang mengaku menemukan barang ini!
</p>
<p className="text-sm text-slate-300 mb-4">
Seseorang telah mengajukan klaim untuk barang ini.
Silakan putuskan apakah ini benar barang Anda.
</p>
<div className="flex gap-3">
<button
onClick={() =>
handlers.handleUserRespondClaim(
lostItem.direct_claim_id,
"approve"
)
}
className="flex-1 bg-gradient-to-r from-green-600 to-green-700 text-white px-4 py-3 rounded-lg font-semibold hover:from-green-700 hover:to-green-800 transition shadow-lg shadow-green-500/30"
>
Approve (Ini barang saya!)
</button>
<button
onClick={() =>
handlers.handleUserRespondClaim(
lostItem.direct_claim_id,
"reject"
)
}
className="flex-1 bg-gradient-to-r from-red-600 to-red-700 text-white px-4 py-3 rounded-lg font-semibold hover:from-red-700 hover:to-red-800 transition shadow-lg shadow-red-500/30"
>
Reject (Bukan barang saya)
</button>
</div>
</div>
)}
{isVerified && (
<div className="bg-green-900/30 border border-green-500/30 rounded-lg p-4 mt-4">
<p className="text-green-300 font-semibold mb-3 flex items-center gap-2">
<span className="text-2xl"></span>
Klaim Disetujui!
</p>
<p className="text-sm text-slate-300 mb-4">
Anda telah menyetujui bahwa penemu menemukan barang
Anda. Koordinasikan pengambilan barang, lalu konfirmasi
setelah menerima barang.
</p>
<button
onClick={() =>
handlers.handleUserCompleteCase(
lostItem.direct_claim_id
)
}
className="w-full bg-gradient-to-r from-purple-600 to-purple-700 text-white px-4 py-3 rounded-lg font-semibold hover:from-purple-700 hover:to-purple-800 transition shadow-lg shadow-purple-500/30"
>
🎉 Konfirmasi: Saya Sudah Terima Barang
</button>
</div>
)}
</div>
);
})}
</div>
</div>
)}
{/* SECTION 2: Klaim Barang yang Saya Ajukan (Anda sebagai Penemu) */}
{regularClaims.length > 0 && (
<div className="bg-slate-800/50 backdrop-blur-sm rounded-2xl border border-slate-700 p-6">
<h3 className="text-2xl font-bold text-white mb-4 flex items-center gap-3">
<span className="text-3xl">🤝</span>
Klaim Barang yang Saya Ajukan
<span className="bg-blue-500/20 text-blue-400 text-sm px-3 py-1 rounded-full border border-blue-500/30">
{regularClaims.length} klaim
</span>
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{regularClaims.map((claim) => {
// Context: False (Ini klaim saya ke orang lain/owner)
// UPDATED: Pass false agar text menjadi "Menunggu Owner"
const statusBadge = getStatusBadge(claim.status, false);
return (
<div
key={claim.id}
className="bg-slate-900/80 rounded-xl border border-slate-700 p-5 hover:shadow-xl transition-all"
>
<div className="flex items-start justify-between mb-3">
<h4 className="text-lg font-bold text-white flex-1">
{claim.item_name}
</h4>
<span
className={`${statusBadge.color} text-white text-xs px-3 py-1 rounded-full font-medium whitespace-nowrap ml-2`}
>
{statusBadge.emoji} {statusBadge.text}
</span>
</div>
<div className="space-y-2 text-sm text-slate-400">
<p>
<span className="font-medium">📝 Deskripsi:</span>{" "}
{claim.description}
</p>
<p>
<span className="font-medium">📞 Kontak:</span>{" "}
{claim.contact}
</p>
<p>
<span className="font-medium">📅 Tanggal Klaim:</span>{" "}
{new Date(claim.created_at).toLocaleDateString("id-ID")}
</p>
{claim.notes && (
<p className="text-yellow-400 mt-2">
<span className="font-medium">💬 Catatan:</span>{" "}
{claim.notes}
</p>
)}
</div>
</div>
);
})}
</div>
</div>
)}
{lostItemsWithClaims.length === 0 && regularClaims.length === 0 && (
<div className="text-center py-16 bg-slate-800/30 rounded-2xl border border-slate-700">
<div className="text-6xl mb-4">🔭</div>
<h3 className="text-xl font-bold text-white mb-2">Belum Ada Klaim</h3>
<p className="text-slate-400 mb-6">
Anda belum memiliki klaim atau barang hilang dengan klaim pending.
</p>
<button
onClick={() => state.setShowReportLostModal(true)}
className="px-6 py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white rounded-lg font-semibold hover:from-blue-700 hover:to-blue-800 transition shadow-lg"
>
Lapor Kehilangan Sekarang
</button>
</div>
)}
</div>
);
};
window.MyLostItemsTab = MyLostItemsTab;