@orion-studios/payload-studio 0.5.0-beta.7 → 0.5.0-beta.71

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 (67) hide show
  1. package/README.md +20 -0
  2. package/dist/admin/client.d.mts +2 -0
  3. package/dist/admin/client.d.ts +2 -0
  4. package/dist/admin/client.js +779 -137
  5. package/dist/admin/client.mjs +769 -129
  6. package/dist/admin/index.d.mts +1 -1
  7. package/dist/admin/index.d.ts +1 -1
  8. package/dist/admin/index.js +100 -8
  9. package/dist/admin/index.mjs +3 -1
  10. package/dist/admin-app/client.d.mts +7 -0
  11. package/dist/admin-app/client.d.ts +7 -0
  12. package/dist/admin-app/client.js +1262 -3
  13. package/dist/admin-app/client.mjs +1164 -2
  14. package/dist/admin-app/index.d.mts +1 -1
  15. package/dist/admin-app/index.d.ts +1 -1
  16. package/dist/admin-app/index.js +167 -0
  17. package/dist/admin-app/index.mjs +13 -1
  18. package/dist/admin-app/styles.css +229 -0
  19. package/dist/blocks/index.js +633 -8
  20. package/dist/blocks/index.mjs +2 -2
  21. package/dist/{chunk-ZLLNO5FM.mjs → chunk-6H4JTVPY.mjs} +44 -13
  22. package/dist/chunk-C6VEFZVY.mjs +1072 -0
  23. package/dist/{chunk-J7W5EE3B.mjs → chunk-HCEPGEAI.mjs} +100 -8
  24. package/dist/chunk-HXGAG6I7.mjs +325 -0
  25. package/dist/chunk-ROTPP5CU.mjs +99 -0
  26. package/dist/{chunk-ETRRXURT.mjs → chunk-SIL2J5MF.mjs} +14 -0
  27. package/dist/{chunk-PC5622T7.mjs → chunk-XK3K5GRP.mjs} +620 -9
  28. package/dist/chunk-XVH5SCBD.mjs +234 -0
  29. package/dist/{index-CmR6NInu.d.ts → index-BIwu3qIH.d.mts} +29 -3
  30. package/dist/{index-CmR6NInu.d.mts → index-BIwu3qIH.d.ts} +29 -3
  31. package/dist/index-CdnUNrvX.d.mts +134 -0
  32. package/dist/{index-DbH0Ljwp.d.ts → index-CpG3UHcS.d.mts} +1 -0
  33. package/dist/{index-DbH0Ljwp.d.mts → index-CpG3UHcS.d.ts} +1 -0
  34. package/dist/index-DyHbWliW.d.ts +134 -0
  35. package/dist/index-ZbOx4OCF.d.mts +128 -0
  36. package/dist/index-ZbOx4OCF.d.ts +128 -0
  37. package/dist/{index-DJFhANvJ.d.mts → index-cDYkEj29.d.mts} +20 -2
  38. package/dist/{index-DJFhANvJ.d.ts → index-cDYkEj29.d.ts} +20 -2
  39. package/dist/index.d.mts +5 -5
  40. package/dist/index.d.ts +5 -5
  41. package/dist/index.js +2145 -305
  42. package/dist/index.mjs +9 -9
  43. package/dist/nextjs/index.d.mts +1 -1
  44. package/dist/nextjs/index.d.ts +1 -1
  45. package/dist/nextjs/index.js +996 -13
  46. package/dist/nextjs/index.mjs +4 -1
  47. package/dist/studio/index.d.mts +2 -1
  48. package/dist/studio/index.d.ts +2 -1
  49. package/dist/studio/index.js +171 -2
  50. package/dist/studio/index.mjs +7 -3
  51. package/dist/studio-pages/builder.css +358 -8
  52. package/dist/studio-pages/client.d.mts +17 -0
  53. package/dist/studio-pages/client.d.ts +17 -0
  54. package/dist/studio-pages/client.js +5657 -1478
  55. package/dist/studio-pages/client.mjs +5549 -1461
  56. package/dist/studio-pages/index.d.mts +3 -2
  57. package/dist/studio-pages/index.d.ts +3 -2
  58. package/dist/studio-pages/index.js +799 -29
  59. package/dist/studio-pages/index.mjs +6 -2
  60. package/package.json +26 -12
  61. package/dist/chunk-AAOHJDNS.mjs +0 -67
  62. package/dist/chunk-N67KVM2S.mjs +0 -156
  63. package/dist/chunk-UJFU323N.mjs +0 -301
  64. package/dist/index-B9N5MyjF.d.mts +0 -39
  65. package/dist/index-BallJs-K.d.mts +0 -43
  66. package/dist/index-BallJs-K.d.ts +0 -43
  67. package/dist/index-g8tBHLKD.d.ts +0 -39
@@ -1156,6 +1156,7 @@ var init_OrionBlocksFieldImpl = __esm({
1156
1156
  // src/admin/client.ts
1157
1157
  var client_exports = {};
1158
1158
  __export(client_exports, {
1159
+ AdminStudioContactFormView: () => AdminStudioContactFormView,
1159
1160
  AdminStudioDashboard: () => AdminStudioDashboard,
1160
1161
  AdminStudioGlobalsView: () => AdminStudioGlobalsView,
1161
1162
  AdminStudioMediaView: () => AdminStudioMediaView,
@@ -1175,6 +1176,7 @@ __export(client_exports, {
1175
1176
  SectionTabs: () => SectionTabs,
1176
1177
  StatusBadge: () => StatusBadge,
1177
1178
  StudioBackBreadcrumb: () => StudioBackBreadcrumb,
1179
+ StudioContactFormRedirect: () => StudioContactFormRedirect,
1178
1180
  ThemeProvider: () => ThemeProvider,
1179
1181
  ThemeSwitcher: () => ThemeSwitcher,
1180
1182
  WelcomeHeader: () => WelcomeHeader,
@@ -2277,6 +2279,83 @@ function WelcomeHeader({
2277
2279
 
2278
2280
  // src/admin/components/studio/AdminStudioDashboard.tsx
2279
2281
  var import_ui3 = require("@payloadcms/ui");
2282
+
2283
+ // src/admin/components/studio/adminPathUtils.ts
2284
+ var import_react11 = require("react");
2285
+ var DEFAULT_ADMIN_BASE_PATH = "/admin";
2286
+ var normalizePath = (value) => {
2287
+ if (!value || value === "/") return "/";
2288
+ const withLeadingSlash = value.startsWith("/") ? value : `/${value}`;
2289
+ const trimmed = withLeadingSlash.replace(/\/+$/, "");
2290
+ return trimmed.length > 0 ? trimmed : "/";
2291
+ };
2292
+ var normalizeAdminBasePath = (value) => {
2293
+ const normalized = normalizePath(value);
2294
+ return normalized === "/" ? DEFAULT_ADMIN_BASE_PATH : normalized;
2295
+ };
2296
+ var detectAdminBasePath = (pathname, fallback = DEFAULT_ADMIN_BASE_PATH) => {
2297
+ const normalizedPathname = normalizePath(pathname);
2298
+ const normalizedFallback = normalizeAdminBasePath(fallback);
2299
+ const markers = [
2300
+ "/studio-contact-form",
2301
+ "/studio-globals",
2302
+ "/collections/",
2303
+ "/globals/",
2304
+ "/pages/",
2305
+ "/tools",
2306
+ "/media",
2307
+ "/logout",
2308
+ "/login"
2309
+ ];
2310
+ for (const marker of markers) {
2311
+ const index = normalizedPathname.indexOf(marker);
2312
+ if (index > 0) {
2313
+ return normalizeAdminBasePath(normalizedPathname.slice(0, index));
2314
+ }
2315
+ }
2316
+ if (normalizedPathname === normalizedFallback || normalizedPathname.startsWith(`${normalizedFallback}/`)) {
2317
+ return normalizedFallback;
2318
+ }
2319
+ const segments = normalizedPathname.split("/").filter(Boolean);
2320
+ if (segments.length > 0) {
2321
+ return normalizeAdminBasePath(`/${segments[0]}`);
2322
+ }
2323
+ return normalizedFallback;
2324
+ };
2325
+ var isAbsoluteExternalURL = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
2326
+ var resolveAdminPath = (adminBasePath, targetPath) => {
2327
+ if (!targetPath) return adminBasePath;
2328
+ if (isAbsoluteExternalURL(targetPath)) return targetPath;
2329
+ const normalizedBasePath = normalizeAdminBasePath(adminBasePath);
2330
+ const normalizedTargetPath = normalizePath(targetPath);
2331
+ if (normalizedTargetPath === "/admin") {
2332
+ return normalizedBasePath;
2333
+ }
2334
+ if (normalizedTargetPath.startsWith("/admin/")) {
2335
+ return `${normalizedBasePath}${normalizedTargetPath.slice("/admin".length)}`;
2336
+ }
2337
+ if (normalizedTargetPath === normalizedBasePath || normalizedTargetPath.startsWith(`${normalizedBasePath}/`)) {
2338
+ return normalizedTargetPath;
2339
+ }
2340
+ if (normalizedTargetPath === "/") {
2341
+ return normalizedBasePath;
2342
+ }
2343
+ return `${normalizedBasePath}${normalizedTargetPath}`;
2344
+ };
2345
+ var useAdminBasePath = (fallback = DEFAULT_ADMIN_BASE_PATH) => {
2346
+ const [adminBasePath, setAdminBasePath] = (0, import_react11.useState)(normalizeAdminBasePath(fallback));
2347
+ (0, import_react11.useEffect)(() => {
2348
+ const update = () => {
2349
+ setAdminBasePath(detectAdminBasePath(window.location.pathname, fallback));
2350
+ };
2351
+ update();
2352
+ window.addEventListener("popstate", update);
2353
+ return () => window.removeEventListener("popstate", update);
2354
+ }, [fallback]);
2355
+ return adminBasePath;
2356
+ };
2357
+
2358
+ // src/admin/components/studio/AdminStudioDashboard.tsx
2280
2359
  var import_jsx_runtime14 = require("react/jsx-runtime");
2281
2360
  var cardStyle = {
2282
2361
  background: "var(--theme-elevation-0)",
@@ -2300,9 +2379,13 @@ var getPropString = (props, key, fallback) => {
2300
2379
  function AdminStudioDashboard(props) {
2301
2380
  const pagesCollectionSlug = getPropString(props, "pagesCollectionSlug", "pages");
2302
2381
  const mediaCollectionSlug = getPropString(props, "mediaCollectionSlug", "media");
2303
- const globalsBasePath = getPropString(props, "globalsBasePath", "/admin/globals");
2382
+ const globalsBasePath = getPropString(props, "globalsBasePath", "/studio-globals");
2383
+ const adminBasePath = useAdminBasePath();
2384
+ const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
2385
+ const pagesPath = resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`);
2386
+ const mediaPath = resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`);
2304
2387
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { padding: "1.2rem 1.2rem 2.5rem" }, children: [
2305
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ui3.SetStepNav, { nav: [{ label: "Dashboard", url: "/admin" }] }),
2388
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ui3.SetStepNav, { nav: [{ label: "Dashboard", url: adminBasePath }] }),
2306
2389
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h1", { style: { fontSize: "1.6rem", margin: 0 }, children: "Studio" }),
2307
2390
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Pick what you want to edit." }),
2308
2391
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
@@ -2315,15 +2398,15 @@ function AdminStudioDashboard(props) {
2315
2398
  marginTop: "1.1rem"
2316
2399
  },
2317
2400
  children: [
2318
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: `/admin/collections/${pagesCollectionSlug}`, style: cardStyle, children: [
2401
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: pagesPath, style: cardStyle, children: [
2319
2402
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 900 }, children: "Pages" }),
2320
2403
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: "Edit your site pages with the custom editor." })
2321
2404
  ] }),
2322
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: globalsBasePath, style: cardStyle, children: [
2405
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: resolvedGlobalsBasePath, style: cardStyle, children: [
2323
2406
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 900 }, children: "Globals" }),
2324
2407
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: "Site settings, header, footer." })
2325
2408
  ] }),
2326
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: `/admin/collections/${mediaCollectionSlug}`, style: cardStyle, children: [
2409
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: mediaPath, style: cardStyle, children: [
2327
2410
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 900 }, children: "Media" }),
2328
2411
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: "Upload and manage images and files." })
2329
2412
  ] })
@@ -2334,7 +2417,7 @@ function AdminStudioDashboard(props) {
2334
2417
  }
2335
2418
 
2336
2419
  // src/admin/components/studio/AdminStudioNav.tsx
2337
- var import_react11 = require("react");
2420
+ var import_react12 = require("react");
2338
2421
  var import_ui4 = require("@payloadcms/ui");
2339
2422
  var import_jsx_runtime15 = require("react/jsx-runtime");
2340
2423
  var isAdmin = (user) => {
@@ -2364,47 +2447,83 @@ var getPropBoolean = (props, key, fallback) => {
2364
2447
  }
2365
2448
  return fallback;
2366
2449
  };
2450
+ var getPropStringArray = (props, key, fallback) => {
2451
+ if (!props || typeof props !== "object") return fallback;
2452
+ const read = (candidate) => Array.isArray(candidate) ? candidate.filter((value) => typeof value === "string" && value.length > 0) : null;
2453
+ const direct = read(props[key]);
2454
+ if (direct) return direct;
2455
+ const clientProps = props.clientProps;
2456
+ if (clientProps && typeof clientProps === "object") {
2457
+ const nested = read(clientProps[key]);
2458
+ if (nested) return nested;
2459
+ }
2460
+ return fallback;
2461
+ };
2367
2462
  function AdminStudioNav(props) {
2368
2463
  const { user } = (0, import_ui4.useAuth)();
2369
2464
  const brandName = getPropString2(props, "brandName", "Orion Studio");
2370
2465
  const logoUrl = getPropString2(props, "logoUrl", "");
2371
2466
  const pagesCollectionSlug = getPropString2(props, "pagesCollectionSlug", "pages");
2372
2467
  const mediaCollectionSlug = getPropString2(props, "mediaCollectionSlug", "media");
2373
- const globalsBasePath = getPropString2(props, "globalsBasePath", "/admin/globals");
2468
+ const globalsBasePath = getPropString2(props, "globalsBasePath", "/studio-globals");
2469
+ const globalsExtraMatchPrefixes = getPropStringArray(props, "globalsExtraMatchPrefixes", []);
2374
2470
  const compact = getPropBoolean(props, "compact", false);
2471
+ const adminBasePath = useAdminBasePath();
2375
2472
  const branding = useSiteBranding(brandName, logoUrl || void 0);
2376
2473
  const resolvedName = branding.siteName || brandName;
2377
- const [pathname, setPathname] = (0, import_react11.useState)("");
2378
- (0, import_react11.useEffect)(() => {
2474
+ const [pathname, setPathname] = (0, import_react12.useState)("");
2475
+ (0, import_react12.useEffect)(() => {
2379
2476
  const update = () => setPathname(window.location.pathname);
2380
2477
  update();
2381
2478
  window.addEventListener("popstate", update);
2382
2479
  return () => window.removeEventListener("popstate", update);
2383
2480
  }, []);
2384
- const pagesPath = `/admin/collections/${pagesCollectionSlug}`;
2385
- const mediaPath = `/admin/collections/${mediaCollectionSlug}`;
2386
- const links = (0, import_react11.useMemo)(
2481
+ const pagesPath = resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`);
2482
+ const mediaPath = resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`);
2483
+ const usersPath = resolveAdminPath(adminBasePath, "/collections/users");
2484
+ const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
2485
+ const resolvedGlobalsExtraMatchPrefixes = globalsExtraMatchPrefixes.map(
2486
+ (prefix) => resolveAdminPath(adminBasePath, prefix)
2487
+ );
2488
+ const dashboardPath = adminBasePath;
2489
+ const links = (0, import_react12.useMemo)(
2387
2490
  () => [
2388
- { href: "/admin", label: "Dashboard", matchPrefixes: ["/admin"] },
2491
+ { href: dashboardPath, label: "Dashboard", matchPrefixes: [dashboardPath] },
2389
2492
  {
2390
2493
  href: pagesPath,
2391
2494
  label: "Pages",
2392
2495
  matchPrefixes: [pagesPath]
2393
2496
  },
2394
- { href: globalsBasePath, label: "Globals", matchPrefixes: [globalsBasePath, "/admin/globals"] },
2497
+ {
2498
+ href: resolvedGlobalsBasePath,
2499
+ label: "Globals",
2500
+ matchPrefixes: [
2501
+ resolvedGlobalsBasePath,
2502
+ resolveAdminPath(adminBasePath, "/globals"),
2503
+ ...resolvedGlobalsExtraMatchPrefixes
2504
+ ]
2505
+ },
2395
2506
  {
2396
2507
  href: mediaPath,
2397
2508
  label: "Media",
2398
2509
  matchPrefixes: [mediaPath]
2399
2510
  },
2400
2511
  {
2401
- href: "/admin/collections/users",
2512
+ href: usersPath,
2402
2513
  label: "Admin Tools",
2403
- matchPrefixes: ["/admin/collections/users"],
2514
+ matchPrefixes: [usersPath],
2404
2515
  adminOnly: true
2405
2516
  }
2406
2517
  ],
2407
- [globalsBasePath, mediaPath, pagesPath]
2518
+ [
2519
+ adminBasePath,
2520
+ dashboardPath,
2521
+ mediaPath,
2522
+ pagesPath,
2523
+ resolvedGlobalsBasePath,
2524
+ resolvedGlobalsExtraMatchPrefixes,
2525
+ usersPath
2526
+ ]
2408
2527
  );
2409
2528
  const linkStyle = (active) => ({
2410
2529
  alignItems: "center",
@@ -2462,7 +2581,7 @@ function AdminStudioNav(props) {
2462
2581
  !compact ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.85rem" }, children: "Studio" }) : null
2463
2582
  ] }),
2464
2583
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("nav", { style: { display: "grid", gap: "0.25rem" }, children: links.filter((link) => !link.adminOnly || isAdmin(user)).map((link) => {
2465
- const active = link.href === "/admin" ? pathname === "/admin" : link.matchPrefixes.some((prefix) => pathname.startsWith(prefix));
2584
+ const active = link.href === dashboardPath ? pathname === dashboardPath : link.matchPrefixes.some((prefix) => pathname.startsWith(prefix));
2466
2585
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: link.href, style: linkStyle(active), title: link.label, children: compact ? link.label.slice(0, 1) : link.label }, link.href);
2467
2586
  }) }),
2468
2587
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { flex: 1 } }),
@@ -2489,7 +2608,7 @@ function AdminStudioNav(props) {
2489
2608
  }
2490
2609
 
2491
2610
  // src/admin/components/studio/AdminStudioPagesListView.tsx
2492
- var import_react12 = require("react");
2611
+ var import_react13 = require("react");
2493
2612
  var import_ui5 = require("@payloadcms/ui");
2494
2613
  var import_jsx_runtime16 = require("react/jsx-runtime");
2495
2614
  var isAdmin2 = (user) => {
@@ -2511,10 +2630,13 @@ var getPropString3 = (props, key, fallback) => {
2511
2630
  function AdminStudioPagesListView(props) {
2512
2631
  const { user } = (0, import_ui5.useAuth)();
2513
2632
  const pagesCollectionSlug = getPropString3(props, "pagesCollectionSlug", "pages");
2514
- const [loading, setLoading] = (0, import_react12.useState)(true);
2515
- const [error, setError] = (0, import_react12.useState)(null);
2516
- const [docs, setDocs] = (0, import_react12.useState)([]);
2517
- const apiURL = (0, import_react12.useMemo)(() => {
2633
+ const adminBasePath = useAdminBasePath();
2634
+ const pagesPath = resolveAdminPath(adminBasePath, "/pages");
2635
+ const rawPagesCollectionPath = resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`);
2636
+ const [loading, setLoading] = (0, import_react13.useState)(true);
2637
+ const [error, setError] = (0, import_react13.useState)(null);
2638
+ const [docs, setDocs] = (0, import_react13.useState)([]);
2639
+ const apiURL = (0, import_react13.useMemo)(() => {
2518
2640
  const params = new URLSearchParams({
2519
2641
  depth: "0",
2520
2642
  limit: "100",
@@ -2523,7 +2645,7 @@ function AdminStudioPagesListView(props) {
2523
2645
  });
2524
2646
  return `/api/${pagesCollectionSlug}?${params.toString()}`;
2525
2647
  }, [pagesCollectionSlug]);
2526
- (0, import_react12.useEffect)(() => {
2648
+ (0, import_react13.useEffect)(() => {
2527
2649
  let cancelled = false;
2528
2650
  const run = async () => {
2529
2651
  setLoading(true);
@@ -2549,7 +2671,7 @@ function AdminStudioPagesListView(props) {
2549
2671
  };
2550
2672
  }, [apiURL]);
2551
2673
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
2552
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ui5.SetStepNav, { nav: [{ label: "Pages", url: "/admin/pages" }] }),
2674
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ui5.SetStepNav, { nav: [{ label: "Pages", url: pagesPath }] }),
2553
2675
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { alignItems: "flex-end", display: "flex", gap: "0.75rem" }, children: [
2554
2676
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { flex: 1 }, children: [
2555
2677
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h1", { style: { margin: 0 }, children: "Pages" }),
@@ -2558,7 +2680,7 @@ function AdminStudioPagesListView(props) {
2558
2680
  isAdmin2(user) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2559
2681
  "a",
2560
2682
  {
2561
- href: `/admin/collections/${pagesCollectionSlug}/create`,
2683
+ href: `${rawPagesCollectionPath}/create`,
2562
2684
  style: {
2563
2685
  background: "var(--theme-elevation-900)",
2564
2686
  borderRadius: 12,
@@ -2595,7 +2717,7 @@ function AdminStudioPagesListView(props) {
2595
2717
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2596
2718
  "a",
2597
2719
  {
2598
- href: `/admin/pages/${id}`,
2720
+ href: resolveAdminPath(adminBasePath, `/pages/${id}`),
2599
2721
  style: {
2600
2722
  background: "var(--theme-elevation-0)",
2601
2723
  border: "1px solid var(--theme-elevation-150)",
@@ -2662,7 +2784,7 @@ function AdminStudioPagesListView(props) {
2662
2784
  }
2663
2785
 
2664
2786
  // src/admin/components/studio/AdminStudioPageEditView.tsx
2665
- var import_react13 = require("react");
2787
+ var import_react14 = require("react");
2666
2788
  var import_ui6 = require("@payloadcms/ui");
2667
2789
  var import_jsx_runtime17 = require("react/jsx-runtime");
2668
2790
  var isAdmin3 = (user) => {
@@ -2695,18 +2817,27 @@ var getParam = (params, key) => {
2695
2817
  return null;
2696
2818
  };
2697
2819
  var getPageIDFromPathname = (pathname) => {
2698
- const match = pathname.match(/\/admin\/pages\/([^/]+)(?:\/|$)/);
2699
- return match?.[1] ? decodeURIComponent(match[1]) : null;
2820
+ const marker = "/pages/";
2821
+ const markerIndex = pathname.indexOf(marker);
2822
+ if (markerIndex < 0) return null;
2823
+ const pagePart = pathname.slice(markerIndex + marker.length).split("/")[0];
2824
+ return pagePart ? decodeURIComponent(pagePart) : null;
2700
2825
  };
2701
2826
  function AdminStudioPageEditView(props) {
2702
2827
  const { user } = (0, import_ui6.useAuth)();
2703
- const iframeRef = (0, import_react13.useRef)(null);
2704
- const [saving, setSaving] = (0, import_react13.useState)(null);
2828
+ const adminBasePath = useAdminBasePath();
2829
+ const iframeRef = (0, import_react14.useRef)(null);
2830
+ const [saving, setSaving] = (0, import_react14.useState)(null);
2831
+ const [dirty, setDirty] = (0, import_react14.useState)(false);
2832
+ const [hasUnpublishedChanges, setHasUnpublishedChanges] = (0, import_react14.useState)(false);
2833
+ const [canUndo, setCanUndo] = (0, import_react14.useState)(false);
2834
+ const [canRedo, setCanRedo] = (0, import_react14.useState)(false);
2705
2835
  const builderBasePath = getPropString4(props, "builderBasePath", "/builder");
2706
- const pageIDFromParams = (0, import_react13.useMemo)(() => getParam(props.params, "id"), [props.params]);
2707
- const [pageID, setPageID] = (0, import_react13.useState)(pageIDFromParams);
2708
- const [didResolvePathFallback, setDidResolvePathFallback] = (0, import_react13.useState)(false);
2709
- (0, import_react13.useEffect)(() => {
2836
+ const pagesPath = resolveAdminPath(adminBasePath, "/pages");
2837
+ const pageIDFromParams = (0, import_react14.useMemo)(() => getParam(props.params, "id"), [props.params]);
2838
+ const [pageID, setPageID] = (0, import_react14.useState)(pageIDFromParams);
2839
+ const [didResolvePathFallback, setDidResolvePathFallback] = (0, import_react14.useState)(false);
2840
+ (0, import_react14.useEffect)(() => {
2710
2841
  if (pageIDFromParams) {
2711
2842
  setPageID(pageIDFromParams);
2712
2843
  setDidResolvePathFallback(true);
@@ -2718,6 +2849,44 @@ function AdminStudioPageEditView(props) {
2718
2849
  setDidResolvePathFallback(true);
2719
2850
  }, [pageIDFromParams]);
2720
2851
  const canPublish = isAdmin3(user) || isEditor(user);
2852
+ const refreshUnpublishedState = async (id) => {
2853
+ try {
2854
+ const response = await fetch(
2855
+ `/api/pages/versions?depth=0&limit=25&sort=-updatedAt&where[parent][equals]=${encodeURIComponent(id)}`,
2856
+ {
2857
+ credentials: "include"
2858
+ }
2859
+ );
2860
+ if (!response.ok) {
2861
+ return;
2862
+ }
2863
+ const payload = await response.json();
2864
+ const docs = Array.isArray(payload.docs) ? payload.docs : [];
2865
+ let latestDraft = 0;
2866
+ let latestPublished = 0;
2867
+ docs.forEach((doc) => {
2868
+ const status = doc.version?._status;
2869
+ const millis = typeof doc.updatedAt === "string" ? Date.parse(doc.updatedAt) : Number.NaN;
2870
+ if (!Number.isFinite(millis)) {
2871
+ return;
2872
+ }
2873
+ if (status === "draft") {
2874
+ latestDraft = Math.max(latestDraft, millis);
2875
+ }
2876
+ if (status === "published") {
2877
+ latestPublished = Math.max(latestPublished, millis);
2878
+ }
2879
+ });
2880
+ setHasUnpublishedChanges(latestDraft > 0 && latestDraft >= latestPublished);
2881
+ } catch {
2882
+ }
2883
+ };
2884
+ (0, import_react14.useEffect)(() => {
2885
+ if (!pageID) {
2886
+ return;
2887
+ }
2888
+ void refreshUnpublishedState(pageID);
2889
+ }, [pageID]);
2721
2890
  const requestSave = (status) => {
2722
2891
  const iframe = iframeRef.current;
2723
2892
  if (!iframe?.contentWindow) {
@@ -2727,17 +2896,43 @@ function AdminStudioPageEditView(props) {
2727
2896
  setSaving(status);
2728
2897
  iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "save", status }, "*");
2729
2898
  };
2730
- (0, import_react13.useEffect)(() => {
2899
+ const requestHistoryAction = (type) => {
2900
+ const iframe = iframeRef.current;
2901
+ if (!iframe?.contentWindow) {
2902
+ import_ui6.toast.error("Editor is not ready yet. Please try again.");
2903
+ return;
2904
+ }
2905
+ iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type }, "*");
2906
+ };
2907
+ (0, import_react14.useEffect)(() => {
2731
2908
  const onMessage = (event) => {
2732
2909
  const data = event.data;
2733
- if (!data || data.source !== "payload-visual-builder-child" || data.type !== "save-result") {
2910
+ if (!data || data.source !== "payload-visual-builder-child" || typeof data.type !== "string") {
2734
2911
  return;
2735
2912
  }
2736
- setSaving(null);
2737
- if (data.ok) {
2738
- import_ui6.toast.success(typeof data.message === "string" ? data.message : "Saved.");
2739
- } else {
2740
- import_ui6.toast.error(typeof data.message === "string" ? data.message : "Save failed.");
2913
+ if (data.type === "dirty-state") {
2914
+ setDirty(Boolean(data.dirty));
2915
+ return;
2916
+ }
2917
+ if (data.type === "history-state") {
2918
+ setCanUndo(Boolean(data.canUndo));
2919
+ setCanRedo(Boolean(data.canRedo));
2920
+ return;
2921
+ }
2922
+ if (data.type === "save-result") {
2923
+ setSaving(null);
2924
+ if (data.ok) {
2925
+ if (data.status === "draft") {
2926
+ setHasUnpublishedChanges(true);
2927
+ } else if (data.status === "published") {
2928
+ setHasUnpublishedChanges(false);
2929
+ } else if (pageID) {
2930
+ void refreshUnpublishedState(pageID);
2931
+ }
2932
+ import_ui6.toast.success(typeof data.message === "string" ? data.message : "Saved.");
2933
+ } else {
2934
+ import_ui6.toast.error(typeof data.message === "string" ? data.message : "Save failed.");
2935
+ }
2741
2936
  }
2742
2937
  };
2743
2938
  window.addEventListener("message", onMessage);
@@ -2749,8 +2944,8 @@ function AdminStudioPageEditView(props) {
2749
2944
  import_ui6.SetStepNav,
2750
2945
  {
2751
2946
  nav: [
2752
- { label: "Pages", url: "/admin/pages" },
2753
- { label: "Page Editor", url: "/admin/pages" }
2947
+ { label: "Pages", url: pagesPath },
2948
+ { label: "Page Editor", url: pagesPath }
2754
2949
  ]
2755
2950
  }
2756
2951
  ),
@@ -2764,8 +2959,8 @@ function AdminStudioPageEditView(props) {
2764
2959
  import_ui6.SetStepNav,
2765
2960
  {
2766
2961
  nav: [
2767
- { label: "Pages", url: "/admin/pages" },
2768
- { label: "Page Editor", url: "/admin/pages" }
2962
+ { label: "Pages", url: pagesPath },
2963
+ { label: "Page Editor", url: pagesPath }
2769
2964
  ]
2770
2965
  }
2771
2966
  ),
@@ -2778,8 +2973,8 @@ function AdminStudioPageEditView(props) {
2778
2973
  import_ui6.SetStepNav,
2779
2974
  {
2780
2975
  nav: [
2781
- { label: "Pages", url: "/admin/pages" },
2782
- { label: `Page ${pageID}`, url: `/admin/pages/${pageID}` }
2976
+ { label: "Pages", url: pagesPath },
2977
+ { label: `Page ${pageID}`, url: resolveAdminPath(adminBasePath, `/pages/${pageID}`) }
2783
2978
  ]
2784
2979
  }
2785
2980
  ),
@@ -2819,6 +3014,56 @@ function AdminStudioPageEditView(props) {
2819
3014
  )
2820
3015
  ] }),
2821
3016
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
3017
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { color: dirty ? "var(--theme-elevation-900)" : "var(--theme-elevation-600)", fontSize: "0.85rem", fontWeight: 700 }, children: dirty ? "Unsaved changes" : "All changes saved" }),
3018
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3019
+ "div",
3020
+ {
3021
+ style: {
3022
+ background: hasUnpublishedChanges ? "#fff3cd" : "#e7f7ee",
3023
+ border: `1px solid ${hasUnpublishedChanges ? "#f0c36d" : "#87c79e"}`,
3024
+ borderRadius: 999,
3025
+ color: hasUnpublishedChanges ? "#6a4a00" : "#0e5a2a",
3026
+ fontSize: "0.75rem",
3027
+ fontWeight: 800,
3028
+ padding: "0.2rem 0.55rem",
3029
+ whiteSpace: "nowrap"
3030
+ },
3031
+ title: hasUnpublishedChanges ? "There are saved draft changes not yet published." : "The live page matches the latest published content.",
3032
+ children: hasUnpublishedChanges ? "Unpublished draft changes" : "Live is up to date"
3033
+ }
3034
+ ),
3035
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3036
+ "button",
3037
+ {
3038
+ disabled: !canUndo,
3039
+ onClick: () => requestHistoryAction("undo"),
3040
+ style: {
3041
+ border: "1px solid var(--theme-elevation-300)",
3042
+ borderRadius: 12,
3043
+ cursor: canUndo ? "pointer" : "not-allowed",
3044
+ fontWeight: 800,
3045
+ padding: "0.5rem 0.65rem"
3046
+ },
3047
+ type: "button",
3048
+ children: "Undo"
3049
+ }
3050
+ ),
3051
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3052
+ "button",
3053
+ {
3054
+ disabled: !canRedo,
3055
+ onClick: () => requestHistoryAction("redo"),
3056
+ style: {
3057
+ border: "1px solid var(--theme-elevation-300)",
3058
+ borderRadius: 12,
3059
+ cursor: canRedo ? "pointer" : "not-allowed",
3060
+ fontWeight: 800,
3061
+ padding: "0.5rem 0.65rem"
3062
+ },
3063
+ type: "button",
3064
+ children: "Redo"
3065
+ }
3066
+ ),
2822
3067
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2823
3068
  "button",
2824
3069
  {
@@ -2864,7 +3109,13 @@ function AdminStudioPageEditView(props) {
2864
3109
  ref: iframeRef,
2865
3110
  src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
2866
3111
  style: { border: "none", height: "100%", width: "100%" },
2867
- title: "Page Builder"
3112
+ title: "Page Builder",
3113
+ onLoad: () => {
3114
+ const iframe = iframeRef.current;
3115
+ if (!iframe?.contentWindow) return;
3116
+ iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "dirty-check-request" }, "*");
3117
+ iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "history-check-request" }, "*");
3118
+ }
2868
3119
  }
2869
3120
  )
2870
3121
  ] })
@@ -2897,42 +3148,48 @@ var getPropString5 = (props, key, fallback) => {
2897
3148
  return fallback;
2898
3149
  };
2899
3150
  function AdminStudioGlobalsView(props) {
2900
- const globalsBasePath = getPropString5(props, "globalsBasePath", "/admin/studio-globals");
3151
+ const globalsBasePath = getPropString5(props, "globalsBasePath", "/studio-globals");
3152
+ const adminBasePath = useAdminBasePath();
3153
+ const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
2901
3154
  const globals = getPropGlobals(props) || [
2902
3155
  { slug: "site-settings", label: "Website Settings" },
2903
3156
  { slug: "header", label: "Header & Navigation" },
2904
- { slug: "footer", label: "Footer" }
3157
+ { slug: "footer", label: "Footer" },
3158
+ { slug: "contact-form", label: "Contact Form", href: "/studio-contact-form" }
2905
3159
  ];
2906
3160
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
2907
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ui7.SetStepNav, { nav: [{ label: "Globals", url: globalsBasePath }] }),
3161
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ui7.SetStepNav, { nav: [{ label: "Globals", url: resolvedGlobalsBasePath }] }),
2908
3162
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h1", { style: { margin: 0 }, children: "Globals" }),
2909
3163
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Site-wide settings." }),
2910
- /* @__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)(
2911
- "a",
2912
- {
2913
- href: `/admin/globals/${global.slug}`,
2914
- style: {
2915
- background: "var(--theme-elevation-0)",
2916
- border: "1px solid var(--theme-elevation-150)",
2917
- borderRadius: 16,
2918
- color: "inherit",
2919
- padding: "0.85rem 1rem",
2920
- textDecoration: "none"
3164
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: globals.map((global) => {
3165
+ const href = resolveAdminPath(
3166
+ adminBasePath,
3167
+ typeof global.href === "string" ? global.href : `/globals/${global.slug}`
3168
+ );
3169
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3170
+ "a",
3171
+ {
3172
+ href,
3173
+ style: {
3174
+ background: "var(--theme-elevation-0)",
3175
+ border: "1px solid var(--theme-elevation-150)",
3176
+ borderRadius: 16,
3177
+ color: "inherit",
3178
+ padding: "0.85rem 1rem",
3179
+ textDecoration: "none"
3180
+ },
3181
+ children: [
3182
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontWeight: 900 }, children: global.label }),
3183
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: typeof global.description === "string" && global.description.length > 0 ? global.description : href })
3184
+ ]
2921
3185
  },
2922
- children: [
2923
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontWeight: 900 }, children: global.label }),
2924
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
2925
- "/admin/globals/",
2926
- global.slug
2927
- ] })
2928
- ]
2929
- },
2930
- global.slug
2931
- )) }),
3186
+ global.slug
3187
+ );
3188
+ }) }),
2932
3189
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2933
3190
  "a",
2934
3191
  {
2935
- href: globalsBasePath,
3192
+ href: resolvedGlobalsBasePath,
2936
3193
  style: { color: "var(--theme-elevation-700)", fontSize: "0.85rem", textDecoration: "none" },
2937
3194
  children: "Reload Globals view"
2938
3195
  }
@@ -2940,9 +3197,24 @@ function AdminStudioGlobalsView(props) {
2940
3197
  ] });
2941
3198
  }
2942
3199
 
2943
- // src/admin/components/studio/AdminStudioMediaView.tsx
3200
+ // src/admin/components/studio/AdminStudioContactFormView.tsx
3201
+ var import_react15 = require("react");
2944
3202
  var import_ui8 = require("@payloadcms/ui");
2945
3203
  var import_jsx_runtime19 = require("react/jsx-runtime");
3204
+ var defaultDoc = {
3205
+ disabledMessage: "This form is temporarily unavailable. Please call us for immediate service.",
3206
+ enabled: true,
3207
+ errorMessage: "Submission failed. Please call us at (512) 555-0149.",
3208
+ notificationEmail: "",
3209
+ serviceOptions: [
3210
+ { label: "Tree Trimming" },
3211
+ { label: "Tree Removal" },
3212
+ { label: "Stump Grinding" },
3213
+ { label: "Storm Cleanup" }
3214
+ ],
3215
+ submitButtonLabel: "Send Request",
3216
+ successMessage: "Thanks, your request has been received. We will follow up shortly."
3217
+ };
2946
3218
  var getPropString6 = (props, key, fallback) => {
2947
3219
  if (!props || typeof props !== "object") return fallback;
2948
3220
  const direct = props[key];
@@ -2954,16 +3226,330 @@ var getPropString6 = (props, key, fallback) => {
2954
3226
  }
2955
3227
  return fallback;
2956
3228
  };
3229
+ var normalizeOption = (value) => {
3230
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
3231
+ const label = value.label;
3232
+ if (typeof label !== "string") return null;
3233
+ const trimmed = label.trim();
3234
+ if (!trimmed) return null;
3235
+ return { label: trimmed };
3236
+ };
3237
+ var normalizeDoc = (value) => {
3238
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
3239
+ return defaultDoc;
3240
+ }
3241
+ const record = value;
3242
+ const options = Array.isArray(record.serviceOptions) ? record.serviceOptions.map(normalizeOption).filter((option) => option !== null) : defaultDoc.serviceOptions;
3243
+ return {
3244
+ disabledMessage: typeof record.disabledMessage === "string" && record.disabledMessage.length > 0 ? record.disabledMessage : defaultDoc.disabledMessage,
3245
+ enabled: record.enabled !== false,
3246
+ errorMessage: typeof record.errorMessage === "string" && record.errorMessage.length > 0 ? record.errorMessage : defaultDoc.errorMessage,
3247
+ notificationEmail: typeof record.notificationEmail === "string" ? record.notificationEmail : defaultDoc.notificationEmail,
3248
+ serviceOptions: options.length > 0 ? options : defaultDoc.serviceOptions,
3249
+ submitButtonLabel: typeof record.submitButtonLabel === "string" && record.submitButtonLabel.length > 0 ? record.submitButtonLabel : defaultDoc.submitButtonLabel,
3250
+ successMessage: typeof record.successMessage === "string" && record.successMessage.length > 0 ? record.successMessage : defaultDoc.successMessage
3251
+ };
3252
+ };
3253
+ var inputStyle = {
3254
+ background: "var(--theme-elevation-0)",
3255
+ border: "1px solid var(--theme-elevation-200)",
3256
+ borderRadius: 10,
3257
+ color: "inherit",
3258
+ fontSize: "0.95rem",
3259
+ minHeight: 42,
3260
+ padding: "0.55rem 0.65rem",
3261
+ width: "100%"
3262
+ };
3263
+ var fieldLabelStyle = {
3264
+ color: "var(--theme-elevation-800)",
3265
+ display: "grid",
3266
+ fontSize: "0.88rem",
3267
+ fontWeight: 700,
3268
+ gap: "0.35rem"
3269
+ };
3270
+ var buttonStyle = {
3271
+ background: "var(--theme-success-700)",
3272
+ border: "1px solid var(--theme-success-700)",
3273
+ borderRadius: 10,
3274
+ color: "#fff",
3275
+ cursor: "pointer",
3276
+ fontSize: "0.9rem",
3277
+ fontWeight: 800,
3278
+ minHeight: 40,
3279
+ padding: "0 0.9rem"
3280
+ };
3281
+ var ghostButtonStyle = {
3282
+ ...buttonStyle,
3283
+ background: "transparent",
3284
+ color: "var(--theme-elevation-900)"
3285
+ };
3286
+ function AdminStudioContactFormView(props) {
3287
+ const globalSlug = getPropString6(props, "globalSlug", "contact-form");
3288
+ const globalsBasePath = getPropString6(props, "globalsBasePath", "/studio-globals");
3289
+ const adminBasePath = useAdminBasePath();
3290
+ const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
3291
+ const rawGlobalPath = resolveAdminPath(adminBasePath, `/globals/${globalSlug}`);
3292
+ const [doc, setDoc] = (0, import_react15.useState)(defaultDoc);
3293
+ const [error, setError] = (0, import_react15.useState)(null);
3294
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(true);
3295
+ const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
3296
+ const [savedMessage, setSavedMessage] = (0, import_react15.useState)(null);
3297
+ (0, import_react15.useEffect)(() => {
3298
+ let mounted = true;
3299
+ const load = async () => {
3300
+ setIsLoading(true);
3301
+ setError(null);
3302
+ setSavedMessage(null);
3303
+ try {
3304
+ const response = await fetch(`/api/globals/${globalSlug}?depth=0&draft=true`, {
3305
+ credentials: "same-origin"
3306
+ });
3307
+ if (!response.ok) {
3308
+ throw new Error(`Failed to load global (${response.status}).`);
3309
+ }
3310
+ const json = await response.json();
3311
+ if (!mounted) return;
3312
+ setDoc(normalizeDoc(json));
3313
+ } catch (loadError) {
3314
+ if (!mounted) return;
3315
+ setError(loadError instanceof Error ? loadError.message : "Failed to load contact form settings.");
3316
+ } finally {
3317
+ if (mounted) {
3318
+ setIsLoading(false);
3319
+ }
3320
+ }
3321
+ };
3322
+ void load();
3323
+ return () => {
3324
+ mounted = false;
3325
+ };
3326
+ }, [globalSlug]);
3327
+ const payload = (0, import_react15.useMemo)(
3328
+ () => ({
3329
+ disabledMessage: doc.disabledMessage,
3330
+ enabled: doc.enabled,
3331
+ errorMessage: doc.errorMessage,
3332
+ notificationEmail: doc.notificationEmail.trim(),
3333
+ serviceOptions: doc.serviceOptions.map((option) => ({ label: option.label.trim() })).filter((option) => option.label.length > 0),
3334
+ submitButtonLabel: doc.submitButtonLabel,
3335
+ successMessage: doc.successMessage
3336
+ }),
3337
+ [doc]
3338
+ );
3339
+ const save = async () => {
3340
+ setIsSaving(true);
3341
+ setError(null);
3342
+ setSavedMessage(null);
3343
+ try {
3344
+ const response = await fetch(`/api/globals/${globalSlug}`, {
3345
+ body: JSON.stringify(payload),
3346
+ credentials: "same-origin",
3347
+ headers: {
3348
+ "Content-Type": "application/json"
3349
+ },
3350
+ method: "PATCH"
3351
+ });
3352
+ if (!response.ok) {
3353
+ throw new Error(`Failed to save settings (${response.status}).`);
3354
+ }
3355
+ const json = await response.json();
3356
+ setDoc(normalizeDoc(json));
3357
+ setSavedMessage("Saved.");
3358
+ } catch (saveError) {
3359
+ setError(saveError instanceof Error ? saveError.message : "Failed to save contact form settings.");
3360
+ } finally {
3361
+ setIsSaving(false);
3362
+ }
3363
+ };
3364
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { paddingBottom: "2rem" }, children: [
3365
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3366
+ import_ui8.SetStepNav,
3367
+ {
3368
+ nav: [
3369
+ { label: "Globals", url: resolvedGlobalsBasePath },
3370
+ { label: "Contact Form" }
3371
+ ]
3372
+ }
3373
+ ),
3374
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { style: { margin: 0 }, children: "Contact Form" }),
3375
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Edit form behavior and submission messaging without leaving Studio." }),
3376
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "Loading form settings\u2026" }) : null,
3377
+ error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-error-600)" }, children: error }) : null,
3378
+ savedMessage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { color: "var(--theme-success-700)" }, children: savedMessage }) : null,
3379
+ !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "grid", gap: "1rem", marginTop: "1rem", maxWidth: 900 }, children: [
3380
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: { ...fieldLabelStyle, alignItems: "center", display: "flex", gap: "0.6rem" }, children: [
3381
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3382
+ "input",
3383
+ {
3384
+ checked: doc.enabled,
3385
+ onChange: (event) => setDoc((prev) => ({ ...prev, enabled: event.target.checked })),
3386
+ type: "checkbox"
3387
+ }
3388
+ ),
3389
+ "Form enabled"
3390
+ ] }),
3391
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: fieldLabelStyle, children: [
3392
+ "Notification Email",
3393
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3394
+ "input",
3395
+ {
3396
+ onChange: (event) => setDoc((prev) => ({ ...prev, notificationEmail: event.target.value })),
3397
+ style: inputStyle,
3398
+ type: "email",
3399
+ value: doc.notificationEmail
3400
+ }
3401
+ )
3402
+ ] }),
3403
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: fieldLabelStyle, children: [
3404
+ "Submit Button Label",
3405
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3406
+ "input",
3407
+ {
3408
+ onChange: (event) => setDoc((prev) => ({ ...prev, submitButtonLabel: event.target.value })),
3409
+ style: inputStyle,
3410
+ type: "text",
3411
+ value: doc.submitButtonLabel
3412
+ }
3413
+ )
3414
+ ] }),
3415
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: fieldLabelStyle, children: [
3416
+ "Success Message",
3417
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3418
+ "input",
3419
+ {
3420
+ onChange: (event) => setDoc((prev) => ({ ...prev, successMessage: event.target.value })),
3421
+ style: inputStyle,
3422
+ type: "text",
3423
+ value: doc.successMessage
3424
+ }
3425
+ )
3426
+ ] }),
3427
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: fieldLabelStyle, children: [
3428
+ "Error Message",
3429
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3430
+ "input",
3431
+ {
3432
+ onChange: (event) => setDoc((prev) => ({ ...prev, errorMessage: event.target.value })),
3433
+ style: inputStyle,
3434
+ type: "text",
3435
+ value: doc.errorMessage
3436
+ }
3437
+ )
3438
+ ] }),
3439
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: fieldLabelStyle, children: [
3440
+ "Disabled Message",
3441
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3442
+ "input",
3443
+ {
3444
+ onChange: (event) => setDoc((prev) => ({ ...prev, disabledMessage: event.target.value })),
3445
+ style: inputStyle,
3446
+ type: "text",
3447
+ value: doc.disabledMessage
3448
+ }
3449
+ )
3450
+ ] }),
3451
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3452
+ "div",
3453
+ {
3454
+ style: {
3455
+ background: "var(--theme-elevation-0)",
3456
+ border: "1px solid var(--theme-elevation-200)",
3457
+ borderRadius: 14,
3458
+ padding: "0.85rem"
3459
+ },
3460
+ children: [
3461
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontWeight: 900, marginBottom: "0.65rem" }, children: "Service Options" }),
3462
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "grid", gap: "0.55rem" }, children: doc.serviceOptions.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
3463
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3464
+ "input",
3465
+ {
3466
+ onChange: (event) => setDoc((prev) => ({
3467
+ ...prev,
3468
+ serviceOptions: prev.serviceOptions.map(
3469
+ (row, rowIndex) => rowIndex === index ? { label: event.target.value } : row
3470
+ )
3471
+ })),
3472
+ style: inputStyle,
3473
+ type: "text",
3474
+ value: option.label
3475
+ }
3476
+ ),
3477
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3478
+ "button",
3479
+ {
3480
+ onClick: () => setDoc((prev) => ({
3481
+ ...prev,
3482
+ serviceOptions: prev.serviceOptions.length > 1 ? prev.serviceOptions.filter((_, rowIndex) => rowIndex !== index) : prev.serviceOptions
3483
+ })),
3484
+ style: ghostButtonStyle,
3485
+ type: "button",
3486
+ children: "Remove"
3487
+ }
3488
+ )
3489
+ ] }, `${index}-${option.label}`)) }),
3490
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3491
+ "button",
3492
+ {
3493
+ onClick: () => setDoc((prev) => ({
3494
+ ...prev,
3495
+ serviceOptions: [...prev.serviceOptions, { label: "" }]
3496
+ })),
3497
+ style: { ...ghostButtonStyle, marginTop: "0.7rem" },
3498
+ type: "button",
3499
+ children: "Add Service"
3500
+ }
3501
+ )
3502
+ ]
3503
+ }
3504
+ ),
3505
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: "0.6rem" }, children: [
3506
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { disabled: isSaving, onClick: () => void save(), style: buttonStyle, type: "button", children: isSaving ? "Saving\u2026" : "Save Form Settings" }),
3507
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3508
+ "a",
3509
+ {
3510
+ href: rawGlobalPath,
3511
+ style: {
3512
+ ...ghostButtonStyle,
3513
+ alignItems: "center",
3514
+ display: "inline-flex",
3515
+ justifyContent: "center",
3516
+ textDecoration: "none"
3517
+ },
3518
+ children: "Open Raw Global"
3519
+ }
3520
+ )
3521
+ ] })
3522
+ ] }) : null
3523
+ ] });
3524
+ }
3525
+
3526
+ // src/admin/components/studio/AdminStudioMediaView.tsx
3527
+ var import_ui9 = require("@payloadcms/ui");
3528
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3529
+ var getPropString7 = (props, key, fallback) => {
3530
+ if (!props || typeof props !== "object") return fallback;
3531
+ const direct = props[key];
3532
+ if (typeof direct === "string" && direct.length > 0) return direct;
3533
+ const clientProps = props.clientProps;
3534
+ if (clientProps && typeof clientProps === "object") {
3535
+ const nested = clientProps[key];
3536
+ if (typeof nested === "string" && nested.length > 0) return nested;
3537
+ }
3538
+ return fallback;
3539
+ };
2957
3540
  function AdminStudioMediaView(props) {
2958
- const mediaCollectionSlug = getPropString6(props, "mediaCollectionSlug", "media");
2959
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2960
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ui8.SetStepNav, { nav: [{ label: "Media", url: "/admin/media" }] }),
2961
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { style: { margin: 0 }, children: "Media" }),
2962
- /* @__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." }),
2963
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3541
+ const mediaCollectionSlug = getPropString7(props, "mediaCollectionSlug", "media");
3542
+ const adminBasePath = useAdminBasePath();
3543
+ const mediaPath = resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`);
3544
+ const mediaViewPath = resolveAdminPath(adminBasePath, "/media");
3545
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3546
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui9.SetStepNav, { nav: [{ label: "Media", url: mediaViewPath }] }),
3547
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Media" }),
3548
+ /* @__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." }),
3549
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "grid", gap: "0.6rem", marginTop: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2964
3550
  "a",
2965
3551
  {
2966
- href: `/admin/collections/${mediaCollectionSlug}`,
3552
+ href: mediaPath,
2967
3553
  style: {
2968
3554
  background: "var(--theme-elevation-0)",
2969
3555
  border: "1px solid var(--theme-elevation-150)",
@@ -2973,11 +3559,8 @@ function AdminStudioMediaView(props) {
2973
3559
  textDecoration: "none"
2974
3560
  },
2975
3561
  children: [
2976
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { fontWeight: 900 }, children: "Open Media Library" }),
2977
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: [
2978
- "/admin/collections/",
2979
- mediaCollectionSlug
2980
- ] })
3562
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontWeight: 900 }, children: "Open Media Library" }),
3563
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: mediaPath })
2981
3564
  ]
2982
3565
  }
2983
3566
  ) })
@@ -2985,14 +3568,14 @@ function AdminStudioMediaView(props) {
2985
3568
  }
2986
3569
 
2987
3570
  // src/admin/components/studio/AdminStudioToolsView.tsx
2988
- var import_ui9 = require("@payloadcms/ui");
2989
- var import_jsx_runtime20 = require("react/jsx-runtime");
3571
+ var import_ui10 = require("@payloadcms/ui");
3572
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2990
3573
  var isAdmin4 = (user) => {
2991
3574
  if (!user || typeof user !== "object") return false;
2992
3575
  const role = user.role;
2993
3576
  return typeof role === "string" && role === "admin";
2994
3577
  };
2995
- var getPropString7 = (props, key, fallback) => {
3578
+ var getPropString8 = (props, key, fallback) => {
2996
3579
  if (!props || typeof props !== "object") return fallback;
2997
3580
  const direct = props[key];
2998
3581
  if (typeof direct === "string" && direct.length > 0) return direct;
@@ -3004,29 +3587,31 @@ var getPropString7 = (props, key, fallback) => {
3004
3587
  return fallback;
3005
3588
  };
3006
3589
  function AdminStudioToolsView(props) {
3007
- const { user } = (0, import_ui9.useAuth)();
3590
+ const { user } = (0, import_ui10.useAuth)();
3591
+ const adminBasePath = useAdminBasePath();
3592
+ const toolsPath = resolveAdminPath(adminBasePath, "/tools");
3008
3593
  if (!isAdmin4(user)) {
3009
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3010
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui9.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
3011
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3012
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "You do not have access to this page." })
3594
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3595
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ui10.SetStepNav, { nav: [{ label: "Admin Tools", url: toolsPath }] }),
3596
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3597
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { color: "var(--theme-elevation-600)" }, children: "You do not have access to this page." })
3013
3598
  ] });
3014
3599
  }
3015
- const pagesCollectionSlug = getPropString7(props, "pagesCollectionSlug", "pages");
3016
- const mediaCollectionSlug = getPropString7(props, "mediaCollectionSlug", "media");
3600
+ const pagesCollectionSlug = getPropString8(props, "pagesCollectionSlug", "pages");
3601
+ const mediaCollectionSlug = getPropString8(props, "mediaCollectionSlug", "media");
3017
3602
  const links = [
3018
- { href: `/admin/collections/${pagesCollectionSlug}`, label: "Raw Pages Collection" },
3019
- { href: `/admin/collections/${mediaCollectionSlug}`, label: "Raw Media Collection" },
3020
- { href: "/admin/globals/site-settings", label: "Raw Site Settings Global" },
3021
- { href: "/admin/globals/header", label: "Raw Header Global" },
3022
- { href: "/admin/globals/footer", label: "Raw Footer Global" },
3023
- { href: "/admin/collections/users", label: "Users / Roles" }
3603
+ { href: resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`), label: "Raw Pages Collection" },
3604
+ { href: resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`), label: "Raw Media Collection" },
3605
+ { href: resolveAdminPath(adminBasePath, "/globals/site-settings"), label: "Raw Site Settings Global" },
3606
+ { href: resolveAdminPath(adminBasePath, "/globals/header"), label: "Raw Header Global" },
3607
+ { href: resolveAdminPath(adminBasePath, "/globals/footer"), label: "Raw Footer Global" },
3608
+ { href: resolveAdminPath(adminBasePath, "/collections/users"), label: "Users / Roles" }
3024
3609
  ];
3025
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3026
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui9.SetStepNav, { nav: [{ label: "Admin Tools", url: "/admin/tools" }] }),
3027
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3028
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Hidden fallback links for administrators." }),
3029
- /* @__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)(
3610
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3611
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ui10.SetStepNav, { nav: [{ label: "Admin Tools", url: toolsPath }] }),
3612
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
3613
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Hidden fallback links for administrators." }),
3614
+ /* @__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)(
3030
3615
  "a",
3031
3616
  {
3032
3617
  href: link.href,
@@ -3039,8 +3624,8 @@ function AdminStudioToolsView(props) {
3039
3624
  textDecoration: "none"
3040
3625
  },
3041
3626
  children: [
3042
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontWeight: 900 }, children: link.label }),
3043
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: link.href })
3627
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontWeight: 900 }, children: link.label }),
3628
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.9rem" }, children: link.href })
3044
3629
  ]
3045
3630
  },
3046
3631
  link.href
@@ -3049,15 +3634,15 @@ function AdminStudioToolsView(props) {
3049
3634
  }
3050
3635
 
3051
3636
  // src/admin/components/studio/OpenInStudioMenuItem.tsx
3052
- var import_ui10 = require("@payloadcms/ui");
3053
- var import_jsx_runtime21 = require("react/jsx-runtime");
3637
+ var import_ui11 = require("@payloadcms/ui");
3638
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3054
3639
  function OpenInStudioMenuItem({ pagesPathBase = "/studio/pages" }) {
3055
- const documentInfo = (0, import_ui10.useDocumentInfo)();
3640
+ const documentInfo = (0, import_ui11.useDocumentInfo)();
3056
3641
  const id = documentInfo?.id;
3057
3642
  if (!id) {
3058
3643
  return null;
3059
3644
  }
3060
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3645
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3061
3646
  "a",
3062
3647
  {
3063
3648
  href: `${pagesPathBase}/${id}`,
@@ -3076,19 +3661,19 @@ function OpenInStudioMenuItem({ pagesPathBase = "/studio/pages" }) {
3076
3661
  }
3077
3662
 
3078
3663
  // src/admin/components/studio/PageEditRedirectToStudio.tsx
3079
- var import_react14 = require("react");
3080
- var import_ui11 = require("@payloadcms/ui");
3081
- var import_jsx_runtime22 = require("react/jsx-runtime");
3664
+ var import_react16 = require("react");
3665
+ var import_ui12 = require("@payloadcms/ui");
3666
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3082
3667
  function PageEditRedirectToStudio({ pagesPathBase = "/studio/pages" }) {
3083
- const documentInfo = (0, import_ui11.useDocumentInfo)();
3668
+ const documentInfo = (0, import_ui12.useDocumentInfo)();
3084
3669
  const id = documentInfo?.id;
3085
- (0, import_react14.useEffect)(() => {
3670
+ (0, import_react16.useEffect)(() => {
3086
3671
  if (!id) {
3087
3672
  return;
3088
3673
  }
3089
3674
  window.location.replace(`${pagesPathBase}/${id}`);
3090
3675
  }, [id, pagesPathBase]);
3091
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3676
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
3092
3677
  "div",
3093
3678
  {
3094
3679
  style: {
@@ -3100,56 +3685,112 @@ function PageEditRedirectToStudio({ pagesPathBase = "/studio/pages" }) {
3100
3685
  minHeight: "50vh"
3101
3686
  },
3102
3687
  children: [
3103
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { style: { margin: 0 }, children: "Opening Editor..." }),
3104
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { color: "var(--theme-elevation-600)", margin: 0 }, children: "Redirecting to the custom page editor." }),
3105
- 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" })
3688
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { style: { margin: 0 }, children: "Opening Editor..." }),
3689
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { color: "var(--theme-elevation-600)", margin: 0 }, children: "Redirecting to the custom page editor." }),
3690
+ 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" })
3106
3691
  ]
3107
3692
  }
3108
3693
  );
3109
3694
  }
3110
3695
 
3111
3696
  // src/admin/components/studio/StudioBackBreadcrumb.tsx
3112
- var import_ui12 = require("@payloadcms/ui");
3113
- var import_navigation = require("next/navigation");
3114
- var import_jsx_runtime23 = require("react/jsx-runtime");
3697
+ var import_react17 = require("react");
3698
+ var import_ui13 = require("@payloadcms/ui");
3699
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3115
3700
  var toTitle = (slug) => slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
3116
- var buildNav = (pathname) => {
3701
+ var buildNav = (pathname, adminBasePath) => {
3117
3702
  if (pathname.includes("/globals/")) {
3118
3703
  const slug = pathname.split("/globals/")[1]?.split("/")[0] || "";
3119
3704
  const currentLabel = slug === "site-settings" ? "Website Settings" : toTitle(slug) || "Global";
3120
3705
  return [
3121
- { label: "Globals", url: "/admin/studio-globals" },
3706
+ { label: "Globals", url: resolveAdminPath(adminBasePath, "/studio-globals") },
3122
3707
  { label: currentLabel }
3123
3708
  ];
3124
3709
  }
3125
- if (pathname.includes("/collections/pages") || pathname.startsWith("/admin/pages/")) {
3710
+ if (pathname.includes("/studio-contact-form")) {
3711
+ return [
3712
+ { label: "Globals", url: resolveAdminPath(adminBasePath, "/studio-globals") },
3713
+ { label: "Contact Form" }
3714
+ ];
3715
+ }
3716
+ if (pathname.includes("/collections/pages") || pathname.includes("/pages/")) {
3126
3717
  return [
3127
- { label: "Pages", url: "/admin/collections/pages" },
3718
+ { label: "Pages", url: resolveAdminPath(adminBasePath, "/collections/pages") },
3128
3719
  { label: "Page" }
3129
3720
  ];
3130
3721
  }
3131
3722
  if (pathname.includes("/collections/media")) {
3132
3723
  return [
3133
- { label: "Media", url: "/admin/collections/media" },
3724
+ { label: "Media", url: resolveAdminPath(adminBasePath, "/collections/media") },
3134
3725
  { label: "Media Item" }
3135
3726
  ];
3136
3727
  }
3137
- if (pathname.startsWith("/admin/tools") || pathname.includes("/collections/users")) {
3728
+ if (pathname.includes("/tools") || pathname.includes("/collections/users")) {
3138
3729
  return [
3139
- { label: "Admin Tools", url: "/admin/collections/users" },
3730
+ { label: "Admin Tools", url: resolveAdminPath(adminBasePath, "/collections/users") },
3140
3731
  { label: "Tool" }
3141
3732
  ];
3142
3733
  }
3143
3734
  return null;
3144
3735
  };
3145
3736
  function StudioBackBreadcrumb() {
3146
- const pathname = (0, import_navigation.usePathname)();
3147
- const nav = buildNav(pathname);
3737
+ const adminBasePath = useAdminBasePath();
3738
+ const [pathname, setPathname] = (0, import_react17.useState)("");
3739
+ (0, import_react17.useEffect)(() => {
3740
+ const update = () => setPathname(window.location.pathname);
3741
+ update();
3742
+ window.addEventListener("popstate", update);
3743
+ return () => window.removeEventListener("popstate", update);
3744
+ }, []);
3745
+ const nav = buildNav(pathname, adminBasePath);
3148
3746
  if (!nav) return null;
3149
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ui12.SetStepNav, { nav });
3747
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ui13.SetStepNav, { nav });
3748
+ }
3749
+
3750
+ // src/admin/components/studio/StudioContactFormRedirect.tsx
3751
+ var import_react18 = require("react");
3752
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3753
+ var getPropString9 = (props, key, fallback) => {
3754
+ if (!props || typeof props !== "object") return fallback;
3755
+ const direct = props[key];
3756
+ if (typeof direct === "string" && direct.length > 0) return direct;
3757
+ const clientProps = props.clientProps;
3758
+ if (clientProps && typeof clientProps === "object") {
3759
+ const nested = clientProps[key];
3760
+ if (typeof nested === "string" && nested.length > 0) return nested;
3761
+ }
3762
+ return fallback;
3763
+ };
3764
+ function StudioContactFormRedirect(props) {
3765
+ const adminBasePath = useAdminBasePath();
3766
+ const studioContactFormPath = getPropString9(props, "studioContactFormPath", "/studio-contact-form");
3767
+ const targetPath = resolveAdminPath(adminBasePath, studioContactFormPath);
3768
+ (0, import_react18.useEffect)(() => {
3769
+ if (window.location.pathname === targetPath) return;
3770
+ window.location.replace(targetPath);
3771
+ }, [targetPath]);
3772
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3773
+ "div",
3774
+ {
3775
+ style: {
3776
+ alignItems: "center",
3777
+ color: "var(--theme-elevation-800)",
3778
+ display: "flex",
3779
+ flexDirection: "column",
3780
+ gap: "0.75rem",
3781
+ justifyContent: "center",
3782
+ minHeight: "40vh"
3783
+ },
3784
+ children: [
3785
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { style: { margin: 0 }, children: "Opening Contact Form Editor..." }),
3786
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: targetPath, children: "Continue" })
3787
+ ]
3788
+ }
3789
+ );
3150
3790
  }
3151
3791
  // Annotate the CommonJS export names for ESM import in node:
3152
3792
  0 && (module.exports = {
3793
+ AdminStudioContactFormView,
3153
3794
  AdminStudioDashboard,
3154
3795
  AdminStudioGlobalsView,
3155
3796
  AdminStudioMediaView,
@@ -3169,6 +3810,7 @@ function StudioBackBreadcrumb() {
3169
3810
  SectionTabs,
3170
3811
  StatusBadge,
3171
3812
  StudioBackBreadcrumb,
3813
+ StudioContactFormRedirect,
3172
3814
  ThemeProvider,
3173
3815
  ThemeSwitcher,
3174
3816
  WelcomeHeader,