@kyro-cms/admin 0.9.4 → 0.9.6

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 (44) hide show
  1. package/dist/index.cjs +966 -585
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +29 -9
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.cts +3 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.js +649 -268
  8. package/dist/index.js.map +1 -1
  9. package/package.json +2 -2
  10. package/src/components/ActionBar.tsx +254 -70
  11. package/src/components/Admin.tsx +10 -17
  12. package/src/components/ApiKeysManager.tsx +1 -0
  13. package/src/components/AuditLogsPage.tsx +3 -3
  14. package/src/components/AutoForm.tsx +51 -34
  15. package/src/components/DetailView.tsx +37 -13
  16. package/src/components/GraphQLPlayground.tsx +460 -224
  17. package/src/components/ListView.tsx +3 -3
  18. package/src/components/LoginPage.tsx +5 -30
  19. package/src/components/MediaGallery.tsx +122 -15
  20. package/src/components/RestPlayground.tsx +443 -519
  21. package/src/components/Sidebar.astro +6 -2
  22. package/src/components/UserManagement.tsx +4 -4
  23. package/src/components/WebhookManager.tsx +4 -4
  24. package/src/components/blocks/AccordionBlock.tsx +1 -1
  25. package/src/components/blocks/ArrayBlock.tsx +1 -1
  26. package/src/components/blocks/ChildBlocksTree.tsx +6 -6
  27. package/src/components/blocks/CodeBlock.tsx +1 -1
  28. package/src/components/blocks/FileBlock.tsx +1 -1
  29. package/src/components/blocks/HeroBlock.tsx +1 -1
  30. package/src/components/blocks/ListBlock.tsx +1 -1
  31. package/src/components/blocks/RelationshipBlock.tsx +1 -1
  32. package/src/components/blocks/RichTextBlock.tsx +1 -1
  33. package/src/components/blocks/VideoBlock.tsx +1 -1
  34. package/src/components/fields/BlocksField.tsx +17 -19
  35. package/src/components/ui/PageHeader.tsx +205 -83
  36. package/src/components/ui/Pagination.tsx +2 -2
  37. package/src/components/ui/SlidePanel.tsx +4 -4
  38. package/src/layouts/AdminLayout.astro +64 -4
  39. package/src/lib/useResourceManager.ts +1 -0
  40. package/src/pages/graphql-explorer.astro +7 -51
  41. package/src/pages/graphql.astro +7 -119
  42. package/src/pages/index.astro +4 -63
  43. package/src/pages/rest-playground.astro +3 -29
  44. package/src/styles/main.css +32 -9
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React56 = require('react');
3
+ var React = require('react');
4
4
  var zustand = require('zustand');
5
5
  var middleware = require('zustand/middleware');
6
6
  var lucideReact = require('lucide-react');
@@ -41,7 +41,7 @@ var worker_threads = require('worker_threads');
41
41
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
42
42
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
43
43
 
44
- var React56__default = /*#__PURE__*/_interopDefault(React56);
44
+ var React__default = /*#__PURE__*/_interopDefault(React);
45
45
  var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
46
46
  var Link4__default = /*#__PURE__*/_interopDefault(Link4);
47
47
  var Image3__default = /*#__PURE__*/_interopDefault(Image3);
@@ -458,6 +458,84 @@ function Shimmer({ variant, count = 1, className = "" }) {
458
458
  i
459
459
  )) });
460
460
  }
461
+ function BackButton({ back }) {
462
+ if (back.href) {
463
+ return /* @__PURE__ */ jsxRuntime.jsx(
464
+ "a",
465
+ {
466
+ href: back.href,
467
+ onClick: (e) => {
468
+ if (back.onClick) {
469
+ e.preventDefault();
470
+ back.onClick();
471
+ }
472
+ },
473
+ className: "p-1.5 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
474
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) })
475
+ }
476
+ );
477
+ }
478
+ return /* @__PURE__ */ jsxRuntime.jsx(
479
+ "button",
480
+ {
481
+ type: "button",
482
+ onClick: back.onClick,
483
+ className: "p-1.5 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
484
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) })
485
+ }
486
+ );
487
+ }
488
+ function DesktopBreadcrumbs({ breadcrumbs }) {
489
+ return breadcrumbs?.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
490
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-20 text-[10px]", children: "/" }),
491
+ crumb.href || crumb.onClick ? /* @__PURE__ */ jsxRuntime.jsx(
492
+ "a",
493
+ {
494
+ href: crumb.href,
495
+ onClick: (e) => {
496
+ if (crumb.onClick) {
497
+ e.preventDefault();
498
+ crumb.onClick();
499
+ }
500
+ },
501
+ className: "text-[10px] font-bold tracking-widest text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-primary)] transition-all",
502
+ children: crumb.label
503
+ }
504
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-widest opacity-40", children: crumb.label })
505
+ ] }, i));
506
+ }
507
+ function ActionsSlot({ actions }) {
508
+ if (Array.isArray(actions)) {
509
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: actions.map((act, i) => /* @__PURE__ */ jsxRuntime.jsxs(
510
+ "button",
511
+ {
512
+ type: "button",
513
+ onClick: act.onClick,
514
+ className: `flex items-center gap-2 px-6 py-2.5 rounded-xl font-bold text-sm transition-all shadow-lg shadow-[var(--kyro-primary)]/10 ${act.variant === "outline" ? "border border-[var(--kyro-border)] text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)]" : act.variant === "ghost" ? "text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)] shadow-none" : "kyro-btn-primary hover:opacity-90"} ${act.className || ""}`,
515
+ children: [
516
+ act.icon && /* @__PURE__ */ jsxRuntime.jsx(act.icon, { className: "w-4 h-4" }),
517
+ act.label
518
+ ]
519
+ },
520
+ i
521
+ )) });
522
+ }
523
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: actions });
524
+ }
525
+ function SingleAction({ action }) {
526
+ return /* @__PURE__ */ jsxRuntime.jsxs(
527
+ "button",
528
+ {
529
+ type: "button",
530
+ onClick: action.onClick,
531
+ className: `kyro-btn kyro-btn-primary flex items-center gap-2 px-6 py-2.5 rounded-xl font-bold text-sm hover:opacity-90 transition-all shadow-lg shadow-[var(--kyro-primary)]/10 w-full lg:w-auto justify-center ${action.className || ""}`,
532
+ children: [
533
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(action.icon, { className: "w-4 h-4" }),
534
+ action.label
535
+ ]
536
+ }
537
+ );
538
+ }
461
539
  function PageHeader({
462
540
  title,
463
541
  description,
@@ -469,80 +547,79 @@ function PageHeader({
469
547
  actions,
470
548
  children
471
549
  }) {
472
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col lg:flex-row lg:items-center surface-tile justify-between gap-6 pt-4 mb-8", children: [
473
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
474
- (breadcrumbs || back) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
475
- back && /* @__PURE__ */ jsxRuntime.jsx(
476
- "a",
477
- {
478
- href: back.href,
479
- onClick: (e) => {
480
- if (back.onClick) {
481
- e.preventDefault();
482
- back.onClick();
483
- }
484
- },
485
- className: "p-1.5 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
486
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) })
487
- }
488
- ),
489
- breadcrumbs?.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React56__default.default.Fragment, { children: [
490
- i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-20 text-[10px]", children: "/" }),
491
- crumb.href || crumb.onClick ? /* @__PURE__ */ jsxRuntime.jsx(
492
- "a",
493
- {
494
- href: crumb.href,
495
- onClick: (e) => {
496
- if (crumb.onClick) {
497
- e.preventDefault();
498
- crumb.onClick();
550
+ const lastBreadcrumb = breadcrumbs?.[breadcrumbs.length - 1];
551
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile px-3 md:px-6 py-3 md:pt-4 mb-4 md:mb-8", children: [
552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden space-y-2", children: [
553
+ (breadcrumbs || back) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
554
+ back && /* @__PURE__ */ jsxRuntime.jsx(BackButton, { back }),
555
+ /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "group [&::-webkit-details-marker]:hidden flex-1 min-w-0", children: [
556
+ /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "flex items-center gap-2 cursor-pointer list-none", children: [
557
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-[10px] font-bold tracking-widest text-[var(--kyro-text-secondary)] truncate", children: lastBreadcrumb?.label || "" }),
558
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3 text-[var(--kyro-text-secondary)] opacity-40 group-open:rotate-180 transition-transform", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6" }) })
559
+ ] }),
560
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 pt-2 border-t border-[var(--kyro-border)] space-y-2", children: [
561
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
562
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-20 text-[10px]", children: "/" }),
563
+ crumb.href || crumb.onClick ? /* @__PURE__ */ jsxRuntime.jsx(
564
+ "a",
565
+ {
566
+ href: crumb.href,
567
+ onClick: (e) => {
568
+ if (crumb.onClick) {
569
+ e.preventDefault();
570
+ crumb.onClick();
571
+ }
572
+ },
573
+ className: "text-[10px] font-bold tracking-widest text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-primary)] transition-all",
574
+ children: crumb.label
499
575
  }
500
- },
501
- className: "text-[10px] font-bold tracking-widest text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-primary)] transition-all",
502
- children: crumb.label
503
- }
504
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-widest opacity-40", children: crumb.label })
505
- ] }, i))
576
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-widest opacity-40", children: crumb.label })
577
+ ] }, i)) }),
578
+ metadata && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-wrap", children: metadata.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(React__default.default.Fragment, { children: item }, i)) }),
579
+ children
580
+ ] })
581
+ ] })
506
582
  ] }),
507
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
508
- Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-6 h-6 text-[var(--kyro-primary)]" }),
509
- title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)] truncate", children: title })
583
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
584
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5 text-[var(--kyro-primary)] shrink-0" }),
585
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-lg font-bold tracking-tighter text-[var(--kyro-text-primary)] truncate", children: title }),
586
+ metadata && !description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-[var(--kyro-primary)] shrink-0" })
510
587
  ] }),
511
- description && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
512
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[var(--kyro-text-secondary)] font-medium opacity-60 line-clamp-1", children: description }),
513
- metadata && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: metadata.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(React56__default.default.Fragment, { children: [
588
+ description && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
589
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[var(--kyro-text-secondary)] font-medium opacity-60 line-clamp-1 min-w-0 text-xs", children: description }),
590
+ metadata && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: metadata.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
514
591
  i === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-20 ml-1", children: "\xB7" }),
515
592
  item
516
- ] }, i)) }),
517
- children
593
+ ] }, i)) })
518
594
  ] })
519
595
  ] }),
520
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
521
- actions && (Array.isArray(actions) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: actions.map((act, i) => /* @__PURE__ */ jsxRuntime.jsxs(
522
- "button",
523
- {
524
- type: "button",
525
- onClick: act.onClick,
526
- className: `flex items-center gap-2 px-6 py-2.5 rounded-xl font-bold text-sm transition-all shadow-lg shadow-[var(--kyro-primary)]/10 ${act.variant === "outline" ? "border border-[var(--kyro-border)] text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)]" : act.variant === "ghost" ? "text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)] shadow-none" : "kyro-btn-primary hover:opacity-90"} ${act.className || ""}`,
527
- children: [
528
- act.icon && /* @__PURE__ */ jsxRuntime.jsx(act.icon, { className: "w-4 h-4" }),
529
- act.label
530
- ]
531
- },
532
- i
533
- )) }) : actions),
534
- action && /* @__PURE__ */ jsxRuntime.jsxs(
535
- "button",
536
- {
537
- type: "button",
538
- onClick: action.onClick,
539
- className: `kyro-btn kyro-btn-primary flex items-center gap-2 px-6 py-2.5 rounded-xl font-bold text-sm hover:opacity-90 transition-all shadow-lg shadow-[var(--kyro-primary)]/10 ${action.className || ""}`,
540
- children: [
541
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(action.icon, { className: "w-4 h-4" }),
542
- action.label
543
- ]
544
- }
545
- )
596
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden md:flex md:flex-row md:items-center justify-between gap-6", children: [
597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
598
+ (breadcrumbs || back) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
599
+ back && /* @__PURE__ */ jsxRuntime.jsx(BackButton, { back }),
600
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx(DesktopBreadcrumbs, { breadcrumbs })
601
+ ] }),
602
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
603
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-6 h-6 text-[var(--kyro-primary)]" }),
604
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)] truncate", children: title })
605
+ ] }),
606
+ (description || metadata) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 mt-1", children: [
607
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[var(--kyro-text-secondary)] font-medium opacity-60 line-clamp-1 min-w-0", children: description }),
608
+ metadata && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: metadata.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
609
+ i === 0 && (description || i > 0) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-20 ml-1", children: "\xB7" }),
610
+ item
611
+ ] }, i)) }),
612
+ children
613
+ ] })
614
+ ] }),
615
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap shrink-0", children: [
616
+ actions && /* @__PURE__ */ jsxRuntime.jsx(ActionsSlot, { actions }),
617
+ action && /* @__PURE__ */ jsxRuntime.jsx(SingleAction, { action })
618
+ ] })
619
+ ] }),
620
+ (actions || action) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden flex items-center gap-2 mt-3 pt-3 border-t border-[var(--kyro-border)]", children: [
621
+ action && /* @__PURE__ */ jsxRuntime.jsx(SingleAction, { action }),
622
+ actions && /* @__PURE__ */ jsxRuntime.jsx(ActionsSlot, { actions })
546
623
  ] })
547
624
  ] });
548
625
  }
@@ -604,7 +681,7 @@ function Button({
604
681
  }
605
682
  function Pagination({ page, totalPages, totalDocs, limit, onPageChange, onLimitChange }) {
606
683
  if (totalPages <= 1) return null;
607
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-t border-[var(--kyro-border)]", children: [
684
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-3 px-4 py-3 border-t border-[var(--kyro-border)]", children: [
608
685
  totalDocs !== void 0 && limit ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-[var(--kyro-text-secondary)] font-medium", children: [
609
686
  "Showing ",
610
687
  (page - 1) * limit + 1,
@@ -613,7 +690,7 @@ function Pagination({ page, totalPages, totalDocs, limit, onPageChange, onLimitC
613
690
  " of ",
614
691
  totalDocs
615
692
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
616
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
693
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap justify-center", children: [
617
694
  onLimitChange && /* @__PURE__ */ jsxRuntime.jsxs(
618
695
  "select",
619
696
  {
@@ -730,14 +807,14 @@ function ListView({
730
807
  window.location.href = `${adminPath}/${collectionSlug}/${id}`;
731
808
  }
732
809
  };
733
- const [docs, setDocs] = React56.useState(initialDocs);
734
- const [totalDocs, setTotalDocs] = React56.useState(initialTotal);
735
- const [loading, setLoading] = React56.useState(false);
736
- const [page, setPage] = React56.useState(1);
737
- const [limit, setLimit] = React56.useState(10);
738
- const [selectedIds, setSelectedIds] = React56.useState(/* @__PURE__ */ new Set());
739
- const [search, setSearch] = React56.useState("");
740
- const [filters, setFilters] = React56.useState([]);
810
+ const [docs, setDocs] = React.useState(initialDocs);
811
+ const [totalDocs, setTotalDocs] = React.useState(initialTotal);
812
+ const [loading, setLoading] = React.useState(false);
813
+ const [page, setPage] = React.useState(1);
814
+ const [limit, setLimit] = React.useState(10);
815
+ const [selectedIds, setSelectedIds] = React.useState(/* @__PURE__ */ new Set());
816
+ const [search, setSearch] = React.useState("");
817
+ const [filters, setFilters] = React.useState([]);
741
818
  const { confirm, alert } = useUIStore();
742
819
  const addFilter = () => {
743
820
  setFilters([...filters, { field: "", operator: "equals", value: "" }]);
@@ -753,9 +830,9 @@ function ListView({
753
830
  const updateFilter = (index, updates) => {
754
831
  setFilters(filters.map((f, i) => i === index ? { ...f, ...updates } : f));
755
832
  };
756
- const [sort, setSort] = React56.useState(null);
757
- const [showFilters, setShowFilters] = React56.useState(false);
758
- const [showColumns, setShowColumns] = React56.useState(false);
833
+ const [sort, setSort] = React.useState(null);
834
+ const [showFilters, setShowFilters] = React.useState(false);
835
+ const [showColumns, setShowColumns] = React.useState(false);
759
836
  function flattenFields(fields2) {
760
837
  const result = [];
761
838
  for (const field3 of fields2 || []) {
@@ -774,12 +851,12 @@ function ListView({
774
851
  }
775
852
  return result;
776
853
  }
777
- const allFields = React56.useMemo(
854
+ const allFields = React.useMemo(
778
855
  () => flattenFields(collection.fields),
779
856
  [collection.fields]
780
857
  );
781
858
  const titleField = typeof collection.admin?.useAsTitle === "string" ? collection.admin.useAsTitle : allFields.find((f) => f.type !== "group" && typeof f.name === "string")?.name;
782
- const [visibleColumns, setVisibleColumns] = React56.useState(() => {
859
+ const [visibleColumns, setVisibleColumns] = React.useState(() => {
783
860
  let cols;
784
861
  if (collection.admin?.defaultColumns) {
785
862
  cols = [...collection.admin?.defaultColumns || []];
@@ -794,7 +871,7 @@ function ListView({
794
871
  }
795
872
  return new Set(cols);
796
873
  });
797
- const toggleColumn = React56.useCallback((fieldName) => {
874
+ const toggleColumn = React.useCallback((fieldName) => {
798
875
  setVisibleColumns((prev) => {
799
876
  const next = new Set(prev);
800
877
  if (next.has(fieldName)) {
@@ -813,7 +890,7 @@ function ListView({
813
890
  }
814
891
  return fieldName;
815
892
  }
816
- const handleSort = React56.useCallback((fieldName) => {
893
+ const handleSort = React.useCallback((fieldName) => {
817
894
  const resolvedField = resolveSortField(fieldName);
818
895
  setSort((prev) => {
819
896
  if (prev && prev.field === resolvedField) {
@@ -825,7 +902,7 @@ function ListView({
825
902
  return { field: resolvedField, direction: "asc" };
826
903
  });
827
904
  }, []);
828
- const displayFields = React56.useMemo(
905
+ const displayFields = React.useMemo(
829
906
  () => {
830
907
  const fields2 = allFields.filter((f) => !!f.name && visibleColumns.has(f.name));
831
908
  if (visibleColumns.has("status")) {
@@ -855,7 +932,7 @@ function ListView({
855
932
  const val = resolveFieldValue(collection.fields, doc, field3.name);
856
933
  return val ?? null;
857
934
  }
858
- const fetchDocs = React56.useCallback(async () => {
935
+ const fetchDocs = React.useCallback(async () => {
859
936
  setLoading(true);
860
937
  try {
861
938
  const params = new URLSearchParams({
@@ -880,13 +957,13 @@ function ListView({
880
957
  setLoading(false);
881
958
  }
882
959
  }, [collectionSlug, page, limit, search, sort, filters]);
883
- React56.useEffect(() => {
960
+ React.useEffect(() => {
884
961
  if (docs.length === 0 && initialTotal === 0) {
885
962
  fetchDocs();
886
963
  }
887
964
  }, []);
888
- const isFirstRender = React56.useRef(true);
889
- React56.useEffect(() => {
965
+ const isFirstRender = React.useRef(true);
966
+ React.useEffect(() => {
890
967
  if (isFirstRender.current) {
891
968
  isFirstRender.current = false;
892
969
  return;
@@ -968,8 +1045,8 @@ function ListView({
968
1045
  }
969
1046
  ),
970
1047
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-4 flex flex-col lg:flex-row gap-4 items-start lg:items-center", children: [
971
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-md", children: [
972
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4" }),
1048
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 w-full lg:max-w-md", children: [
1049
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--kyro-text-muted)]" }),
973
1050
  /* @__PURE__ */ jsxRuntime.jsx(
974
1051
  "input",
975
1052
  {
@@ -1161,7 +1238,7 @@ function ListView({
1161
1238
  }
1162
1239
  )
1163
1240
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left", children: [
1164
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-[var(--kyro-text-secondary)] font-bold text-[10px] tracking-[0.3em] border-b border-[var(--kyro-border)]", children: [
1241
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-[var(--kyro-text-secondary)] font-bold text-[10px] tracking-[0.3em] border-b border-[var(--kyro-border)] whitespace-nowrap", children: [
1165
1242
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-4 w-10", children: /* @__PURE__ */ jsxRuntime.jsx(
1166
1243
  "input",
1167
1244
  {
@@ -1349,26 +1426,26 @@ function UploadField({
1349
1426
  onChange,
1350
1427
  disabled
1351
1428
  }) {
1352
- const inputRef = React56.useRef(null);
1353
- const urlInputRef = React56.useRef(null);
1354
- const [uploading, setUploading] = React56.useState(false);
1355
- const [showPicker, setShowPicker] = React56.useState(false);
1356
- const [isPickerFullscreen, setIsPickerFullscreen] = React56.useState(false);
1357
- const [mediaItems, setMediaItems] = React56.useState([]);
1358
- const [folders, setFolders] = React56.useState([]);
1359
- const [selectedFolder, setSelectedFolder] = React56.useState("");
1360
- const [mediaLoading, setMediaLoading] = React56.useState(false);
1361
- const [pickerSearch, setPickerSearch] = React56.useState("");
1362
- const [showUrlInput, setShowUrlInput] = React56.useState(false);
1363
- const [urlValue, setUrlValue] = React56.useState("");
1364
- const [urlError, setUrlError] = React56.useState("");
1365
- const [selectedItems, setSelectedItems] = React56.useState([]);
1429
+ const inputRef = React.useRef(null);
1430
+ const urlInputRef = React.useRef(null);
1431
+ const [uploading, setUploading] = React.useState(false);
1432
+ const [showPicker, setShowPicker] = React.useState(false);
1433
+ const [isPickerFullscreen, setIsPickerFullscreen] = React.useState(false);
1434
+ const [mediaItems, setMediaItems] = React.useState([]);
1435
+ const [folders, setFolders] = React.useState([]);
1436
+ const [selectedFolder, setSelectedFolder] = React.useState("");
1437
+ const [mediaLoading, setMediaLoading] = React.useState(false);
1438
+ const [pickerSearch, setPickerSearch] = React.useState("");
1439
+ const [showUrlInput, setShowUrlInput] = React.useState(false);
1440
+ const [urlValue, setUrlValue] = React.useState("");
1441
+ const [urlError, setUrlError] = React.useState("");
1442
+ const [selectedItems, setSelectedItems] = React.useState([]);
1366
1443
  const fieldLabel = field3?.label || field3?.name || "File";
1367
1444
  const maxCount = field3.maxCount ?? (field3.hasMany ? 999 : 1);
1368
1445
  const isMultiple = maxCount > 1;
1369
1446
  const currentValue = Array.isArray(value) ? value : value ? [value] : [];
1370
1447
  const canAddMore = currentValue.length < maxCount;
1371
- React56.useEffect(() => {
1448
+ React.useEffect(() => {
1372
1449
  const fetchMissingDetails = async () => {
1373
1450
  const idsToFetch = currentValue.filter((item) => typeof item === "string").map((id) => id);
1374
1451
  const objectIdsToFetch = currentValue.filter(
@@ -1402,7 +1479,7 @@ function UploadField({
1402
1479
  };
1403
1480
  fetchMissingDetails();
1404
1481
  }, [value]);
1405
- React56.useEffect(() => {
1482
+ React.useEffect(() => {
1406
1483
  if (showPicker) {
1407
1484
  loadFolders();
1408
1485
  loadMedia();
@@ -1528,7 +1605,7 @@ function UploadField({
1528
1605
  newValue.splice(index, 1);
1529
1606
  onChange(isMultiple ? newValue : newValue[0] || null);
1530
1607
  };
1531
- const filteredMedia = React56.useMemo(() => {
1608
+ const filteredMedia = React.useMemo(() => {
1532
1609
  return mediaItems.filter((item) => {
1533
1610
  return !pickerSearch || item.filename?.toLowerCase().includes(pickerSearch.toLowerCase()) || item.title?.toLowerCase().includes(pickerSearch.toLowerCase());
1534
1611
  });
@@ -1935,12 +2012,12 @@ function SlidePanel({
1935
2012
  showOverlay = false,
1936
2013
  accentClass
1937
2014
  }) {
1938
- const panelRef = React56.useRef(null);
1939
- const [hydrated, setHydrated] = React56.useState(false);
1940
- React56.useEffect(() => {
2015
+ const panelRef = React.useRef(null);
2016
+ const [hydrated, setHydrated] = React.useState(false);
2017
+ React.useEffect(() => {
1941
2018
  setHydrated(true);
1942
2019
  }, []);
1943
- React56.useEffect(() => {
2020
+ React.useEffect(() => {
1944
2021
  const handleEscape = (e) => {
1945
2022
  if (e.key === "Escape") onClose();
1946
2023
  };
@@ -1954,10 +2031,10 @@ function SlidePanel({
1954
2031
  };
1955
2032
  }, [open, onClose]);
1956
2033
  const widthClasses = {
1957
- sm: "w-[320px]",
1958
- md: "w-[400px]",
1959
- lg: "w-[550px]",
1960
- xl: "w-[700px]"
2034
+ sm: "w-full sm:w-[320px]",
2035
+ md: "w-full sm:w-[400px]",
2036
+ lg: "w-full sm:w-[550px]",
2037
+ xl: "w-full sm:w-[700px]"
1961
2038
  };
1962
2039
  if (!open || !hydrated) return null;
1963
2040
  return reactDom.createPortal(
@@ -2021,7 +2098,7 @@ function Modal({
2021
2098
  size = "md",
2022
2099
  variant = "default"
2023
2100
  }) {
2024
- React56.useEffect(() => {
2101
+ React.useEffect(() => {
2025
2102
  const handleEscape = (e) => {
2026
2103
  if (e.key === "Escape") onClose();
2027
2104
  };
@@ -2129,7 +2206,7 @@ function PromptModal({
2129
2206
  placeholder = "",
2130
2207
  defaultValue = ""
2131
2208
  }) {
2132
- const [value, setValue] = React56.useState(defaultValue);
2209
+ const [value, setValue] = React.useState(defaultValue);
2133
2210
  const handleSubmit = (e) => {
2134
2211
  e.preventDefault();
2135
2212
  if (value.trim()) {
@@ -2242,35 +2319,36 @@ function MediaGallery({
2242
2319
  const canUpload = permissions?.media?.create !== false;
2243
2320
  const canDelete = permissions?.media?.delete !== false;
2244
2321
  const canUpdate = permissions?.media?.update !== false;
2245
- const [items, setItems] = React56.useState([]);
2246
- const [loading, setLoading] = React56.useState(true);
2247
- const [folders, setFolders] = React56.useState([]);
2248
- const [currentFolder, setCurrentFolder] = React56.useState("");
2249
- const [search, setSearch] = React56.useState("");
2250
- const [filter, setFilter] = React56.useState("all");
2251
- const [view, setView] = React56.useState("grid");
2252
- const [panelItem, setPanelItem] = React56.useState(null);
2253
- const [showPreview, setShowPreview] = React56.useState(false);
2254
- const [showCrop, setShowCrop] = React56.useState(false);
2255
- const [uploading, setUploading] = React56.useState(false);
2256
- const [uploadProgress, setUploadProgress] = React56.useState(
2322
+ const [items, setItems] = React.useState([]);
2323
+ const [loading, setLoading] = React.useState(true);
2324
+ const [folders, setFolders] = React.useState([]);
2325
+ const [currentFolder, setCurrentFolder] = React.useState("");
2326
+ const [search, setSearch] = React.useState("");
2327
+ const [filter, setFilter] = React.useState("all");
2328
+ const [view, setView] = React.useState("grid");
2329
+ const [panelItem, setPanelItem] = React.useState(null);
2330
+ const [showPreview, setShowPreview] = React.useState(false);
2331
+ const [showCrop, setShowCrop] = React.useState(false);
2332
+ const [uploading, setUploading] = React.useState(false);
2333
+ const [uploadProgress, setUploadProgress] = React.useState(
2257
2334
  {}
2258
2335
  );
2259
- const [showNewFolderModal, setShowNewFolderModal] = React56.useState(false);
2260
- const [storageConfigured, setStorageConfigured] = React56.useState(null);
2261
- const [storageChecked, setStorageChecked] = React56.useState(false);
2262
- const [showStorageConfigModal, setShowStorageConfigModal] = React56.useState(false);
2263
- const [page, setPage] = React56.useState(1);
2264
- const [total, setTotal] = React56.useState(0);
2265
- const [totalPages, setTotalPages] = React56.useState(1);
2336
+ const [showNewFolderModal, setShowNewFolderModal] = React.useState(false);
2337
+ const [showMobileFilters, setShowMobileFilters] = React.useState(false);
2338
+ const [storageConfigured, setStorageConfigured] = React.useState(null);
2339
+ const [storageChecked, setStorageChecked] = React.useState(false);
2340
+ const [showStorageConfigModal, setShowStorageConfigModal] = React.useState(false);
2341
+ const [page, setPage] = React.useState(1);
2342
+ const [total, setTotal] = React.useState(0);
2343
+ const [totalPages, setTotalPages] = React.useState(1);
2266
2344
  const limit = 40;
2267
- const [selectedIds, setSelectedIds] = React56.useState(/* @__PURE__ */ new Set());
2345
+ const [selectedIds, setSelectedIds] = React.useState(/* @__PURE__ */ new Set());
2268
2346
  const { confirm, alert } = useUIStore();
2269
- const [isDragging, setIsDragging] = React56.useState(false);
2270
- const fileInputRef = React56.useRef(null);
2271
- const [crop, setCrop] = React56.useState();
2272
- const imgRef = React56.useRef(null);
2273
- const loadMedia = React56.useCallback(async () => {
2347
+ const [isDragging, setIsDragging] = React.useState(false);
2348
+ const fileInputRef = React.useRef(null);
2349
+ const [crop, setCrop] = React.useState();
2350
+ const imgRef = React.useRef(null);
2351
+ const loadMedia = React.useCallback(async () => {
2274
2352
  setLoading(true);
2275
2353
  try {
2276
2354
  const params = new URLSearchParams({
@@ -2293,7 +2371,7 @@ function MediaGallery({
2293
2371
  setLoading(false);
2294
2372
  }
2295
2373
  }, [page, currentFolder, search, filter]);
2296
- const loadFolders = React56.useCallback(async () => {
2374
+ const loadFolders = React.useCallback(async () => {
2297
2375
  try {
2298
2376
  const result = await apiGet(withCacheBust("/api/media/folders"));
2299
2377
  setFolders(Array.isArray(result) ? result : result.folders || []);
@@ -2301,7 +2379,7 @@ function MediaGallery({
2301
2379
  console.error("Failed to load folders:", error);
2302
2380
  }
2303
2381
  }, []);
2304
- const checkStorage = React56.useCallback(async () => {
2382
+ const checkStorage = React.useCallback(async () => {
2305
2383
  try {
2306
2384
  const res = await apiGet("/api/globals/storage-settings");
2307
2385
  const isConfigured = !!res?.data?.provider;
@@ -2310,23 +2388,23 @@ function MediaGallery({
2310
2388
  setStorageConfigured(false);
2311
2389
  }
2312
2390
  }, []);
2313
- React56.useEffect(() => {
2391
+ React.useEffect(() => {
2314
2392
  if (!pickerMode) checkStorage();
2315
2393
  }, [checkStorage, pickerMode]);
2316
- React56.useEffect(() => {
2394
+ React.useEffect(() => {
2317
2395
  if (pickerMode) return;
2318
2396
  if (storageConfigured === false && !storageChecked) {
2319
2397
  setStorageChecked(true);
2320
2398
  setShowStorageConfigModal(true);
2321
2399
  }
2322
2400
  }, [pickerMode, storageConfigured, storageChecked]);
2323
- React56.useEffect(() => {
2401
+ React.useEffect(() => {
2324
2402
  loadMedia();
2325
2403
  }, [loadMedia]);
2326
- React56.useEffect(() => {
2404
+ React.useEffect(() => {
2327
2405
  loadFolders();
2328
2406
  }, [loadFolders]);
2329
- React56.useEffect(() => {
2407
+ React.useEffect(() => {
2330
2408
  if (pickerMode) return;
2331
2409
  const handlePaste = (e) => {
2332
2410
  const files = e.clipboardData?.files;
@@ -2410,6 +2488,7 @@ function MediaGallery({
2410
2488
  await apiPost("/api/media/folders", { name });
2411
2489
  loadFolders();
2412
2490
  setShowNewFolderModal(false);
2491
+ toast.success(`Folder "${name}" created`);
2413
2492
  } catch (error) {
2414
2493
  console.error("Failed to create folder:", error);
2415
2494
  toast.error("Failed to create folder");
@@ -2427,6 +2506,7 @@ function MediaGallery({
2427
2506
  if (currentFolder === folder) setCurrentFolder("");
2428
2507
  loadFolders();
2429
2508
  loadMedia();
2509
+ toast.success(`Folder "${folder}" deleted`);
2430
2510
  } catch (error) {
2431
2511
  console.error("Failed to delete folder:", error);
2432
2512
  toast.error("Failed to delete folder");
@@ -2441,8 +2521,10 @@ function MediaGallery({
2441
2521
  if (panelItem?.id === id) {
2442
2522
  setPanelItem(result.doc);
2443
2523
  }
2524
+ toast.success("Metadata updated");
2444
2525
  } catch (error) {
2445
2526
  console.error("Failed to update metadata:", error);
2527
+ toast.error("Failed to update metadata");
2446
2528
  }
2447
2529
  };
2448
2530
  const onImageLoad = (e) => {
@@ -2491,6 +2573,7 @@ function MediaGallery({
2491
2573
  await apiUpload("/api/media", formData);
2492
2574
  loadMedia();
2493
2575
  setShowCrop(false);
2576
+ toast.success("Cropped image saved");
2494
2577
  }
2495
2578
  }
2496
2579
  } catch (err) {
@@ -2500,7 +2583,7 @@ function MediaGallery({
2500
2583
  setUploading(false);
2501
2584
  }
2502
2585
  };
2503
- const stats = React56.useMemo(() => {
2586
+ const stats = React.useMemo(() => {
2504
2587
  return items.reduce(
2505
2588
  (acc, item) => {
2506
2589
  acc.totalSize += item.fileSize || 0;
@@ -2526,7 +2609,7 @@ function MediaGallery({
2526
2609
  }
2527
2610
  },
2528
2611
  children: [
2529
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col lg:flex-row lg:items-center justify-between gap-6 border-b border-[var(--kyro-border)] backdrop-blur-md sticky top-0 z-40 ${pickerMode ? "p-2" : "p-6 rounded-xl surface-tile"}`, children: [
2612
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col lg:flex-row lg:items-center justify-between gap-6 border-b border-[var(--kyro-border)] backdrop-blur-md sticky top-0 ${pickerMode ? "p-2" : "p-6 rounded-xl surface-tile"}`, children: [
2530
2613
  !pickerMode && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2531
2614
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]", children: "Media Library" }),
2532
2615
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 mt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-bold tracking-widest text-[var(--kyro-text-secondary)] opacity-50", children: [
@@ -2537,7 +2620,7 @@ function MediaGallery({
2537
2620
  ] }) }),
2538
2621
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-3 flex-wrap lg:flex-nowrap ${pickerMode ? "w-full" : ""}`, children: [
2539
2622
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group flex-1 min-w-[200px]", children: [
2540
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4" }),
2623
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--kyro-text-muted)]" }),
2541
2624
  /* @__PURE__ */ jsxRuntime.jsx(
2542
2625
  "input",
2543
2626
  {
@@ -2550,21 +2633,31 @@ function MediaGallery({
2550
2633
  )
2551
2634
  ] }),
2552
2635
  !pickerMode && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2553
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex bg-[var(--kyro-surface-accent)] p-1 rounded-xl border border-[var(--kyro-border)]", children: [
2554
- /* @__PURE__ */ jsxRuntime.jsx(
2555
- "button",
2556
- {
2557
- onClick: () => setView("grid"),
2558
- className: `p-2 rounded-lg transition-all ${view === "grid" ? "bg-[var(--kyro-surface)] shadow-sm text-[var(--kyro-text-primary)]" : "text-[var(--kyro-text-secondary)] opacity-50 hover:opacity-100"}`,
2559
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: "w-4 h-4" })
2560
- }
2561
- ),
2636
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2637
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex bg-[var(--kyro-surface-accent)] p-1 rounded-xl border border-[var(--kyro-border)]", children: [
2638
+ /* @__PURE__ */ jsxRuntime.jsx(
2639
+ "button",
2640
+ {
2641
+ onClick: () => setView("grid"),
2642
+ className: `p-2 rounded-lg transition-all ${view === "grid" ? "bg-[var(--kyro-surface)] shadow-sm text-[var(--kyro-text-primary)]" : "text-[var(--kyro-text-secondary)] opacity-50 hover:opacity-100"}`,
2643
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: "w-4 h-4" })
2644
+ }
2645
+ ),
2646
+ /* @__PURE__ */ jsxRuntime.jsx(
2647
+ "button",
2648
+ {
2649
+ onClick: () => setView("list"),
2650
+ className: `p-2 rounded-lg transition-all ${view === "list" ? "bg-[var(--kyro-surface)] shadow-sm text-[var(--kyro-text-primary)]" : "text-[var(--kyro-text-secondary)] opacity-50 hover:opacity-100"}`,
2651
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.File, { className: "w-4 h-4" })
2652
+ }
2653
+ )
2654
+ ] }),
2562
2655
  /* @__PURE__ */ jsxRuntime.jsx(
2563
2656
  "button",
2564
2657
  {
2565
- onClick: () => setView("list"),
2566
- className: `p-2 rounded-lg transition-all ${view === "list" ? "bg-[var(--kyro-surface)] shadow-sm text-[var(--kyro-text-primary)]" : "text-[var(--kyro-text-secondary)] opacity-50 hover:opacity-100"}`,
2567
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.File, { className: "w-4 h-4" })
2658
+ onClick: () => setShowMobileFilters(true),
2659
+ className: "md:hidden p-2 rounded-xl bg-[var(--kyro-surface-accent)] border border-[var(--kyro-border)] text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-text-primary)] transition-colors",
2660
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { className: "w-4 h-4" })
2568
2661
  }
2569
2662
  )
2570
2663
  ] }),
@@ -2663,7 +2756,7 @@ function MediaGallery({
2663
2756
  ] })
2664
2757
  ] }) }),
2665
2758
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col min-h-0 bg-[var(--kyro-bg)]", children: [
2666
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-1 overflow-y-auto custom-scrollbar ${pickerMode ? "px-2 py-4" : "py-8 px-4"}`, children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5", children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { variant: "media-card", count: 12 }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-32 text-center", children: [
2759
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex-1 overflow-y-auto custom-scrollbar ${pickerMode ? "px-2 py-4" : "py-4 px-2 md:py-8 md:px-4"}`, children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5", children: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { variant: "media-card", count: 12 }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-32 text-center", children: [
2667
2760
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-24 h-24 rounded-[2rem] bg-[var(--kyro-surface-accent)] flex items-center justify-center mb-8 rotate-12 group-hover:rotate-0 transition-transform duration-500", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: "w-10 h-10 text-[var(--kyro-text-muted)] opacity-30" }) }),
2668
2761
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xl font-bold text-[var(--kyro-text-primary)] tracking-tight", children: "No assets found" }),
2669
2762
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[var(--kyro-text-secondary)] mt-2 max-w-xs mx-auto text-sm font-medium leading-relaxed", children: "Upload your first file or create a folder to organize your media assets." }),
@@ -2863,6 +2956,105 @@ function MediaGallery({
2863
2956
  )
2864
2957
  ] })
2865
2958
  ] }),
2959
+ showMobileFilters && !pickerMode && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-[70] md:hidden", children: [
2960
+ /* @__PURE__ */ jsxRuntime.jsx(
2961
+ "div",
2962
+ {
2963
+ className: "fixed inset-0 bg-black/50 backdrop-blur-sm",
2964
+ onClick: () => setShowMobileFilters(false)
2965
+ }
2966
+ ),
2967
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-0 left-0 right-0 bg-[var(--kyro-surface)] rounded-t-3xl shadow-2xl max-h-[70vh] overflow-y-auto animate-in slide-in-from-bottom-12 duration-300", children: [
2968
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 bg-[var(--kyro-surface)] z-10 flex items-center justify-between p-6 pb-4 border-b border-[var(--kyro-border)]", children: [
2969
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-bold tracking-tight text-[var(--kyro-text-primary)]", children: "Filters" }),
2970
+ /* @__PURE__ */ jsxRuntime.jsx(
2971
+ "button",
2972
+ {
2973
+ onClick: () => setShowMobileFilters(false),
2974
+ className: "p-2 rounded-xl hover:bg-[var(--kyro-surface-accent)] transition-colors text-[var(--kyro-text-muted)]",
2975
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
2976
+ }
2977
+ )
2978
+ ] }),
2979
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-8", children: [
2980
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2981
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-[0.2em] text-[var(--kyro-text-secondary)] opacity-40 block mb-4", children: "Quick Filters" }),
2982
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: ["all", "image", "video", "audio", "document", "archive"].map((t) => /* @__PURE__ */ jsxRuntime.jsx(
2983
+ "button",
2984
+ {
2985
+ onClick: () => {
2986
+ setFilter(t);
2987
+ setShowMobileFilters(false);
2988
+ },
2989
+ className: `px-4 py-2 rounded-xl text-[11px] font-bold capitalize transition-all border ${filter === t ? "bg-[var(--kyro-sidebar-active)] text-[var(--kyro-sidebar-text-active)] border-transparent" : "bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] border-[var(--kyro-border)] hover:border-[var(--kyro-text-muted)]"}`,
2990
+ children: t
2991
+ },
2992
+ t
2993
+ )) })
2994
+ ] }),
2995
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2996
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
2997
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-[0.2em] text-[var(--kyro-text-secondary)] opacity-40", children: "Folders" }),
2998
+ /* @__PURE__ */ jsxRuntime.jsx(
2999
+ "button",
3000
+ {
3001
+ onClick: () => {
3002
+ setShowNewFolderModal(true);
3003
+ setShowMobileFilters(false);
3004
+ },
3005
+ className: "p-1.5 hover:bg-[var(--kyro-surface-accent)] rounded-lg transition-colors text-[var(--kyro-text-primary)]",
3006
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderPlus, { className: "w-4 h-4" })
3007
+ }
3008
+ )
3009
+ ] }),
3010
+ /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "space-y-1", children: [
3011
+ /* @__PURE__ */ jsxRuntime.jsxs(
3012
+ "button",
3013
+ {
3014
+ onClick: () => {
3015
+ setCurrentFolder("");
3016
+ setShowMobileFilters(false);
3017
+ },
3018
+ className: `w-full flex items-center gap-3 px-4 py-2.5 rounded-xl text-xs font-bold transition-all ${currentFolder === "" ? "bg-[var(--kyro-sidebar-active)] text-[var(--kyro-sidebar-text-active)] shadow-md" : "text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)] hover:text-[var(--kyro-text-primary)]"}`,
3019
+ children: [
3020
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderInput, { className: "w-4 h-4 opacity-70" }),
3021
+ "All Assets"
3022
+ ]
3023
+ }
3024
+ ),
3025
+ folders.map((folder) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
3026
+ /* @__PURE__ */ jsxRuntime.jsxs(
3027
+ "button",
3028
+ {
3029
+ onClick: () => {
3030
+ setCurrentFolder(folder);
3031
+ setShowMobileFilters(false);
3032
+ },
3033
+ className: `w-full flex items-center gap-3 px-4 py-2.5 rounded-xl text-xs font-bold transition-all ${currentFolder === folder ? "bg-[var(--kyro-sidebar-active)] text-[var(--kyro-sidebar-text-active)] shadow-md" : "text-[var(--kyro-text-secondary)] hover:bg-[var(--kyro-surface-accent)] hover:text-[var(--kyro-text-primary)]"}`,
3034
+ children: [
3035
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-4 h-4 flex items-center justify-center opacity-70", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Folder, { fill: currentFolder === folder ? "currentColor" : "none" }) }),
3036
+ folder
3037
+ ]
3038
+ }
3039
+ ),
3040
+ /* @__PURE__ */ jsxRuntime.jsx(
3041
+ "button",
3042
+ {
3043
+ onClick: (e) => {
3044
+ e.stopPropagation();
3045
+ handleDeleteFolder(folder);
3046
+ setShowMobileFilters(false);
3047
+ },
3048
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1.5 text-red-500 opacity-0 group-hover:opacity-100 transition-all hover:bg-red-50 rounded-lg",
3049
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-3.5 h-3.5" })
3050
+ }
3051
+ )
3052
+ ] }, folder))
3053
+ ] })
3054
+ ] })
3055
+ ] })
3056
+ ] })
3057
+ ] }),
2866
3058
  /* @__PURE__ */ jsxRuntime.jsx(
2867
3059
  SlidePanel,
2868
3060
  {
@@ -3160,6 +3352,8 @@ function MediaGallery({
3160
3352
  setShowStorageConfigModal(false);
3161
3353
  setStorageConfigured(true);
3162
3354
  window.location.reload();
3355
+ }).catch(() => {
3356
+ toast.error("Failed to configure storage");
3163
3357
  });
3164
3358
  },
3165
3359
  className: "flex-1 px-4 py-3 border border-[var(--kyro-border)] text-[var(--kyro-text-secondary)] rounded-xl font-bold hover:bg-[var(--kyro-surface-accent)] transition-colors",
@@ -3205,9 +3399,9 @@ var MenuBar = ({
3205
3399
  setIsExpanded,
3206
3400
  onOpenMediaPicker
3207
3401
  }) => {
3208
- const [activeDropdown, setActiveDropdown] = React56.useState(null);
3209
- const menuBarRef = React56.useRef(null);
3210
- React56.useEffect(() => {
3402
+ const [activeDropdown, setActiveDropdown] = React.useState(null);
3403
+ const menuBarRef = React.useRef(null);
3404
+ React.useEffect(() => {
3211
3405
  function handleClickOutside(event) {
3212
3406
  if (menuBarRef.current && !menuBarRef.current.contains(event.target)) {
3213
3407
  setActiveDropdown(null);
@@ -3667,14 +3861,14 @@ function RichTextField({
3667
3861
  error,
3668
3862
  disabled
3669
3863
  }) {
3670
- const [isExpanded, setIsExpanded] = React56.useState(false);
3671
- const [panelWidth, setPanelWidth] = React56.useState(0);
3672
- const [isMediaPickerOpen, setIsMediaPickerOpen] = React56.useState(false);
3673
- const [isMounted, setIsMounted] = React56.useState(false);
3674
- React56.useEffect(() => {
3864
+ const [isExpanded, setIsExpanded] = React.useState(false);
3865
+ const [panelWidth, setPanelWidth] = React.useState(0);
3866
+ const [isMediaPickerOpen, setIsMediaPickerOpen] = React.useState(false);
3867
+ const [isMounted, setIsMounted] = React.useState(false);
3868
+ React.useEffect(() => {
3675
3869
  setIsMounted(true);
3676
3870
  }, []);
3677
- React56.useEffect(() => {
3871
+ React.useEffect(() => {
3678
3872
  if (!isExpanded) {
3679
3873
  setPanelWidth(0);
3680
3874
  return;
@@ -3740,7 +3934,7 @@ function RichTextField({
3740
3934
  }
3741
3935
  }
3742
3936
  });
3743
- React56.useEffect(() => {
3937
+ React.useEffect(() => {
3744
3938
  if (editor && value && JSON.stringify(value) !== JSON.stringify(editor.getJSON())) {
3745
3939
  editor.commands.setContent(value);
3746
3940
  }
@@ -4009,9 +4203,9 @@ function mergeThemes(base, overrides) {
4009
4203
  fields: base.fields ? { ...base.fields, ...overrides.fields } : overrides.fields
4010
4204
  };
4011
4205
  }
4012
- var ThemeContext = React56.createContext(null);
4206
+ var ThemeContext = React.createContext(null);
4013
4207
  function useTheme() {
4014
- const context = React56.useContext(ThemeContext);
4208
+ const context = React.useContext(ThemeContext);
4015
4209
  if (!context) {
4016
4210
  return {
4017
4211
  mode: "light",
@@ -4122,16 +4316,16 @@ function ThemeProvider({
4122
4316
  light: lightOverrides,
4123
4317
  dark: darkOverrides
4124
4318
  }) {
4125
- const [mode, setMode] = React56.useState(defaultMode);
4126
- const [baseLight, setBaseLight] = React56.useState(
4319
+ const [mode, setMode] = React.useState(defaultMode);
4320
+ const [baseLight, setBaseLight] = React.useState(
4127
4321
  lightOverrides || {}
4128
4322
  );
4129
- const [baseDark, setBaseDark] = React56.useState(
4323
+ const [baseDark, setBaseDark] = React.useState(
4130
4324
  darkOverrides || {}
4131
4325
  );
4132
4326
  const lightTheme = mergeThemes(LIGHT_THEME, baseLight);
4133
4327
  const darkTheme = mergeThemes(DARK_THEME, baseDark);
4134
- const getResolvedTheme = React56.useCallback(() => {
4328
+ const getResolvedTheme = React.useCallback(() => {
4135
4329
  if (mode === "system") {
4136
4330
  if (typeof window !== "undefined") {
4137
4331
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? darkTheme : lightTheme;
@@ -4140,13 +4334,13 @@ function ThemeProvider({
4140
4334
  }
4141
4335
  return mode === "dark" ? darkTheme : lightTheme;
4142
4336
  }, [mode, lightTheme, darkTheme]);
4143
- const [theme, setTheme] = React56.useState(getResolvedTheme());
4144
- React56.useEffect(() => {
4337
+ const [theme, setTheme] = React.useState(getResolvedTheme());
4338
+ React.useEffect(() => {
4145
4339
  const resolved = getResolvedTheme();
4146
4340
  setTheme(resolved);
4147
4341
  applyThemeToDOM(resolved);
4148
4342
  }, [getResolvedTheme]);
4149
- React56.useEffect(() => {
4343
+ React.useEffect(() => {
4150
4344
  if (mode !== "system") return;
4151
4345
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
4152
4346
  const handler = () => {
@@ -4157,11 +4351,11 @@ function ThemeProvider({
4157
4351
  mediaQuery.addEventListener("change", handler);
4158
4352
  return () => mediaQuery.removeEventListener("change", handler);
4159
4353
  }, [mode, getResolvedTheme]);
4160
- const updateTheme = React56.useCallback((overrides) => {
4354
+ const updateTheme = React.useCallback((overrides) => {
4161
4355
  setBaseLight((prev) => ({ ...prev, ...overrides }));
4162
4356
  setBaseDark((prev) => ({ ...prev, ...overrides }));
4163
4357
  }, []);
4164
- const getCssVar = React56.useCallback((key) => `var(--kyro-${key})`, []);
4358
+ const getCssVar = React.useCallback((key) => `var(--kyro-${key})`, []);
4165
4359
  return /* @__PURE__ */ jsxRuntime.jsx(
4166
4360
  ThemeContext.Provider,
4167
4361
  {
@@ -4180,7 +4374,7 @@ function ThemeProvider({
4180
4374
  }
4181
4375
  var LightThemeProvider = (props) => /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { defaultMode: "light", ...props });
4182
4376
  var DarkThemeProvider = (props) => /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { defaultMode: "dark", ...props });
4183
- var CodeMirrorEditor = React56.lazy(
4377
+ var CodeMirrorEditor = React.lazy(
4184
4378
  () => import('@uiw/react-codemirror').then((mod) => ({ default: mod.default }))
4185
4379
  );
4186
4380
  var LANGUAGES = [
@@ -4232,16 +4426,16 @@ var CodeField = ({
4232
4426
  error,
4233
4427
  disabled
4234
4428
  }) => {
4235
- const [isMounted, setIsMounted] = React56.useState(false);
4236
- const [isDark, setIsDark] = React56.useState(false);
4237
- const [extensions, setExtensions] = React56.useState([]);
4238
- const [loading, setLoading] = React56.useState(false);
4239
- const [copied, setCopied] = React56.useState(false);
4240
- const [isFullScreen, setIsFullScreen] = React56.useState(false);
4429
+ const [isMounted, setIsMounted] = React.useState(false);
4430
+ const [isDark, setIsDark] = React.useState(false);
4431
+ const [extensions, setExtensions] = React.useState([]);
4432
+ const [loading, setLoading] = React.useState(false);
4433
+ const [copied, setCopied] = React.useState(false);
4434
+ const [isFullScreen, setIsFullScreen] = React.useState(false);
4241
4435
  const { theme } = useTheme();
4242
4436
  const accent = theme.colors?.accent || theme.colors?.primary || "#6366f1";
4243
4437
  const language = field3.language?.toLowerCase() || "javascript";
4244
- React56.useEffect(() => {
4438
+ React.useEffect(() => {
4245
4439
  setIsMounted(true);
4246
4440
  setIsDark(document.documentElement.classList.contains("dark"));
4247
4441
  const observer = new MutationObserver(() => {
@@ -4253,7 +4447,7 @@ var CodeField = ({
4253
4447
  });
4254
4448
  return () => observer.disconnect();
4255
4449
  }, []);
4256
- React56.useEffect(() => {
4450
+ React.useEffect(() => {
4257
4451
  if (!isMounted) return;
4258
4452
  const loadExtensions = async () => {
4259
4453
  setLoading(true);
@@ -4270,16 +4464,16 @@ var CodeField = ({
4270
4464
  };
4271
4465
  loadExtensions();
4272
4466
  }, [language, isMounted]);
4273
- const handleChange = React56.useCallback(
4467
+ const handleChange = React.useCallback(
4274
4468
  (val) => onChange?.(val),
4275
4469
  [onChange]
4276
4470
  );
4277
- const handleCopy = React56.useCallback(() => {
4471
+ const handleCopy = React.useCallback(() => {
4278
4472
  navigator.clipboard.writeText(value);
4279
4473
  setCopied(true);
4280
4474
  setTimeout(() => setCopied(false), 1500);
4281
4475
  }, [value]);
4282
- const toggleFullScreen = React56.useCallback(() => {
4476
+ const toggleFullScreen = React.useCallback(() => {
4283
4477
  setIsFullScreen((prev) => !prev);
4284
4478
  document.body.style.overflow = !isFullScreen ? "hidden" : "";
4285
4479
  }, [isFullScreen]);
@@ -4369,7 +4563,7 @@ var CodeField = ({
4369
4563
  }
4370
4564
  ),
4371
4565
  /* @__PURE__ */ jsxRuntime.jsx(
4372
- React56.Suspense,
4566
+ React.Suspense,
4373
4567
  {
4374
4568
  fallback: /* @__PURE__ */ jsxRuntime.jsx(
4375
4569
  "div",
@@ -4489,18 +4683,18 @@ var MarkdownField = ({
4489
4683
  error,
4490
4684
  disabled
4491
4685
  }) => {
4492
- const [showPreview, setShowPreview] = React56.useState(false);
4493
- const [isMounted, setIsMounted] = React56.useState(false);
4494
- React56.useEffect(() => {
4686
+ const [showPreview, setShowPreview] = React.useState(false);
4687
+ const [isMounted, setIsMounted] = React.useState(false);
4688
+ React.useEffect(() => {
4495
4689
  setIsMounted(true);
4496
4690
  }, []);
4497
- const handleChange = React56.useCallback(
4691
+ const handleChange = React.useCallback(
4498
4692
  (e) => {
4499
4693
  onChange?.(e.target.value);
4500
4694
  },
4501
4695
  [onChange]
4502
4696
  );
4503
- const wordCount = React56.useMemo(() => {
4697
+ const wordCount = React.useMemo(() => {
4504
4698
  if (!value) return 0;
4505
4699
  return value.trim().split(/\s+/).filter(Boolean).length;
4506
4700
  }, [value]);
@@ -4605,8 +4799,8 @@ function SecretField({
4605
4799
  error,
4606
4800
  disabled
4607
4801
  }) {
4608
- const [copied, setCopied] = React56.useState(false);
4609
- const [regenerating, setRegenerating] = React56.useState(false);
4802
+ const [copied, setCopied] = React.useState(false);
4803
+ const [regenerating, setRegenerating] = React.useState(false);
4610
4804
  const fullValue = value ?? "";
4611
4805
  const displayValue = fullValue.length > 8 ? fullValue.slice(0, -8) + "*".repeat(8) : fullValue;
4612
4806
  const handleCopy = async () => {
@@ -5354,22 +5548,22 @@ function RelationshipField({
5354
5548
  error,
5355
5549
  disabled
5356
5550
  }) {
5357
- const [isOpen, setIsOpen] = React56.useState(false);
5358
- const [search, setSearch] = React56.useState("");
5359
- const [options, setOptions] = React56.useState([]);
5360
- const [loading, setLoading] = React56.useState(false);
5361
- const [selectedDocs, setSelectedDocs] = React56.useState([]);
5362
- const fetchedIdsRef = React56.useRef(/* @__PURE__ */ new Set());
5363
- const containerRef = React56.useRef(null);
5364
- const onChangeRef = React56.useRef(() => {
5551
+ const [isOpen, setIsOpen] = React.useState(false);
5552
+ const [search, setSearch] = React.useState("");
5553
+ const [options, setOptions] = React.useState([]);
5554
+ const [loading, setLoading] = React.useState(false);
5555
+ const [selectedDocs, setSelectedDocs] = React.useState([]);
5556
+ const fetchedIdsRef = React.useRef(/* @__PURE__ */ new Set());
5557
+ const containerRef = React.useRef(null);
5558
+ const onChangeRef = React.useRef(() => {
5365
5559
  });
5366
5560
  onChangeRef.current = onChange || (() => {
5367
5561
  });
5368
5562
  const isMultiple = field3.hasMany;
5369
5563
  const relationTo = Array.isArray(field3.relationTo) ? field3.relationTo : [field3.relationTo];
5370
5564
  const isPolymorphic = relationTo.length > 1;
5371
- const [activeRelation, setActiveRelation] = React56.useState(relationTo[0]);
5372
- const extractIds = React56.useCallback(() => {
5565
+ const [activeRelation, setActiveRelation] = React.useState(relationTo[0]);
5566
+ const extractIds = React.useCallback(() => {
5373
5567
  if (!value) return [];
5374
5568
  const items = isMultiple ? Array.isArray(value) ? value : [] : value ? [value] : [];
5375
5569
  return items.map((item) => {
@@ -5379,7 +5573,7 @@ function RelationshipField({
5379
5573
  return String(item);
5380
5574
  }).filter(Boolean);
5381
5575
  }, [value, isMultiple]);
5382
- const fetchSelectedDocs = React56.useCallback((ids) => {
5576
+ const fetchSelectedDocs = React.useCallback((ids) => {
5383
5577
  if (ids.length === 0) return;
5384
5578
  ids.forEach((id) => {
5385
5579
  if (fetchedIdsRef.current.has(id)) return;
@@ -5406,11 +5600,11 @@ function RelationshipField({
5406
5600
  });
5407
5601
  });
5408
5602
  }, [isPolymorphic, value, activeRelation, isMultiple]);
5409
- React56.useEffect(() => {
5603
+ React.useEffect(() => {
5410
5604
  const ids = extractIds();
5411
5605
  fetchSelectedDocs(ids);
5412
5606
  }, [extractIds, fetchSelectedDocs]);
5413
- const fetchOptions = React56.useCallback((query = "") => {
5607
+ const fetchOptions = React.useCallback((query = "") => {
5414
5608
  setLoading(true);
5415
5609
  const searchFields = ["title", "name", "label", "email"];
5416
5610
  const url = `/api/${activeRelation}?${buildSearchQuery(query, searchFields)}`;
@@ -5427,13 +5621,13 @@ function RelationshipField({
5427
5621
  setLoading(false);
5428
5622
  });
5429
5623
  }, [activeRelation]);
5430
- React56.useEffect(() => {
5624
+ React.useEffect(() => {
5431
5625
  if (isOpen) {
5432
5626
  setOptions([]);
5433
5627
  fetchOptions(search);
5434
5628
  }
5435
5629
  }, [isOpen, activeRelation]);
5436
- React56.useEffect(() => {
5630
+ React.useEffect(() => {
5437
5631
  const handleClickOutside = (event) => {
5438
5632
  if (containerRef.current && !containerRef.current.contains(event.target)) {
5439
5633
  setIsOpen(false);
@@ -5581,7 +5775,7 @@ function RelationshipField({
5581
5775
  ] });
5582
5776
  }
5583
5777
  var RelationshipField_default = RelationshipField;
5584
- var BlocksContext = React56.createContext(null);
5778
+ var BlocksContext = React.createContext(null);
5585
5779
  function createBlocksStore(allowedBlocks = [], dynamicCategories = []) {
5586
5780
  return vanilla.createStore((set, get) => ({
5587
5781
  blocks: [],
@@ -5736,7 +5930,7 @@ function getDefaultData(type) {
5736
5930
  return defaults[type] || {};
5737
5931
  }
5738
5932
  function useBlockById(id) {
5739
- const store = React56.useContext(BlocksContext);
5933
+ const store = React.useContext(BlocksContext);
5740
5934
  if (!store) return void 0;
5741
5935
  return zustand.useStore(store, (state) => {
5742
5936
  const findRecursive = (blocksList) => {
@@ -5761,7 +5955,7 @@ function useBlockById(id) {
5761
5955
  });
5762
5956
  }
5763
5957
  function useBlockActions() {
5764
- const store = React56.useContext(BlocksContext);
5958
+ const store = React.useContext(BlocksContext);
5765
5959
  if (!store) {
5766
5960
  throw new Error("useBlockActions must be used within a BlocksContext.Provider");
5767
5961
  }
@@ -6121,7 +6315,7 @@ var VideoBlock = ({
6121
6315
  {
6122
6316
  type: "button",
6123
6317
  onClick: () => removeBlock(block3.id),
6124
- className: "p-1 hover:bg-red-50 rounded text-red-500",
6318
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
6125
6319
  title: "Remove",
6126
6320
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
6127
6321
  }
@@ -6145,7 +6339,7 @@ var ListField = ({
6145
6339
  onChange,
6146
6340
  compact = false
6147
6341
  }) => {
6148
- const [inputValue, setInputValue] = React56__default.default.useState("");
6342
+ const [inputValue, setInputValue] = React__default.default.useState("");
6149
6343
  const handleAdd = () => {
6150
6344
  if (inputValue.trim()) {
6151
6345
  onChange([...items, inputValue.trim()]);
@@ -6231,7 +6425,7 @@ var ListBlock = ({
6231
6425
  {
6232
6426
  type: "button",
6233
6427
  onClick: () => removeBlock(block3.id),
6234
- className: "p-1 hover:bg-red-50 rounded text-red-500",
6428
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
6235
6429
  title: "Remove",
6236
6430
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
6237
6431
  }
@@ -6280,7 +6474,7 @@ var CodeBlock = ({
6280
6474
  {
6281
6475
  type: "button",
6282
6476
  onClick: () => removeBlock(block3.id),
6283
- className: "p-1.5 hover:bg-red-500/10 rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-red-500",
6477
+ className: "p-1.5 hover:bg-[var(--kyro-danger-bg)] rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-[var(--kyro-danger)]",
6284
6478
  title: "Remove",
6285
6479
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
6286
6480
  }
@@ -6379,7 +6573,7 @@ var FileBlock = ({
6379
6573
  {
6380
6574
  type: "button",
6381
6575
  onClick: () => removeBlock(block3.id),
6382
- className: "p-1 hover:bg-red-50 rounded text-red-500",
6576
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
6383
6577
  title: "Remove",
6384
6578
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
6385
6579
  }
@@ -6401,7 +6595,7 @@ var AccordionField = ({
6401
6595
  onChange,
6402
6596
  compact = false
6403
6597
  }) => {
6404
- const [openIndex, setOpenIndex] = React56__default.default.useState(0);
6598
+ const [openIndex, setOpenIndex] = React__default.default.useState(0);
6405
6599
  const handleTitleChange = (index, value) => {
6406
6600
  const newItems = [...items];
6407
6601
  newItems[index] = { ...newItems[index], title: value };
@@ -6625,7 +6819,7 @@ var AccordionBlock = ({
6625
6819
  {
6626
6820
  type: "button",
6627
6821
  onClick: () => removeBlock(block3.id),
6628
- className: "p-1 hover:bg-red-50 rounded text-red-500",
6822
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
6629
6823
  title: "Remove",
6630
6824
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
6631
6825
  }
@@ -6677,7 +6871,7 @@ var RichTextBlock = ({
6677
6871
  {
6678
6872
  type: "button",
6679
6873
  onClick: () => removeBlock(block3.id),
6680
- className: "p-1 hover:bg-red-50 rounded text-red-500",
6874
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
6681
6875
  title: "Remove",
6682
6876
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
6683
6877
  }
@@ -6827,7 +7021,7 @@ function ArrayLayout({
6827
7021
  const firstField = fields2[0];
6828
7022
  const labelField = firstField?.name || "user";
6829
7023
  const isRelationship = firstField?.type === "relationship";
6830
- const [openIndex, setOpenIndex] = React56__default.default.useState(0);
7024
+ const [openIndex, setOpenIndex] = React__default.default.useState(0);
6831
7025
  function getItemLabel(item) {
6832
7026
  for (const key of ["label", "title", "name"]) {
6833
7027
  const val = item[key];
@@ -7367,11 +7561,11 @@ var ChildBlocksTree = ({
7367
7561
  depth = 0,
7368
7562
  maxDepth = MAX_DEPTH
7369
7563
  }) => {
7370
- const [showAddModal, setShowAddModal] = React56.useState(false);
7371
- const [expandedIds, setExpandedIds] = React56.useState(/* @__PURE__ */ new Set());
7372
- const [editingBlockId, setEditingBlockId] = React56.useState(null);
7373
- const [confirmDeleteId, setConfirmDeleteId] = React56.useState(null);
7374
- const store = React56.useContext(BlocksContext);
7564
+ const [showAddModal, setShowAddModal] = React.useState(false);
7565
+ const [expandedIds, setExpandedIds] = React.useState(/* @__PURE__ */ new Set());
7566
+ const [editingBlockId, setEditingBlockId] = React.useState(null);
7567
+ const [confirmDeleteId, setConfirmDeleteId] = React.useState(null);
7568
+ const store = React.useContext(BlocksContext);
7375
7569
  if (!store) throw new Error("ChildBlocksTree must be used within a BlocksContext");
7376
7570
  const dynamicCategories = zustand.useStore(store, (s) => s.dynamicCategories);
7377
7571
  const allowedBlocks = zustand.useStore(store, (s) => s.allowedBlocks);
@@ -7464,7 +7658,7 @@ var ChildBlocksTree = ({
7464
7658
  handleRemoveChild(child.id);
7465
7659
  setConfirmDeleteId(null);
7466
7660
  },
7467
- className: "px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600",
7661
+ className: "px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded",
7468
7662
  children: "Remove"
7469
7663
  }
7470
7664
  ),
@@ -7487,8 +7681,8 @@ var ChildBlocksTree = ({
7487
7681
  e.stopPropagation();
7488
7682
  setConfirmDeleteId(child.id);
7489
7683
  },
7490
- className: "p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-red-50",
7491
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5 text-red-500 invisible group-hover/column:visible" })
7684
+ className: "p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]",
7685
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5 text-[var(--kyro-danger)] invisible group-hover/column:visible" })
7492
7686
  }
7493
7687
  )
7494
7688
  ]
@@ -7588,11 +7782,11 @@ var NestedChildBlocks = ({
7588
7782
  depth,
7589
7783
  maxDepth
7590
7784
  }) => {
7591
- const [showAddModal, setShowAddModal] = React56.useState(false);
7592
- const [expandedIds, setExpandedIds] = React56.useState(/* @__PURE__ */ new Set());
7593
- const [editingBlockId, setEditingBlockId] = React56.useState(null);
7594
- const [confirmDeleteId, setConfirmDeleteId] = React56.useState(null);
7595
- const store = React56.useContext(BlocksContext);
7785
+ const [showAddModal, setShowAddModal] = React.useState(false);
7786
+ const [expandedIds, setExpandedIds] = React.useState(/* @__PURE__ */ new Set());
7787
+ const [editingBlockId, setEditingBlockId] = React.useState(null);
7788
+ const [confirmDeleteId, setConfirmDeleteId] = React.useState(null);
7789
+ const store = React.useContext(BlocksContext);
7596
7790
  if (!store) throw new Error("NestedChildBlocks must be used within a BlocksContext");
7597
7791
  const dynamicCategories = zustand.useStore(store, (s) => s.dynamicCategories);
7598
7792
  const allowedBlocks = zustand.useStore(store, (s) => s.allowedBlocks);
@@ -7685,7 +7879,7 @@ var NestedChildBlocks = ({
7685
7879
  handleRemoveChild(child.id);
7686
7880
  setConfirmDeleteId(null);
7687
7881
  },
7688
- className: "px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600",
7882
+ className: "px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded",
7689
7883
  children: "Remove"
7690
7884
  }
7691
7885
  ),
@@ -7708,8 +7902,8 @@ var NestedChildBlocks = ({
7708
7902
  e.stopPropagation();
7709
7903
  setConfirmDeleteId(child.id);
7710
7904
  },
7711
- className: "p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-red-50",
7712
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5 text-red-500" })
7905
+ className: "p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]",
7906
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5 text-[var(--kyro-danger)]" })
7713
7907
  }
7714
7908
  )
7715
7909
  ]
@@ -7842,7 +8036,7 @@ var HeroBlock = ({
7842
8036
  {
7843
8037
  type: "button",
7844
8038
  onClick: () => removeBlock(block3.id),
7845
- className: "p-1 hover:bg-red-50 rounded text-red-500",
8039
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
7846
8040
  title: "Remove",
7847
8041
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
7848
8042
  }
@@ -8070,7 +8264,7 @@ var ArrayBlock = ({
8070
8264
  {
8071
8265
  type: "button",
8072
8266
  onClick: () => removeBlock(block3.id),
8073
- className: "p-1 hover:bg-red-50 rounded text-red-500",
8267
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
8074
8268
  title: "Remove",
8075
8269
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
8076
8270
  }
@@ -8096,13 +8290,13 @@ var RelationshipBlockField = ({
8096
8290
  onChange,
8097
8291
  compact = false
8098
8292
  }) => {
8099
- const [isOpen, setIsOpen] = React56.useState(false);
8100
- const [search, setSearch] = React56.useState("");
8101
- const [options, setOptions] = React56.useState([]);
8102
- const [loading, setLoading] = React56.useState(false);
8103
- const [collections2, setCollections] = React56.useState([]);
8104
- const [loadingCollections, setLoadingCollections] = React56.useState(true);
8105
- React56.useEffect(() => {
8293
+ const [isOpen, setIsOpen] = React.useState(false);
8294
+ const [search, setSearch] = React.useState("");
8295
+ const [options, setOptions] = React.useState([]);
8296
+ const [loading, setLoading] = React.useState(false);
8297
+ const [collections2, setCollections] = React.useState([]);
8298
+ const [loadingCollections, setLoadingCollections] = React.useState(true);
8299
+ React.useEffect(() => {
8106
8300
  apiGet("/api/collections").then((data) => {
8107
8301
  setCollections(
8108
8302
  (data.collections || []).map((c) => c.slug || c.name || c)
@@ -8118,7 +8312,7 @@ var RelationshipBlockField = ({
8118
8312
  setLoading(false);
8119
8313
  }).catch(() => setLoading(false));
8120
8314
  };
8121
- React56.useEffect(() => {
8315
+ React.useEffect(() => {
8122
8316
  if (isOpen) fetchOptions(search);
8123
8317
  }, [isOpen, search, relationTo, labelField]);
8124
8318
  const getLabel2 = (opt) => {
@@ -8287,7 +8481,7 @@ var RelationshipBlock = ({
8287
8481
  {
8288
8482
  type: "button",
8289
8483
  onClick: () => removeBlock(block3.id),
8290
- className: "p-1 hover:bg-red-50 rounded text-red-500",
8484
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]",
8291
8485
  title: "Remove",
8292
8486
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
8293
8487
  }
@@ -8448,7 +8642,7 @@ var SortableBlockComponent = ({
8448
8642
  } = sortable.useSortable({ id: block3.id });
8449
8643
  const { removeBlock } = useBlockActions();
8450
8644
  const isEditing = editingBlockId === block3.id;
8451
- const [showDeleteConfirm, setShowDeleteConfirm] = React56.useState(false);
8645
+ const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);
8452
8646
  const style = {
8453
8647
  transform: utilities.CSS.Transform.toString(transform),
8454
8648
  transition,
@@ -8487,7 +8681,7 @@ var SortableBlockComponent = ({
8487
8681
  removeBlock(block3.id);
8488
8682
  setShowDeleteConfirm(false);
8489
8683
  },
8490
- className: "px-1.5 py-0.5 text-[9px] bg-red-500 hover:bg-red-600 text-white rounded font-semibold transition-colors",
8684
+ className: "px-1.5 py-0.5 text-[9px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90",
8491
8685
  children: "Remove"
8492
8686
  }
8493
8687
  ),
@@ -8522,7 +8716,7 @@ var SortableBlockComponent = ({
8522
8716
  e.stopPropagation();
8523
8717
  setShowDeleteConfirm(true);
8524
8718
  },
8525
- className: "p-0.5 hover:bg-red-50 hover:text-red-500 rounded text-[var(--kyro-text-muted)] transition-colors",
8719
+ className: "p-0.5 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors",
8526
8720
  title: "Remove",
8527
8721
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
8528
8722
  }
@@ -8541,11 +8735,11 @@ var SortableBlockComponent = ({
8541
8735
  )
8542
8736
  ] });
8543
8737
  }
8544
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: setNodeRef, style, className: "relative group pl-8 mb-2", children: [
8738
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: setNodeRef, style, className: "relative group md:pl-8 mb-2", children: [
8545
8739
  /* @__PURE__ */ jsxRuntime.jsx(
8546
8740
  "div",
8547
8741
  {
8548
- className: "absolute left-0 top-1/2 -translate-y-1/2 p-1.5 cursor-grab active:cursor-grabbing text-[var(--kyro-text-muted)] opacity-0 group-hover:opacity-100 transition-opacity hover:bg-[var(--kyro-surface-accent)] rounded",
8742
+ className: "hidden md:absolute left-0 top-1/2 -translate-y-1/2 p-1.5 cursor-grab active:cursor-grabbing text-[var(--kyro-text-muted)] opacity-0 group-hover:opacity-100 transition-opacity hover:bg-[var(--kyro-surface-accent)] rounded",
8549
8743
  ...attributes,
8550
8744
  ...listeners,
8551
8745
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "w-4 h-4" })
@@ -8586,7 +8780,7 @@ var SortableBlockComponent = ({
8586
8780
  removeBlock(block3.id);
8587
8781
  setShowDeleteConfirm(false);
8588
8782
  },
8589
- className: "px-2.5 py-1 text-[10px] bg-red-500 hover:bg-red-600 text-white rounded font-semibold transition-colors",
8783
+ className: "px-2.5 py-1 text-[10px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90",
8590
8784
  children: "Remove"
8591
8785
  }
8592
8786
  ),
@@ -8623,7 +8817,7 @@ var SortableBlockComponent = ({
8623
8817
  e.stopPropagation();
8624
8818
  setShowDeleteConfirm(true);
8625
8819
  },
8626
- className: "p-1 hover:bg-red-50 hover:text-red-500 rounded text-[var(--kyro-text-muted)] transition-colors",
8820
+ className: "p-1 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors",
8627
8821
  title: "Remove Block",
8628
8822
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3.5 h-3.5" })
8629
8823
  }
@@ -8642,7 +8836,7 @@ var SortableBlockComponent = ({
8642
8836
  )
8643
8837
  ] });
8644
8838
  };
8645
- var SortableBlock = React56__default.default.memo(SortableBlockComponent);
8839
+ var SortableBlock = React__default.default.memo(SortableBlockComponent);
8646
8840
  var BlocksField = ({
8647
8841
  field: field3,
8648
8842
  value,
@@ -8653,9 +8847,9 @@ var BlocksField = ({
8653
8847
  documentStatus,
8654
8848
  justSaved
8655
8849
  }) => {
8656
- const [isDrawerOpen, setIsDrawerOpen] = React56.useState(false);
8657
- const [isDropdownOpen, setIsDropdownOpen] = React56.useState(false);
8658
- const dropdownRef = React56.useRef(null);
8850
+ const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
8851
+ const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
8852
+ const dropdownRef = React.useRef(null);
8659
8853
  const pickerMode = field3.admin?.pickerMode || "drawer";
8660
8854
  const allowedBlocks = field3.blocks || [];
8661
8855
  const groupedBlocks = allowedBlocks.reduce((acc, block3) => {
@@ -8685,18 +8879,18 @@ var BlocksField = ({
8685
8879
  title,
8686
8880
  blocks: blocks3
8687
8881
  }));
8688
- const storeRef = React56.useRef(null);
8882
+ const storeRef = React.useRef(null);
8689
8883
  if (!storeRef.current) {
8690
8884
  storeRef.current = createBlocksStore(allowedBlocks, dynamicCategories);
8691
8885
  }
8692
8886
  const store = storeRef.current;
8693
8887
  const blocks2 = zustand.useStore(store, (s) => s.blocks);
8694
- const [activeDrag, setActiveDrag] = React56.useState(null);
8695
- const [editingBlockId, setEditingBlockId] = React56.useState(null);
8696
- const prevBlocksLengthRef = React56.useRef(blocks2.length);
8697
- const prevBlockIdsRef = React56.useRef(new Set(blocks2.map((b) => b.id)));
8698
- const isInitializedRef = React56.useRef(false);
8699
- React56.useEffect(() => {
8888
+ const [activeDrag, setActiveDrag] = React.useState(null);
8889
+ const [editingBlockId, setEditingBlockId] = React.useState(null);
8890
+ const prevBlocksLengthRef = React.useRef(blocks2.length);
8891
+ const prevBlockIdsRef = React.useRef(new Set(blocks2.map((b) => b.id)));
8892
+ const isInitializedRef = React.useRef(false);
8893
+ React.useEffect(() => {
8700
8894
  if (isInitializedRef.current) {
8701
8895
  if (blocks2.length > prevBlocksLengthRef.current) {
8702
8896
  const newBlock = blocks2.find((b) => b.id && !prevBlockIdsRef.current.has(b.id));
@@ -8708,7 +8902,7 @@ var BlocksField = ({
8708
8902
  prevBlocksLengthRef.current = blocks2.length;
8709
8903
  prevBlockIdsRef.current = new Set(blocks2.map((b) => b.id));
8710
8904
  }, [blocks2]);
8711
- React56.useEffect(() => {
8905
+ React.useEffect(() => {
8712
8906
  if (onBlocksChange) {
8713
8907
  store.getState().setOnBlocksChange(onBlocksChange);
8714
8908
  }
@@ -8717,8 +8911,8 @@ var BlocksField = ({
8717
8911
  });
8718
8912
  };
8719
8913
  }, [onBlocksChange, store]);
8720
- const lastValueRef = React56.useRef(null);
8721
- React56.useEffect(() => {
8914
+ const lastValueRef = React.useRef(null);
8915
+ React.useEffect(() => {
8722
8916
  const valueArray = Array.isArray(value) ? value : [];
8723
8917
  const lastValueArray = lastValueRef.current || [];
8724
8918
  if (JSON.stringify(valueArray) !== JSON.stringify(lastValueArray)) {
@@ -8733,9 +8927,9 @@ var BlocksField = ({
8733
8927
  lastValueRef.current = [];
8734
8928
  }
8735
8929
  }, [value, field3.name, store]);
8736
- const onChangeRef = React56.useRef(onChange);
8930
+ const onChangeRef = React.useRef(onChange);
8737
8931
  onChangeRef.current = onChange;
8738
- React56.useEffect(() => {
8932
+ React.useEffect(() => {
8739
8933
  if (!onChangeRef.current) return;
8740
8934
  const lastValue = lastValueRef.current;
8741
8935
  if (!lastValue) return;
@@ -8744,13 +8938,13 @@ var BlocksField = ({
8744
8938
  onChangeRef.current(blocks2);
8745
8939
  }
8746
8940
  }, [blocks2]);
8747
- const handleAddBlock = React56.useCallback(
8941
+ const handleAddBlock = React.useCallback(
8748
8942
  (blockType) => {
8749
8943
  store.getState().addBlock(blockType);
8750
8944
  },
8751
8945
  [store]
8752
8946
  );
8753
- const duplicateBlock = React56.useCallback(
8947
+ const duplicateBlock = React.useCallback(
8754
8948
  (blockId) => {
8755
8949
  const blockIndex = blocks2.findIndex((b) => b.id === blockId);
8756
8950
  if (blockIndex === -1) return;
@@ -8813,9 +9007,9 @@ var BlocksField = ({
8813
9007
  }
8814
9008
  }
8815
9009
  };
8816
- const activeBlock = activeDrag ? blockCategories.flatMap((cat) => cat.blocks).find((b) => `drawer-${b.type}` === activeDrag.id) || blocks2.find((b) => b.id === activeDrag.id) : null;
9010
+ const activeBlock = activeDrag ? dynamicCategories.flatMap((cat) => cat.blocks).find((b) => `drawer-${b.type}` === activeDrag.id) || blocks2.find((b) => b.id === activeDrag.id) : null;
8817
9011
  activeBlock ? "label" in activeBlock ? activeBlock.label : activeBlock.type : "Block";
8818
- React56.useEffect(() => {
9012
+ React.useEffect(() => {
8819
9013
  if (!isDropdownOpen) return;
8820
9014
  const handleClick = (e) => {
8821
9015
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
@@ -8976,9 +9170,9 @@ function normalizeUploadFields(value) {
8976
9170
  return value;
8977
9171
  }
8978
9172
  function useQueue() {
8979
- const queue = React56.useRef([]);
8980
- const isProcessing = React56.useRef(false);
8981
- const queueTask = React56.useCallback((fn, options) => {
9173
+ const queue = React.useRef([]);
9174
+ const isProcessing = React.useRef(false);
9175
+ const queueTask = React.useCallback((fn, options) => {
8982
9176
  queue.current.push(fn);
8983
9177
  async function processQueue() {
8984
9178
  if (isProcessing.current) return;
@@ -9041,27 +9235,27 @@ function useAutoFormState({
9041
9235
  } = store;
9042
9236
  const versionsEnabled = !!config.versions;
9043
9237
  const currentContextKey = globalSlug || initialData?.id || collectionSlug;
9044
- const needsResetRef = React56.useRef(false);
9238
+ const needsResetRef = React.useRef(false);
9045
9239
  if (!globalSlug && currentContextKey && formData && Object.keys(formData).length > 0 && formData.id !== currentContextKey) {
9046
9240
  needsResetRef.current = true;
9047
9241
  }
9048
- React56.useEffect(() => {
9242
+ React.useEffect(() => {
9049
9243
  if (needsResetRef.current) {
9050
9244
  needsResetRef.current = false;
9051
9245
  resetForm();
9052
9246
  }
9053
9247
  }, [resetForm]);
9054
- const localSaveTimerRef = React56.useRef(null);
9055
- const serverSaveTimerRef = React56.useRef(null);
9056
- const retryTimerRef = React56.useRef(null);
9057
- const isOnlineRef = React56.useRef(typeof navigator !== "undefined" ? navigator.onLine : true);
9058
- const lastAutoSaveTimeRef = React56.useRef(0);
9059
- const autoSaveSkipRef = React56.useRef(false);
9060
- const restorePromptedRef = React56.useRef(null);
9061
- const previousFormDataRef = React56.useRef("");
9062
- const astroSyncDataRef = React56.useRef("");
9248
+ const localSaveTimerRef = React.useRef(null);
9249
+ const serverSaveTimerRef = React.useRef(null);
9250
+ const retryTimerRef = React.useRef(null);
9251
+ const isOnlineRef = React.useRef(typeof navigator !== "undefined" ? navigator.onLine : true);
9252
+ const lastAutoSaveTimeRef = React.useRef(0);
9253
+ const autoSaveSkipRef = React.useRef(false);
9254
+ const restorePromptedRef = React.useRef(null);
9255
+ const previousFormDataRef = React.useRef("");
9256
+ const astroSyncDataRef = React.useRef("");
9063
9257
  const { queueTask } = useQueue();
9064
- const getDocumentKey = React56.useCallback(
9258
+ const getDocumentKey = React.useCallback(
9065
9259
  (id) => {
9066
9260
  if (globalSlug) return `global:${globalSlug}`;
9067
9261
  if (collectionSlug && id) return `${collectionSlug}:${id}`;
@@ -9069,7 +9263,7 @@ function useAutoFormState({
9069
9263
  },
9070
9264
  [collectionSlug, globalSlug]
9071
9265
  );
9072
- const persistBrowserDraft = React56.useCallback(
9266
+ const persistBrowserDraft = React.useCallback(
9073
9267
  (documentKey, data, options) => {
9074
9268
  setDraftCache(documentKey, {
9075
9269
  data,
@@ -9080,7 +9274,7 @@ function useAutoFormState({
9080
9274
  },
9081
9275
  [lastSavedData.updatedAt, setDraftCache]
9082
9276
  );
9083
- const fetchVersions = React56.useCallback(async () => {
9277
+ const fetchVersions = React.useCallback(async () => {
9084
9278
  const url = globalSlug ? resolveApi(`/api/globals/${globalSlug}/versions`) : collectionSlug && formData.id ? resolveApi(`/api/${collectionSlug}/${formData.id}/versions`) : null;
9085
9279
  if (!url) return;
9086
9280
  setLoadingVersions(true);
@@ -9094,7 +9288,7 @@ function useAutoFormState({
9094
9288
  setLoadingVersions(false);
9095
9289
  }
9096
9290
  }, [formData.id, collectionSlug, globalSlug, setLoadingVersions, setVersions]);
9097
- const performLocalAutoSave = React56.useCallback(() => {
9291
+ const performLocalAutoSave = React.useCallback(() => {
9098
9292
  const state = useAutoFormStore.getState();
9099
9293
  const latestFormData = state.formData;
9100
9294
  if (autoSaveSkipRef.current || !collectionSlug || !latestFormData.id) return;
@@ -9104,7 +9298,7 @@ function useAutoFormState({
9104
9298
  persistBrowserDraft(documentKey, latestFormData);
9105
9299
  }
9106
9300
  }, [collectionSlug, getDocumentKey, persistBrowserDraft]);
9107
- const doAutosaveFetch = React56.useCallback(async (options) => {
9301
+ const doAutosaveFetch = React.useCallback(async (options) => {
9108
9302
  const state = useAutoFormStore.getState();
9109
9303
  const latestFormData = state.formData;
9110
9304
  const currentLastSaved = state.lastSavedData;
@@ -9187,7 +9381,7 @@ function useAutoFormState({
9187
9381
  setIsAutoSaving,
9188
9382
  versionsEnabled
9189
9383
  ]);
9190
- const performAutosave = React56.useCallback((options) => {
9384
+ const performAutosave = React.useCallback((options) => {
9191
9385
  queueTask(
9192
9386
  () => doAutosaveFetch(options),
9193
9387
  {
@@ -9199,7 +9393,7 @@ function useAutoFormState({
9199
9393
  }
9200
9394
  );
9201
9395
  }, [doAutosaveFetch, queueTask]);
9202
- const saveDocument = React56.useCallback(
9396
+ const saveDocument = React.useCallback(
9203
9397
  async (dataOverride, isDraft = true) => {
9204
9398
  const state = useAutoFormStore.getState();
9205
9399
  const payload = dataOverride || state.formData;
@@ -9225,17 +9419,17 @@ function useAutoFormState({
9225
9419
  },
9226
9420
  [collectionSlug, globalSlug, setAutoSaveStatus]
9227
9421
  );
9228
- React56.useEffect(() => {
9422
+ React.useEffect(() => {
9229
9423
  const handleToggle = () => {
9230
9424
  setSidebarCollapsed(!sidebarCollapsed);
9231
9425
  };
9232
9426
  window.addEventListener("toggle-sidebar", handleToggle);
9233
9427
  return () => window.removeEventListener("toggle-sidebar", handleToggle);
9234
9428
  }, [sidebarCollapsed, setSidebarCollapsed]);
9235
- const lastLoadedSlugRef = React56.useRef(null);
9236
- const lastInitialDataRef = React56.useRef("");
9237
- const initialDataLoadedRef = React56.useRef(false);
9238
- React56.useEffect(() => {
9429
+ const lastLoadedSlugRef = React.useRef(null);
9430
+ const lastInitialDataRef = React.useRef("");
9431
+ const initialDataLoadedRef = React.useRef(false);
9432
+ React.useEffect(() => {
9239
9433
  const currentSlug = globalSlug || initialData?.id;
9240
9434
  const serialized = JSON.stringify(initialData);
9241
9435
  if (initialDataLoadedRef.current && lastLoadedSlugRef.current === currentSlug && lastInitialDataRef.current === serialized) return;
@@ -9244,7 +9438,7 @@ function useAutoFormState({
9244
9438
  lastLoadedSlugRef.current = currentSlug;
9245
9439
  lastInitialDataRef.current = serialized;
9246
9440
  }, [collectionSlug, formData.id, globalSlug, initialData, loadDocument]);
9247
- React56.useEffect(() => {
9441
+ React.useEffect(() => {
9248
9442
  if (!collectionSlug || !initialData?.id) return;
9249
9443
  const documentKey = getDocumentKey(initialData.id);
9250
9444
  if (!documentKey) return;
@@ -9307,7 +9501,7 @@ function useAutoFormState({
9307
9501
  }
9308
9502
  return void 0;
9309
9503
  }
9310
- React56.useEffect(() => {
9504
+ React.useEffect(() => {
9311
9505
  const fields2 = config.fields;
9312
9506
  const metaTitleField = findFieldDeep(fields2, "metaTitle");
9313
9507
  if (!metaTitleField) return;
@@ -9317,7 +9511,7 @@ function useAutoFormState({
9317
9511
  setField("metaTitle", titleStr);
9318
9512
  }
9319
9513
  }, [formData, config.fields, setField]);
9320
- React56.useEffect(() => {
9514
+ React.useEffect(() => {
9321
9515
  const fields2 = config.fields;
9322
9516
  const slugField = fields2.find(
9323
9517
  (f) => f.name === "slug" && f.admin?.autoGenerate
@@ -9332,7 +9526,7 @@ function useAutoFormState({
9332
9526
  }
9333
9527
  }
9334
9528
  }, [formData, isSlugLocked, config.fields, setField]);
9335
- React56.useEffect(() => {
9529
+ React.useEffect(() => {
9336
9530
  if (sidebarCollapsed) return;
9337
9531
  if (!globalSlug && (!collectionSlug || !formData.id)) return;
9338
9532
  const state = useAutoFormStore.getState();
@@ -9349,7 +9543,7 @@ function useAutoFormState({
9349
9543
  performAutosave();
9350
9544
  }, 8e3);
9351
9545
  }, [formData, sidebarCollapsed, collectionSlug, globalSlug, performLocalAutoSave, performAutosave]);
9352
- React56.useEffect(() => {
9546
+ React.useEffect(() => {
9353
9547
  if (!globalSlug && (!collectionSlug || !formData.id)) return;
9354
9548
  const flushDraft = () => {
9355
9549
  if (autoSaveSkipRef.current) return;
@@ -9386,7 +9580,7 @@ function useAutoFormState({
9386
9580
  document.removeEventListener("visibilitychange", handleVisibilityChange);
9387
9581
  };
9388
9582
  }, [collectionSlug, globalSlug, formData.id, performAutosave]);
9389
- React56.useEffect(() => {
9583
+ React.useEffect(() => {
9390
9584
  const serialized = JSON.stringify(formData);
9391
9585
  if (serialized === astroSyncDataRef.current) return;
9392
9586
  astroSyncDataRef.current = serialized;
@@ -9396,7 +9590,7 @@ function useAutoFormState({
9396
9590
  }
9397
9591
  onChange?.(formData);
9398
9592
  }, [formData, onChange]);
9399
- React56.useEffect(() => {
9593
+ React.useEffect(() => {
9400
9594
  if (globalSlug || formData.id) fetchVersions();
9401
9595
  }, [formData.id, globalSlug, fetchVersions]);
9402
9596
  const documentStatus = (() => {
@@ -9423,9 +9617,9 @@ function Dropdown({
9423
9617
  align = "right",
9424
9618
  direction = "up"
9425
9619
  }) {
9426
- const [open, setOpen] = React56.useState(false);
9427
- const ref = React56.useRef(null);
9428
- React56.useEffect(() => {
9620
+ const [open, setOpen] = React.useState(false);
9621
+ const ref = React.useRef(null);
9622
+ React.useEffect(() => {
9429
9623
  const handleClickOutside = (e) => {
9430
9624
  if (ref.current && !ref.current.contains(e.target)) {
9431
9625
  setOpen(false);
@@ -9552,7 +9746,7 @@ function TabsLayout({
9552
9746
  onTabDataChange,
9553
9747
  renderField
9554
9748
  }) {
9555
- const [activeTab, setActiveTab] = React56.useState(0);
9749
+ const [activeTab, setActiveTab] = React.useState(0);
9556
9750
  const fieldTabs = field3.tabs || [];
9557
9751
  const currentTab = fieldTabs[activeTab] || fieldTabs[0];
9558
9752
  const tabData = field3.name ? formData[field3.name] || {} : formData;
@@ -9653,13 +9847,13 @@ function AutoForm({
9653
9847
  onActionSuccess,
9654
9848
  onActionError
9655
9849
  });
9656
- const menuRef = React56.useRef(null);
9657
- const scheduleRef = React56.useRef(null);
9658
- const [showSchedulePicker, setShowSchedulePicker] = React56.useState(false);
9659
- const [localSaveStatus, setLocalSaveStatus] = React56.useState("idle");
9660
- const [now, setNow] = React56.useState(Date.now());
9850
+ const menuRef = React.useRef(null);
9851
+ const scheduleRef = React.useRef(null);
9852
+ const [showSchedulePicker, setShowSchedulePicker] = React.useState(false);
9853
+ const [localSaveStatus, setLocalSaveStatus] = React.useState("idle");
9854
+ const [now, setNow] = React.useState(Date.now());
9661
9855
  const disabled = propDisabled;
9662
- React56.useEffect(() => {
9856
+ React.useEffect(() => {
9663
9857
  const id = setInterval(() => setNow(Date.now()), 1e4);
9664
9858
  return () => clearInterval(id);
9665
9859
  }, []);
@@ -9737,7 +9931,7 @@ function AutoForm({
9737
9931
  return [...prev, versionId];
9738
9932
  });
9739
9933
  };
9740
- React56.useEffect(() => {
9934
+ React.useEffect(() => {
9741
9935
  const handleShortcuts = (e) => {
9742
9936
  if ((e.metaKey || e.ctrlKey) && e.key === "s") {
9743
9937
  e.preventDefault();
@@ -9760,12 +9954,12 @@ function AutoForm({
9760
9954
  window.addEventListener("keydown", handleShortcuts);
9761
9955
  return () => window.removeEventListener("keydown", handleShortcuts);
9762
9956
  }, []);
9763
- React56.useEffect(() => {
9957
+ React.useEffect(() => {
9764
9958
  const handler = () => setView("version");
9765
9959
  window.addEventListener("kyro:show-version-history", handler);
9766
9960
  return () => window.removeEventListener("kyro:show-version-history", handler);
9767
9961
  }, []);
9768
- React56.useEffect(() => {
9962
+ React.useEffect(() => {
9769
9963
  const handleClickOutside = (e) => {
9770
9964
  if (menuRef.current && !menuRef.current.contains(e.target)) {
9771
9965
  setIsMenuOpen(false);
@@ -9776,7 +9970,7 @@ function AutoForm({
9776
9970
  return () => document.removeEventListener("mousedown", handleClickOutside);
9777
9971
  }
9778
9972
  }, [isMenuOpen]);
9779
- React56.useEffect(() => {
9973
+ React.useEffect(() => {
9780
9974
  const handleClickOutside = (e) => {
9781
9975
  if (scheduleRef.current && !scheduleRef.current.contains(e.target)) {
9782
9976
  setShowSchedulePicker(false);
@@ -10061,7 +10255,7 @@ function AutoForm({
10061
10255
  return /* @__PURE__ */ jsxRuntime.jsx(
10062
10256
  "div",
10063
10257
  {
10064
- className: "kyro-form-row flex gap-6 items-end",
10258
+ className: "kyro-form-row flex flex-col md:flex-row gap-4 md:gap-6 items-start md:items-end w-full",
10065
10259
  children: rowFields?.map((f) => {
10066
10260
  const fAdmin = f.admin || {};
10067
10261
  const actionUrl = fAdmin?.action;
@@ -10293,24 +10487,24 @@ function AutoForm({
10293
10487
  const statusLabel = hasUnpublishedChanges ? "Draft (unpublished changes)" : docStatus === "published" ? "Published" : "Draft";
10294
10488
  const statusColor = docStatus === "published" && !hasUnsavedChanges ? "bg-[var(--kyro-success)]" : hasUnpublishedChanges ? "bg-[var(--kyro-warning)]" : "bg-[var(--kyro-text-muted)]";
10295
10489
  const statusBadgeBg = docStatus === "published" && !hasUnpublishedChanges ? "bg-[var(--kyro-success)]/10 text-[var(--kyro-success)] border-[var(--kyro-success)]/20" : hasUnpublishedChanges ? "bg-[var(--kyro-warning)]/10 text-[var(--kyro-warning)] border-[var(--kyro-warning)]/20" : "bg-[var(--kyro-text-muted)]/10 text-[var(--kyro-text-muted)] border-[var(--kyro-text-muted)]/20";
10296
- return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "surface-tile px-8 py-6 flex items-center justify-between sticky top-0 z-50 border-b border-[var(--kyro-border)] mb-8 bg-[var(--kyro-surface)] backdrop-blur-md", children: [
10297
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
10298
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
10490
+ return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "surface-tile px-3 md:px-8 py-2 md:py-6 flex items-center justify-between max-md:static sticky top-0 z-50 border-b border-[var(--kyro-border)] mb-0 md:mb-8 bg-[var(--kyro-surface)] backdrop-blur-md", children: [
10491
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:gap-2 min-w-0", children: [
10492
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 md:gap-3 flex-wrap min-w-0", children: [
10299
10493
  /* @__PURE__ */ jsxRuntime.jsx(
10300
10494
  "a",
10301
10495
  {
10302
10496
  href: `/${collectionSlug}`,
10303
- className: "p-2 border border-[var(--kyro-border)] rounded-xl hover:bg-[var(--kyro-bg-secondary)] transition-colors",
10497
+ className: "p-1.5 md:p-2 border-0 md:border border-[var(--kyro-border)] rounded-xl hover:bg-[var(--kyro-bg-secondary)] transition-colors shrink-0",
10304
10498
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-4 h-4" })
10305
10499
  }
10306
10500
  ),
10307
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold tracking-tighter", children: docTitle }),
10308
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `inline-flex items-center gap-1.5 px-2 rounded-full text-[10px] font-regular border ${statusBadgeBg}`, children: [
10501
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-lg md:text-xl font-bold tracking-tighter truncate min-w-0", children: docTitle }),
10502
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `shrink-0 inline-flex items-center gap-1.5 px-2 rounded-full text-[10px] font-regular border ${statusBadgeBg}`, children: [
10309
10503
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: `h-1.5 w-1.5 rounded-full ${statusColor}` }),
10310
10504
  statusLabel
10311
10505
  ] })
10312
10506
  ] }),
10313
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-[11px] font-medium tracking-wide opacity-60 ml-12", children: [
10507
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-[11px] font-medium tracking-wide opacity-60 md:ml-12", children: [
10314
10508
  autoSaveStatus === "saving" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-[var(--kyro-text-muted)]", children: [
10315
10509
  /* @__PURE__ */ jsxRuntime.jsxs(
10316
10510
  "svg",
@@ -10431,7 +10625,7 @@ function AutoForm({
10431
10625
  ] })
10432
10626
  ] })
10433
10627
  ] }),
10434
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6", children: [
10628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-md:hidden flex items-center gap-6", children: [
10435
10629
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 bg-[var(--kyro-bg-secondary)] p-1 rounded-xl border border-[var(--kyro-border)]", children: ["edit", "version", "api"].map((v) => /* @__PURE__ */ jsxRuntime.jsx(
10436
10630
  "button",
10437
10631
  {
@@ -10616,15 +10810,15 @@ function AutoForm({
10616
10810
  };
10617
10811
  const renderEditView = () => {
10618
10812
  if (layout === "single") {
10619
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-8", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile p-8 space-y-8", children: config.fields.map((f) => renderField(f)) }) });
10813
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-6 md:space-y-8", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile p-4 md:p-8 space-y-6 md:space-y-8", children: config.fields.map((f) => renderField(f)) }) });
10620
10814
  }
10621
10815
  const hasSidebarFields = config.fields.some((f) => f.admin?.position === "sidebar") && !showPreview;
10622
10816
  return /* @__PURE__ */ jsxRuntime.jsxs(
10623
10817
  "div",
10624
10818
  {
10625
- className: `w-full mx-auto grid gap-8 pb-32 transition-all duration-700 ${showPreview ? "grid-cols-1 lg:grid-cols-2" : sidebarCollapsed || !hasSidebarFields ? "grid-cols-1" : "grid-cols-1 lg:grid-cols-[1fr_380px]"}`,
10819
+ className: `w-full mx-auto grid gap-4 md:gap-8 pb-32 transition-all duration-700 ${showPreview ? "grid-cols-1 lg:grid-cols-2" : sidebarCollapsed || !hasSidebarFields ? "grid-cols-1" : "grid-cols-1 lg:grid-cols-[1fr_380px]"}`,
10626
10820
  children: [
10627
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-8 animate-in fade-in slide-in-from-left-4 duration-500", children: config.tabs ? renderField({ type: "tabs", tabs: config.tabs }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile p-8 space-y-8", children: config.fields.filter(
10821
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6 md:space-y-8 animate-in fade-in slide-in-from-left-4 duration-500", children: config.tabs ? renderField({ type: "tabs", tabs: config.tabs }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile p-4 md:p-8 space-y-6 md:space-y-8", children: config.fields.filter(
10628
10822
  (f) => !f.admin?.position || f.admin.position === "main"
10629
10823
  ).map((f) => renderField(f)) }) }),
10630
10824
  showPreview ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-36 h-[calc(100vh-280px)] animate-in fade-in slide-in-from-right-10 duration-700", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full rounded-3xl border border-[var(--kyro-border)] bg-[var(--kyro-bg-secondary)] shadow-2xl overflow-hidden relative group", children: [
@@ -10641,9 +10835,18 @@ function AutoForm({
10641
10835
  }
10642
10836
  ),
10643
10837
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-transparent pointer-events-none border-[12px] border-[var(--kyro-surface)] rounded-3xl" })
10644
- ] }) }) : sidebarCollapsed ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6 animate-in fade-in slide-in-from-right-4 duration-500", children: config.fields.some((f) => f.admin?.position === "sidebar") && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-6 space-y-6", children: [
10645
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40", children: "Settings" }),
10646
- config.fields.filter((f) => f.admin?.position === "sidebar").map((f) => renderField(f))
10838
+ ] }) }) : sidebarCollapsed ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4 md:space-y-6 animate-in fade-in slide-in-from-right-4 duration-500", children: config.fields.some((f) => f.admin?.position === "sidebar") && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10839
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden lg:block surface-tile p-6 space-y-6", children: [
10840
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40", children: "Settings" }),
10841
+ config.fields.filter((f) => f.admin?.position === "sidebar").map((f) => renderField(f))
10842
+ ] }),
10843
+ /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "lg:hidden surface-tile p-4 space-y-4 group", children: [
10844
+ /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "cursor-pointer font-semibold text-xs tracking-widest opacity-40 text-[var(--kyro-text-secondary)] select-none flex items-center gap-2", children: [
10845
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3 transition-transform group-open:rotate-90", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18l6-6-6-6" }) }),
10846
+ "Settings"
10847
+ ] }),
10848
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4 pt-4 border-t border-[var(--kyro-border)]", children: config.fields.filter((f) => f.admin?.position === "sidebar").map((f) => renderField(f)) })
10849
+ ] })
10647
10850
  ] }) })
10648
10851
  ]
10649
10852
  }
@@ -10895,7 +11098,7 @@ function AutoForm({
10895
11098
  }
10896
11099
  )
10897
11100
  ] }),
10898
- /* @__PURE__ */ jsxRuntime.jsxs("main", { className: "w-full", children: [
11101
+ /* @__PURE__ */ jsxRuntime.jsxs("main", { className: "w-full pt-6 md:pt-0", children: [
10899
11102
  view === "edit" && renderEditView(),
10900
11103
  view === "version" && renderVersionView(),
10901
11104
  view === "api" && renderApiView()
@@ -10913,9 +11116,13 @@ function ActionBar({
10913
11116
  onViewHistory,
10914
11117
  onPreview,
10915
11118
  onDelete,
11119
+ onBack,
11120
+ onToggleSidebar,
10916
11121
  publishedAt,
10917
11122
  updatedAt
10918
11123
  }) {
11124
+ const view = useAutoFormStore((s) => s.view) || "edit";
11125
+ const setView = useAutoFormStore((s) => s.setView);
10919
11126
  const getSaveStatusText = () => {
10920
11127
  if (saveStatus === "saving") return "Saving...";
10921
11128
  if (saveStatus === "saved") return "Saved";
@@ -10962,101 +11169,268 @@ function ActionBar({
10962
11169
  if (!dateStr) return "Never";
10963
11170
  return new Date(dateStr).toLocaleString();
10964
11171
  };
10965
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-3 px-1", children: [
10966
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
10967
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11172
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11173
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden flex flex-col gap-3 py-3 px-4 bg-[var(--kyro-bg)] border-t border-[var(--kyro-border)]", children: [
11174
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
11175
+ onBack && /* @__PURE__ */ jsxRuntime.jsx(
11176
+ "button",
11177
+ {
11178
+ type: "button",
11179
+ onClick: onBack,
11180
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
11181
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 12H5M12 19l-7-7 7-7" }) })
11182
+ }
11183
+ ),
11184
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-auto", children: [
11185
+ onPreview && /* @__PURE__ */ jsxRuntime.jsx(
11186
+ "button",
11187
+ {
11188
+ type: "button",
11189
+ onClick: onPreview,
11190
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
11191
+ title: "Preview",
11192
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "w-4 h-4" })
11193
+ }
11194
+ ),
11195
+ onViewHistory && /* @__PURE__ */ jsxRuntime.jsx(
11196
+ "button",
11197
+ {
11198
+ type: "button",
11199
+ onClick: onViewHistory,
11200
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
11201
+ title: "View History",
11202
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-4 h-4" })
11203
+ }
11204
+ ),
11205
+ onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
11206
+ "button",
11207
+ {
11208
+ type: "button",
11209
+ onClick: onDuplicate,
11210
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
11211
+ title: "Duplicate",
11212
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4" })
11213
+ }
11214
+ ),
11215
+ onDelete && /* @__PURE__ */ jsxRuntime.jsx(
11216
+ "button",
11217
+ {
11218
+ type: "button",
11219
+ onClick: onDelete,
11220
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-danger-bg)] text-[var(--kyro-error)] transition-all",
11221
+ title: "Delete",
11222
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-4 h-4" })
11223
+ }
11224
+ ),
11225
+ onToggleSidebar && /* @__PURE__ */ jsxRuntime.jsx(
11226
+ "button",
11227
+ {
11228
+ type: "button",
11229
+ onClick: onToggleSidebar,
11230
+ className: "p-2 rounded-lg hover:bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-secondary)] transition-all",
11231
+ title: "Toggle Sidebar",
11232
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
11233
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
11234
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21" })
11235
+ ] })
11236
+ }
11237
+ )
11238
+ ] })
11239
+ ] }),
11240
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 bg-[var(--kyro-bg-secondary)] p-0.5 rounded-lg border border-[var(--kyro-border)] self-start", children: ["edit", "version", "api"].map((v) => /* @__PURE__ */ jsxRuntime.jsx(
11241
+ "button",
11242
+ {
11243
+ type: "button",
11244
+ onClick: () => setView(v),
11245
+ className: `px-4 py-1.5 text-xs font-bold rounded-md transition-all ${view === v ? "bg-[var(--kyro-surface)] shadow-sm border border-[var(--kyro-border)] text-[var(--kyro-text-primary)]" : "text-[var(--kyro-text-secondary)] opacity-50 hover:opacity-100"}`,
11246
+ children: v === "edit" ? "Edit" : v === "version" ? "Version" : "API"
11247
+ },
11248
+ v
11249
+ )) }),
11250
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
10968
11251
  getStatusBadge(),
10969
11252
  getSaveStatusText() && /* @__PURE__ */ jsxRuntime.jsxs(
10970
11253
  "span",
10971
11254
  {
10972
- className: `text-sm ${saveStatus === "error" ? "text-[var(--kyro-error)]" : "text-[var(--kyro-text-muted)]"}`,
11255
+ className: `text-xs ${saveStatus === "error" ? "text-[var(--kyro-error)]" : "text-[var(--kyro-text-muted)]"}`,
10973
11256
  children: [
10974
11257
  saveStatus === "saving" ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", className: "inline mr-1" }) : null,
10975
11258
  getSaveStatusText()
10976
11259
  ]
10977
11260
  }
10978
- )
11261
+ ),
11262
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-[var(--kyro-text-muted)] ml-auto", children: [
11263
+ updatedAt && `Updated ${formatDate2(updatedAt)}`,
11264
+ publishedAt && status === "published" && ` \xB7 Published ${formatDate2(publishedAt)}`
11265
+ ] })
10979
11266
  ] }),
10980
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs space-y-0.5", children: [
10981
- updatedAt && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[var(--kyro-text-muted)]", children: [
10982
- "Updated: ",
10983
- formatDate2(updatedAt)
11267
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11268
+ status === "draft" && onPublish && /* @__PURE__ */ jsxRuntime.jsxs(
11269
+ "button",
11270
+ {
11271
+ type: "button",
11272
+ onClick: onPublish,
11273
+ disabled: saveStatus === "saving",
11274
+ className: "kyro-btn kyro-btn-primary kyro-btn-md flex items-center gap-2 flex-1 justify-center",
11275
+ children: [
11276
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" }),
11277
+ "Publish"
11278
+ ]
11279
+ }
11280
+ ),
11281
+ status === "published" && onUnpublish && /* @__PURE__ */ jsxRuntime.jsxs(
11282
+ "button",
11283
+ {
11284
+ type: "button",
11285
+ onClick: onUnpublish,
11286
+ disabled: saveStatus === "saving",
11287
+ className: "kyro-btn kyro-btn-secondary kyro-btn-md flex items-center gap-2 flex-1 justify-center",
11288
+ children: [
11289
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo, { className: "w-4 h-4" }),
11290
+ "Unpublish"
11291
+ ]
11292
+ }
11293
+ ),
11294
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(
11295
+ SplitButton,
11296
+ {
11297
+ status,
11298
+ saveStatus,
11299
+ hasChanges,
11300
+ onPublish: onSave,
11301
+ children: [
11302
+ onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
11303
+ DropdownItem,
11304
+ {
11305
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4" }),
11306
+ children: "Duplicate"
11307
+ }
11308
+ ),
11309
+ onViewHistory && /* @__PURE__ */ jsxRuntime.jsx(
11310
+ DropdownItem,
11311
+ {
11312
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-4 h-4" }),
11313
+ children: "View History"
11314
+ }
11315
+ ),
11316
+ onPreview && /* @__PURE__ */ jsxRuntime.jsx(
11317
+ DropdownItem,
11318
+ {
11319
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "w-4 h-4" }),
11320
+ children: "Preview"
11321
+ }
11322
+ ),
11323
+ (onDuplicate || onViewHistory || onPreview) && /* @__PURE__ */ jsxRuntime.jsx(DropdownSeparator, {}),
11324
+ onDelete && /* @__PURE__ */ jsxRuntime.jsx(
11325
+ DropdownItem,
11326
+ {
11327
+ onClick: onDelete,
11328
+ danger: true,
11329
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-4 h-4" }),
11330
+ children: "Delete"
11331
+ }
11332
+ )
11333
+ ]
11334
+ }
11335
+ ) })
11336
+ ] })
11337
+ ] }),
11338
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden md:flex flex-row items-center justify-between gap-4 py-3 px-6 bg-transparent border-0 static z-40", children: [
11339
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center gap-4", children: [
11340
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11341
+ getStatusBadge(),
11342
+ getSaveStatusText() && /* @__PURE__ */ jsxRuntime.jsxs(
11343
+ "span",
11344
+ {
11345
+ className: `text-sm ${saveStatus === "error" ? "text-[var(--kyro-error)]" : "text-[var(--kyro-text-muted)]"}`,
11346
+ children: [
11347
+ saveStatus === "saving" ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm", className: "inline mr-1" }) : null,
11348
+ getSaveStatusText()
11349
+ ]
11350
+ }
11351
+ )
10984
11352
  ] }),
10985
- publishedAt && status === "published" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[var(--kyro-primary)] font-medium", children: [
10986
- "Published: ",
10987
- formatDate2(publishedAt)
11353
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs space-y-0.5", children: [
11354
+ updatedAt && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[var(--kyro-text-muted)]", children: [
11355
+ "Updated: ",
11356
+ formatDate2(updatedAt)
11357
+ ] }),
11358
+ publishedAt && status === "published" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[var(--kyro-primary)] font-medium", children: [
11359
+ "Published: ",
11360
+ formatDate2(publishedAt)
11361
+ ] })
10988
11362
  ] })
11363
+ ] }),
11364
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
11365
+ status === "draft" && onPublish && /* @__PURE__ */ jsxRuntime.jsxs(
11366
+ "button",
11367
+ {
11368
+ type: "button",
11369
+ onClick: onPublish,
11370
+ disabled: saveStatus === "saving",
11371
+ className: "kyro-btn kyro-btn-primary kyro-btn-md flex items-center gap-2",
11372
+ children: [
11373
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" }),
11374
+ "Publish"
11375
+ ]
11376
+ }
11377
+ ),
11378
+ status === "published" && onUnpublish && /* @__PURE__ */ jsxRuntime.jsxs(
11379
+ "button",
11380
+ {
11381
+ type: "button",
11382
+ onClick: onUnpublish,
11383
+ disabled: saveStatus === "saving",
11384
+ className: "kyro-btn kyro-btn-secondary kyro-btn-md flex items-center gap-2",
11385
+ children: [
11386
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo, { className: "w-4 h-4" }),
11387
+ "Unpublish"
11388
+ ]
11389
+ }
11390
+ ),
11391
+ /* @__PURE__ */ jsxRuntime.jsxs(
11392
+ SplitButton,
11393
+ {
11394
+ status,
11395
+ saveStatus,
11396
+ hasChanges,
11397
+ onPublish: onSave,
11398
+ children: [
11399
+ onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
11400
+ DropdownItem,
11401
+ {
11402
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4" }),
11403
+ children: "Duplicate"
11404
+ }
11405
+ ),
11406
+ onViewHistory && /* @__PURE__ */ jsxRuntime.jsx(
11407
+ DropdownItem,
11408
+ {
11409
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-4 h-4" }),
11410
+ children: "View History"
11411
+ }
11412
+ ),
11413
+ onPreview && /* @__PURE__ */ jsxRuntime.jsx(
11414
+ DropdownItem,
11415
+ {
11416
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "w-4 h-4" }),
11417
+ children: "Preview"
11418
+ }
11419
+ ),
11420
+ (onDuplicate || onViewHistory || onPreview) && /* @__PURE__ */ jsxRuntime.jsx(DropdownSeparator, {}),
11421
+ onDelete && /* @__PURE__ */ jsxRuntime.jsx(
11422
+ DropdownItem,
11423
+ {
11424
+ onClick: onDelete,
11425
+ danger: true,
11426
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-4 h-4" }),
11427
+ children: "Delete"
11428
+ }
11429
+ )
11430
+ ]
11431
+ }
11432
+ )
10989
11433
  ] })
10990
- ] }),
10991
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10992
- status === "draft" && onPublish && /* @__PURE__ */ jsxRuntime.jsxs(
10993
- "button",
10994
- {
10995
- type: "button",
10996
- onClick: onPublish,
10997
- disabled: saveStatus === "saving",
10998
- className: "kyro-btn kyro-btn-primary kyro-btn-md flex items-center gap-2",
10999
- children: [
11000
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" }),
11001
- "Publish"
11002
- ]
11003
- }
11004
- ),
11005
- status === "published" && onUnpublish && /* @__PURE__ */ jsxRuntime.jsxs(
11006
- "button",
11007
- {
11008
- type: "button",
11009
- onClick: onUnpublish,
11010
- disabled: saveStatus === "saving",
11011
- className: "kyro-btn kyro-btn-secondary kyro-btn-md flex items-center gap-2",
11012
- children: [
11013
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo, { className: "w-4 h-4" }),
11014
- "Unpublish"
11015
- ]
11016
- }
11017
- ),
11018
- /* @__PURE__ */ jsxRuntime.jsxs(
11019
- SplitButton,
11020
- {
11021
- status,
11022
- saveStatus,
11023
- hasChanges,
11024
- onPublish: onSave,
11025
- children: [
11026
- onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
11027
- DropdownItem,
11028
- {
11029
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4" }),
11030
- children: "Duplicate"
11031
- }
11032
- ),
11033
- onViewHistory && /* @__PURE__ */ jsxRuntime.jsx(
11034
- DropdownItem,
11035
- {
11036
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-4 h-4" }),
11037
- children: "View History"
11038
- }
11039
- ),
11040
- onPreview && /* @__PURE__ */ jsxRuntime.jsx(
11041
- DropdownItem,
11042
- {
11043
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "w-4 h-4" }),
11044
- children: "Preview"
11045
- }
11046
- ),
11047
- (onDuplicate || onViewHistory || onPreview) && /* @__PURE__ */ jsxRuntime.jsx(DropdownSeparator, {}),
11048
- onDelete && /* @__PURE__ */ jsxRuntime.jsx(
11049
- DropdownItem,
11050
- {
11051
- onClick: onDelete,
11052
- danger: true,
11053
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-4 h-4" }),
11054
- children: "Delete"
11055
- }
11056
- )
11057
- ]
11058
- }
11059
- )
11060
11434
  ] })
11061
11435
  ] });
11062
11436
  }
@@ -11072,32 +11446,32 @@ function DetailView({
11072
11446
  mode = "collection"
11073
11447
  }) {
11074
11448
  const { confirm, alert } = useUIStore();
11075
- const [data, setData] = React56.useState({});
11076
- const [originalData, setOriginalData] = React56.useState({});
11077
- const [loading, setLoading] = React56.useState(true);
11078
- const [saving, setSaving] = React56.useState(false);
11079
- const [saveStatus, setSaveStatus] = React56.useState("idle");
11080
- const [deleting, setDeleting] = React56.useState(false);
11081
- const [status, setStatus] = React56.useState("draft");
11082
- const [createdAt, setCreatedAt] = React56.useState(null);
11083
- const [updatedAt, setUpdatedAt] = React56.useState(null);
11084
- const [publishedAt, setPublishedAt] = React56.useState(null);
11085
- const [justSaved, setJustSaved] = React56.useState(false);
11449
+ const [data, setData] = React.useState({});
11450
+ const [originalData, setOriginalData] = React.useState({});
11451
+ const [loading, setLoading] = React.useState(true);
11452
+ const [saving, setSaving] = React.useState(false);
11453
+ const [saveStatus, setSaveStatus] = React.useState("idle");
11454
+ const [deleting, setDeleting] = React.useState(false);
11455
+ const [status, setStatus] = React.useState("draft");
11456
+ const [createdAt, setCreatedAt] = React.useState(null);
11457
+ const [updatedAt, setUpdatedAt] = React.useState(null);
11458
+ const [publishedAt, setPublishedAt] = React.useState(null);
11459
+ const [justSaved, setJustSaved] = React.useState(false);
11086
11460
  const fields2 = global?.fields || collection?.fields || [];
11087
11461
  const label = global?.label || collection?.label || "Document";
11088
11462
  const slug = global?.slug || collection?.slug || "";
11089
11463
  const hasChanges = JSON.stringify(data) !== JSON.stringify(originalData);
11090
- React56.useEffect(() => {
11464
+ React.useEffect(() => {
11091
11465
  if (hasChanges && status === "published") {
11092
11466
  setStatus("draft");
11093
11467
  }
11094
11468
  }, [hasChanges, status]);
11095
- React56.useEffect(() => {
11469
+ React.useEffect(() => {
11096
11470
  if (hasChanges && saveStatus === "saved") {
11097
11471
  setSaveStatus("idle");
11098
11472
  }
11099
11473
  }, [hasChanges, saveStatus]);
11100
- React56.useEffect(() => {
11474
+ React.useEffect(() => {
11101
11475
  if (mode === "global") {
11102
11476
  loadGlobal();
11103
11477
  } else if (documentId) {
@@ -11136,7 +11510,7 @@ function DetailView({
11136
11510
  setLoading(false);
11137
11511
  }
11138
11512
  };
11139
- const handleSave = React56.useCallback(
11513
+ const handleSave = React.useCallback(
11140
11514
  async (isAutosave = false) => {
11141
11515
  try {
11142
11516
  setSaveStatus("saving");
@@ -11280,7 +11654,27 @@ function DetailView({
11280
11654
  ]
11281
11655
  }
11282
11656
  ),
11283
- !isSingleLayout && /* @__PURE__ */ jsxRuntime.jsx(
11657
+ isSingleLayout ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11658
+ ActionBar,
11659
+ {
11660
+ status,
11661
+ saveStatus,
11662
+ hasChanges,
11663
+ onSave: () => handleSave(false),
11664
+ onPublish: handlePublish,
11665
+ onUnpublish: status === "published" ? handleUnpublish : void 0,
11666
+ onDuplicate: handleDuplicate,
11667
+ onViewHistory: () => {
11668
+ window.dispatchEvent(new CustomEvent("kyro:show-version-history"));
11669
+ },
11670
+ onPreview: () => window.open(`/preview/${slug}/${documentId}`, "_blank"),
11671
+ onDelete: handleDeleteTrigger,
11672
+ onBack,
11673
+ onToggleSidebar: () => window.dispatchEvent(new CustomEvent("toggle-sidebar")),
11674
+ publishedAt,
11675
+ updatedAt
11676
+ }
11677
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(
11284
11678
  ActionBar,
11285
11679
  {
11286
11680
  status,
@@ -11295,6 +11689,8 @@ function DetailView({
11295
11689
  },
11296
11690
  onPreview: () => window.open(`/preview/${slug}/${documentId}`, "_blank"),
11297
11691
  onDelete: handleDeleteTrigger,
11692
+ onBack,
11693
+ onToggleSidebar: () => window.dispatchEvent(new CustomEvent("toggle-sidebar")),
11298
11694
  publishedAt,
11299
11695
  updatedAt
11300
11696
  }
@@ -11302,9 +11698,9 @@ function DetailView({
11302
11698
  /* @__PURE__ */ jsxRuntime.jsxs(
11303
11699
  "div",
11304
11700
  {
11305
- className: isSingleLayout ? "w-full pb-32 pt-8" : "w-full mx-auto grid grid-cols-1 lg:grid-cols-[1fr_360px] gap-8 pb-32",
11701
+ className: isSingleLayout ? "w-full pb-32 pt-4 md:pt-8" : "w-full mx-auto grid grid-cols-1 lg:grid-cols-[1fr_360px] gap-4 md:gap-8 pt-4 md:pt-0 pb-32",
11306
11702
  children: [
11307
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-8 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-8", children: [
11703
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4 md:space-y-8 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-4 md:p-8", children: [
11308
11704
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-8 px-1", children: [
11309
11705
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40", children: "Core Configuration" }),
11310
11706
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-[var(--kyro-border)] ml-6 opacity-30" })
@@ -11346,10 +11742,10 @@ function DetailView({
11346
11742
  )
11347
11743
  ] })
11348
11744
  ] }) }),
11349
- !isSingleLayout && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 animate-in fade-in slide-in-from-right-4 duration-500", children: [
11350
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-8", children: [
11351
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40 mb-6", children: "Metadata" }),
11352
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
11745
+ !isSingleLayout && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 md:space-y-6 animate-in fade-in slide-in-from-right-4 duration-500", children: [
11746
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-4 md:p-8", children: [
11747
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40 mb-4 md:mb-6", children: "Metadata" }),
11748
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 md:space-y-6", children: [
11353
11749
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
11354
11750
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold tracking-widest opacity-40", children: "Dynamic Status" }),
11355
11751
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -11383,9 +11779,9 @@ function DetailView({
11383
11779
  ] })
11384
11780
  ] })
11385
11781
  ] }),
11386
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-8 bg-[var(--kyro-bg-secondary)]", children: [
11387
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40 mb-4", children: "Quick Links" }),
11388
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
11782
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "surface-tile p-4 md:p-8 bg-[var(--kyro-bg-secondary)]", children: [
11783
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[10px] font-bold tracking-[0.2em] opacity-40 mb-3 md:mb-4", children: "Quick Links" }),
11784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 md:space-y-3", children: [
11389
11785
  /* @__PURE__ */ jsxRuntime.jsx(
11390
11786
  "button",
11391
11787
  {
@@ -11428,8 +11824,8 @@ function CreateView({
11428
11824
  onSuccess,
11429
11825
  onError
11430
11826
  }) {
11431
- const [data, setData] = React56.useState({});
11432
- const [saving, setSaving] = React56.useState(false);
11827
+ const [data, setData] = React.useState({});
11828
+ const [saving, setSaving] = React.useState(false);
11433
11829
  const fields2 = collection.fields || [];
11434
11830
  const label = collection.label || collection.slug;
11435
11831
  const handleSubmit = async (e) => {
@@ -11472,8 +11868,8 @@ function CreateView({
11472
11868
  ] });
11473
11869
  }
11474
11870
  function Toast({ type, message, onClose }) {
11475
- const [isPaused, setIsPaused] = React56__default.default.useState(false);
11476
- const timerRef = React56__default.default.useRef(null);
11871
+ const [isPaused, setIsPaused] = React__default.default.useState(false);
11872
+ const timerRef = React__default.default.useRef(null);
11477
11873
  const startTimer = () => {
11478
11874
  if (timerRef.current) clearTimeout(timerRef.current);
11479
11875
  timerRef.current = setTimeout(onClose, 5e3);
@@ -11481,7 +11877,7 @@ function Toast({ type, message, onClose }) {
11481
11877
  const clearTimer = () => {
11482
11878
  if (timerRef.current) clearTimeout(timerRef.current);
11483
11879
  };
11484
- React56__default.default.useEffect(() => {
11880
+ React__default.default.useEffect(() => {
11485
11881
  if (!isPaused) {
11486
11882
  startTimer();
11487
11883
  } else {
@@ -11527,15 +11923,20 @@ function useToast() {
11527
11923
  const toasts = useToastStore((state) => state.toasts);
11528
11924
  return { toasts, addToast, removeToast };
11529
11925
  }
11926
+ function Toaster() {
11927
+ const toasts = useToastStore((state) => state.toasts);
11928
+ const removeToast = useToastStore((state) => state.removeToast);
11929
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kyro-toasts-container", style: { position: "fixed", bottom: "24px", right: "24px", display: "flex", flexDirection: "column", gap: "12px", zIndex: 9999, pointerEvents: "none" }, children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(Toast, { type: t.type, message: t.message, onClose: () => removeToast(t.id) }) }, t.id)) });
11930
+ }
11530
11931
  function LoginPage({ onAuth, theme = "light" }) {
11531
- const [mode, setMode] = React56.useState("login");
11532
- const [email, setEmail] = React56.useState("");
11533
- const [password, setPassword] = React56.useState("");
11534
- const [confirmPassword, setConfirmPassword] = React56.useState("");
11535
- const [loading, setLoading] = React56.useState(false);
11536
- const [toasts, setToasts] = React56.useState([]);
11537
- const [isFirstUser, setIsFirstUser] = React56.useState(false);
11538
- React56.useEffect(() => {
11932
+ const [mode, setMode] = React.useState("login");
11933
+ const [email, setEmail] = React.useState("");
11934
+ const [password, setPassword] = React.useState("");
11935
+ const [confirmPassword, setConfirmPassword] = React.useState("");
11936
+ const [loading, setLoading] = React.useState(false);
11937
+ const [isFirstUser, setIsFirstUser] = React.useState(false);
11938
+ const addToast = useToastStore((state) => state.addToast);
11939
+ React.useEffect(() => {
11539
11940
  checkIfFirstUser();
11540
11941
  }, []);
11541
11942
  const checkIfFirstUser = async () => {
@@ -11546,13 +11947,6 @@ function LoginPage({ onAuth, theme = "light" }) {
11546
11947
  setMode("register");
11547
11948
  }
11548
11949
  };
11549
- const addToast = (type, message) => {
11550
- const id = Math.random().toString(36).substring(7);
11551
- setToasts((prev) => [...prev, { id, type, message }]);
11552
- setTimeout(() => {
11553
- setToasts((prev) => prev.filter((t) => t.id !== id));
11554
- }, 5e3);
11555
- };
11556
11950
  const handleSubmit = async (e) => {
11557
11951
  e.preventDefault();
11558
11952
  setLoading(true);
@@ -11578,7 +11972,7 @@ function LoginPage({ onAuth, theme = "light" }) {
11578
11972
  setLoading(false);
11579
11973
  }
11580
11974
  };
11581
- return /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { defaultMode: theme, children: /* @__PURE__ */ jsxRuntime.jsx(ToastProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "kyro-login-page", children: [
11975
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { defaultMode: theme, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "kyro-login-page", children: [
11582
11976
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "kyro-login-container", children: [
11583
11977
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "kyro-login-header", children: [
11584
11978
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "kyro-login-title", children: isFirstUser ? "Create Admin Account" : mode === "login" ? "Sign In" : "Create Account" }),
@@ -11668,27 +12062,19 @@ function LoginPage({ onAuth, theme = "light" }) {
11668
12062
  )
11669
12063
  ] }) }) })
11670
12064
  ] }),
11671
- toasts.map((toast2) => /* @__PURE__ */ jsxRuntime.jsx(
11672
- Toast,
11673
- {
11674
- type: toast2.type,
11675
- message: toast2.message,
11676
- onClose: () => setToasts((prev) => prev.filter((t) => t.id !== toast2.id))
11677
- },
11678
- toast2.id
11679
- ))
11680
- ] }) }) });
12065
+ /* @__PURE__ */ jsxRuntime.jsx(Toaster, {})
12066
+ ] }) });
11681
12067
  }
11682
12068
  function Dashboard({ collections: collections2, onNavigate, user }) {
11683
12069
  const { permissions } = useAuthStore();
11684
- const [stats, setStats] = React56.useState({
12070
+ const [stats, setStats] = React.useState({
11685
12071
  totalDocs: 0,
11686
12072
  totalMedia: 0,
11687
12073
  totalUsers: 0,
11688
12074
  recentActivity: []
11689
12075
  });
11690
- const [loading, setLoading] = React56.useState(true);
11691
- React56.useEffect(() => {
12076
+ const [loading, setLoading] = React.useState(true);
12077
+ React.useEffect(() => {
11692
12078
  const timer = setTimeout(() => {
11693
12079
  setStats({
11694
12080
  totalDocs: 124,
@@ -12009,15 +12395,15 @@ function Dashboard({ collections: collections2, onNavigate, user }) {
12009
12395
  ] });
12010
12396
  }
12011
12397
  function UserManagement() {
12012
- const [users, setUsers] = React56.useState([]);
12013
- const [loading, setLoading] = React56.useState(true);
12014
- const [searchQuery, setSearchQuery] = React56.useState("");
12015
- const [showCreateModal, setShowCreateModal] = React56.useState(false);
12016
- const [createForm, setCreateForm] = React56.useState({ name: "", email: "", password: "", role: "customer" });
12017
- const [createError, setCreateError] = React56.useState("");
12018
- const [creating, setCreating] = React56.useState(false);
12398
+ const [users, setUsers] = React.useState([]);
12399
+ const [loading, setLoading] = React.useState(true);
12400
+ const [searchQuery, setSearchQuery] = React.useState("");
12401
+ const [showCreateModal, setShowCreateModal] = React.useState(false);
12402
+ const [createForm, setCreateForm] = React.useState({ name: "", email: "", password: "", role: "customer" });
12403
+ const [createError, setCreateError] = React.useState("");
12404
+ const [creating, setCreating] = React.useState(false);
12019
12405
  const { confirm, alert } = useUIStore();
12020
- React56.useEffect(() => {
12406
+ React.useEffect(() => {
12021
12407
  loadUsers();
12022
12408
  }, []);
12023
12409
  const loadUsers = async () => {
@@ -12099,7 +12485,7 @@ function UserManagement() {
12099
12485
  const filteredUsers = users.filter(
12100
12486
  (u) => u.email.toLowerCase().includes(searchQuery.toLowerCase()) || u.name?.toLowerCase().includes(searchQuery.toLowerCase())
12101
12487
  );
12102
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-700 px-8 pb-12", children: [
12488
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-700 px-4 md:px-8 pb-12", children: [
12103
12489
  /* @__PURE__ */ jsxRuntime.jsx(
12104
12490
  PageHeader,
12105
12491
  {
@@ -12137,8 +12523,8 @@ function UserManagement() {
12137
12523
  /* @__PURE__ */ jsxRuntime.jsx("button", { className: "px-4 py-1.5 text-[10px] font-bold tracking-widest opacity-40 hover:opacity-100 transition-all", children: "LOCKED" })
12138
12524
  ] })
12139
12525
  ] }),
12140
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left table-fixed", children: [
12141
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-[var(--kyro-text-secondary)] font-bold text-[9px] tracking-[0.2em] uppercase border-b border-[var(--kyro-border)]", children: [
12526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "surface-tile overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-left", children: [
12527
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "text-[var(--kyro-text-secondary)] font-bold text-[9px] tracking-[0.2em] uppercase border-b border-[var(--kyro-border)] whitespace-nowrap", children: [
12142
12528
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-6 py-4 w-64", children: "Member Identity" }),
12143
12529
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-6 py-4", children: "Administrative Role" }),
12144
12530
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-6 py-4", children: "Security Status" }),
@@ -12282,8 +12668,8 @@ function UserManagement() {
12282
12668
  ] });
12283
12669
  }
12284
12670
  function AvatarCell({ user }) {
12285
- const [url, setUrl] = React56.useState(null);
12286
- React56.useEffect(() => {
12671
+ const [url, setUrl] = React.useState(null);
12672
+ React.useEffect(() => {
12287
12673
  const avatar = user.avatar;
12288
12674
  if (typeof avatar === "string" && /^[0-9a-f-]+$/i.test(avatar)) {
12289
12675
  apiGet(`/api/media/${avatar}`).then((media) => setUrl(media?.thumbnailUrl || media?.url || null)).catch(() => setUrl(null));
@@ -12295,15 +12681,15 @@ function AvatarCell({ user }) {
12295
12681
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-lg bg-[var(--kyro-surface-accent)] border border-[var(--kyro-border)] flex items-center justify-center text-xs font-bold text-[var(--kyro-primary)] flex-shrink-0", children: user.name ? user.name[0] : user.email[0].toUpperCase() });
12296
12682
  }
12297
12683
  function BrandingHub() {
12298
- const [siteName, setSiteName] = React56.useState("Kyro CMS");
12299
- const [adminTitle, setAdminTitle] = React56.useState("Command Center");
12300
- const [primaryColor, setPrimaryColor] = React56.useState("#6366f1");
12301
- const [dashboardGreeting, setDashboardGreeting] = React56.useState(
12684
+ const [siteName, setSiteName] = React.useState("Kyro CMS");
12685
+ const [adminTitle, setAdminTitle] = React.useState("Command Center");
12686
+ const [primaryColor, setPrimaryColor] = React.useState("#6366f1");
12687
+ const [dashboardGreeting, setDashboardGreeting] = React.useState(
12302
12688
  "Welcome back to your Command Center."
12303
12689
  );
12304
- const [saving, setSaving] = React56.useState(false);
12305
- const [saved, setSaved] = React56.useState(false);
12306
- React56.useEffect(() => {
12690
+ const [saving, setSaving] = React.useState(false);
12691
+ const [saved, setSaved] = React.useState(false);
12692
+ React.useEffect(() => {
12307
12693
  const fetchBranding = async () => {
12308
12694
  try {
12309
12695
  const result = await apiGet("/api/globals/site-settings");
@@ -12499,15 +12885,15 @@ function BrandingHub() {
12499
12885
  }
12500
12886
  var API_BASE2 = typeof __KYRO_API_PATH__ !== "undefined" ? __KYRO_API_PATH__ : "/api";
12501
12887
  function DeveloperCenter({ collections: collections2 }) {
12502
- const [keys, setKeys] = React56.useState([]);
12503
- const [loading, setLoading] = React56.useState(false);
12504
- const [showKey, setShowKey] = React56.useState(null);
12505
- const [testEndpoint, setTestEndpoint] = React56.useState("");
12506
- const [playgroundResult, setPlaygroundResult] = React56.useState(null);
12507
- const [exploring, setExploring] = React56.useState(false);
12888
+ const [keys, setKeys] = React.useState([]);
12889
+ const [loading, setLoading] = React.useState(false);
12890
+ const [showKey, setShowKey] = React.useState(null);
12891
+ const [testEndpoint, setTestEndpoint] = React.useState("");
12892
+ const [playgroundResult, setPlaygroundResult] = React.useState(null);
12893
+ const [exploring, setExploring] = React.useState(false);
12508
12894
  const { confirm, alert } = useUIStore();
12509
- const [showCreateModal, setShowCreateModal] = React56.useState(false);
12510
- const [newKeyName, setNewKeyName] = React56.useState("");
12895
+ const [showCreateModal, setShowCreateModal] = React.useState(false);
12896
+ const [newKeyName, setNewKeyName] = React.useState("");
12511
12897
  const loadKeys = async () => {
12512
12898
  try {
12513
12899
  const data = await apiGet("/api/keys");
@@ -12516,7 +12902,7 @@ function DeveloperCenter({ collections: collections2 }) {
12516
12902
  console.error(e);
12517
12903
  }
12518
12904
  };
12519
- React56.useEffect(() => {
12905
+ React.useEffect(() => {
12520
12906
  loadKeys();
12521
12907
  }, []);
12522
12908
  const handleGenerateKey = async () => {
@@ -12834,12 +13220,12 @@ function DeveloperCenter({ collections: collections2 }) {
12834
13220
  ] });
12835
13221
  }
12836
13222
  function useResourceManager(options) {
12837
- const [items, setItems] = React56.useState([]);
12838
- const [loading, setLoading] = React56.useState(false);
12839
- const [error, setError] = React56.useState(null);
12840
- const [isCreateModalOpen, setIsCreateModalOpen] = React56.useState(false);
13223
+ const [items, setItems] = React.useState([]);
13224
+ const [loading, setLoading] = React.useState(false);
13225
+ const [error, setError] = React.useState(null);
13226
+ const [isCreateModalOpen, setIsCreateModalOpen] = React.useState(false);
12841
13227
  const { confirm } = useUIStore();
12842
- const load = React56.useCallback(async () => {
13228
+ const load = React.useCallback(async () => {
12843
13229
  setLoading(true);
12844
13230
  setError(null);
12845
13231
  try {
@@ -12856,10 +13242,10 @@ function useResourceManager(options) {
12856
13242
  setLoading(false);
12857
13243
  }
12858
13244
  }, [options.endpoint, options.transformLoad]);
12859
- React56.useEffect(() => {
13245
+ React.useEffect(() => {
12860
13246
  load();
12861
13247
  }, [load]);
12862
- const remove = React56.useCallback((id, resourceName = "item") => {
13248
+ const remove = React.useCallback((id, resourceName = "item") => {
12863
13249
  confirm({
12864
13250
  title: `Delete ${resourceName}`,
12865
13251
  message: `Are you sure you want to delete this ${resourceName.toLowerCase()}? This action cannot be undone.`,
@@ -12869,6 +13255,7 @@ function useResourceManager(options) {
12869
13255
  await apiDelete(`${options.endpoint}/${id}`);
12870
13256
  setItems((prev) => prev.filter((item) => item.id !== id));
12871
13257
  options.onSuccess?.("delete", id);
13258
+ toast.success(`${resourceName} deleted`);
12872
13259
  } catch (e) {
12873
13260
  const message = e instanceof Error ? e.message : `Failed to delete ${resourceName}`;
12874
13261
  toast.error(message);
@@ -12877,7 +13264,7 @@ function useResourceManager(options) {
12877
13264
  }
12878
13265
  });
12879
13266
  }, [options.endpoint, confirm]);
12880
- const create3 = React56.useCallback(async (data) => {
13267
+ const create3 = React.useCallback(async (data) => {
12881
13268
  setError(null);
12882
13269
  try {
12883
13270
  const created = await apiPost(options.endpoint, data);
@@ -12892,7 +13279,7 @@ function useResourceManager(options) {
12892
13279
  throw e;
12893
13280
  }
12894
13281
  }, [options.endpoint]);
12895
- const update = React56.useCallback(async (id, data) => {
13282
+ const update = React.useCallback(async (id, data) => {
12896
13283
  setError(null);
12897
13284
  try {
12898
13285
  const updated = await apiPatch(`${options.endpoint}/${id}`, data);
@@ -12932,17 +13319,17 @@ function WebhookManager() {
12932
13319
  endpoint: "/api/webhooks"
12933
13320
  });
12934
13321
  const { confirm } = useUIStore();
12935
- const [showTestModal, setShowTestModal] = React56.useState(false);
12936
- const [showHelpModal, setShowHelpModal] = React56.useState(false);
12937
- const [testResult, setTestResult] = React56.useState(null);
12938
- const [testId, setTestId] = React56.useState(null);
12939
- const [formData, setFormData] = React56.useState({
13322
+ const [showTestModal, setShowTestModal] = React.useState(false);
13323
+ const [showHelpModal, setShowHelpModal] = React.useState(false);
13324
+ const [testResult, setTestResult] = React.useState(null);
13325
+ const [testId, setTestId] = React.useState(null);
13326
+ const [formData, setFormData] = React.useState({
12940
13327
  name: "",
12941
13328
  url: "",
12942
13329
  events: [],
12943
13330
  secret: ""
12944
13331
  });
12945
- const [createError, setCreateError] = React56.useState("");
13332
+ const [createError, setCreateError] = React.useState("");
12946
13333
  const handleCreate = async () => {
12947
13334
  if (!formData.name.trim() || !formData.url.trim()) {
12948
13335
  setCreateError("Name and URL are required");
@@ -13097,12 +13484,12 @@ function WebhookManager() {
13097
13484
  ] })
13098
13485
  ] })
13099
13486
  ] }),
13100
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid sm:grid-cols-3 gap-6 pt-2", children: [
13487
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-6 pt-2", children: [
13101
13488
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
13102
13489
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold uppercase tracking-widest opacity-30", children: "Destination" }),
13103
13490
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs opacity-60 truncate max-w-[200px]", title: webhook.url, children: webhook.url })
13104
13491
  ] }),
13105
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 border-l border-[var(--kyro-border)] pl-6", children: [
13492
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 sm:border-l border-t sm:border-t-0 border-[var(--kyro-border)] pt-4 sm:pt-0 sm:pl-6 mt-4 sm:mt-0", children: [
13106
13493
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold uppercase tracking-widest opacity-30", children: "Events" }),
13107
13494
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
13108
13495
  webhook.events.slice(0, 2).map((event) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "text-[8px] font-bold px-1.5 opacity-60", children: event }, event)),
@@ -13113,7 +13500,7 @@ function WebhookManager() {
13113
13500
  ] })
13114
13501
  ] })
13115
13502
  ] }),
13116
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 border-l border-[var(--kyro-border)] pl-6", children: [
13503
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 sm:border-l border-t sm:border-t-0 border-[var(--kyro-border)] pt-4 sm:pt-0 sm:pl-6 mt-4 sm:mt-0", children: [
13117
13504
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold uppercase tracking-widest opacity-30", children: "Activity" }),
13118
13505
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] font-bold opacity-60 flex items-center gap-1.5", children: [
13119
13506
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "w-3 h-3" }),
@@ -13216,7 +13603,7 @@ function WebhookManager() {
13216
13603
  ] }),
13217
13604
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
13218
13605
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-xs font-bold mb-1.5 text-[var(--kyro-text-secondary)] uppercase tracking-wider", children: "Subscribed Events" }),
13219
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-4", children: eventOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
13606
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: eventOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
13220
13607
  "button",
13221
13608
  {
13222
13609
  type: "button",
@@ -13394,13 +13781,13 @@ function CommandPalette({
13394
13781
  onNavigate
13395
13782
  }) {
13396
13783
  const { user, permissions } = useAuthStore();
13397
- const [query, setQuery] = React56.useState("");
13398
- const [selectedIndex, setSelectedIndex] = React56.useState(0);
13399
- const [loading, setLoading] = React56.useState(false);
13400
- const [searchResults, setSearchResults] = React56.useState([]);
13401
- const inputRef = React56.useRef(null);
13402
- const debounceRef = React56.useRef(null);
13403
- React56.useEffect(() => {
13784
+ const [query, setQuery] = React.useState("");
13785
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
13786
+ const [loading, setLoading] = React.useState(false);
13787
+ const [searchResults, setSearchResults] = React.useState([]);
13788
+ const inputRef = React.useRef(null);
13789
+ const debounceRef = React.useRef(null);
13790
+ React.useEffect(() => {
13404
13791
  if (isOpen) {
13405
13792
  setQuery("");
13406
13793
  setSelectedIndex(0);
@@ -13409,7 +13796,7 @@ function CommandPalette({
13409
13796
  setTimeout(() => inputRef.current?.focus(), 100);
13410
13797
  }
13411
13798
  }, [isOpen]);
13412
- const performSearch = React56.useCallback(async (searchQuery) => {
13799
+ const performSearch = React.useCallback(async (searchQuery) => {
13413
13800
  if (!searchQuery || searchQuery.length < 2) {
13414
13801
  setSearchResults([]);
13415
13802
  return;
@@ -13430,7 +13817,7 @@ function CommandPalette({
13430
13817
  setLoading(false);
13431
13818
  }
13432
13819
  }, []);
13433
- React56.useEffect(() => {
13820
+ React.useEffect(() => {
13434
13821
  if (debounceRef.current) {
13435
13822
  clearTimeout(debounceRef.current);
13436
13823
  }
@@ -13677,7 +14064,7 @@ function CommandPalette({
13677
14064
  }
13678
14065
  function GlobalModal() {
13679
14066
  const { modal, closeModal } = useUIStore();
13680
- const [loading, setLoading] = React56.useState(false);
14067
+ const [loading, setLoading] = React.useState(false);
13681
14068
  if (!modal.open || !modal.config) return null;
13682
14069
  const { config } = modal;
13683
14070
  const handleConfirm = async () => {
@@ -13717,24 +14104,22 @@ function GlobalModal() {
13717
14104
  );
13718
14105
  }
13719
14106
  function Admin({ config, theme = "light", onThemeChange }) {
13720
- const [authenticated, setAuthenticated] = React56.useState(false);
13721
- const [currentUser, setCurrentUser] = React56.useState(null);
13722
- const collections2 = React56.useMemo(
14107
+ const [authenticated, setAuthenticated] = React.useState(false);
14108
+ const [currentUser, setCurrentUser] = React.useState(null);
14109
+ const collections2 = React.useMemo(
13723
14110
  () => toCollectionMap(toArray(config.collections)),
13724
14111
  [config.collections]
13725
14112
  );
13726
- const globals2 = React56.useMemo(
14113
+ const globals2 = React.useMemo(
13727
14114
  () => toGlobalMap(toArray(config.globals)),
13728
14115
  [config.globals]
13729
14116
  );
13730
- const [activeCollection, setActiveCollection] = React56.useState(null);
13731
- const [activeGlobal, setActiveGlobal] = React56.useState(null);
13732
- const [currentView, setCurrentView] = React56.useState("list");
13733
- const [activeDocumentId, setActiveDocumentId] = React56.useState(null);
13734
- const [isCommandPaletteOpen, setIsCommandPaletteOpen] = React56.useState(false);
13735
- const toasts = useToastStore((state) => state.toasts);
13736
- const removeToast = useToastStore((state) => state.removeToast);
13737
- React56.useEffect(() => {
14117
+ const [activeCollection, setActiveCollection] = React.useState(null);
14118
+ const [activeGlobal, setActiveGlobal] = React.useState(null);
14119
+ const [currentView, setCurrentView] = React.useState("list");
14120
+ const [activeDocumentId, setActiveDocumentId] = React.useState(null);
14121
+ const [isCommandPaletteOpen, setIsCommandPaletteOpen] = React.useState(false);
14122
+ React.useEffect(() => {
13738
14123
  const checkAuth = async () => {
13739
14124
  try {
13740
14125
  const response = await fetch("/api/users/me");
@@ -13749,7 +14134,7 @@ function Admin({ config, theme = "light", onThemeChange }) {
13749
14134
  };
13750
14135
  checkAuth();
13751
14136
  }, []);
13752
- React56.useEffect(() => {
14137
+ React.useEffect(() => {
13753
14138
  if (authenticated && !activeCollection) {
13754
14139
  const firstCol = Object.keys(collections2)[0];
13755
14140
  if (firstCol) setActiveCollection(firstCol);
@@ -13761,7 +14146,7 @@ function Admin({ config, theme = "light", onThemeChange }) {
13761
14146
  if (id) setActiveDocumentId(id);
13762
14147
  setIsCommandPaletteOpen(false);
13763
14148
  };
13764
- React56.useEffect(() => {
14149
+ React.useEffect(() => {
13765
14150
  const handleKeyDown = (e) => {
13766
14151
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
13767
14152
  e.preventDefault();
@@ -13769,7 +14154,11 @@ function Admin({ config, theme = "light", onThemeChange }) {
13769
14154
  }
13770
14155
  };
13771
14156
  window.addEventListener("keydown", handleKeyDown);
13772
- return () => window.removeEventListener("keydown", handleKeyDown);
14157
+ window.openCommandPalette = () => setIsCommandPaletteOpen(true);
14158
+ return () => {
14159
+ window.removeEventListener("keydown", handleKeyDown);
14160
+ delete window.openCommandPalette;
14161
+ };
13773
14162
  }, []);
13774
14163
  if (!authenticated) {
13775
14164
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -13855,15 +14244,7 @@ function Admin({ config, theme = "light", onThemeChange }) {
13855
14244
  renderContent()
13856
14245
  ] }) }) }),
13857
14246
  /* @__PURE__ */ jsxRuntime.jsx(GlobalModal, {}),
13858
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kyro-toasts-container", children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
13859
- Toast,
13860
- {
13861
- type: t.type,
13862
- message: t.message,
13863
- onClose: () => removeToast(t.id)
13864
- },
13865
- t.id
13866
- )) })
14247
+ /* @__PURE__ */ jsxRuntime.jsx(Toaster, {})
13867
14248
  ] }) });
13868
14249
  }
13869
14250
  function BulkActionsBar({
@@ -14161,10 +14542,10 @@ function getApiUrl(path2) {
14161
14542
  return `${base}${path2}`;
14162
14543
  }
14163
14544
  function useKyroQuery(slug, options = {}) {
14164
- const [data, setData] = React56.useState(null);
14165
- const [loading, setLoading] = React56.useState(true);
14166
- const [error, setError] = React56.useState(null);
14167
- const fetchData = React56.useCallback(async () => {
14545
+ const [data, setData] = React.useState(null);
14546
+ const [loading, setLoading] = React.useState(true);
14547
+ const [error, setError] = React.useState(null);
14548
+ const fetchData = React.useCallback(async () => {
14168
14549
  setLoading(true);
14169
14550
  setError(null);
14170
14551
  try {
@@ -14186,15 +14567,15 @@ function useKyroQuery(slug, options = {}) {
14186
14567
  setLoading(false);
14187
14568
  }
14188
14569
  }, [slug, options.page, options.limit, options.sort, options.order]);
14189
- React56.useEffect(() => {
14570
+ React.useEffect(() => {
14190
14571
  fetchData();
14191
14572
  }, [fetchData]);
14192
14573
  return { data, loading, error, refetch: fetchData };
14193
14574
  }
14194
14575
  function useKyroMutation(slug, method = "POST") {
14195
- const [loading, setLoading] = React56.useState(false);
14196
- const [error, setError] = React56.useState(null);
14197
- const mutate = React56.useCallback(
14576
+ const [loading, setLoading] = React.useState(false);
14577
+ const [error, setError] = React.useState(null);
14578
+ const mutate = React.useCallback(
14198
14579
  async (data) => {
14199
14580
  setLoading(true);
14200
14581
  setError(null);