Add bulkCsvFile/bulkZipFile fields and handleBulkUploadSubmit to support ZIP archive uploads in frontend
All checks were successful
Beta CI/CD Pipeline / build-and-test (push) Successful in 45s
Beta CI/CD Pipeline / deploy-beta (push) Successful in 6s

This commit is contained in:
vickytechkey 2026-08-12 20:30:52 +05:30
parent b924a30af7
commit 6e5e175689

View file

@ -276,9 +276,11 @@ export default function App() {
.catch(err => console.error(err)) .catch(err => console.error(err))
} }
// Bulk Upload simulations // Bulk Upload
const [bulkLog, setBulkLog] = useState<string[]>([]) const [bulkLog, setBulkLog] = useState<string[]>([])
const [isParsingBulk, setIsParsingBulk] = useState(false) const [isParsingBulk, setIsParsingBulk] = useState(false)
const [bulkCsvFile, setBulkCsvFile] = useState<File | null>(null)
const [bulkZipFile, setBulkZipFile] = useState<File | null>(null)
// GSTIN verification simulator // GSTIN verification simulator
const handleVerifyGstin = () => { const handleVerifyGstin = () => {
@ -625,45 +627,56 @@ export default function App() {
} }
} }
// Bulk parser simulation const handleBulkUploadSubmit = async (e: React.FormEvent) => {
const handleBulkUploadSimulate = (e: React.ChangeEvent<HTMLInputElement>) => { e.preventDefault();
if (!e.target.files?.length) return if (!bulkCsvFile) {
setIsParsingBulk(true) alert("Please select a CSV file to upload.");
setBulkLog(['Parsing CSV file template...', 'Validating rows against inventory Schema...']) return;
}
setIsParsingBulk(true);
setBulkLog(['Uploading files to server...', 'Parsing CSV data and extracting ZIP images...']);
const mockBulkProducts = [ const formData = new FormData();
{ title: 'Hand-Carved Walnut Bowl', category: 'Kitchenware', price: '65.00', stock: 15, sku: 'BOWL-WAL-12' }, formData.append('csv_file', bulkCsvFile);
{ title: 'Organic Cotton Tablecloth', category: 'Linens', price: '48.00', stock: 30, sku: 'LINE-COT-15' } if (bulkZipFile) {
] formData.append('zip_file', bulkZipFile);
}
setTimeout(() => { try {
apiFetch(`${CONFIG.apiBaseUrl}/api/products/bulk-upload/`, { const token = localStorage.getItem('access_token');
const response = await fetch(`${CONFIG.apiBaseUrl}/api/products/bulk-upload/`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: {
body: JSON.stringify({ products: mockBulkProducts }) ...(token ? { 'Authorization': `Bearer ${token}` } : {})
}) },
.then(res => res.json()) body: formData
.then(() => { });
setBulkLog(prev => [
...prev, const data = await response.json();
'Row 1: Verified SKU BOWL-WAL-12 - Added', if (!response.ok) {
'Row 2: Verified SKU LINE-COT-15 - Added', throw new Error(data.error || 'Failed to complete bulk upload.');
'Successfully added 2 new listings bulk!' }
])
// Refresh products setBulkLog([
apiFetch(`${CONFIG.apiBaseUrl}/api/products/`) 'CSV file parsed successfully.',
.then(r => r.json()) `Extracted and matched images for SKUs from ZIP file.`,
.then(prods => { `Successfully added ${data.products?.length || 0} product listings!`,
setProducts(prods) ]);
setIsParsingBulk(false)
}) // Refresh product list
}) const prodRes = await apiFetch(`${CONFIG.apiBaseUrl}/api/products/`);
.catch(() => { const prods = await prodRes.json();
setBulkLog(prev => [...prev, 'Error during upload to server.']) if (Array.isArray(prods)) {
setIsParsingBulk(false) setProducts(prods);
}) }
}, 1500) setBulkCsvFile(null);
} setBulkZipFile(null);
} catch (err: any) {
setBulkLog(prev => [...prev, `Error: ${err.message}`]);
} finally {
setIsParsingBulk(false);
}
};
// Wallet outstanding requests // Wallet outstanding requests
const handleWithdrawRequest = (e: React.FormEvent) => { const handleWithdrawRequest = (e: React.FormEvent) => {
@ -1983,10 +1996,38 @@ export default function App() {
</button> </button>
</div> </div>
<div className="bulk-drop-zone" onClick={() => document.getElementById('bulk-file-pick')?.click()}> <form onSubmit={handleBulkUploadSubmit} style={{ marginTop: '1.5rem' }}>
<span>{isParsingBulk ? 'Processing bulk data...' : '📂 Click or drop your populated template file here to import'}</span> <div className="form-group" style={{ marginBottom: '1rem' }}>
<input id="bulk-file-pick" type="file" accept=".csv" onChange={handleBulkUploadSimulate} style={{ display: 'none' }} /> <label style={{ fontWeight: 'bold', fontSize: '0.85rem' }}>1. Upload Populated Template (.csv) *</label>
</div> <input
type="file"
accept=".csv"
onChange={(e) => setBulkCsvFile(e.target.files?.[0] || null)}
style={{ display: 'block', marginTop: '0.5rem', width: '100%', padding: '0.5rem', border: '1px solid var(--border)', borderRadius: '6px' }}
/>
{bulkCsvFile && <span style={{ fontSize: '0.8rem', color: 'green', display: 'block', marginTop: '0.25rem' }}> Selected: {bulkCsvFile.name}</span>}
</div>
<div className="form-group" style={{ marginBottom: '1.5rem' }}>
<label style={{ fontWeight: 'bold', fontSize: '0.85rem' }}>2. Upload Image Archive (.zip) - Optional</label>
<input
type="file"
accept=".zip"
onChange={(e) => setBulkZipFile(e.target.files?.[0] || null)}
style={{ display: 'block', marginTop: '0.5rem', width: '100%', padding: '0.5rem', border: '1px solid var(--border)', borderRadius: '6px' }}
/>
{bulkZipFile && <span style={{ fontSize: '0.8rem', color: 'green', display: 'block', marginTop: '0.25rem' }}> Selected: {bulkZipFile.name}</span>}
</div>
<button
type="submit"
className="btn btn-primary"
style={{ width: '100%', padding: '0.75rem', backgroundColor: 'var(--primary)', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer' }}
disabled={isParsingBulk || !bulkCsvFile}
>
{isParsingBulk ? 'Uploading & Processing...' : '🚀 Start Bulk Import'}
</button>
</form>
{bulkLog.length > 0 && ( {bulkLog.length > 0 && (
<div style={{ backgroundColor: '#f1f5f9', padding: '1rem', borderRadius: '8px', fontFamily: 'monospace', fontSize: '0.85rem', marginTop: '1rem' }}> <div style={{ backgroundColor: '#f1f5f9', padding: '1rem', borderRadius: '8px', fontFamily: 'monospace', fontSize: '0.85rem', marginTop: '1rem' }}>