Harden catalog writes: bulk import batch + field allowlists.
Local Build and Deploy / deploy (push) Successful in 1m16s
Local Build and Deploy / deploy (push) Successful in 1m16s
Bulk import resolves names from items_base and refreshes RCON once. Page/item updates only accept an allowlisted field set. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
b52e25578d
commit
2ff5b47104
4 files changed
+288
-50
No files matched your search
@@ -3,7 +3,7 @@
|
||||
import { AlertTriangle, CheckCircle2, Loader2, Upload } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { createCatalogItem } from "@/actions/catalog-items";
|
||||
import { bulkCreateCatalogItems } from "@/actions/catalog-items";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
@@ -91,43 +91,39 @@ export function BulkImportItems({ pageId, onImported }: BulkImportItemsProps) {
|
||||
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++;
|
||||
try {
|
||||
const res = await bulkCreateCatalogItems({
|
||||
pageId,
|
||||
rows: valid.map((row) => ({
|
||||
baseId: row.baseId!,
|
||||
credits: row.credits,
|
||||
points: row.points,
|
||||
pointsType: row.pointsType,
|
||||
})),
|
||||
});
|
||||
if (!res.ok) {
|
||||
toast.error(res.error || "Bulk import failed.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
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.`);
|
||||
const { created, failed } = res.data;
|
||||
if (created > 0) {
|
||||
toast.success(
|
||||
`Imported ${created} item(s)${failed > 0 ? `, ${failed} failed` : ""}.`,
|
||||
);
|
||||
setInput("");
|
||||
setOpen(false);
|
||||
onImported?.();
|
||||
} else {
|
||||
toast.error(
|
||||
failed > 0
|
||||
? `All ${failed} imports failed (unknown base IDs?).`
|
||||
: "Nothing imported.",
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
toast.error("Bulk import failed.");
|
||||
} finally {
|
||||
setImporting(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user