// Dashboard User JavaScript - FIXED ENDPOINTS let allItems = []; let allLostItems = []; let allClaims = []; // Initialize dashboard window.addEventListener("DOMContentLoaded", async () => { const user = checkAuth(); if (!user || user.role !== "user") { window.location.href = "/login"; return; } await loadStats(); await loadBrowseItems(); setupSearchAndFilters(); }); // Load statistics - CORRECT (sudah sesuai) async function loadStats() { try { const stats = await apiCall("/api/user/stats"); document.getElementById("statLost").textContent = stats.lost_items || 0; document.getElementById("statFound").textContent = stats.found_items || 0; document.getElementById("statClaims").textContent = stats.claims || 0; } catch (error) { console.error("Error loading stats:", error); } } // Load browse items - CORRECT (sudah sesuai) async function loadBrowseItems() { setLoading("itemsGrid", true); try { const response = await apiCall("/api/items"); allItems = response.data || []; renderItems(allItems); } catch (error) { console.error("Error loading items:", error); showEmptyState("itemsGrid", "📦", "Gagal memuat data barang"); } } // Render items function renderItems(items) { const grid = document.getElementById("itemsGrid"); if (!items || items.length === 0) { showEmptyState("itemsGrid", "📦", "Belum ada barang ditemukan"); return; } grid.innerHTML = items .map( (item) => `
${item.name}

${item.name}

📍 ${item.location} 📅 ${formatDate(item.date_found)} ${getStatusBadge(item.status)}
${ item.status === "unclaimed" ? `` : "" }
` ) .join(""); } // View item detail - CORRECT (sudah sesuai) async function viewItemDetail(itemId) { try { const item = await apiCall(`/api/items/${itemId}`); const modalContent = document.getElementById("itemDetailContent"); modalContent.innerHTML = ` ${item.name}

${item.name}

Kategori: ${item.category}
Lokasi Ditemukan: ${item.location}
Tanggal Ditemukan: ${formatDate( item.date_found )}
Status: ${getStatusBadge(item.status)}
${ item.status === "unclaimed" ? `` : "" } `; openModal("itemDetailModal"); } catch (error) { console.error("Error loading item detail:", error); showAlert("Gagal memuat detail barang", "danger"); } } // Open claim modal function openClaimModal(itemId) { closeModal("itemDetailModal"); const modalContent = document.getElementById("claimModalContent"); modalContent.innerHTML = `
Upload foto barang saat Anda masih memilikinya (opsional)
`; openModal("claimModal"); } // Submit claim - CORRECT (sudah sesuai) async function submitClaim(event, itemId) { event.preventDefault(); const form = event.target; const formData = new FormData(form); formData.append("item_id", itemId); try { const submitBtn = form.querySelector('button[type="submit"]'); submitBtn.disabled = true; submitBtn.innerHTML = ' Mengirim...'; await apiUpload("/api/claims", formData); showAlert( "Klaim berhasil disubmit! Menunggu verifikasi dari manager.", "success" ); closeModal("claimModal"); await loadBrowseItems(); await loadStats(); } catch (error) { console.error("Error submitting claim:", error); showAlert(error.message || "Gagal submit klaim", "danger"); } finally { const submitBtn = form.querySelector('button[type="submit"]'); if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = "Submit Klaim"; } } } // Load my lost items - CORRECT (sudah sesuai) async function loadLost() { setLoading("lostItemsGrid", true); try { const response = await apiCall("/api/user/lost-items"); allLostItems = response.data || []; renderLostItems(allLostItems); } catch (error) { console.error("Error loading lost items:", error); showEmptyState("lostItemsGrid", "😢", "Gagal memuat data barang hilang"); } } // Render lost items function renderLostItems(items) { const grid = document.getElementById("lostItemsGrid"); if (!items || items.length === 0) { showEmptyState( "lostItemsGrid", "😢", "Anda belum melaporkan barang hilang" ); return; } grid.innerHTML = items .map( (item) => `

${item.name}

🏷️ ${item.category} 🎨 ${item.color} 📅 ${formatDate(item.date_lost)} ${item.location ? `📍 ${item.location}` : ""}

${ item.description }

` ) .join(""); } // Load my found items - FIXED async function loadFound() { setLoading("foundItemsGrid", true); try { const response = await apiCall("/api/user/items"); const items = response.data || []; renderFoundItems(items); } catch (error) { console.error("Error loading found items:", error); showEmptyState( "foundItemsGrid", "🎉", "Gagal memuat data barang yang ditemukan" ); } } // Render found items function renderFoundItems(items) { const grid = document.getElementById("foundItemsGrid"); if (!items || items.length === 0) { showEmptyState( "foundItemsGrid", "🎉", "Anda belum melaporkan penemuan barang" ); return; } grid.innerHTML = items .map( (item) => `
${item.name}

${item.name}

📍 ${item.location} 📅 ${formatDate(item.date_found)} ${getStatusBadge(item.status)}
` ) .join(""); } // Load my claims - CORRECT (sudah sesuai) async function loadClaims() { setLoading("claimsGrid", true); try { const response = await apiCall("/api/user/claims"); allClaims = response.data || []; renderClaims(allClaims); } catch (error) { console.error("Error loading claims:", error); showEmptyState("claimsGrid", "🤝", "Gagal memuat data klaim"); } } // Render claims function renderClaims(claims) { const grid = document.getElementById("claimsGrid"); if (!claims || claims.length === 0) { showEmptyState("claimsGrid", "🤝", "Anda belum pernah mengajukan klaim"); return; } grid.innerHTML = claims .map( (claim) => `

${claim.item_name}

📅 ${formatDate(claim.created_at)} ${getStatusBadge(claim.status)}

${claim.description}

${ claim.status === "rejected" && claim.notes ? `

Alasan ditolak: ${claim.notes}

` : "" }
` ) .join(""); } // Report lost item function openReportLostModal() { openModal("reportLostModal"); } // Submit lost item report - CORRECT (sudah sesuai) document .getElementById("reportLostForm") ?.addEventListener("submit", async (e) => { e.preventDefault(); const formData = new FormData(e.target); const data = Object.fromEntries(formData); try { const submitBtn = e.target.querySelector('button[type="submit"]'); submitBtn.disabled = true; submitBtn.innerHTML = ' Mengirim...'; await apiCall("/api/lost-items", { method: "POST", body: JSON.stringify(data), }); showAlert("Laporan kehilangan berhasil disubmit!", "success"); closeModal("reportLostModal"); e.target.reset(); await loadLost(); await loadStats(); } catch (error) { console.error("Error submitting lost item:", error); showAlert(error.message || "Gagal submit laporan", "danger"); } finally { const submitBtn = e.target.querySelector('button[type="submit"]'); if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = "Submit Laporan"; } } }); // Report found item function openReportFoundModal() { openModal("reportFoundModal"); } // Submit found item report - CORRECT (sudah sesuai) document .getElementById("reportFoundForm") ?.addEventListener("submit", async (e) => { e.preventDefault(); const formData = new FormData(e.target); try { const submitBtn = e.target.querySelector('button[type="submit"]'); submitBtn.disabled = true; submitBtn.innerHTML = ' Mengirim...'; await apiUpload("/api/items", formData); showAlert("Laporan penemuan berhasil disubmit!", "success"); closeModal("reportFoundModal"); e.target.reset(); await loadFound(); await loadStats(); } catch (error) { console.error("Error submitting found item:", error); showAlert(error.message || "Gagal submit laporan", "danger"); } finally { const submitBtn = e.target.querySelector('button[type="submit"]'); if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = "Submit Penemuan"; } } }); // Setup search and filters function setupSearchAndFilters() { const searchInput = document.getElementById("searchInput"); const categoryFilter = document.getElementById("categoryFilter"); const sortBy = document.getElementById("sortBy"); const performSearch = debounce(() => { const searchTerm = searchInput?.value.toLowerCase() || ""; const category = categoryFilter?.value || ""; const sort = sortBy?.value || "date_desc"; let filtered = allItems.filter((item) => { const matchesSearch = item.name.toLowerCase().includes(searchTerm) || item.location.toLowerCase().includes(searchTerm); const matchesCategory = !category || item.category === category; return matchesSearch && matchesCategory; }); // Sort filtered.sort((a, b) => { switch (sort) { case "date_desc": return new Date(b.date_found) - new Date(a.date_found); case "date_asc": return new Date(a.date_found) - new Date(b.date_found); case "name_asc": return a.name.localeCompare(b.name); case "name_desc": return b.name.localeCompare(a.name); default: return 0; } }); renderItems(filtered); }, 300); searchInput?.addEventListener("input", performSearch); categoryFilter?.addEventListener("change", performSearch); sortBy?.addEventListener("change", performSearch); } // Create claim modal if not exists if (!document.getElementById("claimModal")) { const claimModal = document.createElement("div"); claimModal.id = "claimModal"; claimModal.className = "modal"; claimModal.innerHTML = ` `; document.body.appendChild(claimModal); } // Create item detail modal if not exists if (!document.getElementById("itemDetailModal")) { const itemDetailModal = document.createElement("div"); itemDetailModal.id = "itemDetailModal"; itemDetailModal.className = "modal"; itemDetailModal.innerHTML = ` `; document.body.appendChild(itemDetailModal); }