Add bulkCsvFile/bulkZipFile fields and handleBulkUploadSubmit to support ZIP archive uploads in frontend
This commit is contained in:
parent
b924a30af7
commit
6e5e175689
1 changed files with 82 additions and 41 deletions
123
src/App.tsx
123
src/App.tsx
|
|
@ -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' }}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue