updates in frontend based on product DB

This commit is contained in:
sriram
2026-08-17 15:33:17 +05:30
parent 2d1f8e4156
commit 8e219ca277

View File

@@ -8,7 +8,7 @@ import { ErrorBoundary } from '../components/ErrorBoundary';
import {
PlusCircle, Upload, CheckCircle2, Database, Sparkles,
RefreshCw, Search, FileSpreadsheet, Download, ShoppingBag,
Store, LayoutGrid, Filter, ArrowRight
Store, LayoutGrid, Filter, ArrowRight, AlertTriangle
} from 'lucide-react';
const STORES_SAMPLE = [
@@ -293,6 +293,16 @@ export function UserPage() {
setUploadingBatch(false);
if (data.added_products && Array.isArray(data.added_products)) {
// Re-read the brand from the API rather than trusting the response, so
// the panel below is showing what the database actually holds. A card
// built purely from the upload response is what made a failed import
// look successful.
const firstBrand = data.added_products[0]?.brand;
if (firstBrand) {
setBrandSearch(firstBrand);
fetchBrandCatalog(firstBrand);
}
const newBatchCards = data.added_products.map((item, idx) => ({
image_id: String(item.image_id || `batch_${Date.now()}_${idx}`),
product_name: String(item.product_name || 'Batch Product'),
@@ -421,6 +431,13 @@ export function UserPage() {
return Array.from(setB);
}, [allCardProducts]);
// A spreadsheet import can genuinely half-succeed, and that must not be
// painted the same green as a clean one - the whole complaint was a success
// panel over rows that never landed.
const batchHadErrors = Boolean(
batchResult && ((batchResult.error_count ?? 0) > 0 || batchResult.status === 'partial')
);
return (
<ErrorBoundary>
<div className="min-h-screen bg-paper-100 font-sans text-ink-950">
@@ -752,20 +769,78 @@ export function UserPage() {
)}
{batchResult && (
<div className="rounded-2xl border border-emerald-500/30 bg-emerald-50/70 p-6 shadow-sm space-y-3">
<div className="flex items-center gap-2 text-emerald-700">
<CheckCircle2 className="h-5 w-5" />
<h4 className="font-bold text-sm">Batch Products Processed</h4>
<div
className={`rounded-2xl border p-6 shadow-sm space-y-3 ${
batchHadErrors
? 'border-amber-500/40 bg-amber-50/70'
: 'border-emerald-500/30 bg-emerald-50/70'
}`}
>
<div className={`flex items-center gap-2 ${batchHadErrors ? 'text-amber-700' : 'text-emerald-700'}`}>
{batchHadErrors ? <AlertTriangle className="h-5 w-5" /> : <CheckCircle2 className="h-5 w-5" />}
<h4 className="font-bold text-sm">
{batchHadErrors ? 'Batch Partially Imported' : 'Batch Products Saved to Database'}
</h4>
</div>
<p className="text-xs text-slate-700">{batchResult.message}</p>
<button
type="button"
onClick={() => switchTab('cards')}
className="w-full flex items-center justify-center gap-2 py-2 px-3 rounded-xl bg-emerald-600 text-white font-bold text-xs shadow-sm hover:bg-emerald-700 transition cursor-pointer"
>
<ShoppingBag className="h-4 w-4" /> View Batch Items as Product Cards <ArrowRight className="h-3.5 w-3.5" />
</button>
{/* Counts, so "success" is never a claim without a number
behind it. added_count is the number of rows verified
present in the database, not the number attempted. */}
<div className="grid grid-cols-3 gap-2 text-center">
<div className="rounded-xl bg-white border border-emerald-200 py-2">
<p className="text-base font-extrabold text-emerald-700">{batchResult.added_count ?? 0}</p>
<p className="text-[10px] font-semibold text-slate-500 uppercase">Saved</p>
</div>
<div className="rounded-xl bg-white border border-rose-200 py-2">
<p className="text-base font-extrabold text-rose-700">{batchResult.error_count ?? 0}</p>
<p className="text-[10px] font-semibold text-slate-500 uppercase">Failed</p>
</div>
<div className="rounded-xl bg-white border border-slate-200 py-2">
<p className="text-base font-extrabold text-slate-700">{batchResult.skipped_blank_rows ?? 0}</p>
<p className="text-[10px] font-semibold text-slate-500 uppercase">Blank Rows</p>
</div>
</div>
{Array.isArray(batchResult.warnings) && batchResult.warnings.length > 0 && (
<ul className="space-y-1">
{batchResult.warnings.map((w, idx) => (
<li key={idx} className="flex items-start gap-1.5 text-[11px] text-amber-800">
<AlertTriangle className="h-3 w-3 shrink-0 mt-0.5" />
<span>{w}</span>
</li>
))}
</ul>
)}
{Array.isArray(batchResult.errors) && batchResult.errors.length > 0 && (
<div className="rounded-xl bg-white border border-rose-200 p-3 space-y-1 max-h-40 overflow-y-auto no-scrollbar">
<p className="text-[11px] font-bold text-rose-800">Rows that were not saved</p>
{batchResult.errors.map((e, idx) => (
<p key={idx} className="text-[11px] text-slate-600 font-mono">
{e.row ? `Row ${e.row}: ` : ''}
{e.product_name ? `${e.product_name} - ` : ''}
{e.error}
</p>
))}
{batchResult.errors_truncated > 0 && (
<p className="text-[11px] text-slate-400 italic">
+{batchResult.errors_truncated} more not shown
</p>
)}
</div>
)}
{(batchResult.added_count ?? 0) > 0 && (
<button
type="button"
onClick={() => switchTab('cards')}
className="w-full flex items-center justify-center gap-2 py-2 px-3 rounded-xl bg-emerald-600 text-white font-bold text-xs shadow-sm hover:bg-emerald-700 transition cursor-pointer"
>
<ShoppingBag className="h-4 w-4" /> View Batch Items as Product Cards <ArrowRight className="h-3.5 w-3.5" />
</button>
)}
</div>
)}