function MobileSecondsSales({ salesUrl, token }) { const [form, setForm] = React.useState({ mobileName: '', model: '', imeNo: '', specification: '', mobileCondition: '', colour: '', sellerName: '', sellerAddress: '', referenceName: '', referenceNumber: '', reasonForSale: '', proofType: '', proofNo: '', valueOfProduct: '', paymentMethod: '' }); const [images, setImages] = React.useState([]); const [documents, setDocuments] = React.useState([]); const [signatures, setSignatures] = React.useState([]); const [banks, setBanks] = React.useState([]); const [entries, setEntries] = React.useState([]); const [mobileNameFilter, setMobileNameFilter] = React.useState(''); const [modelFilter, setModelFilter] = React.useState(''); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(''); const [success, setSuccess] = React.useState(''); const [showAlert, setShowAlert] = React.useState(false); const [activeSection, setActiveSection] = React.useState('create'); // create | list React.useEffect(() => { if (!error && !success) { setShowAlert(false); return; } setShowAlert(true); const t = setTimeout(() => setShowAlert(false), 3500); return () => clearTimeout(t); }, [error, success]); async function loadEntries() { try { const res = await fetch((salesUrl || '') + '/api/seconds-sales', { headers: { Authorization: token ? 'Bearer ' + token : '' } }); const data = await res.json(); if (!res.ok) throw new Error(data.message || 'Failed to load'); setEntries(Array.isArray(data.rows) ? data.rows : []); } catch (err) { console.error('loadEntries error', err); setError(err.message || 'Failed to load entries'); } } async function loadBanks() { try { const res = await fetch((salesUrl || '') + '/api/banks', { headers: { Authorization: token ? 'Bearer ' + token : '' } }); const data = await res.json(); if (!res.ok) throw new Error(data.message || 'Failed to load banks'); setBanks(Array.isArray(data.banks) ? data.banks : []); } catch (err) { console.error('loadBanks error', err); setBanks([]); } } React.useEffect(() => { loadEntries(); loadBanks(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); function onChange(e) { const { name, value } = e.target; setForm((f) => ({ ...f, [name]: value })); } function toBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(file); }); } async function handleFiles(e, setter) { const files = Array.from(e.target.files || []); if (!files.length) return; setLoading(true); try { const arr = await Promise.all(files.map(async (f) => ({ name: f.name, base64: await toBase64(f) }))); setter((prev) => [...prev, ...arr]); } catch (err) { console.error(err); setError('Failed to read files'); } finally { setLoading(false); } } async function submit(e) { e.preventDefault(); setError(''); setSuccess(''); setLoading(true); try { const payload = { ...form, images, documents, signatures, bank_id: form.paymentMethod || '' }; const res = await fetch((salesUrl || '') + '/api/seconds-sales', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: token ? 'Bearer ' + token : '' }, body: JSON.stringify(payload) }); const data = await res.json(); if (!res.ok) throw new Error(data.message || data.error || 'Save failed'); setSuccess('Saved successfully'); setForm({ mobileName: '', model: '', imeNo: '', specification: '', mobileCondition: '', colour: '', sellerName: '', sellerAddress: '', referenceName: '', referenceNumber: '', reasonForSale: '', proofType: '', proofNo: '', valueOfProduct: '', paymentMethod: '' }); setImages([]); setDocuments([]); setSignatures([]); await loadEntries(); setActiveSection('list'); } catch (err) { setError(err.message || 'Save failed'); } finally { setLoading(false); } } function resetForm() { setForm({ mobileName: '', model: '', imeNo: '', specification: '', mobileCondition: '', colour: '', sellerName: '', sellerAddress: '', referenceName: '', referenceNumber: '', reasonForSale: '', proofType: '', proofNo: '', valueOfProduct: '', paymentMethod: '' }); setImages([]); setDocuments([]); setSignatures([]); } function isSold(entry) { return Array.isArray(entry.purchases) && entry.purchases.length > 0; } const filteredEntries = React.useMemo(() => { return (entries || []).filter((r) => { return ( (!mobileNameFilter || (r.mobileName || '').toLowerCase().includes(mobileNameFilter.toLowerCase())) && (!modelFilter || (r.model || '').toLowerCase().includes(modelFilter.toLowerCase())) ); }); }, [entries, mobileNameFilter, modelFilter]); const sortedEntries = React.useMemo(() => { return [...filteredEntries.filter((e) => !isSold(e)), ...filteredEntries.filter((e) => isSold(e))]; }, [filteredEntries]); const selectedBank = form.paymentMethod ? banks.find((b) => b._id === form.paymentMethod) : null; const SectionButton = ({ id, label, count }) => ( ); return (