@sevenfold/setto-client 0.3.4 → 0.5.0
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.
- package/README.md +61 -36
- package/dist/SettoRepeater.d.ts +2 -1
- package/dist/admin/App.d.ts +4 -5
- package/dist/edit-mode/constants.d.ts +4 -2
- package/dist/edit-mode/document-layout.d.ts +4 -2
- package/dist/edit-mode/mount.d.ts +2 -2
- package/dist/edit-mode/setto-mark.d.ts +16 -0
- package/dist/guest-edit.d.ts +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/lib/theme-store.d.ts +2 -0
- package/dist/lib/urls.d.ts +13 -3
- package/dist/lib/use-site-access.d.ts +16 -0
- package/dist/provider.d.ts +10 -5
- package/dist/setto-client.js +426 -249
- package/dist/setto-client.js.map +1 -1
- package/dist/theme-target-utils.d.ts +2 -2
- package/package.json +3 -2
package/dist/setto-client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useSyncExternalStore,
|
|
2
|
+
import { useState, useEffect, useSyncExternalStore, useRef, useLayoutEffect, createContext, useContext, useCallback, useMemo, useId, forwardRef } from "react";
|
|
3
3
|
import { useTranslation } from "react-i18next";
|
|
4
4
|
import { createPortal } from "react-dom";
|
|
5
5
|
function __rest(s, e) {
|
|
@@ -21129,6 +21129,15 @@ class ThemeStore {
|
|
|
21129
21129
|
this.drafts.clear();
|
|
21130
21130
|
this.bump();
|
|
21131
21131
|
}
|
|
21132
|
+
/** Resets every draft back to its original value. */
|
|
21133
|
+
revertAll() {
|
|
21134
|
+
for (const draft of this.drafts.values()) {
|
|
21135
|
+
if (!this.data[draft.sectionId]) this.data[draft.sectionId] = {};
|
|
21136
|
+
this.data[draft.sectionId][draft.field] = draft.original;
|
|
21137
|
+
}
|
|
21138
|
+
this.drafts.clear();
|
|
21139
|
+
this.bump();
|
|
21140
|
+
}
|
|
21132
21141
|
commit() {
|
|
21133
21142
|
this.baseline = structuredClone(this.data);
|
|
21134
21143
|
this.drafts.clear();
|
|
@@ -21146,41 +21155,77 @@ class ThemeStore {
|
|
|
21146
21155
|
for (const fn of this.listeners) fn(this.cachedSnapshot);
|
|
21147
21156
|
}
|
|
21148
21157
|
}
|
|
21149
|
-
const
|
|
21150
|
-
|
|
21158
|
+
const EMPTY = {
|
|
21159
|
+
sites: null,
|
|
21160
|
+
currentSite: null,
|
|
21161
|
+
loading: true,
|
|
21162
|
+
error: null
|
|
21163
|
+
};
|
|
21164
|
+
function useSiteAccess(supabase, session, siteId) {
|
|
21165
|
+
const [state, setState] = useState(EMPTY);
|
|
21166
|
+
useEffect(() => {
|
|
21167
|
+
if (!session) {
|
|
21168
|
+
setState({ sites: null, currentSite: null, loading: false, error: null });
|
|
21169
|
+
return;
|
|
21170
|
+
}
|
|
21171
|
+
let cancelled = false;
|
|
21172
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
21173
|
+
supabase.from("sites").select("*").then(({ data, error }) => {
|
|
21174
|
+
if (cancelled) return;
|
|
21175
|
+
if (error) {
|
|
21176
|
+
setState({ sites: [], currentSite: null, loading: false, error: error.message });
|
|
21177
|
+
return;
|
|
21178
|
+
}
|
|
21179
|
+
const rows = data ?? [];
|
|
21180
|
+
const current = rows.find((s) => s.id === siteId) ?? null;
|
|
21181
|
+
setState({ sites: rows, currentSite: current, loading: false, error: null });
|
|
21182
|
+
});
|
|
21183
|
+
return () => {
|
|
21184
|
+
cancelled = true;
|
|
21185
|
+
};
|
|
21186
|
+
}, [supabase, session, siteId]);
|
|
21187
|
+
return state;
|
|
21188
|
+
}
|
|
21189
|
+
const SETTO_BASE = "/setto";
|
|
21190
|
+
function siteHomeUrl(pathname = "/") {
|
|
21191
|
+
const u = new URL(window.location.href);
|
|
21192
|
+
u.pathname = pathname;
|
|
21193
|
+
u.search = "";
|
|
21194
|
+
return u.toString();
|
|
21195
|
+
}
|
|
21196
|
+
function isAdminRoute() {
|
|
21197
|
+
return window.location.pathname.startsWith(SETTO_BASE);
|
|
21198
|
+
}
|
|
21199
|
+
function isAdminDeploymentView() {
|
|
21200
|
+
return isAdminRoute() && new URLSearchParams(window.location.search).has("deployment");
|
|
21201
|
+
}
|
|
21202
|
+
function adminRedirectUrl() {
|
|
21203
|
+
return `${window.location.origin}${SETTO_BASE}`;
|
|
21204
|
+
}
|
|
21205
|
+
const FAB_SIZE = 52;
|
|
21206
|
+
const FAB_INSET = 16;
|
|
21207
|
+
const STYLE_ID$1 = "setto-edit-layout";
|
|
21151
21208
|
const HTML_CLASS = "setto-edit-mode";
|
|
21152
21209
|
function useSettoDocumentLayout(active) {
|
|
21153
21210
|
useEffect(() => {
|
|
21154
21211
|
const html = document.documentElement;
|
|
21155
21212
|
html.classList.add(HTML_CLASS);
|
|
21156
|
-
html.style.setProperty("--setto-
|
|
21157
|
-
|
|
21213
|
+
html.style.setProperty("--setto-fab-size", `${FAB_SIZE}px`);
|
|
21214
|
+
html.style.setProperty("--setto-fab-inset", `${FAB_INSET}px`);
|
|
21215
|
+
let styleEl = document.getElementById(STYLE_ID$1);
|
|
21158
21216
|
if (!styleEl) {
|
|
21159
21217
|
styleEl = document.createElement("style");
|
|
21160
|
-
styleEl.id = STYLE_ID;
|
|
21218
|
+
styleEl.id = STYLE_ID$1;
|
|
21161
21219
|
styleEl.textContent = `
|
|
21162
21220
|
html.setto-edit-mode {
|
|
21163
21221
|
width: 100%;
|
|
21164
21222
|
overflow-x: clip;
|
|
21165
21223
|
}
|
|
21166
21224
|
|
|
21167
|
-
html.setto-edit-mode body {
|
|
21168
|
-
padding-top: var(--setto-toolbar-height);
|
|
21169
|
-
}
|
|
21170
|
-
|
|
21171
|
-
html.setto-edit-mode #root {
|
|
21172
|
-
width: 100%;
|
|
21173
|
-
min-height: calc(100dvh - var(--setto-toolbar-height));
|
|
21174
|
-
/* Containing block for position:fixed descendants so they sit below the toolbar. */
|
|
21175
|
-
transform: translateZ(0);
|
|
21176
|
-
}
|
|
21177
|
-
|
|
21178
21225
|
html.setto-edit-mode #setto-toolbar-root {
|
|
21179
21226
|
position: fixed;
|
|
21180
|
-
|
|
21181
|
-
|
|
21182
|
-
right: 0;
|
|
21183
|
-
height: var(--setto-toolbar-height);
|
|
21227
|
+
left: var(--setto-fab-inset);
|
|
21228
|
+
bottom: var(--setto-fab-inset);
|
|
21184
21229
|
z-index: 2147483647;
|
|
21185
21230
|
}
|
|
21186
21231
|
|
|
@@ -21207,19 +21252,13 @@ function useSettoDocumentLayout(active) {
|
|
|
21207
21252
|
}
|
|
21208
21253
|
|
|
21209
21254
|
html.setto-edit-mode [data-setto-key]:hover {
|
|
21210
|
-
outline: 1px dashed rgba(
|
|
21255
|
+
outline: 1px dashed rgba(196, 80, 42, 0.55);
|
|
21211
21256
|
outline-offset: 2px;
|
|
21212
21257
|
border-radius: 2px;
|
|
21213
21258
|
}
|
|
21214
21259
|
|
|
21215
21260
|
html.setto-edit-mode [data-setto-section]:hover {
|
|
21216
|
-
box-shadow: inset 0 0 0 1px rgba(
|
|
21217
|
-
}
|
|
21218
|
-
|
|
21219
|
-
@media (max-width: 480px) {
|
|
21220
|
-
html.setto-edit-mode [data-setto-draft-count] {
|
|
21221
|
-
display: none;
|
|
21222
|
-
}
|
|
21261
|
+
box-shadow: inset 0 0 0 1px rgba(196, 80, 42, 0.3);
|
|
21223
21262
|
}
|
|
21224
21263
|
`;
|
|
21225
21264
|
document.head.appendChild(styleEl);
|
|
@@ -21227,7 +21266,8 @@ function useSettoDocumentLayout(active) {
|
|
|
21227
21266
|
notifyLayoutChange();
|
|
21228
21267
|
return () => {
|
|
21229
21268
|
html.classList.remove(HTML_CLASS);
|
|
21230
|
-
html.style.removeProperty("--setto-
|
|
21269
|
+
html.style.removeProperty("--setto-fab-size");
|
|
21270
|
+
html.style.removeProperty("--setto-fab-inset");
|
|
21231
21271
|
styleEl?.remove();
|
|
21232
21272
|
notifyLayoutChange();
|
|
21233
21273
|
};
|
|
@@ -21395,8 +21435,7 @@ function computePosition(targetEl, toolbarW, toolbarH) {
|
|
|
21395
21435
|
const rect = targetEl.getBoundingClientRect();
|
|
21396
21436
|
let left = rect.left + (rect.width - toolbarW) / 2;
|
|
21397
21437
|
left = Math.max(MARGIN$1, Math.min(left, window.innerWidth - toolbarW - MARGIN$1));
|
|
21398
|
-
const
|
|
21399
|
-
const top = Math.max(minTop, rect.top - toolbarH - GAP);
|
|
21438
|
+
const top = Math.max(MARGIN$1, rect.top - toolbarH - GAP);
|
|
21400
21439
|
return { top, left };
|
|
21401
21440
|
}
|
|
21402
21441
|
function BrandColorPicker({
|
|
@@ -21432,7 +21471,7 @@ function BrandColorPicker({
|
|
|
21432
21471
|
left = window.innerWidth - popoverW - 8;
|
|
21433
21472
|
}
|
|
21434
21473
|
if (left < 8) left = 8;
|
|
21435
|
-
if (top <
|
|
21474
|
+
if (top < 8) top = rect.bottom + 6;
|
|
21436
21475
|
if (top + popoverH > window.innerHeight - 8) {
|
|
21437
21476
|
top = rect.top - popoverH - 6;
|
|
21438
21477
|
}
|
|
@@ -22150,6 +22189,43 @@ function useEditBaseline() {
|
|
|
22150
22189
|
};
|
|
22151
22190
|
}, [session, store, config.siteId]);
|
|
22152
22191
|
}
|
|
22192
|
+
function SettoMark({
|
|
22193
|
+
size = 24,
|
|
22194
|
+
letterColor = "#F2EBDF",
|
|
22195
|
+
dotColor = "#C4502A",
|
|
22196
|
+
style
|
|
22197
|
+
}) {
|
|
22198
|
+
return /* @__PURE__ */ jsxs(
|
|
22199
|
+
"svg",
|
|
22200
|
+
{
|
|
22201
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
22202
|
+
viewBox: "0 0 64 64",
|
|
22203
|
+
width: size,
|
|
22204
|
+
height: size,
|
|
22205
|
+
"aria-hidden": true,
|
|
22206
|
+
style: { display: "block", ...style },
|
|
22207
|
+
children: [
|
|
22208
|
+
/* @__PURE__ */ jsx(
|
|
22209
|
+
"text",
|
|
22210
|
+
{
|
|
22211
|
+
x: "32",
|
|
22212
|
+
y: "46",
|
|
22213
|
+
textAnchor: "middle",
|
|
22214
|
+
fontFamily: "Georgia, serif",
|
|
22215
|
+
fontStyle: "italic",
|
|
22216
|
+
fontSize: "42",
|
|
22217
|
+
fill: letterColor,
|
|
22218
|
+
children: "S"
|
|
22219
|
+
}
|
|
22220
|
+
),
|
|
22221
|
+
/* @__PURE__ */ jsx("circle", { cx: "49", cy: "17", r: "5", fill: dotColor })
|
|
22222
|
+
]
|
|
22223
|
+
}
|
|
22224
|
+
);
|
|
22225
|
+
}
|
|
22226
|
+
const BLEKK = "#211711";
|
|
22227
|
+
const CREMA = "#F2EBDF";
|
|
22228
|
+
const TERRACOTTA = "#C4502A";
|
|
22153
22229
|
function EditToolbar() {
|
|
22154
22230
|
const { store, themeStore, assetStore, api, config, supabase } = useSetto();
|
|
22155
22231
|
const { i18n } = useTranslation();
|
|
@@ -22178,6 +22254,7 @@ function EditToolbar() {
|
|
|
22178
22254
|
const [error, setError] = useState(null);
|
|
22179
22255
|
const [publishedNotice, setPublishedNotice] = useState(false);
|
|
22180
22256
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
22257
|
+
const [expanded, setExpanded] = useState(false);
|
|
22181
22258
|
const menuRef = useRef(null);
|
|
22182
22259
|
const publishedNoticeTimer = useRef(null);
|
|
22183
22260
|
const { row: deploymentRow, status: deploymentStatus } = useDeploymentStatus(
|
|
@@ -22208,6 +22285,18 @@ function EditToolbar() {
|
|
|
22208
22285
|
const hasDrafts = draftCount > 0;
|
|
22209
22286
|
const showToolbarProgress = activeDeployment !== null && !publishDialogOpen && deploymentRow !== null && isDeploymentInProgress(deploymentRow.status) && !isDeploymentStale(deploymentRow);
|
|
22210
22287
|
const showPublishedNotice = publishedNotice && !publishDialogOpen;
|
|
22288
|
+
useEffect(() => {
|
|
22289
|
+
if (error || showToolbarProgress || showPublishedNotice) {
|
|
22290
|
+
setExpanded(true);
|
|
22291
|
+
}
|
|
22292
|
+
}, [error, showToolbarProgress, showPublishedNotice]);
|
|
22293
|
+
const toggleExpanded = () => {
|
|
22294
|
+
setExpanded((prev) => {
|
|
22295
|
+
const next = !prev;
|
|
22296
|
+
if (!next) setMenuOpen(false);
|
|
22297
|
+
return next;
|
|
22298
|
+
});
|
|
22299
|
+
};
|
|
22211
22300
|
useEffect(() => {
|
|
22212
22301
|
return () => {
|
|
22213
22302
|
if (publishedNoticeTimer.current) clearTimeout(publishedNoticeTimer.current);
|
|
@@ -22358,76 +22447,109 @@ function EditToolbar() {
|
|
|
22358
22447
|
setPublishedNotice(false);
|
|
22359
22448
|
if (publishedNoticeTimer.current) clearTimeout(publishedNoticeTimer.current);
|
|
22360
22449
|
};
|
|
22450
|
+
const cancelDrafts = () => {
|
|
22451
|
+
setMenuOpen(false);
|
|
22452
|
+
store?.revertAll();
|
|
22453
|
+
themeStore?.revertAll();
|
|
22454
|
+
assetStore?.revertAll();
|
|
22455
|
+
setError(null);
|
|
22456
|
+
setExpanded(false);
|
|
22457
|
+
};
|
|
22361
22458
|
const signOut = () => {
|
|
22362
22459
|
setMenuOpen(false);
|
|
22363
22460
|
void supabase.auth.signOut();
|
|
22364
22461
|
};
|
|
22365
22462
|
const goToHistory = () => {
|
|
22366
22463
|
setMenuOpen(false);
|
|
22367
|
-
window.location.href =
|
|
22464
|
+
window.location.href = SETTO_BASE;
|
|
22368
22465
|
};
|
|
22369
22466
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22370
|
-
/* @__PURE__ */ jsxs(
|
|
22371
|
-
|
|
22372
|
-
|
|
22373
|
-
|
|
22374
|
-
|
|
22375
|
-
|
|
22376
|
-
|
|
22377
|
-
|
|
22378
|
-
|
|
22379
|
-
|
|
22380
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: publish, style: publishBtnStyle, children: "Publiser" })
|
|
22381
|
-
] }) : null,
|
|
22382
|
-
showPublishedNotice ? /* @__PURE__ */ jsxs(
|
|
22383
|
-
"button",
|
|
22384
|
-
{
|
|
22385
|
-
type: "button",
|
|
22386
|
-
onClick: dismissPublishedNotice,
|
|
22387
|
-
style: publishedNoticeStyle,
|
|
22388
|
-
title: "Lukk",
|
|
22389
|
-
children: [
|
|
22390
|
-
/* @__PURE__ */ jsx(PublishedCheckIcon, {}),
|
|
22391
|
-
"Publisert"
|
|
22392
|
-
]
|
|
22393
|
-
}
|
|
22394
|
-
) : null,
|
|
22395
|
-
showToolbarProgress && deploymentRow ? /* @__PURE__ */ jsx(
|
|
22396
|
-
PublishProgressBar,
|
|
22397
|
-
{
|
|
22398
|
-
status: deploymentRow.status,
|
|
22399
|
-
compact: true,
|
|
22400
|
-
href: `/admin?deployment=${encodeURIComponent(activeDeployment)}`
|
|
22401
|
-
}
|
|
22402
|
-
) : null,
|
|
22403
|
-
/* @__PURE__ */ jsxs("div", { ref: menuRef, style: { position: "relative" }, children: [
|
|
22467
|
+
/* @__PURE__ */ jsxs(
|
|
22468
|
+
"div",
|
|
22469
|
+
{
|
|
22470
|
+
role: "toolbar",
|
|
22471
|
+
"aria-label": "Setto editor",
|
|
22472
|
+
style: {
|
|
22473
|
+
...containerStyleFor(hasDrafts),
|
|
22474
|
+
...expanded ? expandedContainerStyle : {}
|
|
22475
|
+
},
|
|
22476
|
+
children: [
|
|
22404
22477
|
/* @__PURE__ */ jsx(
|
|
22405
22478
|
"button",
|
|
22406
22479
|
{
|
|
22407
22480
|
type: "button",
|
|
22408
|
-
|
|
22409
|
-
"aria-
|
|
22410
|
-
"
|
|
22411
|
-
style:
|
|
22412
|
-
|
|
22413
|
-
|
|
22414
|
-
},
|
|
22415
|
-
onMouseEnter: (e) => {
|
|
22416
|
-
e.currentTarget.style.background = "#f0f0f0";
|
|
22417
|
-
},
|
|
22418
|
-
onMouseLeave: (e) => {
|
|
22419
|
-
e.currentTarget.style.background = menuOpen ? "#f0f0f0" : "transparent";
|
|
22420
|
-
},
|
|
22421
|
-
children: "⋮"
|
|
22481
|
+
"aria-label": expanded ? "Lukk Setto-meny" : "Åpne Setto-meny",
|
|
22482
|
+
"aria-expanded": expanded,
|
|
22483
|
+
title: "Setto",
|
|
22484
|
+
style: markButtonStyle,
|
|
22485
|
+
onClick: toggleExpanded,
|
|
22486
|
+
children: /* @__PURE__ */ jsx(SettoMark, { size: 28 })
|
|
22422
22487
|
}
|
|
22423
22488
|
),
|
|
22424
|
-
|
|
22425
|
-
/* @__PURE__ */ jsx(
|
|
22426
|
-
/* @__PURE__ */ jsx(
|
|
22489
|
+
expanded ? /* @__PURE__ */ jsxs("div", { style: contentStyle, children: [
|
|
22490
|
+
error ? /* @__PURE__ */ jsx("span", { style: errorStyle, children: error }) : null,
|
|
22491
|
+
hasDrafts && !publishing && activeDeployment === null ? /* @__PURE__ */ jsx("button", { type: "button", onClick: publish, style: publishBtnStyle, children: "Publiser" }) : null,
|
|
22492
|
+
showPublishedNotice ? /* @__PURE__ */ jsxs(
|
|
22493
|
+
"button",
|
|
22494
|
+
{
|
|
22495
|
+
type: "button",
|
|
22496
|
+
onClick: dismissPublishedNotice,
|
|
22497
|
+
style: publishedNoticeStyle,
|
|
22498
|
+
title: "Lukk",
|
|
22499
|
+
children: [
|
|
22500
|
+
/* @__PURE__ */ jsx(PublishedCheckIcon, {}),
|
|
22501
|
+
"Publisert"
|
|
22502
|
+
]
|
|
22503
|
+
}
|
|
22504
|
+
) : null,
|
|
22505
|
+
showToolbarProgress && deploymentRow ? /* @__PURE__ */ jsx(
|
|
22506
|
+
PublishProgressBar,
|
|
22507
|
+
{
|
|
22508
|
+
status: deploymentRow.status,
|
|
22509
|
+
compact: true,
|
|
22510
|
+
href: `${SETTO_BASE}?deployment=${encodeURIComponent(activeDeployment)}`
|
|
22511
|
+
}
|
|
22512
|
+
) : null,
|
|
22513
|
+
!hasDrafts && !error && !showPublishedNotice && !showToolbarProgress && !publishing ? /* @__PURE__ */ jsx("span", { style: emptyStateStyle, children: "Ingen endringer" }) : null,
|
|
22514
|
+
/* @__PURE__ */ jsxs("div", { ref: menuRef, style: { position: "relative" }, children: [
|
|
22515
|
+
/* @__PURE__ */ jsx(
|
|
22516
|
+
"button",
|
|
22517
|
+
{
|
|
22518
|
+
type: "button",
|
|
22519
|
+
onClick: () => setMenuOpen((o) => !o),
|
|
22520
|
+
"aria-label": "Meny",
|
|
22521
|
+
"aria-expanded": menuOpen,
|
|
22522
|
+
style: {
|
|
22523
|
+
...menuBtnStyle,
|
|
22524
|
+
background: menuOpen ? "rgba(242, 235, 223, 0.16)" : "transparent"
|
|
22525
|
+
},
|
|
22526
|
+
onMouseEnter: (e) => {
|
|
22527
|
+
e.currentTarget.style.background = "rgba(242, 235, 223, 0.16)";
|
|
22528
|
+
},
|
|
22529
|
+
onMouseLeave: (e) => {
|
|
22530
|
+
e.currentTarget.style.background = menuOpen ? "rgba(242, 235, 223, 0.16)" : "transparent";
|
|
22531
|
+
},
|
|
22532
|
+
children: "⋮"
|
|
22533
|
+
}
|
|
22534
|
+
),
|
|
22535
|
+
menuOpen ? /* @__PURE__ */ jsxs("div", { style: dropdownStyle, role: "menu", children: [
|
|
22536
|
+
/* @__PURE__ */ jsx(
|
|
22537
|
+
MenuItem,
|
|
22538
|
+
{
|
|
22539
|
+
onClick: cancelDrafts,
|
|
22540
|
+
icon: /* @__PURE__ */ jsx(UndoIcon, {}),
|
|
22541
|
+
disabled: !hasDrafts,
|
|
22542
|
+
children: "Avbryt"
|
|
22543
|
+
}
|
|
22544
|
+
),
|
|
22545
|
+
/* @__PURE__ */ jsx(MenuItem, { onClick: goToHistory, icon: /* @__PURE__ */ jsx(HistoryIcon, {}), children: "Historikk" }),
|
|
22546
|
+
/* @__PURE__ */ jsx(MenuItem, { onClick: signOut, icon: /* @__PURE__ */ jsx(LogOutIcon, {}), children: "Logg ut" })
|
|
22547
|
+
] }) : null
|
|
22548
|
+
] })
|
|
22427
22549
|
] }) : null
|
|
22428
|
-
]
|
|
22429
|
-
|
|
22430
|
-
|
|
22550
|
+
]
|
|
22551
|
+
}
|
|
22552
|
+
),
|
|
22431
22553
|
/* @__PURE__ */ jsx(EditOnboardingDialog, {}),
|
|
22432
22554
|
publishDialogOpen && (publishing || activeDeployment !== null) ? /* @__PURE__ */ jsx(
|
|
22433
22555
|
PublishDialog,
|
|
@@ -22442,82 +22564,112 @@ function EditToolbar() {
|
|
|
22442
22564
|
) : null
|
|
22443
22565
|
] });
|
|
22444
22566
|
}
|
|
22445
|
-
const
|
|
22446
|
-
|
|
22447
|
-
|
|
22448
|
-
|
|
22449
|
-
|
|
22450
|
-
|
|
22451
|
-
|
|
22452
|
-
|
|
22453
|
-
|
|
22454
|
-
|
|
22455
|
-
|
|
22456
|
-
|
|
22457
|
-
|
|
22567
|
+
const EASE_OUT_EXPO = "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
22568
|
+
const FAB_SHADOW = "0 8px 24px rgba(33, 23, 17, 0.35), 0 2px 6px rgba(33, 23, 17, 0.2)";
|
|
22569
|
+
function containerStyleFor(hasDrafts) {
|
|
22570
|
+
return {
|
|
22571
|
+
display: "inline-flex",
|
|
22572
|
+
alignItems: "center",
|
|
22573
|
+
height: FAB_SIZE,
|
|
22574
|
+
width: FAB_SIZE,
|
|
22575
|
+
padding: 0,
|
|
22576
|
+
background: BLEKK,
|
|
22577
|
+
color: CREMA,
|
|
22578
|
+
borderRadius: FAB_SIZE / 2,
|
|
22579
|
+
boxShadow: hasDrafts ? `0 0 0 2px ${TERRACOTTA}, ${FAB_SHADOW}` : FAB_SHADOW,
|
|
22580
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
22581
|
+
fontSize: 13,
|
|
22582
|
+
overflow: "visible",
|
|
22583
|
+
transition: `width 500ms ${EASE_OUT_EXPO}, padding 500ms ${EASE_OUT_EXPO}, box-shadow 300ms ${EASE_OUT_EXPO}`
|
|
22584
|
+
};
|
|
22585
|
+
}
|
|
22586
|
+
const expandedContainerStyle = {
|
|
22587
|
+
width: "auto",
|
|
22588
|
+
paddingRight: 10
|
|
22458
22589
|
};
|
|
22459
|
-
const
|
|
22460
|
-
display: "flex",
|
|
22590
|
+
const markButtonStyle = {
|
|
22591
|
+
display: "inline-flex",
|
|
22461
22592
|
alignItems: "center",
|
|
22462
|
-
|
|
22593
|
+
justifyContent: "center",
|
|
22594
|
+
flexShrink: 0,
|
|
22595
|
+
width: FAB_SIZE,
|
|
22596
|
+
height: FAB_SIZE,
|
|
22597
|
+
background: "transparent",
|
|
22598
|
+
border: "none",
|
|
22599
|
+
padding: 0,
|
|
22600
|
+
cursor: "pointer",
|
|
22601
|
+
color: "inherit"
|
|
22463
22602
|
};
|
|
22464
|
-
const
|
|
22603
|
+
const contentStyle = {
|
|
22465
22604
|
display: "flex",
|
|
22466
22605
|
alignItems: "center",
|
|
22467
|
-
gap:
|
|
22468
|
-
|
|
22606
|
+
gap: 6,
|
|
22607
|
+
paddingLeft: 4,
|
|
22608
|
+
whiteSpace: "nowrap"
|
|
22469
22609
|
};
|
|
22470
|
-
const
|
|
22471
|
-
color: "#
|
|
22610
|
+
const errorStyle = {
|
|
22611
|
+
color: "#ffb4a8",
|
|
22472
22612
|
fontSize: 12,
|
|
22473
|
-
|
|
22613
|
+
maxWidth: 240,
|
|
22614
|
+
overflow: "hidden",
|
|
22615
|
+
textOverflow: "ellipsis"
|
|
22474
22616
|
};
|
|
22475
|
-
const errorStyle = { color: "#dc2626", fontSize: 12 };
|
|
22476
22617
|
const publishedNoticeStyle = {
|
|
22477
22618
|
display: "inline-flex",
|
|
22478
22619
|
alignItems: "center",
|
|
22479
22620
|
gap: 5,
|
|
22480
22621
|
padding: "4px 10px",
|
|
22481
|
-
borderRadius:
|
|
22482
|
-
border: "1px solid
|
|
22483
|
-
background: "
|
|
22484
|
-
color:
|
|
22622
|
+
borderRadius: 999,
|
|
22623
|
+
border: "1px solid rgba(242, 235, 223, 0.25)",
|
|
22624
|
+
background: "rgba(242, 235, 223, 0.08)",
|
|
22625
|
+
color: CREMA,
|
|
22485
22626
|
fontSize: 12,
|
|
22486
22627
|
fontWeight: 500,
|
|
22487
22628
|
cursor: "pointer",
|
|
22488
22629
|
whiteSpace: "nowrap"
|
|
22489
22630
|
};
|
|
22490
22631
|
const publishBtnStyle = {
|
|
22491
|
-
background:
|
|
22492
|
-
color:
|
|
22632
|
+
background: TERRACOTTA,
|
|
22633
|
+
color: CREMA,
|
|
22493
22634
|
border: "none",
|
|
22494
|
-
borderRadius:
|
|
22635
|
+
borderRadius: 999,
|
|
22495
22636
|
padding: "6px 14px",
|
|
22496
22637
|
fontSize: 13,
|
|
22497
|
-
fontWeight:
|
|
22638
|
+
fontWeight: 600,
|
|
22498
22639
|
cursor: "pointer",
|
|
22499
22640
|
whiteSpace: "nowrap"
|
|
22500
22641
|
};
|
|
22501
22642
|
const menuBtnStyle = {
|
|
22502
22643
|
background: "transparent",
|
|
22503
|
-
color:
|
|
22644
|
+
color: CREMA,
|
|
22504
22645
|
border: "none",
|
|
22505
|
-
borderRadius:
|
|
22506
|
-
|
|
22507
|
-
|
|
22646
|
+
borderRadius: 999,
|
|
22647
|
+
width: 32,
|
|
22648
|
+
height: 32,
|
|
22649
|
+
display: "inline-flex",
|
|
22650
|
+
alignItems: "center",
|
|
22651
|
+
justifyContent: "center",
|
|
22652
|
+
fontSize: 22,
|
|
22508
22653
|
lineHeight: 1,
|
|
22509
|
-
cursor: "pointer"
|
|
22654
|
+
cursor: "pointer",
|
|
22655
|
+
fontWeight: 700
|
|
22656
|
+
};
|
|
22657
|
+
const emptyStateStyle = {
|
|
22658
|
+
color: "rgba(242, 235, 223, 0.55)",
|
|
22659
|
+
fontSize: 13,
|
|
22660
|
+
whiteSpace: "nowrap",
|
|
22661
|
+
padding: "0 4px"
|
|
22510
22662
|
};
|
|
22511
22663
|
const dropdownStyle = {
|
|
22512
22664
|
position: "absolute",
|
|
22513
|
-
|
|
22514
|
-
|
|
22515
|
-
|
|
22665
|
+
bottom: "100%",
|
|
22666
|
+
left: 0,
|
|
22667
|
+
marginBottom: 8,
|
|
22516
22668
|
background: "#fff",
|
|
22517
22669
|
border: "1px solid #e8e8e8",
|
|
22518
|
-
borderRadius:
|
|
22519
|
-
boxShadow: "0
|
|
22520
|
-
minWidth:
|
|
22670
|
+
borderRadius: 10,
|
|
22671
|
+
boxShadow: "0 12px 32px rgba(33, 23, 17, 0.18)",
|
|
22672
|
+
minWidth: 160,
|
|
22521
22673
|
overflow: "hidden",
|
|
22522
22674
|
zIndex: 1
|
|
22523
22675
|
};
|
|
@@ -22537,17 +22689,19 @@ const menuItemStyle = {
|
|
|
22537
22689
|
function MenuItem({
|
|
22538
22690
|
onClick,
|
|
22539
22691
|
icon,
|
|
22540
|
-
children
|
|
22692
|
+
children,
|
|
22693
|
+
disabled = false
|
|
22541
22694
|
}) {
|
|
22542
22695
|
return /* @__PURE__ */ jsxs(
|
|
22543
22696
|
"button",
|
|
22544
22697
|
{
|
|
22545
22698
|
type: "button",
|
|
22546
22699
|
onClick,
|
|
22547
|
-
|
|
22700
|
+
disabled,
|
|
22701
|
+
style: { ...menuItemStyle, opacity: disabled ? 0.4 : 1, cursor: disabled ? "not-allowed" : "pointer" },
|
|
22548
22702
|
role: "menuitem",
|
|
22549
22703
|
onMouseEnter: (e) => {
|
|
22550
|
-
e.currentTarget.style.background = "#f5f5f5";
|
|
22704
|
+
if (!disabled) e.currentTarget.style.background = "#f5f5f5";
|
|
22551
22705
|
},
|
|
22552
22706
|
onMouseLeave: (e) => {
|
|
22553
22707
|
e.currentTarget.style.background = "transparent";
|
|
@@ -22596,6 +22750,12 @@ function LogOutIcon() {
|
|
|
22596
22750
|
/* @__PURE__ */ jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
|
|
22597
22751
|
] });
|
|
22598
22752
|
}
|
|
22753
|
+
function UndoIcon() {
|
|
22754
|
+
return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
22755
|
+
/* @__PURE__ */ jsx("path", { d: "M3 7v6h6" }),
|
|
22756
|
+
/* @__PURE__ */ jsx("path", { d: "M21 17a9 9 0 0 0-15-6.7L3 13" })
|
|
22757
|
+
] });
|
|
22758
|
+
}
|
|
22599
22759
|
function EditModeShell({ children, themeStore }) {
|
|
22600
22760
|
useSettoDocumentLayout(true);
|
|
22601
22761
|
const [toolbarRoot, setToolbarRoot] = useState(null);
|
|
@@ -22635,7 +22795,9 @@ function SettoProvider({ config, children }) {
|
|
|
22635
22795
|
const api = useMemo(() => createApi({ apiUrl: config.apiUrl, supabase }), [config.apiUrl, supabase]);
|
|
22636
22796
|
const [session, setSession] = useState(null);
|
|
22637
22797
|
const [authLoading, setAuthLoading] = useState(true);
|
|
22638
|
-
const [
|
|
22798
|
+
const [onAdminRoute, setOnAdminRoute] = useState(
|
|
22799
|
+
() => typeof window === "undefined" ? false : isAdminRoute()
|
|
22800
|
+
);
|
|
22639
22801
|
useEffect(() => {
|
|
22640
22802
|
let cancelled = false;
|
|
22641
22803
|
supabase.auth.getSession().then(({ data }) => {
|
|
@@ -22652,18 +22814,12 @@ function SettoProvider({ config, children }) {
|
|
|
22652
22814
|
};
|
|
22653
22815
|
}, [supabase]);
|
|
22654
22816
|
useEffect(() => {
|
|
22655
|
-
const compute = () =>
|
|
22656
|
-
try {
|
|
22657
|
-
const params = new URLSearchParams(window.location.search);
|
|
22658
|
-
setEditParam(params.get("setto") === "edit");
|
|
22659
|
-
} catch {
|
|
22660
|
-
setEditParam(false);
|
|
22661
|
-
}
|
|
22662
|
-
};
|
|
22817
|
+
const compute = () => setOnAdminRoute(isAdminRoute());
|
|
22663
22818
|
compute();
|
|
22664
22819
|
window.addEventListener("popstate", compute);
|
|
22665
22820
|
return () => window.removeEventListener("popstate", compute);
|
|
22666
22821
|
}, []);
|
|
22822
|
+
const access = useSiteAccess(supabase, session, config.siteId);
|
|
22667
22823
|
const { i18n } = useTranslation();
|
|
22668
22824
|
const storeRef = useRef(null);
|
|
22669
22825
|
const themeStoreRef = useRef(null);
|
|
@@ -22676,7 +22832,7 @@ function SettoProvider({ config, children }) {
|
|
|
22676
22832
|
assetStoreRef.current = new AssetStore();
|
|
22677
22833
|
setStoreReady(true);
|
|
22678
22834
|
}, [i18n, config.theme]);
|
|
22679
|
-
const editMode = !!session &&
|
|
22835
|
+
const editMode = !!session && !!access.currentSite && !onAdminRoute && !authLoading && !access.loading;
|
|
22680
22836
|
const value = {
|
|
22681
22837
|
config,
|
|
22682
22838
|
supabase,
|
|
@@ -22684,6 +22840,8 @@ function SettoProvider({ config, children }) {
|
|
|
22684
22840
|
session,
|
|
22685
22841
|
authLoading,
|
|
22686
22842
|
editMode,
|
|
22843
|
+
currentSite: access.currentSite,
|
|
22844
|
+
sites: access.sites,
|
|
22687
22845
|
store: storeReady ? storeRef.current : null,
|
|
22688
22846
|
themeStore: storeReady ? themeStoreRef.current : null,
|
|
22689
22847
|
assetStore: storeReady ? assetStoreRef.current : null
|
|
@@ -22699,7 +22857,8 @@ function useSetto() {
|
|
|
22699
22857
|
}
|
|
22700
22858
|
const GuestEditContext = createContext(null);
|
|
22701
22859
|
function GuestEditProvider({ children }) {
|
|
22702
|
-
const { editMode } = useSetto();
|
|
22860
|
+
const { editMode, themeStore } = useSetto();
|
|
22861
|
+
const { selectSection } = useSectionEdit();
|
|
22703
22862
|
const [active, setActive] = useState(false);
|
|
22704
22863
|
useEffect(() => {
|
|
22705
22864
|
if (editMode && active) setActive(false);
|
|
@@ -22709,8 +22868,14 @@ function GuestEditProvider({ children }) {
|
|
|
22709
22868
|
return () => document.documentElement.classList.remove("setto-guest-editing");
|
|
22710
22869
|
}, [active]);
|
|
22711
22870
|
const start = useCallback(() => setActive(true), []);
|
|
22712
|
-
const stop = useCallback(() =>
|
|
22713
|
-
|
|
22871
|
+
const stop = useCallback(() => {
|
|
22872
|
+
setActive(false);
|
|
22873
|
+
selectSection(null);
|
|
22874
|
+
}, [selectSection]);
|
|
22875
|
+
return /* @__PURE__ */ jsxs(GuestEditContext.Provider, { value: { active, start, stop }, children: [
|
|
22876
|
+
children,
|
|
22877
|
+
active && themeStore ? createPortal(/* @__PURE__ */ jsx(SectionToolbar, {}), document.body) : null
|
|
22878
|
+
] });
|
|
22714
22879
|
}
|
|
22715
22880
|
function useGuestEdit() {
|
|
22716
22881
|
const ctx = useContext(GuestEditContext);
|
|
@@ -22852,9 +23017,9 @@ function T({ k }) {
|
|
|
22852
23017
|
const value = store ? store.get(k, i18n.language) : t(k);
|
|
22853
23018
|
useEffect(() => {
|
|
22854
23019
|
const el = ref.current;
|
|
22855
|
-
if (!el || focused || !
|
|
23020
|
+
if (!el || focused || !editable) return;
|
|
22856
23021
|
if (el.textContent !== value) el.textContent = value;
|
|
22857
|
-
}, [value, focused,
|
|
23022
|
+
}, [value, focused, editable]);
|
|
22858
23023
|
if (!editable) return /* @__PURE__ */ jsx(Fragment, { children: value });
|
|
22859
23024
|
const handleMouseDown = (e) => {
|
|
22860
23025
|
e.stopPropagation();
|
|
@@ -22901,7 +23066,6 @@ function T({ k }) {
|
|
|
22901
23066
|
commit(e.currentTarget);
|
|
22902
23067
|
};
|
|
22903
23068
|
const handleInput = (e) => {
|
|
22904
|
-
if (!editMode) return;
|
|
22905
23069
|
store?.set(k, i18n.language, e.currentTarget.textContent ?? "");
|
|
22906
23070
|
};
|
|
22907
23071
|
const handlePaste = (e) => {
|
|
@@ -22924,7 +23088,7 @@ function T({ k }) {
|
|
|
22924
23088
|
contentEditable: true,
|
|
22925
23089
|
suppressContentEditableWarning: true,
|
|
22926
23090
|
lang,
|
|
22927
|
-
spellCheck:
|
|
23091
|
+
spellCheck: false,
|
|
22928
23092
|
role: "textbox",
|
|
22929
23093
|
tabIndex: 0,
|
|
22930
23094
|
onFocus: (e) => {
|
|
@@ -22977,9 +23141,9 @@ function isNestedThemeTarget(target, container) {
|
|
|
22977
23141
|
const hit = target.closest("[data-setto-section]");
|
|
22978
23142
|
return !!(hit && hit !== container);
|
|
22979
23143
|
}
|
|
22980
|
-
function handleThemeTargetClick(e,
|
|
23144
|
+
function handleThemeTargetClick(e, editable, themeId, selected, selectSection, onClick) {
|
|
22981
23145
|
onClick?.(e);
|
|
22982
|
-
if (!
|
|
23146
|
+
if (!editable || e.defaultPrevented) return;
|
|
22983
23147
|
const target = e.target;
|
|
22984
23148
|
if (isTextEditClick(target)) return;
|
|
22985
23149
|
if (target.closest("a[href], button, input, textarea, select")) return;
|
|
@@ -22987,11 +23151,11 @@ function handleThemeTargetClick(e, editMode, themeId, selected, selectSection, o
|
|
|
22987
23151
|
e.stopPropagation();
|
|
22988
23152
|
selectSection(selected ? null : themeId);
|
|
22989
23153
|
}
|
|
22990
|
-
function themeTargetEditStyle(
|
|
22991
|
-
if (!
|
|
23154
|
+
function themeTargetEditStyle(editable, selected, accent = "#640AFF") {
|
|
23155
|
+
if (!editable) return {};
|
|
22992
23156
|
return {
|
|
22993
23157
|
cursor: "pointer",
|
|
22994
|
-
outline: selected ?
|
|
23158
|
+
outline: selected ? `2px solid ${accent}` : void 0,
|
|
22995
23159
|
outlineOffset: selected ? -2 : void 0
|
|
22996
23160
|
};
|
|
22997
23161
|
}
|
|
@@ -23009,23 +23173,26 @@ function useSectionTheme(sectionId) {
|
|
|
23009
23173
|
const SettoSection = forwardRef(
|
|
23010
23174
|
function SettoSection2({ sectionId, className, style, children, onClick, ...rest }, ref) {
|
|
23011
23175
|
const { editMode } = useSetto();
|
|
23176
|
+
const guest = useGuestEdit();
|
|
23177
|
+
const editable = editMode || guest.active;
|
|
23178
|
+
const accent = editMode ? "#640AFF" : "#C4502A";
|
|
23012
23179
|
const { selectedId, selectSection } = useSectionEdit();
|
|
23013
23180
|
const colors = useSectionTheme(sectionId);
|
|
23014
23181
|
const selected = selectedId === sectionId;
|
|
23015
23182
|
const handleClick = useCallback(
|
|
23016
23183
|
(e) => {
|
|
23017
|
-
if (
|
|
23184
|
+
if (editable) {
|
|
23018
23185
|
const target = e.target;
|
|
23019
23186
|
if (isNestedThemeTarget(target, e.currentTarget)) return;
|
|
23020
23187
|
}
|
|
23021
|
-
handleThemeTargetClick(e,
|
|
23188
|
+
handleThemeTargetClick(e, editable, sectionId, selected, selectSection, onClick);
|
|
23022
23189
|
},
|
|
23023
|
-
[
|
|
23190
|
+
[editable, onClick, selectSection, selected, sectionId]
|
|
23024
23191
|
);
|
|
23025
23192
|
const mergedStyle = {
|
|
23026
23193
|
...style,
|
|
23027
23194
|
...colors.background ? { backgroundColor: colors.background } : {},
|
|
23028
|
-
...themeTargetEditStyle(
|
|
23195
|
+
...themeTargetEditStyle(editable, selected, accent)
|
|
23029
23196
|
};
|
|
23030
23197
|
return /* @__PURE__ */ jsx(
|
|
23031
23198
|
"section",
|
|
@@ -23044,6 +23211,9 @@ const SettoSection = forwardRef(
|
|
|
23044
23211
|
const SettoBlock = forwardRef(
|
|
23045
23212
|
function SettoBlock2({ blockId, className, style, children, onClick, ...rest }, ref) {
|
|
23046
23213
|
const { editMode } = useSetto();
|
|
23214
|
+
const guest = useGuestEdit();
|
|
23215
|
+
const editable = editMode || guest.active;
|
|
23216
|
+
const accent = editMode ? "#640AFF" : "#C4502A";
|
|
23047
23217
|
const { selectedId, selectSection } = useSectionEdit();
|
|
23048
23218
|
const colors = useSectionTheme(blockId);
|
|
23049
23219
|
const selected = selectedId === blockId;
|
|
@@ -23051,19 +23221,19 @@ const SettoBlock = forwardRef(
|
|
|
23051
23221
|
(e) => {
|
|
23052
23222
|
handleThemeTargetClick(
|
|
23053
23223
|
e,
|
|
23054
|
-
|
|
23224
|
+
editable,
|
|
23055
23225
|
blockId,
|
|
23056
23226
|
selected,
|
|
23057
23227
|
selectSection,
|
|
23058
23228
|
onClick
|
|
23059
23229
|
);
|
|
23060
23230
|
},
|
|
23061
|
-
[
|
|
23231
|
+
[editable, blockId, selected, selectSection, onClick]
|
|
23062
23232
|
);
|
|
23063
23233
|
const mergedStyle = {
|
|
23064
23234
|
...style,
|
|
23065
23235
|
...colors.background ? { backgroundColor: colors.background } : {},
|
|
23066
|
-
...themeTargetEditStyle(
|
|
23236
|
+
...themeTargetEditStyle(editable, selected, accent)
|
|
23067
23237
|
};
|
|
23068
23238
|
return /* @__PURE__ */ jsx(
|
|
23069
23239
|
"div",
|
|
@@ -23111,7 +23281,7 @@ function FloatingPopover({
|
|
|
23111
23281
|
if (top + popoverH > window.innerHeight - 8) {
|
|
23112
23282
|
top = rect.top - popoverH - 6;
|
|
23113
23283
|
}
|
|
23114
|
-
if (top <
|
|
23284
|
+
if (top < 8) top = rect.bottom + 6;
|
|
23115
23285
|
setPos({ top, left });
|
|
23116
23286
|
};
|
|
23117
23287
|
update();
|
|
@@ -23175,6 +23345,9 @@ function FloatingPopover({
|
|
|
23175
23345
|
function SettoIcon({ k, icons, size = 24, className, style }) {
|
|
23176
23346
|
const { t, i18n } = useTranslation();
|
|
23177
23347
|
const { editMode, store } = useSetto();
|
|
23348
|
+
const guest = useGuestEdit();
|
|
23349
|
+
const editable = editMode || guest.active;
|
|
23350
|
+
const accent = editMode ? "#640AFF" : "#C4502A";
|
|
23178
23351
|
const anchorRef = useRef(null);
|
|
23179
23352
|
const [open, setOpen] = useState(false);
|
|
23180
23353
|
const [search, setSearch] = useState("");
|
|
@@ -23186,7 +23359,7 @@ function SettoIcon({ k, icons, size = 24, className, style }) {
|
|
|
23186
23359
|
const iconName = store ? store.get(k, i18n.language) : t(k);
|
|
23187
23360
|
const Icon = icons[iconName] ?? icons[Object.keys(icons)[0] ?? ""] ?? null;
|
|
23188
23361
|
if (!Icon) return null;
|
|
23189
|
-
if (!
|
|
23362
|
+
if (!editable) {
|
|
23190
23363
|
return /* @__PURE__ */ jsx(Icon, { size, className, style });
|
|
23191
23364
|
}
|
|
23192
23365
|
const handleClick = (e) => {
|
|
@@ -23217,7 +23390,7 @@ function SettoIcon({ k, icons, size = 24, className, style }) {
|
|
|
23217
23390
|
style: {
|
|
23218
23391
|
display: "inline-flex",
|
|
23219
23392
|
cursor: "pointer",
|
|
23220
|
-
outline: open ?
|
|
23393
|
+
outline: open ? `2px solid ${accent}` : void 0,
|
|
23221
23394
|
outlineOffset: 2,
|
|
23222
23395
|
borderRadius: 4
|
|
23223
23396
|
},
|
|
@@ -23484,6 +23657,28 @@ function SettoImage({ srcKey, alt, className, style, ...rest }) {
|
|
|
23484
23657
|
)
|
|
23485
23658
|
] });
|
|
23486
23659
|
}
|
|
23660
|
+
const STYLE_ID = "setto-repeater-styles";
|
|
23661
|
+
function useRepeaterStyles() {
|
|
23662
|
+
useEffect(() => {
|
|
23663
|
+
if (document.getElementById(STYLE_ID)) return;
|
|
23664
|
+
const el = document.createElement("style");
|
|
23665
|
+
el.id = STYLE_ID;
|
|
23666
|
+
el.textContent = `
|
|
23667
|
+
.setto-repeater-remove {
|
|
23668
|
+
opacity: 0;
|
|
23669
|
+
transition: opacity 120ms ease;
|
|
23670
|
+
}
|
|
23671
|
+
.setto-repeater-item:hover .setto-repeater-remove,
|
|
23672
|
+
.setto-repeater-remove:focus-visible {
|
|
23673
|
+
opacity: 1;
|
|
23674
|
+
}
|
|
23675
|
+
@media (hover: none) {
|
|
23676
|
+
.setto-repeater-remove { opacity: 1; }
|
|
23677
|
+
}
|
|
23678
|
+
`;
|
|
23679
|
+
document.head.appendChild(el);
|
|
23680
|
+
}, []);
|
|
23681
|
+
}
|
|
23487
23682
|
function SettoRepeater({
|
|
23488
23683
|
itemsKey,
|
|
23489
23684
|
defaultItem,
|
|
@@ -23493,7 +23688,10 @@ function SettoRepeater({
|
|
|
23493
23688
|
}) {
|
|
23494
23689
|
const { i18n } = useTranslation();
|
|
23495
23690
|
const { editMode, store } = useSetto();
|
|
23691
|
+
const guest = useGuestEdit();
|
|
23692
|
+
const editable = editMode || guest.active;
|
|
23496
23693
|
const lng = i18n.language;
|
|
23694
|
+
useRepeaterStyles();
|
|
23497
23695
|
const [, force] = useState(0);
|
|
23498
23696
|
useEffect(() => {
|
|
23499
23697
|
if (!store) return;
|
|
@@ -23507,16 +23705,35 @@ function SettoRepeater({
|
|
|
23507
23705
|
if (keys.length <= 1) return;
|
|
23508
23706
|
store?.removeListItem(itemsKey, itemKey, lng);
|
|
23509
23707
|
};
|
|
23708
|
+
const canRemove = keys.length > 1;
|
|
23510
23709
|
return /* @__PURE__ */ jsxs("div", { className, "data-setto-repeater": true, children: [
|
|
23511
|
-
|
|
23710
|
+
keys.map((itemKey, index) => /* @__PURE__ */ jsxs("div", { className: "setto-repeater-item", style: { position: "relative" }, children: [
|
|
23711
|
+
editable && canRemove ? /* @__PURE__ */ jsx(
|
|
23712
|
+
"button",
|
|
23713
|
+
{
|
|
23714
|
+
type: "button",
|
|
23715
|
+
"data-setto-ui": true,
|
|
23716
|
+
className: "setto-repeater-remove",
|
|
23717
|
+
"aria-label": `Fjern ${itemLabel}`,
|
|
23718
|
+
title: `Fjern ${itemLabel}`,
|
|
23719
|
+
onClick: (e) => {
|
|
23720
|
+
e.stopPropagation();
|
|
23721
|
+
handleRemove(itemKey);
|
|
23722
|
+
},
|
|
23723
|
+
style: removeBtnStyle,
|
|
23724
|
+
children: "×"
|
|
23725
|
+
}
|
|
23726
|
+
) : null,
|
|
23727
|
+
children(itemKey, index)
|
|
23728
|
+
] }, itemKey)),
|
|
23729
|
+
editable ? /* @__PURE__ */ jsx(
|
|
23512
23730
|
"div",
|
|
23513
23731
|
{
|
|
23514
23732
|
"data-setto-ui": true,
|
|
23515
23733
|
style: {
|
|
23516
23734
|
display: "flex",
|
|
23517
23735
|
justifyContent: "flex-end",
|
|
23518
|
-
|
|
23519
|
-
gap: 8
|
|
23736
|
+
marginTop: 8
|
|
23520
23737
|
},
|
|
23521
23738
|
children: /* @__PURE__ */ jsxs(
|
|
23522
23739
|
"button",
|
|
@@ -23527,7 +23744,7 @@ function SettoRepeater({
|
|
|
23527
23744
|
e.stopPropagation();
|
|
23528
23745
|
handleAdd();
|
|
23529
23746
|
},
|
|
23530
|
-
style:
|
|
23747
|
+
style: addBtnStyle,
|
|
23531
23748
|
children: [
|
|
23532
23749
|
"+ Legg til ",
|
|
23533
23750
|
itemLabel
|
|
@@ -23535,37 +23752,10 @@ function SettoRepeater({
|
|
|
23535
23752
|
}
|
|
23536
23753
|
)
|
|
23537
23754
|
}
|
|
23538
|
-
) : null
|
|
23539
|
-
keys.map((itemKey, index) => /* @__PURE__ */ jsxs("div", { className: "setto-repeater-item", style: { position: "relative" }, children: [
|
|
23540
|
-
editMode ? /* @__PURE__ */ jsx(
|
|
23541
|
-
"button",
|
|
23542
|
-
{
|
|
23543
|
-
type: "button",
|
|
23544
|
-
"data-setto-ui": true,
|
|
23545
|
-
"aria-label": `Fjern ${itemLabel}`,
|
|
23546
|
-
disabled: keys.length <= 1,
|
|
23547
|
-
onClick: (e) => {
|
|
23548
|
-
e.stopPropagation();
|
|
23549
|
-
handleRemove(itemKey);
|
|
23550
|
-
},
|
|
23551
|
-
style: {
|
|
23552
|
-
...controlBtnStyle,
|
|
23553
|
-
position: "absolute",
|
|
23554
|
-
top: 0,
|
|
23555
|
-
right: 0,
|
|
23556
|
-
zIndex: 2,
|
|
23557
|
-
padding: "4px 8px",
|
|
23558
|
-
fontSize: 11,
|
|
23559
|
-
opacity: keys.length <= 1 ? 0.4 : 1
|
|
23560
|
-
},
|
|
23561
|
-
children: "× Fjern"
|
|
23562
|
-
}
|
|
23563
|
-
) : null,
|
|
23564
|
-
children(itemKey, index)
|
|
23565
|
-
] }, itemKey))
|
|
23755
|
+
) : null
|
|
23566
23756
|
] });
|
|
23567
23757
|
}
|
|
23568
|
-
const
|
|
23758
|
+
const addBtnStyle = {
|
|
23569
23759
|
padding: "6px 10px",
|
|
23570
23760
|
background: "#f7f7f7",
|
|
23571
23761
|
border: "1px solid #e0e0e0",
|
|
@@ -23575,22 +23765,27 @@ const controlBtnStyle = {
|
|
|
23575
23765
|
cursor: "pointer",
|
|
23576
23766
|
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
23577
23767
|
};
|
|
23578
|
-
|
|
23579
|
-
|
|
23580
|
-
|
|
23581
|
-
|
|
23582
|
-
|
|
23583
|
-
|
|
23584
|
-
|
|
23585
|
-
|
|
23586
|
-
|
|
23587
|
-
|
|
23588
|
-
|
|
23589
|
-
|
|
23590
|
-
|
|
23591
|
-
|
|
23592
|
-
|
|
23593
|
-
|
|
23768
|
+
const removeBtnStyle = {
|
|
23769
|
+
position: "absolute",
|
|
23770
|
+
top: 4,
|
|
23771
|
+
right: 4,
|
|
23772
|
+
zIndex: 2,
|
|
23773
|
+
display: "flex",
|
|
23774
|
+
alignItems: "center",
|
|
23775
|
+
justifyContent: "center",
|
|
23776
|
+
width: 24,
|
|
23777
|
+
height: 24,
|
|
23778
|
+
padding: 0,
|
|
23779
|
+
background: "#ffffff",
|
|
23780
|
+
border: "1px solid #e0e0e0",
|
|
23781
|
+
borderRadius: "50%",
|
|
23782
|
+
fontSize: 16,
|
|
23783
|
+
lineHeight: 1,
|
|
23784
|
+
color: "#444",
|
|
23785
|
+
cursor: "pointer",
|
|
23786
|
+
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
|
|
23787
|
+
fontFamily: 'system-ui, -apple-system, "Segoe UI", sans-serif'
|
|
23788
|
+
};
|
|
23594
23789
|
function authCallbackType() {
|
|
23595
23790
|
const hash = window.location.hash.replace(/^#/, "");
|
|
23596
23791
|
if (!hash) return null;
|
|
@@ -23693,7 +23888,7 @@ function AuthGate({ children }) {
|
|
|
23693
23888
|
clearAuthHashFromUrl();
|
|
23694
23889
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
23695
23890
|
if (sessionData.session) {
|
|
23696
|
-
window.location.replace(
|
|
23891
|
+
window.location.replace(siteHomeUrl());
|
|
23697
23892
|
return;
|
|
23698
23893
|
}
|
|
23699
23894
|
setMode("signin");
|
|
@@ -23871,7 +24066,7 @@ const loadingStyle = {
|
|
|
23871
24066
|
};
|
|
23872
24067
|
function deploymentAdminUrl(deploymentId) {
|
|
23873
24068
|
const u = new URL(window.location.href);
|
|
23874
|
-
u.pathname =
|
|
24069
|
+
u.pathname = SETTO_BASE;
|
|
23875
24070
|
u.search = "";
|
|
23876
24071
|
u.searchParams.set("deployment", deploymentId);
|
|
23877
24072
|
return u.pathname + u.search;
|
|
@@ -23883,8 +24078,7 @@ function SettoAdminApp() {
|
|
|
23883
24078
|
return /* @__PURE__ */ jsx(AuthGate, { children: /* @__PURE__ */ jsx(SiteList, {}) });
|
|
23884
24079
|
}
|
|
23885
24080
|
function SiteList() {
|
|
23886
|
-
const { supabase, session, config } = useSetto();
|
|
23887
|
-
const [sites, setSites] = useState(null);
|
|
24081
|
+
const { supabase, session, sites, currentSite, config } = useSetto();
|
|
23888
24082
|
const [error, setError] = useState(null);
|
|
23889
24083
|
const redirectAfterSignIn = useRef(false);
|
|
23890
24084
|
useEffect(() => {
|
|
@@ -23895,33 +24089,13 @@ function SiteList() {
|
|
|
23895
24089
|
});
|
|
23896
24090
|
return () => sub.subscription.unsubscribe();
|
|
23897
24091
|
}, [supabase]);
|
|
23898
|
-
useEffect(() => {
|
|
23899
|
-
if (!session) return;
|
|
23900
|
-
let cancelled = false;
|
|
23901
|
-
supabase.from("sites").select("*").then(({ data, error: err }) => {
|
|
23902
|
-
if (cancelled) return;
|
|
23903
|
-
if (err) {
|
|
23904
|
-
setError(err.message);
|
|
23905
|
-
setSites([]);
|
|
23906
|
-
return;
|
|
23907
|
-
}
|
|
23908
|
-
setSites(data ?? []);
|
|
23909
|
-
});
|
|
23910
|
-
return () => {
|
|
23911
|
-
cancelled = true;
|
|
23912
|
-
};
|
|
23913
|
-
}, [supabase, session]);
|
|
23914
|
-
const currentSite = useMemo(
|
|
23915
|
-
() => sites?.find((s) => s.id === config.siteId) ?? null,
|
|
23916
|
-
[sites, config.siteId]
|
|
23917
|
-
);
|
|
23918
24092
|
useEffect(() => {
|
|
23919
24093
|
if (!redirectAfterSignIn.current || !session || sites === null || isAdminDeploymentView()) {
|
|
23920
24094
|
return;
|
|
23921
24095
|
}
|
|
23922
24096
|
if (currentSite) {
|
|
23923
24097
|
redirectAfterSignIn.current = false;
|
|
23924
|
-
window.location.replace(
|
|
24098
|
+
window.location.replace(siteHomeUrl());
|
|
23925
24099
|
return;
|
|
23926
24100
|
}
|
|
23927
24101
|
redirectAfterSignIn.current = false;
|
|
@@ -23946,8 +24120,8 @@ function SiteList() {
|
|
|
23946
24120
|
" · branch ",
|
|
23947
24121
|
currentSite.branch
|
|
23948
24122
|
] }),
|
|
23949
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8 }, children: /* @__PURE__ */ jsx("a", { href:
|
|
23950
|
-
/* @__PURE__ */ jsx(DeploymentList, { siteId: currentSite.id })
|
|
24123
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8 }, children: /* @__PURE__ */ jsx("a", { href: siteHomeUrl(), style: primaryBtnLinkStyle, children: "Begynn å redigere" }) }),
|
|
24124
|
+
/* @__PURE__ */ jsx(DeploymentList, { siteId: currentSite.id, onError: setError })
|
|
23951
24125
|
] }) : sites && sites.length === 0 ? /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "Du er ikke medlem av noen sider ennå. Be administratoren legge deg til." }) : null,
|
|
23952
24126
|
sites && !currentSite && sites.length > 0 ? /* @__PURE__ */ jsxs("section", { style: cardStyle, children: [
|
|
23953
24127
|
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: 16 }, children: "Andre sider du har tilgang til" }),
|
|
@@ -23965,7 +24139,10 @@ function SiteList() {
|
|
|
23965
24139
|
] })
|
|
23966
24140
|
] });
|
|
23967
24141
|
}
|
|
23968
|
-
function DeploymentList({
|
|
24142
|
+
function DeploymentList({
|
|
24143
|
+
siteId,
|
|
24144
|
+
onError
|
|
24145
|
+
}) {
|
|
23969
24146
|
const { supabase, api, config } = useSetto();
|
|
23970
24147
|
const [rows, setRows] = useState(null);
|
|
23971
24148
|
const [focusId, setFocusId] = useState(focusedDeploymentId);
|
|
@@ -23984,7 +24161,7 @@ function DeploymentList({ siteId }) {
|
|
|
23984
24161
|
try {
|
|
23985
24162
|
await api.cancelDeployment(config.siteId, focusId);
|
|
23986
24163
|
setFocusId(null);
|
|
23987
|
-
window.history.replaceState(null, "",
|
|
24164
|
+
window.history.replaceState(null, "", SETTO_BASE);
|
|
23988
24165
|
} catch (err) {
|
|
23989
24166
|
setCancelError(err instanceof Error ? err.message : "Kunne ikke avbryte");
|
|
23990
24167
|
} finally {
|
|
@@ -23997,8 +24174,10 @@ function DeploymentList({ siteId }) {
|
|
|
23997
24174
|
}, [api, config.siteId]);
|
|
23998
24175
|
useEffect(() => {
|
|
23999
24176
|
let cancelled = false;
|
|
24000
|
-
supabase.from("deployments").select("*").eq("site_id", siteId).order("started_at", { ascending: false }).limit(10).then(({ data }) => {
|
|
24001
|
-
if (
|
|
24177
|
+
supabase.from("deployments").select("*").eq("site_id", siteId).order("started_at", { ascending: false }).limit(10).then(({ data, error }) => {
|
|
24178
|
+
if (cancelled) return;
|
|
24179
|
+
if (error) onError?.(error.message);
|
|
24180
|
+
setRows(data ?? []);
|
|
24002
24181
|
});
|
|
24003
24182
|
const channel = supabase.channel(`setto-site-deps-${siteId}`).on(
|
|
24004
24183
|
"postgres_changes",
|
|
@@ -24017,7 +24196,7 @@ function DeploymentList({ siteId }) {
|
|
|
24017
24196
|
cancelled = true;
|
|
24018
24197
|
supabase.removeChannel(channel);
|
|
24019
24198
|
};
|
|
24020
|
-
}, [supabase, siteId]);
|
|
24199
|
+
}, [supabase, siteId, onError]);
|
|
24021
24200
|
const showFocusPanel = focusId !== null && (focusRow === null || isDeploymentInProgress(focusRow.status));
|
|
24022
24201
|
if (!rows) return /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "Laster deploys…" });
|
|
24023
24202
|
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
@@ -24102,9 +24281,6 @@ function SignOutButton() {
|
|
|
24102
24281
|
const { supabase } = useSetto();
|
|
24103
24282
|
return /* @__PURE__ */ jsx("button", { onClick: () => supabase.auth.signOut(), style: signOutBtnStyle, children: "Logg ut" });
|
|
24104
24283
|
}
|
|
24105
|
-
function editUrl() {
|
|
24106
|
-
return editModeUrl("/");
|
|
24107
|
-
}
|
|
24108
24284
|
const loadingRedirectStyle = {
|
|
24109
24285
|
minHeight: "100dvh",
|
|
24110
24286
|
display: "flex",
|
|
@@ -24213,6 +24389,7 @@ function depDotStyle(status) {
|
|
|
24213
24389
|
export {
|
|
24214
24390
|
AuthGate,
|
|
24215
24391
|
GuestEditProvider,
|
|
24392
|
+
SETTO_BASE,
|
|
24216
24393
|
SettoAdminApp,
|
|
24217
24394
|
SettoBlock,
|
|
24218
24395
|
SettoIcon,
|