From aa683cc57465a4bcbe100020c38972bdd4a60a4a Mon Sep 17 00:00:00 2001 From: "dev.daminik00" Date: Thu, 23 Oct 2025 02:20:09 +0200 Subject: [PATCH] trial choice --- .storybook/preview.tsx | 26 ++++++++++++++++++- .../payment/PaymentPlacementProvider.tsx | 19 +++++++++++--- src/hooks/auth/useClientToken.ts | 21 +++++++++++++-- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index ca0b6b9..97a2e57 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -6,6 +6,8 @@ import { PaymentPlacementProvider, TrialVariantSelectionProvider, } from "../src/entities/session/payment"; +import type { IFunnelPaymentPlacement } from "../src/entities/session/funnel/types"; +import { Currency } from "../src/shared/types"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -35,6 +37,24 @@ const poppins = Poppins({ weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], }); +// Storybook mock placement to avoid network calls +const storybookPlacement: IFunnelPaymentPlacement = { + currency: Currency.USD, + billingPeriod: "WEEK", + billingInterval: 1, + trialPeriod: "DAY", + trialInterval: 7, + placementId: "plc_story", + paywallId: "pw_story", + paymentUrl: "https://example.com/pay", + variants: [ + { id: "v1", key: "basic", type: "subscription", price: 1499, trialPrice: 100, title: "Basic" }, + { id: "v2", key: "standard", type: "subscription", price: 1499, trialPrice: 499, title: "Standard" }, + { id: "v3", key: "popular", type: "subscription", price: 1499, trialPrice: 899, title: "Popular", accent: true }, + { id: "v4", key: "premium", type: "subscription", price: 1499, trialPrice: 1367, title: "Premium" }, + ], +}; + const preview: Preview = { parameters: { controls: { @@ -62,7 +82,11 @@ const preview: Preview = { }, decorators: [ (Story) => ( - +
- const [cache, setCache] = useState>( - new Map() - ); + const [cache, setCache] = useState>(() => { + const map = new Map(); + initialCache?.forEach(({ funnelKey, paymentId, placement }) => { + const key = `${funnelKey}:${paymentId}`; + map.set(key, { placement, isLoading: false, error: null }); + }); + return map; + }); const getCacheKey = (funnelKey: string, paymentId: string) => `${funnelKey}:${paymentId}`; diff --git a/src/hooks/auth/useClientToken.ts b/src/hooks/auth/useClientToken.ts index 19533c0..1a7eed3 100644 --- a/src/hooks/auth/useClientToken.ts +++ b/src/hooks/auth/useClientToken.ts @@ -8,8 +8,25 @@ export const useClientToken = () => { useEffect(() => { (async () => { - const token = await getAuthTokenFromCookie(); - setToken(token); + try { + const token = await getAuthTokenFromCookie(); + // If server returned undefined, fall back to a stable mock in Storybook + if (!token && typeof window !== "undefined") { + const w = window as Window & { __STORYBOOK_ADDONS?: unknown }; + const isStorybook = Boolean(w.__STORYBOOK_ADDONS) || + /:\/\/.*(:6006|storybook)/i.test(w.location.href); + setToken(isStorybook ? "storybook-token" : undefined); + } else { + setToken(token); + } + } catch { + // In Storybook or non-Next runtime, server action may fail; use mock token + if (typeof window !== "undefined") { + setToken("storybook-token"); + } else { + setToken(undefined); + } + } })(); }, []);