@sevenfold/setto-client 0.8.0 → 0.8.2

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.
@@ -1,3 +1,29 @@
1
1
  /** True when this page is served from a Setto preview address. */
2
2
  export declare function isPreviewHost(hostname: string): boolean;
3
+ export type PreviewBarState = 'hidden' | 'owner' | 'visitor';
4
+ /**
5
+ * Whether the bar shows at all, and as whom.
6
+ *
7
+ * Pulled out of the component because the interesting failures are all in this
8
+ * decision and none of them are visual: showing «Publiser» to somebody who has
9
+ * already paid, showing «Forhåndsvisning» on a site that has been bought, or
10
+ * flashing either one during the round trip that would have said otherwise.
11
+ *
12
+ * Unknown is a state, not a default. Both `sitesLoaded` and `soldPublic` start
13
+ * out unresolved, and every unresolved input means `hidden` — the bar arrives
14
+ * a moment late rather than asserting something it has to take back.
15
+ */
16
+ export declare function previewBarState(input: {
17
+ onPreview: boolean;
18
+ authLoading: boolean;
19
+ hasSession: boolean;
20
+ /** `sites !== null` — whether this account's site list has come back. */
21
+ sitesLoaded: boolean;
22
+ hasCurrentSite: boolean;
23
+ currentSiteIsLive: boolean;
24
+ /** The public answer, null until it arrives or if it never does. */
25
+ soldPublic: boolean | null;
26
+ /** Stripe's own `?betaling=ok`, which lands before the webhook does. */
27
+ paidMarker: boolean;
28
+ }): PreviewBarState;
3
29
  export declare function SettoPreviewBar(): import("react").ReactPortal | null;
@@ -21362,22 +21362,51 @@ const PREVIEW_HOST = /(^|\.)site\.setto\.no$/i;
21362
21362
  function isPreviewHost(hostname) {
21363
21363
  return PREVIEW_HOST.test(hostname);
21364
21364
  }
21365
+ function previewBarState(input) {
21366
+ if (!input.onPreview || input.authLoading) return "hidden";
21367
+ if (input.hasSession && !input.sitesLoaded) return "hidden";
21368
+ if (!input.hasSession && input.soldPublic === null) return "hidden";
21369
+ const bought = input.paidMarker || input.currentSiteIsLive || input.soldPublic === true;
21370
+ if (bought) return "hidden";
21371
+ return input.hasSession && input.hasCurrentSite ? "owner" : "visitor";
21372
+ }
21365
21373
  function SettoPreviewBar() {
21366
21374
  const { supabase, api, config, session, authLoading, currentSite, sites, editMode } = useSetto();
21367
21375
  const [onPreview, setOnPreview] = useState(false);
21368
21376
  const [busy, setBusy] = useState(false);
21369
21377
  const [error, setError] = useState(null);
21370
21378
  const [paid, setPaid] = useState(false);
21379
+ const [soldPublic, setSoldPublic] = useState(null);
21371
21380
  useEffect(() => {
21372
21381
  setOnPreview(isPreviewHost(window.location.hostname));
21373
21382
  setPaid(new URLSearchParams(window.location.search).get("betaling") === "ok");
21374
21383
  }, []);
21375
- if (!onPreview || authLoading) return null;
21376
- if (session && sites === null) return null;
21377
- const bought = paid || currentSite?.status === "live";
21378
- const owner = !!session && !!currentSite && !bought;
21384
+ useEffect(() => {
21385
+ if (!onPreview || session) return;
21386
+ let cancelled = false;
21387
+ fetch(`${config.apiUrl}/onboarding/sites/${config.siteId}/sold`, {
21388
+ headers: { Accept: "application/json" }
21389
+ }).then((r) => r.ok ? r.json() : null).then((d) => {
21390
+ if (!cancelled && d) setSoldPublic(d.sold === true);
21391
+ }).catch(() => {
21392
+ });
21393
+ return () => {
21394
+ cancelled = true;
21395
+ };
21396
+ }, [onPreview, session, config.apiUrl, config.siteId]);
21397
+ const state = previewBarState({
21398
+ onPreview,
21399
+ authLoading,
21400
+ hasSession: !!session,
21401
+ sitesLoaded: sites !== null,
21402
+ hasCurrentSite: !!currentSite,
21403
+ currentSiteIsLive: currentSite?.status === "live",
21404
+ soldPublic,
21405
+ paidMarker: paid
21406
+ });
21407
+ if (state === "hidden") return null;
21408
+ const owner = state === "owner";
21379
21409
  const name = currentSite?.display_name?.trim() || config.displayName?.trim() || config.siteId;
21380
- if (bought) return null;
21381
21410
  const signIn = () => {
21382
21411
  window.location.href = "/setto";
21383
21412
  };
@@ -21486,6 +21515,17 @@ const primaryStyle = {
21486
21515
  const errorStyle$1 = {
21487
21516
  color: "#ffb4a2",
21488
21517
  fontSize: 13,
21518
+ /*
21519
+ * Shrinkable, unlike the label beside it.
21520
+ *
21521
+ * `nowrap` on a flex child whose `min-width` is `auto` cannot shrink below
21522
+ * its own text, so on a 320px phone the error shouldered «Publiser» 19px
21523
+ * past the right edge of the screen and the bar clipped it — the button
21524
+ * that takes the money, unreachable, exactly when something had gone wrong.
21525
+ */
21526
+ minWidth: 0,
21527
+ overflow: "hidden",
21528
+ textOverflow: "ellipsis",
21489
21529
  whiteSpace: "nowrap"
21490
21530
  };
21491
21531
  const SETTO_BASE = "/setto";