"use client"; import { useState } from "react"; import { Upload, Plus, AlertCircle, CheckCircle2 } from "lucide-react"; import * as xlsx from "xlsx"; export default function AddImportPage() { const [formData, setFormData] = useState({ name: "", qrCodeId: "", quantity: 0, price: 0.0, category: "", description: "" }); const [loading, setLoading] = useState(false); const [status, setStatus] = useState({ type: "", message: "" }); const [importStats, setImportStats] = useState(null); const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handleManualSubmit = async (e) => { e.preventDefault(); setLoading(true); setStatus({ type: "", message: "" }); try { const payload = { ...formData, quantity: parseInt(formData.quantity) || 0, price: parseFloat(formData.price) || 0.0, }; const res = await fetch("/api/inventory", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to create item"); setStatus({ type: "success", message: `Successfully added ${data.name}.` }); setFormData({ name: "", qrCodeId: "", quantity: 0, price: 0.0, category: "", description: "" }); } catch (err) { setStatus({ type: "error", message: err.message }); } finally { setLoading(false); } }; const handleFileUpload = async (e) => { const file = e.target.files[0]; if (!file) return; setLoading(true); setStatus({ type: "", message: "" }); setImportStats(null); const reader = new FileReader(); reader.onload = async (evt) => { try { const bstr = evt.target.result; const wb = xlsx.read(bstr, { type: "binary" }); const wsname = wb.SheetNames[0]; const ws = wb.Sheets[wsname]; const data = xlsx.utils.sheet_to_json(ws); let successCount = 0; let errorCount = 0; for (const row of data) { try { // Normalize row keys to prevent trailing spaces or casing errors const normalizedRow = {}; for (const key in row) { if (row.hasOwnProperty(key)) { normalizedRow[key.trim().toLowerCase()] = row[key]; } } const payload = { qrCodeId: (normalizedRow["qr id"] || normalizedRow["qrcodeid"] || normalizedRow["id"] || normalizedRow["sku"])?.toString(), name: normalizedRow["name"] || normalizedRow["item"], quantity: parseInt(normalizedRow["quantity"] || normalizedRow["qty"]) || 0, price: parseFloat(normalizedRow["price"] || normalizedRow["cost"]) || 0.0, category: normalizedRow["category"] || "", description: normalizedRow["description"] || "", }; if (!payload.qrCodeId || !payload.name) { errorCount++; continue; } const res = await fetch("/api/inventory", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (res.ok) { successCount++; } else { errorCount++; } } catch (error) { errorCount++; } } setImportStats({ successCount, errorCount, total: data.length }); setStatus({ type: "success", message: `Import completed.` }); } catch (err) { setStatus({ type: "error", message: "Failed to parse or process the Excel file." }); } finally { setLoading(false); } }; reader.readAsBinaryString(file); e.target.value = ""; // reset file input }; return (
Upload an .xlsx file to bulk import inventory.
{status.message}
{importStats && (Total Items: {importStats.total}
Successful: {importStats.successCount}
Failed/Skipped: {importStats.errorCount}