bitsnap-react 1.16.0 → 1.18.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/AGENTS.md +5 -0
- package/README.md +87 -0
- package/dist/CartProvider-ECQQH3PS.css +2 -0
- package/dist/CartProvider-ECQQH3PS.css.map +1 -0
- package/dist/CartProvider-OEI526IN.js +2 -0
- package/dist/{CartProvider-VGZMDVFJ.js.map → CartProvider-OEI526IN.js.map} +1 -1
- package/dist/CartProvider-RYAA3JDA.mjs +2 -0
- package/dist/{PanelModelFiles-NYCOFPLY.js → PanelModelFiles-7HPXWONN.js} +2 -2
- package/dist/{PanelModelFiles-NYCOFPLY.js.map → PanelModelFiles-7HPXWONN.js.map} +1 -1
- package/dist/PanelModelFiles-JZFSF7BF.mjs +2 -0
- package/dist/PanelModelFiles-JZFSF7BF.mjs.map +1 -0
- package/dist/analytics.d.mts +2 -2
- package/dist/analytics.d.ts +2 -2
- package/dist/analytics.js +1 -1
- package/dist/analytics.mjs +1 -1
- package/dist/catalog.css +1 -1
- package/dist/catalog.css.map +1 -1
- package/dist/catalog.d.mts +3 -1
- package/dist/catalog.d.ts +3 -1
- package/dist/catalog.js +1 -1
- package/dist/catalog.mjs +1 -1
- package/dist/{chunk-GXUNRJ5S.js → chunk-4HGZZJEL.js} +2 -2
- package/dist/{chunk-GXUNRJ5S.js.map → chunk-4HGZZJEL.js.map} +1 -1
- package/dist/chunk-4OVOKGGS.mjs +2 -0
- package/dist/chunk-4OVOKGGS.mjs.map +1 -0
- package/dist/chunk-5X7TP3TQ.mjs +2 -0
- package/dist/{chunk-SULHGFYN.mjs.map → chunk-5X7TP3TQ.mjs.map} +1 -1
- package/dist/{chunk-QQQ2JSPQ.mjs → chunk-CF45RDMD.mjs} +2 -2
- package/dist/{chunk-QQQ2JSPQ.mjs.map → chunk-CF45RDMD.mjs.map} +1 -1
- package/dist/{chunk-GQJDFLSL.js → chunk-DP2NOHCI.js} +2 -2
- package/dist/{chunk-GQJDFLSL.js.map → chunk-DP2NOHCI.js.map} +1 -1
- package/dist/chunk-EVIDNS22.mjs +2 -0
- package/dist/chunk-EVIDNS22.mjs.map +1 -0
- package/dist/chunk-G4V2KWTV.js +2 -0
- package/dist/chunk-G4V2KWTV.js.map +1 -0
- package/dist/{chunk-SXKJ26OA.mjs → chunk-GEBRXFT3.mjs} +2 -2
- package/dist/chunk-GWF3MRUP.js +2 -0
- package/dist/chunk-GWF3MRUP.js.map +1 -0
- package/dist/chunk-JA62KNAQ.js +2 -0
- package/dist/chunk-JA62KNAQ.js.map +1 -0
- package/dist/chunk-JHJ3ZZF4.mjs +2 -0
- package/dist/chunk-JHJ3ZZF4.mjs.map +1 -0
- package/dist/{chunk-WKE6ECID.mjs → chunk-UPAOIY4R.mjs} +2 -2
- package/dist/chunk-V5ECGBFW.js +5 -0
- package/dist/chunk-V5ECGBFW.js.map +1 -0
- package/dist/{chunk-SRQOFCMO.js → chunk-VNV5BD4X.js} +2 -2
- package/dist/{chunk-SRQOFCMO.js.map → chunk-VNV5BD4X.js.map} +1 -1
- package/dist/chunk-WJO5GSY3.mjs +5 -0
- package/dist/chunk-WJO5GSY3.mjs.map +1 -0
- package/dist/chunk-ZATPBYOA.js +2 -0
- package/dist/chunk-ZATPBYOA.js.map +1 -0
- package/dist/chunk-ZHTMK5TA.mjs +2 -0
- package/dist/chunk-ZHTMK5TA.mjs.map +1 -0
- package/dist/course.d.mts +13 -3
- package/dist/course.d.ts +13 -3
- package/dist/course.js +1 -1
- package/dist/course.js.map +1 -1
- package/dist/course.mjs +1 -1
- package/dist/course.mjs.map +1 -1
- package/dist/embed/analytics.js +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +41 -12
- package/dist/index.d.ts +41 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{instrument-BE8ktMUv.d.mts → instrument-eXaC8hc2.d.mts} +1 -1
- package/dist/{instrument-BE8ktMUv.d.ts → instrument-eXaC8hc2.d.ts} +1 -1
- package/dist/methods-AULQDKVS.mjs +2 -0
- package/dist/methods-OJEZREBK.css +2 -0
- package/dist/methods-OJEZREBK.css.map +1 -0
- package/dist/methods-PMH5VQ25.js +2 -0
- package/dist/{methods-WRONKK3D.js.map → methods-PMH5VQ25.js.map} +1 -1
- package/dist/returns.d.mts +19 -10
- package/dist/returns.d.ts +19 -10
- package/dist/returns.js +1 -1
- package/dist/returns.js.map +1 -1
- package/dist/returns.mjs +1 -1
- package/dist/{texts-tQtAGJCT.d.mts → texts-LGhuQfA9.d.mts} +28 -3
- package/dist/{texts-CIEFbJTN.d.ts → texts-m6XQGZ6w.d.ts} +28 -3
- package/dist/types-ClFCVzk_.d.ts +121 -0
- package/dist/types-D6LsoycW.d.mts +121 -0
- package/dist/viewer3d.css +1 -1
- package/dist/viewer3d.css.map +1 -1
- package/dist/viewer3d.mjs +1 -1
- package/package.json +2 -2
- package/dist/CartProvider-PDEV6GCV.css +0 -2
- package/dist/CartProvider-PDEV6GCV.css.map +0 -1
- package/dist/CartProvider-VGZMDVFJ.js +0 -2
- package/dist/CartProvider-ZY5OLTAF.mjs +0 -2
- package/dist/PanelModelFiles-RV7OHUUZ.mjs +0 -2
- package/dist/PanelModelFiles-RV7OHUUZ.mjs.map +0 -1
- package/dist/chunk-5AYH23UJ.mjs +0 -4
- package/dist/chunk-5AYH23UJ.mjs.map +0 -1
- package/dist/chunk-AGYS7Z6G.mjs +0 -2
- package/dist/chunk-AGYS7Z6G.mjs.map +0 -1
- package/dist/chunk-DPKWYLN7.mjs +0 -2
- package/dist/chunk-DPKWYLN7.mjs.map +0 -1
- package/dist/chunk-I3QXJJ7U.mjs +0 -2
- package/dist/chunk-I3QXJJ7U.mjs.map +0 -1
- package/dist/chunk-LL7ASBGY.js +0 -2
- package/dist/chunk-LL7ASBGY.js.map +0 -1
- package/dist/chunk-OZHXRKMX.js +0 -2
- package/dist/chunk-OZHXRKMX.js.map +0 -1
- package/dist/chunk-QERYM7RC.js +0 -2
- package/dist/chunk-QERYM7RC.js.map +0 -1
- package/dist/chunk-QXGK337V.mjs +0 -2
- package/dist/chunk-QXGK337V.mjs.map +0 -1
- package/dist/chunk-SULHGFYN.mjs +0 -2
- package/dist/chunk-WPOXLITY.js +0 -2
- package/dist/chunk-WPOXLITY.js.map +0 -1
- package/dist/chunk-Y5KWVTXT.js +0 -4
- package/dist/chunk-Y5KWVTXT.js.map +0 -1
- package/dist/methods-NJEP64AG.mjs +0 -2
- package/dist/methods-QAZED7TJ.css +0 -2
- package/dist/methods-QAZED7TJ.css.map +0 -1
- package/dist/methods-WRONKK3D.js +0 -2
- package/dist/types-DP1vxo5E.d.mts +0 -53
- package/dist/types-u8VwmC3j.d.ts +0 -53
- /package/dist/{CartProvider-ZY5OLTAF.mjs.map → CartProvider-RYAA3JDA.mjs.map} +0 -0
- /package/dist/{chunk-SXKJ26OA.mjs.map → chunk-GEBRXFT3.mjs.map} +0 -0
- /package/dist/{chunk-WKE6ECID.mjs.map → chunk-UPAOIY4R.mjs.map} +0 -0
- /package/dist/{methods-NJEP64AG.mjs.map → methods-AULQDKVS.mjs.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/panel/components/PanelLogin.tsx","../src/ui/card.tsx","../src/ui/email-code-login/EmailCodeLoginForm.tsx","../src/panel/login-adapter.ts","../src/panel/login-texts.ts","../src/panel/return-url.ts","../src/panel/components/PanelPage.tsx","../src/panel/hooks/useUrlSearchParams.ts","../src/panel/returns-appearance.ts","../src/panel/texts.ts","../src/panel/components/PanelNotifications.tsx","../src/panel/components/PanelOrderHistory.tsx","../src/panel/components/PanelPlans.tsx","../src/panel/components/PanelReturns.tsx","../src/panel/components/PanelProductGrid.tsx","../src/panel/components/products/texts.ts","../src/lib/render.text.tsx","../src/panel/components/PanelProductDetails.tsx","../src/panel/audio-player/AudioPlayer.tsx","../src/panel/LoadingIndicator.tsx","../src/panel/audio-player/hls-engine.ts","../src/panel/audio-player/media.session.coordinator.ts","../src/panel/audio-player/texts.ts","../src/panel/audio-player/storage.ts","../src/panel/audio-player/ChapterList.tsx","../src/panel/components/model-files-load.ts","../src/panel/components/PanelProductHeader.tsx","../src/panel/components/nav/items.ts","../src/panel/components/PanelProfile.tsx","../src/panel/components/LazyPanelCourse.tsx","../src/panel/components/PublicOrderPage.tsx","../src/components/checkout/CartProvider.tsx","../src/public.api.client.ts","../src/components/checkout/frontent.analytics.ts","../src/components/checkout/lib/round.number.ts","../src/components/checkout/google.pay.mapper.ts","../src/components/checkout/helper.methods.ts","../src/components/checkout/lib/err.ts","../src/components/checkout/cart-items.ts","../src/components/checkout/state.ts","../src/components/checkout/texts.context.tsx","../src/components/checkout/pending-order.ts","../src/components/checkout/buy-error.ts","../src/components/checkout/payment-method.ts","../src/components/checkout/methods.ts"],"sourcesContent":["import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { useEffect, useMemo, type CSSProperties } from \"react\";\nimport {\n InstrumentProvider,\n useInstrument,\n useInstrumentContext,\n type AnalyticsOption,\n} from \"../../analytics/instrument\";\nimport { getLocale } from \"../../components/checkout/locale\";\nimport { rpcProvider, useMutation } from \"../../rpc-provider\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"../../ui/card\";\nimport { kindFromRpcError } from \"../../ui/email-code-login/errors\";\nimport {\n LoginBrandLogo,\n type LoginLogoOptions,\n} from \"../../ui/email-code-login/LoginBrandLogo\";\nimport { EmailCodeLoginForm } from \"../../ui/email-code-login/EmailCodeLoginForm\";\nimport { pendingLoginKey } from \"../../ui/email-code-login/pending\";\nimport {\n useEmailCodeLogin,\n type EmailCodeAdapter,\n} from \"../../ui/email-code-login/useEmailCodeLogin\";\nimport {\n getAllowedReturnOrigins,\n setAllowedReturnOrigins,\n} from \"../config\";\nimport { panelFailureKind } from \"../login-adapter\";\nimport { resolvePanelLoginTexts, type PanelLoginTexts } from \"../login-texts\";\nimport { usePanelConfig } from \"../PanelProvider\";\nimport type { PanelLoginProps } from \"../types\";\nimport {\n buildAccessTokenRedirect,\n getReturnURLFromSearch,\n persistReturnURL,\n readPersistedReturnURL,\n} from \"../return-url\";\nimport { getPanelSession, savePanelSession } from \"../session-storage\";\n\nif (typeof window !== \"undefined\") {\n const currentOrigin = window.location.origin;\n const knownSiblings = [\n currentOrigin,\n \"https://bitsnap.pl\",\n \"https://kursy.bitsnap.pl\",\n ];\n if (getAllowedReturnOrigins().length === 0) {\n setAllowedReturnOrigins(Array.from(new Set(knownSiblings)));\n }\n}\n\n\n/** Props of {@link PanelLogin}; `PanelLoginProps` of the package is a superset. */\nexport type PanelLoginComponentProps = Pick<\n PanelLoginProps,\n \"analytics\" | \"texts\" | \"locale\" | \"showLogo\" | \"logoUrl\" | \"logoDarkUrl\"\n>;\n\ntype PanelLoginResult = { accessToken: string };\n\nconst PanelLoginForm = ({\n texts,\n projectID,\n host,\n locale,\n logo,\n}: {\n texts: PanelLoginTexts;\n projectID?: string;\n host?: string;\n locale?: string;\n logo: LoginLogoOptions;\n}) => {\n const instrument = useInstrumentContext();\n const { mutateAsync: loginUserAsync } = useMutation(\n rpcProvider.publicApi.userPanelLogin,\n );\n const { mutateAsync: verifyCodeAsync } = useMutation(\n rpcProvider.publicApi.userPanelLoginWithCode,\n );\n\n const adapter = useMemo<EmailCodeAdapter<PanelLoginResult>>(\n () => ({\n async send(email) {\n try {\n const response = await loginUserAsync({ email });\n if (response.result.case === \"success\") {\n return {\n ok: true,\n retryIn: response.result.value.retryIn || undefined,\n challengeId: response.result.value.challengeId || undefined,\n };\n }\n return {\n ok: false,\n kind: panelFailureKind(\n response.result.case === \"failure\" ? response.result.value : 0,\n ),\n };\n } catch (cause) {\n return { ok: false, kind: kindFromRpcError(cause), cause };\n }\n },\n async verify({ email, code, challengeId }) {\n try {\n const response = await verifyCodeAsync({\n code: parseInt(code, 10),\n email,\n challengeId,\n });\n if (response.result.case === \"accessToken\" && response.result.value) {\n return { ok: true, value: { accessToken: response.result.value } };\n }\n return {\n ok: false,\n kind: panelFailureKind(\n response.result.case === \"failure\" ? response.result.value : 0,\n ),\n };\n } catch (cause) {\n return { ok: false, kind: kindFromRpcError(cause), cause };\n }\n },\n }),\n [loginUserAsync, verifyCodeAsync],\n );\n\n const login = useEmailCodeLogin<PanelLoginResult>({\n adapter,\n texts,\n storageKey: pendingLoginKey(\"panel\", projectID, host),\n onVerified: ({ accessToken }, email) => {\n instrument.track(\"panel_login\", {});\n savePanelSession(projectID, accessToken, email, host);\n const returnURL =\n typeof window !== \"undefined\" ? readPersistedReturnURL() : null;\n setTimeout(() => {\n if (returnURL) {\n window.location.href = buildAccessTokenRedirect(returnURL, accessToken);\n return;\n }\n window.location.reload();\n }, 100);\n },\n });\n\n const onCodeStep = login.step === \"code\";\n const title = onCodeStep && !login.needsEmail ? texts.codeTitle : texts.title;\n const description =\n onCodeStep && !login.needsEmail ? texts.codeDescription : texts.description;\n\n return (\n // Top-aligned: a vertically centred card moved when the step changed height.\n <main className=\"mx-auto flex w-full max-w-sm flex-1 flex-col justify-start pt-4 sm:pt-[12vh]\">\n <Card>\n <LoginBrandLogo\n projectId={projectID}\n locale={locale}\n className=\"px-4 sm:px-6\"\n {...logo}\n />\n <CardHeader className=\"px-4 sm:px-6\">\n <CardTitle role=\"heading\" aria-level={1} className=\"text-2xl\">\n {title}\n </CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent className=\"px-4 sm:px-6\">\n <EmailCodeLoginForm\n login={login}\n texts={texts}\n emailInputId=\"email\"\n codeInputId=\"verify-code\"\n />\n </CardContent>\n </Card>\n </main>\n );\n};\n\nconst PanelLoginComponentWrapper = ({\n analytics,\n texts: textOverrides,\n locale,\n showLogo,\n logoUrl,\n logoDarkUrl,\n}: PanelLoginComponentProps) => {\n const { theme, allowedReturnOrigins, projectID, host } = usePanelConfig();\n const instrument = useInstrument(projectID, analytics, \"panel\");\n const texts = useMemo(\n () => resolvePanelLoginTexts(locale ?? getLocale(), textOverrides),\n [locale, textOverrides],\n );\n\n const styles = {\n \"--button-background-color\": theme?.colors?.brand ?? \"#FFFFFF\",\n \"--button-background-color-dark\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color-dark\": theme?.colors?.brand ?? \"#FFFFFF\",\n } as CSSProperties;\n\n const [parent] = useAutoAnimate({\n duration: 300,\n easing: \"ease-in-out\",\n disrespectUserMotionPreference: false,\n });\n\n // Already signed in: leave the login page. Declared before the return URL\n // effect below, so that one (a token redirect) wins when both apply.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (getPanelSession(projectID, host) != null) {\n window.location.href = window.location.href.replaceAll(\"login\", \"\");\n }\n }, [projectID, host]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (window.parent !== window) return;\n\n const queryReturnURL = getReturnURLFromSearch(window.location.search);\n if (queryReturnURL) {\n persistReturnURL(queryReturnURL);\n }\n\n const returnURL = queryReturnURL ?? readPersistedReturnURL();\n if (!returnURL) return;\n\n const existingToken = getPanelSession(projectID, host);\n if (!existingToken) return;\n\n window.location.href = buildAccessTokenRedirect(returnURL, existingToken);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [allowedReturnOrigins, projectID, host]);\n\n return (\n <InstrumentProvider value={instrument}>\n <div className=\"bg-white text-black dark:bg-black dark:text-white\">\n <div\n className=\"font-inter flex min-h-screen w-full flex-col p-4\"\n style={styles}\n ref={parent}\n >\n <PanelLoginForm\n texts={texts}\n projectID={projectID}\n host={host}\n locale={locale}\n logo={{\n showLogo,\n logoUrl: logoUrl ?? theme?.logoURL,\n logoDarkUrl: logoDarkUrl ?? theme?.logoDarkURL,\n }}\n />\n </div>\n </div>\n </InstrumentProvider>\n );\n};\n\nexport const PanelLogin = (props: PanelLoginComponentProps = {}) => {\n return <PanelLoginComponentWrapper {...props} />;\n};\n","import * as React from \"react\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","import { CircleCheck } from \"lucide-react\";\nimport { useId, type FormEvent, type ReactNode } from \"react\";\nimport { cn } from \"@/src/lib/utils\";\nimport { Button } from \"../button\";\nimport { Input } from \"../input\";\nimport { Label } from \"../label\";\nimport { Spinner } from \"../spinner\";\nimport { OtpCodeField } from \"./OtpCodeField\";\nimport { fillText, type EmailCodeTexts } from \"./texts\";\nimport { type EmailCodeLogin } from \"./useEmailCodeLogin\";\n\nexport type EmailCodeLoginFormProps = {\n login: EmailCodeLogin;\n texts: EmailCodeTexts;\n /** Offers \"I already have a code\" under the e-mail step. */\n allowHaveCode?: boolean;\n /** Overrides the e-mail input placeholder. */\n emailPlaceholder?: string;\n /** `id` of the e-mail input; unique per instance by default. */\n emailInputId?: string;\n /** `id` of the code input; unique per instance by default. */\n codeInputId?: string;\n className?: string;\n /** Classes of the two primary buttons (brand colors). */\n buttonClassName?: string;\n /** Shown above the fields of the code step, after the \"sent to\" line. */\n children?: ReactNode;\n};\n\nconst MUTED = \"text-muted-foreground text-xs leading-5\";\n/** Borders of the dark theme: the `input` token is nearly the card colour. */\nconst DARK_FIELD =\n \"dark:border-foreground/30 dark:focus-visible:border-foreground/70 dark:focus-visible:ring-foreground/25 dark:aria-invalid:border-destructive-foreground dark:aria-invalid:ring-destructive-foreground/30\";\n/** Failures about the address itself; a throttled or failed send is not. */\nconst EMAIL_FAILURES = new Set([\"invalidEmail\", \"emailNotFound\", \"deliveryUnavailable\"]);\nconst LINK =\n \"inline-flex min-h-11 items-center px-1 text-sm underline underline-offset-4 hover:no-underline focus-visible:ring-[3px] focus-visible:ring-ring/50 rounded-sm outline-none disabled:opacity-50 disabled:no-underline\";\n\n/**\n * The two steps of the shared e-mail-code login. Markup only: all state comes\n * from {@link useEmailCodeLogin}. The surface wraps it in its own card or\n * dialog and renders the titles.\n */\nexport function EmailCodeLoginForm({\n login,\n texts,\n allowHaveCode = true,\n emailPlaceholder,\n emailInputId,\n codeInputId,\n className,\n buttonClassName,\n children,\n}: EmailCodeLoginFormProps) {\n const uid = useId();\n const emailId = emailInputId ?? `${uid}-email`;\n const codeId = codeInputId ?? `${uid}-code`;\n const noticeId = `${uid}-notice`;\n const hintId = `${uid}-hint`;\n\n const { notice } = login;\n const isError = notice?.kind === \"error\";\n const sending = login.busy === \"send\";\n const verifying = login.busy === \"verify\";\n const resending = login.busy === \"resend\";\n const buttonBase = cn(\"h-11 w-full\", buttonClassName);\n\n // Both live regions stay mounted (empty) so that a screen reader has\n // registered them before a message is put in; only their text changes.\n // The area reserves two lines, so a longer message does not push the buttons.\n const success = notice?.kind === \"success\";\n const noticeArea = (\n <div id={noticeId} className=\"min-h-10 text-sm leading-5\">\n <p\n role=\"alert\"\n className=\"font-medium text-red-700 dark:text-red-400\"\n >\n {isError ? notice.text : null}\n </p>\n <p\n role=\"status\"\n className={cn(\n \"flex items-start gap-1.5\",\n success\n ? \"font-medium text-emerald-700 dark:text-emerald-400\"\n : \"text-foreground\",\n )}\n >\n {success && <CircleCheck aria-hidden className=\"mt-0.5 size-4 shrink-0\" />}\n <span>{notice != null && !isError ? notice.text : null}</span>\n </p>\n </div>\n );\n const emailInvalid =\n isError &&\n login.step === \"email\" &&\n (notice.failure == null || EMAIL_FAILURES.has(notice.failure));\n\n const announcer = (\n <p className=\"sr-only\" role=\"status\" aria-live=\"polite\">\n {login.announcement}\n </p>\n );\n\n const emailField = (\n <div className=\"grid gap-2\">\n <Label htmlFor={emailId}>{texts.emailLabel}</Label>\n <Input\n id={emailId}\n ref={login.emailRef}\n name=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n inputMode=\"email\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck={false}\n autoFocus\n required\n className={cn(\n \"h-11 text-base disabled:opacity-100 disabled:text-foreground/70\",\n DARK_FIELD,\n )}\n placeholder={emailPlaceholder ?? texts.emailPlaceholder}\n value={login.email}\n disabled={login.isBusy}\n aria-invalid={emailInvalid ? true : undefined}\n aria-describedby={noticeId}\n onChange={(event) => login.setEmail(event.target.value)}\n />\n </div>\n );\n\n if (login.step === \"email\") {\n return (\n <form\n noValidate\n className={cn(\"flex flex-col gap-4\", className)}\n onSubmit={(event: FormEvent) => {\n event.preventDefault();\n void login.sendCode();\n }}\n >\n {announcer}\n {emailField}\n {noticeArea}\n <Button\n type=\"submit\"\n disabled={login.isBusy}\n aria-busy={sending}\n className={buttonBase}\n >\n {sending && <Spinner aria-hidden />}\n {sending ? texts.sending : texts.sendCode}\n </Button>\n {allowHaveCode && (\n <p className=\"flex flex-wrap items-center justify-center text-center text-sm\">\n {texts.haveCodePrompt !== \"\" && <span>{texts.haveCodePrompt}</span>}\n <button\n type=\"button\"\n className={LINK}\n disabled={login.isBusy}\n onClick={login.haveCode}\n >\n {texts.haveCode}\n </button>\n </p>\n )}\n </form>\n );\n }\n\n const [before, after] = texts.codeSentTo.split(\"{email}\");\n const dead = login.dead != null;\n const resendLabel = dead\n ? texts.resendNew\n : login.secondsLeft > 0\n ? fillText(texts.resendIn, { seconds: login.secondsLeft })\n : texts.resend;\n\n return (\n <form\n noValidate\n className={cn(\"flex flex-col gap-4\", className)}\n onSubmit={(event: FormEvent) => {\n event.preventDefault();\n void login.submitCode();\n }}\n >\n {announcer}\n {login.needsEmail ? (\n emailField\n ) : (\n <div className=\"flex flex-wrap items-center justify-between gap-x-2\">\n {/* The address moves to its own line before it is cut; the word\n joiner keeps the full stop with it. */}\n <p className=\"min-w-0 flex-[1_1_14rem] text-sm leading-5 break-words\">\n {before}\n <strong className=\"font-semibold\">{login.email}</strong>\n {\"\\u2060\"}\n {after}\n </p>\n <button\n type=\"button\"\n className={cn(LINK, \"-ml-1 shrink-0\")}\n disabled={login.isBusy}\n onClick={login.changeEmail}\n >\n {texts.changeEmail}\n </button>\n </div>\n )}\n {children}\n <div className=\"grid gap-2\">\n <Label htmlFor={codeId}>{texts.codeLabel}</Label>\n <OtpCodeField\n id={codeId}\n name=\"code\"\n inputRef={login.codeRef}\n value={login.code}\n onChange={login.setCode}\n onComplete={(value) => void login.submitCode(value)}\n disabled={login.isBusy || dead}\n invalid={isError && !login.needsEmail}\n aria-describedby={`${noticeId} ${hintId}`}\n />\n <p id={hintId} className={MUTED}>\n {texts.validity} {texts.spamHint}\n </p>\n </div>\n {noticeArea}\n <Button\n type=\"submit\"\n disabled={login.isBusy || dead}\n aria-busy={verifying}\n className={buttonBase}\n >\n {verifying && <Spinner aria-hidden />}\n {verifying ? texts.verifying : texts.verify}\n </Button>\n {login.needsEmail ? (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n className={LINK}\n disabled={login.isBusy}\n onClick={login.changeEmail}\n >\n {texts.noCode}\n </button>\n </div>\n ) : (\n <Button\n type=\"button\"\n variant={dead ? \"default\" : \"outline\"}\n disabled={login.isBusy || (!dead && login.secondsLeft > 0)}\n aria-busy={resending}\n className={dead ? buttonBase : \"h-11 w-full\"}\n onClick={() => void login.resend()}\n >\n {resending && <Spinner aria-hidden />}\n {resendLabel}\n </Button>\n )}\n </form>\n );\n}\n","import { FailureMessage } from \"../gen/proto/public/v1/public_api_pb\";\nimport type { FailureKind } from \"../ui/email-code-login/useEmailCodeLogin\";\n\n/**\n * Kind of failure for each `FailureMessage` the login RPCs return. Every\n * value has an answer, so the customer never sees \"Nieprawidłowy adres email\"\n * for a mistyped code or a throttled request.\n */\nexport function panelFailureKind(failure: FailureMessage): FailureKind {\n switch (failure) {\n case FailureMessage.EMAIL_NOT_FOUND:\n return \"emailNotFound\";\n case FailureMessage.INCORRECT_EMAIL:\n return \"invalidEmail\";\n case FailureMessage.INCORRECT_CODE:\n return \"wrongCode\";\n case FailureMessage.CODE_EXPIRED:\n return \"expired\";\n case FailureMessage.TOO_MANY_ATTEMPTS:\n return \"tooManyAttempts\";\n case FailureMessage.RATE_LIMITED:\n return \"rateLimited\";\n case FailureMessage.DELIVERY_FAILED:\n return \"deliveryFailed\";\n case FailureMessage.DELIVERY_METHOD_UNAVAILABLE:\n return \"deliveryUnavailable\";\n default:\n return \"unknown\";\n }\n}\n","import { pickLocaleTable, type LocaleTables } from \"../lib/texts\";\nimport { getLocale } from \"../components/checkout/locale\";\nimport {\n resolveEmailCodeTexts,\n type EmailCodeTexts,\n} from \"../ui/email-code-login/texts\";\n\n/** Strings of `PanelLogin`: the shared login texts plus the two titles. */\nexport type PanelLoginTexts = EmailCodeTexts & {\n title: string;\n description: string;\n codeTitle: string;\n codeDescription: string;\n};\n\ntype TitleKey = \"title\" | \"description\" | \"codeTitle\" | \"codeDescription\";\n\nconst TITLES: LocaleTables<TitleKey> = {\n pl: {\n title: \"Zaloguj się\",\n description: \"Wyślemy do Ciebie kod na maila, dzięki któremu się zalogujesz.\",\n codeTitle: \"Wpisz kod z maila\",\n codeDescription: \"Kod ma 6 cyfr.\",\n },\n en: {\n title: \"Sign in\",\n description: \"We will email you a code that signs you in.\",\n codeTitle: \"Enter the code from the email\",\n codeDescription: \"The code has 6 digits.\",\n },\n};\n\n/** Panel login texts: Polish unless the locale starts with `en`, then overrides. */\nexport function resolvePanelLoginTexts(\n locale: string = getLocale(),\n overrides?: Partial<PanelLoginTexts>,\n): PanelLoginTexts {\n return {\n ...resolveEmailCodeTexts(locale, overrides),\n ...pickLocaleTable(TITLES, locale),\n ...definedOnly(overrides, [\"title\", \"description\", \"codeTitle\", \"codeDescription\"]),\n };\n}\n\nfunction definedOnly<K extends TitleKey>(\n overrides: Partial<PanelLoginTexts> | undefined,\n keys: K[],\n): Partial<Record<K, string>> {\n const result: Partial<Record<K, string>> = {};\n for (const key of keys) {\n const value = overrides?.[key];\n if (value != null) result[key] = value;\n }\n return result;\n}\n","import { getAllowedReturnOrigins } from \"./config\";\n\nconst RETURN_URL_PARAM = \"return_url\";\nconst RETURN_URL_STORAGE_KEY = \"__return_url\";\nconst ACCESS_TOKEN_PARAM = \"accessToken\";\n\nexport function getReturnURLFromSearch(search: string): string | null {\n const raw = new URLSearchParams(search).get(RETURN_URL_PARAM);\n if (!raw) return null;\n return validateReturnURL(raw);\n}\n\nexport function persistReturnURL(returnURL: string | null): void {\n if (typeof window === \"undefined\") return;\n if (returnURL) {\n window.sessionStorage.setItem(RETURN_URL_STORAGE_KEY, returnURL);\n } else {\n window.sessionStorage.removeItem(RETURN_URL_STORAGE_KEY);\n }\n}\n\nexport function readPersistedReturnURL(): string | null {\n if (typeof window === \"undefined\") return null;\n const stored = window.sessionStorage.getItem(RETURN_URL_STORAGE_KEY);\n if (!stored) return null;\n return validateReturnURL(stored);\n}\n\nfunction isOriginAllowed(origin: string, allowedOrigins: string[]): boolean {\n return allowedOrigins.some((allowed) => {\n if (origin === allowed) return true;\n const allowedHost = new URL(allowed).hostname;\n const originHost = new URL(origin).hostname;\n return originHost.endsWith(`.${allowedHost}`) || originHost === allowedHost;\n });\n}\n\nfunction validateReturnURL(raw: string): string | null {\n try {\n const u = new URL(raw);\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n if (!isOriginAllowed(u.origin, getAllowedReturnOrigins())) return null;\n return u.toString();\n } catch {\n return null;\n }\n}\n\nexport function buildAccessTokenRedirect(\n returnURL: string,\n accessToken: string,\n): string {\n const u = new URL(returnURL);\n u.searchParams.set(ACCESS_TOKEN_PARAM, accessToken);\n return u.toString();\n}\n","import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\nimport { rpcProvider, useMutation } from \"../../rpc-provider\";\nimport { useUrlSearchParams } from \"../hooks/useUrlSearchParams\";\nimport { InstrumentProvider, useInstrument } from \"../../analytics/instrument\";\nimport { usePanelConfig } from \"../PanelProvider\";\nimport { resolvePanelReturnsAppearance } from \"../returns-appearance\";\nimport type { PanelProps } from \"../types\";\nimport {\n buildAccessTokenRedirect,\n getReturnURLFromSearch,\n persistReturnURL,\n readPersistedReturnURL,\n} from \"../return-url\";\n\nimport PanelNotificationsComponent from \"./PanelNotifications\";\nimport PanelOrderHistoryComponent from \"./PanelOrderHistory\";\nimport PanelPlansComponent from \"./PanelPlans\";\nimport PanelReturnsComponent from \"./PanelReturns\";\nimport PanelProductGridComponent from \"./PanelProductGrid\";\nimport PanelProductHeaderComponent from \"./PanelProductHeader\";\nimport PanelProfileComponent from \"./PanelProfile\";\nimport LazyPanelCourse from \"./LazyPanelCourse\";\nimport PublicOrderPage from \"./PublicOrderPage\";\nimport { clearPanelSession, getPanelEmail, getPanelSession } from \"../session-storage\";\n\nexport type PanelScreen =\n | \"products\"\n | \"notifications\"\n | \"profile\"\n | \"plans\"\n | \"orders\"\n | \"order-details\"\n | \"returns\"\n | \"return-details\"\n | \"course\";\n\nexport type PanelSearchParamsType = {\n product?: string;\n state: PanelScreen;\n orderId?: string;\n returnId?: string;\n /** `state: \"course\"`: `UserProduct.accessId` of the open course. */\n course?: string;\n /** `state: \"course\"`: id of the open lesson or test. */\n item?: string;\n};\n\nconst PanelPage = ({\n returnsAppearance,\n returnsTexts,\n analytics,\n}: Pick<PanelProps, \"returnsAppearance\" | \"returnsTexts\" | \"analytics\"> = {}) => {\n const { projectID, theme, loginURL, host } = usePanelConfig();\n const [, refreshLocale] = useState(0);\n const instrument = useInstrument(projectID, analytics, \"panel\");\n\n const accessToken = getPanelSession(projectID, host);\n const email = getPanelEmail(projectID, host);\n\n const { mutateAsync: logoutUserAsync } = useMutation(\n rpcProvider.publicApi.userPanelLogout,\n );\n\n async function logout() {\n if (accessToken) {\n await logoutUserAsync({\n accessToken: accessToken as string,\n });\n }\n if (typeof window !== \"undefined\") {\n clearPanelSession(projectID, host);\n window.location.reload();\n }\n }\n\n const [panelParentRef] = useAutoAnimate();\n const isScreen = (value: unknown): value is PanelScreen =>\n [\n \"products\",\n \"notifications\",\n \"profile\",\n \"plans\",\n \"orders\",\n \"order-details\",\n \"returns\",\n \"return-details\",\n \"course\",\n ].includes(value as string);\n\n const [params, setParams] = useUrlSearchParams<PanelSearchParamsType>({\n product: undefined,\n state: \"products\",\n orderId: undefined,\n returnId: undefined,\n course: undefined,\n item: undefined,\n });\n\n const [activeScreen, setActiveScreen] = useState<PanelScreen>(\n isScreen(params.state) ? params.state : \"products\",\n );\n\n const handleOpenOrderDetails = (orderID: string) => {\n setParams({\n state: \"order-details\",\n orderId: orderID,\n });\n setActiveScreen(\"order-details\");\n };\n\n const handleBackToOrders = () => {\n setParams({\n state: \"orders\",\n orderId: undefined,\n });\n setActiveScreen(\"orders\");\n };\n\n // Navigation starts a screen from scratch, so ids of the previous screen\n // must not leak into it.\n const navigate = (next: { product?: string; state: PanelScreen }) =>\n setParams({\n orderId: undefined,\n returnId: undefined,\n course: undefined,\n item: undefined,\n ...next,\n });\n\n const handleOpenCourse = (accessId: string) => {\n setParams({\n state: \"course\",\n course: accessId,\n item: undefined,\n product: undefined,\n });\n setActiveScreen(\"course\");\n };\n\n const handleLeaveCourse = () => {\n setParams({\n state: \"products\",\n course: undefined,\n item: undefined,\n product: undefined,\n });\n setActiveScreen(\"products\");\n };\n\n // The browser's back and forward buttons move between the lessons of a\n // course and in and out of it.\n useEffect(() => {\n if (!isScreen(params.state)) return;\n if (params.state === \"course\" || activeScreen === \"course\") {\n setActiveScreen(params.state);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [params.state]);\n\n const styles = {\n \"--button-background-color\": theme?.colors?.brand ?? \"#000000\",\n \"--button-background-color-dark\": theme?.colors?.brandDark ?? \"#ffffff\",\n \"--button-text-color\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color-dark\": theme?.colors?.brand ?? \"#000000\",\n } as CSSProperties;\n\n useEffect(() => {\n if (accessToken == null || accessToken.length === 0) {\n window.location.href = loginURL ?? \"/panel/login\";\n return;\n }\n }, []);\n\n useEffect(() => {\n if (accessToken == null || accessToken.length === 0) {\n window.location.href = loginURL ?? \"/panel/login\";\n return;\n }\n }, [activeScreen]);\n\nuseEffect(() => {\n if (typeof window === \"undefined\") return;\n if (window.parent !== window) return;\n if (!accessToken) return;\n\n const queryReturnURL = getReturnURLFromSearch(window.location.search);\n if (queryReturnURL) {\n persistReturnURL(queryReturnURL);\n }\n\n const returnURL = queryReturnURL ?? readPersistedReturnURL();\n if (!returnURL) return;\n\n window.location.href = buildAccessTokenRedirect(returnURL, accessToken);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [accessToken]);\n\n return (\n <InstrumentProvider value={instrument}>\n <div\n ref={panelParentRef}\n className=\"font-inter relative flex h-dvh w-full flex-col bg-beige-100 text-black dark:bg-black dark:text-white md:flex-row\"\n >\n <PanelProductHeaderComponent\n activeScreen={activeScreen}\n setActiveScreen={setActiveScreen}\n setParams={navigate}\n styles={styles}\n theme={theme}\n logout={logout}\n email={email}\n projectID={projectID}\n />\n\n <main className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto w-full p-5 pb-[calc(76px+env(safe-area-inset-bottom))] md:pb-5\">\n {activeScreen === \"products\" && (\n <PanelProductGridComponent\n projectID={projectID ?? \"\"}\n accessToken={accessToken!}\n loginURL={loginURL ?? \"/panel/login\"}\n styles={styles}\n activeScreen={activeScreen}\n params={params as PanelSearchParamsType}\n setParams={setParams}\n openCourse={handleOpenCourse}\n />\n )}\n\n {activeScreen === \"course\" && params.course && accessToken && (\n <LazyPanelCourse\n accessId={params.course}\n accessToken={accessToken}\n theme={theme}\n itemId={params.item}\n onItemChange={(item) => setParams({ item })}\n onBack={handleLeaveCourse}\n />\n )}\n\n {activeScreen === \"notifications\" && <PanelNotificationsComponent />}\n\n {activeScreen === \"plans\" && (\n <PanelPlansComponent projectID={projectID ?? \"\"} />\n )}\n\n {activeScreen === \"orders\" && (\n <PanelOrderHistoryComponent\n projectID={projectID ?? \"\"}\n accessToken={accessToken ?? \"\"}\n openOrderDetails={handleOpenOrderDetails}\n />\n )}\n\n {activeScreen === \"order-details\" && params.orderId && (\n <PublicOrderPage\n orderID={params.orderId}\n onBack={handleBackToOrders}\n />\n )}\n\n {(activeScreen === \"returns\" || activeScreen === \"return-details\") &&\n accessToken && (\n <PanelReturnsComponent\n projectID={projectID ?? \"\"}\n host={host}\n accessToken={accessToken}\n loginURL={loginURL ?? \"/panel/login\"}\n appearance={resolvePanelReturnsAppearance(\n returnsAppearance,\n theme?.colors?.brand,\n )}\n texts={returnsTexts}\n screen={activeScreen}\n params={params as PanelSearchParamsType}\n setParams={setParams}\n setActiveScreen={setActiveScreen}\n />\n )}\n\n {activeScreen === \"profile\" && (\n <PanelProfileComponent\n email={email}\n logout={logout}\n onLocaleChange={() => refreshLocale(value => value + 1)}\n />\n )}\n </main>\n </div>\n </InstrumentProvider>\n );\n};\n\nexport default PanelPage;\n","import { useState, useCallback, useEffect } from \"react\";\n\nexport function useUrlSearchParams<T extends Record<string, unknown>>(\n initialValue: T,\n): [T, (params: Partial<T>) => void] {\n const [params, setParams] = useState<T>(() => {\n if (typeof window === \"undefined\") {\n return initialValue;\n }\n const urlParams = new URLSearchParams(window.location.search);\n const parsed: Partial<T> = {};\n \n (Object.keys(initialValue) as Array<keyof T>).forEach((key) => {\n const value = urlParams.get(key as string);\n if (value !== null) {\n try {\n (parsed as Record<string, unknown>)[key as string] = JSON.parse(value);\n } catch {\n (parsed as Record<string, unknown>)[key as string] = value as T[keyof T];\n }\n }\n });\n \n return { ...initialValue, ...parsed };\n });\n\n const updateParams = useCallback((newParams: Partial<T>) => {\n setParams((prev) => {\n const updated = { ...prev, ...newParams };\n \n if (typeof window !== \"undefined\") {\n const urlParams = new URLSearchParams();\n (Object.keys(updated) as Array<keyof T>).forEach((key) => {\n const value = updated[key];\n if (value !== undefined && value !== null) {\n urlParams.set(key as string, JSON.stringify(value));\n }\n });\n \n const newUrl = `${window.location.pathname}?${urlParams.toString()}`;\n window.history.pushState({}, \"\", newUrl);\n }\n \n return updated;\n });\n }, []);\n\n useEffect(() => {\n const handlePopState = () => {\n const urlParams = new URLSearchParams(window.location.search);\n const parsed: Partial<T> = {};\n \n (Object.keys(initialValue) as Array<keyof T>).forEach((key) => {\n const value = urlParams.get(key as string);\n if (value !== null) {\n try {\n (parsed as Record<string, unknown>)[key as string] = JSON.parse(value);\n } catch {\n (parsed as Record<string, unknown>)[key as string] = value as T[keyof T];\n }\n }\n });\n \n setParams({ ...initialValue, ...parsed });\n };\n\n window.addEventListener(\"popstate\", handlePopState);\n return () => window.removeEventListener(\"popstate\", handlePopState);\n }, [initialValue]);\n\n return [params, updateParams];\n}\n","import type { ReturnsAppearance } from \"../components/returns/appearance\";\nimport { brandColorTokens, readableForeground } from \"../components/returns/color\";\n\nexport { readableForeground };\n\n/**\n * Returns appearance of the panel Returns screen derived from the panel brand\n * color. An explicit appearance wins; without a brand color the library\n * defaults apply (`undefined`).\n */\nexport function resolvePanelReturnsAppearance(\n explicit: ReturnsAppearance | undefined,\n brand: string | undefined,\n): ReturnsAppearance | undefined {\n if (explicit != null) {\n return explicit;\n }\n const color = brand?.trim();\n if (color == null || color === \"\") {\n return undefined;\n }\n return { tokens: brandColorTokens(color) };\n}\n","import { getLocale } from \"../components/checkout/locale\";\nimport { pickLocaleTable, type LocaleTables } from \"../lib/texts\";\n\n/** Panel strings that are not part of the returns views. */\nexport type PanelTexts = {\n returnsNavLabel: string;\n openCourse: string;\n libraryNavLabel: string;\n ordersNavLabel: string;\n accountNavLabel: string;\n navigationLabel: string;\n logout: string;\n profileHeading: string;\n emailLabel: string;\n noData: string;\n languageLabel: string;\n polishLanguage: string;\n englishLanguage: string;\n plansHeading: string;\n plansUnavailable: string;\n notificationsHeading: string;\n notificationsUnavailable: string;\n ordersHeading: string;\n ordersDescription: string;\n ordersEmpty: string;\n ordersError: string;\n retry: string;\n orderLabel: string;\n customerLabel: string;\n dateLabel: string;\n ordersEnd: string;\n previousPage: string;\n nextPage: string;\n paginationLabel: string;\n statusDraft: string;\n statusUnpaid: string;\n statusPaid: string;\n statusOverdue: string;\n statusCancelled: string;\n statusCompleted: string;\n statusProcessing: string;\n statusRefunded: string;\n};\n\nconst PANEL_TEXT_TABLES: LocaleTables<keyof PanelTexts> = {\n pl: {\n \"returnsNavLabel\": \"Zwroty\",\n \"openCourse\": \"Otwórz kurs\",\n \"libraryNavLabel\": \"Biblioteka\",\n \"ordersNavLabel\": \"Zamówienia\",\n \"accountNavLabel\": \"Konto\",\n \"navigationLabel\": \"Panel klienta\",\n \"logout\": \"Wyloguj się\",\n \"profileHeading\": \"Profil\",\n \"emailLabel\": \"E-mail\",\n \"noData\": \"Brak danych\",\n \"languageLabel\": \"Język\",\n \"polishLanguage\": \"Polski\",\n \"englishLanguage\": \"English\",\n \"plansHeading\": \"Plany\",\n \"plansUnavailable\": \"Plany nie są obecnie dostępne w panelu.\",\n \"notificationsHeading\": \"Powiadomienia\",\n \"notificationsUnavailable\": \"Ustawienia powiadomień nie są obecnie dostępne w panelu.\",\n \"ordersHeading\": \"Historia zamówień\",\n \"ordersDescription\": \"Twoje zamówienia\",\n \"ordersEmpty\": \"Brak zamówień.\",\n \"ordersError\": \"Nie udało się pobrać zamówień.\",\n \"retry\": \"Spróbuj ponownie\",\n \"orderLabel\": \"Zamówienie\",\n \"customerLabel\": \"Klient\",\n \"dateLabel\": \"Data\",\n \"ordersEnd\": \"To już wszystkie Twoje zamówienia.\",\n \"previousPage\": \"Poprzednia strona\",\n \"nextPage\": \"Następna strona\",\n \"paginationLabel\": \"Strony zamówień\",\n \"statusDraft\": \"Szkic\",\n \"statusUnpaid\": \"Nieopłacone\",\n \"statusPaid\": \"Opłacone\",\n \"statusOverdue\": \"Zaległe\",\n \"statusCancelled\": \"Anulowane\",\n \"statusCompleted\": \"Zakończone\",\n \"statusProcessing\": \"Przetwarzane\",\n \"statusRefunded\": \"Zwrócone\"\n },\n en: {\n \"returnsNavLabel\": \"Returns\",\n \"openCourse\": \"Open the course\",\n \"libraryNavLabel\": \"Library\",\n \"ordersNavLabel\": \"Orders\",\n \"accountNavLabel\": \"Account\",\n \"navigationLabel\": \"Customer panel\",\n \"logout\": \"Log out\",\n \"profileHeading\": \"Profile\",\n \"emailLabel\": \"Email\",\n \"noData\": \"No data\",\n \"languageLabel\": \"Language\",\n \"polishLanguage\": \"Polski\",\n \"englishLanguage\": \"English\",\n \"plansHeading\": \"Plans\",\n \"plansUnavailable\": \"Plans are currently unavailable in the panel.\",\n \"notificationsHeading\": \"Notifications\",\n \"notificationsUnavailable\": \"Notification settings are currently unavailable in the panel.\",\n \"ordersHeading\": \"Order history\",\n \"ordersDescription\": \"Your orders\",\n \"ordersEmpty\": \"No orders yet.\",\n \"ordersError\": \"Could not load your orders.\",\n \"retry\": \"Try again\",\n \"orderLabel\": \"Order\",\n \"customerLabel\": \"Customer\",\n \"dateLabel\": \"Date\",\n \"ordersEnd\": \"You’ve reached the end of your orders.\",\n \"previousPage\": \"Previous page\",\n \"nextPage\": \"Next page\",\n \"paginationLabel\": \"Order pages\",\n \"statusDraft\": \"Draft\",\n \"statusUnpaid\": \"Unpaid\",\n \"statusPaid\": \"Paid\",\n \"statusOverdue\": \"Overdue\",\n \"statusCancelled\": \"Cancelled\",\n \"statusCompleted\": \"Completed\",\n \"statusProcessing\": \"Processing\",\n \"statusRefunded\": \"Refunded\"\n },\n};\n\n/** Panel strings for the library locale (`setLocale`), Polish by default. */\nexport function getPanelTexts(locale: string = getLocale()): PanelTexts {\n return pickLocaleTable(PANEL_TEXT_TABLES, locale);\n}\n","import { getPanelTexts } from \"../texts\";\n\nexport default function PanelNotifications({}: {}) {\n const texts = getPanelTexts();\n return <section>\n <h3 className=\"text-2xl\">{texts.notificationsHeading}</h3>\n <p className=\"mt-6 text-sm text-neutral-600 dark:text-neutral-400\">{texts.notificationsUnavailable}</p>\n </section>;\n}\n","import { getLocale } from \"../../components/checkout/locale\";\nimport { getPanelTexts } from \"../texts\";\nimport { Button } from \"../../ui/button\";\nimport { rpcProvider, useQuery } from \"../../rpc-provider\";\nimport { Skeleton } from \"../../ui/skeleton\";\nimport { useState } from \"react\";\n\ninterface PanelOrderHistoryComponentProps {\n projectID: string;\n accessToken: string;\n openOrderDetails: (orderId: string) => void;\n}\n\nconst formatDate = (ts: number): string =>\n new Date(ts * 1000).toLocaleDateString(getLocale(), {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n\nconst formatAmount = (amount: number, currency: string): string =>\n new Intl.NumberFormat(getLocale(), {\n style: \"currency\",\n currency: currency.toUpperCase(),\n }).format(amount / 100);\n\nconst statusColor: Record<string, string> = {\n draft: \"text-neutral-600 dark:text-neutral-400\",\n unpaid: \"text-amber-700 dark:text-amber-300\",\n paid: \"text-green-700 dark:text-green-400\",\n overdue: \"text-red-700 dark:text-red-400\",\n cancelled: \"text-neutral-600 line-through dark:text-neutral-400\",\n completed: \"text-green-700 dark:text-green-400\",\n processing: \"text-blue-700 dark:text-blue-400\",\n refunded: \"text-purple-700 dark:text-purple-400\",\n};\n\nfunction PanelOrderHistory({\n openOrderDetails,\n projectID,\n accessToken,\n}: PanelOrderHistoryComponentProps) {\n const texts = getPanelTexts();\n const statusLabel: Record<string, string> = {\n draft: texts.statusDraft,\n unpaid: texts.statusUnpaid,\n paid: texts.statusPaid,\n overdue: texts.statusOverdue,\n cancelled: texts.statusCancelled,\n completed: texts.statusCompleted,\n processing: texts.statusProcessing,\n refunded: texts.statusRefunded,\n };\n const [offset, setOffset] = useState(0);\n const limit = 20;\n\n const { data, isFetching, isError, refetch } = useQuery(rpcProvider.publicApi.getOrders, {\n projectId: projectID,\n accessToken,\n offset,\n limit,\n });\n\n const orders = data?.orders ?? [];\n const totalCount = data?.totalCount ?? 0;\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(totalCount / limit);\n\n const handlePageChange = (newOffset: number) => {\n setOffset(newOffset);\n };\n\n return (\n <>\n <h3 className=\"text-2xl\">{texts.ordersHeading}</h3>\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400\">\n {texts.ordersDescription}\n </p>\n\n {isFetching ? (\n <div className=\"mt-6 flex w-full flex-col gap-3\">\n {[...Array(5)].map((_, i) => (\n <div\n key={i}\n className=\"rounded-xl bg-white p-4 shadow-sm dark:bg-neutral-800\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"space-y-2\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-32\" />\n </div>\n <div className=\"space-y-2 text-right\">\n <Skeleton className=\"ml-auto h-4 w-16\" />\n <Skeleton className=\"ml-auto h-3 w-12\" />\n </div>\n </div>\n <div className=\"mt-3\">\n <Skeleton className=\"h-3 w-40\" />\n </div>\n </div>\n ))}\n </div>\n ) : isError ? (\n <div role=\"alert\" className=\"mt-6 space-y-3\">\n <p>{texts.ordersError}</p>\n <Button\n onClick={() => void refetch()}\n className=\"min-h-11 focus-visible:outline-2 focus-visible:outline-current\"\n >\n {texts.retry}\n </Button>\n </div>\n ) : orders.length === 0 ? (\n <div className=\"mt-6 text-sm text-neutral-600 dark:text-neutral-400\">{texts.ordersEmpty}</div>\n ) : (\n <div>\n <div className=\"mt-6 flex w-full flex-col gap-3\">\n {orders.map((order) => (\n <button\n key={order.id}\n onClick={() => openOrderDetails(order.id)}\n className=\"block min-h-11 focus-visible:outline-2 focus-visible:outline-current rounded-xl bg-white p-4 text-left shadow-sm transition-colors hover:bg-neutral-50 dark:bg-neutral-800 dark:hover:bg-neutral-700\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0 break-words\">\n <p className=\"font-medium\">{texts.orderLabel} #{order.id}</p>\n <p className=\"text-xs text-neutral-500 dark:text-neutral-400\">\n {order.customerName || texts.customerLabel}\n </p>\n </div>\n <div className=\"shrink-0 text-right\">\n <p className=\"font-semibold\">\n {formatAmount(order.totalAmount, order.currency)}\n </p>\n <p\n className={`text-xs font-medium ${statusColor[order.status] ?? \"text-neutral-400\"}`}\n >\n {statusLabel[order.status] ?? order.status}\n </p>\n </div>\n </div>\n\n <div className=\"mt-2 flex items-center justify-between gap-3 text-xs text-neutral-500 dark:text-neutral-400\">\n <span>\n {texts.dateLabel}:{\" \"}\n {order.createdAt\n ? formatDate(Number(order.createdAt.seconds))\n : \"-\"}\n </span>\n </div>\n </button>\n ))}\n </div>\n\n {currentPage >= totalPages && (\n <p className=\"mt-6 text-center text-sm text-neutral-600 dark:text-neutral-400\">\n {texts.ordersEnd}\n </p>\n )}\n {totalPages > 1 && (\n <nav\n aria-label={texts.paginationLabel}\n className=\"mt-4 flex flex-wrap items-center justify-center gap-2\"\n >\n {currentPage > 1 && (\n <Button variant=\"outline\" className=\"min-h-11\" onClick={() => handlePageChange(offset - limit)}>\n {texts.previousPage}\n </Button>\n )}\n {Array.from(new Set([1, currentPage - 1, currentPage, currentPage + 1, totalPages]))\n .filter(page => page > 0 && page <= totalPages)\n .sort((a, b) => a - b)\n .map(page => (\n <Button\n key={page}\n variant={page === currentPage ? \"secondary\" : \"ghost\"}\n className=\"min-h-11 min-w-11\"\n aria-current={page === currentPage ? \"page\" : undefined}\n onClick={() => handlePageChange((page - 1) * limit)}\n >\n {page}\n </Button>\n ))}\n {currentPage < totalPages && (\n <Button variant=\"outline\" className=\"min-h-11\" onClick={() => handlePageChange(offset + limit)}>\n {texts.nextPage}\n </Button>\n )}\n </nav>\n )}\n </div>\n )}\n </>\n );\n}\n\nexport default PanelOrderHistory;\n","import { getPanelTexts } from \"../texts\";\n\nexport default function PanelPlans({ projectID: _projectID }: { projectID: string }) {\n const texts = getPanelTexts();\n return <section>\n <h3 className=\"text-2xl\">{texts.plansHeading}</h3>\n <p className=\"mt-6 text-sm text-neutral-600 dark:text-neutral-400\">{texts.plansUnavailable}</p>\n </section>;\n}\n","import { useEffect, useState } from \"react\";\nimport {\n ReturnsConfirmation,\n ReturnsOrderDetail,\n ReturnsOrderList,\n ReturnsResult,\n} from \"../../components/returns/OrderSteps\";\nimport {\n ReturnsMyReturnDetail,\n ReturnsMyReturnsList,\n} from \"../../components/returns/MyReturns\";\nimport {\n ReturnsProvider,\n useReturnsContext,\n} from \"../../components/returns/ReturnsProvider\";\nimport { SkeletonRows } from \"../../components/returns/internal\";\nimport { isSessionExpiredError, mapReturnsError } from \"../../components/returns/errors\";\nimport { useReturnsText } from \"../../components/returns/texts.context\";\nimport type { SelectedReturnLine } from \"../../components/returns/state-machine\";\nimport type { ReturnsAppearance } from \"../../components/returns/appearance\";\nimport type { ReturnsTexts } from \"../../components/returns/texts\";\nimport { Button } from \"../../ui/button\";\nimport { clearPanelSession } from \"../session-storage\";\nimport type { PanelScreen, PanelSearchParamsType } from \"../types\";\n\ntype Props = {\n projectID: string;\n host?: string;\n accessToken: string;\n loginURL: string;\n appearance?: ReturnsAppearance;\n texts?: Partial<ReturnsTexts>;\n screen: PanelScreen;\n params: PanelSearchParamsType;\n setParams: (params: Partial<PanelSearchParamsType>) => void;\n setActiveScreen: (screen: PanelScreen) => void;\n};\n\ntype Draft = { items: SelectedReturnLine[]; note: string };\n\nfunction redirectToLogin(\n loginURL: string,\n dropToken: boolean,\n projectID: string,\n host?: string,\n) {\n if (typeof window === \"undefined\") return;\n if (dropToken) {\n clearPanelSession(projectID, host);\n }\n window.location.href = loginURL;\n}\n\nfunction ReturnsScreens({\n projectID,\n host,\n loginURL,\n screen,\n params,\n setParams,\n setActiveScreen,\n}: Pick<\n Props,\n \"projectID\" | \"host\" | \"loginURL\" | \"screen\" | \"params\" | \"setParams\" | \"setActiveScreen\"\n>) {\n const { status, exchangeError } = useReturnsContext(\"PanelReturns\");\n const text = useReturnsText();\n\n // The panel token is the login, so there is no email or code step. A failed\n // exchange or a dropped session means the panel session is no longer valid.\n const expired =\n status === \"anonymous\" &&\n (exchangeError == null || isSessionExpiredError(exchangeError));\n useEffect(() => {\n if (expired) {\n redirectToLogin(loginURL, exchangeError != null, projectID, host);\n }\n }, [expired, loginURL, exchangeError, projectID, host]);\n\n const [view, setView] = useState<\"orders\" | \"myReturns\" | \"confirmation\" | \"result\">(\n \"orders\",\n );\n const [draft, setDraft] = useState<Draft>({ items: [], note: \"\" });\n const [createdReturnId, setCreatedReturnId] = useState<string>();\n\n if (status === \"anonymous\" && !expired) {\n return (\n <div role=\"alert\" className=\"flex flex-col items-start gap-3\">\n <p className=\"text-sm\">{text(mapReturnsError(exchangeError))}</p>\n <Button type=\"button\" onClick={() => window.location.reload()}>\n {text(\"errorRetry\")}\n </Button>\n </div>\n );\n }\n\n if (status !== \"authenticated\") {\n return <SkeletonRows />;\n }\n\n const openReturns = (next: \"orders\" | \"myReturns\") => {\n setView(next);\n setParams({ state: \"returns\", orderId: undefined, returnId: undefined });\n setActiveScreen(\"returns\");\n };\n\n if (screen === \"return-details\" && params.returnId) {\n return (\n <ReturnsMyReturnDetail\n returnId={params.returnId}\n onBack={() => openReturns(\"myReturns\")}\n />\n );\n }\n\n if (view === \"myReturns\") {\n return (\n <ReturnsMyReturnsList\n onBack={() => openReturns(\"orders\")}\n onSelectReturn={(returnId) => {\n setParams({ state: \"return-details\", returnId, orderId: undefined });\n setActiveScreen(\"return-details\");\n }}\n />\n );\n }\n\n if (view === \"result\" && createdReturnId != null) {\n return (\n <ReturnsResult\n returnId={createdReturnId}\n onContinue={() => openReturns(\"orders\")}\n onOpenMyReturns={() => openReturns(\"myReturns\")}\n />\n );\n }\n\n if (params.orderId) {\n const orderId = params.orderId;\n\n if (view === \"confirmation\") {\n return (\n <ReturnsConfirmation\n orderId={orderId}\n items={draft.items}\n note={draft.note}\n onBack={() => setView(\"orders\")}\n onSubmitted={(returnId) => {\n setCreatedReturnId(returnId);\n setDraft({ items: [], note: \"\" });\n setView(\"result\");\n setParams({ orderId: undefined });\n }}\n />\n );\n }\n\n return (\n <ReturnsOrderDetail\n orderId={orderId}\n initialItems={draft.items.length > 0 ? draft.items : undefined}\n initialNote={draft.note}\n onBack={() => {\n setDraft({ items: [], note: \"\" });\n setParams({ orderId: undefined });\n }}\n onContinue={(selection) => {\n setDraft(selection);\n setView(\"confirmation\");\n }}\n />\n );\n }\n\n return (\n <ReturnsOrderList\n showLogout={false}\n onSelectOrder={(orderId) => {\n setDraft({ items: [], note: \"\" });\n setView(\"orders\");\n setParams({ orderId });\n }}\n onOpenMyReturns={() => openReturns(\"myReturns\")}\n />\n );\n}\n\n/**\n * Panel Returns screen: the exported returns step components under a\n * `ReturnsProvider` that exchanges the panel access token for a returns\n * session.\n */\nexport default function PanelReturns({\n accessToken,\n appearance,\n texts,\n ...rest\n}: Props) {\n return (\n <ReturnsProvider\n projectID={rest.projectID}\n host={rest.host}\n appearance={appearance}\n texts={texts}\n panelAccessToken={accessToken}\n >\n <ReturnsScreens {...rest} />\n </ReturnsProvider>\n );\n}\n","import {\n lazy,\n Suspense,\n useEffect,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport {\n FailureMessage,\n UserProductSchema,\n UserProductType,\n type UserProduct,\n} from \"../../gen/proto/public/v1/public_api_pb\";\nimport { rpcProvider, useQuery } from \"../../rpc-provider\";\nimport { Button } from \"../../ui/button\";\nimport { BookOpen, Files, Headphones, Ticket } from \"lucide-react\";\nimport { getProductTexts } from \"./products/texts\";\n\nimport { renderText } from \"@/src/lib/render.text\";\nimport { fromJsonString } from \"@bufbuild/protobuf\";\nimport type { PanelScreen, PanelSearchParamsType } from \"../types\";\nimport PanelProductDetails from \"./PanelProductDetails\";\nimport { clearPanelSession } from \"../session-storage\";\nimport { usePanelConfig } from \"../PanelProvider\";\nimport { getLocale } from \"../../components/checkout/locale\";\nimport { useModelFiles, type ModelFilesLoad } from \"./model-files-load\";\n\n// The 3D files list (UI + download RPC) loads only for buyers who have some.\nconst PanelModelFiles = lazy(() => import(\"./PanelModelFiles\"));\n\ninterface PanelProductGridComponentProps {\n projectID: string;\n accessToken: string;\n loginURL: string;\n styles: CSSProperties;\n activeScreen: PanelScreen;\n params: PanelSearchParamsType;\n setParams: (params: PanelSearchParamsType) => void;\n openCourse: (accessId: string) => void;\n}\n\nconst PanelProductGridComponent = ({\n accessToken,\n projectID,\n loginURL,\n styles,\n activeScreen,\n params,\n setParams,\n openCourse,\n}: PanelProductGridComponentProps) => {\n const { host } = usePanelConfig();\n const {\n data: products,\n isLoading: isProductsLoading,\n error: productsError,\n refetch,\n } = useQuery(rpcProvider.publicApi.userPanelGetProducts, {\n accessToken: accessToken,\n });\n const modelFiles = useModelFiles(accessToken, projectID);\n const decision = decidePanelProducts({\n products: isProductsLoading\n ? { status: \"loading\" }\n : productsError != null\n ? { status: \"error\" }\n : products?.result.case === \"success\"\n ? { status: \"ok\", count: products.result.value.products.length }\n : products?.result.case === \"failure\"\n ? {\n status: \"failure\",\n unauthorized:\n products.result.value === FailureMessage.UNAUTHORIZED,\n }\n : { status: \"error\" },\n modelFiles,\n });\n\n // Only an expired session signs the buyer out; an empty list or another\n // failure keeps them in (a buyer of 3D files only has no access products).\n useEffect(() => {\n if (decision.kind !== \"signed-out\") return;\n clearPanelSession(projectID, host);\n window.location.href = loginURL;\n }, [decision.kind, projectID, host, loginURL]);\n\n if (decision.kind === \"loading\" || decision.kind === \"signed-out\") {\n return (\n <div\n role=\"status\"\n aria-label={getProductTexts().loading}\n aria-busy=\"true\"\n className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5\"\n >\n {Array.from({ length: 6 }, (_, index) => (\n <div\n key={index}\n aria-hidden=\"true\"\n className=\"h-72 rounded-xl bg-neutral-100 motion-safe:animate-pulse dark:bg-neutral-800\"\n />\n ))}\n </div>\n );\n }\n\n const productsList =\n products && products.result.case === \"success\"\n ? products.result.value.products\n : [];\n const models = modelFiles.status === \"ready\" ? modelFiles.models : [];\n const filesSection =\n models.length > 0 ? (\n <Suspense fallback={null}>\n <PanelModelFiles\n accessToken={accessToken}\n models={models}\n buttonStyle={styles}\n />\n </Suspense>\n ) : null;\n\n if (decision.kind === \"error\") {\n return (\n <>\n <PanelProductsError onRetry={() => void refetch()} />\n {filesSection}\n </>\n );\n }\n\n if (decision.kind === \"empty\") {\n return <PanelProductsEmpty />;\n }\n\n return (\n <ProductsComponent\n accessToken={accessToken}\n products={productsList}\n styles={styles}\n activeScreen={activeScreen}\n params={params}\n setParams={setParams}\n openCourse={openCourse}\n filesSection={filesSection}\n />\n );\n};\n\n/** Inputs of `decidePanelProducts`, in the shape the RPC answers. */\nexport type PanelProductsInput = {\n products:\n | { status: \"loading\" }\n | { status: \"ok\"; count: number }\n | { status: \"failure\"; unauthorized: boolean }\n | { status: \"error\" };\n modelFiles: ModelFilesLoad;\n};\n\nexport type PanelProductsDecision =\n | { kind: \"loading\" }\n /** The session expired: clear it and go to the login page. */\n | { kind: \"signed-out\" }\n /** Products and/or 3D files to show. */\n | { kind: \"list\" }\n /** Nothing bought in this shop yet. */\n | { kind: \"empty\" }\n /** The products could not be loaded (3D files, if any, still show). */\n | { kind: \"error\" };\n\n/**\n * What the products screen shows. Pure, so the sign-out rule is tested\n * without a browser: only an expired session (`UNAUTHORIZED` from either\n * call) signs the buyer out. Older panels also signed out on an empty list\n * or any failure, which locked out buyers of 3D files only.\n */\nexport function decidePanelProducts({\n products,\n modelFiles,\n}: PanelProductsInput): PanelProductsDecision {\n if (products.status === \"failure\" && products.unauthorized) {\n return { kind: \"signed-out\" };\n }\n if (products.status === \"loading\") return { kind: \"loading\" };\n // Access products show at once; the 3D files join the list when they arrive.\n if (products.status === \"ok\" && products.count > 0) return { kind: \"list\" };\n if (modelFiles.status === \"loading\") return { kind: \"loading\" };\n if (products.status === \"failure\" || products.status === \"error\") {\n return modelFiles.status === \"unauthorized\"\n ? { kind: \"signed-out\" }\n : { kind: \"error\" };\n }\n const models = modelFiles.status === \"ready\" ? modelFiles.models.length : 0;\n if (products.count === 0 && models === 0) return { kind: \"empty\" };\n return { kind: \"list\" };\n}\n\nfunction PanelProductsEmpty() {\n const t = getProductTexts();\n return (\n <div className=\"flex flex-col items-start gap-1\" data-testid=\"panel-empty\">\n <h3 className=\"text-2xl\">{t.hello}</h3>\n <p className=\"text-sm text-neutral-500\">{t.empty}</p>\n </div>\n );\n}\n\nfunction PanelProductsError({ onRetry }: { onRetry: () => void }) {\n const en = getLocale().toLowerCase().startsWith(\"en\");\n return (\n <div\n className=\"flex flex-col items-start gap-3\"\n role=\"alert\"\n data-testid=\"panel-error\"\n >\n <p className=\"text-sm text-neutral-600 dark:text-neutral-300\">\n {en\n ? \"Your products could not be loaded.\"\n : \"Nie udało się wczytać Twoich produktów.\"}\n </p>\n <Button type=\"button\" onClick={onRetry} className=\"text-sm\">\n {en ? \"Try again\" : \"Spróbuj ponownie\"}\n </Button>\n </div>\n );\n}\n\nexport default PanelProductGridComponent;\n\ninterface ProductsComponentProps {\n accessToken: string;\n products: UserProduct[];\n styles: CSSProperties;\n filesSection?: ReactNode;\n activeScreen: PanelScreen;\n params: PanelSearchParamsType;\n setParams: (params: PanelSearchParamsType) => void;\n openCourse: (accessId: string) => void;\n}\n\nconst ProductsComponent = ({\n accessToken,\n products,\n styles,\n filesSection,\n activeScreen,\n params,\n setParams,\n openCourse,\n}: ProductsComponentProps) => {\n const t = getProductTexts();\n const [selectedProduct, setSelectedProduct] = useState(() =>\n resolvePanelProduct(params.product, products),\n );\n useEffect(() => {\n setSelectedProduct(resolvePanelProduct(params.product, products));\n }, [params.product, products]);\n const reveal = (product?: UserProduct) => {\n setSelectedProduct(product);\n setParams({\n product: product ? product.accessId || product.productId : undefined,\n state: \"products\",\n });\n };\n\n useEffect(() => {\n if (\n activeScreen === \"products\" &&\n selectedProduct?.productType === UserProductType.COURSE\n )\n openCourse(selectedProduct.accessId);\n }, [activeScreen, selectedProduct, openCourse]);\n\n function handleSelectedProduct(product: UserProduct) {\n // A course opens in its own screen, not in the product details.\n if (product.productType === UserProductType.COURSE) {\n openCourse(product.accessId);\n return;\n }\n reveal(product);\n }\n\n if (\n activeScreen === \"products\" &&\n selectedProduct?.productType === UserProductType.COURSE\n )\n return null;\n\n if (activeScreen === \"products\" && selectedProduct != undefined) {\n return (\n <PanelProductDetails\n accessToken={accessToken}\n product={selectedProduct}\n styles={styles}\n reveal={reveal}\n onOpenCourse={openCourse}\n />\n );\n }\n\n return (\n <>\n <h3 className=\"text-2xl\">{t.hello}</h3>\n {products.length > 0 && (\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400\">\n {t.intro}\n </p>\n )}\n <div className=\"mt-6 grid grid-cols-2 gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5\">\n {products.map((product) => {\n const [label, action, Icon] =\n product.productType === UserProductType.AUDIO\n ? ([t.audio, t.listen, Headphones] as const)\n : product.productType === UserProductType.COURSE\n ? ([t.course, t.openCourse, BookOpen] as const)\n : product.productType === UserProductType.TICKET\n ? ([t.ticket, t.showTicket, Ticket] as const)\n : ([t.files, t.downloadFiles, Files] as const);\n return (\n <button\n type=\"button\"\n key={product.accessId || product.productId}\n onClick={() => handleSelectedProduct(product)}\n className=\"flex min-h-11 min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white text-left text-neutral-900 transition-colors hover:border-neutral-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-neutral-500 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-50 dark:hover:border-neutral-500\"\n >\n <span className=\"flex w-full flex-col gap-3 bg-neutral-100 p-3 dark:bg-neutral-800\">\n <span className=\"flex w-fit items-center gap-1.5 rounded-md bg-white px-2 py-1 text-xs font-medium dark:bg-neutral-900\">\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n {label}\n </span>\n <img\n src={product.productImageUrl}\n alt={product.productName}\n draggable={false}\n className=\"aspect-square w-full object-contain\"\n />\n </span>\n <span className=\"flex flex-1 flex-col gap-3 p-3\">\n <span className=\"line-clamp-2 font-semibold\">\n {product.productName}\n </span>\n <span className=\"line-clamp-2 text-sm text-neutral-600 dark:text-neutral-300\">\n {renderText(product.productDescription)}\n </span>\n <span className=\"mt-auto pt-2 text-sm font-medium underline underline-offset-4\">\n {action}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n {filesSection}\n </>\n );\n};\n\n/** Resolve current IDs and old protobuf JSON links against the buyer's library. */\nexport function resolvePanelProduct(\n value: string | undefined,\n products: UserProduct[],\n): UserProduct | undefined {\n if (!value) return undefined;\n const match = products.find(\n (product) =>\n (product.accessId || product.productId) === value ||\n product.productId === value,\n );\n if (match) return match;\n try {\n const legacy = fromJsonString(UserProductSchema, value);\n return products.find((product) =>\n legacy.accessId\n ? product.accessId === legacy.accessId\n : product.productId === legacy.productId,\n );\n } catch {\n return undefined;\n }\n}\n","import { getLocale } from \"../../../components/checkout/locale\";\nconst pl = {\n hello: \"Hej 👋\",\n intro: \"Poniżej znajdziesz swoje produkty\",\n loading: \"Ładowanie produktów…\",\n empty:\n \"Nie masz jeszcze produktów w tym sklepie. Twoje zakupy pojawią się tutaj.\",\n audio: \"Audio\",\n files: \"Pliki\",\n course: \"Kurs\",\n ticket: \"Bilet\",\n listen: \"Słuchaj\",\n openCourse: \"Otwórz kurs\",\n downloadFiles: \"Pobierz pliki\",\n showTicket: \"Pokaż bilet\",\n back: \"Wróć\",\n yourFiles: \"Twoje pliki\",\n download: \"Pobierz\",\n retry: \"Spróbuj ponownie\",\n fileError: \"Nie udało się wczytać plików.\",\n noFiles: \"Brak plików do pobrania.\",\n ticketInfo: \"Twój zakupiony bilet\",\n file: \"Plik\",\n};\nconst en: typeof pl = {\n hello: \"Hi 👋\",\n intro: \"Your products are below\",\n loading: \"Loading products…\",\n empty:\n \"You have no products in this shop yet. Your purchases will show up here.\",\n audio: \"Audio\",\n files: \"Files\",\n course: \"Course\",\n ticket: \"Ticket\",\n listen: \"Listen\",\n openCourse: \"Open course\",\n downloadFiles: \"Download files\",\n showTicket: \"Show ticket\",\n back: \"Back\",\n yourFiles: \"Your files\",\n download: \"Download\",\n retry: \"Try again\",\n fileError: \"Your files could not be loaded.\",\n noFiles: \"No files to download.\",\n ticketInfo: \"Your purchased ticket\",\n file: \"File\",\n};\nexport function getProductTexts() {\n return getLocale().toLowerCase().startsWith(\"en\") ? en : pl;\n}\n","const URL_REGEX =\n /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)/g;\n\ntype Replacements = {\n url: string;\n startIndex: number;\n endIndex: number;\n replacementText?: string;\n};\n\nconst findURLIndices = (text: string) => {\n const matches = [...text.matchAll(URL_REGEX)];\n return matches.map(\n (match) =>\n ({\n url: match[0],\n startIndex: match.index,\n endIndex: match.index + match[0].length - 1,\n }) as Replacements,\n );\n};\n\nconst replaceTextByIndices = (\n originalText: string,\n replacements: Replacements[],\n) => {\n let result = \"\";\n let lastIndex = 0;\n\n // Sort replacements by startIndex to handle them in order\n replacements.sort((a, b) => a.startIndex - b.startIndex);\n\n for (const { startIndex, endIndex, replacementText } of replacements) {\n // Append text before the current replacement\n result += originalText.slice(lastIndex, startIndex);\n // Append the replacement text\n result += replacementText;\n // Update lastIndex to after the replaced segment\n lastIndex = endIndex + 1;\n }\n\n // Append any remaining text after the last replacement\n result += originalText.slice(lastIndex);\n\n return result;\n};\n\nexport const renderText = (txt: string) => {\n const urlIndices = findURLIndices(txt);\n\n return (\n <p\n dangerouslySetInnerHTML={{\n __html: replaceTextByIndices(\n txt,\n urlIndices.map((el) => {\n el[\"replacementText\"] =\n `<a key=${el.url} href=${el.url} style=\"text-decoration: underline;\" target=\"_blank\">\n ${el.url}\n </a>`;\n return el;\n }),\n ),\n }}\n ></p>\n );\n};\n","import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { ChevronLeft, Download } from \"lucide-react\";\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport {\n UserProductType,\n type UserPanelGetAudiobookDetailsDownloadURLsResponse_AudiobookDownloadDetails,\n type UserProduct,\n} from \"../../gen/proto/public/v1/public_api_pb\";\nimport { useInstrumentContext } from \"../../analytics/instrument\";\nimport { rpcProvider, useMutation } from \"../../rpc-provider\";\nimport { Button } from \"../../ui/button\";\nimport AudioPlayer, {\n type AudioPlayerMethods,\n} from \"../audio-player/AudioPlayer\";\nimport LoadingIndicator from \"../LoadingIndicator\";\nimport ChapterList from \"../audio-player/ChapterList\";\n\nimport { getProductTexts } from \"./products/texts\";\n\ninterface PanelProductDetailsProps {\n accessToken: string;\n product: UserProduct;\n styles: CSSProperties;\n reveal: (product?: UserProduct) => void;\n /** Opens the course screen of a course product. */\n onOpenCourse: (accessId: string) => void;\n}\n\nfunction warn(message: string, ...args: unknown[]) {\n console.warn(message, ...args);\n}\n\nfunction error(message: string) {\n console.error(message);\n}\n\nconst PanelProductDetails = ({\n accessToken,\n product,\n styles,\n reveal,\n}: PanelProductDetailsProps) => {\n const t = getProductTexts();\n const productType: UserProductType = product.productType;\n const instrument = useInstrumentContext();\n const trackDownload = () =>\n instrument.track(\n \"panel_download\",\n {},\n { product_id: product.productId.length <= 64 ? product.productId : null },\n );\n\n const audioPlayerRef = useRef<AudioPlayerMethods>(null!);\n const [filesRefAnimation] = useAutoAnimate();\n const [fileError, setFileError] = useState(false);\n const [filesResponse, setFilesResponse] = useState<string[] | null>(null);\n const { mutateAsync: fileDetailsAsync, isPending: isFileLoading } =\n useMutation(rpcProvider.publicApi.userPanelGetFileDetails);\n\n const audioPlayerSeekToHandler = useRef<\n ((second: number) => void) | undefined\n >(undefined);\n const [audioResponse, setAudioResponse] = useState<Record<\n string,\n unknown\n > | null>(null);\n const [audioDownloadURLs, setAudioDownloadURLs] = useState<\n | UserPanelGetAudiobookDetailsDownloadURLsResponse_AudiobookDownloadDetails[]\n | null\n >(null);\n const [\n isAvailableToDownloadInMobileApp,\n setIsAvailableToDownloadInMobileApp,\n ] = useState(false);\n const { mutateAsync: audioDetailsAsync, isPending: isAudioLoading } =\n useMutation(rpcProvider.publicApi.userPanelGetAudiobookDetails);\n const {\n mutateAsync: audioDetailsDownloadURLsAsync,\n isPending: isAudioDownloadURLsLoading,\n } = useMutation(\n rpcProvider.publicApi.userPanelGetAudiobookDetailsDownloadURLs,\n );\n\n type ChapterWithPublicUrl = {\n id: string;\n multimediaId?: string;\n name: string;\n description?: string;\n publicUrl: string;\n downloadableUrl?: string;\n duration?: number;\n };\n\n const [selectedChapter, setSelectedChapter] =\n useState<ChapterWithPublicUrl | null>(null);\n const [chapters, setChapters] = useState<ChapterWithPublicUrl[] | null>(null);\n\n async function handleFileDownload() {\n setFileError(false);\n try {\n const filesResult = await fileDetailsAsync({\n accessId: product.accessId,\n accessToken: accessToken as string,\n });\n\n if (filesResult.result.case === \"success\") {\n setFilesResponse(filesResult.result.value.files);\n return;\n } else {\n setFileError(true);\n warn(\"Pobranie plików nie powiodło się. Zalecamy kontakt.\");\n warn(\"Kod błędu: \", filesResult.result.value);\n }\n } catch (err) {\n setFileError(true);\n warn(\"Nieoczekiwany błąd. Spróbuj ponownie za chwilę.\");\n error(\"Błąd podczas pobierania danych:\" + err);\n }\n }\n\n async function handleAudioDownload() {\n try {\n const audioResult = await audioDetailsAsync({\n accessId: product.accessId,\n accessToken: accessToken as string,\n });\n\n if (audioResult.result.case === \"audiobook\") {\n setAudioResponse(\n audioResult.result.value as unknown as Record<string, unknown>,\n );\n return;\n } else {\n warn(\"Pobranie plików nie powiodło się. Zalecamy kontakt.\");\n warn(\"Kod błędu: \", audioResult.result.value);\n }\n } catch (err) {\n warn(\"Nieoczekiwany błąd. Spróbuj ponownie za chwilę.\");\n error(\"Błąd podczas pobierania danych:\" + err);\n }\n }\n\n async function handleAudioURLsDownload() {\n try {\n const audioURLsResult = await audioDetailsDownloadURLsAsync({\n accessId: product.accessId,\n accessToken: accessToken as string,\n isBrowser: true,\n });\n\n if (audioURLsResult.result.case === \"success\") {\n setAudioDownloadURLs(\n audioURLsResult.result.value.audiobookDownloadDetails,\n );\n setIsAvailableToDownloadInMobileApp(\n audioURLsResult.result.value.isAvailableToDownloadInMobileApp ===\n true,\n );\n return;\n } else {\n warn(\"Pobranie plików nie powiodło się. Zalecamy kontakt.\");\n warn(\"Kod błędu: \", audioURLsResult.result.value);\n }\n } catch (err) {\n warn(\"Nieoczekiwany błąd. Spróbuj ponownie za chwilę.\");\n error(\"Błąd podczas pobierania danych:\" + err);\n }\n }\n\n useEffect(() => {\n if (productType === UserProductType.FILE) void handleFileDownload();\n if (productType === UserProductType.AUDIO) {\n handleAudioDownload().then().catch();\n handleAudioURLsDownload().then().catch();\n }\n }, []);\n\n useEffect(() => {\n if (audioResponse != null && audioDownloadURLs != null) {\n const audioChapters = (\n audioResponse as { chapters?: ChapterWithPublicUrl[] }\n ).chapters;\n if (!audioChapters) return;\n\n const mappedChapters = audioChapters\n .map((chapter) => {\n const details = audioDownloadURLs?.find(\n (el) => el.chapterId === chapter.id,\n );\n if (details == null) {\n return undefined;\n }\n return {\n ...chapter,\n publicUrl: details.publicUrl,\n downloadableUrl: details.downloadableUrl,\n duration: details.duration,\n } as ChapterWithPublicUrl;\n })\n .filter((el) => el != null);\n\n if (mappedChapters != undefined && mappedChapters.length > 0) {\n setChapters(mappedChapters);\n }\n }\n }, [audioResponse, audioDownloadURLs]);\n\n return (\n <div>\n <div className=\"mb-3 space-y-4 rounded bg-white p-4 dark:bg-black\">\n <Button\n onClick={() => reveal()}\n variant=\"ghost\"\n className=\"min-h-11 w-fit\"\n >\n <ChevronLeft className=\"h-6 w-6\" />\n <span className=\"font-inter text-sm font-medium\">{t.back}</span>\n </Button>\n </div>\n\n <main className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <header className=\"flex min-w-0 flex-col gap-4 rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900 lg:row-span-2 lg:self-start\">\n <img\n src={product.productImageUrl}\n alt={product.productName}\n width={384}\n height={384}\n draggable={false}\n className=\"aspect-square max-h-72 w-full object-contain\"\n />\n <h2 className=\"text-2xl font-semibold\">{product.productName}</h2>\n </header>\n <div className=\"flex min-w-0 flex-col gap-6\">\n {productType === UserProductType.FILE && (\n <section\n ref={filesRefAnimation}\n className=\"flex flex-col gap-4 rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900\"\n >\n <h3 className=\"text-xl font-semibold\">{t.yourFiles}</h3>\n {isFileLoading && (\n <div role=\"status\" aria-label={t.loading}>\n <LoadingIndicator />\n </div>\n )}\n {fileError && (\n <div role=\"alert\">\n <p>{t.fileError}</p>\n <Button className=\"min-h-11\" onClick={handleFileDownload}>\n {t.retry}\n </Button>\n </div>\n )}\n {filesResponse?.length === 0 && <p>{t.noFiles}</p>}\n {filesResponse && (\n <ul className=\"flex flex-col gap-3\">\n {filesResponse.map((url, index) => (\n <li\n key={url}\n className=\"flex min-w-0 flex-wrap items-center justify-between gap-3\"\n >\n <span className=\"min-w-0 break-all text-sm\">\n {downloadFileName(url) || `${t.file} ${index + 1}`}\n </span>\n <a\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n href={url}\n download\n onClick={trackDownload}\n className=\"inline-flex min-h-11 items-center gap-2 rounded-md bg-neutral-900 px-3 py-2 text-sm text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 dark:bg-neutral-100 dark:text-neutral-900\"\n aria-label={`${t.download}: ${downloadFileName(url) || `${t.file} ${index + 1}`}`}\n >\n {t.download}\n <Download className=\"size-4\" aria-hidden=\"true\" />\n </a>\n </li>\n ))}\n </ul>\n )}\n </section>\n )}\n {productType === UserProductType.TICKET && (\n <section className=\"rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900\">\n <h3 className=\"text-lg font-semibold\">{t.ticket}</h3>\n <p className=\"mt-2 font-medium\">{product.productName}</p>\n <p className=\"mt-2 text-sm text-neutral-600 dark:text-neutral-300\">\n {t.ticketInfo}\n </p>\n </section>\n )}\n\n {productType === UserProductType.AUDIO && (\n <>\n <div className=\"flex flex-col space-y-6 rounded-xl bg-white p-3 drop-shadow-xl dark:bg-neutral-900 dark:drop-shadow-none\">\n <h4 className=\"text-xl font-semibold\">\n {selectedChapter?.name ?? \"Odtwarzacz\"}\n </h4>\n {selectedChapter?.description && (\n <p className=\"text-sm\">{selectedChapter?.description}</p>\n )}\n <>\n {isAudioLoading ? (\n <div className=\"flex gap-2\">\n <LoadingIndicator />\n <p className=\"text-xl font-semibold\">\n Trwa pobierania audiobooka...\n </p>\n </div>\n ) : (\n <>\n {chapters != null ? (\n <>\n <AudioPlayer\n ref={audioPlayerRef}\n coverShownBeside\n chapters={chapters}\n author={\n typeof audioResponse?.author === \"string\"\n ? audioResponse.author\n : undefined\n }\n onExpiredUrl={() => {\n void handleAudioURLsDownload();\n }}\n title={\n (audioResponse as { name?: string })?.name ??\n product.productName ??\n undefined\n }\n imageURL={\n (audioResponse as { coverImage?: string })\n ?.coverImage ??\n product.productImageUrl ??\n undefined\n }\n styles={styles}\n setCurrentTimeHandler={(handler) => {\n audioPlayerSeekToHandler.current = handler;\n }}\n uniqueProductID={product.productId}\n onChapterChange={(chapter) => {\n setSelectedChapter(chapter);\n }}\n />\n </>\n ) : (\n <p className=\"mt-2\">\n Wybierz rozdział, który cię interesuje.\n </p>\n )}\n </>\n )}\n </>\n <div className=\"rounded-xl bg-neutral-100 p-3 dark:bg-neutral-800\">\n <p className=\"mt-3 mb-3 text-xs\">\n {isAvailableToDownloadInMobileApp\n ? \"Możesz słuchać tego audiobooka w aplikacji również bez dostępu do internetu.\"\n : \"Możesz słuchać tego audiobooka w aplikacji.\"}\n </p>\n <div className=\"flex gap-3\">\n <a href=\"https://apps.apple.com/us/app/bitsnap/id6741902807\">\n <img\n width=\"100\"\n src=\"https://bitsnap.pl/appstore.svg\"\n alt=\"Pobierz aplikacje z AppStore\"\n />\n </a>\n\n <a href=\"https://play.google.com/store/apps/details?id=com.bitsnap.Bitsnap\">\n <img\n width=\"100\"\n src=\"https://bitsnap.pl/playstore.svg\"\n alt=\"Pobierz aplikację z GooglePlay\"\n />\n </a>\n </div>\n </div>\n </div>\n </>\n )}\n\n <div className=\"flex items-center justify-center rounded-xl bg-white p-3 drop-shadow-xl dark:bg-neutral-900 dark:drop-shadow-none\">\n {productType === UserProductType.AUDIO && (\n <ChapterList\n chapters={chapters}\n currentID={selectedChapter?.id}\n productID={product.productId}\n loading={isAudioLoading}\n downloadable={audioResponse?.isDownloadable === true}\n onDownload={trackDownload}\n onSelect={(chapter) =>\n audioPlayerRef.current?.selectChapter(chapter)\n }\n />\n )}\n </div>\n </div>\n\n <section className=\"rounded-xl border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-900\">\n <p className=\"whitespace-pre-wrap text-sm text-neutral-600 dark:text-neutral-300\">\n {product.productDescription}\n </p>\n </section>\n </main>\n </div>\n );\n};\n\nexport default PanelProductDetails;\n\n/** File RPC exposes URLs only; no size or filename metadata. */\nexport function downloadFileName(url: string): string {\n try {\n return decodeURIComponent(\n new URL(url, \"https://bitsnap.pl\").pathname.split(\"/\").pop() || \"\",\n );\n } catch {\n return \"\";\n }\n}\n","import Hls from \"hls.js\";\nimport { Pause, Play, SkipBack, SkipForward } from \"lucide-react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../../ui/button\";\nimport LoadingIndicator from \"../LoadingIndicator\";\nimport {\n createHlsSource,\n playerErrorFromMediaError,\n prefersNativeHls,\n type HlsSource,\n type PlayerError,\n} from \"./hls-engine\";\nimport {\n PREVIOUS_TRACK_RESTART_SECONDS,\n SEEK_STEP_SECONDS,\n mediaSessionPause,\n mediaSessionPlay,\n mediaSessionSetMetadata,\n mediaSessionUpdateDurationAndPosition,\n startMediaSessionCoordinator,\n stopMediaSessionCoordinator,\n} from \"./media.session.coordinator\";\n\nimport \"./audio-player.css\";\nimport { useAudioTexts, formatTime } from \"./texts\";\nimport { playerStorage, SPEED_KEY, SPEEDS } from \"./storage\";\n\nexport type ChapterWithPublicUrl = {\n id: string;\n multimediaId?: string;\n name: string;\n description?: string;\n publicUrl: string;\n downloadableUrl?: string;\n duration?: number;\n};\n\n/** What the player could not play; `status` is the HTTP status when known. */\nexport type AudioPlayerError = PlayerError;\n\nexport type AudioPlayerMethods = {\n selectChapter: (chapter: ChapterWithPublicUrl) => void;\n /** Loads the current chapter again after an error, keeping the position. */\n retry: () => void;\n /** The error currently shown, if any. */\n getError: () => AudioPlayerError | null;\n};\n\ntype AudioPlayerProps = {\n locale?: string;\n chapters: ChapterWithPublicUrl[];\n styles: CSSProperties;\n updateCurrentTime?: (currentTime: number) => void;\n\n title?: string;\n imageURL?: string;\n /** Hide the repeated visual heading when the desktop details show the cover beside it. */\n coverShownBeside?: boolean;\n /** Book author, used as the lock-screen artist. */\n author?: string;\n\n setCurrentTimeHandler?: (seekTo: (second: number) => void) => void;\n uniqueProductID: string;\n\n onChapterChange?: (chapter: ChapterWithPublicUrl) => void;\n /** A fatal playback error the player could not recover from. */\n onError?: (error: AudioPlayerError) => void;\n /** The signed URL returned 401/403; the owner should refetch the chapters. */\n onExpiredUrl?: () => void;\n /** The last chapter ended. */\n onFinished?: () => void;\n};\n\nconst AudioPlayer = forwardRef<AudioPlayerMethods, AudioPlayerProps>(\n (\n {\n chapters,\n locale,\n styles,\n updateCurrentTime,\n setCurrentTimeHandler,\n title,\n imageURL,\n coverShownBeside,\n author,\n uniqueProductID,\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n },\n ref,\n ) => {\n const t = useAudioTexts(locale);\n const [speed, setSpeed] = useState(1);\n const speedRef = useRef(1);\n const [chapterID, setChapterID] = useState<string>();\n const [sleepMode, setSleepMode] = useState(\"off\");\n const [sleepRemaining, setSleepRemaining] = useState(0);\n const sleepRef = useRef<{ mode: string; deadline: number }>({\n mode: \"off\",\n deadline: 0,\n });\n\n function cancelSleep() {\n sleepRef.current = { mode: \"off\", deadline: 0 };\n setSleepMode(\"off\");\n setSleepRemaining(0);\n }\n function changeSleep(mode: string) {\n const seconds = Number(mode) * 60;\n sleepRef.current = {\n mode,\n deadline: Number.isFinite(seconds) ? Date.now() + seconds * 1000 : 0,\n };\n setSleepMode(mode);\n setSleepRemaining(Number.isFinite(seconds) ? seconds : 0);\n }\n function changeSpeed(rate: number) {\n if (!SPEEDS.includes(rate)) return;\n setSpeed(rate);\n speedRef.current = rate;\n playerStorage.set(SPEED_KEY, String(rate));\n if (videoRef.current) videoRef.current.playbackRate = rate;\n updatePlayerDetails();\n }\n useEffect(() => {\n const saved = Number(playerStorage.get(SPEED_KEY));\n if (SPEEDS.includes(saved)) changeSpeed(saved);\n const timer = setInterval(() => {\n const { mode, deadline } = sleepRef.current;\n if (mode === \"off\" || mode === \"chapter\") return;\n const remaining = Math.max(\n 0,\n Math.ceil((deadline - Date.now()) / 1000),\n );\n setSleepRemaining(remaining);\n if (remaining === 0) {\n playWhenReadyRef.current = false;\n pause();\n cancelSleep();\n }\n }, 1000);\n return () => clearInterval(timer);\n }, []);\n\n enum PlayState {\n Playing,\n Paused,\n }\n\n const [playState, setPlayState] = useState<PlayState>(PlayState.Paused);\n const [currentTime, setCurrentTime] = useState<number | undefined>(\n undefined,\n );\n const [duration, setDuration] = useState<number | undefined>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n const [playerError, setPlayerError] = useState<AudioPlayerError | null>(\n null,\n );\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<HlsSource | null>(null);\n const timerRef = useRef<ReturnType<typeof setInterval> | undefined>(\n undefined,\n );\n\n const audioPlayerContainerRef = useRef<HTMLDivElement>(null!);\n\n const currentChapterRef = useRef<ChapterWithPublicUrl | null>(null);\n const playerErrorRef = useRef<AudioPlayerError | null>(null);\n\n /** Set by a user action; the next `loadeddata` starts playback once. */\n const playWhenReadyRef = useRef(false);\n /** Position restored for the chapter that is loading, once. */\n const resumedRef = useRef(false);\n /** Position to restore instead of the remembered one (URL refresh, retry). */\n const pendingSeekRef = useRef<number | null>(null);\n /** Chapter URL that already asked the owner for a fresh signed URL. */\n const expiredUrlRef = useRef<string | null>(null);\n const chaptersRef = useRef(chapters);\n const chaptersSignatureRef = useRef<string | null>(null);\n\n // The owner passes new callbacks on every render; the player must keep the\n // current ones without restarting playback.\n const callbacksRef = useRef({\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n updateCurrentTime,\n title,\n imageURL,\n author,\n });\n callbacksRef.current = {\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n updateCurrentTime,\n title,\n imageURL,\n author,\n };\n\n function saveLastPlayedTime(timeInSeconds: number) {\n if (\n !resumedRef.current ||\n !Number.isFinite(timeInSeconds) ||\n timeInSeconds < 0\n ) {\n return;\n }\n playerStorage.set(\n `__player__${uniqueProductID}_${currentChapterRef.current?.id}`,\n `${Math.floor(timeInSeconds)}`,\n );\n }\n\n function getLastPlayedTime(): number | undefined {\n const time = playerStorage.get(\n `__player__${uniqueProductID}_${currentChapterRef.current?.id}`,\n );\n\n if (time == null) {\n return undefined;\n }\n try {\n const result = parseInt(time);\n\n if (isNaN(result) || result < 0) {\n return undefined;\n }\n\n return result;\n } catch (e) {\n return undefined;\n }\n }\n\n function getLastSelectedChapterID(): string | undefined {\n const lastSelectedChapterID = playerStorage.get(\n `__player__${uniqueProductID}_last_chapter`,\n );\n if (lastSelectedChapterID == null) {\n return undefined;\n }\n return lastSelectedChapterID;\n }\n\n function setLastSelectedChapterID(chapterID: string) {\n playerStorage.set(`__player__${uniqueProductID}_last_chapter`, chapterID);\n }\n\n function deleteMemoryChapter(chapterID: string) {\n playerStorage.remove(`__player__${uniqueProductID}_${chapterID}`);\n }\n\n function syncMediaSessionMetadata(chapter: ChapterWithPublicUrl | null) {\n mediaSessionSetMetadata({\n title: chapter?.name ?? callbacksRef.current.title ?? \"\",\n album: callbacksRef.current.title,\n artist: callbacksRef.current.author,\n artwork: callbacksRef.current.imageURL,\n });\n }\n\n function reportError(error: AudioPlayerError) {\n playerErrorRef.current = error;\n setPlayerError(error);\n setIsLoading(false);\n callbacksRef.current.onError?.(error);\n }\n\n function clearError() {\n playerErrorRef.current = null;\n setPlayerError(null);\n }\n\n function attemptPlay() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n const result = video.play() as Promise<void> | undefined;\n if (result != null && typeof result.catch == \"function\") {\n result.catch(() => {\n // The browser blocked playback; the user presses play.\n });\n }\n updatePlayerDetails();\n }\n\n function play() {\n attemptPlay();\n }\n\n function pause() {\n videoRef.current?.pause();\n updatePlayerDetails();\n }\n\n function togglePlayState() {\n if (playState === PlayState.Playing) {\n pause();\n return;\n }\n play();\n }\n\n function seekTo(toSecond: number) {\n const video = videoRef.current;\n if (video == null || !Number.isFinite(toSecond)) {\n return;\n }\n const knownDuration = Number.isFinite(video.duration)\n ? video.duration\n : 0;\n const target =\n knownDuration > 0\n ? Math.min(Math.max(toSecond, 0), knownDuration)\n : Math.max(toSecond, 0);\n setCurrentTime(target);\n video.currentTime = target;\n updatePlayerDetails();\n }\n\n function seekBy(seconds: number) {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n const knownDuration = Number.isFinite(video.duration)\n ? video.duration\n : undefined;\n let target = Math.max(video.currentTime + seconds, 0);\n if (knownDuration != null && target > knownDuration) {\n target = knownDuration;\n }\n seekTo(target);\n }\n\n function loadSource(src: string) {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n clearError();\n setIsLoading(true);\n\n if (prefersNativeHls(video)) {\n destroyHls();\n video.src = src;\n video.load();\n return;\n }\n\n if (Hls.isSupported()) {\n if (hlsRef.current == null) {\n hlsRef.current = createHlsSource({\n media: video,\n handlers: {\n onError: (error) => {\n reportError(error);\n },\n onExpiredUrl: () => {\n callbacksRef.current.onExpiredUrl?.();\n },\n },\n });\n }\n hlsRef.current.load(src);\n return;\n }\n\n // No Media Source and no native HLS: let the browser try the URL itself.\n destroyHls();\n video.src = src;\n video.load();\n }\n\n function destroyHls() {\n hlsRef.current?.destroy();\n hlsRef.current = null;\n }\n\n function playChapter(\n chapter: ChapterWithPublicUrl,\n options?: { play?: boolean },\n ) {\n const shouldPlay = options?.play === true;\n if (\n currentChapterRef.current &&\n videoRef.current &&\n !videoRef.current.ended\n ) {\n saveLastPlayedTime(videoRef.current.currentTime);\n }\n resumedRef.current = false;\n pendingSeekRef.current = null;\n playWhenReadyRef.current = shouldPlay;\n currentChapterRef.current = chapter;\n setChapterID(chapter.id);\n setCurrentTime(0);\n setDuration(chapter.duration);\n loadSource(chapter.publicUrl);\n syncMediaSessionMetadata(chapter);\n callbacksRef.current.onChapterChange?.(chapter);\n setLastSelectedChapterID(chapter.id);\n }\n\n function loadChapters(list: ChapterWithPublicUrl[]) {\n if (list.length === 0) {\n return;\n }\n\n const chapterID = getLastSelectedChapterID();\n const chapter =\n (chapterID != null\n ? list.find((candidate) => candidate.id === chapterID)\n : undefined) ?? list[0];\n\n // Mount and content changes never start playback on their own.\n playChapter(chapter, { play: false });\n }\n\n function playNextChapter() {\n const list = chaptersRef.current;\n const current = currentChapterRef.current;\n if (list == null || list.length === 0 || current == null) {\n return;\n }\n const currentChapterIndex = list.findIndex(\n (chapter) => chapter.id === current.id,\n );\n if (currentChapterIndex === -1) {\n return;\n }\n const nextChapterIndex = currentChapterIndex + 1;\n if (nextChapterIndex >= list.length) {\n finishPlayback(current);\n return;\n }\n playChapter(list[nextChapterIndex], { play: true });\n }\n\n function playPreviousChapter() {\n const list = chaptersRef.current;\n const current = currentChapterRef.current;\n if (current == null) {\n return;\n }\n const video = videoRef.current;\n if (video != null && video.currentTime > PREVIOUS_TRACK_RESTART_SECONDS) {\n seekTo(0);\n return;\n }\n const currentChapterIndex =\n list == null\n ? -1\n : list.findIndex((chapter) => chapter.id === current.id);\n if (currentChapterIndex > 0) {\n playChapter(list[currentChapterIndex - 1], { play: true });\n return;\n }\n seekTo(0);\n }\n\n function finishPlayback(chapter: ChapterWithPublicUrl) {\n // The chapter is done: no resume point, and the element stays at the end.\n deleteMemoryChapter(chapter.id);\n playWhenReadyRef.current = false;\n videoRef.current?.pause();\n setPlayState(PlayState.Paused);\n callbacksRef.current.onFinished?.();\n }\n\n function handleEnded() {\n const current = currentChapterRef.current;\n if (current == null) {\n return;\n }\n playerStorage.set(\n `__player__${uniqueProductID}_${current.id}_completed`,\n \"true\",\n );\n deleteMemoryChapter(current.id);\n if (sleepRef.current.mode === \"chapter\") {\n playWhenReadyRef.current = false;\n pause();\n cancelSleep();\n return;\n }\n playNextChapter();\n updatePlayerDetails();\n }\n\n function handleLoadedData() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n setIsLoading(false);\n video.playbackRate = speedRef.current;\n expiredUrlRef.current = null;\n if (!resumedRef.current) {\n resumedRef.current = true;\n const pending = pendingSeekRef.current;\n pendingSeekRef.current = null;\n if (pending != null) {\n seekTo(pending);\n } else {\n const lastPlayedTime = getLastPlayedTime();\n if (lastPlayedTime != null) {\n seekTo(lastPlayedTime);\n }\n }\n }\n if (playWhenReadyRef.current) {\n playWhenReadyRef.current = false;\n attemptPlay();\n }\n }\n\n function handleMediaElementError() {\n const mediaError = videoRef.current?.error;\n const src = currentChapterRef.current?.publicUrl;\n // Safari plays HLS itself and reports an expired signed URL as a network\n // error (2) or an unsupported source (4). Ask for a fresh URL once per\n // URL; an error that repeats after that refresh is a real error.\n const refreshable = mediaError?.code === 2 || mediaError?.code === 4;\n if (\n refreshable &&\n hlsRef.current == null &&\n src != null &&\n expiredUrlRef.current !== src\n ) {\n expiredUrlRef.current = src;\n callbacksRef.current.onExpiredUrl?.();\n }\n reportError(playerErrorFromMediaError(mediaError));\n }\n\n function retry() {\n const chapter = currentChapterRef.current;\n const src = chapter?.publicUrl ?? hlsRef.current?.src;\n if (src == null) {\n return;\n }\n const video = videoRef.current;\n const position = video?.currentTime ?? 0;\n clearError();\n resumedRef.current = false;\n pendingSeekRef.current = position > 0 ? position : null;\n setCurrentTime(position);\n if (hlsRef.current != null) {\n hlsRef.current.retry();\n } else {\n loadSource(src);\n }\n }\n\n function handleMediaSessionAction(details: MediaSessionActionDetails) {\n switch (details.action) {\n case \"play\":\n play();\n break;\n case \"pause\":\n case \"stop\":\n pause();\n break;\n case \"seekbackward\":\n seekBy(-(details.seekOffset ?? SEEK_STEP_SECONDS));\n break;\n case \"seekforward\":\n seekBy(details.seekOffset ?? SEEK_STEP_SECONDS);\n break;\n case \"seekto\":\n // A seek to 0 is valid: only a missing time is ignored.\n if (details.seekTime != null) {\n seekTo(details.seekTime);\n }\n break;\n case \"previoustrack\":\n playPreviousChapter();\n break;\n case \"nexttrack\":\n playNextChapter();\n break;\n default:\n break;\n }\n }\n\n useImperativeHandle(ref, () => {\n return {\n selectChapter: (chapter: ChapterWithPublicUrl) => {\n playChapter(chapter, { play: true });\n },\n retry,\n getError: () => playerErrorRef.current,\n };\n });\n\n function updatePlayerDetails() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n setPlayState(video.paused ? PlayState.Paused : PlayState.Playing);\n setDuration(video.duration);\n setCurrentTime(video.currentTime);\n if (!video.ended) {\n saveLastPlayedTime(video.currentTime);\n }\n mediaSessionUpdateDurationAndPosition(\n video.duration,\n video.currentTime,\n video.playbackRate,\n );\n if (\n video.networkState === video.NETWORK_LOADING &&\n video.readyState <= video.HAVE_FUTURE_DATA\n ) {\n setIsLoading(true);\n } else {\n setIsLoading(false);\n }\n callbacksRef.current.updateCurrentTime?.(video.currentTime);\n }\n\n // Lock-screen handlers are registered once; they read refs, so they always\n // see the current chapters and callbacks.\n useEffect(() => {\n startMediaSessionCoordinator({\n title: title ?? \"\",\n album: title,\n artist: author,\n artwork: imageURL,\n action: handleMediaSessionAction,\n });\n\n return () => {\n stopMediaSessionCoordinator();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // The book title, cover or author arrive after the details request.\n useEffect(() => {\n syncMediaSessionMetadata(currentChapterRef.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [title, author, imageURL]);\n\n useEffect(() => {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"error\", handleMediaElementError);\n video.addEventListener(\"timeupdate\", updatePlayerDetails);\n video.addEventListener(\"play\", updatePlayerDetails);\n video.addEventListener(\"pause\", updatePlayerDetails);\n video.addEventListener(\"ratechange\", updatePlayerDetails);\n\n updatePlayerDetails();\n timerRef.current = setInterval(updatePlayerDetails, 500);\n\n return () => {\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"error\", handleMediaElementError);\n video.removeEventListener(\"timeupdate\", updatePlayerDetails);\n video.removeEventListener(\"play\", updatePlayerDetails);\n video.removeEventListener(\"pause\", updatePlayerDetails);\n video.removeEventListener(\"ratechange\", updatePlayerDetails);\n if (timerRef.current != null) {\n clearInterval(timerRef.current);\n timerRef.current = undefined;\n }\n if (!video.ended) saveLastPlayedTime(video.currentTime);\n setCurrentTime(undefined);\n video.pause();\n destroyHls();\n video.removeAttribute(\"src\");\n video.load();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (setCurrentTimeHandler != null) {\n setCurrentTimeHandler(seekTo);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Compare by chapter ids and URLs: a new array with the same content must\n // not reload the stream or restart playback.\n const chaptersSignature = chapters\n .map((chapter) => `${chapter.id}|${chapter.publicUrl ?? \"\"}`)\n .join(\"\\n\");\n\n useEffect(() => {\n chaptersRef.current = chapters;\n const previousSignature = chaptersSignatureRef.current;\n if (previousSignature === chaptersSignature) {\n return;\n }\n chaptersSignatureRef.current = chaptersSignature;\n\n if (previousSignature == null) {\n loadChapters(chapters);\n return;\n }\n\n const current = currentChapterRef.current;\n if (current == null) {\n loadChapters(chapters);\n return;\n }\n const replacement = chapters.find((chapter) => chapter.id === current.id);\n if (replacement != null && replacement.publicUrl === current.publicUrl) {\n // Same stream, different array: keep playing.\n return;\n }\n if (replacement != null) {\n // A fresh signed URL for the chapter that is playing: keep the position\n // and whether it was playing.\n const video = videoRef.current;\n const position = video?.currentTime ?? 0;\n const wasPlaying = video != null && !video.paused;\n currentChapterRef.current = replacement;\n resumedRef.current = false;\n pendingSeekRef.current = position > 0 ? position : null;\n playWhenReadyRef.current = wasPlaying;\n loadSource(replacement.publicUrl);\n syncMediaSessionMetadata(replacement);\n callbacksRef.current.onChapterChange?.(replacement);\n setLastSelectedChapterID(replacement.id);\n return;\n }\n loadChapters(chapters);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [chaptersSignature]);\n\n useEffect(() => {\n switch (playState) {\n case PlayState.Playing:\n mediaSessionPlay();\n break;\n case PlayState.Paused:\n mediaSessionPause();\n break;\n }\n }, [playState]);\n\n const currentIndex = chapters.findIndex(\n (chapter) => chapter.id === chapterID,\n );\n const knownDuration =\n Number.isFinite(duration) && duration! > 0\n ? duration!\n : (chapters[currentIndex]?.duration ?? 0);\n const position = Math.min(\n Math.max(currentTime ?? 0, 0),\n knownDuration || Infinity,\n );\n const wholeBookKnown =\n chapters.length > 0 &&\n chapters.every(\n (chapter) => Number.isFinite(chapter.duration) && chapter.duration! > 0,\n );\n const remaining =\n Math.max(\n 0,\n knownDuration -\n position +\n (wholeBookKnown\n ? chapters\n .slice(currentIndex + 1)\n .reduce((sum, chapter) => sum + chapter.duration!, 0)\n : 0),\n ) / speed;\n const minutesLeft = Math.ceil(remaining / 60);\n const leftText = `${Math.floor(minutesLeft / 60) > 0 ? `${Math.floor(minutesLeft / 60)} h ` : \"\"}${minutesLeft % 60} min`;\n\n return (\n <div\n id=\"audio-player-container\"\n className=\"bitsnap-audio-player flex min-w-0 flex-col gap-3 text-neutral-900 dark:text-neutral-100\"\n style={\n {\n ...styles,\n \"--seek-before-width\": `${knownDuration > 0 ? (position / knownDuration) * 100 : 0}%`,\n } as CSSProperties\n }\n ref={audioPlayerContainerRef}\n data-player-error={playerError?.kind}\n >\n <video\n ref={videoRef}\n className=\"hidden\"\n poster={imageURL}\n title={title}\n />\n <div className={cn(\"flex min-w-0 items-center gap-3\", coverShownBeside && \"lg:hidden\")}>\n {imageURL && (\n <img\n src={imageURL}\n alt=\"\"\n className=\"h-16 w-16 shrink-0 rounded object-contain\"\n />\n )}\n <div className=\"min-w-0 break-words\">\n <p className=\"font-semibold\">\n {chapters[currentIndex]?.name ?? title}\n </p>\n {author && (\n <p className=\"text-sm text-neutral-600 dark:text-neutral-300\">\n {author}\n </p>\n )}\n </div>\n </div>\n {playerError && (\n <div\n role=\"alert\"\n className=\"rounded-lg bg-red-50 p-3 text-red-800 dark:bg-red-950 dark:text-red-200\"\n >\n <p>{t.error}</p>\n <Button variant=\"outline\" onClick={retry}>\n {t.retry}\n </Button>\n </div>\n )}\n <input\n type=\"range\"\n min=\"0\"\n max={knownDuration || 100}\n value={position}\n disabled={!knownDuration}\n aria-label={t.progress}\n aria-valuetext={`${formatTime(position)} ${t.of} ${formatTime(knownDuration)}`}\n onChange={(event) => seekTo(Number(event.target.value))}\n />\n <section className=\"flex w-full justify-between text-sm tabular-nums\">\n <span id=\"current-time\">{formatTime(position)}</span>\n <span id=\"duration\">{formatTime(knownDuration)}</span>\n </section>\n {knownDuration > 0 && (\n <p className=\"text-sm text-neutral-600 dark:text-neutral-300\">\n {t.left === \"left\"\n ? `${leftText} ${t.left}`\n : `${t.left} ${leftText}`}{\" \"}\n · {wholeBookKnown ? t.book : t.chapter} ({speed}×)\n </p>\n )}\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={playPreviousChapter}\n disabled={currentIndex < 0}\n aria-label={t.previous}\n >\n <SkipBack className=\"h-5 w-5\" />\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => seekBy(-SEEK_STEP_SECONDS)}\n aria-label={t.rewind}\n >\n −{SEEK_STEP_SECONDS}\n </Button>\n <Button\n variant=\"outline\"\n onClick={togglePlayState}\n aria-label={playState === PlayState.Paused ? t.play : t.pause}\n >\n {playState === PlayState.Paused ? (\n <Play className=\"h-5 w-5\" />\n ) : (\n <Pause className=\"h-5 w-5\" />\n )}\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => seekBy(SEEK_STEP_SECONDS)}\n aria-label={t.forward}\n >\n +{SEEK_STEP_SECONDS}\n </Button>\n <Button\n variant=\"outline\"\n onClick={playNextChapter}\n disabled={currentIndex < 0 || currentIndex >= chapters.length - 1}\n aria-label={t.next}\n >\n <SkipForward className=\"h-5 w-5\" />\n </Button>\n </div>\n <div className=\"flex flex-wrap gap-3 md:grid md:grid-cols-2\">\n <label className=\"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap\">\n {t.speed}\n <select\n aria-label={t.speed}\n value={speed}\n onChange={(event) => changeSpeed(Number(event.target.value))}\n >\n {SPEEDS.map((rate) => (\n <option key={rate} value={rate}>\n {rate}×\n </option>\n ))}\n </select>\n </label>\n <label className=\"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap\">\n {t.sleep}\n <select\n aria-label={t.sleep}\n value={sleepMode}\n onChange={(event) => changeSleep(event.target.value)}\n >\n <option value=\"off\">{t.off}</option>\n {[15, 30, 45, 60].map((minutes) => (\n <option key={minutes} value={minutes}>\n {minutes} min\n </option>\n ))}\n <option value=\"chapter\">{t.end}</option>\n </select>\n </label>\n </div>\n {sleepMode !== \"off\" && (\n <div className=\"flex items-center justify-between gap-2 text-sm\">\n <span role=\"timer\">\n {sleepMode === \"chapter\" ? t.end : formatTime(sleepRemaining)}\n </span>\n <Button variant=\"outline\" onClick={cancelSleep}>\n {t.cancel}\n </Button>\n </div>\n )}\n {isLoading && (\n <div role=\"status\" className=\"flex justify-center\">\n <LoadingIndicator />\n </div>\n )}\n </div>\n );\n },\n);\n\nexport default AudioPlayer;\n","export function LoadingIndicator() {\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 animate-bounce rounded-full bg-current [animation-delay:-0.3s]\" />\n <div className=\"h-3 w-3 animate-bounce rounded-full bg-current [animation-delay:-0.15s]\" />\n <div className=\"h-3 w-3 animate-bounce rounded-full bg-current\" />\n </div>\n );\n}\n\nexport default LoadingIndicator;\n","import Hls from \"hls.js\";\n\nexport type PlayerErrorKind = \"network\" | \"media\" | \"unknown\";\n\n/** Playback failure the parent can show and offer a retry for. */\nexport type PlayerError = {\n kind: PlayerErrorKind;\n status?: number;\n};\n\n/** Statuses a signed URL returns once it expired; the owner should refetch it. */\nconst EXPIRED_STATUSES = [401, 403];\n\n/** hls.js `ErrorTypes.NETWORK_ERROR`. */\nconst NETWORK_ERROR = \"networkError\";\n/** hls.js `ErrorTypes.MEDIA_ERROR`. */\nconst MEDIA_ERROR = \"mediaError\";\n\nexport type HlsErrorData = {\n fatal?: boolean;\n type?: string;\n response?: { code?: number };\n};\n\n/** The subset of the hls.js API the player uses; kept small so tests can fake it. */\nexport type HlsLike = {\n attachMedia: (media: HTMLMediaElement) => void;\n loadSource: (src: string) => void;\n startLoad: () => void;\n recoverMediaError: () => void;\n destroy: () => void;\n on: (event: string, listener: (event: string, data: HlsErrorData) => void) => void;\n};\n\nexport type HlsConstructor = {\n isSupported: () => boolean;\n Events: { ERROR: string };\n ErrorTypes: { NETWORK_ERROR: string; MEDIA_ERROR: string };\n new (): HlsLike;\n};\n\nexport type HlsErrorDecision =\n | { action: \"ignore\" }\n | { action: \"expired\"; error: PlayerError }\n | { action: \"restart-load\" }\n | { action: \"recover-media\" }\n | { action: \"fail\"; error: PlayerError };\n\n/**\n * What to do with an hls.js error. Only fatal errors matter: a signed URL that\n * expired asks the owner for a fresh one, a network failure gets one\n * `startLoad()` retry, a media failure one `recoverMediaError()` retry, and\n * anything else is reported to the parent.\n */\nexport function decideHlsError(\n data: HlsErrorData | null | undefined,\n retried: { network: boolean; media: boolean },\n): HlsErrorDecision {\n if (data == null || data.fatal !== true) {\n return { action: \"ignore\" };\n }\n const status = data.response?.code;\n const kind: PlayerErrorKind =\n data.type === NETWORK_ERROR\n ? \"network\"\n : data.type === MEDIA_ERROR\n ? \"media\"\n : \"unknown\";\n const error: PlayerError = status == null ? { kind } : { kind, status };\n\n if (status != null && EXPIRED_STATUSES.includes(status)) {\n return { action: \"expired\", error: { kind: \"network\", status } };\n }\n if (data.type === NETWORK_ERROR && !retried.network) {\n return { action: \"restart-load\" };\n }\n if (data.type === MEDIA_ERROR && !retried.media) {\n return { action: \"recover-media\" };\n }\n return { action: \"fail\", error };\n}\n\nexport type HlsSourceHandlers = {\n /** A fatal error the player could not recover from. */\n onError?: (error: PlayerError) => void;\n /** The signed URL was refused (401/403); the owner should refetch it. */\n onExpiredUrl?: () => void;\n};\n\nexport type HlsSource = {\n load: (src: string) => void;\n /** Loads the current source again, giving the error retries a new chance. */\n retry: () => void;\n destroy: () => void;\n readonly src: string | undefined;\n};\n\n/**\n * hls.js playback for one media element, mirroring the course `VideoPlayer`:\n * one network retry, one media recovery, expired URLs handed to the owner.\n * `HlsCtor` is injectable so the error paths can be tested without a stream.\n */\nexport function createHlsSource(args: {\n media: HTMLMediaElement;\n handlers?: HlsSourceHandlers;\n HlsCtor?: HlsConstructor;\n}): HlsSource {\n const HlsImpl = args.HlsCtor ?? (Hls as unknown as HlsConstructor);\n const instance = new HlsImpl();\n let src: string | undefined;\n let retriedNetwork = false;\n let retriedMedia = false;\n\n instance.attachMedia(args.media);\n instance.on(HlsImpl.Events.ERROR, (_event, data) => {\n const decision = decideHlsError(data, {\n network: retriedNetwork,\n media: retriedMedia,\n });\n switch (decision.action) {\n case \"expired\":\n args.handlers?.onExpiredUrl?.();\n args.handlers?.onError?.(decision.error);\n break;\n case \"restart-load\":\n retriedNetwork = true;\n instance.startLoad();\n break;\n case \"recover-media\":\n retriedMedia = true;\n instance.recoverMediaError();\n break;\n case \"fail\":\n args.handlers?.onError?.(decision.error);\n break;\n case \"ignore\":\n break;\n }\n });\n\n return {\n load(nextSrc) {\n src = nextSrc;\n retriedNetwork = false;\n retriedMedia = false;\n instance.loadSource(nextSrc);\n },\n retry() {\n if (src == null) {\n return;\n }\n retriedNetwork = false;\n retriedMedia = false;\n instance.loadSource(src);\n },\n destroy() {\n instance.destroy();\n },\n get src() {\n return src;\n },\n };\n}\n\n/** True when the element plays HLS itself (Safari, iOS); no user-agent sniffing. */\nexport function prefersNativeHls(\n video: Pick<HTMLMediaElement, \"canPlayType\">,\n): boolean {\n try {\n return video.canPlayType(\"application/vnd.apple.mpegurl\") !== \"\";\n } catch (e) {\n return false;\n }\n}\n\n/** Maps a media element `MediaError` to the error the parent sees. */\nexport function playerErrorFromMediaError(\n mediaError: MediaError | null | undefined,\n): PlayerError {\n switch (mediaError?.code) {\n case 2:\n return { kind: \"network\" };\n case 3:\n case 4:\n return { kind: \"media\" };\n default:\n return { kind: \"unknown\" };\n }\n}\n","/** Skip length of the player buttons and of the lock-screen skip handlers. */\nexport const SEEK_STEP_SECONDS = 10;\n\n/** Under this position \"previous track\" restarts the chapter instead of going back. */\nexport const PREVIOUS_TRACK_RESTART_SECONDS = 3;\n\nexport type MediaSessionArtwork = {\n src: string;\n sizes?: string;\n type?: string;\n};\n\nexport type MediaSessionMetadata = {\n title: string;\n album?: string;\n artist?: string;\n artwork?: string | MediaSessionArtwork | (string | MediaSessionArtwork)[];\n};\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n avif: \"image/avif\",\n svg: \"image/svg+xml\",\n};\n\n/** Lock-screen artwork size we declare; the player does not decode the image. */\nconst ARTWORK_SIZES = \"512x512\";\n\nfunction mediaSessionAvailable(): boolean {\n return (\n typeof navigator != \"undefined\" &&\n typeof navigator.mediaSession != \"undefined\"\n );\n}\n\n/**\n * Turns an image URL into a media-session artwork entry. The `type` comes from\n * the file extension and is omitted when the extension is unknown, so the\n * browser does not get a wrong MIME type.\n */\nexport function mediaSessionArtworkFromUrl(url: string): MediaSessionArtwork {\n if (typeof url != \"string\" || url.length === 0) {\n return { src: url, sizes: ARTWORK_SIZES };\n }\n const withoutQuery = url.split(/[?#]/)[0];\n const extension = withoutQuery.includes(\".\")\n ? withoutQuery.slice(withoutQuery.lastIndexOf(\".\") + 1).toLowerCase()\n : \"\";\n const type = MIME_BY_EXTENSION[extension];\n const artwork: MediaSessionArtwork = { src: url, sizes: ARTWORK_SIZES };\n if (type != null) {\n artwork.type = type;\n }\n return artwork;\n}\n\nfunction normalizeArtwork(\n artwork: MediaSessionMetadata[\"artwork\"],\n): MediaSessionArtwork[] | undefined {\n if (artwork == null) {\n return undefined;\n }\n const entries = Array.isArray(artwork) ? artwork : [artwork];\n const normalized: MediaSessionArtwork[] = [];\n for (const entry of entries) {\n if (typeof entry === \"string\") {\n if (entry.length > 0) {\n normalized.push(mediaSessionArtworkFromUrl(entry));\n }\n continue;\n }\n if (entry != null && entry.src.length > 0) {\n normalized.push({\n src: entry.src,\n sizes: entry.sizes ?? ARTWORK_SIZES,\n ...(entry.type != null ? { type: entry.type } : {}),\n });\n }\n }\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function mediaSessionSetMetadata(metadata: MediaSessionMetadata) {\n if (\n !mediaSessionAvailable() ||\n typeof MediaMetadata == \"undefined\"\n ) {\n return;\n }\n navigator.mediaSession.metadata = new MediaMetadata({\n title: metadata.title,\n album: metadata.album,\n artist: metadata.artist,\n artwork: normalizeArtwork(metadata.artwork),\n });\n}\n\nexport function mediaSessionPlay() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.playbackState = \"playing\";\n}\n\nexport function mediaSessionPause() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.playbackState = \"paused\";\n}\n\n/**\n * Reports duration, position and the real playback rate to the lock screen.\n * `setPositionState` throws on values it does not accept (no duration yet,\n * position past the end), so those calls are skipped or clamped.\n */\nexport function mediaSessionUpdateDurationAndPosition(\n duration: number | undefined,\n currentTime: number | undefined,\n playbackRate = 1,\n) {\n if (!mediaSessionAvailable()) return;\n if (duration == null || !Number.isFinite(duration) || duration <= 0) {\n return;\n }\n if (currentTime != null && isNaN(currentTime)) {\n return;\n }\n const position = Math.min(Math.max(currentTime ?? 0, 0), duration);\n const rate =\n Number.isFinite(playbackRate) && playbackRate > 0 ? playbackRate : 1;\n try {\n navigator.mediaSession.setPositionState({\n playbackRate: rate,\n duration,\n position,\n });\n } catch (e) {\n // Older browsers reject some combinations; the lock screen just keeps the\n // previous state.\n }\n}\n\nconst MEDIA_SESSION_ACTIONS: MediaSessionAction[] = [\n \"play\",\n \"pause\",\n \"stop\",\n \"seekbackward\",\n \"seekforward\",\n \"seekto\",\n \"previoustrack\",\n \"nexttrack\",\n];\n\nexport function startMediaSessionCoordinator(args: {\n title: string;\n album?: string;\n artist?: string;\n artwork?: MediaSessionMetadata[\"artwork\"];\n\n action: (details: MediaSessionActionDetails) => void;\n}) {\n if (!mediaSessionAvailable()) return;\n\n mediaSessionSetMetadata({\n title: args.title,\n album: args.album,\n artist: args.artist,\n artwork: args.artwork,\n });\n\n for (const action of MEDIA_SESSION_ACTIONS) {\n try {\n navigator.mediaSession.setActionHandler(action, (details) => {\n args.action(details);\n });\n } catch (e) {\n // The browser does not support this action (e.g. nexttrack).\n }\n }\n}\n\nexport function stopMediaSessionCoordinator() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.metadata = null;\n for (const action of MEDIA_SESSION_ACTIONS) {\n try {\n navigator.mediaSession.setActionHandler(action, null);\n } catch (e) {\n // Unsupported action; nothing to clear.\n }\n }\n}\n","import { getLocale } from \"../../components/checkout/locale\";\nimport { useEffect, useState } from \"react\";\n\nconst pl = {\n play: \"Odtwórz\",\n pause: \"Wstrzymaj\",\n previous: \"Poprzedni rozdział\",\n next: \"Następny rozdział\",\n rewind: \"Cofnij o 10 sekund\",\n forward: \"Przewiń o 10 sekund\",\n progress: \"Postęp odtwarzania\",\n of: \"z\",\n speed: \"Prędkość\",\n sleep: \"Wyłącznik czasowy\",\n off: \"Wyłączony\",\n end: \"Koniec rozdziału\",\n cancel: \"Anuluj wyłącznik\",\n error: \"Nie udało się odtworzyć nagrania.\",\n retry: \"Spróbuj ponownie\",\n left: \"zostało\",\n book: \"cała książka\",\n chapter: \"rozdział\",\n chapters: \"Rozdziały\",\n loading: \"Ładowanie rozdziałów…\",\n empty: \"Brak rozdziałów do wyświetlenia.\",\n resume: \"Kontynuuj\",\n chapterName: \"Rozdział\",\n download: \"Pobierz rozdział\",\n playing: \"Teraz odtwarzane\",\n played: \"Odsłuchane\",\n};\nconst en: typeof pl = {\n play: \"Play\",\n pause: \"Pause\",\n previous: \"Previous chapter\",\n next: \"Next chapter\",\n rewind: \"Rewind 10 seconds\",\n forward: \"Forward 10 seconds\",\n progress: \"Playback progress\",\n of: \"of\",\n speed: \"Speed\",\n sleep: \"Sleep timer\",\n off: \"Off\",\n end: \"End of chapter\",\n cancel: \"Cancel timer\",\n error: \"The recording could not be played.\",\n retry: \"Try again\",\n left: \"left\",\n book: \"whole book\",\n chapter: \"chapter\",\n chapters: \"Chapters\",\n loading: \"Loading chapters…\",\n empty: \"No chapters to display.\",\n resume: \"Continue\",\n chapterName: \"Chapter\",\n download: \"Download chapter\",\n playing: \"Now playing\",\n played: \"Played\",\n};\nexport function useAudioTexts(locale?: string) {\n // Storage is consulted only after mount, including when rendered on the server.\n const [deviceLocale, setDeviceLocale] = useState(\"pl\");\n useEffect(() => {\n try {\n setDeviceLocale(getLocale());\n } catch {\n /* Storage may be disabled. */\n }\n }, []);\n return (locale ?? deviceLocale).toLowerCase().startsWith(\"en\") ? en : pl;\n}\nexport function formatTime(value: number) {\n const seconds = Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n return `${seconds >= 3600 ? `${Math.floor(seconds / 3600)}:` : \"\"}${String(Math.floor(seconds / 60) % 60).padStart(2, \"0\")}:${String(seconds % 60).padStart(2, \"0\")}`;\n}\n","/** Device-only listening memory; blocked/full storage must never stop playback. */\nexport const playerStorage = {\n get(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n set(key: string, value: string) {\n try {\n localStorage.setItem(key, value);\n } catch {\n /* Optional memory. */\n }\n },\n remove(key: string) {\n try {\n localStorage.removeItem(key);\n } catch {\n /* Optional memory. */\n }\n },\n};\nexport const SPEED_KEY = \"__player__speed\";\nexport const SPEEDS = [0.75, 1, 1.25, 1.5, 1.75, 2];\n","import { Check, Download, Play } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport type { ChapterWithPublicUrl } from \"./AudioPlayer\";\nimport { playerStorage } from \"./storage\";\nimport { formatTime, useAudioTexts } from \"./texts\";\n\nexport default function ChapterList({\n chapters,\n currentID,\n productID,\n onSelect,\n downloadable,\n onDownload,\n loading,\n locale,\n}: {\n chapters: ChapterWithPublicUrl[] | null;\n currentID?: string;\n productID: string;\n onSelect: (chapter: ChapterWithPublicUrl) => void;\n downloadable?: boolean;\n onDownload?: () => void;\n loading?: boolean;\n locale?: string;\n}) {\n const t = useAudioTexts(locale);\n const [resume, setResume] = useState<{ id: string; time: number } | null>(\n null,\n );\n const [played, setPlayed] = useState<string[]>([]);\n useEffect(() => {\n const prefix = `__player__${productID}_`;\n const id = playerStorage.get(`${prefix}last_chapter`);\n const time = Number(id && playerStorage.get(`${prefix}${id}`));\n setResume(id && time > 0 && Number.isFinite(time) ? { id, time } : null);\n setPlayed(\n (chapters ?? [])\n .filter(\n (chapter) =>\n playerStorage.get(`${prefix}${chapter.id}_completed`) === \"true\" ||\n Number(playerStorage.get(`${prefix}${chapter.id}`)) > 0,\n )\n .map((chapter) => chapter.id),\n );\n }, [chapters, productID, currentID]);\n const resumeIndex =\n chapters?.findIndex((chapter) => chapter.id === resume?.id) ?? -1;\n const currentIndex =\n chapters?.findIndex((chapter) => chapter.id === currentID) ?? -1;\n return (\n <div className=\"max-h-96 w-full overflow-y-auto\">\n <h2 className=\"mb-3 text-xl font-semibold\">{t.chapters}</h2>\n {loading ? (\n <p role=\"status\">{t.loading}</p>\n ) : !chapters?.length ? (\n <p>{t.empty}</p>\n ) : (\n <>\n {resume && resumeIndex >= 0 && (\n <button\n type=\"button\"\n className=\"mb-3 min-h-11 rounded-lg border border-neutral-300 px-3 py-2 text-left dark:border-neutral-600\"\n onClick={() => onSelect(chapters[resumeIndex])}\n >\n {t.resume}: {t.chapterName} {resumeIndex + 1},{\" \"}\n {formatTime(resume.time)}\n </button>\n )}\n <ul className=\"flex w-full flex-col gap-2\">\n {chapters.map((chapter, index) => {\n const current = chapter.id === currentID;\n const isPlayed =\n index < currentIndex || played.includes(chapter.id);\n return (\n <li\n key={chapter.id}\n className=\"flex min-w-0 items-center gap-2\"\n >\n <button\n type=\"button\"\n aria-current={current ? \"true\" : undefined}\n className={`min-h-11 min-w-0 flex-1 rounded-lg p-3 text-left hover:bg-neutral-200 dark:hover:bg-neutral-700 ${current ? \"bg-neutral-200 dark:bg-neutral-700\" : \"bg-neutral-100 dark:bg-neutral-800\"}`}\n onClick={() => onSelect(chapter)}\n >\n <span className=\"flex items-center gap-2\">\n {current ? (\n <Play\n className=\"size-4 shrink-0\"\n aria-label={t.playing}\n />\n ) : isPlayed ? (\n <Check\n className=\"size-4 shrink-0\"\n aria-label={t.played}\n />\n ) : null}\n <span className=\"min-w-0 flex-1 break-words text-sm font-medium\">\n {chapter.name}\n </span>\n {!!chapter.duration && (\n <span className=\"shrink-0 text-xs tabular-nums text-neutral-600 dark:text-neutral-300\">\n {formatTime(chapter.duration)}\n </span>\n )}\n </span>\n {chapter.description && (\n <span className=\"mt-2 block text-xs\">\n {chapter.description}\n </span>\n )}\n </button>\n {downloadable && chapter.downloadableUrl && (\n <a\n href={chapter.downloadableUrl}\n onClick={onDownload}\n aria-label={`${t.download} ${index + 1}`}\n className=\"inline-flex min-h-11 min-w-11 items-center justify-center rounded focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\"\n >\n <Download className=\"size-4\" aria-hidden=\"true\" />\n </a>\n )}\n </li>\n );\n })}\n </ul>\n </>\n )}\n </div>\n );\n}\n","import { useTransport } from \"@connectrpc/connect-query\";\nimport { useEffect, useState } from \"react\";\n\nimport type { PurchasedModel } from \"../../gen/proto/public/v1/model_delivery_pb\";\n\n/** What the 3D files call ended with; `hidden` = no 3D delivery on the server (or it failed). */\nexport type ModelFilesLoad =\n | { status: \"loading\" }\n | { status: \"hidden\" }\n | { status: \"unauthorized\" }\n | { status: \"ready\"; models: PurchasedModel[] };\n\n/**\n * The buyer's 3D files, once per token. The RPC client is loaded with\n * `import()`, so pages that never mount the panel products screen do not\n * carry it.\n */\nexport function useModelFiles(\n accessToken: string,\n projectID: string,\n): ModelFilesLoad {\n const transport = useTransport();\n const [load, setLoad] = useState<ModelFilesLoad>({ status: \"loading\" });\n\n useEffect(() => {\n if (!accessToken) {\n setLoad({ status: \"hidden\" });\n return;\n }\n let cancelled = false;\n setLoad({ status: \"loading\" });\n import(\"./model-files-client\")\n .then(({ listModelFiles }) => listModelFiles(transport, accessToken, projectID))\n .catch((): ModelFilesLoad => ({ status: \"hidden\" }))\n .then((next) => {\n if (!cancelled) setLoad(next);\n });\n return () => {\n cancelled = true;\n };\n }, [transport, accessToken, projectID]);\n\n return load;\n}\n","import { LogOut } from \"lucide-react\";\nimport type { CSSProperties } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { LoginBrandLogo, useLoginBranding } from \"../../ui/email-code-login/LoginBrandLogo\";\nimport type { GetThemeOutput, PanelScreen } from \"../types\";\nimport { getPanelTexts } from \"../texts\";\nimport { panelNavItems, navScreen } from \"./nav/items\";\n\ninterface PanelProductHeaderComponentProps {\n activeScreen: PanelScreen;\n setActiveScreen: (screen: PanelScreen) => void;\n setParams: (params: { product?: string; state: PanelScreen }) => void;\n styles: CSSProperties;\n theme?: GetThemeOutput;\n logout: () => void;\n email?: string | null;\n projectID?: string;\n}\n\nexport default function PanelProductHeaderComponent({\n activeScreen,\n setActiveScreen,\n setParams,\n theme,\n logout,\n email,\n projectID,\n}: PanelProductHeaderComponentProps) {\n const texts = getPanelTexts();\n const { data: branding } = useLoginBranding(projectID ?? \"\", Boolean(projectID));\n return (\n <header className=\"flex h-14 shrink-0 items-center border-b border-neutral-200 bg-white px-4 md:h-dvh md:w-56 md:flex-col md:items-stretch md:border-r md:border-b-0 md:py-5 dark:border-neutral-800 dark:bg-neutral-900\">\n <div className=\"flex min-w-0 items-center gap-3 md:mb-6 md:flex-col md:items-start\">\n <LoginBrandLogo projectId={projectID} logoUrl={theme?.logoURL} logoDarkUrl={theme?.logoDarkURL} name={branding?.name} className=\"shrink-0\" />\n {branding?.name && <span title={branding.name} className=\"truncate text-sm font-medium md:line-clamp-2 md:whitespace-normal\">{branding.name}</span>}\n </div>\n <nav aria-label={texts.navigationLabel} className=\"fixed inset-x-0 bottom-0 z-10 flex h-[calc(56px+env(safe-area-inset-bottom))] items-start justify-around border-t border-neutral-200 bg-white pb-[env(safe-area-inset-bottom)] md:static md:h-auto md:flex-1 md:flex-col md:justify-start md:gap-2 md:border-0 md:bg-transparent md:pb-0 dark:border-neutral-800 dark:bg-neutral-900\">\n {panelNavItems.map(({ screen, label, icon: Icon }) => {\n const active = navScreen(activeScreen) === screen;\n return (\n <button\n key={screen}\n type=\"button\"\n aria-current={active ? \"page\" : undefined}\n onClick={() => {\n setActiveScreen(screen);\n setParams({ product: undefined, state: screen });\n }}\n className={cn(\"flex h-14 min-h-11 min-w-0 flex-1 flex-col items-center justify-center gap-1 px-1 text-[11px] focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-current md:h-11 md:w-full md:flex-none md:flex-row md:justify-start md:gap-3 md:rounded-md md:px-3 md:text-sm\", active ? \"bg-neutral-100 font-semibold text-black dark:bg-neutral-800 dark:text-white\" : \"text-neutral-600 hover:bg-neutral-100 dark:text-neutral-400 dark:hover:bg-neutral-800\")}>\n <Icon className=\"h-5 w-5 shrink-0\" aria-hidden=\"true\" />\n <span>{texts[label]}</span>\n </button>\n );\n })}\n </nav>\n <div className=\"hidden border-t border-neutral-200 pt-4 md:block dark:border-neutral-800\">\n {email && <p title={email} className=\"mb-3 truncate text-sm text-neutral-600 dark:text-neutral-400\">{email}</p>}\n <button type=\"button\" onClick={logout} className=\"flex min-h-11 w-full items-center gap-3 rounded-md px-3 text-sm text-red-700 hover:bg-red-50 focus-visible:outline-2 focus-visible:outline-current dark:text-red-400 dark:hover:bg-neutral-800\">\n <LogOut className=\"h-4 w-4\" aria-hidden=\"true\" />{texts.logout}\n </button>\n </div>\n </header>\n );\n}\n","import { Library, Receipt, Undo2, User } from \"lucide-react\";\nimport type { PanelTexts } from \"../../texts\";\nimport type { PanelScreen } from \"../../types\";\n\nexport const panelNavItems = [\n { screen: \"products\", label: \"libraryNavLabel\", icon: Library },\n { screen: \"orders\", label: \"ordersNavLabel\", icon: Receipt },\n { screen: \"returns\", label: \"returnsNavLabel\", icon: Undo2 },\n { screen: \"profile\", label: \"accountNavLabel\", icon: User },\n] as const satisfies ReadonlyArray<{ screen: PanelScreen; label: keyof PanelTexts; icon: typeof Library }>;\n\nexport function navScreen(screen: PanelScreen): PanelScreen {\n if (screen === \"course\") return \"products\";\n if (screen === \"order-details\") return \"orders\";\n if (screen === \"return-details\") return \"returns\";\n return screen;\n}\n","import { useState } from \"react\";\nimport { LogOut } from \"lucide-react\";\nimport { getLocale, setLocale } from \"../../components/checkout/locale\";\nimport { getPanelTexts } from \"../texts\";\n\ninterface PanelProfileComponentProps { email: string | null; logout: () => void; onLocaleChange?: () => void; }\n\nexport default function PanelProfileComponent({ email, logout, onLocaleChange }: PanelProfileComponentProps) {\n const [locale, updateLocale] = useState(getLocale);\n const texts = getPanelTexts(locale);\n return <section className=\"w-full max-w-xl\">\n <h3 className=\"text-2xl\">{texts.accountNavLabel}</h3>\n <h4 className=\"mt-6 mb-2 text-sm font-medium text-neutral-600 dark:text-neutral-400\">{texts.profileHeading}</h4>\n <div className=\"divide-y divide-neutral-200 rounded-lg border border-neutral-200 bg-white dark:divide-neutral-800 dark:border-neutral-800 dark:bg-neutral-900\">\n <div className=\"p-4\"><p className=\"text-sm text-neutral-600 dark:text-neutral-400\">{texts.emailLabel}</p><p className=\"mt-1 break-words\">{email || texts.noData}</p></div>\n <label className=\"flex min-h-11 flex-wrap items-center justify-between gap-3 p-4\">\n <span>{texts.languageLabel}</span>\n <select value={locale.toLowerCase().startsWith(\"en\") ? \"en-US\" : \"pl-PL\"} onChange={(event) => { setLocale(event.target.value); updateLocale(event.target.value); onLocaleChange?.(); }} className=\"min-h-11 rounded-md border border-neutral-300 bg-white px-3 focus-visible:outline-2 focus-visible:outline-current dark:border-neutral-700 dark:bg-neutral-900\">\n <option value=\"pl-PL\">{texts.polishLanguage}</option><option value=\"en-US\">{texts.englishLanguage}</option>\n </select>\n </label>\n </div>\n <button type=\"button\" onClick={logout} className=\"mt-6 flex min-h-11 w-full items-center gap-3 rounded-lg border border-neutral-200 bg-white px-4 py-3 text-red-700 hover:bg-red-50 focus-visible:outline-2 focus-visible:outline-current dark:border-neutral-800 dark:bg-neutral-900 dark:text-red-400 dark:hover:bg-neutral-800\"><LogOut className=\"h-5 w-5\" aria-hidden=\"true\" />{texts.logout}</button>\n </section>;\n}\n","import { lazy, Suspense } from \"react\";\nimport type { PanelCourseProps } from \"../../course\";\nimport LoadingIndicator from \"../LoadingIndicator\";\n\n// The course view (video player, sanitizer, tests) is loaded when a customer\n// opens a course, so it does not weigh on the rest of the panel.\nconst PanelCourse = lazy(() =>\n import(\"../../course\").then((module) => ({\n default: module.PanelCourse,\n })),\n);\n\n/** `PanelCourse` loaded on demand. */\nexport default function LazyPanelCourse(props: PanelCourseProps) {\n return (\n <Suspense\n fallback={\n <div className=\"flex items-center gap-2 p-2\" role=\"status\">\n <LoadingIndicator />\n </div>\n }\n >\n <div className=\"[--course-mobile-bottom:calc(56px+env(safe-area-inset-bottom))] md:[--course-mobile-bottom:0px]\">\n <PanelCourse {...props} />\n </div>\n </Suspense>\n );\n}\n","import {\n AlertCircle,\n CheckCircle2,\n ChevronLeft,\n Loader2,\n Lock,\n Package,\n Truck,\n} from \"lucide-react\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\nimport { useInstrument, type AnalyticsOption } from \"../../analytics/instrument\";\nimport { rpcProvider, useMutation, useQuery } from \"../../rpc-provider\";\nimport { Button } from \"../../ui/button\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../../ui/card\";\nimport { Input } from \"../../ui/input\";\nimport { Label } from \"../../ui/label\";\nimport { Textarea } from \"../../ui/textarea\";\n\nimport { usePanelConfig } from \"../PanelProvider\";\n\ninterface Props {\n orderID: string;\n initialEmail?: string;\n accessToken?: string;\n onBack?: () => void;\n /**\n * Usage statistics for your Bitsnap dashboard (order viewed). Inside\n * `<Panel>` or `<PanelProvider>` their setting applies unless this is given.\n */\n analytics?: AnalyticsOption;\n}\n\nfunction StatusBadge({ status }: { status: string }) {\n const statusConfig: Record<\n string,\n { color: string; icon: typeof AlertCircle | null }\n > = {\n created: { color: \"bg-neutral-100 text-neutral-700\", icon: null },\n paid: { color: \"bg-green-100 text-green-700\", icon: CheckCircle2 },\n completed: { color: \"bg-blue-100 text-blue-700\", icon: CheckCircle2 },\n canceled: { color: \"bg-red-100 text-red-700\", icon: AlertCircle },\n sent: { color: \"bg-purple-100 text-purple-700\", icon: Truck },\n processing: { color: \"bg-yellow-100 text-yellow-700\", icon: Loader2 },\n };\n\n const config = statusConfig[status] || statusConfig.created;\n const Icon = config.icon;\n\n const statusLabels: Record<string, string> = {\n created: \"Utworzone\",\n paid: \"Opłacone\",\n completed: \"Zakończone\",\n canceled: \"Anulowane\",\n sent: \"Wysłane\",\n processing: \"Przetwarzane\",\n };\n\n return (\n <span\n className={`inline-flex items-center gap-1 rounded-full px-3 py-1 text-sm font-medium ${config.color}`}\n >\n {Icon && <Icon className=\"h-4 w-4\" />}\n {statusLabels[status] || status}\n </span>\n );\n}\n\nfunction AddCommentForm({\n orderID,\n email,\n}: {\n orderID: string;\n email: string;\n}) {\n const [message, setMessage] = useState(\"\");\n const addCommentMutation = useMutation(\n rpcProvider.publicApi.addPublicOrderComment,\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!message.trim()) return;\n\n try {\n await addCommentMutation.mutateAsync({\n projectId: \"\",\n orderId: orderID,\n message: message.trim(),\n accessToken: email,\n });\n setMessage(\"\");\n } catch (error) {\n console.error(\"Failed to add comment:\", error);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"mt-4 space-y-2\">\n <Label htmlFor=\"comment\">Dodaj komentarz</Label>\n <Textarea\n id=\"comment\"\n value={message}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n setMessage(e.target.value)\n }\n placeholder=\"Wpisz komentarz...\"\n rows={3}\n disabled={addCommentMutation.isPending}\n />\n <Button\n type=\"submit\"\n disabled={!message.trim() || addCommentMutation.isPending}\n >\n {addCommentMutation.isPending ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Wysyłanie...\n </>\n ) : (\n \"Dodaj komentarz\"\n )}\n </Button>\n </form>\n );\n}\n\nfunction formatDate(timestamp: { seconds: bigint } | undefined): string {\n if (!timestamp) return \"N/A\";\n const date = new Date(Number(timestamp.seconds) * 1000);\n return date.toLocaleDateString(\"pl-PL\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nfunction formatCurrency(amount: number, currency: string): string {\n return new Intl.NumberFormat(\"pl-PL\", {\n style: \"currency\",\n currency: currency.toUpperCase(),\n }).format(amount / 100);\n}\n\nfunction PublicOrderPageContent({\n orderID,\n initialEmail,\n onBack,\n accessToken,\n analytics,\n}: Props) {\n const { theme, projectID } = usePanelConfig();\n const instrument = useInstrument(projectID, analytics, \"order\");\n\n const [verifyEmail, setVerifyEmail] = useState(initialEmail || \"\");\n const [isVerifyDialogOpen, setIsVerifyDialogOpen] = useState(false);\n\n const {\n data: orderData,\n isLoading,\n error,\n refetch,\n } = useQuery(\n rpcProvider.publicApi.getPublicOrderDetails,\n {\n projectId: projectID ?? \"\",\n orderId: orderID,\n email: verifyEmail || undefined,\n accessToken: accessToken,\n },\n { enabled: !!orderID },\n );\n\n const order =\n orderData?.result.case === \"order\" ? orderData.result.value : null;\n const isVerified = order?.isVerified ?? false;\n\n const viewedOrder = order != null;\n useEffect(() => {\n if (viewedOrder) {\n // The id in the URL may be an access token: report no order reference.\n instrument.track(\"panel_order_viewed\", {}, { order_ref: null });\n }\n }, [instrument, viewedOrder]);\n\n const handleVerifyEmail = () => {\n refetch();\n setIsVerifyDialogOpen(false);\n };\n\n const styles = {\n \"--button-background-color\": theme?.colors?.brand ?? \"#000000\",\n \"--button-background-color-dark\": theme?.colors?.brandDark ?? \"#ffffff\",\n \"--button-text-color\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color-dark\": theme?.colors?.brand ?? \"#000000\",\n } as CSSProperties;\n\n if (isLoading) {\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <div className=\"text-center\">\n <Loader2 className=\"mx-auto h-8 w-8 animate-spin text-neutral-400\" />\n <p className=\"mt-2 text-neutral-600 dark:text-neutral-400\">\n Ładowanie zamówienia...\n </p>\n </div>\n </div>\n );\n }\n\n if (error || !order) {\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <Card className=\"w-full max-w-md\">\n <CardContent className=\"pt-6\">\n <div className=\"text-center\">\n <AlertCircle className=\"mx-auto h-12 w-12 text-red-500\" />\n <h2 className=\"mt-4 text-xl font-semibold\">\n Zamówienie nie znalezione\n </h2>\n <p className=\"mt-2 text-neutral-600 dark:text-neutral-400\">\n Nie znaleziono zamówienia o podanym numerze.\n </p>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n }\n\n return (\n <div className=\"w-full bg-white py-8 dark:bg-black\" style={styles}>\n <div className=\"w-full px-4\">\n {onBack && (\n <Button onClick={onBack} variant=\"ghost\" className=\"mb-4 w-fit\">\n <ChevronLeft className=\"h-4 w-4\" />\n Wróć do historii zamówień\n </Button>\n )}\n <div className=\"mb-6 flex items-center gap-4\">\n {theme?.logoURL && (\n <>\n <img\n src={theme.logoURL}\n alt=\"Project logo\"\n className={`h-12 w-auto ${theme.logoDarkURL ? \"dark:hidden\" : \"\"}`}\n />\n {theme.logoDarkURL && (\n <img\n src={theme.logoDarkURL}\n alt=\"Project logo\"\n className=\"hidden h-12 w-auto dark:block\"\n />\n )}\n </>\n )}\n <div>\n <h1 className=\"text-3xl font-bold\">Zamówienie</h1>\n <p className=\"text-neutral-600 dark:text-neutral-400\">\n Numer zamówienia: #{order.orderId}\n </p>\n </div>\n </div>\n\n <Card className=\"mb-6\">\n <CardHeader>\n <CardTitle className=\"flex items-center\">\n <Package className=\"mr-2 h-5 w-5\" />\n Status zamówienia\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div>\n <div className=\"flex items-center gap-2\">\n <StatusBadge status={order.status} />\n {order.processingStatus && (\n <span className=\"text-sm text-neutral-600\">\n · {order.processingStatus}\n </span>\n )}\n </div>\n <p className=\"mt-2 text-sm text-neutral-600\">\n Zamówienie złożone {formatDate(order.createdAt)}\n </p>\n </div>\n\n <div className=\"border-t pt-4\">\n <h3 className=\"mb-3 font-semibold\">Dane klienta</h3>\n <div className=\"space-y-2\">\n <div>\n <span className=\"font-medium\">Imię i nazwisko:</span>{\" \"}\n <span className={!isVerified ? \"text-neutral-500\" : \"\"}>\n {order.customerName}\n </span>\n </div>\n <div>\n <span className=\"font-medium\">Email:</span>{\" \"}\n <span className={!isVerified ? \"text-neutral-500\" : \"\"}>\n {order.customerEmail}\n </span>\n </div>\n {order.customerPhone && (\n <div>\n <span className=\"font-medium\">Telefon:</span>{\" \"}\n <span className={!isVerified ? \"text-neutral-500\" : \"\"}>\n {order.customerPhone}\n </span>\n </div>\n )}\n </div>\n </div>\n\n {!isVerified && (\n <div className=\"border-t pt-4\">\n <Button\n onClick={() => setIsVerifyDialogOpen(true)}\n variant=\"outline\"\n className=\"w-full\"\n >\n <Lock className=\"mr-2 h-4 w-4\" />\n Zweryfikuj swój email\n </Button>\n </div>\n )}\n </CardContent>\n </Card>\n\n <Card className=\"mb-6\">\n <CardHeader>\n <CardTitle>Produkty</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-6\">\n <div className=\"space-y-4\">\n {order.items.map((item, index) => (\n <div key={index} className=\"flex items-center gap-4\">\n {item.imageUrl && (\n <img\n src={item.imageUrl}\n alt={item.name}\n className=\"h-16 w-16 rounded object-cover\"\n />\n )}\n <div className=\"flex-1\">\n <p className=\"font-medium\">{item.name}</p>\n <p className=\"text-sm text-neutral-600\">\n Ilość: {item.quantity}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"font-medium\">\n {formatCurrency(Number(item.price), item.currency)}\n </p>\n </div>\n </div>\n ))}\n </div>\n\n {(order.deliveryAddress || order.deliveryMethod) && (\n <div className=\"border-t pt-4\">\n <h3 className=\"mb-3 flex items-center font-semibold\">\n <Truck className=\"mr-2 h-5 w-5\" />\n Informacje o dostawie\n </h3>\n <div className=\"space-y-2\">\n {order.deliveryAddress && (\n <div>\n <span className=\"font-medium\">Adres:</span>{\" \"}\n <span className={!isVerified ? \"text-neutral-500\" : \"\"}>\n {order.deliveryAddress}\n </span>\n </div>\n )}\n {order.deliveryMethod && (\n <div>\n <span className=\"font-medium\">Metoda:</span>{\" \"}\n {order.deliveryMethod}\n </div>\n )}\n {order.trackingNumber && isVerified && (\n <div>\n <span className=\"font-medium\">Tracking:</span>{\" \"}\n {order.trackingNumber}\n </div>\n )}\n </div>\n </div>\n )}\n\n <div className=\"border-t pt-4\">\n <div className=\"flex justify-between text-lg font-bold\">\n <span>Suma:</span>\n <span>\n {formatCurrency(Number(order.totalAmount), order.currency)}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>\n Komentarze {order.commentCount > 0 && `(${order.commentCount})`}\n </CardTitle>\n </CardHeader>\n <CardContent>\n {order.comments.length > 0 ? (\n <div className=\"space-y-4\">\n {order.comments.map((comment) => (\n <div\n key={comment.id}\n className=\"border-b pb-4 last:border-b-0\"\n >\n <div className=\"mb-1 flex items-center gap-2\">\n <span className=\"font-medium\">\n {comment.authorName || \"System\"}\n </span>\n <span className=\"text-xs text-neutral-500\">\n {formatDate(comment.createdAt)}\n </span>\n {comment.authorType === \"admin\" && (\n <span className=\"rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-700\">\n Admin\n </span>\n )}\n </div>\n <p className={!isVerified ? \"text-neutral-500\" : \"\"}>\n {comment.message}\n </p>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-neutral-600\">Brak komentarzy.</p>\n )}\n\n {isVerified ? (\n <AddCommentForm orderID={order.orderId} email={verifyEmail} />\n ) : (\n <div className=\"mt-4\">\n <Button\n onClick={() => setIsVerifyDialogOpen(true)}\n variant=\"outline\"\n className=\"w-full\"\n >\n <Lock className=\"mr-2 h-4 w-4\" />\n Zweryfikuj swój email\n </Button>\n </div>\n )}\n </CardContent>\n </Card>\n\n {isVerifyDialogOpen && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\n <Card className=\"w-full max-w-md\">\n <CardHeader>\n <CardTitle>Zweryfikuj swój email</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-neutral-700\">\n Podaj adres email użyty przy składaniu zamówienia.\n </p>\n <div className=\"space-y-2\">\n <Label htmlFor=\"verify-email\">Adres email</Label>\n <Input\n id=\"verify-email\"\n type=\"email\"\n placeholder=\"twoj@email.com\"\n value={verifyEmail}\n onChange={(e) => setVerifyEmail(e.target.value)}\n />\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => setIsVerifyDialogOpen(false)}\n className=\"flex-1\"\n >\n Anuluj\n </Button>\n <Button onClick={handleVerifyEmail} className=\"flex-1\">\n Zweryfikuj\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction PublicOrderPage(props: Props) {\n return <PublicOrderPageContent {...props} />;\n}\nexport default PublicOrderPage;\n","import { setAllowedReturnOrigins, setPanelConfig } from \"@/src/panel\";\nimport { create } from \"@bufbuild/protobuf\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { createContext, useContext, useEffect, useState } from \"react\";\nimport {\n AddressSchema,\n BillingAddressSchema,\n} from \"src/gen/proto/common/v1/address_pb\";\nimport {\n GetPreOrderDetailsRequestSchema,\n OneClickAuthorizePaymentRequest_Gateway,\n PreOrderItemSchema,\n} from \"src/gen/proto/public/v1/public_api_pb\";\nimport { PublicApiClient } from \"src/public.api.client\";\nimport zod from \"zod\";\nimport { getCartInstrument, type Instrument } from \"@/src/analytics/instrument\";\nimport { withClientParam } from \"@/src/lib/client-header\";\nimport { HOST, setCustomHost } from \"./constants\";\nimport { sendAnalyticEvent } from \"./frontent.analytics\";\nimport { mapGooglePayConfiguration } from \"./google.pay.mapper\";\nimport { buildURL } from \"./helper.methods\";\nimport { Err, isErr } from \"./lib/err\";\nimport {\n cartItemURL,\n findMissingProductIDs,\n findProductForCartItem,\n} from \"./cart-items\";\nimport { round } from \"./lib/round.number\";\nimport { LinkRequest } from \"./link.request.schema\";\nimport {\n createPaymentURL,\n getPaymentMethodChoice,\n getReferenceIfPossible,\n injectReferenceToRequestIfNeeded,\n} from \"./methods\";\nimport { SingleProduct } from \"./product.details.model\";\nimport { useCheckoutStore } from \"./state\";\nimport { getLocale } from \"./locale\";\nimport { useCheckoutTextsConfig } from \"./texts.context\";\nimport { getCheckoutText, type CheckoutTexts } from \"./texts\";\nimport {\n orderStatusFromResponse,\n reconcilePendingOrder,\n subtractOrderLines,\n throttleOrderStatus,\n type PendingOrderLine,\n type PendingOrderOutcome,\n} from \"./pending-order\";\nimport type { PaymentMethod, PaymentMethodChoice } from \"./payment-method\";\n\nexport const MARKETING_AGREEMENT_ID = \"__m_a\";\n\ntype CartProduct = {\n productID: string;\n quantity: number;\n metadata?: { [key: string]: string | undefined };\n /** Product page the cart item links to (image and name). */\n url?: string;\n\n // Those fields are used to send the price and currency to the analytics\n name?: string;\n price?: number;\n currency?: string;\n priceVersion?: string;\n\n /** Where `add_to_cart` is reported; defaults to the mounted `<BitsnapCheckout>`. */\n analytics?: Instrument;\n};\n\nexport interface CartMethods {\n checkIfApplePayIsAvailable(): Promise<boolean>;\n getGooglePayConfiguration(args: { items: CartProduct[] }): Promise<\n | {\n isAvailable: true;\n config: google.payments.api.PaymentDataRequest;\n }\n | {\n isAvailable: false;\n }\n >;\n\n addProduct(args: CartProduct): Promise<Err | void>;\n\n getProducts: () => Promise<\n | Err\n | {\n id: string;\n productID: string;\n quantity: number;\n metadata?: { [key: string]: string | undefined };\n /** Product page given when the item was added. */\n url?: string;\n details?: SingleProduct;\n /** The catalog product, when `productID` is one of its variants. */\n catalogProductID?: string;\n }[]\n >;\n\n updateQuantity(args: { id: string; quantity: number }): Promise<Err | void>;\n\n removeProductFromCart: (args: { id: string }) => Promise<Err | void>;\n\n clearCart: () => Promise<Err | void>;\n\n getNumberOfElementsInCart: () => Promise<number>;\n\n setCouponCodeIfPossible: (couponCode?: string) => Promise<Err | void>;\n setDeliveryMethod: (deliveryMethod?: string) => Promise<Err | void>;\n setPostalCode: (postalCode?: string) => Promise<Err | void>;\n setEmail: (email?: string) => Promise<Err | void>;\n setCountry: (country: string) => Promise<Err | void>;\n getCountry: () => Promise<Err | string>;\n getAvailableCountries: () => Promise<Err | { name: string; code: string }[]>;\n\n /**\n * Whether the buyer may choose between paying online, paying the seller by\n * hand and paying on delivery for the current cart. `null` (also on any failure) means nothing\n * to choose.\n */\n getPaymentMethodChoice: () => Promise<PaymentMethodChoice | null>;\n\n /**\n * Creates the order of the cart (`/buy`). `paymentMethod` is sent only when\n * given, that is when the buyer was offered the choice.\n */\n redirectToNextStep: (args?: { paymentMethod?: PaymentMethod }) => Promise<\n Err | { url: string; orderId?: string; projectId?: string }\n >;\n\n getApplePayPaymentRequest: (args?: {\n expectedItems?: CartProduct[];\n }) => Promise<Err | ApplePayJS.ApplePayPaymentRequest>;\n /**\n * Country, currency and total of the cart as the backend calculates them,\n * for an Apple Pay session that has to be created before any request.\n */\n getApplePayPreview: (args: { items: CartProduct[] }) => Promise<\n | Err\n | {\n countryCode: string;\n currencyCode: string;\n /** Major units, as Apple Pay wants them. */\n totalAmount: string;\n }\n >;\n completeApplePayPayment: (args: {\n token: ApplePayJS.ApplePayPaymentToken;\n shippingContact?: ApplePayJS.ApplePayPaymentContact;\n billingContact?: ApplePayJS.ApplePayPaymentContact;\n }) => Promise<\n | Err\n | {\n isSuccess: boolean;\n redirectURL?: string;\n }\n >;\n completeGooglePayPayment: (args: {\n paymentData: google.payments.api.PaymentData;\n }) => Promise<\n | Err\n | {\n isSuccess: boolean;\n redirectURL?: string;\n }\n >;\n\n justRedirectToPayment: (args: {\n email?: string;\n productID: string;\n name?: string;\n country?: string;\n marketingAgreement?: boolean;\n locale?: string;\n }) => Promise<\n | Err\n | {\n url: string;\n }\n >;\n}\n\nconst CartProviderContext = createContext<CartMethods | undefined>(undefined);\n\nexport var bitsnapProjectID: string | undefined = undefined;\nexport function setProjectID(projectID: string) {\n setPanelConfig({\n projectID,\n });\n bitsnapProjectID = projectID;\n if (typeof window !== \"undefined\") {\n setAllowedReturnOrigins([window.location.origin]);\n }\n}\n\nexport function getProjectID(): string | undefined {\n if (bitsnapProjectID != null) {\n return bitsnapProjectID;\n }\n const me = document.querySelector(\n 'script[data-id][data-name=\"internal-cart\"]',\n );\n const projectID = me?.getAttribute(\"data-id\");\n return projectID ?? undefined;\n}\n\nexport { getLocale, setLocale } from \"./locale\";\n\nfunction getNewHostIfExist(): string | undefined {\n const me = document.querySelector(\n 'script[data-id][data-name=\"internal-cart\"]',\n );\n const customHost = me?.getAttribute(\"data-custom-host\");\n return customHost ?? undefined;\n}\n\nconst CartProvider = ({\n children,\n locale,\n}: {\n children: React.ReactNode;\n locale?: string;\n}) => {\n const [queryClient] = useState(() => new QueryClient());\n const textsConfig = useCheckoutTextsConfig();\n\n useEffect(() => {\n updateNumberOfProductsInCart();\n }, []);\n\n const projectID = getProjectID();\n\n // An order that was left for the payment page clears the cart once it is paid.\n useEffect(() => {\n if (projectID == null) {\n return;\n }\n const reconcile = () => {\n void reconcileOrderOfLastPayment(projectID).then((outcome) => {\n // An open drawer refetches on focus before the order answers.\n if (outcome === \"paid\") {\n void queryClient.invalidateQueries({ queryKey: [\"cart\"] });\n }\n });\n };\n const onVisibilityChange = () => {\n if (document.visibilityState === \"visible\") {\n reconcile();\n }\n };\n reconcile();\n window.addEventListener(\"pageshow\", reconcile);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n return () => {\n window.removeEventListener(\"pageshow\", reconcile);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n };\n }, [projectID, queryClient]);\n\n if (projectID == null) {\n return <></>;\n }\n\n const checkoutMethods = getCheckoutMethods(\n projectID,\n locale ?? textsConfig.locale,\n textsConfig.texts,\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <CartProviderContext.Provider value={checkoutMethods}>\n {children}\n </CartProviderContext.Provider>\n </QueryClientProvider>\n );\n};\n\nlet reconciling: Promise<PendingOrderOutcome | undefined> | undefined;\n\nconst askAboutOrder = throttleOrderStatus(async (order) =>\n orderStatusFromResponse(\n await PublicApiClient.get(HOST).getOrder({\n id: order.orderId,\n projectId: order.projectId,\n }),\n ),\n);\n\n/** What the buyer picked that changes the totals (for cache keys of wallet previews). */\nexport function getCheckoutSelection() {\n const { country, couponCode, selectedDeliveryMethod, postalCode } =\n getCheckout() ?? emptyCheckout;\n return { country, couponCode, selectedDeliveryMethod, postalCode };\n}\n\n/** The lines of the cart right now, for the order that is about to be paid. */\nexport function getCartLines(): PendingOrderLine[] {\n return (getCheckout()?.products ?? []).map((el) => ({\n id: el.id,\n quantity: el.quantity,\n }));\n}\n\n/** Removes the lines of a paid order from the cart; what was added since stays. */\nfunction removeOrderLinesFromCart(lines: PendingOrderLine[]) {\n const checkout = getCheckout();\n saveCheckout({\n ...checkout,\n products: subtractOrderLines(checkout?.products ?? [], lines),\n });\n updateNumberOfProductsInCart();\n}\n\n/** Asks the backend about the order the buyer left for, once at a time. */\nexport function reconcileOrderOfLastPayment(\n projectID: string,\n): Promise<PendingOrderOutcome | undefined> {\n reconciling ??= reconcilePendingOrder({\n projectId: projectID,\n fetchStatus: askAboutOrder,\n removeLines: removeOrderLinesFromCart,\n })\n .catch((e) => {\n console.warn(\"cannot check the pending order\", e);\n return undefined;\n })\n .finally(() => {\n reconciling = undefined;\n });\n return reconciling;\n}\n\n// @ts-ignore\nconst getProducts: (\n projectID: string,\n args?: { items?: CheckoutProduct[]; locale?: string },\n) => Promise<\n | Err\n | {\n id: string;\n productID: string;\n quantity: number;\n metadata?: { [key: string]: string | undefined };\n url?: string;\n details?: SingleProduct;\n /** The catalog product, when `productID` is one of its variants. */\n catalogProductID?: string;\n }[]\n> = async (\n projectID: string,\n args?: { items?: CheckoutProduct[]; locale?: string },\n) => {\n let products: CheckoutProduct[] = [];\n\n if (args?.items != null && args.items.length > 0) {\n products = args.items;\n } else {\n products = getCheckout()?.products ?? [];\n }\n\n const productIds = Array.from(\n new Set(products.map((product) => product.productID)),\n );\n\n if (productIds.length === 0) {\n return [];\n }\n\n const params = new URLSearchParams();\n params.set(\"ids\", productIds.join(\",\"));\n params.set(\"locale\", args?.locale ?? getLocale());\n\n let payload: {\n success: boolean;\n message?: string | undefined;\n result?: SingleProduct[] | undefined;\n };\n try {\n const result = await fetch(\n withClientParam(buildURL(projectID, `/products?${params.toString()}`)),\n {\n method: \"GET\",\n },\n );\n\n // A backend failure is not an empty cart.\n if (result.status != 200) {\n return Err(\"products-load-failed\", \"internal\");\n }\n\n payload = await result.json();\n } catch (e) {\n console.warn(\"cannot load the products of the cart\", e);\n return Err(\"products-load-failed\", \"internal\");\n }\n\n // Items the backend does not know (removed product, wrong id) are dropped.\n return products.flatMap((product) => {\n const details = findProductForCartItem(product.productID, payload.result);\n if (details == null) {\n return [];\n }\n return [\n {\n ...product,\n details: resolveProductDetailsFromSingleProduct(\n product.productID,\n details,\n ),\n catalogProductID: details.id,\n },\n ];\n });\n};\n\nexport const useCartProvider = () => {\n const context = useContext(CartProviderContext);\n\n if (context === undefined) {\n throw new Error(\"useCartProvider must be used within a CartProvider\");\n }\n\n return context;\n};\n\nexport default CartProvider;\n\nconst googlePayConfigSchema = zod.object({\n isAvailable: zod.boolean(),\n merchantId: zod.string(),\n merchantName: zod.string(),\n gateway: zod.string(),\n gatewayId: zod.string(),\n});\nconst checkoutProduct = zod.object({\n id: zod.string(),\n productID: zod.string(),\n quantity: zod.number(),\n priceVersion: zod.string().optional(),\n metadata: zod.record(zod.string(), zod.string().optional()).optional(),\n url: zod.string().optional(),\n});\ntype CheckoutProduct = zod.infer<typeof checkoutProduct>;\nconst checkoutSchema = zod.object({\n country: zod.string().optional(),\n couponCode: zod.string().optional(),\n selectedDeliveryMethod: zod.string().optional(),\n postalCode: zod.string().optional(),\n email: zod.string().optional(),\n products: zod.array(checkoutProduct).optional(),\n googlePayConfig: googlePayConfigSchema.optional(),\n});\nexport type GooglePayConfig = zod.infer<typeof googlePayConfigSchema>;\nconst emptyCheckout: Checkout = {\n country: undefined,\n couponCode: undefined,\n email: undefined,\n selectedDeliveryMethod: undefined,\n postalCode: undefined,\n products: [],\n googlePayConfig: undefined,\n};\nexport type Checkout = zod.infer<typeof checkoutSchema>;\n\nconst checkoutKey = \"checkout\";\n\nfunction getCheckout(): Checkout {\n try {\n const value = localStorage.getItem(checkoutKey);\n if (value == null) {\n return emptyCheckout;\n }\n return checkoutSchema.parse(JSON.parse(value));\n } catch (e) {\n return emptyCheckout;\n }\n}\n\nasync function addProducts(projectID: string, products: CartProduct[]) {\n const latestProducts = await getProducts(projectID, {\n items: products.map((item, index) => ({ ...item, id: `price-check-${index}` })),\n });\n if (isErr(latestProducts)) return latestProducts;\n const missingIDs = findMissingProductIDs(\n products.map((el) => el.productID),\n latestProducts,\n );\n if (missingIDs.length > 0) {\n return Err(\"item-ids-not-found\", \"notFound\", missingIDs);\n }\n\n const checkout = getCheckout();\n if (checkout.products == null) {\n checkout.products = [];\n }\n checkout.products.push(\n ...products.map((el) => ({\n id: Math.random().toString(36).substring(7),\n productID: el.productID,\n quantity: el.quantity,\n priceVersion: latestProducts.find((product) => product.productID === el.productID)?.details?.pricing?.priceVersion,\n metadata: el.metadata,\n url: cartItemURL(\n el.url,\n typeof window !== \"undefined\" ? window.location.href : undefined,\n ),\n })),\n );\n trackCartAdd(products, latestProducts);\n sendAnalyticEvent({\n event: \"addToCart\",\n currency: \"PLN\",\n items: products.map((el) => ({\n id: el.productID,\n name: el.name ?? \"\",\n price: el.price ?? 0,\n quantity: el.quantity,\n currency: el.currency ?? \"PLN\",\n })),\n });\n saveCheckout(checkout);\n updateNumberOfProductsInCart();\n return undefined;\n}\n\n/** `add_to_cart` per added line, priced by the backend's answer. */\nfunction trackCartAdd(\n added: CartProduct[],\n latest: { productID: string; details?: SingleProduct; catalogProductID?: string }[],\n) {\n for (const item of added) {\n try {\n const found = latest.find((el) => el.productID === item.productID);\n const price = found?.details?.pricing?.effectivePrice ?? found?.details?.price ?? item.price;\n const currency = found?.details?.currency ?? item.currency;\n if (price == null || currency == null) continue;\n const productID = found?.catalogProductID ?? item.productID;\n (item.analytics ?? getCartInstrument()).track(\n \"add_to_cart\",\n { qty: item.quantity, value_minor: Math.round(price * item.quantity), currency },\n { product_id: productID, variant_id: productID !== item.productID ? item.productID : null },\n );\n } catch {}\n }\n}\n\nfunction removeProductFromCheckout(ids: string[]) {\n const checkout = getCheckout();\n const newCheckout = {\n ...checkout,\n products: checkout?.products?.filter(\n (product) =>\n !ids.includes(product.productID) && !ids.includes(product.id),\n ),\n };\n sendAnalyticEvent({\n event: \"removeFromCart\",\n items: ids.map((id) => ({\n id: id,\n name: \"\",\n price: 0,\n quantity: 1,\n currency: \"PLN\",\n })),\n });\n saveCheckout(newCheckout);\n updateNumberOfProductsInCart();\n}\n\nfunction saveCheckout(model: Checkout) {\n localStorage.setItem(checkoutKey, JSON.stringify(model));\n}\n\n/** The `/buy` body of the cart (also sent to `payment-methods`); `undefined` when it is empty. */\nfunction cartLinkRequest(\n checkout: Checkout,\n locale: string,\n): LinkRequest | undefined {\n if (checkout.products == null || checkout.products.length == 0) {\n return undefined;\n }\n const mergedMetadata = checkout.products.reduce(\n (acc, product) => {\n if (product.metadata != null) {\n Object.keys(product.metadata).forEach((key) => {\n const value = product.metadata?.[key];\n if (value != null) {\n acc[key] = value;\n }\n });\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n return {\n items: checkout.products.map((el) => {\n return {\n id: el.productID,\n quantity: el.quantity,\n priceVersion: el.priceVersion,\n };\n }),\n askForNote: true,\n countries: checkout.country ? [checkout.country] : undefined,\n metadata: mergedMetadata,\n locale,\n };\n}\n\nexport const getCheckoutMethods: (\n projectID: string,\n locale?: string,\n texts?: Partial<CheckoutTexts>,\n) => CartMethods = (projectID, locale = getLocale(), texts) => {\n const newHost = getNewHostIfExist();\n if (newHost != null) {\n setCustomHost(newHost);\n }\n return {\n async checkIfApplePayIsAvailable(): Promise<boolean> {\n if (typeof window == \"undefined\" || typeof document == \"undefined\") {\n return false;\n }\n if (\"ApplePaySession\" in window === false) {\n return false;\n }\n\n try {\n const result = await PublicApiClient.get(\n HOST,\n ).isOneClickPaymentAvailable({\n projectId: projectID,\n });\n\n return result.applePay;\n } catch (e) {\n console.error(\"Error checking if Apple Pay is available\", e);\n return false;\n }\n },\n async getGooglePayConfiguration(args: { items: CartProduct[] }): Promise<\n | {\n isAvailable: true;\n config: google.payments.api.PaymentDataRequest;\n }\n | {\n isAvailable: false;\n }\n > {\n if (typeof window == \"undefined\" || typeof document == \"undefined\") {\n return {\n isAvailable: false,\n };\n }\n\n try {\n const googlePayConfig = await resolveGooglePayConfiguration(projectID);\n if (googlePayConfig?.isAvailable != true) {\n return {\n isAvailable: false,\n };\n }\n\n const checkout = getCheckout();\n if (checkout == null) {\n console.log(\"checkout is null\");\n return {\n isAvailable: false,\n };\n }\n\n const products = await getProducts(projectID, {\n locale,\n items: args.items.map((el) => {\n return {\n id: Math.random().toString(36).substring(7),\n quantity: el.quantity,\n metadata: el.metadata,\n productID: el.productID,\n };\n }),\n });\n\n if (isErr(products)) {\n return {\n isAvailable: false,\n };\n }\n const result = await PublicApiClient.get(HOST).getPreOrderDetails({\n items: products.map((el) =>\n create(PreOrderItemSchema, {\n id: el.productID,\n quantity: el.quantity,\n }),\n ),\n projectId: projectID,\n // we can detect 5 the closest inpost pickup point based on shipping address.\n postCode: checkout.postalCode,\n couponCode: checkout.couponCode,\n countryCode: checkout.country,\n selectedDeliveryMethod: checkout.selectedDeliveryMethod,\n });\n if (result.totalAmount == null) {\n return {\n isAvailable: false,\n };\n }\n const cartRequiresShipping =\n products.find((el) => el.details?.isDeliverable == true) != null;\n\n const mappedPaymentRequest = await mapGooglePayConfiguration({\n items: products,\n googlePayConfig: googlePayConfig,\n checkout: checkout,\n cartRequiresShipping: cartRequiresShipping,\n result: result,\n locale,\n texts,\n });\n if (mappedPaymentRequest == null) {\n return {\n isAvailable: false,\n };\n }\n\n return {\n isAvailable: true,\n config: mappedPaymentRequest,\n };\n } catch (e) {\n console.error(\"Error resolving Google Pay configuration\", e);\n return {\n isAvailable: false,\n };\n }\n },\n async clearCart(): Promise<Err | void> {\n const empty = structuredClone(emptyCheckout);\n empty.country = getCheckout()?.country;\n saveCheckout(empty);\n updateNumberOfProductsInCart();\n },\n\n async getAvailableCountries(): Promise<\n Err | { name: string; code: string }[]\n > {\n const result = await fetch(\n withClientParam(buildURL(projectID, \"/countries\")),\n {\n method: \"GET\",\n },\n );\n\n if (result.status != 200) {\n return [];\n }\n\n try {\n return zod\n .array(\n zod.object({\n name: zod.string(),\n code: zod.string(),\n }),\n )\n .parse(await result.json());\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return Err(e.toString(), \"internal\");\n }\n },\n\n async getCountry(): Promise<Err | string> {\n let country = getCheckout()?.country;\n if (country == null) {\n country = \"PL\";\n const checkout = getCheckout();\n checkout.country = country;\n saveCheckout(checkout);\n }\n\n return country;\n },\n\n async getNumberOfElementsInCart(): Promise<number> {\n return (\n getCheckout()?.products?.reduce(\n (acc, product) => acc + product.quantity,\n 0,\n ) ?? 0\n );\n },\n\n async getProducts(): Promise<\n | Err\n | {\n id: string;\n productID: string;\n quantity: number;\n metadata?: {\n [p: string]: string | undefined;\n };\n details?: SingleProduct;\n catalogProductID?: string;\n }[]\n > {\n return await getProducts(projectID, { locale });\n },\n\n async removeProductFromCart(args: { id: string }): Promise<Err | void> {\n return removeProductFromCheckout([args.id]);\n },\n\n async setCountry(country: string): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.country = country;\n saveCheckout(checkout);\n },\n\n async setCouponCodeIfPossible(couponCode?: string): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.couponCode = couponCode;\n saveCheckout(checkout);\n },\n\n async setPostalCode(postalCode?: string): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.postalCode = postalCode;\n saveCheckout(checkout);\n },\n\n async setDeliveryMethod(deliveryMethod?: string): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.selectedDeliveryMethod = deliveryMethod;\n saveCheckout(checkout);\n },\n\n async setEmail(email?: string): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.email = email;\n saveCheckout(checkout);\n },\n\n async addProduct(args: CartProduct): Promise<Err | void> {\n return await addProducts(projectID, [args]);\n },\n\n async updateQuantity(args: {\n id: string;\n quantity: number;\n }): Promise<Err | void> {\n const checkout = getCheckout();\n checkout.products = checkout.products?.map((product) => {\n if (product.id === args.id) {\n product.quantity = args.quantity;\n }\n return product;\n });\n saveCheckout(checkout);\n updateNumberOfProductsInCart();\n },\n\n async getPaymentMethodChoice(): Promise<PaymentMethodChoice | null> {\n const payload = cartLinkRequest(getCheckout(), locale);\n return payload == null ? null : getPaymentMethodChoice(payload);\n },\n\n async redirectToNextStep(args?: {\n paymentMethod?: PaymentMethod;\n }): Promise<Err | { url: string; orderId?: string; projectId?: string }> {\n const payload = cartLinkRequest(getCheckout(), locale);\n if (payload == null) {\n return Err(\"cart-is-empty\", \"badInput\");\n }\n if (args?.paymentMethod != null) {\n payload.paymentMethod = args.paymentMethod;\n }\n\n const paymentResponse = await createPaymentURL(payload);\n\n if (isErr(paymentResponse)) {\n console.warn(\"cannot create payment URL\", paymentResponse.error);\n return paymentResponse;\n }\n\n return {\n url: paymentResponse.url,\n ...(paymentResponse.orderId != null\n ? { orderId: paymentResponse.orderId }\n : {}),\n ...(paymentResponse.projectId != null\n ? { projectId: paymentResponse.projectId }\n : {}),\n };\n },\n\n async justRedirectToPayment(args: {\n email?: string;\n productID: string;\n name?: string;\n country?: string;\n marketingAgreement?: boolean;\n locale?: string;\n }): Promise<Err | { url: string }> {\n let payload: LinkRequest = {\n items: [\n {\n id: args.productID,\n quantity: 1,\n },\n ],\n askForNote: false,\n details:\n args.email || args.name\n ? {\n name: args.name,\n email: args.email,\n }\n : undefined,\n locale: args.locale ?? locale,\n };\n\n payload = injectReferenceToRequestIfNeeded(payload);\n\n if (args.country == null) {\n args.country = \"pl\";\n }\n\n if (payload.details == null) {\n payload.details = {};\n }\n if (payload.details.address == null) {\n payload.details.address = {};\n }\n payload.details.address.country = args.country;\n\n if (args.marketingAgreement === true) {\n payload.additionalAgreements = [\n {\n id: MARKETING_AGREEMENT_ID,\n name: \"\",\n required: true,\n answer: true,\n },\n ];\n }\n\n const result = await createPaymentURL(payload);\n\n if (isErr(result)) {\n return result;\n } else {\n return {\n url: result.url,\n };\n }\n },\n\n async getApplePayPreview(args: {\n items: CartProduct[];\n }): Promise<\n | Err\n | { countryCode: string; currencyCode: string; totalAmount: string }\n > {\n const checkout = getCheckout();\n try {\n const result = await PublicApiClient.get(HOST).getPreOrderDetails({\n items: args.items.map((el) =>\n create(PreOrderItemSchema, {\n id: el.productID,\n quantity: el.quantity,\n }),\n ),\n projectId: projectID,\n postCode: checkout.postalCode,\n couponCode: checkout.couponCode,\n countryCode: checkout.country,\n selectedDeliveryMethod: checkout.selectedDeliveryMethod,\n });\n if (result.totalAmount == null || result.currency.length === 0) {\n return Err(\"pre-order-unavailable\", \"internal\");\n }\n return {\n countryCode: result.country || checkout.country || \"PL\",\n currencyCode: result.currency,\n totalAmount: `${round(result.totalAmount / 100, 2)}`,\n };\n } catch (e) {\n console.warn(\"cannot load the Apple Pay preview\", e);\n return Err(\"pre-order-unavailable\", \"internal\");\n }\n },\n\n async completeApplePayPayment(args: {\n token: ApplePayJS.ApplePayPaymentToken;\n shippingContact?: ApplePayJS.ApplePayPaymentContact;\n billingContact?: ApplePayJS.ApplePayPaymentContact;\n }): Promise<\n | Err\n | {\n isSuccess: boolean;\n redirectURL?: string;\n }\n > {\n const checkout = getCheckout();\n if (checkout == null) {\n return Err(\"Checkout not found\");\n }\n\n const products = await getProducts(projectID, { locale });\n\n if (isErr(products)) {\n return products;\n }\n\n try {\n let shippingName = args.shippingContact?.givenName;\n if (args.shippingContact?.familyName != null) {\n shippingName += \" \" + args.shippingContact?.familyName;\n } else if (args.billingContact?.familyName != null) {\n shippingName += \" \" + args.billingContact?.familyName;\n }\n\n let metadata: Record<string, string> = {};\n\n const ref = getReferenceIfPossible();\n if (ref != null) {\n metadata[\"ref\"] = ref;\n }\n\n const result = await PublicApiClient.get(HOST).authorizeOneClickPayment(\n {\n gateway: OneClickAuthorizePaymentRequest_Gateway.APPLE_PAY,\n paymentData: JSON.stringify(args.token.paymentData),\n paymentMethod: JSON.stringify(args.token.paymentMethod),\n transactionIdentifier: args.token.transactionIdentifier,\n order: create(GetPreOrderDetailsRequestSchema, {\n items: products.map((el) => ({\n id: el.productID,\n quantity: el.quantity,\n })),\n couponCode: checkout.couponCode,\n email:\n args.shippingContact?.emailAddress ??\n args.billingContact?.emailAddress ??\n checkout.email ??\n undefined,\n phone:\n args.shippingContact?.phoneNumber ??\n args.billingContact?.phoneNumber ??\n undefined,\n selectedDeliveryMethod: checkout.selectedDeliveryMethod,\n postCode: checkout.postalCode,\n projectId: projectID,\n }),\n shippingAddress: create(AddressSchema, {\n line1: args.shippingContact?.addressLines?.[0] ?? \"\",\n city: args.shippingContact?.locality ?? \"\",\n country: args.shippingContact?.countryCode ?? \"\",\n zipCode: args.shippingContact?.postalCode ?? \"\",\n name: shippingName,\n }),\n billingAddress: create(BillingAddressSchema, {\n name:\n args.billingContact?.givenName ??\n \"\" + \" \" + (args.billingContact?.familyName ?? \"\"),\n line1: args.billingContact?.addressLines?.[0] ?? \"\",\n city: args.billingContact?.locality ?? \"\",\n country: args.billingContact?.countryCode ?? \"\",\n zipCode: args.billingContact?.postalCode ?? \"\",\n }),\n metadata:\n Object.keys(metadata).length > 0\n ? JSON.stringify(metadata)\n : undefined,\n },\n );\n\n return {\n isSuccess: result.isSuccess,\n redirectURL: result.redirectUrl,\n };\n } catch (error) {\n console.error(error);\n return Err(\"Failed to authorize payment\");\n }\n },\n\n async completeGooglePayPayment(args: {\n paymentData: google.payments.api.PaymentData;\n }): Promise<\n | Err\n | {\n isSuccess: boolean;\n redirectURL?: string;\n }\n > {\n const checkout = getCheckout();\n if (checkout == null) {\n return Err(\"Checkout not found\");\n }\n\n const products = await getProducts(projectID, { locale });\n\n if (isErr(products)) {\n return products;\n }\n\n try {\n let shippingName = args.paymentData.shippingAddress?.name;\n\n let metadata: Record<string, string> = {};\n\n const ref = getReferenceIfPossible();\n if (ref != null) {\n metadata[\"ref\"] = ref;\n }\n\n const result = await PublicApiClient.get(HOST).authorizeOneClickPayment(\n {\n gateway: OneClickAuthorizePaymentRequest_Gateway.GOOGLE_PAY,\n paymentData:\n args.paymentData.paymentMethodData.tokenizationData.token,\n paymentMethod: args.paymentData.paymentMethodData.type,\n transactionIdentifier: \"\",\n order: create(GetPreOrderDetailsRequestSchema, {\n items: products.map((el) => ({\n id: el.productID,\n quantity: el.quantity,\n })),\n couponCode: checkout.couponCode,\n email: args.paymentData.email ?? undefined,\n phone: args.paymentData.shippingAddress?.phoneNumber ?? undefined,\n selectedDeliveryMethod:\n args.paymentData.shippingOptionData?.id ??\n checkout.selectedDeliveryMethod,\n postCode: args.paymentData.shippingAddress?.postalCode,\n projectId: projectID,\n }),\n shippingAddress: create(AddressSchema, {\n line1: args.paymentData.shippingAddress?.address1 ?? \"\",\n city: args.paymentData.shippingAddress?.locality ?? \"\",\n country: args.paymentData.shippingAddress?.countryCode ?? \"\",\n zipCode: args.paymentData.shippingAddress?.postalCode ?? \"\",\n name: shippingName,\n }),\n billingAddress: create(BillingAddressSchema, {\n name: args.paymentData.paymentMethodData.info?.billingAddress\n ?.name,\n line1:\n args.paymentData.paymentMethodData.info?.billingAddress\n ?.address1 ?? \"\",\n city:\n args.paymentData.paymentMethodData.info?.billingAddress\n ?.locality ?? \"\",\n country:\n args.paymentData.paymentMethodData.info?.billingAddress\n ?.countryCode ?? \"\",\n zipCode:\n args.paymentData.paymentMethodData.info?.billingAddress\n ?.postalCode ?? \"\",\n }),\n metadata:\n Object.keys(metadata).length > 0\n ? JSON.stringify(metadata)\n : undefined,\n },\n );\n\n return {\n isSuccess: result.isSuccess,\n redirectURL: result.redirectUrl,\n };\n } catch (error) {\n console.error(error);\n return Err(\"Failed to authorize payment\");\n }\n\n return {\n isSuccess: true,\n };\n },\n\n async getApplePayPaymentRequest(args?: {\n expectedItems?: CartProduct[];\n }): Promise<Err | ApplePayJS.ApplePayPaymentRequest> {\n const checkout = getCheckout();\n if (checkout == null) {\n return Err(\"Checkout not found\");\n }\n if (args && args.expectedItems != null && args.expectedItems.length > 0) {\n if (checkout.products) {\n removeProductFromCheckout(\n checkout.products.map((el) => el.productID),\n );\n }\n await addProducts(projectID, args.expectedItems);\n }\n\n const products = await getProducts(projectID, { locale });\n\n if (isErr(products)) {\n return products;\n }\n\n const result = await PublicApiClient.get(HOST).getPreOrderDetails({\n items: products.map((el) =>\n create(PreOrderItemSchema, {\n id: el.productID,\n quantity: el.quantity,\n }),\n ),\n projectId: projectID,\n // we can detect 5 the closest inpost pickup point based on shipping address.\n postCode: checkout.postalCode,\n couponCode: checkout.couponCode,\n countryCode: checkout.country,\n selectedDeliveryMethod: checkout.selectedDeliveryMethod,\n });\n\n const items = products.map((el) => {\n return {\n amount: `${round(\n (el.quantity *\n (el.details?.pricing?.effectivePrice ?? el.details?.price ?? 0)) /\n 100,\n 2,\n )}`,\n label: el.details?.name + \" - \" + el.quantity,\n type: \"final\" as ApplePayJS.ApplePayLineItemType,\n };\n });\n\n if (result.selectedDeliveryMethod != null) {\n const deliveryMethod = result.methods.find(\n (el) => el.id == result.selectedDeliveryMethod,\n );\n if (deliveryMethod != null) {\n items.push({\n amount: `${round(deliveryMethod.amount / 100, 2)}`,\n label: deliveryMethod.name,\n type: \"final\" as ApplePayJS.ApplePayLineItemType,\n });\n }\n }\n\n if (result.couponCode != null && result.couponValue != null) {\n items.push({\n amount: `-${round(result.couponValue / 100, 2)}`,\n label: result.couponCode,\n type: \"final\" as ApplePayJS.ApplePayLineItemType,\n });\n }\n\n return {\n countryCode: result.country || checkout.country || \"PL\",\n merchantCapabilities: [\n \"supports3DS\",\n \"supportsCredit\",\n \"supportsDebit\",\n ],\n supportedNetworks: [\"visa\", \"masterCard\"],\n total: {\n amount: `${round((result.totalAmount ?? 0) / 100, 2)}`,\n label: getCheckoutText(\"paymentForCart\", locale, texts),\n type: \"final\",\n },\n shippingMethods: result.methods.map((el) => ({\n amount: `${round(el.amount / 100, 2)}`,\n detail: el.description ?? \"\",\n identifier: el.id,\n label: el.name,\n dateComponentsRange: {\n startDateComponents: {\n days: el.minDays ?? 1,\n hours: 0,\n months: 0,\n years: 0,\n } satisfies ApplePayJS.ApplePayDateComponents,\n endDateComponents: {\n days: el.maxDays ?? 14,\n hours: 0,\n months: 0,\n years: 0,\n } satisfies ApplePayJS.ApplePayDateComponents,\n },\n })),\n lineItems: items,\n currencyCode:\n result.currency || products[0]?.details?.currency || \"PLN\",\n };\n },\n };\n};\n\nasync function resolveGooglePayConfiguration(projectID: string) {\n const checkout = getCheckout();\n if (checkout.googlePayConfig?.isAvailable != true) {\n const result = await PublicApiClient.get(HOST).isOneClickPaymentAvailable({\n projectId: projectID,\n });\n if (result.googlePay == true && result.googlePayConfig != null) {\n checkout.googlePayConfig = {\n isAvailable: true,\n gateway: result.googlePayConfig.gateway,\n gatewayId: result.googlePayConfig.gatewayMerchantId,\n merchantName: result.googlePayConfig.merchantName,\n merchantId: result.googlePayConfig.merchantId,\n };\n } else {\n checkout.googlePayConfig = {\n isAvailable: false,\n gateway: \"\",\n gatewayId: \"\",\n merchantName: \"\",\n merchantId: \"\",\n };\n }\n }\n saveCheckout(checkout);\n return checkout.googlePayConfig;\n}\n\nfunction resolveProductDetailsFromSingleProduct(\n id: string,\n product: SingleProduct,\n) {\n if (id == product.id) {\n const variantIndex = product.variants?.findIndex((v) => v.id === id);\n if (variantIndex != null && variantIndex != -1) {\n const variant = product.variants![variantIndex];\n return {\n ...product,\n availableQuantity: variant.availableQuantity,\n isDeliverable: variant.isDeliverable,\n images: variant.images ?? product.images,\n name: product.name + \" \" + variant.name,\n baseName: product.name,\n variantName: variant.name,\n price: variant.price,\n currency: variant.currency,\n pricing: variant.pricing,\n };\n }\n return product;\n }\n\n const variant = product.variants?.find((v) => v.id === id);\n if (variant == null) {\n return product;\n }\n\n return {\n ...product,\n id: variant.id,\n name: product.name + \" \" + variant.name,\n baseName: product.name,\n variantName: variant.name,\n price: variant.price,\n currency: variant.currency,\n pricing: variant.pricing,\n metadata: product.metadata,\n availableQuantity: variant.availableQuantity,\n isDeliverable: variant.isDeliverable,\n images: variant.images ?? product.images,\n };\n}\n\ntype ApplePaySessionArgs = {\n postCode?: string;\n email?: string;\n couponCode?: string;\n};\n\nfunction updateNumberOfProductsInCart() {\n const checkout = getCheckout();\n let numberOfProductsInCart = 0;\n if (checkout == null) {\n useCheckoutStore.setState((state) => ({\n ...state,\n numberOfProductsInCart,\n }));\n return;\n }\n numberOfProductsInCart =\n checkout.products?.reduce((acc, product) => acc + product.quantity, 0) ?? 0;\n useCheckoutStore.setState((state) => ({ ...state, numberOfProductsInCart }));\n}\n","import type { Transport } from \"@connectrpc/connect\";\nimport { createClient, type Client } from \"@connectrpc/connect\";\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport { clientHeaderInterceptor } from \"./lib/client-header\";\nimport { PublicApiService } from \"./gen/proto/public/v1/public_api_pb\";\n\nexport namespace PublicApiClient {\n export function get(host: string): Client<typeof PublicApiService> {\n return createClient(PublicApiService, getTransport(host));\n }\n\n const transports = new Map<string, Transport>();\n function getTransport(host: string): Transport {\n let transport = transports.get(host);\n if (transport == null) {\n transport = createConnectTransport({\n useBinaryFormat: true,\n baseUrl: host + \"/api/rpc\",\n interceptors: [clientHeaderInterceptor],\n });\n transports.set(host, transport);\n }\n return transport;\n }\n}\n","import zod from \"zod\";\nimport { round } from \"./lib/round.number\";\n\nconst eventPayload = zod.object({\n event: zod.enum([\n \"purchase\",\n \"addToCart\",\n \"customizeProduct\",\n \"viewCart\",\n \"removeFromCart\",\n \"initiateCheckout\",\n \"lead\",\n ]),\n step: zod.string().optional(),\n value: zod.number().optional(),\n currency: zod.string().optional(),\n content_name: zod.string().optional(),\n items: zod\n .array(\n zod.object({\n id: zod.string(),\n name: zod.string(),\n price: zod.number().default(0),\n currency: zod.string().default(\"PLN\"),\n quantity: zod.number().default(1),\n })\n )\n .optional(),\n});\ntype EventPayload = zod.infer<typeof eventPayload>;\n\nexport function sendAnalyticEvent(payload: EventPayload) {\n if (typeof window == \"undefined\") {\n return;\n }\n\n sendGoogleAnalyticsEvent(payload);\n sendPixelAnalyticsEvent(payload);\n sendTikTokAnalyticsEvent(payload);\n}\n\nfunction sendGoogleAnalyticsEvent(payload: EventPayload) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof window.dataLayer == \"undefined\") {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window.dataLayer = [];\n }\n\n const ga4Event = mapToGA4EcommerceEvent(payload);\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window.dataLayer.push(ga4Event);\n } catch (e) {\n console.warn(\"cannot send google analytics event\", e);\n }\n}\n\nfunction mapToGA4EcommerceEvent(payload: EventPayload) {\n // Calculate total value from items if not provided\n const totalValue =\n payload.value ??\n payload.items?.reduce(\n (sum, item) => sum + (item.price || 0) * (item.quantity || 1),\n 0\n ) ??\n 0;\n\n // Map items to GA4 format\n const items = payload.items?.map((item) => ({\n item_id: item.id,\n item_name: item.name || item.id,\n price: round((item.price || 0) / 100, 2),\n quantity: item.quantity || 1,\n }));\n\n // Build base ecommerce object\n const ecommerce: Record<string, unknown> = {\n currency: payload.currency || \"PLN\",\n value: round(totalValue / 100, 2),\n };\n\n if (items && items.length > 0) {\n ecommerce.items = items;\n }\n\n // Map event names to GA4 ecommerce events\n let eventName: string;\n switch (payload.event) {\n case \"purchase\":\n eventName = \"purchase\";\n // Purchase events require transaction_id, but we'll use a timestamp-based one if not provided\n ecommerce.transaction_id = payload.step || `txn_${Date.now()}`;\n break;\n case \"addToCart\":\n eventName = \"add_to_cart\";\n break;\n case \"viewCart\":\n eventName = \"view_cart\";\n break;\n case \"removeFromCart\":\n eventName = \"remove_from_cart\";\n break;\n case \"initiateCheckout\":\n eventName = \"begin_checkout\";\n break;\n case \"customizeProduct\":\n // Customize product is not a standard GA4 ecommerce event\n // We'll send it as a custom event with ecommerce data\n eventName = \"customize_product\";\n break;\n default:\n eventName = payload.event;\n }\n\n return {\n event: eventName,\n ecommerce,\n // Include step if provided for additional context\n ...(payload.step && { step: payload.step }),\n // Include content_name if provided\n ...(payload.content_name && { content_name: payload.content_name }),\n };\n}\n\nfunction sendPixelAnalyticsEvent(payload: EventPayload) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof window.fbq == \"undefined\") {\n return;\n }\n\n let eventType = \"\";\n let eventName = \"\";\n let eventPayload: unknown = {};\n\n switch (payload.event) {\n case \"purchase\":\n eventType = \"track\";\n eventName = \"Purchase\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"lead\":\n eventType = \"track\";\n eventName = \"Lead\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"addToCart\":\n eventType = \"track\";\n eventName = \"Add to Cart\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"customizeProduct\":\n eventType = \"track\";\n eventName = \"Customize Product\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"viewCart\":\n eventType = \"track\";\n eventName = \"View Cart\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"removeFromCart\":\n eventType = \"track\";\n eventName = \"Remove from Cart\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n case \"initiateCheckout\":\n eventType = \"track\";\n eventName = \"Initiate Checkout\";\n eventPayload = {\n category_name: payload.step,\n ...payload,\n };\n break;\n default:\n break;\n }\n\n if (window.location.search.includes(\"analytics\")) {\n console.log(\"Pushing FB event\", eventType, eventName, eventPayload);\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window.fbq(eventType, eventName, eventPayload);\n}\n\nfunction sendTikTokAnalyticsEvent(payload: EventPayload) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof window.ttq == \"undefined\") {\n return;\n }\n\n const tiktokEvent = mapToTikTokEvent(payload);\n\n if (!tiktokEvent) {\n return;\n }\n\n if (window.location.search.includes(\"analytics\")) {\n console.log(\n \"Pushing TikTok event\",\n tiktokEvent.eventName,\n tiktokEvent.eventPayload\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n window.ttq.track(tiktokEvent.eventName, tiktokEvent.eventPayload);\n } catch (e) {\n console.warn(\"cannot send tiktok analytics event\", e);\n }\n}\n\nfunction mapToTikTokEvent(payload: EventPayload) {\n // Calculate total value from items if not provided\n const totalValue =\n payload.value ??\n payload.items?.reduce(\n (sum, item) => sum + (item.price || 0) * (item.quantity || 1),\n 0\n ) ??\n 0;\n\n // Map items to TikTok contents format\n const contents =\n payload.items?.map((item) => ({\n content_id: item.id,\n content_type: \"product\",\n content_name: item.name || item.id,\n quantity: item.quantity || 1,\n price: round((item.price || 0) / 100, 2),\n })) || [];\n\n // If no items but we have content_name, create a single content entry\n if (contents.length === 0 && payload.content_name) {\n contents.push({\n content_id: payload.step || \"unknown\",\n content_type: \"product\",\n content_name: payload.content_name,\n quantity: 1,\n price: round(totalValue / 100, 2),\n });\n }\n\n // Build base event payload\n const eventPayload: Record<string, unknown> = {\n currency: payload.currency || \"PLN\",\n value: round(totalValue / 100, 2),\n };\n\n if (contents.length > 0) {\n eventPayload.contents = contents;\n }\n\n // Map event names to TikTok events\n let eventName: string | null = null;\n switch (payload.event) {\n case \"purchase\":\n eventName = \"Purchase\";\n break;\n case \"addToCart\":\n eventName = \"AddToCart\";\n break;\n case \"initiateCheckout\":\n eventName = \"InitiateCheckout\";\n break;\n case \"customizeProduct\":\n eventName = \"CustomizeProduct\";\n break;\n case \"viewCart\":\n return undefined;\n // // TikTok doesn't have a ViewCart event, use ViewContent as fallback\n // eventName = 'ViewContent'\n break;\n case \"removeFromCart\":\n return undefined;\n // // TikTok doesn't have a RemoveFromCart event, use ViewContent as fallback\n // eventName = 'ViewContent'\n break;\n case \"lead\":\n return undefined;\n // // TikTok doesn't have a standard Lead event, use ViewContent as fallback\n // eventName = 'ViewContent'\n break;\n default:\n return null;\n }\n\n return {\n eventName,\n eventPayload,\n };\n}\n","export function round(num: number, numberOfDecimals: number = 2): number {\n return Number(\n +(\n Math.round(Number(num + \"e+\" + numberOfDecimals)) +\n \"e-\" +\n numberOfDecimals\n )\n );\n}\n\nexport function formatCurrency(amount: number, currency: string): string {\n const language = typeof navigator === \"undefined\" ? \"pl-PL\" : navigator.language;\n const formatter = Intl.NumberFormat(language, {\n style: \"currency\",\n currency: currency,\n currencyDisplay: \"symbol\",\n });\n\n return formatter.format(amount / 100);\n}\n\nexport function formatPriceWithoutCurrency(amount: number, currency: string) {\n let language = \"pl\";\n if (typeof navigator != \"undefined\") {\n language = navigator.language;\n }\n const result = new Intl.NumberFormat(language, {\n style: \"currency\",\n currency,\n currencyDisplay: \"code\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })\n .formatToParts(amount / 100)\n .filter((x) => x.type !== \"currency\")\n .filter((x) => x.type !== \"literal\" || x.value.trim().length !== 0)\n .map((x) => x.value)\n .join(\"\");\n\n const regex = new RegExp(`(\\\\.00)(?=\\\\D*$)`);\n return result.replace(regex, \"\");\n}\n","import { GetPreOrderDetailsResponse } from \"src/gen/proto/public/v1/public_api_pb\";\nimport { Checkout, GooglePayConfig } from \"./CartProvider\";\nimport { formatCurrency, round } from \"./lib/round.number\";\nimport { SingleProduct } from \"./product.details.model\";\nimport { getLocale } from \"./locale\";\nimport { getCheckoutText, type CheckoutTexts } from \"./texts\";\n\nexport function mapGooglePayConfiguration(args: {\n items: {\n id: string;\n productID: string;\n quantity: number;\n metadata?: {\n [key: string]: string | undefined;\n };\n details?: SingleProduct;\n }[];\n googlePayConfig: GooglePayConfig;\n checkout: Checkout;\n result: GetPreOrderDetailsResponse;\n cartRequiresShipping: boolean;\n locale?: string;\n texts?: Partial<CheckoutTexts>;\n}): google.payments.api.PaymentDataRequest | undefined {\n const { items, googlePayConfig, checkout, result, cartRequiresShipping } =\n args;\n const locale = args.locale ?? getLocale();\n if (result.totalAmount == null) {\n return undefined;\n }\n let intents: google.payments.api.CallbackIntent[] = [];\n if (cartRequiresShipping) {\n intents.push(\"SHIPPING_ADDRESS\");\n intents.push(\"SHIPPING_OPTION\");\n }\n\n const returnValue: google.payments.api.PaymentDataRequest = {\n apiVersion: 2,\n apiVersionMinor: 0,\n callbackIntents: intents,\n allowedPaymentMethods: [\n {\n type: \"CARD\",\n parameters: {\n allowedAuthMethods: [\"PAN_ONLY\", \"CRYPTOGRAM_3DS\"],\n allowedCardNetworks: [\"MASTERCARD\", \"VISA\"],\n },\n tokenizationSpecification: {\n type: \"PAYMENT_GATEWAY\",\n parameters: {\n gateway: googlePayConfig.gateway,\n gatewayMerchantId: googlePayConfig.gatewayId,\n },\n },\n },\n ],\n emailRequired: true,\n shippingAddressParameters: {\n phoneNumberRequired: cartRequiresShipping,\n },\n shippingAddressRequired: cartRequiresShipping,\n shippingOptionRequired: cartRequiresShipping,\n shippingOptionParameters: cartRequiresShipping\n ? {\n shippingOptions: result.methods.slice(0, 5).map((method) => ({\n id: method.id,\n label:\n method.name +\n \" - \" +\n `${formatCurrency(method.amount, result.currency)}`,\n description: method.description ?? \"\",\n })),\n defaultSelectedOptionId: result.selectedDeliveryMethod,\n }\n : undefined,\n merchantInfo: {\n merchantId: googlePayConfig.merchantId + \"\",\n merchantName: googlePayConfig.merchantName,\n },\n transactionInfo: {\n totalPriceStatus: \"FINAL\",\n totalPriceLabel: getCheckoutText(\"paymentForCart\", locale, args.texts),\n totalPrice: `${round(result.totalAmount / 100, 2)}`,\n currencyCode: result.currency,\n countryCode: result.country,\n checkoutOption: \"COMPLETE_IMMEDIATE_PURCHASE\",\n displayItems: mapGooglePayDisplayItems(\n items,\n result.methods,\n result.selectedDeliveryMethod ??\n (result.methods.length > 0 ? result.methods[0].id : undefined),\n checkout.couponCode,\n result.couponValue,\n getCheckoutText(\"coupon\", locale, args.texts)\n ),\n },\n };\n return returnValue;\n}\n\nfunction mapGooglePayDisplayItems(\n items: {\n id: string;\n productID: string;\n quantity: number;\n metadata?: {\n [key: string]: string | undefined;\n };\n details?: SingleProduct;\n }[],\n methods: GetPreOrderDetailsResponse[\"methods\"],\n deliveryMethod?: string,\n couponCode?: string,\n couponValue?: number,\n couponLabel: string = \"Coupon\"\n): google.payments.api.DisplayItem[] {\n const displayItems: google.payments.api.DisplayItem[] = [];\n\n let subtotalAmount = 0;\n for (const item of items) {\n if (item.details == null) {\n continue;\n }\n const unitPrice = item.details.pricing?.effectivePrice ?? item.details.price;\n subtotalAmount += unitPrice * item.quantity;\n displayItems.push({\n label: item.details.name + \" x \" + item.quantity,\n price: `${round(unitPrice / 100, 2)}`,\n type: \"LINE_ITEM\",\n status: \"FINAL\",\n });\n }\n\n const selectedDeliveryMethod = methods.find(\n (method) => method.id === deliveryMethod\n );\n if (selectedDeliveryMethod != null) {\n displayItems.push({\n label: selectedDeliveryMethod.name,\n price: `${round(selectedDeliveryMethod.amount / 100, 2)}`,\n type: \"SHIPPING_OPTION\",\n status: \"FINAL\",\n });\n }\n\n if (couponCode != null && couponValue != null) {\n displayItems.push({\n label: `${couponLabel} ${couponCode}`,\n price: `${round(couponValue / 100, 2)}`,\n type: \"DISCOUNT\",\n status: \"FINAL\",\n });\n }\n if (subtotalAmount > 0) {\n displayItems.push({\n label: \"Subtotal\",\n price: `${round(subtotalAmount / 100, 2)}`,\n type: \"SUBTOTAL\",\n status: \"FINAL\",\n });\n }\n\n return displayItems;\n}\n","import { HOST } from \"./constants\";\n\nexport function buildURL(projectID: string, path: string): string {\n return `${HOST}/api/integrations/${projectID}/public-commerce${path}`;\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nexport type Err = {\n ERR: true;\n error: unknown;\n type?: ErrTypes;\n data?: unknown;\n};\n\ntype ErrTypes = \"internal\" | \"badInput\" | \"notFound\";\n\nexport function isErr(x: unknown): x is Err {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof x === \"object\" && x != null && \"ERR\" in x;\n}\n\nexport function Err(message: string, type?: ErrTypes, data?: unknown): Err {\n return { ERR: true, error: message, type: type, data: data };\n}\n\nexport async function tryFail<T>(\n f: (() => Promise<T>) | (() => T)\n): Promise<T | Err> {\n try {\n return await f();\n } catch (e) {\n return { ERR: true, error: e };\n }\n}\n\nexport function assertOk<T>(x: T | Err) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (isErr(x)) throw Error((x.error as any).toString());\n}\n","type MatchableProduct = {\n id: string;\n variants?: { id: string }[] | null;\n};\n\n/**\n * The product from a `/products` response that serves a cart item: the\n * product itself or the product that has it as a variant.\n */\nexport function findProductForCartItem<T extends MatchableProduct>(\n productID: string,\n products: T[] | undefined,\n): T | undefined {\n return products?.find(\n (el) =>\n el.id === productID ||\n (el.variants?.some((variant) => variant.id === productID) ?? false),\n );\n}\n\n/** Requested product IDs that the backend did not resolve. */\nexport function findMissingProductIDs(\n requested: string[],\n resolved: { productID: string }[],\n): string[] {\n const found = new Set(resolved.map((el) => el.productID));\n return Array.from(new Set(requested.filter((id) => !found.has(id))));\n}\n\n/**\n * The product page URL a cart item links to: absolute (resolved against the\n * page that adds the item) and only `http`/`https`, so a `javascript:` link\n * never reaches the cart. Anything else gives `undefined`.\n */\nexport function cartItemURL(\n url: string | undefined,\n base?: string,\n): string | undefined {\n const value = url?.trim();\n if (value == null || value.length === 0) {\n return undefined;\n }\n try {\n const resolved = new URL(value, base);\n if (resolved.protocol !== \"http:\" && resolved.protocol !== \"https:\") {\n return undefined;\n }\n return resolved.href;\n } catch {\n return undefined;\n }\n}\n","import { create } from 'zustand';\n\ninterface CheckoutStore {\n isCartVisible: boolean;\n /** A message for the buyer raised outside of the drawer; the drawer shows it as an error. */\n notice: string | undefined;\n setNotice: (notice: string | undefined) => void;\n numberOfProductsInCart: number;\n showCart: () => void;\n hideCart: () => void;\n setNumberOfProductsInCart: (numberOfProductsInCart: number) => void;\n}\n\nexport const useCheckoutStore = create<CheckoutStore>((set) => ({\n isCartVisible: false,\n notice: undefined,\n setNotice: (notice) => set((state) => ({ ...state, notice })),\n numberOfProductsInCart: 0,\n showCart: () => set((state) => ({ ...state, isCartVisible: true })),\n hideCart: () => set((state) => ({ ...state, isCartVisible: false })),\n setNumberOfProductsInCart: (numberOfProductsInCart: number) => set((state) => ({ ...state, numberOfProductsInCart: numberOfProductsInCart })),\n}))\n","import { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { getLocale } from \"./locale\";\nimport {\n getCheckoutText,\n type CheckoutTextKey,\n type CheckoutTexts,\n} from \"./texts\";\n\ntype CheckoutTextsContextValue = {\n locale?: string;\n texts?: Partial<CheckoutTexts>;\n};\n\nconst CheckoutTextsContext = createContext<CheckoutTextsContextValue>({});\n\n/**\n * Checkout scoped texts provider. Carries the `texts` overrides and the\n * `locale` prop down to the checkout tree, so nothing leaks outside of it.\n */\nexport function CheckoutTextsProvider({\n texts,\n locale,\n children,\n}: {\n texts?: Partial<CheckoutTexts>;\n locale?: string;\n children: ReactNode;\n}) {\n const value = useMemo(() => ({ texts, locale }), [texts, locale]);\n\n return (\n <CheckoutTextsContext.Provider value={value}>\n {children}\n </CheckoutTextsContext.Provider>\n );\n}\n\n/** The `texts` overrides and `locale` of the surrounding checkout, if any. */\nexport function useCheckoutTextsConfig(): CheckoutTextsContextValue {\n return useContext(CheckoutTextsContext);\n}\n\n/**\n * Returns the checkout string for `key`: the caller override when provided,\n * otherwise the default for the `locale` prop (or the active locale).\n */\nexport function useCheckoutText(key: CheckoutTextKey): string {\n const { texts, locale } = useContext(CheckoutTextsContext);\n\n return getCheckoutText(key, locale ?? getLocale(), texts);\n}\n\n/**\n * Like `useCheckoutText`, for a key picked at runtime (for example from a\n * backend error code).\n */\nexport function useCheckoutTextResolver(): (key: CheckoutTextKey) => string {\n const { texts, locale } = useContext(CheckoutTextsContext);\n const activeLocale = locale ?? getLocale();\n\n return useMemo(\n () => (key: CheckoutTextKey) => getCheckoutText(key, activeLocale, texts),\n [activeLocale, texts],\n );\n}\n","/**\n * The cart is cleared once the payment is confirmed, not when the buyer is\n * sent to the payment page: a buyer who comes back from the gateway unpaid\n * still has the cart. Before redirecting we remember which order was created;\n * `reconcilePendingOrder` later asks the backend for its status.\n */\n\nexport const PENDING_ORDER_KEY = \"bitsnap-pending-order\";\n/** A pending order older than this is forgotten without asking the backend. */\nexport const PENDING_ORDER_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** A cart line as it was when the buyer left: the line id and how many were ordered. */\nexport type PendingOrderLine = { id: string; quantity: number };\n\nexport type PendingOrder = {\n orderId: string;\n /** The project id of the order, as the payment page URL / `/buy` response gives it. */\n projectId: string;\n /** The project id of the cart the order was made from (the page's project). */\n cartProjectId?: string;\n /** The cart lines the order was made of; only these are removed once it is paid. */\n lines: PendingOrderLine[];\n /** When the buyer was sent to the payment page (ms since epoch). */\n ts: number;\n};\n\n/** The cart without the lines (and quantities) of a paid order; lines added afterwards stay. */\nexport function subtractOrderLines<T extends { id: string; quantity: number }>(\n cart: T[],\n lines: PendingOrderLine[],\n): T[] {\n const ordered = new Map<string, number>();\n for (const line of lines) {\n ordered.set(line.id, (ordered.get(line.id) ?? 0) + line.quantity);\n }\n const rest: T[] = [];\n for (const item of cart) {\n const quantity = ordered.get(item.id);\n if (quantity == null) {\n rest.push(item);\n } else if (item.quantity > quantity) {\n rest.push({ ...item, quantity: item.quantity - quantity });\n }\n }\n return rest;\n}\n\n/**\n * `placed` is a cash on delivery order the buyer accepted: it is paid to the\n * courier later, so for the cart it is as finished as a paid one. `unknown` is\n * an order the backend does not know (yet) or a status we do not recognise.\n */\nexport type OrderStatus = \"created\" | \"placed\" | \"paid\" | \"canceled\" | \"unknown\";\n\nexport type PendingOrderOutcome =\n /** Nothing was pending. */\n | \"none\"\n /** Paid or placed: its cart lines were removed and the order forgotten. */\n | \"paid\"\n /** Canceled: the order was forgotten, the cart stays. */\n | \"canceled\"\n /** Older than 24 hours: the order was forgotten, the cart stays. */\n | \"expired\"\n /** Not paid yet or the backend could not be asked: kept for the next time. */\n | \"pending\";\n\nexport type PendingOrderStorage = Pick<\n Storage,\n \"getItem\" | \"setItem\" | \"removeItem\"\n>;\n\n/** The backend is asked about the same pending order at most this often. */\nexport const PENDING_ORDER_MIN_ASK_INTERVAL_MS = 60 * 1000;\n\n/**\n * Wraps `fetchStatus` so the same order is asked about at most once per\n * `minIntervalMs`; in between it rejects, which `reconcilePendingOrder` treats\n * as \"keep it for the next time\". A new order is asked about right away.\n */\nexport function throttleOrderStatus(\n fetchStatus: (order: PendingOrder) => Promise<OrderStatus>,\n now: () => number = Date.now,\n minIntervalMs: number = PENDING_ORDER_MIN_ASK_INTERVAL_MS,\n): (order: PendingOrder) => Promise<OrderStatus> {\n let last: { key: string; at: number } | undefined;\n return (order) => {\n const key = `${order.orderId}:${order.ts}`;\n const at = now();\n if (last?.key === key && at - last.at < minIntervalMs) {\n return Promise.reject(new Error(\"pending order was asked about recently\"));\n }\n last = { key, at };\n return fetchStatus(order);\n };\n}\n\n/** `/payment/common/<projectId>/<orderId>` of the payment page the /buy response points to. */\nexport function parseOrderFromPaymentUrl(\n url: string | undefined,\n): { orderId: string; projectId: string } | undefined {\n if (url == null || url.length === 0) {\n return undefined;\n }\n try {\n const path = new URL(url, \"https://bitsnap.invalid\").pathname;\n const match = /\\/payment\\/common\\/([^/]+)\\/([^/]+)\\/?$/.exec(path);\n if (match == null) {\n return undefined;\n }\n return {\n projectId: decodeURIComponent(match[1]),\n orderId: decodeURIComponent(match[2]),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * `/payment/manualPayment/<projectId>/<orderId>`: the page with the transfer /\n * BLIK details of an order the buyer chose to pay by hand. The order is placed\n * there and paid outside of Bitsnap, often days later.\n */\nexport function isManualPaymentUrl(url: string | undefined): boolean {\n if (url == null || url.length === 0) {\n return false;\n }\n try {\n const path = new URL(url, \"https://bitsnap.invalid\").pathname;\n return /\\/payment\\/manualPayment\\/[^/]+\\/[^/]+\\/?$/.test(path);\n } catch {\n return false;\n }\n}\n\n/**\n * The order to wait for after redirecting to `response.url`: the ids of the\n * /buy response, else the ones in the payment page URL. `undefined` when\n * neither tells which order it is, and for a manual payment page: that order\n * is already placed (the buyer only transfers the money), so the cart is\n * cleared right away instead of being kept for a day and offered again.\n */\nexport function resolvePendingOrder(\n response: { url: string; orderId?: string; projectId?: string },\n now: number = Date.now(),\n cart: { cartProjectId?: string; lines?: PendingOrderLine[] } = {},\n): PendingOrder | undefined {\n if (isManualPaymentUrl(response.url)) {\n return undefined;\n }\n const fromUrl = parseOrderFromPaymentUrl(response.url);\n const orderId = nonEmpty(response.orderId) ?? fromUrl?.orderId;\n const projectId = nonEmpty(response.projectId) ?? fromUrl?.projectId;\n if (orderId == null || projectId == null) {\n return undefined;\n }\n return {\n orderId,\n projectId,\n ...(cart.cartProjectId != null ? { cartProjectId: cart.cartProjectId } : {}),\n lines: cart.lines ?? [],\n ts: now,\n };\n}\n\n/**\n * Remembers the order of a payment page the buyer is about to be sent to.\n * `false` when it cannot tell which order it is (or cannot store it): the\n * caller then keeps clearing the cart on its own.\n */\nexport function rememberPendingOrder(\n response: { url: string; orderId?: string; projectId?: string },\n options: {\n storage?: PendingOrderStorage;\n cartProjectId?: string;\n lines?: PendingOrderLine[];\n now?: number;\n } = {},\n): boolean {\n const order = resolvePendingOrder(response, options.now, options);\n return order != null && savePendingOrder(order, options.storage);\n}\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n return value != null && value.length > 0 ? value : undefined;\n}\n\nfunction defaultStorage(): PendingOrderStorage | undefined {\n try {\n return typeof localStorage === \"undefined\" ? undefined : localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport function savePendingOrder(\n order: PendingOrder,\n storage: PendingOrderStorage | undefined = defaultStorage(),\n): boolean {\n try {\n storage?.setItem(PENDING_ORDER_KEY, JSON.stringify(order));\n return storage != null;\n } catch {\n return false;\n }\n}\n\nexport function readPendingOrder(\n storage: PendingOrderStorage | undefined = defaultStorage(),\n): PendingOrder | undefined {\n try {\n const raw = storage?.getItem(PENDING_ORDER_KEY);\n if (raw == null) {\n return undefined;\n }\n const value: unknown = JSON.parse(raw);\n if (\n typeof value === \"object\" &&\n value != null &&\n typeof (value as PendingOrder).orderId === \"string\" &&\n typeof (value as PendingOrder).projectId === \"string\" &&\n typeof (value as PendingOrder).ts === \"number\" &&\n (value as PendingOrder).orderId.length > 0\n ) {\n const { orderId, projectId, cartProjectId, ts, lines } = value as PendingOrder;\n return {\n orderId,\n projectId,\n ...(typeof cartProjectId === \"string\" ? { cartProjectId } : {}),\n lines: Array.isArray(lines)\n ? lines.filter(\n (line) =>\n typeof line?.id === \"string\" && typeof line.quantity === \"number\",\n )\n : [],\n ts,\n };\n }\n } catch {\n // a broken value is dropped below\n }\n clearPendingOrder(storage);\n return undefined;\n}\n\nexport function clearPendingOrder(\n storage: PendingOrderStorage | undefined = defaultStorage(),\n) {\n try {\n storage?.removeItem(PENDING_ORDER_KEY);\n } catch {\n // storage is not available\n }\n}\n\n/** Status text of the `getOrder` answer (`details.status`), `unknown` when missing. */\nexport function orderStatusFromResponse(response: {\n details?: { status?: string; $unknown?: unknown };\n}): OrderStatus {\n const status =\n response.details?.status ?? readUnknownStatus(response.details?.$unknown);\n return status === \"created\" ||\n status === \"placed\" ||\n status === \"paid\" ||\n status === \"canceled\"\n ? status\n : \"unknown\";\n}\n\n/**\n * `status` is field 3 of `OrderDetails`. A generated client that predates it\n * keeps the field as an unknown field; read the string from there.\n */\nfunction readUnknownStatus(unknown: unknown): string | undefined {\n if (!Array.isArray(unknown)) {\n return undefined;\n }\n for (const field of unknown as { no?: number; wireType?: number; data?: Uint8Array }[]) {\n if (field?.no === 3 && field.wireType === 2 && field.data instanceof Uint8Array) {\n // `data` is the length varint followed by the bytes.\n let length = 0;\n let offset = 0;\n for (let shift = 0; offset < field.data.length && shift < 35; shift += 7) {\n const byte = field.data[offset++];\n length |= (byte & 0x7f) << shift;\n if ((byte & 0x80) === 0) break;\n }\n if (offset + length !== field.data.length) {\n return undefined;\n }\n try {\n return new TextDecoder().decode(field.data.subarray(offset));\n } catch {\n return undefined;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Settles the order that was pending when the buyer left for the payment\n * page. Paid, or placed (cash on delivery): removes the order's cart lines\n * (not what was added since), forgets the order. Canceled or older than 24 hours: forgets the order only.\n * Anything else (not paid yet, backend or network error) keeps it for the\n * next call. An order of another project (`projectId` is the cart's project\n * id) is left alone and not asked about.\n */\nexport async function reconcilePendingOrder(deps: {\n fetchStatus: (order: PendingOrder) => Promise<OrderStatus>;\n removeLines: (lines: PendingOrderLine[]) => Promise<unknown> | unknown;\n /** The project of the page; an order made from another project's cart is skipped. */\n projectId?: string;\n storage?: PendingOrderStorage;\n now?: () => number;\n}): Promise<PendingOrderOutcome> {\n const storage = deps.storage ?? defaultStorage();\n const order = readPendingOrder(storage);\n if (order == null) {\n return \"none\";\n }\n\n const now = (deps.now ?? Date.now)();\n if (now - order.ts > PENDING_ORDER_MAX_AGE_MS) {\n clearPendingOrder(storage);\n return \"expired\";\n }\n\n if (\n deps.projectId != null &&\n order.cartProjectId != null &&\n order.cartProjectId !== deps.projectId\n ) {\n return \"pending\";\n }\n\n let status: OrderStatus;\n try {\n status = await deps.fetchStatus(order);\n } catch {\n return \"pending\";\n }\n\n // The buyer may have started another payment while we were asking.\n const current = readPendingOrder(storage);\n if (current?.orderId !== order.orderId || current.ts !== order.ts) {\n return \"pending\";\n }\n\n if (status === \"paid\" || status === \"placed\") {\n try {\n await deps.removeLines(order.lines);\n } catch {\n return \"pending\";\n }\n clearPendingOrder(storage);\n return \"paid\";\n }\n // A canceled order may still be paid again (PayU keeps it payable after a\n // declined attempt), so it is kept until it is paid or too old.\n return \"pending\";\n}\n","import { Err } from \"./lib/err\";\nimport type { CheckoutTextKey } from \"./texts\";\n\n/** Longest plain text body that is still shown to the shopper. */\nconst MAX_PLAIN_MESSAGE_LENGTH = 200;\n\n/** Code of an Err that carries the ids of unavailable products in `data`. */\nexport const ITEM_IDS_NOT_FOUND = \"item-ids-not-found\";\n\n/** Code used when the backend gave no (or an unknown) reason. */\nexport const INTERNAL_ERROR = \"internal-error\";\n\n/** What the buy endpoints failed with, after reading whatever the body was. */\nexport type ParsedBuyError = {\n /** Backend `code`, or `internal-error` when the body has none. */\n code: string;\n /** Human readable reason from the server, when there was a usable one. */\n message?: string;\n /** Ids of the products that cannot be bought. */\n itemIds?: string[];\n};\n\n/**\n * `data` of a buy Err that is not `item-ids-not-found`. `itemIds` is set when\n * the backend listed products under a code other than \"not available\".\n */\nexport type BuyErrorData = { message?: string; itemIds?: string[] };\n\n/**\n * Backend codes that have a shopper-friendly text. Any other 4xx code falls\n * back to the server message; `internal` and `invalid-request` show the\n * generic text.\n */\nconst BUY_ERROR_TEXT_KEYS: Record<string, CheckoutTextKey> = {\n \"no-payment-gateway\": \"noPaymentGateway\",\n \"gateway-not-configured\": \"gatewayNotConfigured\",\n \"shipping-not-configured\": \"shippingNotConfigured\",\n \"mixed-recurring\": \"mixedRecurring\",\n \"currency-unsupported\": \"currencyUnsupported\",\n \"price-changed\": \"priceChanged\",\n \"product-not-found\": \"unavailableProducts\",\n \"product-not-available\": \"unavailableProducts\",\n};\n\n/** Codes whose server message is not meant for the shopper. */\nconst GENERIC_TEXT_CODES = new Set([\"internal\", \"invalid-request\"]);\n\n/** Codes (besides a missing one) under which `itemIds` mean unavailable products. */\nconst ITEM_IDS_CODES = new Set([\"product-not-available\", \"product-not-found\"]);\n\nexport function buyErrorTextKey(code: unknown): CheckoutTextKey | undefined {\n return typeof code === \"string\" && Object.hasOwn(BUY_ERROR_TEXT_KEYS, code)\n ? BUY_ERROR_TEXT_KEYS[code]\n : undefined;\n}\n\nfunction looksLikeMarkup(text: string): boolean {\n return /<\\/?[a-z!?][^>]*>/i.test(text);\n}\n\n/**\n * A bare code such as `internal_error`, `INTERNAL_ERROR` or `ECONNREFUSED`, or\n * a stringified non-message: not meant to be read by a shopper.\n */\nfunction looksLikeCode(text: string): boolean {\n return (\n // A capitalised word (\"Ups\") still reads as a message.\n (/^[A-Za-z][A-Za-z0-9]*(?:[-_.:][A-Za-z0-9]+)*$/.test(text) &&\n !/^[A-Z][a-z]+$/.test(text)) ||\n /^\\[object \\w+\\]$|^(?:undefined|null)$/.test(text)\n );\n}\n\nfunction looksLikeStack(text: string): boolean {\n return /Error:/.test(text) || /\\n\\s+at /.test(text);\n}\n\nfunction plainMessage(text: string): string | undefined {\n const trimmed = text.trim();\n if (\n trimmed.length === 0 ||\n trimmed.length > MAX_PLAIN_MESSAGE_LENGTH ||\n /[\\r\\n]/.test(trimmed) ||\n looksLikeMarkup(trimmed) ||\n looksLikeCode(trimmed) ||\n looksLikeStack(trimmed)\n ) {\n return undefined;\n }\n return trimmed;\n}\n\ntype UnwrappedError = { message?: string; code?: string };\n\n/** How many levels (a JSON string or an object each) `error` is unwrapped. */\nconst MAX_UNWRAP_DEPTH = 3;\n\n/**\n * Old backends put a JSON string such as `{\"message\":\"...\"}` (or\n * `{\"error\":\"...\",\"code\":\"...\"}`) in `error`.\n */\nfunction unwrapMessage(error: unknown, depth = 0): UnwrappedError {\n if (typeof error === \"object\" && error != null) {\n if (Array.isArray(error) || depth >= MAX_UNWRAP_DEPTH) {\n return {};\n }\n const inner = error as { error?: unknown; message?: unknown; code?: unknown };\n let result = unwrapMessage(inner.error, depth + 1);\n if (result.message == null && inner.message != null) {\n const fromMessage = unwrapMessage(inner.message, depth + 1);\n result = { ...fromMessage, code: result.code ?? fromMessage.code };\n }\n if (typeof inner.code === \"string\" && inner.code.length > 0) {\n result.code = inner.code;\n }\n return result;\n }\n if (typeof error !== \"string\") {\n return {};\n }\n try {\n const inner: unknown = JSON.parse(error);\n // A JSON scalar (`\"123\"`, `\"null\"`, `\"\\\"text\\\"\"`) is not a message.\n return typeof inner === \"object\" && inner != null\n ? unwrapMessage(inner, depth + 1)\n : {};\n } catch {\n // Not JSON: the string itself is the message.\n }\n return { message: plainMessage(error) };\n}\n\n/**\n * Reads the body of a failed buy response, whatever its Content-Type was:\n * `{ success, code, error, itemIds }` JSON, the old `{ error }` shapes, plain\n * text, or nothing.\n */\nexport function parseBuyError(bodyText: string): ParsedBuyError {\n let payload: unknown;\n try {\n payload = JSON.parse(bodyText);\n } catch {\n return { code: INTERNAL_ERROR, message: plainMessage(bodyText) };\n }\n\n if (typeof payload === \"string\") {\n return { code: INTERNAL_ERROR, message: plainMessage(payload) };\n }\n if (typeof payload !== \"object\" || payload == null) {\n return { code: INTERNAL_ERROR };\n }\n\n const body = payload as { code?: unknown; error?: unknown; itemIds?: unknown };\n const { message, code: innerCode } = unwrapMessage(body.error);\n const parsed: ParsedBuyError = {\n code:\n typeof body.code === \"string\" && body.code.length > 0\n ? body.code\n : (innerCode ?? INTERNAL_ERROR),\n message,\n };\n if (Array.isArray(body.itemIds)) {\n parsed.itemIds = body.itemIds.filter(\n (id): id is string => typeof id === \"string\",\n );\n }\n return parsed;\n}\n\n/** The Err returned by the buy calls for a failed response. */\nexport function buyErrorFromResponse(status: number, bodyText: string): Err {\n const { code, message, itemIds } = parseBuyError(bodyText);\n const hasItemIds = itemIds != null && itemIds.length > 0;\n if (hasItemIds && (code === INTERNAL_ERROR || ITEM_IDS_CODES.has(code))) {\n return Err(ITEM_IDS_NOT_FOUND, \"badInput\", itemIds);\n }\n const data: BuyErrorData = { message };\n if (hasItemIds) {\n data.itemIds = itemIds;\n }\n return Err(code, status >= 500 ? \"internal\" : \"badInput\", data);\n}\n\n/**\n * The text a shopper sees for a buy Err: the text mapped to the backend\n * code; the generic one for server errors and `invalid-request`; else the\n * server message of a 4xx, else the generic one. Never the bare code.\n */\nexport function buyErrorText(\n err: { error: unknown; type?: string; data?: unknown },\n getText: (key: CheckoutTextKey) => string,\n): string {\n const key = buyErrorTextKey(err.error);\n if (key != null) {\n return getText(key);\n }\n if (\n err.type === \"internal\" ||\n (typeof err.error === \"string\" && GENERIC_TEXT_CODES.has(err.error))\n ) {\n return getText(\"checkoutFailed\");\n }\n const message = (err.data as BuyErrorData | null | undefined)?.message;\n if (typeof message === \"string\" && message.length > 0) {\n return message;\n }\n return getText(\"checkoutFailed\");\n}\n","/**\n * The buyer's choice between paying online, paying the seller by hand (bank\n * transfer or \"BLIK przelew na telefon\") and paying the courier on delivery,\n * offered when the seller turned on \"show at checkout\" for the manual payment\n * gateway or offers cash on delivery.\n *\n * `POST /public-commerce/payment-methods` takes the body of `/buy` and answers\n * `{ success: true, choice: null }` (nothing to choose) or\n * `{ success: true, choice: { methods, manualAccountTypes } }`. The pick goes\n * to `/buy` as `paymentMethod`. Anything else (an old backend, an error, a\n * timeout) counts as \"nothing to choose\", so the cart buys as before.\n */\n\nimport type { CheckoutTextKey } from \"./texts\";\n\n/** `cod` is cash on delivery: the buyer pays the courier (Poland only, shipped carts). */\nexport type PaymentMethod = \"online\" | \"manual\" | \"cod\";\nexport type ManualAccountType = \"bankTransfer\" | \"blik\";\n\nexport type PaymentMethodChoice = {\n /** In the seller's order (cash on delivery last); the first one is selected by default. */\n methods: PaymentMethod[];\n /** How the manual option is paid; decides its label. */\n manualAccountTypes: ManualAccountType[];\n};\n\n/** A slow answer must not hold up the \"Next step\" button for long. */\nexport const PAYMENT_METHODS_TIMEOUT_MS = 5000;\n\nconst METHODS: readonly PaymentMethod[] = [\"online\", \"manual\", \"cod\"];\nconst ACCOUNT_TYPES: readonly ManualAccountType[] = [\"bankTransfer\", \"blik\"];\n\nfunction uniqueKnown<T extends string>(value: unknown, known: readonly T[]): T[] {\n if (!Array.isArray(value)) {\n return [];\n }\n const result: T[] = [];\n for (const item of value) {\n if (known.includes(item as T) && !result.includes(item as T)) {\n result.push(item as T);\n }\n }\n return result;\n}\n\n/**\n * The choice in a `payment-methods` answer, or `null` when there is nothing\n * to choose: `choice: null`, a malformed answer, or fewer than two known\n * methods. Methods this version does not know are left out.\n */\nexport function parsePaymentMethodChoice(body: unknown): PaymentMethodChoice | null {\n if (typeof body !== \"object\" || body == null) {\n return null;\n }\n const choice = (body as { choice?: unknown }).choice;\n if (typeof choice !== \"object\" || choice == null) {\n return null;\n }\n const methods = uniqueKnown((choice as { methods?: unknown }).methods, METHODS);\n if (methods.length < 2) {\n return null;\n }\n return {\n methods,\n manualAccountTypes: uniqueKnown(\n (choice as { manualAccountTypes?: unknown }).manualAccountTypes,\n ACCOUNT_TYPES,\n ),\n };\n}\n\n/**\n * The choice without cash on delivery, `null` when fewer than two methods are\n * left: shown while the choice for a new country is asked for.\n */\nexport function withoutCod(choice: PaymentMethodChoice | null): PaymentMethodChoice | null {\n if (choice == null) {\n return null;\n }\n const methods = choice.methods.filter((method) => method !== \"cod\");\n return methods.length < 2 ? null : { ...choice, methods };\n}\n\n/** The method the buyer picked, or the seller's first one when the pick is not offered. */\nexport function effectivePaymentMethod(\n choice: PaymentMethodChoice,\n selected: PaymentMethod | undefined,\n): PaymentMethod {\n return selected != null && choice.methods.includes(selected)\n ? selected\n : choice.methods[0];\n}\n\n/** Label of the manual option for the account types the seller has. */\nexport function manualPaymentTitleKey(types: ManualAccountType[]): CheckoutTextKey {\n const hasBank = types.includes(\"bankTransfer\");\n const hasBlik = types.includes(\"blik\");\n if (hasBlik && !hasBank) {\n return \"paymentMethodManualBlik\";\n }\n if (hasBank && !hasBlik) {\n return \"paymentMethodManualTransfer\";\n }\n return \"paymentMethodManualBoth\";\n}\n\n/**\n * Asks the backend whether the cart offers a choice. Never throws: any\n * failure is `null`, which keeps today's plain `/buy`.\n */\nexport async function fetchPaymentMethodChoice(\n url: string,\n init: { headers: Record<string, string>; body: string },\n timeoutMs: number = PAYMENT_METHODS_TIMEOUT_MS,\n): Promise<PaymentMethodChoice | null> {\n const controller = typeof AbortController === \"undefined\" ? undefined : new AbortController();\n const timer = setTimeout(() => controller?.abort(), timeoutMs);\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: init.headers,\n body: init.body,\n signal: controller?.signal,\n });\n if (!response.ok) {\n return null;\n }\n return parsePaymentMethodChoice(await response.json());\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { Instrument } from \"@/src/analytics/instrument\";\nimport { visitorHeaders } from \"@/src/analytics/core\";\nimport { clientHeaders } from \"@/src/lib/client-header\";\nimport { getCheckoutMethods, getLocale, getProjectID } from \"./CartProvider\";\nimport { HOST } from \"./constants\";\nimport { buyErrorFromResponse } from \"./buy-error\";\nimport { buildURL } from \"./helper.methods\";\nimport { Err } from \"./lib/err\";\nimport { LinkRequest } from \"./link.request.schema\";\nimport {\n fetchPaymentMethodChoice,\n type PaymentMethodChoice,\n} from \"./payment-method\";\nimport { useCheckoutStore } from \"./state\";\n\nexport namespace Bitsnap {\n /**\n * Adds a product or variant to the cart. Returns an `Err` instead of adding\n * anything when the backend does not know the id\n * (`item-ids-not-found`, with the unknown ids in `data`).\n *\n * `args.url` is the product page: the cart links the item's image and name\n * to it. A relative URL is resolved against the current page; only `http`\n * and `https` links are kept.\n */\n export async function addProductToCart(\n id: string,\n quantity: number = 1,\n metadata?: Record<string, string | undefined>,\n // Those fields are used to send the price and currency to the analytics\n args?: {\n /** Product page the cart item links to. */\n url?: string;\n name?: string;\n price?: number;\n currency?: string;\n /** Where `add_to_cart` is reported. Defaults to the mounted `<BitsnapCheckout>`. */\n analytics?: Instrument;\n },\n ) {\n const projectID = getProjectID();\n if (projectID == null) {\n throw new Error(\"No project ID found\");\n }\n\n const methods = getCheckoutMethods(projectID);\n\n const err = await methods.addProduct({\n productID: id,\n quantity: quantity,\n metadata: metadata,\n ...args,\n });\n if (err != null) {\n return err;\n }\n\n return undefined;\n }\n\n export function showCart() {\n useCheckoutStore.setState({ isCartVisible: true });\n }\n\n export function hideCart() {\n useCheckoutStore.setState({ isCartVisible: false });\n }\n}\n\nasync function readBody(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\n/** Headers and body of a cart request, as `/buy` and `/payment-methods` send them. */\nfunction cartRequestInit(projectID: string, request: LinkRequest) {\n request = injectReferenceToRequestIfNeeded(request);\n request.locale ??= getLocale();\n return {\n headers: {\n ...clientHeaders,\n ...visitorHeaders(projectID),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n };\n}\n\n/**\n * Whether the buyer may choose between paying online, paying the seller by\n * transfer / BLIK to a phone number and paying on delivery, for the cart\n * `/buy` would get. `null`\n * means nothing to choose, also when the request fails.\n */\nexport async function getPaymentMethodChoice(\n request: LinkRequest,\n): Promise<PaymentMethodChoice | null> {\n const projectID = getProjectID();\n if (projectID == null) {\n return null;\n }\n return fetchPaymentMethodChoice(\n buildURL(projectID, \"/payment-methods\"),\n cartRequestInit(projectID, request),\n );\n}\n\nexport async function createPaymentURL(request: LinkRequest) {\n const projectID = getProjectID();\n if (projectID == null) {\n throw new Error(\"No project ID found\");\n }\n\n const result = await fetch(buildURL(projectID, \"/buy\"), {\n method: \"POST\",\n ...cartRequestInit(projectID, request),\n });\n\n if (result.status != 200) {\n const err = buyErrorFromResponse(result.status, await readBody(result));\n console.warn(\"cannot create payment URL\", result.status, err.error);\n return err;\n }\n\n const response: {\n url: string;\n sessionID: string;\n orderId?: string;\n projectId?: string;\n } = await result.json();\n\n return {\n url: response.url,\n ...(response.orderId != null ? { orderId: response.orderId } : {}),\n ...(response.projectId != null ? { projectId: response.projectId } : {}),\n };\n}\n\n/**\n * What `createCheckout` resolves to. A failed response is an `Err` that also\n * has `status: \"error\"`, so `result.status === \"ok\"` narrows to the success.\n */\nexport type CreateCheckoutResult =\n | { status: \"ok\"; redirectURL: string }\n | (Err & { status: \"error\" });\n\n/**\n * Creates a checkout link.\n *\n * @warning SERVER-SIDE ONLY. When `apiKey` is set, this sends it as an\n * `Authorization: Bearer` header to the Bitsnap API. Calling it from a client\n * component, browser bundle, island or any code shipped to the browser exposes\n * the project API key to every visitor and to anyone reading the bundle or its\n * source maps. Use it only in a server route, server action or backend module\n * that reads the key from a server-only environment variable.\n *\n * The safe default is to omit `apiKey` entirely: a normal checkout for a public\n * product needs no key and can be created from the browser. For a keyed server\n * test checkout use `Bitsnap.createCheckout(projectID, request)` from\n * `bitsnap-js` instead. See AGENTS.md.\n */\nexport async function createCheckout(\n request: LinkRequest & { apiKey?: string; testMode?: boolean },\n): Promise<CreateCheckoutResult> {\n const projectID = getProjectID();\n if (projectID == null) {\n throw new Error(\"No project ID found\");\n }\n\n const headers = {\n ...clientHeaders,\n ...visitorHeaders(projectID),\n \"Content-Type\": \"application/json\",\n ...(request.apiKey != null\n ? { Authorization: `Bearer ${request.apiKey}` }\n : {}),\n };\n\n const path = request.testMode\n ? `/api/payment/link/auto/${projectID}/test`\n : `/api/payment/link/auto/${projectID}`;\n\n delete request.apiKey;\n delete request.testMode;\n request.locale ??= getLocale();\n\n const response = await fetch(HOST + path, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n // `status` keeps `result.status === \"ok\"` narrowing for existing callers.\n return {\n ...buyErrorFromResponse(response.status, await readBody(response)),\n status: \"error\" as const,\n };\n }\n\n const payload: {\n url: string;\n } = await response.json();\n\n return {\n status: \"ok\" as const,\n redirectURL: payload.url,\n };\n}\n\nexport function getReferenceIfPossible(): string | undefined {\n if (typeof localStorage == \"undefined\") {\n return undefined;\n }\n const refLink = localStorage.getItem(\"bitsnap-ref\");\n if (refLink == null) {\n return undefined;\n }\n return refLink;\n}\n\nexport function injectReferenceToRequestIfNeeded(\n request: LinkRequest,\n): LinkRequest {\n const ref = getReferenceIfPossible();\n if (ref == null) {\n return request;\n }\n\n if (request.metadata == null) {\n request.metadata = {};\n }\n request.metadata[\"ref\"] = ref;\n return request;\n}\n"],"mappings":"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","names":["useAutoAnimate","useEffect","useMemo","jsx","Card","className","props","cn","CardHeader","CardTitle","CardDescription","CardContent","className","props","jsx","cn","CircleCheck","useId","jsx","jsxs","MUTED","DARK_FIELD","EMAIL_FAILURES","LINK","EmailCodeLoginForm","login","texts","allowHaveCode","emailPlaceholder","emailInputId","codeInputId","className","buttonClassName","children","uid","useId","emailId","codeId","noticeId","hintId","notice","isError","sending","verifying","resending","buttonBase","cn","success","noticeArea","CircleCheck","emailInvalid","announcer","emailField","Label","Input","event","Button","Spinner","before","after","dead","resendLabel","fillText","OtpCodeField","value","panelFailureKind","failure","TITLES","resolvePanelLoginTexts","locale","getLocale","overrides","resolveEmailCodeTexts","pickLocaleTable","definedOnly","keys","result","key","value","RETURN_URL_PARAM","RETURN_URL_STORAGE_KEY","ACCESS_TOKEN_PARAM","getReturnURLFromSearch","search","raw","validateReturnURL","persistReturnURL","returnURL","readPersistedReturnURL","stored","isOriginAllowed","origin","allowedOrigins","allowed","allowedHost","originHost","u","getAllowedReturnOrigins","buildAccessTokenRedirect","accessToken","jsx","jsxs","knownSiblings","getAllowedReturnOrigins","setAllowedReturnOrigins","PanelLoginForm","texts","projectID","host","locale","logo","instrument","useInstrumentContext","loginUserAsync","useMutation","rpcProvider","verifyCodeAsync","adapter","useMemo","email","response","panelFailureKind","cause","kindFromRpcError","code","challengeId","login","useEmailCodeLogin","pendingLoginKey","accessToken","savePanelSession","returnURL","readPersistedReturnURL","buildAccessTokenRedirect","onCodeStep","title","description","Card","LoginBrandLogo","CardHeader","CardTitle","CardDescription","CardContent","EmailCodeLoginForm","PanelLoginComponentWrapper","analytics","textOverrides","showLogo","logoUrl","logoDarkUrl","theme","allowedReturnOrigins","usePanelConfig","useInstrument","resolvePanelLoginTexts","getLocale","styles","parent","useAutoAnimate","useEffect","getPanelSession","queryReturnURL","getReturnURLFromSearch","persistReturnURL","existingToken","InstrumentProvider","PanelLogin","props","useAutoAnimate","useEffect","useState","useState","useCallback","useEffect","useUrlSearchParams","initialValue","params","setParams","urlParams","parsed","key","value","updateParams","newParams","prev","updated","newUrl","handlePopState","resolvePanelReturnsAppearance","explicit","brand","color","brandColorTokens","PANEL_TEXT_TABLES","getPanelTexts","locale","getLocale","pickLocaleTable","jsx","jsxs","PanelNotifications","texts","getPanelTexts","useState","Fragment","jsx","jsxs","formatDate","ts","getLocale","formatAmount","amount","currency","statusColor","PanelOrderHistory","openOrderDetails","projectID","accessToken","texts","getPanelTexts","statusLabel","offset","setOffset","limit","data","isFetching","isError","refetch","useQuery","rpcProvider","orders","totalCount","currentPage","totalPages","handlePageChange","newOffset","_","i","Skeleton","Button","order","page","a","b","PanelOrderHistory_default","jsx","jsxs","PanelPlans","_projectID","texts","getPanelTexts","useEffect","useState","jsx","jsxs","redirectToLogin","loginURL","dropToken","projectID","host","clearPanelSession","ReturnsScreens","screen","params","setParams","setActiveScreen","status","exchangeError","useReturnsContext","text","useReturnsText","expired","isSessionExpiredError","useEffect","view","setView","useState","draft","setDraft","createdReturnId","setCreatedReturnId","mapReturnsError","Button","SkeletonRows","openReturns","next","ReturnsMyReturnDetail","ReturnsMyReturnsList","returnId","ReturnsResult","orderId","ReturnsConfirmation","ReturnsOrderDetail","selection","ReturnsOrderList","PanelReturns","accessToken","appearance","texts","rest","ReturnsProvider","lazy","Suspense","useEffect","useState","BookOpen","Files","Headphones","Ticket","pl","en","getProductTexts","getLocale","jsx","URL_REGEX","findURLIndices","text","match","replaceTextByIndices","originalText","replacements","result","lastIndex","a","b","startIndex","endIndex","replacementText","renderText","txt","urlIndices","el","fromJsonString","useAutoAnimate","ChevronLeft","Download","useEffect","useRef","useState","Hls","Pause","Play","SkipBack","SkipForward","forwardRef","useEffect","useImperativeHandle","useRef","useState","jsx","jsxs","LoadingIndicator","LoadingIndicator_default","Hls","EXPIRED_STATUSES","NETWORK_ERROR","MEDIA_ERROR","decideHlsError","data","retried","status","kind","error","createHlsSource","args","HlsImpl","instance","src","retriedNetwork","retriedMedia","_event","decision","nextSrc","prefersNativeHls","video","playerErrorFromMediaError","mediaError","MIME_BY_EXTENSION","ARTWORK_SIZES","mediaSessionAvailable","mediaSessionArtworkFromUrl","url","withoutQuery","extension","type","artwork","normalizeArtwork","entries","normalized","entry","mediaSessionSetMetadata","metadata","mediaSessionPlay","mediaSessionPause","mediaSessionUpdateDurationAndPosition","duration","currentTime","playbackRate","position","rate","MEDIA_SESSION_ACTIONS","startMediaSessionCoordinator","args","action","details","stopMediaSessionCoordinator","useEffect","useState","pl","en","useAudioTexts","locale","deviceLocale","setDeviceLocale","getLocale","formatTime","value","seconds","playerStorage","key","value","SPEED_KEY","SPEEDS","jsx","jsxs","AudioPlayer","forwardRef","chapters","locale","styles","updateCurrentTime","setCurrentTimeHandler","title","imageURL","coverShownBeside","author","uniqueProductID","onChapterChange","onError","onExpiredUrl","onFinished","ref","t","useAudioTexts","speed","setSpeed","useState","speedRef","useRef","chapterID","setChapterID","sleepMode","setSleepMode","sleepRemaining","setSleepRemaining","sleepRef","cancelSleep","changeSleep","mode","seconds","changeSpeed","rate","SPEEDS","playerStorage","SPEED_KEY","videoRef","updatePlayerDetails","useEffect","saved","timer","deadline","remaining","playWhenReadyRef","pause","PlayState","playState","setPlayState","currentTime","setCurrentTime","duration","setDuration","isLoading","setIsLoading","playerError","setPlayerError","hlsRef","timerRef","audioPlayerContainerRef","currentChapterRef","playerErrorRef","resumedRef","pendingSeekRef","expiredUrlRef","chaptersRef","chaptersSignatureRef","callbacksRef","saveLastPlayedTime","timeInSeconds","getLastPlayedTime","time","result","getLastSelectedChapterID","lastSelectedChapterID","setLastSelectedChapterID","deleteMemoryChapter","syncMediaSessionMetadata","chapter","mediaSessionSetMetadata","reportError","error","clearError","attemptPlay","video","play","togglePlayState","seekTo","toSecond","knownDuration","target","seekBy","loadSource","src","prefersNativeHls","destroyHls","Hls","createHlsSource","playChapter","options","shouldPlay","loadChapters","list","candidate","playNextChapter","current","currentChapterIndex","nextChapterIndex","finishPlayback","playPreviousChapter","handleEnded","handleLoadedData","pending","lastPlayedTime","handleMediaElementError","mediaError","playerErrorFromMediaError","retry","position","handleMediaSessionAction","details","useImperativeHandle","mediaSessionUpdateDurationAndPosition","startMediaSessionCoordinator","stopMediaSessionCoordinator","chaptersSignature","previousSignature","replacement","wasPlaying","mediaSessionPlay","mediaSessionPause","currentIndex","wholeBookKnown","sum","minutesLeft","leftText","cn","Button","formatTime","event","SkipBack","Play","Pause","SkipForward","minutes","LoadingIndicator_default","AudioPlayer_default","Check","Download","Play","useEffect","useState","Fragment","jsx","jsxs","ChapterList","chapters","currentID","productID","onSelect","downloadable","onDownload","loading","locale","t","useAudioTexts","resume","setResume","useState","played","setPlayed","useEffect","prefix","id","playerStorage","time","chapter","resumeIndex","currentIndex","formatTime","index","current","isPlayed","Play","Check","Download","Fragment","jsx","jsxs","warn","message","args","error","PanelProductDetails","accessToken","product","styles","reveal","t","getProductTexts","productType","instrument","useInstrumentContext","trackDownload","audioPlayerRef","useRef","filesRefAnimation","useAutoAnimate","fileError","setFileError","useState","filesResponse","setFilesResponse","fileDetailsAsync","isFileLoading","useMutation","rpcProvider","audioPlayerSeekToHandler","audioResponse","setAudioResponse","audioDownloadURLs","setAudioDownloadURLs","isAvailableToDownloadInMobileApp","setIsAvailableToDownloadInMobileApp","audioDetailsAsync","isAudioLoading","audioDetailsDownloadURLsAsync","isAudioDownloadURLsLoading","selectedChapter","setSelectedChapter","chapters","setChapters","handleFileDownload","filesResult","err","handleAudioDownload","audioResult","handleAudioURLsDownload","audioURLsResult","useEffect","audioChapters","mappedChapters","chapter","details","el","Button","ChevronLeft","LoadingIndicator_default","url","index","downloadFileName","Download","AudioPlayer_default","handler","ChapterList","PanelProductDetails_default","useTransport","useEffect","useState","useModelFiles","accessToken","projectID","transport","load","setLoad","cancelled","listModelFiles","next","Fragment","jsx","jsxs","PanelModelFiles","lazy","PanelProductGridComponent","accessToken","projectID","loginURL","styles","activeScreen","params","setParams","openCourse","host","usePanelConfig","products","isProductsLoading","productsError","refetch","useQuery","rpcProvider","modelFiles","useModelFiles","decision","decidePanelProducts","useEffect","clearPanelSession","getProductTexts","_","index","productsList","models","filesSection","Suspense","PanelProductsError","PanelProductsEmpty","ProductsComponent","t","onRetry","en","getLocale","Button","PanelProductGrid_default","selectedProduct","setSelectedProduct","useState","resolvePanelProduct","reveal","product","handleSelectedProduct","PanelProductDetails_default","label","action","Icon","Headphones","BookOpen","Ticket","Files","renderText","value","match","legacy","fromJsonString","UserProductSchema","LogOut","Library","Receipt","Undo2","User","panelNavItems","navScreen","screen","jsx","jsxs","PanelProductHeaderComponent","activeScreen","setActiveScreen","setParams","theme","logout","email","projectID","texts","getPanelTexts","branding","useLoginBranding","LoginBrandLogo","panelNavItems","screen","label","Icon","active","navScreen","cn","LogOut","useState","LogOut","jsx","jsxs","PanelProfileComponent","email","logout","onLocaleChange","locale","updateLocale","useState","getLocale","texts","getPanelTexts","event","setLocale","LogOut","lazy","Suspense","jsx","PanelCourse","lazy","module","LazyPanelCourse","props","Suspense","LoadingIndicator_default","AlertCircle","CheckCircle2","ChevronLeft","Loader2","Lock","Package","Truck","useEffect","useState","Fragment","jsx","jsxs","StatusBadge","status","statusConfig","CheckCircle2","AlertCircle","Truck","Loader2","config","Icon","statusLabels","AddCommentForm","orderID","email","message","setMessage","useState","addCommentMutation","useMutation","rpcProvider","e","error","Label","Textarea","Button","formatDate","timestamp","formatCurrency","amount","currency","PublicOrderPageContent","initialEmail","onBack","accessToken","analytics","theme","projectID","usePanelConfig","instrument","useInstrument","verifyEmail","setVerifyEmail","isVerifyDialogOpen","setIsVerifyDialogOpen","orderData","isLoading","refetch","useQuery","order","isVerified","viewedOrder","useEffect","handleVerifyEmail","styles","Card","CardContent","ChevronLeft","CardHeader","CardTitle","Package","Lock","item","index","comment","Input","PublicOrderPage","props","PublicOrderPage_default","jsx","jsxs","PanelPage","returnsAppearance","returnsTexts","analytics","projectID","theme","loginURL","host","usePanelConfig","refreshLocale","useState","instrument","useInstrument","accessToken","getPanelSession","email","getPanelEmail","logoutUserAsync","useMutation","rpcProvider","logout","clearPanelSession","panelParentRef","useAutoAnimate","isScreen","value","params","setParams","useUrlSearchParams","activeScreen","setActiveScreen","handleOpenOrderDetails","orderID","handleBackToOrders","navigate","next","handleOpenCourse","accessId","handleLeaveCourse","useEffect","styles","queryReturnURL","getReturnURLFromSearch","persistReturnURL","returnURL","readPersistedReturnURL","buildAccessTokenRedirect","InstrumentProvider","PanelProductHeaderComponent","PanelProductGrid_default","LazyPanelCourse","item","PanelNotifications","PanelPlans","PanelOrderHistory_default","PublicOrderPage_default","PanelReturns","resolvePanelReturnsAppearance","PanelProfileComponent","PanelPage_default","create","QueryClient","QueryClientProvider","createContext","useContext","useEffect","useState","createClient","createConnectTransport","PublicApiClient","get","host","createClient","PublicApiService","getTransport","transports","transport","createConnectTransport","clientHeaderInterceptor","zod","zod","round","num","numberOfDecimals","formatCurrency","amount","currency","language","eventPayload","zod","sendAnalyticEvent","payload","sendGoogleAnalyticsEvent","sendPixelAnalyticsEvent","sendTikTokAnalyticsEvent","ga4Event","mapToGA4EcommerceEvent","e","totalValue","sum","item","items","round","ecommerce","eventName","eventType","tiktokEvent","mapToTikTokEvent","contents","mapGooglePayConfiguration","args","items","googlePayConfig","checkout","result","cartRequiresShipping","locale","getLocale","intents","method","formatCurrency","getCheckoutText","round","mapGooglePayDisplayItems","methods","deliveryMethod","couponCode","couponValue","couponLabel","displayItems","subtotalAmount","item","unitPrice","selectedDeliveryMethod","buildURL","projectID","path","HOST","isErr","x","Err","message","type","data","findProductForCartItem","productID","products","el","variant","findMissingProductIDs","requested","resolved","found","id","cartItemURL","url","base","value","create","useCheckoutStore","set","notice","state","numberOfProductsInCart","createContext","useContext","useMemo","jsx","CheckoutTextsContext","createContext","CheckoutTextsProvider","texts","locale","children","value","useMemo","useCheckoutTextsConfig","useContext","useCheckoutText","key","getCheckoutText","getLocale","useCheckoutTextResolver","activeLocale","PENDING_ORDER_KEY","subtractOrderLines","cart","lines","ordered","line","rest","item","quantity","PENDING_ORDER_MIN_ASK_INTERVAL_MS","throttleOrderStatus","fetchStatus","now","minIntervalMs","last","order","key","at","parseOrderFromPaymentUrl","url","path","match","isManualPaymentUrl","resolvePendingOrder","response","fromUrl","orderId","nonEmpty","projectId","rememberPendingOrder","options","savePendingOrder","value","defaultStorage","storage","PENDING_ORDER_KEY","readPendingOrder","raw","cartProjectId","ts","clearPendingOrder","orderStatusFromResponse","status","readUnknownStatus","unknown","field","length","offset","shift","byte","reconcilePendingOrder","deps","current","Fragment","jsx","MARKETING_AGREEMENT_ID","CartProviderContext","createContext","bitsnapProjectID","setProjectID","projectID","setPanelConfig","setAllowedReturnOrigins","getProjectID","getNewHostIfExist","CartProvider","children","locale","queryClient","useState","QueryClient","textsConfig","useCheckoutTextsConfig","useEffect","updateNumberOfProductsInCart","reconcile","reconcileOrderOfLastPayment","outcome","onVisibilityChange","checkoutMethods","getCheckoutMethods","QueryClientProvider","reconciling","askAboutOrder","throttleOrderStatus","order","orderStatusFromResponse","PublicApiClient","HOST","getCheckoutSelection","country","couponCode","selectedDeliveryMethod","postalCode","getCheckout","emptyCheckout","getCartLines","el","removeOrderLinesFromCart","lines","checkout","saveCheckout","subtractOrderLines","reconcilePendingOrder","e","getProducts","args","products","productIds","product","params","getLocale","payload","result","withClientParam","buildURL","Err","details","findProductForCartItem","resolveProductDetailsFromSingleProduct","useCartProvider","context","useContext","CartProvider_default","googlePayConfigSchema","zod","checkoutProduct","checkoutSchema","checkoutKey","value","addProducts","latestProducts","item","index","isErr","missingIDs","findMissingProductIDs","cartItemURL","trackCartAdd","sendAnalyticEvent","added","latest","found","price","currency","productID","getCartInstrument","removeProductFromCheckout","ids","newCheckout","id","model","cartLinkRequest","mergedMetadata","acc","key","texts","newHost","setCustomHost","googlePayConfig","resolveGooglePayConfiguration","create","PreOrderItemSchema","cartRequiresShipping","mappedPaymentRequest","mapGooglePayConfiguration","empty","deliveryMethod","email","getPaymentMethodChoice","paymentResponse","createPaymentURL","injectReferenceToRequestIfNeeded","round","shippingName","metadata","ref","getReferenceIfPossible","GetPreOrderDetailsRequestSchema","AddressSchema","BillingAddressSchema","error","items","getCheckoutText","variantIndex","v","variant","numberOfProductsInCart","useCheckoutStore","state","MAX_PLAIN_MESSAGE_LENGTH","ITEM_IDS_NOT_FOUND","INTERNAL_ERROR","BUY_ERROR_TEXT_KEYS","GENERIC_TEXT_CODES","ITEM_IDS_CODES","buyErrorTextKey","code","looksLikeMarkup","text","looksLikeCode","looksLikeStack","plainMessage","trimmed","MAX_UNWRAP_DEPTH","unwrapMessage","error","depth","inner","result","fromMessage","parseBuyError","bodyText","payload","body","message","innerCode","parsed","id","buyErrorFromResponse","status","itemIds","hasItemIds","Err","data","buyErrorText","err","getText","key","METHODS","ACCOUNT_TYPES","uniqueKnown","value","known","result","item","parsePaymentMethodChoice","body","choice","methods","withoutCod","method","effectivePaymentMethod","selected","manualPaymentTitleKey","types","hasBank","hasBlik","fetchPaymentMethodChoice","url","init","timeoutMs","controller","timer","response","Bitsnap","addProductToCart","id","quantity","metadata","args","projectID","getProjectID","err","getCheckoutMethods","showCart","useCheckoutStore","hideCart","readBody","response","cartRequestInit","request","injectReferenceToRequestIfNeeded","getLocale","clientHeaders","visitorHeaders","getPaymentMethodChoice","fetchPaymentMethodChoice","buildURL","createPaymentURL","result","buyErrorFromResponse","createCheckout","headers","path","HOST","getReferenceIfPossible","refLink","ref"]}
|