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 (

📱 Seconds Sales - Create New Entry

Fill in the mobile device details and seller information

{/* Mobile Details Section */}

📋 Mobile Device Information

e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
e.target.style.borderColor = '#667eea'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
{/* Seller Information Section */}

👤 Seller Information

e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
e.target.style.borderColor = '#ea580c'} onBlur={(e) => e.target.style.borderColor = '#fed7aa'} />
{/* Payment & Proof Section */}

💰 Payment & Proof Details

e.target.style.borderColor = '#15803d'} onBlur={(e) => e.target.style.borderColor = '#bbf7d0'} />
e.target.style.borderColor = '#15803d'} onBlur={(e) => e.target.style.borderColor = '#bbf7d0'} />
{form.paymentMethod ? (
💳 Selected balance: ₹{Number((banks.find(x=>x._id===form.paymentMethod)||{}).accountBalance||0).toFixed(2)}
) : null}
{/* File Upload Section */}

📎 File Attachments

handleFiles(e, setImages)} style={{ width: '100%', padding: '12px', border: '2px dashed #d8b4fe', borderRadius: '8px', fontSize: '14px', backgroundColor: 'white', cursor: 'pointer' }} /> {images.length > 0 && (
✓ {images.length} image{images.length !== 1 ? 's' : ''} selected
)}
handleFiles(e, setDocuments)} style={{ width: '100%', padding: '12px', border: '2px dashed #d8b4fe', borderRadius: '8px', fontSize: '14px', backgroundColor: 'white', cursor: 'pointer' }} /> {documents.length > 0 && (
✓ {documents.length} document{documents.length !== 1 ? 's' : ''} selected
)}
handleFiles(e, setSignatures)} style={{ width: '100%', padding: '12px', border: '2px dashed #d8b4fe', borderRadius: '8px', fontSize: '14px', backgroundColor: 'white', cursor: 'pointer' }} /> {signatures.length > 0 && (
✓ {signatures.length} signature{signatures.length !== 1 ? 's' : ''} selected
)}
{/* Action Buttons */}
{/* Status Messages */} {error ? (
⚠️ {error}
) : null} {success ? (
✅ {success}
) : null}
{/*
Selected Files
Images:
    {images.map((f,i) =>
  • {f.name}
  • )}
Documents:
    {documents.map((f,i) =>
  • {f.name}
  • )}
Signatures:
    {signatures.map((f,i) =>
  • {f.name}
  • )}
*/}

📊 Saved Entries ({sortedEntries.length})

Manage and view all mobile device entries

{/* Enhanced Filter Section */}
🔍 Filters:
setMobileNameFilter(e.target.value)} style={{ padding: '10px 16px', width: '200px', border: '2px solid #e2e8f0', borderRadius: '8px', fontSize: '14px', transition: 'all 0.2s ease' }} onFocus={(e) => e.target.style.borderColor = '#4f46e5'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
setModelFilter(e.target.value)} style={{ padding: '10px 16px', width: '200px', border: '2px solid #e2e8f0', borderRadius: '8px', fontSize: '14px', transition: 'all 0.2s ease' }} onFocus={(e) => e.target.style.borderColor = '#4f46e5'} onBlur={(e) => e.target.style.borderColor = '#e2e8f0'} />
{(mobileNameFilter || modelFilter) && ( )}
{sortedEntries.length === 0 ? (
📱

No Entries Found

{(mobileNameFilter || modelFilter) ? 'Try adjusting your search filters' : 'Start by creating your first mobile entry above' }

) : ( {sortedEntries.map((r, i) => ( { e.currentTarget.style.backgroundColor = isSold(r) ? '#fee2e2' : '#f8fafc'; e.currentTarget.style.transform = 'translateX(2px)'; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = isSold(r) ? '#fef2f2' : 'white'; e.currentTarget.style.transform = 'translateX(0px)'; }} onClick={() => { try { location.hash = '#seconds-sales-view-' + (r._id || i); } catch {} }} > ))}
# 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 )}
)}
); } window.SecondsSales = SecondsSales;