@orion-studios/payload-studio 0.3.0-beta.7 → 0.3.0-beta.8

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.
@@ -2469,9 +2469,65 @@ function AdminStudioNav(props) {
2469
2469
  }
2470
2470
 
2471
2471
  // src/admin/components/studio/AdminStudioPagesListView.tsx
2472
- var import_react12 = require("react");
2472
+ var import_react13 = require("react");
2473
2473
  var import_ui4 = require("@payloadcms/ui");
2474
+
2475
+ // src/admin/components/studio/StudioSectionLayout.tsx
2476
+ var import_react12 = require("react");
2474
2477
  var import_jsx_runtime16 = require("react/jsx-runtime");
2478
+ var STORAGE_KEY2 = "orion-studio-sidebar-collapsed";
2479
+ function StudioSectionLayout({ children, navProps }) {
2480
+ const [collapsed, setCollapsed] = (0, import_react12.useState)(false);
2481
+ (0, import_react12.useEffect)(() => {
2482
+ try {
2483
+ const stored = window.localStorage.getItem(STORAGE_KEY2);
2484
+ if (stored === "1") {
2485
+ setCollapsed(true);
2486
+ }
2487
+ } catch {
2488
+ }
2489
+ }, []);
2490
+ const toggle = () => {
2491
+ setCollapsed((prev) => {
2492
+ const next = !prev;
2493
+ try {
2494
+ window.localStorage.setItem(STORAGE_KEY2, next ? "1" : "0");
2495
+ } catch {
2496
+ }
2497
+ return next;
2498
+ });
2499
+ };
2500
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2501
+ "div",
2502
+ {
2503
+ className: `orion-studio-shell ${collapsed ? "is-collapsed" : ""}`,
2504
+ style: {
2505
+ display: "grid",
2506
+ gridTemplateColumns: collapsed ? "84px minmax(0, 1fr)" : "260px minmax(0, 1fr)",
2507
+ minHeight: "100vh"
2508
+ },
2509
+ children: [
2510
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("aside", { className: "orion-studio-sidebar", children: [
2511
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2512
+ "button",
2513
+ {
2514
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
2515
+ className: "orion-studio-sidebar-toggle",
2516
+ onClick: toggle,
2517
+ type: "button",
2518
+ children: collapsed ? ">" : "<"
2519
+ }
2520
+ ),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "orion-studio-sidebar-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AdminStudioNav, { ...navProps, compact: collapsed }) })
2522
+ ] }),
2523
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("main", { className: "orion-studio-main", children })
2524
+ ]
2525
+ }
2526
+ );
2527
+ }
2528
+
2529
+ // src/admin/components/studio/AdminStudioPagesListView.tsx
2530
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2475
2531
  var isAdmin2 = (user) => {
2476
2532
  if (!user || typeof user !== "object") return false;
2477
2533
  const role = user.role;
@@ -2491,10 +2547,10 @@ var getPropString2 = (props, key, fallback) => {
2491
2547
  function AdminStudioPagesListView(props) {
2492
2548
  const { user } = (0, import_ui4.useAuth)();
2493
2549
  const pagesCollectionSlug = getPropString2(props, "pagesCollectionSlug", "pages");
2494
- const [loading, setLoading] = (0, import_react12.useState)(true);
2495
- const [error, setError] = (0, import_react12.useState)(null);
2496
- const [docs, setDocs] = (0, import_react12.useState)([]);
2497
- const apiURL = (0, import_react12.useMemo)(() => {
2550
+ const [loading, setLoading] = (0, import_react13.useState)(true);
2551
+ const [error, setError] = (0, import_react13.useState)(null);
2552
+ const [docs, setDocs] = (0, import_react13.useState)([]);
2553
+ const apiURL = (0, import_react13.useMemo)(() => {
2498
2554
  const params = new URLSearchParams({
2499
2555
  depth: "0",
2500
2556
  limit: "100",
@@ -2503,7 +2559,7 @@ function AdminStudioPagesListView(props) {
2503
2559
  });
2504
2560
  return `/api/${pagesCollectionSlug}?${params.toString()}`;
2505
2561
  }, [pagesCollectionSlug]);
2506
- (0, import_react12.useEffect)(() => {
2562
+ (0, import_react13.useEffect)(() => {
2507
2563
  let cancelled = false;
2508
2564
  const run = async () => {
2509
2565
  setLoading(true);
@@ -2528,14 +2584,14 @@ function AdminStudioPagesListView(props) {
2528
2584
  cancelled = true;
2529
2585
  };
2530
2586
  }, [apiURL]);
2531
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2532
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ui4.SetStepNav, { nav: [{ label: "Pages", url: "/admin/pages" }] }),
2533
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { alignItems: "flex-end", display: "flex", gap: "0.75rem" }, children: [
2534
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { flex: 1 }, children: [
2535
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h1", { style: { margin: 0 }, children: "Pages" }),
2536
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Open a page to edit it in the custom editor." })
2587
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(StudioSectionLayout, { navProps: props, children: [
2588
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ui4.SetStepNav, { nav: [{ label: "Pages", url: "/admin/pages" }] }),
2589
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { alignItems: "flex-end", display: "flex", gap: "0.75rem" }, children: [
2590
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { flex: 1 }, children: [
2591
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h1", { style: { margin: 0 }, children: "Pages" }),
2592
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Open a page to edit it in the custom editor." })
2537
2593
  ] }),
2538
- isAdmin2(user) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2594
+ isAdmin2(user) ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2539
2595
  "a",
2540
2596
  {
2541
2597
  href: `/admin/collections/${pagesCollectionSlug}/create`,
@@ -2551,10 +2607,10 @@ function AdminStudioPagesListView(props) {
2551
2607
  }
2552
2608
  ) : null
2553
2609
  ] }),
2554
- loading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "1rem" }, children: "Loading..." }) : null,
2555
- error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { color: "crimson", marginTop: "1rem" }, children: error }) : null,
2556
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: [
2557
- !loading && !error && docs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2610
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "1rem" }, children: "Loading..." }) : null,
2611
+ error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { color: "crimson", marginTop: "1rem" }, children: error }) : null,
2612
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: [
2613
+ !loading && !error && docs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2558
2614
  "div",
2559
2615
  {
2560
2616
  style: {
@@ -2572,7 +2628,7 @@ function AdminStudioPagesListView(props) {
2572
2628
  const path = typeof doc.path === "string" ? doc.path : "/";
2573
2629
  const status = typeof doc._status === "string" ? doc._status : "";
2574
2630
  if (!id) return null;
2575
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2631
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2576
2632
  "a",
2577
2633
  {
2578
2634
  href: `/admin/pages/${id}`,
@@ -2588,9 +2644,9 @@ function AdminStudioPagesListView(props) {
2588
2644
  textDecoration: "none"
2589
2645
  },
2590
2646
  children: [
2591
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { minWidth: 0 }, children: [
2592
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { fontWeight: 900, overflow: "hidden", textOverflow: "ellipsis" }, children: title }),
2593
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2647
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { minWidth: 0 }, children: [
2648
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { fontWeight: 900, overflow: "hidden", textOverflow: "ellipsis" }, children: title }),
2649
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2594
2650
  "div",
2595
2651
  {
2596
2652
  style: {
@@ -2603,7 +2659,7 @@ function AdminStudioPagesListView(props) {
2603
2659
  }
2604
2660
  )
2605
2661
  ] }),
2606
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2662
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2607
2663
  "div",
2608
2664
  {
2609
2665
  style: {
@@ -2613,7 +2669,7 @@ function AdminStudioPagesListView(props) {
2613
2669
  gap: "0.5rem"
2614
2670
  },
2615
2671
  children: [
2616
- status ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2672
+ status ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2617
2673
  "span",
2618
2674
  {
2619
2675
  style: {
@@ -2628,7 +2684,7 @@ function AdminStudioPagesListView(props) {
2628
2684
  children: status
2629
2685
  }
2630
2686
  ) : null,
2631
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { color: "var(--theme-elevation-600)", fontWeight: 800 }, children: "Open" })
2687
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { color: "var(--theme-elevation-600)", fontWeight: 800 }, children: "Open" })
2632
2688
  ]
2633
2689
  }
2634
2690
  )
@@ -2642,9 +2698,9 @@ function AdminStudioPagesListView(props) {
2642
2698
  }
2643
2699
 
2644
2700
  // src/admin/components/studio/AdminStudioPageEditView.tsx
2645
- var import_react13 = require("react");
2701
+ var import_react14 = require("react");
2646
2702
  var import_ui5 = require("@payloadcms/ui");
2647
- var import_jsx_runtime17 = require("react/jsx-runtime");
2703
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2648
2704
  var isAdmin3 = (user) => {
2649
2705
  if (!user || typeof user !== "object") return false;
2650
2706
  const role = user.role;
@@ -2680,13 +2736,13 @@ var getPageIDFromPathname = (pathname) => {
2680
2736
  };
2681
2737
  function AdminStudioPageEditView(props) {
2682
2738
  const { user } = (0, import_ui5.useAuth)();
2683
- const iframeRef = (0, import_react13.useRef)(null);
2684
- const [saving, setSaving] = (0, import_react13.useState)(null);
2739
+ const iframeRef = (0, import_react14.useRef)(null);
2740
+ const [saving, setSaving] = (0, import_react14.useState)(null);
2685
2741
  const builderBasePath = getPropString3(props, "builderBasePath", "/builder");
2686
- const pageIDFromParams = (0, import_react13.useMemo)(() => getParam(props.params, "id"), [props.params]);
2687
- const [pageID, setPageID] = (0, import_react13.useState)(pageIDFromParams);
2688
- const [didResolvePathFallback, setDidResolvePathFallback] = (0, import_react13.useState)(false);
2689
- (0, import_react13.useEffect)(() => {
2742
+ const pageIDFromParams = (0, import_react14.useMemo)(() => getParam(props.params, "id"), [props.params]);
2743
+ const [pageID, setPageID] = (0, import_react14.useState)(pageIDFromParams);
2744
+ const [didResolvePathFallback, setDidResolvePathFallback] = (0, import_react14.useState)(false);
2745
+ (0, import_react14.useEffect)(() => {
2690
2746
  if (pageIDFromParams) {
2691
2747
  setPageID(pageIDFromParams);
2692
2748
  setDidResolvePathFallback(true);
@@ -2707,7 +2763,7 @@ function AdminStudioPageEditView(props) {
2707
2763
  setSaving(status);
2708
2764
  iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "save", status }, "*");
2709
2765
  };
2710
- (0, import_react13.useEffect)(() => {
2766
+ (0, import_react14.useEffect)(() => {
2711
2767
  const onMessage = (event) => {
2712
2768
  const data = event.data;
2713
2769
  if (!data || data.source !== "payload-visual-builder-child" || data.type !== "save-result") {
@@ -2724,107 +2780,136 @@ function AdminStudioPageEditView(props) {
2724
2780
  return () => window.removeEventListener("message", onMessage);
2725
2781
  }, []);
2726
2782
  if (!pageID && !didResolvePathFallback) {
2727
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { padding: "1.2rem" }, children: [
2728
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h1", { style: { margin: 0 }, children: "Page Editor" }),
2729
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "Loading page editor..." })
2783
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(StudioSectionLayout, { navProps: props, children: [
2784
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2785
+ import_ui5.SetStepNav,
2786
+ {
2787
+ nav: [
2788
+ { label: "Pages", url: "/admin/pages" },
2789
+ { label: "Page Editor", url: "/admin/pages" }
2790
+ ]
2791
+ }
2792
+ ),
2793
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h1", { style: { margin: 0 }, children: "Page Editor" }),
2794
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "Loading page editor..." })
2730
2795
  ] });
2731
2796
  }
2732
2797
  if (!pageID) {
2733
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { padding: "1.2rem" }, children: [
2734
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h1", { style: { margin: 0 }, children: "Page Editor" }),
2735
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "Missing page ID." })
2798
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(StudioSectionLayout, { navProps: props, children: [
2799
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2800
+ import_ui5.SetStepNav,
2801
+ {
2802
+ nav: [
2803
+ { label: "Pages", url: "/admin/pages" },
2804
+ { label: "Page Editor", url: "/admin/pages" }
2805
+ ]
2806
+ }
2807
+ ),
2808
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h1", { style: { margin: 0 }, children: "Page Editor" }),
2809
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "Missing page ID." })
2736
2810
  ] });
2737
2811
  }
2738
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "grid", gridTemplateRows: "auto 1fr", height: "calc(100vh - 0px)" }, children: [
2739
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2740
- "div",
2812
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(StudioSectionLayout, { navProps: props, children: [
2813
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2814
+ import_ui5.SetStepNav,
2741
2815
  {
2742
- style: {
2743
- alignItems: "center",
2744
- background: "var(--theme-elevation-0)",
2745
- borderBottom: "1px solid var(--theme-elevation-150)",
2746
- display: "flex",
2747
- gap: "0.6rem",
2748
- justifyContent: "space-between",
2749
- padding: "0.65rem 0.9rem",
2750
- position: "sticky",
2751
- top: 0,
2752
- zIndex: 20
2753
- },
2754
- children: [
2755
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { minWidth: 0 }, children: [
2756
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { fontWeight: 900 }, children: "Page Editor" }),
2757
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2758
- "div",
2759
- {
2760
- style: {
2761
- color: "var(--theme-elevation-600)",
2762
- fontSize: "0.85rem",
2763
- overflow: "hidden",
2764
- textOverflow: "ellipsis"
2765
- },
2766
- children: [
2767
- "Editing: ",
2768
- pageID
2769
- ]
2770
- }
2771
- )
2772
- ] }),
2773
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
2774
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2775
- "button",
2776
- {
2777
- disabled: saving !== null,
2778
- onClick: () => requestSave("draft"),
2779
- style: {
2780
- border: "1px solid var(--theme-elevation-300)",
2781
- borderRadius: 12,
2782
- cursor: saving ? "not-allowed" : "pointer",
2783
- fontWeight: 800,
2784
- padding: "0.5rem 0.75rem"
2785
- },
2786
- type: "button",
2787
- children: saving === "draft" ? "Saving\u2026" : "Save Draft"
2788
- }
2789
- ),
2790
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2791
- "button",
2792
- {
2793
- disabled: !canPublish || saving !== null,
2794
- onClick: () => requestSave("published"),
2795
- style: {
2796
- background: canPublish ? "var(--theme-elevation-900)" : "var(--theme-elevation-300)",
2797
- border: "none",
2798
- borderRadius: 12,
2799
- color: canPublish ? "var(--theme-elevation-0)" : "var(--theme-elevation-700)",
2800
- cursor: !canPublish || saving ? "not-allowed" : "pointer",
2801
- fontWeight: 900,
2802
- padding: "0.5rem 0.75rem"
2803
- },
2804
- type: "button",
2805
- title: !canPublish ? "You do not have publish permissions." : void 0,
2806
- children: saving === "published" ? "Publishing\u2026" : "Publish"
2807
- }
2808
- )
2809
- ] })
2816
+ nav: [
2817
+ { label: "Pages", url: "/admin/pages" },
2818
+ { label: `Page ${pageID}`, url: `/admin/pages/${pageID}` }
2810
2819
  ]
2811
2820
  }
2812
2821
  ),
2813
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2814
- "iframe",
2815
- {
2816
- ref: iframeRef,
2817
- src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
2818
- style: { border: "none", height: "100%", width: "100%" },
2819
- title: "Page Builder"
2820
- }
2821
- )
2822
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "grid", gridTemplateRows: "auto 1fr", height: "calc(100vh - 120px)" }, children: [
2823
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2824
+ "div",
2825
+ {
2826
+ style: {
2827
+ alignItems: "center",
2828
+ background: "var(--theme-elevation-0)",
2829
+ borderBottom: "1px solid var(--theme-elevation-150)",
2830
+ display: "flex",
2831
+ gap: "0.6rem",
2832
+ justifyContent: "space-between",
2833
+ padding: "0.65rem 0.9rem",
2834
+ position: "sticky",
2835
+ top: 0,
2836
+ zIndex: 20
2837
+ },
2838
+ children: [
2839
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { minWidth: 0 }, children: [
2840
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontWeight: 900 }, children: "Page Editor" }),
2841
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2842
+ "div",
2843
+ {
2844
+ style: {
2845
+ color: "var(--theme-elevation-600)",
2846
+ fontSize: "0.85rem",
2847
+ overflow: "hidden",
2848
+ textOverflow: "ellipsis"
2849
+ },
2850
+ children: [
2851
+ "Editing: ",
2852
+ pageID
2853
+ ]
2854
+ }
2855
+ )
2856
+ ] }),
2857
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
2858
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2859
+ "button",
2860
+ {
2861
+ disabled: saving !== null,
2862
+ onClick: () => requestSave("draft"),
2863
+ style: {
2864
+ border: "1px solid var(--theme-elevation-300)",
2865
+ borderRadius: 12,
2866
+ cursor: saving ? "not-allowed" : "pointer",
2867
+ fontWeight: 800,
2868
+ padding: "0.5rem 0.75rem"
2869
+ },
2870
+ type: "button",
2871
+ children: saving === "draft" ? "Saving\u2026" : "Save Draft"
2872
+ }
2873
+ ),
2874
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2875
+ "button",
2876
+ {
2877
+ disabled: !canPublish || saving !== null,
2878
+ onClick: () => requestSave("published"),
2879
+ style: {
2880
+ background: canPublish ? "var(--theme-elevation-900)" : "var(--theme-elevation-300)",
2881
+ border: "none",
2882
+ borderRadius: 12,
2883
+ color: canPublish ? "var(--theme-elevation-0)" : "var(--theme-elevation-700)",
2884
+ cursor: !canPublish || saving ? "not-allowed" : "pointer",
2885
+ fontWeight: 900,
2886
+ padding: "0.5rem 0.75rem"
2887
+ },
2888
+ type: "button",
2889
+ title: !canPublish ? "You do not have publish permissions." : void 0,
2890
+ children: saving === "published" ? "Publishing\u2026" : "Publish"
2891
+ }
2892
+ )
2893
+ ] })
2894
+ ]
2895
+ }
2896
+ ),
2897
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2898
+ "iframe",
2899
+ {
2900
+ ref: iframeRef,
2901
+ src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
2902
+ style: { border: "none", height: "100%", width: "100%" },
2903
+ title: "Page Builder"
2904
+ }
2905
+ )
2906
+ ] })
2822
2907
  ] });
2823
2908
  }
2824
2909
 
2825
2910
  // src/admin/components/studio/AdminStudioGlobalsView.tsx
2826
2911
  var import_ui6 = require("@payloadcms/ui");
2827
- var import_jsx_runtime18 = require("react/jsx-runtime");
2912
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2828
2913
  var getPropGlobals = (props) => {
2829
2914
  if (!props || typeof props !== "object") return null;
2830
2915
  const direct = props.globals;
@@ -2854,11 +2939,11 @@ function AdminStudioGlobalsView(props) {
2854
2939
  { slug: "header", label: "Header & Navigation" },
2855
2940
  { slug: "footer", label: "Footer" }
2856
2941
  ];
2857
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
2858
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ui6.SetStepNav, { nav: [{ label: "Globals", url: globalsBasePath }] }),
2859
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h1", { style: { margin: 0 }, children: "Globals" }),
2860
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Site-wide settings." }),
2861
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: globals.map((global) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2942
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(StudioSectionLayout, { navProps: props, children: [
2943
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ui6.SetStepNav, { nav: [{ label: "Globals", url: globalsBasePath }] }),
2944
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { style: { margin: 0 }, children: "Globals" }),
2945
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Site-wide settings." }),
2946
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: globals.map((global) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2862
2947
  "a",
2863
2948
  {
2864
2949
  href: `/admin/globals/${global.slug}`,
@@ -2871,8 +2956,8 @@ function AdminStudioGlobalsView(props) {
2871
2956
  textDecoration: "none"
2872
2957
  },
2873
2958
  children: [
2874
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontWeight: 900 }, children: global.label }),
2875
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
2959
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontWeight: 900 }, children: global.label }),
2960
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
2876
2961
  "/admin/globals/",
2877
2962
  global.slug
2878
2963
  ] })
@@ -2880,7 +2965,7 @@ function AdminStudioGlobalsView(props) {
2880
2965
  },
2881
2966
  global.slug
2882
2967
  )) }),
2883
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2968
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2884
2969
  "a",
2885
2970
  {
2886
2971
  href: globalsBasePath,
@@ -2893,7 +2978,7 @@ function AdminStudioGlobalsView(props) {
2893
2978
 
2894
2979
  // src/admin/components/studio/AdminStudioMediaView.tsx
2895
2980
  var import_ui7 = require("@payloadcms/ui");
2896
- var import_jsx_runtime19 = require("react/jsx-runtime");
2981
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2897
2982
  var getPropString5 = (props, key, fallback) => {
2898
2983
  if (!props || typeof props !== "object") return fallback;
2899
2984
  const direct = props[key];
@@ -2907,11 +2992,11 @@ var getPropString5 = (props, key, fallback) => {
2907
2992
  };
2908
2993
  function AdminStudioMediaView(props) {
2909
2994
  const mediaCollectionSlug = getPropString5(props, "mediaCollectionSlug", "media");
2910
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2911
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ui7.SetStepNav, { nav: [{ label: "Media", url: "/admin/media" }] }),
2912
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { style: { margin: 0 }, children: "Media" }),
2913
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Media management is currently using Payload's library." }),
2914
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2995
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(StudioSectionLayout, { navProps: props, children: [
2996
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui7.SetStepNav, { nav: [{ label: "Media", url: "/admin/media" }] }),
2997
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Media" }),
2998
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Media management is currently using Payload's library." }),
2999
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2915
3000
  "a",
2916
3001
  {
2917
3002
  href: `/admin/collections/${mediaCollectionSlug}`,
@@ -2924,8 +3009,8 @@ function AdminStudioMediaView(props) {
2924
3009
  textDecoration: "none"
2925
3010
  },
2926
3011
  children: [
2927
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontWeight: 900 }, children: "Open Media Library" }),
2928
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
3012
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontWeight: 900 }, children: "Open Media Library" }),
3013
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
2929
3014
  "/admin/collections/",
2930
3015
  mediaCollectionSlug
2931
3016
  ] })
@@ -2937,7 +3022,7 @@ function AdminStudioMediaView(props) {
2937
3022
 
2938
3023
  // src/admin/components/studio/AdminStudioToolsView.tsx
2939
3024
  var import_ui8 = require("@payloadcms/ui");
2940
- var import_jsx_runtime20 = require("react/jsx-runtime");
3025
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2941
3026
  var isAdmin4 = (user) => {
2942
3027
  if (!user || typeof user !== "object") return false;
2943
3028
  const role = user.role;
@@ -2957,10 +3042,10 @@ var getPropString6 = (props, key, fallback) => {
2957
3042
  function AdminStudioToolsView(props) {
2958
3043
  const { user } = (0, import_ui8.useAuth)();
2959
3044
  if (!isAdmin4(user)) {
2960
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2961
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui8.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
2962
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
2963
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "You do not have access to this page." })
3045
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(StudioSectionLayout, { navProps: props, children: [
3046
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ui8.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
3047
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3048
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "You do not have access to this page." })
2964
3049
  ] });
2965
3050
  }
2966
3051
  const pagesCollectionSlug = getPropString6(props, "pagesCollectionSlug", "pages");
@@ -2973,11 +3058,11 @@ function AdminStudioToolsView(props) {
2973
3058
  { href: "/admin/globals/footer", label: "Raw Footer Global" },
2974
3059
  { href: "/admin/collections/users", label: "Users / Roles" }
2975
3060
  ];
2976
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2977
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui8.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
2978
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
2979
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Hidden fallback links for administrators." }),
2980
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3061
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(StudioSectionLayout, { navProps: props, children: [
3062
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ui8.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
3063
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3064
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Hidden fallback links for administrators." }),
3065
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2981
3066
  "a",
2982
3067
  {
2983
3068
  href: link.href,
@@ -2990,8 +3075,8 @@ function AdminStudioToolsView(props) {
2990
3075
  textDecoration: "none"
2991
3076
  },
2992
3077
  children: [
2993
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontWeight: 900 }, children: link.label }),
2994
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: link.href })
3078
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontWeight: 900 }, children: link.label }),
3079
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: link.href })
2995
3080
  ]
2996
3081
  },
2997
3082
  link.href
@@ -3001,14 +3086,14 @@ function AdminStudioToolsView(props) {
3001
3086
 
3002
3087
  // src/admin/components/studio/OpenInStudioMenuItem.tsx
3003
3088
  var import_ui9 = require("@payloadcms/ui");
3004
- var import_jsx_runtime21 = require("react/jsx-runtime");
3089
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3005
3090
  function OpenInStudioMenuItem({ pagesPathBase = "/admin/pages" }) {
3006
3091
  const documentInfo = (0, import_ui9.useDocumentInfo)();
3007
3092
  const id = documentInfo?.id;
3008
3093
  if (!id) {
3009
3094
  return null;
3010
3095
  }
3011
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3096
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3012
3097
  "a",
3013
3098
  {
3014
3099
  href: `${pagesPathBase}/${id}`,
@@ -3027,19 +3112,19 @@ function OpenInStudioMenuItem({ pagesPathBase = "/admin/pages" }) {
3027
3112
  }
3028
3113
 
3029
3114
  // src/admin/components/studio/PageEditRedirectToStudio.tsx
3030
- var import_react14 = require("react");
3115
+ var import_react15 = require("react");
3031
3116
  var import_ui10 = require("@payloadcms/ui");
3032
- var import_jsx_runtime22 = require("react/jsx-runtime");
3117
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3033
3118
  function PageEditRedirectToStudio({ pagesPathBase = "/admin/pages" }) {
3034
3119
  const documentInfo = (0, import_ui10.useDocumentInfo)();
3035
3120
  const id = documentInfo?.id;
3036
- (0, import_react14.useEffect)(() => {
3121
+ (0, import_react15.useEffect)(() => {
3037
3122
  if (!id) {
3038
3123
  return;
3039
3124
  }
3040
3125
  window.location.replace(`${pagesPathBase}/${id}`);
3041
3126
  }, [id, pagesPathBase]);
3042
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3127
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
3043
3128
  "div",
3044
3129
  {
3045
3130
  style: {
@@ -3051,9 +3136,9 @@ function PageEditRedirectToStudio({ pagesPathBase = "/admin/pages" }) {
3051
3136
  minHeight: "50vh"
3052
3137
  },
3053
3138
  children: [
3054
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { style: { margin: 0 }, children: "Opening Editor..." }),
3055
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { color: "var(--theme-elevation-600)", margin: 0 }, children: "Redirecting to the custom page editor." }),
3056
- id ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { href: `${pagesPathBase}/${id}`, children: "Continue to Editor" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { href: pagesPathBase, children: "Open Pages" })
3139
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { style: { margin: 0 }, children: "Opening Editor..." }),
3140
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { color: "var(--theme-elevation-600)", margin: 0 }, children: "Redirecting to the custom page editor." }),
3141
+ id ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { href: `${pagesPathBase}/${id}`, children: "Continue to Editor" }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { href: pagesPathBase, children: "Open Pages" })
3057
3142
  ]
3058
3143
  }
3059
3144
  );
@@ -3062,36 +3147,44 @@ function PageEditRedirectToStudio({ pagesPathBase = "/admin/pages" }) {
3062
3147
  // src/admin/components/studio/StudioBackBreadcrumb.tsx
3063
3148
  var import_ui11 = require("@payloadcms/ui");
3064
3149
  var import_navigation = require("next/navigation");
3065
- var import_react15 = require("react");
3066
- var import_jsx_runtime23 = require("react/jsx-runtime");
3150
+ var import_react16 = require("react");
3151
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3067
3152
  var resolveSectionLink = (pathname) => {
3068
3153
  if (pathname.includes("/globals/")) {
3069
- return { href: "/admin/studio-globals", label: "Globals" };
3154
+ return { label: "Globals", url: "/admin/studio-globals" };
3070
3155
  }
3071
3156
  if (pathname.includes("/collections/pages") || pathname.startsWith("/admin/pages/")) {
3072
- return { href: "/admin/pages", label: "Pages" };
3157
+ return { label: "Pages", url: "/admin/pages" };
3073
3158
  }
3074
3159
  if (pathname.includes("/collections/media")) {
3075
- return { href: "/admin/media", label: "Media" };
3160
+ return { label: "Media", url: "/admin/media" };
3076
3161
  }
3077
3162
  if (pathname.startsWith("/admin/tools")) {
3078
- return { href: "/admin/tools", label: "Admin Tools" };
3163
+ return { label: "Admin Tools", url: "/admin/tools" };
3079
3164
  }
3080
3165
  return null;
3081
3166
  };
3167
+ var normalizeItem = (item) => {
3168
+ if (!item || typeof item !== "object") return null;
3169
+ const row = item;
3170
+ if (typeof row.label !== "string" || row.label.length === 0) return null;
3171
+ if (typeof row.url === "string" && row.url.length > 0) {
3172
+ return { label: row.label, url: row.url };
3173
+ }
3174
+ return { label: row.label };
3175
+ };
3082
3176
  function StudioBackBreadcrumb() {
3083
3177
  const pathname = (0, import_navigation.usePathname)();
3084
3178
  const { stepNav } = (0, import_ui11.useStepNav)();
3085
3179
  const section = resolveSectionLink(pathname);
3086
- const mergedNav = (0, import_react15.useMemo)(() => {
3180
+ const mergedNav = (0, import_react16.useMemo)(() => {
3087
3181
  if (!section) return stepNav;
3088
- const rest = stepNav.filter((item) => {
3089
- return !(typeof item.label === "string" && item.label.toLowerCase() === section.label.toLowerCase());
3090
- });
3091
- return [{ label: section.label, url: section.href }, ...rest];
3182
+ const sectionLabel = section.label.toLowerCase();
3183
+ const normalized = stepNav.map((item) => normalizeItem(item)).filter((item) => Boolean(item)).filter((item) => item.label.toLowerCase() !== sectionLabel);
3184
+ return [section, ...normalized];
3092
3185
  }, [section, stepNav]);
3093
3186
  if (!section) return null;
3094
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ui11.SetStepNav, { nav: mergedNav });
3187
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui11.SetStepNav, { nav: mergedNav });
3095
3188
  }
3096
3189
  // Annotate the CommonJS export names for ESM import in node:
3097
3190
  0 && (module.exports = {