"use client"; import { AlertTriangle, CheckCircle2, Loader2, Upload } from "lucide-react"; import { useMemo, useState } from "react"; import { toast } from "sonner"; import { createCatalogItem } from "@/actions/catalog-items"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; interface ParsedRow { lineNumber: number; raw: string; ok: boolean; error?: string; baseId?: number; credits?: number; points?: number; pointsType?: number; } interface BulkImportItemsProps { pageId: number; onImported?: () => void; } export function BulkImportItems({ pageId, onImported }: BulkImportItemsProps) { const [open, setOpen] = useState(false); const [input, setInput] = useState(""); const [importing, setImporting] = useState(false); const parsed = useMemo(() => { const lines = input.split("\n"); const out: ParsedRow[] = []; lines.forEach((raw, idx) => { const trimmed = raw.trim(); if (!trimmed || trimmed.startsWith("#")) return; const parts = trimmed.split(/[,\s;]+/).filter(Boolean); const baseId = parseInt(parts[0], 10); if (Number.isNaN(baseId) || baseId <= 0) { out.push({ lineNumber: idx + 1, raw: trimmed, ok: false, error: "Invalid base ID" }); return; } const credits = parts[1] !== undefined ? parseInt(parts[1], 10) : 0; const points = parts[2] !== undefined ? parseInt(parts[2], 10) : 0; const pointsType = parts[3] !== undefined ? parseInt(parts[3], 10) : 0; if ( (parts[1] !== undefined && Number.isNaN(credits)) || (parts[2] !== undefined && Number.isNaN(points)) ) { out.push({ lineNumber: idx + 1, raw: trimmed, ok: false, error: "Invalid number" }); return; } out.push({ lineNumber: idx + 1, raw: trimmed, ok: true, baseId, credits, points, pointsType, }); }); return out; }, [input]); const validCount = parsed.filter((r) => r.ok).length; const invalidCount = parsed.length - validCount; async function handleImport() { const valid = parsed.filter((r) => r.ok); if (valid.length === 0) { toast.error("No valid rows to import"); return; } setImporting(true); let success = 0; let failed = 0; for (const row of valid) { try { const res = await createCatalogItem({ pageId, itemIds: String(row.baseId!), catalogName: "", costCredits: row.credits ?? 0, costPoints: row.points ?? 0, pointsType: row.pointsType ?? 0, amount: 1, limitedSells: 0, limitedStack: 0, orderNumber: 1, offerId: -1, songId: 0, haveOffer: "1", clubOnly: "0", extradata: "", }); if (res.ok) success++; else failed++; } catch { failed++; } } setImporting(false); if (success > 0) { toast.success(`Imported ${success} item(s)${failed > 0 ? `, ${failed} failed` : ""}.`); setInput(""); setOpen(false); onImported?.(); } else { toast.error(`All ${failed} imports failed.`); } } return ( Bulk Import Items