function SecondsSales({ 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 [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(''); const [success, setSuccess] = React.useState(''); const [entries, setEntries] = React.useState([]); const [banks, setBanks] = React.useState([]); const [selectedBankId, setSelectedBankId] = React.useState(''); const [selectedBankBalance, setSelectedBankBalance] = React.useState(0); const [mobileNameFilter, setMobileNameFilter] = React.useState(''); const [modelFilter, setModelFilter] = React.useState(''); async function loadEntries() { try { const res = await fetch((salesUrl || '') + '/api/seconds-sales', { headers: { Authorization: token ? ('Bearer ' + token) : '' } }); console.log("sales",res); 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); } } React.useEffect(() => { loadEntries(); }, []); React.useEffect(() => { loadBanks(); }, []); 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); } } 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(); } catch (err) { setError(err.message || 'Save failed'); } finally { setLoading(false); } } // Filtering logic for entries 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]); // Helper to check if a mobile is sold function isSold(entry) { return Array.isArray(entry.purchases) && entry.purchases.length > 0; } // Sort: unsold first, sold last const sortedEntries = [ ...filteredEntries.filter(e => !isSold(e)), ...filteredEntries.filter(e => isSold(e)) ]; return (
Fill in the mobile device details and seller information
Manage and view all mobile device entries
{(mobileNameFilter || modelFilter) ? 'Try adjusting your search filters' : 'Start by creating your first mobile entry above' }
| # | Mobile Info | IMEI | Seller | Price | Files | Date | Status |
|---|---|---|---|---|---|---|---|
| {i + 1} |
{r.mobileName || '-'}
{r.model || 'Model not specified'}
|
{r.imeNo || '-'}
|
{r.sellerName || '-'} | ₹{Number(r.valueOfProduct || 0).toFixed(2)} | 📎 {((r.images || []).length + (r.documents || []).length + (r.signatures || []).length) || 0} |
{new Date(r.createdAt || Date.now()).toLocaleDateString('en-IN', {
day: '2-digit',
month: 'short',
year: 'numeric'
})}
{new Date(r.createdAt || Date.now()).toLocaleTimeString('en-IN', { hour: '2-digit', minute: '2-digit' })} |
{isSold(r) ? ( 🔴 SOLD ) : ( 🟢 AVAILABLE )} |