@sevenfold/setto-client 0.8.5 → 0.9.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.
@@ -0,0 +1,3 @@
1
+ export declare function DomainView({ siteId }: {
2
+ siteId: string;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import type { SettoModule } from '../module';
2
+ /**
3
+ * The customer's own domain.
4
+ *
5
+ * A dashboard tab rather than a step in the conversation: a domain is a
6
+ * setting somebody returns to — when they finally buy the name, when they move
7
+ * registrar, when a record gets deleted by accident — and the conversation
8
+ * that built the site is not somewhere anybody goes back to.
9
+ */
10
+ export declare const domainModule: SettoModule;
11
+ export { DomainView } from './DomainView';
@@ -5039,26 +5039,26 @@ var PostgrestClient = class PostgrestClient2 {
5039
5039
  this.schemaName = schema;
5040
5040
  this.urlLengthLimit = urlLengthLimit;
5041
5041
  const originalFetch = fetch$1 !== null && fetch$1 !== void 0 ? fetch$1 : globalThis.fetch;
5042
- if (timeout !== void 0 && timeout > 0) this.fetch = (input, init) => {
5042
+ if (timeout !== void 0 && timeout > 0) this.fetch = (input2, init) => {
5043
5043
  const controller = new AbortController();
5044
5044
  const timeoutId = setTimeout(() => controller.abort(), timeout);
5045
5045
  const existingSignal = init === null || init === void 0 ? void 0 : init.signal;
5046
5046
  if (existingSignal) {
5047
5047
  if (existingSignal.aborted) {
5048
5048
  clearTimeout(timeoutId);
5049
- return originalFetch(input, init);
5049
+ return originalFetch(input2, init);
5050
5050
  }
5051
5051
  const abortHandler = () => {
5052
5052
  clearTimeout(timeoutId);
5053
5053
  controller.abort();
5054
5054
  };
5055
5055
  existingSignal.addEventListener("abort", abortHandler, { once: true });
5056
- return originalFetch(input, _objectSpread2$2(_objectSpread2$2({}, init), {}, { signal: controller.signal })).finally(() => {
5056
+ return originalFetch(input2, _objectSpread2$2(_objectSpread2$2({}, init), {}, { signal: controller.signal })).finally(() => {
5057
5057
  clearTimeout(timeoutId);
5058
5058
  existingSignal.removeEventListener("abort", abortHandler);
5059
5059
  });
5060
5060
  }
5061
- return originalFetch(input, _objectSpread2$2(_objectSpread2$2({}, init), {}, { signal: controller.signal })).finally(() => clearTimeout(timeoutId));
5061
+ return originalFetch(input2, _objectSpread2$2(_objectSpread2$2({}, init), {}, { signal: controller.signal })).finally(() => clearTimeout(timeoutId));
5062
5062
  };
5063
5063
  else this.fetch = originalFetch;
5064
5064
  this.retry = retry;
@@ -20182,25 +20182,25 @@ const fetchWithAuth = (supabaseKey, supabaseUrl, getAccessToken, customFetch, tr
20182
20182
  const traceEnabled = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.enabled) === true;
20183
20183
  const respectSampling = (tracePropagationOptions === null || tracePropagationOptions === void 0 ? void 0 : tracePropagationOptions.respectSamplingDecision) !== false;
20184
20184
  const traceTargets = traceEnabled ? getDefaultPropagationTargets(supabaseUrl) : null;
20185
- return async (input, init) => {
20185
+ return async (input2, init) => {
20186
20186
  var _await$getAccessToken;
20187
20187
  const accessToken = (_await$getAccessToken = await getAccessToken()) !== null && _await$getAccessToken !== void 0 ? _await$getAccessToken : supabaseKey;
20188
20188
  let headers = new HeadersConstructor(init === null || init === void 0 ? void 0 : init.headers);
20189
20189
  if (!headers.has("apikey")) headers.set("apikey", supabaseKey);
20190
20190
  if (!headers.has("Authorization")) headers.set("Authorization", `Bearer ${accessToken}`);
20191
20191
  if (traceTargets) {
20192
- const traceHeaders = await getTraceHeaders(input, traceTargets, respectSampling);
20192
+ const traceHeaders = await getTraceHeaders(input2, traceTargets, respectSampling);
20193
20193
  if (traceHeaders) {
20194
20194
  if (traceHeaders.traceparent && !headers.has("traceparent")) headers.set("traceparent", traceHeaders.traceparent);
20195
20195
  if (traceHeaders.tracestate && !headers.has("tracestate")) headers.set("tracestate", traceHeaders.tracestate);
20196
20196
  if (traceHeaders.baggage && !headers.has("baggage")) headers.set("baggage", traceHeaders.baggage);
20197
20197
  }
20198
20198
  }
20199
- return fetch$1(input, _objectSpread2(_objectSpread2({}, init), {}, { headers }));
20199
+ return fetch$1(input2, _objectSpread2(_objectSpread2({}, init), {}, { headers }));
20200
20200
  };
20201
20201
  };
20202
- async function getTraceHeaders(input, targets, respectSampling) {
20203
- if (!shouldPropagateToTarget(typeof input === "string" ? input : input instanceof URL ? input : input.url, targets)) return null;
20202
+ async function getTraceHeaders(input2, targets, respectSampling) {
20203
+ if (!shouldPropagateToTarget(typeof input2 === "string" ? input2 : input2 instanceof URL ? input2 : input2.url, targets)) return null;
20204
20204
  const traceContext = await extractTraceContext();
20205
20205
  if (!traceContext || !traceContext.traceparent) return null;
20206
20206
  if (respectSampling) {
@@ -21310,14 +21310,14 @@ class ThemeStore {
21310
21310
  for (const fn of this.listeners) fn(this.cachedSnapshot);
21311
21311
  }
21312
21312
  }
21313
- const EMPTY = {
21313
+ const EMPTY$1 = {
21314
21314
  sites: null,
21315
21315
  currentSite: null,
21316
21316
  loading: true,
21317
21317
  error: null
21318
21318
  };
21319
21319
  function useSiteAccess(supabase, session, siteId) {
21320
- const [state, setState] = useState(EMPTY);
21320
+ const [state, setState] = useState(EMPTY$1);
21321
21321
  const cachedUserIdRef = useRef(null);
21322
21322
  useEffect(() => {
21323
21323
  if (!session) {
@@ -21396,13 +21396,13 @@ const PREVIEW_HOST = /(^|\.)site\.setto\.no$/i;
21396
21396
  function isPreviewHost(hostname) {
21397
21397
  return PREVIEW_HOST.test(hostname);
21398
21398
  }
21399
- function previewBarState(input) {
21400
- if (!input.onPreview || input.authLoading) return "hidden";
21401
- if (input.hasSession && !input.sitesLoaded) return "hidden";
21402
- if (!input.hasSession && input.soldPublic === null) return "hidden";
21403
- const bought = input.paidMarker || input.currentSiteIsLive || input.soldPublic === true;
21399
+ function previewBarState(input2) {
21400
+ if (!input2.onPreview || input2.authLoading) return "hidden";
21401
+ if (input2.hasSession && !input2.sitesLoaded) return "hidden";
21402
+ if (!input2.hasSession && input2.soldPublic === null) return "hidden";
21403
+ const bought = input2.paidMarker || input2.currentSiteIsLive || input2.soldPublic === true;
21404
21404
  if (bought) return "hidden";
21405
- return input.hasSession && input.hasCurrentSite ? "owner" : "visitor";
21405
+ return input2.hasSession && input2.hasCurrentSite ? "owner" : "visitor";
21406
21406
  }
21407
21407
  function SettoPreviewBar() {
21408
21408
  const { supabase, api, config, session, authLoading, currentSite, sites, editMode } = useSetto();
@@ -21505,7 +21505,7 @@ function SettoPreviewBar() {
21505
21505
  "Du forhåndsviser nå ",
21506
21506
  /* @__PURE__ */ jsx("strong", { style: { fontWeight: 600 }, children: name })
21507
21507
  ] }),
21508
- error && /* @__PURE__ */ jsx("span", { style: errorStyle$1, children: error }),
21508
+ error && /* @__PURE__ */ jsx("span", { style: errorStyle$2, children: error }),
21509
21509
  /* @__PURE__ */ jsx("button", { type: "button", style: primaryStyle, onClick: publish, disabled: busy, children: busy ? "Åpner betaling …" : "Publiser" })
21510
21510
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
21511
21511
  /* @__PURE__ */ jsx("span", { style: dotStyle, "aria-hidden": true }),
@@ -21572,7 +21572,7 @@ const primaryStyle = {
21572
21572
  fontWeight: 600,
21573
21573
  cursor: "pointer"
21574
21574
  };
21575
- const errorStyle$1 = {
21575
+ const errorStyle$2 = {
21576
21576
  color: "#ffb4a2",
21577
21577
  fontSize: 13,
21578
21578
  /*
@@ -22268,13 +22268,13 @@ function isDeploymentInProgress(status) {
22268
22268
  }
22269
22269
  const STALE_PENDING_MS = 20 * 60 * 1e3;
22270
22270
  const STALE_BUILDING_MS = 45 * 60 * 1e3;
22271
- function isDeploymentStale(row) {
22272
- if (row.status !== "pending" && row.status !== "building") return false;
22271
+ function isDeploymentStale(row2) {
22272
+ if (row2.status !== "pending" && row2.status !== "building") return false;
22273
22273
  const now = Date.now();
22274
- if (row.status === "pending") {
22275
- return now - new Date(row.started_at).getTime() > STALE_PENDING_MS;
22274
+ if (row2.status === "pending") {
22275
+ return now - new Date(row2.started_at).getTime() > STALE_PENDING_MS;
22276
22276
  }
22277
- return now - new Date(row.updated_at).getTime() > STALE_BUILDING_MS;
22277
+ return now - new Date(row2.updated_at).getTime() > STALE_BUILDING_MS;
22278
22278
  }
22279
22279
  async function fetchInProgressDeploymentId(supabase, siteId) {
22280
22280
  const { data } = await supabase.from("deployments").select("id, status, started_at, updated_at").eq("site_id", siteId).in("status", [...IN_PROGRESS_STATUSES]).order("started_at", { ascending: false }).limit(5);
@@ -22292,7 +22292,7 @@ async function waitForDeploymentByCommit(supabase, siteId, commitSha, timeoutMs
22292
22292
  return null;
22293
22293
  }
22294
22294
  function useDeploymentStatus(supabase, deploymentId) {
22295
- const [row, setRow] = useState(null);
22295
+ const [row2, setRow] = useState(null);
22296
22296
  useEffect(() => {
22297
22297
  if (!deploymentId) {
22298
22298
  setRow(null);
@@ -22322,7 +22322,7 @@ function useDeploymentStatus(supabase, deploymentId) {
22322
22322
  if (channel) supabase.removeChannel(channel);
22323
22323
  };
22324
22324
  }, [supabase, deploymentId]);
22325
- return { row, status: row?.status ?? null };
22325
+ return { row: row2, status: row2?.status ?? null };
22326
22326
  }
22327
22327
  function deploymentStepIndex(status) {
22328
22328
  switch (status) {
@@ -22461,14 +22461,14 @@ function PublishProgressBar({ status, compact, href }) {
22461
22461
  return /* @__PURE__ */ jsx("div", { style: wrapStyle, children: inner });
22462
22462
  }
22463
22463
  function PublishDialog({
22464
- row,
22464
+ row: row2,
22465
22465
  status,
22466
22466
  onClose,
22467
22467
  onComplete
22468
22468
  }) {
22469
22469
  const buildingStartedAt = useRef(null);
22470
22470
  const [elapsed, setElapsed] = useState(0);
22471
- const progressStatus = row?.status ?? status ?? "pending";
22471
+ const progressStatus = row2?.status ?? status ?? "pending";
22472
22472
  const errored = progressStatus === "error" || progressStatus === "canceled";
22473
22473
  const isReady = progressStatus === "ready";
22474
22474
  const isBuilding = progressStatus === "building";
@@ -22495,7 +22495,7 @@ function PublishDialog({
22495
22495
  /* @__PURE__ */ jsx("h2", { style: { margin: "0 0 12px", fontSize: 18, fontWeight: 600, color: "#dc2626" }, children: "Publisering feilet" }),
22496
22496
  /* @__PURE__ */ jsxs("p", { style: { margin: "0 0 20px", fontSize: 14, lineHeight: 1.5, color: "#444" }, children: [
22497
22497
  progressStatus === "error" ? "Bygg feilet." : "Avbrutt.",
22498
- row?.error_message ? ` ${row.error_message}` : ""
22498
+ row2?.error_message ? ` ${row2.error_message}` : ""
22499
22499
  ] }),
22500
22500
  /* @__PURE__ */ jsx("button", { type: "button", onClick: onComplete, style: secondaryBtnStyle$1, children: "OK" })
22501
22501
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -22576,6 +22576,226 @@ function useEditBaseline() {
22576
22576
  };
22577
22577
  }, [session, store, config.siteId]);
22578
22578
  }
22579
+ const EMPTY = {
22580
+ host: null,
22581
+ verified: false,
22582
+ status: null,
22583
+ instructions: [],
22584
+ statusLine: null
22585
+ };
22586
+ function Copyable({ value }) {
22587
+ const [copied, setCopied] = useState(false);
22588
+ return /* @__PURE__ */ jsx(
22589
+ "button",
22590
+ {
22591
+ type: "button",
22592
+ onClick: () => {
22593
+ void navigator.clipboard?.writeText(value).then(
22594
+ () => {
22595
+ setCopied(true);
22596
+ window.setTimeout(() => setCopied(false), 1400);
22597
+ },
22598
+ () => void 0
22599
+ );
22600
+ },
22601
+ title: "Kopier",
22602
+ style: {
22603
+ font: "inherit",
22604
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
22605
+ background: "none",
22606
+ border: 0,
22607
+ padding: 0,
22608
+ cursor: "pointer",
22609
+ color: "inherit",
22610
+ textAlign: "left",
22611
+ wordBreak: "break-all"
22612
+ },
22613
+ children: copied ? "Kopiert" : value
22614
+ }
22615
+ );
22616
+ }
22617
+ function DomainView({ siteId }) {
22618
+ const { api } = useSetto();
22619
+ const [state, setState] = useState(EMPTY);
22620
+ const [host, setHost] = useState("");
22621
+ const [loading, setLoading] = useState(true);
22622
+ const [busy, setBusy] = useState(false);
22623
+ const [error, setError] = useState(null);
22624
+ const load = async () => {
22625
+ try {
22626
+ setState(await api.request(`/onboarding/sites/${siteId}/domain`, {}, "domain"));
22627
+ } catch {
22628
+ setState(EMPTY);
22629
+ } finally {
22630
+ setLoading(false);
22631
+ }
22632
+ };
22633
+ useEffect(() => {
22634
+ void load();
22635
+ }, [siteId]);
22636
+ async function attach() {
22637
+ setBusy(true);
22638
+ setError(null);
22639
+ try {
22640
+ setState(
22641
+ await api.request(
22642
+ `/onboarding/sites/${siteId}/domain`,
22643
+ { method: "POST", body: { host } },
22644
+ "attachDomain"
22645
+ )
22646
+ );
22647
+ setHost("");
22648
+ } catch (err) {
22649
+ const detail = err instanceof Error ? err.message : "";
22650
+ setError(
22651
+ detail.includes("invalid_domain") ? "Det ser ikke ut som et domenenavn. Skriv det som dittfirma.no." : detail.includes("domain_taken") ? "Domenet er allerede i bruk på en annen Setto-side." : detail.includes("site_not_deployed") ? "Nettsiden er ikke publisert ennå." : "Klarte ikke legge til domenet. Prøv igjen."
22652
+ );
22653
+ } finally {
22654
+ setBusy(false);
22655
+ }
22656
+ }
22657
+ async function recheck() {
22658
+ setBusy(true);
22659
+ setError(null);
22660
+ try {
22661
+ setState(
22662
+ await api.request(
22663
+ `/onboarding/sites/${siteId}/domain/verify`,
22664
+ { method: "POST" },
22665
+ "verifyDomain"
22666
+ )
22667
+ );
22668
+ } catch {
22669
+ setError("Klarte ikke sjekke akkurat nå. Prøv igjen om litt.");
22670
+ } finally {
22671
+ setBusy(false);
22672
+ }
22673
+ }
22674
+ async function detach() {
22675
+ setBusy(true);
22676
+ setError(null);
22677
+ try {
22678
+ setState(
22679
+ await api.request(
22680
+ `/onboarding/sites/${siteId}/domain`,
22681
+ { method: "DELETE" },
22682
+ "detachDomain"
22683
+ )
22684
+ );
22685
+ } catch {
22686
+ setError("Klarte ikke fjerne domenet.");
22687
+ } finally {
22688
+ setBusy(false);
22689
+ }
22690
+ }
22691
+ if (loading) return /* @__PURE__ */ jsx("p", { style: muted, children: "Henter …" });
22692
+ if (!state.host) {
22693
+ return /* @__PURE__ */ jsxs("div", { style: wrap, children: [
22694
+ /* @__PURE__ */ jsx("p", { style: lead, children: "Har du et domene fra før — dittfirma.no — kan du peke det hit. Nettsiden beholder adressen den har nå i tillegg, så ingenting slutter å virke underveis." }),
22695
+ /* @__PURE__ */ jsxs("div", { style: row, children: [
22696
+ /* @__PURE__ */ jsx(
22697
+ "input",
22698
+ {
22699
+ value: host,
22700
+ onChange: (e) => setHost(e.target.value),
22701
+ placeholder: "dittfirma.no",
22702
+ "aria-label": "Domenet ditt",
22703
+ autoCapitalize: "off",
22704
+ autoCorrect: "off",
22705
+ spellCheck: false,
22706
+ style: input
22707
+ }
22708
+ ),
22709
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void attach(), disabled: busy || !host.trim(), style: primary, children: busy ? "Legger til …" : "Legg til domene" })
22710
+ ] }),
22711
+ error && /* @__PURE__ */ jsx("p", { style: errorStyle$1, children: error })
22712
+ ] });
22713
+ }
22714
+ return /* @__PURE__ */ jsxs("div", { style: wrap, children: [
22715
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "0.6rem", flexWrap: "wrap" }, children: [
22716
+ /* @__PURE__ */ jsx("strong", { style: { fontSize: "1.05rem" }, children: state.host }),
22717
+ /* @__PURE__ */ jsx("span", { style: state.verified ? liveBadge : pendingBadge, children: state.verified ? "Live" : "Venter på DNS" })
22718
+ ] }),
22719
+ state.statusLine && /* @__PURE__ */ jsx("p", { style: lead, children: state.statusLine }),
22720
+ state.instructions.length > 0 && !state.verified && /* @__PURE__ */ jsxs(Fragment, { children: [
22721
+ /* @__PURE__ */ jsx("p", { style: muted, children: "Logg inn der du kjøpte domenet, finn DNS-innstillingene, og legg inn dette:" }),
22722
+ /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: "0.6rem" }, children: state.instructions.map((rec) => /* @__PURE__ */ jsxs("div", { style: card, children: [
22723
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "1.2rem", flexWrap: "wrap" }, children: [
22724
+ /* @__PURE__ */ jsx(Field, { label: "Type", value: rec.type }),
22725
+ /* @__PURE__ */ jsx(Field, { label: "Navn", value: rec.name }),
22726
+ /* @__PURE__ */ jsx(Field, { label: "Peker til", value: rec.value, wide: true })
22727
+ ] }),
22728
+ /* @__PURE__ */ jsx("p", { style: { ...muted, margin: "0.35rem 0 0" }, children: rec.why })
22729
+ ] }, `${rec.type}-${rec.name}`)) })
22730
+ ] }),
22731
+ error && /* @__PURE__ */ jsx("p", { style: errorStyle$1, children: error }),
22732
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.6rem", flexWrap: "wrap" }, children: [
22733
+ !state.verified && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void recheck(), disabled: busy, style: primary, children: busy ? "Sjekker …" : "Jeg har lagt inn radene" }),
22734
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void detach(), disabled: busy, style: quiet, children: "Fjern domenet" })
22735
+ ] })
22736
+ ] });
22737
+ }
22738
+ function Field({ label, value, wide }) {
22739
+ return /* @__PURE__ */ jsxs("div", { style: { minWidth: wide ? "14rem" : "5rem", flex: wide ? "1 1 14rem" : "0 0 auto" }, children: [
22740
+ /* @__PURE__ */ jsx("div", { style: { ...muted, fontSize: "0.72rem", textTransform: "uppercase", letterSpacing: "0.04em" }, children: label }),
22741
+ /* @__PURE__ */ jsx(Copyable, { value })
22742
+ ] });
22743
+ }
22744
+ const wrap = { display: "grid", gap: "0.9rem", maxWidth: "42rem" };
22745
+ const lead = { margin: 0, lineHeight: 1.5 };
22746
+ const muted = { margin: 0, opacity: 0.65, lineHeight: 1.5 };
22747
+ const row = { display: "flex", gap: "0.6rem", flexWrap: "wrap" };
22748
+ const input = {
22749
+ flex: "1 1 14rem",
22750
+ padding: "0.6rem 0.75rem",
22751
+ border: "1px solid rgba(0,0,0,0.18)",
22752
+ borderRadius: "0.5rem",
22753
+ font: "inherit"
22754
+ };
22755
+ const card = {
22756
+ padding: "0.7rem 0.85rem",
22757
+ border: "1px solid rgba(0,0,0,0.12)",
22758
+ borderRadius: "0.6rem",
22759
+ background: "rgba(0,0,0,0.02)"
22760
+ };
22761
+ const primary = {
22762
+ padding: "0.6rem 1.1rem",
22763
+ borderRadius: "999px",
22764
+ border: 0,
22765
+ background: "#c4502a",
22766
+ color: "#fff",
22767
+ font: "inherit",
22768
+ fontWeight: 600,
22769
+ cursor: "pointer"
22770
+ };
22771
+ const quiet = {
22772
+ padding: "0.6rem 0.9rem",
22773
+ borderRadius: "999px",
22774
+ border: "1px solid rgba(0,0,0,0.18)",
22775
+ background: "transparent",
22776
+ font: "inherit",
22777
+ cursor: "pointer"
22778
+ };
22779
+ const errorStyle$1 = { margin: 0, color: "#b42318" };
22780
+ const liveBadge = {
22781
+ fontSize: "0.75rem",
22782
+ padding: "0.15rem 0.5rem",
22783
+ borderRadius: "999px",
22784
+ background: "rgba(15,123,79,0.12)",
22785
+ color: "#0f7b4f"
22786
+ };
22787
+ const pendingBadge = {
22788
+ fontSize: "0.75rem",
22789
+ padding: "0.15rem 0.5rem",
22790
+ borderRadius: "999px",
22791
+ background: "rgba(196,80,42,0.12)",
22792
+ color: "#c4502a"
22793
+ };
22794
+ const domainModule = {
22795
+ id: "domain",
22796
+ label: "Domene",
22797
+ AdminView: DomainView
22798
+ };
22579
22799
  const shellStyle$1 = {
22580
22800
  minHeight: "100dvh",
22581
22801
  background: "#0a0a0d",
@@ -22846,28 +23066,28 @@ function SubmissionList({ siteId }) {
22846
23066
  return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
22847
23067
  /* @__PURE__ */ jsx("h3", { style: subheadingStyle, children: "Henvendelser" }),
22848
23068
  error ? /* @__PURE__ */ jsx("p", { style: errStyle, children: error }) : null,
22849
- rows.length === 0 ? /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "Ingen henvendelser ennå. Når noen sender inn et skjema på siden, dukker det opp her og i e-posten." }) : /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 6 }, children: rows.map((row) => /* @__PURE__ */ jsx(
23069
+ rows.length === 0 ? /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "Ingen henvendelser ennå. Når noen sender inn et skjema på siden, dukker det opp her og i e-posten." }) : /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 6 }, children: rows.map((row2) => /* @__PURE__ */ jsx(
22850
23070
  SubmissionItem,
22851
23071
  {
22852
- row,
22853
- open: openId === row.id,
22854
- onToggle: () => setOpenId(openId === row.id ? null : row.id),
22855
- onDelete: () => void remove2(row.id)
23072
+ row: row2,
23073
+ open: openId === row2.id,
23074
+ onToggle: () => setOpenId(openId === row2.id ? null : row2.id),
23075
+ onDelete: () => void remove2(row2.id)
22856
23076
  },
22857
- row.id
23077
+ row2.id
22858
23078
  )) }),
22859
23079
  hasMore ? /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void loadMore(), disabled: loadingMore, style: secondaryBtnStyle, children: loadingMore ? "Laster …" : "Vis eldre" }) : null
22860
23080
  ] });
22861
23081
  }
22862
23082
  function SubmissionItem({
22863
- row,
23083
+ row: row2,
22864
23084
  open,
22865
23085
  onToggle,
22866
23086
  onDelete
22867
23087
  }) {
22868
- const fields = submissionFields(row);
23088
+ const fields = submissionFields(row2);
22869
23089
  const sender = senderOf(fields);
22870
- const title = row.meta.title ?? row.form_id;
23090
+ const title = row2.meta.title ?? row2.form_id;
22871
23091
  return /* @__PURE__ */ jsxs("li", { children: [
22872
23092
  /* @__PURE__ */ jsxs(
22873
23093
  "button",
@@ -22877,7 +23097,7 @@ function SubmissionItem({
22877
23097
  "aria-expanded": open,
22878
23098
  style: { ...rowStyle, width: "100%", textAlign: "left", color: "inherit", border: "none", cursor: "pointer", font: "inherit" },
22879
23099
  children: [
22880
- /* @__PURE__ */ jsx("span", { style: statusDotStyle(row.email_status), title: emailStatusLabel(row) }),
23100
+ /* @__PURE__ */ jsx("span", { style: statusDotStyle(row2.email_status), title: emailStatusLabel(row2) }),
22881
23101
  /* @__PURE__ */ jsxs("span", { style: { flex: 1, fontSize: 13, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: [
22882
23102
  sender ?? /* @__PURE__ */ jsx("span", { style: { color: "#aaa" }, children: "Uten navn" }),
22883
23103
  /* @__PURE__ */ jsxs("span", { style: { color: "#888" }, children: [
@@ -22885,7 +23105,7 @@ function SubmissionItem({
22885
23105
  title
22886
23106
  ] })
22887
23107
  ] }),
22888
- /* @__PURE__ */ jsx("time", { style: { fontSize: 11, color: "#888", flexShrink: 0 }, children: formatWhen(row.created_at) })
23108
+ /* @__PURE__ */ jsx("time", { style: { fontSize: 11, color: "#888", flexShrink: 0 }, children: formatWhen(row2.created_at) })
22889
23109
  ]
22890
23110
  }
22891
23111
  ),
@@ -22895,26 +23115,26 @@ function SubmissionItem({
22895
23115
  /* @__PURE__ */ jsx("dd", { style: { margin: 0, fontSize: 14, whiteSpace: "pre-wrap", wordBreak: "break-word" }, children: f.value === "" ? /* @__PURE__ */ jsx("span", { style: { color: "#666" }, children: "—" }) : f.value })
22896
23116
  ] }, f.name)) }),
22897
23117
  /* @__PURE__ */ jsxs("p", { style: mutedStyle, children: [
22898
- emailStatusLabel(row),
22899
- row.recipients.length > 0 ? ` til ${row.recipients.join(", ")}` : "",
22900
- row.email_error ? ` — ${row.email_error}` : "",
22901
- row.meta.page ? /* @__PURE__ */ jsxs(Fragment, { children: [
23118
+ emailStatusLabel(row2),
23119
+ row2.recipients.length > 0 ? ` til ${row2.recipients.join(", ")}` : "",
23120
+ row2.email_error ? ` — ${row2.email_error}` : "",
23121
+ row2.meta.page ? /* @__PURE__ */ jsxs(Fragment, { children: [
22902
23122
  " · ",
22903
- /* @__PURE__ */ jsx("a", { href: row.meta.page, style: { color: "#bda6ff" }, target: "_blank", rel: "noreferrer", children: "Sendt fra siden" })
23123
+ /* @__PURE__ */ jsx("a", { href: row2.meta.page, style: { color: "#bda6ff" }, target: "_blank", rel: "noreferrer", children: "Sendt fra siden" })
22904
23124
  ] }) : null
22905
23125
  ] }),
22906
23126
  /* @__PURE__ */ jsx("button", { type: "button", onClick: onDelete, style: dangerBtnStyle, children: "Slett henvendelse" })
22907
23127
  ] }) : null
22908
23128
  ] });
22909
23129
  }
22910
- function submissionFields(row) {
23130
+ function submissionFields(row2) {
22911
23131
  const flat = [];
22912
- flatten(row.data, "", flat);
22913
- const rank = new Map((row.field_order ?? []).map((n, i) => [n, i]));
23132
+ flatten(row2.data, "", flat);
23133
+ const rank = new Map((row2.field_order ?? []).map((n, i) => [n, i]));
22914
23134
  const rankOf = (name) => rank.get(name) ?? rank.get(name.split(".")[0]) ?? Number.MAX_SAFE_INTEGER;
22915
23135
  return flat.map((f, i) => ({ f, i })).sort((a, b) => rankOf(a.f.name) - rankOf(b.f.name) || a.i - b.i).map(({ f }) => ({
22916
23136
  name: f.name,
22917
- label: row.labels?.[f.name] ?? row.labels?.[f.name.split(".")[0]] ?? prettify(f.name),
23137
+ label: row2.labels?.[f.name] ?? row2.labels?.[f.name.split(".")[0]] ?? prettify(f.name),
22918
23138
  value: f.value
22919
23139
  }));
22920
23140
  }
@@ -22953,8 +23173,8 @@ function senderOf(fields) {
22953
23173
  const first = fields.find((f) => f.value !== "");
22954
23174
  return first ? first.value.slice(0, 80) : null;
22955
23175
  }
22956
- function emailStatusLabel(row) {
22957
- switch (row.email_status) {
23176
+ function emailStatusLabel(row2) {
23177
+ switch (row2.email_status) {
22958
23178
  case "sent":
22959
23179
  return "E-post sendt";
22960
23180
  case "failed":
@@ -24404,7 +24624,7 @@ const formsModule = {
24404
24624
  label: "Skjemaer",
24405
24625
  AdminView: FormsView
24406
24626
  };
24407
- const SETTO_MODULES = [formsModule];
24627
+ const SETTO_MODULES = [formsModule, domainModule];
24408
24628
  function findModule(id) {
24409
24629
  return id ? SETTO_MODULES.find((m) => m.id === id) : void 0;
24410
24630
  }
@@ -26230,8 +26450,8 @@ function DeploymentsView({
26230
26450
  ] })
26231
26451
  ] });
26232
26452
  }
26233
- function statusLabel(row) {
26234
- switch (row.status) {
26453
+ function statusLabel(row2) {
26454
+ switch (row2.status) {
26235
26455
  case "pending":
26236
26456
  return "Venter";
26237
26457
  case "building":
@@ -26239,7 +26459,7 @@ function statusLabel(row) {
26239
26459
  case "ready":
26240
26460
  return "Publisert";
26241
26461
  case "error":
26242
- return row.error_message?.includes("webhook") ? "Utløpt" : "Feilet";
26462
+ return row2.error_message?.includes("webhook") ? "Utløpt" : "Feilet";
26243
26463
  case "canceled":
26244
26464
  return "Avbrutt";
26245
26465
  }
@@ -26400,20 +26620,20 @@ function nodeChildren(node) {
26400
26620
  }
26401
26621
  }
26402
26622
  const ANIMATION_PRESETS = ["fadeIn", "slideUp", "stagger", "scrollReveal"];
26403
- function validateBlockTree(input) {
26623
+ function validateBlockTree(input2) {
26404
26624
  const issues = [];
26405
- if (!isRecord(input)) {
26625
+ if (!isRecord(input2)) {
26406
26626
  return fail("$", "Block tree must be an object");
26407
26627
  }
26408
- if (input.version !== "1") {
26628
+ if (input2.version !== "1") {
26409
26629
  issues.push({ path: "$.version", message: 'Expected version "1"' });
26410
26630
  }
26411
- if (!Array.isArray(input.root)) {
26631
+ if (!Array.isArray(input2.root)) {
26412
26632
  return fail("$.root", "root must be an array of block nodes");
26413
26633
  }
26414
26634
  const seenIds = /* @__PURE__ */ new Set();
26415
- for (let i = 0; i < input.root.length; i++) {
26416
- validateNode(input.root[i], `root[${i}]`, seenIds, issues);
26635
+ for (let i = 0; i < input2.root.length; i++) {
26636
+ validateNode(input2.root[i], `root[${i}]`, seenIds, issues);
26417
26637
  }
26418
26638
  return issues.length ? { ok: false, issues } : { ok: true };
26419
26639
  }
@@ -26563,14 +26783,14 @@ function isRecord(value) {
26563
26783
  function fail(path, message) {
26564
26784
  return { ok: false, issues: [{ path, message }] };
26565
26785
  }
26566
- function parseBlockTree(input) {
26567
- const result = validateBlockTree(input);
26786
+ function parseBlockTree(input2) {
26787
+ const result = validateBlockTree(input2);
26568
26788
  if (!result.ok) {
26569
26789
  const first = result.issues[0];
26570
26790
  const detail = first ? `${first.path}: ${first.message}` : "unknown";
26571
26791
  throw new Error(`Invalid block tree at ${detail}`);
26572
26792
  }
26573
- return input;
26793
+ return input2;
26574
26794
  }
26575
26795
  const IconRegistryContext = createContext(null);
26576
26796
  const RepeaterScopeContext = createContext(null);