@orion-studios/payload-studio 0.5.0-beta.49 → 0.5.0-beta.50

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.
@@ -508,6 +508,7 @@ function PageEditorFrame({ src }) {
508
508
  const [showUnsavedDialog, setShowUnsavedDialog] = (0, import_react4.useState)(false);
509
509
  const [canUndo, setCanUndo] = (0, import_react4.useState)(false);
510
510
  const [canRedo, setCanRedo] = (0, import_react4.useState)(false);
511
+ const [sessionExpired, setSessionExpired] = (0, import_react4.useState)(false);
511
512
  const clearDirtyCheckTimer = () => {
512
513
  if (dirtyCheckTimerRef.current) {
513
514
  window.clearTimeout(dirtyCheckTimerRef.current);
@@ -578,6 +579,10 @@ function PageEditorFrame({ src }) {
578
579
  setCanRedo(Boolean(data.canRedo));
579
580
  return;
580
581
  }
582
+ if (data.type === "session-expired") {
583
+ setSessionExpired(true);
584
+ return;
585
+ }
581
586
  if (data.type !== "save-result") {
582
587
  return;
583
588
  }
@@ -741,6 +746,21 @@ function PageEditorFrame({ src }) {
741
746
  ),
742
747
  message ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#0f7d52", fontSize: "0.9rem", fontWeight: 700 }, children: message }) : null,
743
748
  error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "orion-admin-error", children: error }) : null,
749
+ sessionExpired ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
750
+ "div",
751
+ {
752
+ style: {
753
+ background: "#fef2f2",
754
+ borderLeft: "4px solid #8d1d1d",
755
+ borderRadius: 8,
756
+ color: "#8d1d1d",
757
+ fontSize: "0.9rem",
758
+ fontWeight: 600,
759
+ padding: "0.6rem 0.8rem"
760
+ },
761
+ children: "Session expired. Log in again in a new tab, then save your changes."
762
+ }
763
+ ) : null,
744
764
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
745
765
  "iframe",
746
766
  {
@@ -480,6 +480,7 @@ function PageEditorFrame({ src }) {
480
480
  const [showUnsavedDialog, setShowUnsavedDialog] = useState4(false);
481
481
  const [canUndo, setCanUndo] = useState4(false);
482
482
  const [canRedo, setCanRedo] = useState4(false);
483
+ const [sessionExpired, setSessionExpired] = useState4(false);
483
484
  const clearDirtyCheckTimer = () => {
484
485
  if (dirtyCheckTimerRef.current) {
485
486
  window.clearTimeout(dirtyCheckTimerRef.current);
@@ -550,6 +551,10 @@ function PageEditorFrame({ src }) {
550
551
  setCanRedo(Boolean(data.canRedo));
551
552
  return;
552
553
  }
554
+ if (data.type === "session-expired") {
555
+ setSessionExpired(true);
556
+ return;
557
+ }
553
558
  if (data.type !== "save-result") {
554
559
  return;
555
560
  }
@@ -713,6 +718,21 @@ function PageEditorFrame({ src }) {
713
718
  ),
714
719
  message ? /* @__PURE__ */ jsx4("div", { style: { color: "#0f7d52", fontSize: "0.9rem", fontWeight: 700 }, children: message }) : null,
715
720
  error ? /* @__PURE__ */ jsx4("div", { className: "orion-admin-error", children: error }) : null,
721
+ sessionExpired ? /* @__PURE__ */ jsx4(
722
+ "div",
723
+ {
724
+ style: {
725
+ background: "#fef2f2",
726
+ borderLeft: "4px solid #8d1d1d",
727
+ borderRadius: 8,
728
+ color: "#8d1d1d",
729
+ fontSize: "0.9rem",
730
+ fontWeight: 600,
731
+ padding: "0.6rem 0.8rem"
732
+ },
733
+ children: "Session expired. Log in again in a new tab, then save your changes."
734
+ }
735
+ ) : null,
716
736
  /* @__PURE__ */ jsx4(
717
737
  "iframe",
718
738
  {
@@ -1391,6 +1391,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1391
1391
  const [expandedItemIndex, setExpandedItemIndex] = (0, import_react.useState)(null);
1392
1392
  const [testimonialsOffsets, setTestimonialsOffsets] = (0, import_react.useState)({});
1393
1393
  const [presetQuery, setPresetQuery] = (0, import_react.useState)("");
1394
+ const [sessionExpired, setSessionExpired] = (0, import_react.useState)(false);
1394
1395
  const [pastSnapshots, setPastSnapshots] = (0, import_react.useState)([]);
1395
1396
  const [futureSnapshots, setFutureSnapshots] = (0, import_react.useState)([]);
1396
1397
  const isSidebarPanelKey = (value) => value === "pageDefaults" || value === "addSections" || value === "selected";
@@ -1460,6 +1461,34 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1460
1461
  };
1461
1462
  void loadMediaLibrary();
1462
1463
  }, []);
1464
+ (0, import_react.useEffect)(() => {
1465
+ let active = true;
1466
+ const checkSession = async () => {
1467
+ try {
1468
+ const response = await fetch("/api/users/me", {
1469
+ credentials: "include"
1470
+ });
1471
+ if (!active) return;
1472
+ if (response.status === 401 || response.status === 403) {
1473
+ setSessionExpired(true);
1474
+ window.parent?.postMessage(
1475
+ {
1476
+ source: "payload-visual-builder-child",
1477
+ type: "session-expired"
1478
+ },
1479
+ "*"
1480
+ );
1481
+ }
1482
+ } catch {
1483
+ }
1484
+ };
1485
+ void checkSession();
1486
+ const intervalId = window.setInterval(checkSession, 5 * 60 * 1e3);
1487
+ return () => {
1488
+ active = false;
1489
+ window.clearInterval(intervalId);
1490
+ };
1491
+ }, []);
1463
1492
  (0, import_react.useEffect)(() => {
1464
1493
  if (selectedType !== "hero") {
1465
1494
  setSelectedHeroMediaID("");
@@ -1903,12 +1932,24 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1903
1932
  ),
1904
1933
  title
1905
1934
  }),
1935
+ credentials: "include",
1906
1936
  headers: {
1907
1937
  "Content-Type": "application/json"
1908
1938
  },
1909
1939
  method: "PATCH"
1910
1940
  });
1911
1941
  if (!response.ok) {
1942
+ if (response.status === 401 || response.status === 403) {
1943
+ setSessionExpired(true);
1944
+ window.parent?.postMessage(
1945
+ {
1946
+ source: "payload-visual-builder-child",
1947
+ type: "session-expired"
1948
+ },
1949
+ "*"
1950
+ );
1951
+ throw new Error("Your session has expired. Log in again in a new tab, then retry saving.");
1952
+ }
1912
1953
  throw new Error(await parsePayloadErrorMessage(response, "Could not save this page."));
1913
1954
  }
1914
1955
  const savedSnapshot = {
@@ -2151,6 +2192,77 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2151
2192
  padding: "0 0 1.2rem"
2152
2193
  },
2153
2194
  children: [
2195
+ sessionExpired ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2196
+ "div",
2197
+ {
2198
+ style: {
2199
+ alignItems: "center",
2200
+ background: "rgba(0, 0, 0, 0.6)",
2201
+ display: "grid",
2202
+ inset: 0,
2203
+ justifyItems: "center",
2204
+ padding: "1rem",
2205
+ position: "fixed",
2206
+ zIndex: 9999
2207
+ },
2208
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2209
+ "div",
2210
+ {
2211
+ style: {
2212
+ background: "#ffffff",
2213
+ borderRadius: 14,
2214
+ boxShadow: "0 20px 42px rgba(0, 0, 0, 0.3)",
2215
+ display: "grid",
2216
+ gap: "0.8rem",
2217
+ maxWidth: 420,
2218
+ padding: "1.2rem",
2219
+ textAlign: "center",
2220
+ width: "100%"
2221
+ },
2222
+ children: [
2223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: "1.1rem", fontWeight: 700 }, children: "Session Expired" }),
2224
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#333", fontSize: "0.9rem", lineHeight: 1.5 }, children: "Your login session has expired. Your edits are still here, but you must log in again before saving. Open the login page in a new tab, sign in, then return here and try saving again." }),
2225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2226
+ "a",
2227
+ {
2228
+ href: "/admin",
2229
+ rel: "noopener noreferrer",
2230
+ style: {
2231
+ background: "#0f7d52",
2232
+ borderRadius: 8,
2233
+ color: "#ffffff",
2234
+ display: "inline-block",
2235
+ fontSize: "0.9rem",
2236
+ fontWeight: 600,
2237
+ padding: "0.5rem 1rem",
2238
+ textDecoration: "none"
2239
+ },
2240
+ target: "_blank",
2241
+ children: "Open Login Page"
2242
+ }
2243
+ ),
2244
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2245
+ "button",
2246
+ {
2247
+ onClick: () => setSessionExpired(false),
2248
+ style: {
2249
+ background: "transparent",
2250
+ border: "none",
2251
+ color: "#666",
2252
+ cursor: "pointer",
2253
+ fontSize: "0.85rem",
2254
+ padding: "0.3rem",
2255
+ textDecoration: "underline"
2256
+ },
2257
+ type: "button",
2258
+ children: "Dismiss"
2259
+ }
2260
+ )
2261
+ ]
2262
+ }
2263
+ )
2264
+ }
2265
+ ) : null,
2154
2266
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { minWidth: 0 }, children: [
2155
2267
  layout.map((block, index) => {
2156
2268
  const type = normalizeText(block.blockType, "unknown");
@@ -1363,6 +1363,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1363
1363
  const [expandedItemIndex, setExpandedItemIndex] = useState(null);
1364
1364
  const [testimonialsOffsets, setTestimonialsOffsets] = useState({});
1365
1365
  const [presetQuery, setPresetQuery] = useState("");
1366
+ const [sessionExpired, setSessionExpired] = useState(false);
1366
1367
  const [pastSnapshots, setPastSnapshots] = useState([]);
1367
1368
  const [futureSnapshots, setFutureSnapshots] = useState([]);
1368
1369
  const isSidebarPanelKey = (value) => value === "pageDefaults" || value === "addSections" || value === "selected";
@@ -1432,6 +1433,34 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1432
1433
  };
1433
1434
  void loadMediaLibrary();
1434
1435
  }, []);
1436
+ useEffect(() => {
1437
+ let active = true;
1438
+ const checkSession = async () => {
1439
+ try {
1440
+ const response = await fetch("/api/users/me", {
1441
+ credentials: "include"
1442
+ });
1443
+ if (!active) return;
1444
+ if (response.status === 401 || response.status === 403) {
1445
+ setSessionExpired(true);
1446
+ window.parent?.postMessage(
1447
+ {
1448
+ source: "payload-visual-builder-child",
1449
+ type: "session-expired"
1450
+ },
1451
+ "*"
1452
+ );
1453
+ }
1454
+ } catch {
1455
+ }
1456
+ };
1457
+ void checkSession();
1458
+ const intervalId = window.setInterval(checkSession, 5 * 60 * 1e3);
1459
+ return () => {
1460
+ active = false;
1461
+ window.clearInterval(intervalId);
1462
+ };
1463
+ }, []);
1435
1464
  useEffect(() => {
1436
1465
  if (selectedType !== "hero") {
1437
1466
  setSelectedHeroMediaID("");
@@ -1875,12 +1904,24 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1875
1904
  ),
1876
1905
  title
1877
1906
  }),
1907
+ credentials: "include",
1878
1908
  headers: {
1879
1909
  "Content-Type": "application/json"
1880
1910
  },
1881
1911
  method: "PATCH"
1882
1912
  });
1883
1913
  if (!response.ok) {
1914
+ if (response.status === 401 || response.status === 403) {
1915
+ setSessionExpired(true);
1916
+ window.parent?.postMessage(
1917
+ {
1918
+ source: "payload-visual-builder-child",
1919
+ type: "session-expired"
1920
+ },
1921
+ "*"
1922
+ );
1923
+ throw new Error("Your session has expired. Log in again in a new tab, then retry saving.");
1924
+ }
1884
1925
  throw new Error(await parsePayloadErrorMessage(response, "Could not save this page."));
1885
1926
  }
1886
1927
  const savedSnapshot = {
@@ -2123,6 +2164,77 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2123
2164
  padding: "0 0 1.2rem"
2124
2165
  },
2125
2166
  children: [
2167
+ sessionExpired ? /* @__PURE__ */ jsx(
2168
+ "div",
2169
+ {
2170
+ style: {
2171
+ alignItems: "center",
2172
+ background: "rgba(0, 0, 0, 0.6)",
2173
+ display: "grid",
2174
+ inset: 0,
2175
+ justifyItems: "center",
2176
+ padding: "1rem",
2177
+ position: "fixed",
2178
+ zIndex: 9999
2179
+ },
2180
+ children: /* @__PURE__ */ jsxs(
2181
+ "div",
2182
+ {
2183
+ style: {
2184
+ background: "#ffffff",
2185
+ borderRadius: 14,
2186
+ boxShadow: "0 20px 42px rgba(0, 0, 0, 0.3)",
2187
+ display: "grid",
2188
+ gap: "0.8rem",
2189
+ maxWidth: 420,
2190
+ padding: "1.2rem",
2191
+ textAlign: "center",
2192
+ width: "100%"
2193
+ },
2194
+ children: [
2195
+ /* @__PURE__ */ jsx("div", { style: { color: "#8d1d1d", fontSize: "1.1rem", fontWeight: 700 }, children: "Session Expired" }),
2196
+ /* @__PURE__ */ jsx("div", { style: { color: "#333", fontSize: "0.9rem", lineHeight: 1.5 }, children: "Your login session has expired. Your edits are still here, but you must log in again before saving. Open the login page in a new tab, sign in, then return here and try saving again." }),
2197
+ /* @__PURE__ */ jsx(
2198
+ "a",
2199
+ {
2200
+ href: "/admin",
2201
+ rel: "noopener noreferrer",
2202
+ style: {
2203
+ background: "#0f7d52",
2204
+ borderRadius: 8,
2205
+ color: "#ffffff",
2206
+ display: "inline-block",
2207
+ fontSize: "0.9rem",
2208
+ fontWeight: 600,
2209
+ padding: "0.5rem 1rem",
2210
+ textDecoration: "none"
2211
+ },
2212
+ target: "_blank",
2213
+ children: "Open Login Page"
2214
+ }
2215
+ ),
2216
+ /* @__PURE__ */ jsx(
2217
+ "button",
2218
+ {
2219
+ onClick: () => setSessionExpired(false),
2220
+ style: {
2221
+ background: "transparent",
2222
+ border: "none",
2223
+ color: "#666",
2224
+ cursor: "pointer",
2225
+ fontSize: "0.85rem",
2226
+ padding: "0.3rem",
2227
+ textDecoration: "underline"
2228
+ },
2229
+ type: "button",
2230
+ children: "Dismiss"
2231
+ }
2232
+ )
2233
+ ]
2234
+ }
2235
+ )
2236
+ }
2237
+ ) : null,
2126
2238
  /* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
2127
2239
  layout.map((block, index) => {
2128
2240
  const type = normalizeText(block.blockType, "unknown");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-studios/payload-studio",
3
- "version": "0.5.0-beta.49",
3
+ "version": "0.5.0-beta.50",
4
4
  "description": "Unified Payload CMS toolkit for Orion Studios",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",