sa2kit 1.6.70 → 1.6.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/festivalCard/core/index.d.mts +1 -1
  2. package/dist/festivalCard/core/index.d.ts +1 -1
  3. package/dist/festivalCard/core/index.js +4 -2
  4. package/dist/festivalCard/core/index.js.map +1 -1
  5. package/dist/festivalCard/core/index.mjs +4 -2
  6. package/dist/festivalCard/core/index.mjs.map +1 -1
  7. package/dist/festivalCard/index.d.mts +2 -2
  8. package/dist/festivalCard/index.d.ts +2 -2
  9. package/dist/festivalCard/index.js +118 -155
  10. package/dist/festivalCard/index.js.map +1 -1
  11. package/dist/festivalCard/index.mjs +118 -155
  12. package/dist/festivalCard/index.mjs.map +1 -1
  13. package/dist/festivalCard/miniapp/index.d.mts +3 -3
  14. package/dist/festivalCard/miniapp/index.d.ts +3 -3
  15. package/dist/festivalCard/miniapp/index.js +21 -15
  16. package/dist/festivalCard/miniapp/index.js.map +1 -1
  17. package/dist/festivalCard/miniapp/index.mjs +21 -15
  18. package/dist/festivalCard/miniapp/index.mjs.map +1 -1
  19. package/dist/festivalCard/routes/index.d.mts +13 -16
  20. package/dist/festivalCard/routes/index.d.ts +13 -16
  21. package/dist/festivalCard/routes/index.js +14 -5
  22. package/dist/festivalCard/routes/index.js.map +1 -1
  23. package/dist/festivalCard/routes/index.mjs +14 -5
  24. package/dist/festivalCard/routes/index.mjs.map +1 -1
  25. package/dist/festivalCard/server/index.d.mts +1 -1
  26. package/dist/festivalCard/server/index.d.ts +1 -1
  27. package/dist/festivalCard/web/index.d.mts +3 -3
  28. package/dist/festivalCard/web/index.d.ts +3 -3
  29. package/dist/festivalCard/web/index.js +118 -155
  30. package/dist/festivalCard/web/index.js.map +1 -1
  31. package/dist/festivalCard/web/index.mjs +118 -155
  32. package/dist/festivalCard/web/index.mjs.map +1 -1
  33. package/dist/{festivalCardService-CgNBOjjO.d.mts → festivalCardService-CqBTVC6x.d.mts} +1 -1
  34. package/dist/{festivalCardService-ClJiAP6P.d.ts → festivalCardService-iFKu0k9q.d.ts} +1 -1
  35. package/dist/index.d.mts +2 -2
  36. package/dist/index.d.ts +2 -2
  37. package/dist/index.js +118 -155
  38. package/dist/index.js.map +1 -1
  39. package/dist/index.mjs +118 -155
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/{types-COyg0XDw.d.mts → types-D2WetAPc.d.mts} +1 -0
  42. package/dist/{types-COyg0XDw.d.ts → types-D2WetAPc.d.ts} +1 -0
  43. package/package.json +1 -1
@@ -61,7 +61,8 @@ var DEFAULT_FESTIVAL_CARD_CONFIG = {
61
61
  src: "https://images.unsplash.com/photo-1512389142860-9c449e58a543?auto=format&fit=crop&w=1200&q=80",
62
62
  fit: "cover",
63
63
  borderRadius: 16,
64
- alt: "holiday"
64
+ alt: "holiday",
65
+ isBackground: false
65
66
  }
66
67
  ]
67
68
  },
@@ -120,7 +121,8 @@ var DEFAULT_FESTIVAL_CARD_CONFIG = {
120
121
  src: "https://images.unsplash.com/photo-1456324504439-367cee3b3c32?auto=format&fit=crop&w=1200&q=80",
121
122
  fit: "cover",
122
123
  borderRadius: 14,
123
- alt: "gift"
124
+ alt: "gift",
125
+ isBackground: false
124
126
  },
125
127
  {
126
128
  id: "p3-text-1",
@@ -186,9 +188,10 @@ var useFestivalCardConfig = (options) => {
186
188
  const [loading, setLoading] = React3.useState(Boolean(options?.fetchConfig));
187
189
  const [saving, setSaving] = React3.useState(false);
188
190
  React3.useEffect(() => {
189
- if (!options?.fetchConfig) return;
191
+ const fetchConfig = options?.fetchConfig;
192
+ if (!fetchConfig) return;
190
193
  let active = true;
191
- void options.fetchConfig().then((value) => {
194
+ void fetchConfig().then((value) => {
192
195
  if (!active) return;
193
196
  setConfig(normalizeFestivalCardConfig(value));
194
197
  }).finally(() => {
@@ -197,16 +200,17 @@ var useFestivalCardConfig = (options) => {
197
200
  return () => {
198
201
  active = false;
199
202
  };
200
- }, [options]);
203
+ }, [options?.fetchConfig]);
201
204
  const save = React3.useCallback(async () => {
202
- if (!options?.onSave) return;
205
+ const onSave = options?.onSave;
206
+ if (!onSave) return;
203
207
  setSaving(true);
204
208
  try {
205
- await options.onSave(config);
209
+ await onSave(config);
206
210
  } finally {
207
211
  setSaving(false);
208
212
  }
209
- }, [config, options]);
213
+ }, [config, options?.onSave]);
210
214
  return React3.useMemo(
211
215
  () => ({
212
216
  config,
@@ -220,6 +224,7 @@ var useFestivalCardConfig = (options) => {
220
224
  };
221
225
  var elementStyle = (element) => ({
222
226
  position: "absolute",
227
+ zIndex: 2,
223
228
  left: `${element.x}%`,
224
229
  top: `${element.y}%`,
225
230
  width: `${element.width ?? 70}%`,
@@ -262,22 +267,23 @@ var renderElement = (element) => {
262
267
  );
263
268
  };
264
269
  var FestivalCardPageRenderer = ({ page }) => {
270
+ const backgroundElement = page.elements.find(
271
+ (element) => element.type === "image" && Boolean(element.isBackground)
272
+ );
273
+ const foregroundElements = page.elements.filter((element) => !(element.type === "image" && element.isBackground));
265
274
  return /* @__PURE__ */ React3__default.default.createElement(
266
275
  "div",
267
276
  {
277
+ className: "relative h-full w-full overflow-hidden rounded-2xl",
268
278
  style: {
269
- position: "relative",
270
- width: "100%",
271
- height: "100%",
272
- overflow: "hidden",
273
- borderRadius: 16,
274
279
  backgroundColor: page.background?.color || "#0f172a",
275
- backgroundImage: page.background?.image ? `url(${page.background.image})` : void 0,
280
+ backgroundImage: backgroundElement ? `url(${backgroundElement.src})` : page.background?.image ? `url(${page.background.image})` : void 0,
276
281
  backgroundSize: "cover",
277
282
  backgroundPosition: "center"
278
283
  }
279
284
  },
280
- page.elements.map(renderElement)
285
+ /* @__PURE__ */ React3__default.default.createElement("div", { className: "absolute inset-0 bg-slate-950/20" }),
286
+ foregroundElements.map(renderElement)
281
287
  );
282
288
  };
283
289
 
@@ -291,100 +297,31 @@ var FestivalCardBook3D = ({ config, className }) => {
291
297
  return /* @__PURE__ */ React3__default.default.createElement("div", { className }, /* @__PURE__ */ React3__default.default.createElement(
292
298
  "div",
293
299
  {
300
+ className: "w-full min-h-[560px] rounded-3xl p-6 shadow-2xl shadow-slate-900/50",
294
301
  style: {
295
- width: "100%",
296
- minHeight: 560,
297
- borderRadius: 24,
298
- padding: 24,
299
- background: `linear-gradient(145deg, ${normalized.background?.colorA || "#0c1a34"} 0%, ${normalized.background?.colorB || "#1f4f8a"} 100%)`,
300
- boxShadow: "0 26px 70px rgba(2, 6, 23, 0.45)"
302
+ background: `linear-gradient(145deg, ${normalized.background?.colorA || "#0c1a34"} 0%, ${normalized.background?.colorB || "#1f4f8a"} 100%)`
301
303
  }
302
304
  },
303
- /* @__PURE__ */ React3__default.default.createElement(
304
- "div",
305
- {
306
- style: {
307
- marginBottom: 14,
308
- color: "#f8fafc",
309
- fontSize: 14,
310
- opacity: 0.9,
311
- textAlign: "center"
312
- }
313
- },
314
- normalized.coverTitle || "Festival Card",
315
- " \xB7 \u7B2C ",
316
- currentPage + 1,
317
- " / ",
318
- pages.length,
319
- " \u9875"
320
- ),
321
- /* @__PURE__ */ React3__default.default.createElement("div", { style: { perspective: 1400, width: "100%", maxWidth: 920, margin: "0 auto" } }, /* @__PURE__ */ React3__default.default.createElement(
305
+ /* @__PURE__ */ React3__default.default.createElement("div", { className: "mx-auto w-full max-w-5xl text-center text-slate-100" }, /* @__PURE__ */ React3__default.default.createElement("h3", { className: "mb-4 text-lg font-semibold" }, normalized.coverTitle || "Festival Card")),
306
+ /* @__PURE__ */ React3__default.default.createElement("div", { className: "mx-auto w-full max-w-5xl" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "relative h-[460px]" }, pages.map((page, index) => /* @__PURE__ */ React3__default.default.createElement(
322
307
  "div",
323
308
  {
309
+ key: page.id,
310
+ className: "absolute inset-0 transition-opacity duration-500 ease-out",
324
311
  style: {
325
- position: "relative",
326
- height: 460,
327
- transformStyle: "preserve-3d"
312
+ opacity: index === currentPage ? 1 : 0,
313
+ pointerEvents: index === currentPage ? "auto" : "none"
328
314
  }
329
315
  },
330
- pages.map((page, index) => {
331
- const isFlipped = index < currentPage;
332
- const zIndex = pages.length - index;
333
- return /* @__PURE__ */ React3__default.default.createElement(
334
- "div",
335
- {
336
- key: page.id,
337
- style: {
338
- position: "absolute",
339
- inset: 0,
340
- transformStyle: "preserve-3d",
341
- transformOrigin: "left center",
342
- transform: `rotateY(${isFlipped ? -170 : 0}deg)`,
343
- transition: "transform 600ms cubic-bezier(0.2, 0.8, 0.2, 1)",
344
- zIndex
345
- }
346
- },
347
- /* @__PURE__ */ React3__default.default.createElement(
348
- "div",
349
- {
350
- style: {
351
- position: "absolute",
352
- inset: 0,
353
- backfaceVisibility: "hidden"
354
- }
355
- },
356
- /* @__PURE__ */ React3__default.default.createElement(FestivalCardPageRenderer, { page })
357
- ),
358
- /* @__PURE__ */ React3__default.default.createElement(
359
- "div",
360
- {
361
- style: {
362
- position: "absolute",
363
- inset: 0,
364
- transform: "rotateY(180deg)",
365
- backfaceVisibility: "hidden",
366
- borderRadius: 16,
367
- background: "#0f172a"
368
- }
369
- }
370
- )
371
- );
372
- })
373
- )),
374
- /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "flex", justifyContent: "center", gap: 12, marginTop: 18 } }, /* @__PURE__ */ React3__default.default.createElement(
316
+ /* @__PURE__ */ React3__default.default.createElement(FestivalCardPageRenderer, { page })
317
+ )))),
318
+ /* @__PURE__ */ React3__default.default.createElement("div", { className: "mt-5 flex justify-center gap-3" }, /* @__PURE__ */ React3__default.default.createElement(
375
319
  "button",
376
320
  {
377
321
  type: "button",
378
322
  disabled: !canPrev,
379
323
  onClick: () => setCurrentPage((p) => Math.max(0, p - 1)),
380
- style: {
381
- border: "none",
382
- borderRadius: 999,
383
- padding: "9px 16px",
384
- fontSize: 14,
385
- cursor: canPrev ? "pointer" : "not-allowed",
386
- opacity: canPrev ? 1 : 0.4
387
- }
324
+ className: "rounded-full bg-white px-5 py-2 text-sm font-medium text-slate-900 disabled:cursor-not-allowed disabled:opacity-45"
388
325
  },
389
326
  "\u4E0A\u4E00\u9875"
390
327
  ), /* @__PURE__ */ React3__default.default.createElement(
@@ -393,14 +330,7 @@ var FestivalCardBook3D = ({ config, className }) => {
393
330
  type: "button",
394
331
  disabled: !canNext,
395
332
  onClick: () => setCurrentPage((p) => Math.min(pages.length - 1, p + 1)),
396
- style: {
397
- border: "none",
398
- borderRadius: 999,
399
- padding: "9px 16px",
400
- fontSize: 14,
401
- cursor: canNext ? "pointer" : "not-allowed",
402
- opacity: canNext ? 1 : 0.4
403
- }
333
+ className: "rounded-full bg-sky-300 px-5 py-2 text-sm font-medium text-slate-900 disabled:cursor-not-allowed disabled:opacity-45"
404
334
  },
405
335
  "\u4E0B\u4E00\u9875"
406
336
  ))
@@ -411,7 +341,7 @@ var FestivalCardBook3D = ({ config, className }) => {
411
341
  autoPlay: normalized.backgroundMusic.autoPlay,
412
342
  loop: normalized.backgroundMusic.loop,
413
343
  controls: true,
414
- style: { width: "100%", marginTop: 10 }
344
+ className: "mt-3 w-full"
415
345
  }
416
346
  ) : null);
417
347
  };
@@ -453,16 +383,17 @@ var FestivalCardConfigEditor = ({ value, onChange }) => {
453
383
  )
454
384
  });
455
385
  };
456
- return /* @__PURE__ */ React3__default.default.createElement("div", { style: { borderRadius: 16, background: "#0f172a", color: "#e2e8f0", padding: 16 } }, /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gap: 12 } }, /* @__PURE__ */ React3__default.default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React3__default.default.createElement("span", null, "\u9875\u9762\u6570\u91CF"), /* @__PURE__ */ React3__default.default.createElement(
386
+ return /* @__PURE__ */ React3__default.default.createElement("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 text-slate-900 shadow-sm" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "grid gap-3" }, /* @__PURE__ */ React3__default.default.createElement("label", { className: "grid gap-1.5" }, /* @__PURE__ */ React3__default.default.createElement("span", { className: "text-sm font-medium text-slate-700" }, "\u9875\u9762\u6570\u91CF"), /* @__PURE__ */ React3__default.default.createElement(
457
387
  "input",
458
388
  {
459
389
  type: "number",
460
390
  min: 1,
461
391
  max: 12,
462
392
  value: value.pages.length,
463
- onChange: (event) => onChange(resizeFestivalCardPages(value, Number(event.target.value)))
393
+ onChange: (event) => onChange(resizeFestivalCardPages(value, Number(event.target.value))),
394
+ className: "rounded-lg border border-slate-300 bg-white px-3 py-2 text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
464
395
  }
465
- )), /* @__PURE__ */ React3__default.default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React3__default.default.createElement("span", null, "\u80CC\u666F\u97F3\u4E50 URL"), /* @__PURE__ */ React3__default.default.createElement(
396
+ )), /* @__PURE__ */ React3__default.default.createElement("label", { className: "grid gap-1.5" }, /* @__PURE__ */ React3__default.default.createElement("span", { className: "text-sm font-medium text-slate-700" }, "\u80CC\u666F\u97F3\u4E50 URL"), /* @__PURE__ */ React3__default.default.createElement(
466
397
  "input",
467
398
  {
468
399
  type: "url",
@@ -473,9 +404,18 @@ var FestivalCardConfigEditor = ({ value, onChange }) => {
473
404
  ...value.backgroundMusic,
474
405
  src: event.target.value
475
406
  }
476
- })
407
+ }),
408
+ className: "rounded-lg border border-slate-300 bg-white px-3 py-2 text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
477
409
  }
478
- )), /* @__PURE__ */ React3__default.default.createElement("label", { style: { display: "grid", gap: 6 } }, /* @__PURE__ */ React3__default.default.createElement("span", null, "\u7F16\u8F91\u9875\u9762"), /* @__PURE__ */ React3__default.default.createElement("select", { value: activePageIndex, onChange: (event) => setActivePageIndex(Number(event.target.value)) }, pageOptions.map((index) => /* @__PURE__ */ React3__default.default.createElement("option", { key: index, value: index }, "\u7B2C ", index + 1, " \u9875"))))), canEditPage ? /* @__PURE__ */ React3__default.default.createElement("div", { style: { marginTop: 16 } }, /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "flex", gap: 8, marginBottom: 12 } }, /* @__PURE__ */ React3__default.default.createElement(
410
+ )), /* @__PURE__ */ React3__default.default.createElement("label", { className: "grid gap-1.5" }, /* @__PURE__ */ React3__default.default.createElement("span", { className: "text-sm font-medium text-slate-700" }, "\u7F16\u8F91\u9875\u9762"), /* @__PURE__ */ React3__default.default.createElement(
411
+ "select",
412
+ {
413
+ value: activePageIndex,
414
+ onChange: (event) => setActivePageIndex(Number(event.target.value)),
415
+ className: "rounded-lg border border-slate-300 bg-white px-3 py-2 text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
416
+ },
417
+ pageOptions.map((index) => /* @__PURE__ */ React3__default.default.createElement("option", { key: index, value: index }, "\u7B2C ", index + 1, " \u9875"))
418
+ ))), canEditPage ? /* @__PURE__ */ React3__default.default.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "mb-3 flex gap-2" }, /* @__PURE__ */ React3__default.default.createElement(
479
419
  "button",
480
420
  {
481
421
  type: "button",
@@ -484,7 +424,8 @@ var FestivalCardConfigEditor = ({ value, onChange }) => {
484
424
  pages: value.pages.map(
485
425
  (p, index) => index === activePageIndex ? { ...p, elements: [...p.elements, createTextElement(index)] } : p
486
426
  )
487
- })
427
+ }),
428
+ className: "rounded-lg bg-slate-900 px-3 py-2 text-sm font-medium text-white"
488
429
  },
489
430
  "+ \u6587\u5B57"
490
431
  ), /* @__PURE__ */ React3__default.default.createElement(
@@ -496,26 +437,35 @@ var FestivalCardConfigEditor = ({ value, onChange }) => {
496
437
  pages: value.pages.map(
497
438
  (p, index) => index === activePageIndex ? { ...p, elements: [...p.elements, createImageElement(index)] } : p
498
439
  )
499
- })
440
+ }),
441
+ className: "rounded-lg bg-sky-600 px-3 py-2 text-sm font-medium text-white"
500
442
  },
501
443
  "+ \u56FE\u7247"
502
- )), /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gap: 10, maxHeight: 340, overflow: "auto" } }, (page?.elements ?? []).map((element) => /* @__PURE__ */ React3__default.default.createElement("div", { key: element.id, style: { border: "1px solid #334155", borderRadius: 10, padding: 10 } }, /* @__PURE__ */ React3__default.default.createElement("div", { style: { marginBottom: 8 } }, element.type.toUpperCase()), element.type === "text" ? /* @__PURE__ */ React3__default.default.createElement(
444
+ )), /* @__PURE__ */ React3__default.default.createElement("div", { className: "grid max-h-[340px] gap-2.5 overflow-auto pr-1" }, (page?.elements ?? []).map((element) => /* @__PURE__ */ React3__default.default.createElement("div", { key: element.id, className: "rounded-xl border border-slate-200 bg-slate-50 p-3" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "mb-2 text-xs font-semibold tracking-wide text-slate-500" }, element.type.toUpperCase()), element.type === "text" ? /* @__PURE__ */ React3__default.default.createElement(
503
445
  "textarea",
504
446
  {
505
447
  value: element.content,
506
448
  onChange: (event) => updateElement(element.id, { content: event.target.value }),
507
449
  rows: 3,
508
- style: { width: "100%" }
450
+ className: "w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
509
451
  }
510
- ) : /* @__PURE__ */ React3__default.default.createElement(
452
+ ) : /* @__PURE__ */ React3__default.default.createElement("div", { className: "grid gap-2" }, /* @__PURE__ */ React3__default.default.createElement(
511
453
  "input",
512
454
  {
513
455
  type: "url",
514
456
  value: element.src,
515
457
  onChange: (event) => updateElement(element.id, { src: event.target.value }),
516
- style: { width: "100%" }
458
+ className: "w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
517
459
  }
518
- ))))) : null);
460
+ ), /* @__PURE__ */ React3__default.default.createElement("label", { className: "inline-flex items-center gap-2 text-sm text-slate-700" }, /* @__PURE__ */ React3__default.default.createElement(
461
+ "input",
462
+ {
463
+ type: "checkbox",
464
+ checked: Boolean(element.isBackground),
465
+ onChange: (event) => updateElement(element.id, { isBackground: event.target.checked }),
466
+ className: "h-4 w-4 rounded border-slate-300 text-sky-600"
467
+ }
468
+ ), "\u4F5C\u4E3A\u672C\u9875\u80CC\u666F\u56FE")))))) : null);
519
469
  };
520
470
 
521
471
  // src/festivalCard/components/FestivalCardStudio.tsx
@@ -526,13 +476,13 @@ var FestivalCardStudio = ({ initialConfig, fetchConfig, onSave }) => {
526
476
  onSave
527
477
  });
528
478
  if (loading) return /* @__PURE__ */ React3__default.default.createElement("div", null, "\u52A0\u8F7D\u4E2D...");
529
- return /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 16 } }, /* @__PURE__ */ React3__default.default.createElement(FestivalCardBook3D, { config }), /* @__PURE__ */ React3__default.default.createElement("div", null, /* @__PURE__ */ React3__default.default.createElement(FestivalCardConfigEditor, { value: config, onChange: setConfig }), onSave ? /* @__PURE__ */ React3__default.default.createElement(
479
+ return /* @__PURE__ */ React3__default.default.createElement("div", { className: "grid gap-4 lg:grid-cols-[1.45fr_1fr]" }, /* @__PURE__ */ React3__default.default.createElement(FestivalCardBook3D, { config, className: "h-full" }), /* @__PURE__ */ React3__default.default.createElement("div", null, /* @__PURE__ */ React3__default.default.createElement(FestivalCardConfigEditor, { value: config, onChange: setConfig }), onSave ? /* @__PURE__ */ React3__default.default.createElement(
530
480
  "button",
531
481
  {
532
482
  type: "button",
533
483
  onClick: () => void save(),
534
484
  disabled: saving,
535
- style: { marginTop: 12, width: "100%", padding: "10px 16px" }
485
+ className: "mt-3 w-full rounded-lg bg-slate-900 px-4 py-2.5 text-sm font-medium text-white disabled:opacity-60"
536
486
  },
537
487
  saving ? "\u4FDD\u5B58\u4E2D..." : "\u4FDD\u5B58\u914D\u7F6E"
538
488
  ) : null));
@@ -559,25 +509,42 @@ var FestivalCardConfigPage = ({
559
509
  return normalizeFestivalCardConfig(payload);
560
510
  };
561
511
  const reloadList = React3.useCallback(async () => {
562
- const response = await fetch(apiBase, { cache: "no-store" });
563
- const data = await response.json();
564
- setList(parseListResponse2(data));
512
+ try {
513
+ const response = await fetch(apiBase, { cache: "no-store" });
514
+ if (!response.ok) throw new Error(`\u52A0\u8F7D\u5361\u7247\u5217\u8868\u5931\u8D25: ${response.status}`);
515
+ const data = await response.json();
516
+ setList(parseListResponse2(data));
517
+ } catch (error) {
518
+ window.alert(error.message || "\u52A0\u8F7D\u5361\u7247\u5217\u8868\u5931\u8D25");
519
+ }
565
520
  }, [apiBase]);
566
521
  React3.useEffect(() => {
567
522
  void reloadList();
568
523
  }, [reloadList]);
569
524
  const fetchConfig = async () => {
570
525
  const response = await fetch(`${apiBase}/${encodeURIComponent(selectedId)}`, { cache: "no-store" });
526
+ if (!response.ok) {
527
+ const message = `\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25: ${response.status}`;
528
+ window.alert(message);
529
+ throw new Error(message);
530
+ }
571
531
  const data = await response.json();
572
532
  return parseConfigResponse2(data);
573
533
  };
574
534
  const saveConfig = async (config) => {
575
- await fetch(`${apiBase}/${encodeURIComponent(selectedId)}`, {
576
- method: "PUT",
577
- headers: { "Content-Type": "application/json" },
578
- body: JSON.stringify({ config })
579
- });
580
- await reloadList();
535
+ try {
536
+ const response = await fetch(`${apiBase}/${encodeURIComponent(selectedId)}`, {
537
+ method: "PUT",
538
+ headers: { "Content-Type": "application/json" },
539
+ body: JSON.stringify({ config })
540
+ });
541
+ if (!response.ok) throw new Error(`\u4FDD\u5B58\u5931\u8D25: ${response.status}`);
542
+ await reloadList();
543
+ window.alert("\u4FDD\u5B58\u6210\u529F");
544
+ } catch (error) {
545
+ window.alert(error.message || "\u4FDD\u5B58\u5931\u8D25");
546
+ throw error;
547
+ }
581
548
  };
582
549
  const createNew = async () => {
583
550
  const name = window.prompt("\u8BF7\u8F93\u5165\u65B0\u5361\u7247\u540D\u79F0");
@@ -587,16 +554,30 @@ var FestivalCardConfigPage = ({
587
554
  id,
588
555
  name
589
556
  });
590
- await fetch(`${apiBase}/${encodeURIComponent(id)}`, {
591
- method: "PUT",
592
- headers: { "Content-Type": "application/json" },
593
- body: JSON.stringify({ config })
594
- });
595
- setSelectedId(id);
596
- await reloadList();
557
+ try {
558
+ const response = await fetch(`${apiBase}/${encodeURIComponent(id)}`, {
559
+ method: "PUT",
560
+ headers: { "Content-Type": "application/json" },
561
+ body: JSON.stringify({ config })
562
+ });
563
+ if (!response.ok) throw new Error(`\u521B\u5EFA\u5931\u8D25: ${response.status}`);
564
+ setSelectedId(id);
565
+ await reloadList();
566
+ window.alert("\u65B0\u5361\u7247\u521B\u5EFA\u6210\u529F");
567
+ } catch (error) {
568
+ window.alert(error.message || "\u521B\u5EFA\u5931\u8D25");
569
+ }
597
570
  };
598
571
  const mainLink = React3.useMemo(() => `${mainPagePath}?cardId=${encodeURIComponent(selectedId)}`, [mainPagePath, selectedId]);
599
- return /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gap: 12 } }, /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "flex", gap: 10, alignItems: "center" } }, /* @__PURE__ */ React3__default.default.createElement("select", { value: selectedId, onChange: (event) => setSelectedId(event.target.value) }, list.map((item) => /* @__PURE__ */ React3__default.default.createElement("option", { key: item.id, value: item.id }, item.name || item.id))), /* @__PURE__ */ React3__default.default.createElement("button", { type: "button", onClick: () => void createNew() }, "\u65B0\u5EFA\u5361\u7247"), /* @__PURE__ */ React3__default.default.createElement("a", { href: mainLink, style: { color: "#2563eb", fontSize: 14 } }, "\u6253\u5F00\u4E3B\u9875\u9762")), /* @__PURE__ */ React3__default.default.createElement(FestivalCardStudio, { fetchConfig, onSave: saveConfig }));
572
+ return /* @__PURE__ */ React3__default.default.createElement("div", { className: "grid gap-3" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React3__default.default.createElement(
573
+ "select",
574
+ {
575
+ value: selectedId,
576
+ onChange: (event) => setSelectedId(event.target.value),
577
+ className: "min-w-[200px] rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
578
+ },
579
+ list.map((item) => /* @__PURE__ */ React3__default.default.createElement("option", { key: item.id, value: item.id }, item.name || item.id))
580
+ ), /* @__PURE__ */ React3__default.default.createElement("button", { type: "button", onClick: () => void createNew(), className: "rounded-lg bg-slate-900 px-3 py-2 text-sm font-medium text-white" }, "\u65B0\u5EFA\u5361\u7247"), /* @__PURE__ */ React3__default.default.createElement("a", { href: mainLink, className: "rounded-lg border border-sky-200 bg-sky-50 px-3 py-2 text-sm text-sky-700" }, "\u6253\u5F00\u4E3B\u9875\u9762")), /* @__PURE__ */ React3__default.default.createElement(FestivalCardStudio, { fetchConfig, onSave: saveConfig }));
600
581
  };
601
582
  var isSummary = (value) => {
602
583
  if (!value || typeof value !== "object") return false;
@@ -620,7 +601,6 @@ var FestivalCardManagedPage = ({
620
601
  cardId,
621
602
  configPagePath = "/festivalCard/config"
622
603
  }) => {
623
- const [list, setList] = React3.useState([]);
624
604
  const [currentCardId, setCurrentCardId] = React3.useState(cardId || "");
625
605
  const [config, setConfig] = React3.useState(null);
626
606
  const [loading, setLoading] = React3.useState(true);
@@ -629,7 +609,6 @@ var FestivalCardManagedPage = ({
629
609
  const response = await fetch(apiBase, { cache: "no-store" });
630
610
  const data = await response.json();
631
611
  const items = parseListResponse(data);
632
- setList(items);
633
612
  const first = items[0];
634
613
  if (!currentCardId && first) {
635
614
  setCurrentCardId(first.id);
@@ -646,23 +625,7 @@ var FestivalCardManagedPage = ({
646
625
  if (!currentCardId) return configPagePath;
647
626
  return `${configPagePath}?cardId=${encodeURIComponent(currentCardId)}`;
648
627
  }, [configPagePath, currentCardId]);
649
- return /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "240px 1fr", gap: 14 } }, /* @__PURE__ */ React3__default.default.createElement("aside", { style: { borderRadius: 16, padding: 12, background: "#0f172a", color: "#e2e8f0" } }, /* @__PURE__ */ React3__default.default.createElement("div", { style: { fontSize: 14, marginBottom: 8 } }, "\u5361\u7247\u5217\u8868"), /* @__PURE__ */ React3__default.default.createElement("div", { style: { display: "grid", gap: 8 } }, list.map((item) => /* @__PURE__ */ React3__default.default.createElement(
650
- "button",
651
- {
652
- key: item.id,
653
- type: "button",
654
- onClick: () => setCurrentCardId(item.id),
655
- style: {
656
- borderRadius: 8,
657
- border: "1px solid #334155",
658
- padding: "8px 10px",
659
- textAlign: "left",
660
- background: currentCardId === item.id ? "#1e293b" : "#0b1220",
661
- color: "#e2e8f0"
662
- }
663
- },
664
- item.name || item.id
665
- ))), /* @__PURE__ */ React3__default.default.createElement("a", { href: configLink, style: { display: "inline-block", marginTop: 12, color: "#93c5fd", fontSize: 13 } }, "\u8FDB\u5165\u914D\u7F6E\u9875")), /* @__PURE__ */ React3__default.default.createElement("div", null, loading || !config ? /* @__PURE__ */ React3__default.default.createElement("div", null, "\u52A0\u8F7D\u4E2D...") : /* @__PURE__ */ React3__default.default.createElement(FestivalCardBook3D, { config })));
628
+ return /* @__PURE__ */ React3__default.default.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React3__default.default.createElement("div", { className: "flex justify-end" }, /* @__PURE__ */ React3__default.default.createElement("a", { href: configLink, className: "rounded-lg border border-slate-700 bg-slate-900 px-3 py-1.5 text-sm text-sky-300" }, "\u8FDB\u5165\u914D\u7F6E\u9875")), /* @__PURE__ */ React3__default.default.createElement("div", null, loading || !config ? /* @__PURE__ */ React3__default.default.createElement("div", { className: "py-12 text-center text-slate-400" }, "\u52A0\u8F7D\u4E2D...") : /* @__PURE__ */ React3__default.default.createElement(FestivalCardBook3D, { config })));
666
629
  };
667
630
 
668
631
  // src/festivalCard/server/db.ts