Basdat/web/js/pages/manager/ManagerReportFoundModal.js
2025-12-20 00:01:08 +07:00

321 lines
11 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.

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 ManagerReportFoundModal = ({
isOpen,
onClose,
onSubmit,
loading,
photoPreview,
onPhotoChange,
categories,
}) => {
const [users, setUsers] = React.useState([]);
const [loadingUsers, setLoadingUsers] = React.useState(false);
// ✅ ADD: State untuk menyimpan user yang dipilih
const [selectedUser, setSelectedUser] = React.useState(null);
// ✅ ADD: State untuk input manual
const [reporterName, setReporterName] = React.useState("");
const [reporterContact, setReporterContact] = React.useState("");
// Load users when modal opens
React.useEffect(() => {
if (isOpen) {
loadUsers();
// Reset form saat modal dibuka
setSelectedUser(null);
setReporterName("");
setReporterContact("");
}
}, [isOpen]);
const loadUsers = async () => {
try {
setLoadingUsers(true);
const response = await fetch(
`${CONFIG.API_URL}/api/manager/users?page=1&limit=1000`,
{
headers: {
Authorization: `Bearer ${AuthUtils.getToken()}`,
},
}
);
if (response.ok) {
const data = await response.json();
setUsers(data.data || []);
}
} catch (error) {
console.error("Failed to load users:", error);
} finally {
setLoadingUsers(false);
}
};
// ✅ UPDATE: Handle user selection
const handleUserSelect = (e) => {
const userId = e.target.value;
if (!userId) {
setSelectedUser(null);
return;
}
const user = users.find((u) => u.id === parseInt(userId));
if (user) {
setSelectedUser(user);
setReporterName(user.name);
setReporterContact(user.phone || "");
}
};
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title="📦 Laporan Barang Ditemukan (Offline)"
size="large"
>
<form onSubmit={onSubmit} className="space-y-4">
{/* Info Box */}
<div className="bg-blue-500/10 border-2 border-blue-500/30 p-4 rounded-xl">
<div className="flex items-start gap-3">
<span className="text-2xl"></span>
<div className="flex-1">
<strong className="text-blue-400 block mb-1">
Laporan Offline
</strong>
<p className="text-sm text-slate-300">
Fitur ini untuk mencatat barang yang diserahkan langsung kepada
manager. Jika pelapor memiliki akun, silakan pilih di bawah.
Jika tidak, cukup isi nama manual.
</p>
</div>
</div>
</div>
{/* User Selection */}
<div>
<label className="block font-semibold mb-2 text-slate-300">
Pilih User (Penemu Barang){" "}
<span className="text-slate-500 font-normal text-sm">
(Opsional)
</span>
</label>
<select
name="reporter_user_id"
onChange={handleUserSelect}
disabled={loadingUsers}
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white focus:border-blue-500 focus:outline-none"
>
<option value="">-- Tamu / Tidak Terdaftar --</option>
{users.map((user) => (
<option key={user.id} value={user.id}>
{user.name} - {user.email} ({user.nrp})
</option>
))}
</select>
<p className="text-xs text-slate-400 mt-1">
Pilih jika pelapor sudah punya akun. Jika belum, biarkan kosong.
</p>
</div>
{/* ✅ FIXED: Selected User Info - sekarang selectedUser sudah didefinisikan */}
{selectedUser && (
<div className="bg-green-500/10 border border-green-500/30 p-4 rounded-xl">
<strong className="text-green-400 block mb-2">
User Terpilih:
</strong>
<div className="grid grid-cols-2 gap-3 text-sm text-slate-300">
<div>
<strong className="text-slate-200">Nama:</strong>{" "}
{selectedUser.name}
</div>
<div>
<strong className="text-slate-200">Email:</strong>{" "}
{selectedUser.email}
</div>
<div>
<strong className="text-slate-200">NRP:</strong>{" "}
{selectedUser.nrp}
</div>
<div>
<strong className="text-slate-200">Telepon:</strong>{" "}
{selectedUser.phone || "-"}
</div>
</div>
</div>
)}
<div className="border-t border-slate-700 pt-4">
<h3 className="text-lg font-semibold text-white mb-4">
Detail Barang Ditemukan
</h3>
</div>
{/* Item Details */}
<div>
<label className="block font-semibold mb-2 text-slate-300">
Nama Barang *
</label>
<input
type="text"
name="name"
required
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Contoh: Dompet Kulit Coklat"
/>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Foto Barang
</label>
<input
type="file"
name="photo"
accept="image/*"
onChange={onPhotoChange}
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-blue-600 file:text-white hover:file:bg-blue-700 focus:outline-none"
/>
{photoPreview && (
<div className="mt-3">
<img
src={photoPreview}
alt="Preview"
className="w-full h-48 object-cover rounded-xl border-2 border-blue-500"
/>
</div>
)}
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Kategori *
</label>
<select
name="category_id"
required
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white focus:border-blue-500 focus:outline-none"
>
<option value="">Pilih Kategori</option>
{/* PERBAIKAN: Gunakan 'categories' langsung, bukan 'state.categories' */}
{categories &&
categories.map((cat) => (
<option key={cat.id} value={cat.id}>
{cat.name}
</option>
))}
</select>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Lokasi Ditemukan *
</label>
<input
type="text"
name="location"
required
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Contoh: Perpustakaan Lantai 2"
/>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Deskripsi Umum *
</label>
<textarea
name="description"
required
rows="3"
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Deskripsi umum barang yang akan ditampilkan..."
/>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Ciri Khusus Rahasia * 🔒
</label>
<textarea
name="secret_details"
required
rows="3"
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Jelaskan ciri khusus yang HANYA pemilik asli yang tahu (contoh: ada goresan di bagian belakang, ada tulisan nama di dalam, dll)"
/>
<p className="text-xs text-yellow-400 mt-1">
Info ini RAHASIA dan hanya digunakan untuk verifikasi klaim
</p>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Tanggal Ditemukan *
</label>
<input
type="date"
name="date_found"
required
max={new Date().toISOString().split("T")[0]}
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white focus:border-blue-500 focus:outline-none"
/>
</div>
{/* ✅ INPUT MANUAL dengan controlled state */}
<div>
<label className="block font-semibold mb-2 text-slate-300">
Nama Pelapor *
</label>
<input
type="text"
name="reporter_name"
required
value={reporterName}
onChange={(e) => setReporterName(e.target.value)}
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Nama lengkap penemu barang"
/>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Kontak Pelapor *
</label>
<input
type="text"
name="reporter_contact"
required
value={reporterContact}
onChange={(e) => setReporterContact(e.target.value)}
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="08123456789"
/>
</div>
<div>
<label className="block font-semibold mb-2 text-slate-300">
Catatan Manager (Opsional)
</label>
<textarea
name="manager_notes"
rows="2"
className="w-full px-4 py-3 bg-slate-700 border-2 border-slate-600 rounded-xl text-white placeholder-slate-400 focus:border-blue-500 focus:outline-none"
placeholder="Catatan internal dari manager..."
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full px-4 py-3 bg-gradient-to-r from-green-600 to-green-700 text-white rounded-xl hover:from-green-700 hover:to-green-800 transition font-semibold shadow-lg disabled:from-slate-600 disabled:to-slate-700"
>
{loading ? "⏳ Menyimpan..." : "✅ Submit Laporan"}
</button>
</form>
</Modal>
);
};
window.ManagerReportFoundModal = ManagerReportFoundModal;