bitsnap-react 1.18.0 → 1.19.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.
Files changed (157) hide show
  1. package/AGENTS.md +106 -0
  2. package/README.md +98 -0
  3. package/dist/BitsnapCart-E72W5RRZ.mjs +2 -0
  4. package/dist/BitsnapCart-LHJ6KOTV.css +2 -0
  5. package/dist/BitsnapCart-LHJ6KOTV.css.map +1 -0
  6. package/dist/BitsnapCart-Q2HER6GU.js +2 -0
  7. package/dist/BitsnapCart-Q2HER6GU.js.map +1 -0
  8. package/dist/CartProvider-677CE2FI.js +2 -0
  9. package/dist/CartProvider-677CE2FI.js.map +1 -0
  10. package/dist/CartProvider-YPDOFSYC.mjs +2 -0
  11. package/dist/{PanelModelFiles-JZFSF7BF.mjs → PanelModelFiles-4B2HYGIE.mjs} +2 -2
  12. package/dist/{PanelModelFiles-7HPXWONN.js → PanelModelFiles-EKQRLF46.js} +2 -2
  13. package/dist/PanelModelFiles-EKQRLF46.js.map +1 -0
  14. package/dist/analytics.js +1 -1
  15. package/dist/analytics.js.map +1 -1
  16. package/dist/analytics.mjs +1 -1
  17. package/dist/catalog.js +1 -1
  18. package/dist/catalog.js.map +1 -1
  19. package/dist/catalog.mjs +1 -1
  20. package/dist/chat.css +2 -0
  21. package/dist/chat.css.map +1 -0
  22. package/dist/chat.d.mts +172 -0
  23. package/dist/chat.d.ts +172 -0
  24. package/dist/chat.js +2 -0
  25. package/dist/chat.js.map +1 -0
  26. package/dist/chat.mjs +2 -0
  27. package/dist/chat.mjs.map +1 -0
  28. package/dist/chunk-2FD2QP4Y.js +2 -0
  29. package/dist/chunk-2FD2QP4Y.js.map +1 -0
  30. package/dist/chunk-5JRUPLXY.mjs +2 -0
  31. package/dist/chunk-5JRUPLXY.mjs.map +1 -0
  32. package/dist/chunk-5M6M7FAR.mjs +2 -0
  33. package/dist/chunk-5M6M7FAR.mjs.map +1 -0
  34. package/dist/chunk-6Q3VGPSF.js.map +1 -1
  35. package/dist/chunk-AAC576BC.mjs +5 -0
  36. package/dist/chunk-AAC576BC.mjs.map +1 -0
  37. package/dist/{chunk-4OVOKGGS.mjs → chunk-AB37DWOK.mjs} +2 -2
  38. package/dist/{chunk-ZATPBYOA.js → chunk-BUYTK7KM.js} +2 -2
  39. package/dist/chunk-BUYTK7KM.js.map +1 -0
  40. package/dist/{chunk-DP2NOHCI.js → chunk-D2ASWUXM.js} +2 -2
  41. package/dist/chunk-D2ASWUXM.js.map +1 -0
  42. package/dist/chunk-DDIEFKNP.mjs +2 -0
  43. package/dist/{chunk-ZHTMK5TA.mjs.map → chunk-DDIEFKNP.mjs.map} +1 -1
  44. package/dist/{chunk-4HGZZJEL.js → chunk-DOJICJCQ.js} +2 -2
  45. package/dist/chunk-DOJICJCQ.js.map +1 -0
  46. package/dist/chunk-EMR4YXNY.mjs +2 -0
  47. package/dist/chunk-EMR4YXNY.mjs.map +1 -0
  48. package/dist/{chunk-JA62KNAQ.js → chunk-GJOGATP6.js} +2 -2
  49. package/dist/chunk-GJOGATP6.js.map +1 -0
  50. package/dist/chunk-GQ5OKU74.js +2 -0
  51. package/dist/chunk-GQ5OKU74.js.map +1 -0
  52. package/dist/chunk-JSDGZ4NY.js.map +1 -1
  53. package/dist/chunk-KHQEDQYF.js +5 -0
  54. package/dist/chunk-KHQEDQYF.js.map +1 -0
  55. package/dist/chunk-KOYBZORL.js.map +1 -1
  56. package/dist/chunk-LGPNJ5XE.js +2 -0
  57. package/dist/chunk-LGPNJ5XE.js.map +1 -0
  58. package/dist/chunk-MDAFPGPA.js +2 -0
  59. package/dist/chunk-MDAFPGPA.js.map +1 -0
  60. package/dist/{chunk-JHJ3ZZF4.mjs → chunk-MMLBQHBM.mjs} +2 -2
  61. package/dist/chunk-MWWEPEU2.js +2 -0
  62. package/dist/chunk-MWWEPEU2.js.map +1 -0
  63. package/dist/{chunk-GEBRXFT3.mjs → chunk-N523LFAM.mjs} +2 -2
  64. package/dist/chunk-NWXZ45TV.js +2 -0
  65. package/dist/chunk-NWXZ45TV.js.map +1 -0
  66. package/dist/chunk-OFPRIENJ.mjs +2 -0
  67. package/dist/chunk-OFPRIENJ.mjs.map +1 -0
  68. package/dist/chunk-OR566YJI.mjs +2 -0
  69. package/dist/chunk-OR566YJI.mjs.map +1 -0
  70. package/dist/chunk-Q337IQNA.js +2 -0
  71. package/dist/chunk-Q337IQNA.js.map +1 -0
  72. package/dist/chunk-SCEWYZUZ.mjs +2 -0
  73. package/dist/chunk-SCEWYZUZ.mjs.map +1 -0
  74. package/dist/{chunk-CF45RDMD.mjs → chunk-SSSF64M7.mjs} +2 -2
  75. package/dist/{chunk-CF45RDMD.mjs.map → chunk-SSSF64M7.mjs.map} +1 -1
  76. package/dist/chunk-W3RGQYPD.js.map +1 -1
  77. package/dist/chunk-WG54EHST.mjs +2 -0
  78. package/dist/chunk-WG54EHST.mjs.map +1 -0
  79. package/dist/chunk-XEXPQFKN.mjs +2 -0
  80. package/dist/chunk-XEXPQFKN.mjs.map +1 -0
  81. package/dist/chunk-YV2C276H.js +2 -0
  82. package/dist/chunk-YV2C276H.js.map +1 -0
  83. package/dist/consent.js.map +1 -1
  84. package/dist/course.d.mts +2 -14
  85. package/dist/course.d.ts +2 -14
  86. package/dist/course.js +1 -1
  87. package/dist/course.js.map +1 -1
  88. package/dist/course.mjs +1 -1
  89. package/dist/course.mjs.map +1 -1
  90. package/dist/embed/analytics.js +1 -1
  91. package/dist/errors.js.map +1 -1
  92. package/dist/index.css +1 -1
  93. package/dist/index.css.map +1 -1
  94. package/dist/index.d.mts +288 -4
  95. package/dist/index.d.ts +288 -4
  96. package/dist/index.js +1 -1
  97. package/dist/index.js.map +1 -1
  98. package/dist/index.mjs +1 -1
  99. package/dist/index.mjs.map +1 -1
  100. package/dist/internal.js.map +1 -1
  101. package/dist/methods-64D5DD6K.js +2 -0
  102. package/dist/methods-64D5DD6K.js.map +1 -0
  103. package/dist/methods-NQA3DFLE.mjs +2 -0
  104. package/dist/methods-NQA3DFLE.mjs.map +1 -0
  105. package/dist/model-files-client-P4PORZJ6.js.map +1 -1
  106. package/dist/models.js.map +1 -1
  107. package/dist/returns.js +1 -1
  108. package/dist/returns.js.map +1 -1
  109. package/dist/returns.mjs +1 -1
  110. package/dist/texts-9kfgClsA.d.mts +14 -0
  111. package/dist/texts-9kfgClsA.d.ts +14 -0
  112. package/dist/{types-D6LsoycW.d.mts → types-B-sjyZQs.d.mts} +7 -1
  113. package/dist/{types-ClFCVzk_.d.ts → types-iRe6ix2y.d.ts} +7 -1
  114. package/dist/viewer3d.js.map +1 -1
  115. package/dist/viewer3d.mjs +1 -1
  116. package/dist/viewer3d.mjs.map +1 -1
  117. package/dist/widgets-BT2LN2Nq.d.mts +547 -0
  118. package/dist/widgets-BVOSj9fU.d.ts +547 -0
  119. package/package.json +18 -3
  120. package/dist/CartProvider-OEI526IN.js +0 -2
  121. package/dist/CartProvider-OEI526IN.js.map +0 -1
  122. package/dist/CartProvider-RYAA3JDA.mjs +0 -2
  123. package/dist/PanelModelFiles-7HPXWONN.js.map +0 -1
  124. package/dist/chunk-4HGZZJEL.js.map +0 -1
  125. package/dist/chunk-5X7TP3TQ.mjs +0 -2
  126. package/dist/chunk-5X7TP3TQ.mjs.map +0 -1
  127. package/dist/chunk-7RXW6XFY.js +0 -2
  128. package/dist/chunk-7RXW6XFY.js.map +0 -1
  129. package/dist/chunk-DP2NOHCI.js.map +0 -1
  130. package/dist/chunk-EVIDNS22.mjs +0 -2
  131. package/dist/chunk-EVIDNS22.mjs.map +0 -1
  132. package/dist/chunk-G4V2KWTV.js +0 -2
  133. package/dist/chunk-G4V2KWTV.js.map +0 -1
  134. package/dist/chunk-GWF3MRUP.js +0 -2
  135. package/dist/chunk-GWF3MRUP.js.map +0 -1
  136. package/dist/chunk-JA62KNAQ.js.map +0 -1
  137. package/dist/chunk-UPAOIY4R.mjs +0 -2
  138. package/dist/chunk-UPAOIY4R.mjs.map +0 -1
  139. package/dist/chunk-V5ECGBFW.js +0 -5
  140. package/dist/chunk-V5ECGBFW.js.map +0 -1
  141. package/dist/chunk-VNV5BD4X.js +0 -2
  142. package/dist/chunk-VNV5BD4X.js.map +0 -1
  143. package/dist/chunk-VNYHJT6V.mjs +0 -2
  144. package/dist/chunk-VNYHJT6V.mjs.map +0 -1
  145. package/dist/chunk-WJO5GSY3.mjs +0 -5
  146. package/dist/chunk-WJO5GSY3.mjs.map +0 -1
  147. package/dist/chunk-ZATPBYOA.js.map +0 -1
  148. package/dist/chunk-ZHTMK5TA.mjs +0 -2
  149. package/dist/methods-AULQDKVS.mjs +0 -2
  150. package/dist/methods-PMH5VQ25.js +0 -2
  151. package/dist/methods-PMH5VQ25.js.map +0 -1
  152. /package/dist/{CartProvider-RYAA3JDA.mjs.map → BitsnapCart-E72W5RRZ.mjs.map} +0 -0
  153. /package/dist/{methods-AULQDKVS.mjs.map → CartProvider-YPDOFSYC.mjs.map} +0 -0
  154. /package/dist/{PanelModelFiles-JZFSF7BF.mjs.map → PanelModelFiles-4B2HYGIE.mjs.map} +0 -0
  155. /package/dist/{chunk-4OVOKGGS.mjs.map → chunk-AB37DWOK.mjs.map} +0 -0
  156. /package/dist/{chunk-JHJ3ZZF4.mjs.map → chunk-MMLBQHBM.mjs.map} +0 -0
  157. /package/dist/{chunk-GEBRXFT3.mjs.map → chunk-N523LFAM.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/checkout/ApplePay.tsx","../src/components/checkout/project-id.ts","../src/components/checkout/BitsnapCart.tsx","../src/components/checkout/CartComponent.tsx","../src/components/checkout/appearance.context.tsx","../src/components/checkout/appearance.ts","../src/components/checkout/CartComponentContent.tsx","../src/components/checkout/CountrySelector.tsx","../src/ui/select.tsx","../src/components/checkout/SingleProduct.tsx","../src/ui/button-group.tsx","../src/components/checkout/ProductPrice.tsx","../src/components/checkout/quantity.ts","../src/components/checkout/Skeleton.tsx","../src/components/checkout/PaymentMethodChoice.tsx","../src/components/checkout/GooglePay.tsx","../src/components/notifications/NotificationsComponentPublic.tsx","../src/components/notifications/constants.tsx","../src/components/notifications/NotificationHeader.tsx","../src/ui/switch.tsx","../src/components/notifications/NotificationGroupsList.tsx","../src/ui/popover.tsx","../src/components/notifications/HowOftenComponent.tsx","../src/components/notifications/QRCodeSection.tsx","../src/components/notifications/AddUserToGroups.tsx","../src/components/notifications/FormInput.tsx","../src/components/notifications/ManageMyData.tsx","../src/components/notifications/UnsubscribeDialog.tsx","../src/components/notifications/LoginScreen.tsx","../src/ui/dialog.tsx","../src/components/notifications/login-adapter.ts"],"sourcesContent":["import ApplePayButtonModule from \"apple-pay-button\";\nimport { PublicApiClient } from \"src/public.api.client\";\nimport CartProvider, {\n getCheckoutSelection,\n getProjectID,\n useCartProvider,\n} from \"./CartProvider\";\nimport { HOST } from \"./constants\";\nimport { isErr } from \"./lib/err\";\nimport { currentProjectID } from \"./project-id\";\nimport { round } from \"./lib/round.number\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { sendAnalyticEvent } from \"./frontent.analytics\";\nimport { useCheckoutText } from \"./texts.context\";\nimport {\n InstrumentProvider,\n useInstrument,\n useInstrumentContext,\n type AnalyticsOption,\n} from \"@/src/analytics/instrument\";\n\n// A CommonJS package with a `default` export: bundlers unwrap it, Node's own\n// ESM loader (server rendering of the unbundled library) does not.\nconst ApplePayButton: typeof ApplePayButtonModule =\n (ApplePayButtonModule as unknown as { default?: typeof ApplePayButtonModule })\n .default ?? ApplePayButtonModule;\n\ntype AppleButtonType =\n | \"plain\"\n | \"add-money\"\n | \"book\"\n | \"buy\"\n | \"check-out\"\n | \"continue\"\n | \"contribute\"\n | \"donate\"\n | \"order\"\n | \"pay\"\n | \"reload\"\n | \"rent\"\n | \"set-up\"\n | \"subscribe\"\n | \"support\"\n | \"tip\"\n | \"top-up\";\ntype ColorType = \"black\" | \"white\" | \"white-outline\";\n\nexport type Props = {\n style?: {\n width?: string;\n height?: string;\n borderRadius?: string;\n padding?: string;\n boxSizing?: string;\n };\n buttonType?: AppleButtonType;\n colorType?: ColorType;\n items: {\n name: string;\n id: string;\n price: number;\n /** Currency of `price` (minor units); defaults to PLN. */\n currency?: string;\n quantity: number;\n isDeliverable?: boolean;\n metadata?: { [key: string]: string | undefined };\n }[];\n onClick?: () => Promise<void>;\n /**\n * Usage statistics for your Bitsnap dashboard (Apple Pay clicks and\n * results). On by default; `false` turns it off. Inside `<BitsnapCheckout>`\n * the checkout's setting applies unless this is given.\n */\n analytics?: AnalyticsOption;\n};\n\nfunction ApplePayButtonComponent({\n style,\n buttonType,\n colorType,\n items,\n onClick,\n}: Props) {\n const {\n checkIfApplePayIsAvailable,\n getApplePayPaymentRequest,\n completeApplePayPayment,\n setCountry,\n setCouponCodeIfPossible,\n setDeliveryMethod,\n setEmail,\n setPostalCode,\n clearCart,\n getApplePayPreview,\n } = useCartProvider();\n const instrument = useInstrumentContext();\n const paymentForCartText = useCheckoutText(\"paymentForCart\");\n const { data: isApplePayAvailable } = useQuery({\n queryKey: [\"is-apple-pay-available\"],\n queryFn: checkIfApplePayIsAvailable,\n });\n const itemsKey = items.map((el) => `${el.id}:${el.quantity}`).join(\",\");\n const selection = getCheckoutSelection();\n const { data: preview } = useQuery({\n queryKey: [\n \"apple-pay-preview\",\n itemsKey,\n selection.country ?? \"\",\n selection.couponCode ?? \"\",\n selection.selectedDeliveryMethod ?? \"\",\n selection.postalCode ?? \"\",\n ],\n queryFn: () =>\n getApplePayPreview({\n items: items.map((el) => ({\n productID: el.id,\n quantity: el.quantity,\n metadata: el.metadata,\n })),\n }),\n enabled: isApplePayAvailable === true,\n });\n if (isApplePayAvailable != true) {\n return null;\n }\n // The backend's answer when it is there; else the cart's own currency and\n // total, with no delivery in it (it is added once the buyer picks a method).\n const loadedPreview =\n preview != null && !isErr(preview)\n ? preview\n : {\n countryCode: selection.country || \"PL\",\n currencyCode: items[0]?.currency ?? \"PLN\",\n totalAmount: `${round(\n items.reduce((acc, item) => acc + item.price * item.quantity, 0) /\n 100,\n 2,\n )}`,\n };\n\n const expectedItems = items.map((el) => ({\n productID: el.id,\n quantity: el.quantity,\n metadata: el.metadata,\n }));\n\n async function beginSession() {\n let reported = false;\n const report = (outcome: \"success\" | \"fail\" | \"cancel\") => {\n if (reported) {\n return;\n }\n reported = true;\n instrument.track(\"apple_pay_result\", { outcome });\n };\n instrument.track(\"apple_pay_clicked\", {});\n instrument.track(\"payment_method_selected\", {\n gateway: \"apple_pay\",\n method: \"apple_pay\",\n });\n sendAnalyticEvent({\n event: \"initiateCheckout\",\n items: items.map((el) => ({\n id: el.id,\n name: el.name,\n price: el.price,\n quantity: el.quantity,\n currency: loadedPreview.currencyCode,\n })),\n });\n const requiresShipping =\n items.find((el) => el.isDeliverable === true) != null;\n // The session has to be created inside the click, so country, currency\n // and total come from the backend's answer that was loaded beforehand.\n const session = new ApplePaySession(14, {\n countryCode: loadedPreview.countryCode,\n merchantCapabilities: [\"supports3DS\"],\n supportedNetworks: [\"visa\", \"masterCard\"],\n currencyCode: loadedPreview.currencyCode,\n total: {\n amount: loadedPreview.totalAmount,\n label: paymentForCartText,\n type: \"pending\",\n },\n // Delivery is added once the buyer picks a contact and a method.\n lineItems: items.map(\n (item) =>\n ({\n amount: `${round((item.price * item.quantity) / 100, 2)}`,\n label: item.name,\n type: \"final\",\n } as ApplePayJS.ApplePayLineItem)\n ),\n ...(requiresShipping\n ? {\n shippingMethods: [],\n supportsCouponCode: true,\n requiredBillingContactFields: [\n \"name\",\n \"email\",\n \"postalAddress\",\n \"phone\",\n ],\n requiredShippingContactFields: [\n \"name\",\n \"email\",\n \"postalAddress\",\n \"phone\",\n ],\n }\n : {}),\n });\n await onClick?.();\n const apRequest = await getApplePayPaymentRequest({ expectedItems });\n if (isErr(apRequest)) {\n console.error(\"Error creating ApplePaySession:\", apRequest.error);\n report(\"fail\");\n return;\n }\n\n session.oncancel = (event) => {\n console.log(\"ApplePaySession cancelled\", event);\n report(\"cancel\");\n };\n\n session.onvalidatemerchant = async (event) => {\n try {\n const result = await PublicApiClient.get(HOST).applePayValidateMerchant(\n {\n validationUrl: event.validationURL,\n projectId: getProjectID(),\n }\n );\n console.log(\"merchantSession\", result.merchantSession);\n if (result.merchantSession.length > 0) {\n console.log(\"completing merchant session\");\n session.completeMerchantValidation(\n JSON.parse(result.merchantSession)\n );\n } else {\n session.abort();\n }\n } catch (error) {\n session.abort();\n }\n };\n\n session.onshippingmethodselected = async (event) => {\n console.log(\"shipping method selected\", event);\n instrument.track(\"delivery_method_selected\", {\n method: event.shippingMethod.identifier,\n });\n await setDeliveryMethod(event.shippingMethod.identifier);\n const apRequest = await getApplePayPaymentRequest({ expectedItems });\n console.log(\"apRequest\", apRequest);\n if (isErr(apRequest)) {\n session.abort();\n throw new Error(\"Failed to get Apple Pay payment request\");\n }\n\n session.completeShippingMethodSelection({\n newTotal: apRequest.total,\n newLineItems: apRequest.lineItems,\n newShippingMethods: apRequest.shippingMethods,\n });\n };\n session.onshippingcontactselected = async (event) => {\n try {\n if (event.shippingContact.countryCode != null) {\n await setCountry(event.shippingContact.countryCode);\n }\n if (event.shippingContact.postalCode != null) {\n await setPostalCode(event.shippingContact.postalCode);\n }\n if (event.shippingContact.phoneNumber != null) {\n await setEmail(event.shippingContact.emailAddress);\n }\n const apRequest = await getApplePayPaymentRequest({ expectedItems });\n if (isErr(apRequest)) {\n session.abort();\n throw new Error(\"Failed to get Apple Pay payment request\");\n }\n\n console.log(\"apRequest\", apRequest);\n session.completeShippingContactSelection({\n newLineItems: apRequest.lineItems,\n newTotal: apRequest.total,\n newShippingMethods: apRequest.shippingMethods,\n });\n } catch (error) {\n console.log(\"shipping contact selected error\", error);\n session.abort();\n }\n };\n\n session.oncouponcodechanged = async (event) => {\n try {\n console.log(\"coupon code changed\", event);\n const result = await setCouponCodeIfPossible(event.couponCode);\n const apRequest = await getApplePayPaymentRequest({ expectedItems });\n console.log(\"apRequest\", apRequest);\n if (isErr(apRequest)) {\n session.abort();\n throw new Error(\"Failed to get Apple Pay payment request\");\n }\n\n session.completeCouponCodeChange({\n errors: isErr(result)\n ? [new ApplePayError(\"couponCodeInvalid\")]\n : undefined,\n newTotal: apRequest.total,\n newLineItems: apRequest.lineItems,\n newShippingMethods: apRequest.shippingMethods,\n });\n } catch (error) {\n console.log(\"coupon code changed error\", error);\n session.abort();\n }\n };\n\n session.onpaymentauthorized = async (event) => {\n instrument.track(\"payment_submitted\", {\n gateway: \"apple_pay\",\n method: \"apple_pay\",\n });\n try {\n const result = await completeApplePayPayment({\n token: event.payment.token,\n billingContact: event.payment.billingContact,\n shippingContact: event.payment.shippingContact,\n });\n if (isErr(result)) {\n console.log(\"apple pay error\", result);\n report(\"fail\");\n session.completePayment({\n status: ApplePaySession.STATUS_FAILURE,\n });\n return;\n }\n\n if (result.redirectURL) {\n setTimeout(() => {\n open(result.redirectURL, \"_self\");\n }, 2000);\n }\n report(result.isSuccess ? \"success\" : \"fail\");\n session.completePayment({\n status: result.isSuccess\n ? ApplePaySession.STATUS_SUCCESS\n : ApplePaySession.STATUS_FAILURE,\n });\n\n result.isSuccess && clearCart();\n } catch (e) {\n report(\"fail\");\n session.completePayment({\n status: ApplePaySession.STATUS_FAILURE,\n });\n }\n // event.complete(ApplePaySession.STATUS_SUCCESS);\n };\n\n session.begin();\n }\n\n return (\n <ApplePayButton\n style={style}\n buttonStyle={colorType}\n type={buttonType}\n onClick={beginSession}\n />\n );\n}\n\nfunction Wrapper(props: Props) {\n const instrument = useInstrument(\n currentProjectID(),\n props.analytics,\n \"cart\",\n );\n return (\n <InstrumentProvider value={instrument}>\n <CartProvider>\n <ApplePayButtonComponent {...props} />\n </CartProvider>\n </InstrumentProvider>\n );\n}\nexport default Wrapper;\n","import { getProjectID } from \"./CartProvider\";\n\n/** The page's project ID; `undefined` (instead of a throw) during server rendering. */\nexport function currentProjectID(): string | undefined {\n try {\n return getProjectID();\n } catch {\n return undefined;\n }\n}\n","import { useEffect, useId, useRef } from \"react\";\nimport zod from \"zod\";\nimport {\n InstrumentProvider,\n useCartInstrument,\n useInstrument,\n type AnalyticsOption,\n} from \"@/src/analytics/instrument\";\nimport type { CheckoutAppearance } from \"./appearance\";\nimport type { CheckoutTexts } from \"./texts\";\nimport CartComponent from \"./CartComponent\";\nimport { getCheckoutMethods, getProjectID, setProjectID } from \"./CartProvider\";\nimport { sendAnalyticEvent } from \"./frontent.analytics\";\nimport { isErr } from \"./lib/err\";\nimport { useCheckoutStore } from \"./state\";\nimport { getLocale, setLocale } from \"./locale\";\nimport { getCheckoutText, type CheckoutTextKey } from \"./texts\";\n\nenum CartEvent {\n ADD_TO_CART = \"ADD_TO_CART\",\n}\n\nconst cartAddToCartSchema = zod.object({\n id: zod.string(),\n isSubscription: zod.boolean().default(false),\n quantity: zod.number(),\n metadata: zod.record(zod.string(), zod.string().optional()).optional(),\n url: zod.string().optional(),\n});\n\ntype CartAddToCartEvent = zod.infer<typeof cartAddToCartSchema>;\n\nexport type BitsnapCartProps = {\n projectID: string;\n locale?: string;\n children?: React.ReactNode;\n onVisibleChange?: (isVisible: boolean) => void;\n className?: string;\n numberOfProductsInCartOptions?: {\n style?: React.CSSProperties;\n isVisible?: boolean;\n };\n /**\n * Optional checkout appearance. Omitting it (or passing `{}`) keeps the\n * current presentation; every token and element slot is partial.\n */\n appearance?: CheckoutAppearance;\n /**\n * Optional text overrides. Any key given here replaces the built-in string\n * whatever the locale; omitted keys keep the `pl`/`en` defaults.\n */\n texts?: Partial<CheckoutTexts>;\n /**\n * Usage statistics for your Bitsnap dashboard (cart opened, checkout\n * started, add to cart). On by default; `false` turns it off. An object\n * lets you forward every event: `{ onEvent }`. Nothing is stored on the\n * visitor's device.\n */\n analytics?: AnalyticsOption;\n};\n\nconst visuallyHidden: React.CSSProperties = {\n position: \"absolute\",\n width: 1,\n height: 1,\n margin: -1,\n padding: 0,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n};\n\nfunction BitsnapCart({\n projectID,\n locale,\n children,\n onVisibleChange,\n className,\n numberOfProductsInCartOptions,\n appearance,\n texts,\n analytics,\n}: BitsnapCartProps) {\n const instrument = useInstrument(projectID, analytics, \"cart\");\n // Cart changes made outside of components (`Bitsnap.addProductToCart`) are reported here.\n useCartInstrument(instrument);\n const { isCartVisible, showCart, hideCart, numberOfProductsInCart } =\n useCheckoutStore();\n const panelId = `bitsnap-cart-${useId()}`;\n const text = (key: CheckoutTextKey) =>\n getCheckoutText(key, locale ?? getLocale(), texts);\n // The `window.cart` handlers are created once and must read the latest props.\n const textRef = useRef(text);\n textRef.current = text;\n\n /** Shows a message through the error area of the cart drawer. */\n function showCartNotice(key: CheckoutTextKey) {\n useCheckoutStore.getState().setNotice(textRef.current(key));\n showCart();\n }\n\n function sentPostMessageToIframe(msg: unknown) {\n const iframes = document.querySelectorAll(\"iframe\");\n\n iframes.forEach((iframe) => {\n iframe.contentWindow?.postMessage(msg, \"*\");\n });\n }\n\n useEffect(() => {\n onVisibleChange?.(isCartVisible);\n if (isCartVisible) {\n sendAnalyticEvent({\n event: \"viewCart\",\n });\n }\n }, [isCartVisible]);\n\n useEffect(() => {\n setProjectID(projectID);\n }, [projectID]);\n\n useEffect(() => {\n setLocale(locale);\n }, [locale]);\n\n useEffect(() => {\n if (!(\"cart\" in window)) {\n const projectID = getProjectID();\n if (projectID == null) {\n console.warn(\"There is no project ID configured.\");\n return;\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n window[\"cart\"] = {\n buyProduct: async (args: unknown) => {\n try {\n const payload = zod\n .object({\n productID: zod.string(),\n email: zod.string().optional(),\n name: zod.string().optional(),\n country: zod.string().optional(),\n marketingAgreement: zod.boolean().optional(),\n locale: zod.string().optional(),\n })\n .parse(args);\n const methods = getCheckoutMethods(projectID);\n try {\n const products = await methods.getProducts();\n if (isErr(products) == false) {\n sendAnalyticEvent({\n event: \"initiateCheckout\",\n items: products.map((el) => ({\n id: el.productID,\n name: el.details?.name ?? \"\",\n price: el.details?.price ?? 0,\n quantity: el.quantity,\n currency: el.details?.currency ?? \"PLN\",\n })),\n });\n }\n } catch (e) {}\n\n const result = await methods.justRedirectToPayment(payload);\n\n if (isErr(result) == false) {\n window.location.href = result.url;\n } else {\n showCartNotice(\"redirectFailed\");\n }\n } catch (e) {\n console.warn(e);\n }\n },\n };\n }\n }, []);\n\n async function handleAddingToCart(id: string, payload?: unknown) {\n const projectID = getProjectID();\n if (projectID == null) {\n console.warn(\"There is no project ID configured.\");\n return;\n }\n\n try {\n const data = cartAddToCartSchema.parse(payload);\n\n if (data.isSubscription) {\n await handleAddingSubscriptionToCart(projectID, data);\n return;\n }\n\n const methods = getCheckoutMethods(projectID);\n\n await methods.addProduct({\n productID: data.id,\n quantity: data.quantity,\n metadata: data.metadata,\n url: data.url,\n });\n\n sentPostMessageToIframe({\n id: id,\n type: CartEvent.ADD_TO_CART,\n success: true,\n });\n showCart();\n } catch (e) {\n console.warn(\"cannot add item to cart\", e);\n }\n }\n\n async function handleAddingSubscriptionToCart(\n projectID: string,\n event: CartAddToCartEvent,\n ) {\n console.warn(\n \"subscriptions cannot be added to the cart yet\",\n projectID,\n event.id,\n );\n showCartNotice(\"subscriptionUnsupported\");\n }\n\n function setupEventListener() {\n if (\"__cart_is_listening\" in window) {\n return;\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n window[\"__cart_is_listening\"] = true;\n window.addEventListener(\"message\", (event) => {\n if (\n typeof event.data[\"id\"] != \"undefined\" &&\n typeof event.data[\"type\"] != \"undefined\"\n ) {\n const { id, type } = event.data;\n switch (type) {\n case CartEvent.ADD_TO_CART.toString():\n handleAddingToCart(id, event.data[\"payload\"]).then().catch();\n break;\n default:\n break;\n }\n }\n });\n }\n\n useEffect(() => {\n setupEventListener();\n\n if (typeof window !== \"undefined\") {\n try {\n const parsedParams = new URLSearchParams(window.location.search);\n const refLink =\n parsedParams.get(\"ref\") ?? parsedParams.get(\"utm-source\");\n if (\n typeof localStorage != \"undefined\" &&\n refLink &&\n refLink.length > 0\n ) {\n localStorage.setItem(\"bitsnap-ref\", refLink);\n }\n } catch (e) {\n return;\n }\n }\n }, []);\n\n return (\n <>\n <button\n type=\"button\"\n onClick={() => (isCartVisible ? hideCart() : showCart())}\n aria-label={\n children\n ? undefined\n : numberOfProductsInCart > 0\n ? `${text(\"openCart\")}. ${text(\"cartItemsCount\")}: ${numberOfProductsInCart}`\n : text(\"openCart\")\n }\n aria-expanded={isCartVisible}\n aria-haspopup=\"dialog\"\n aria-controls={isCartVisible ? panelId : undefined}\n style={{ position: \"relative\" }}\n className={[\n \"bitsnap-react\",\n className ?? \"rounded-full hover:bg-neutral-300 transition p-1\",\n ].join(\" \")}\n >\n {children ? (\n <>{children}</>\n ) : (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-shopping-cart\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"8\" cy=\"21\" r=\"1\" />\n <circle cx=\"19\" cy=\"21\" r=\"1\" />\n <path d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\" />\n </svg>\n )}\n {numberOfProductsInCart > 0 && (\n <span style={visuallyHidden}>\n {text(\"cartItemsCount\")}: {numberOfProductsInCart}\n </span>\n )}\n {numberOfProductsInCartOptions?.isVisible != false &&\n numberOfProductsInCart > 0 && (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n bottom: -5,\n right: -5,\n background: \"black\",\n color: \"white\",\n borderRadius: \"50%\",\n width: \"22px\",\n height: \"22px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"13px\",\n fontWeight: 600,\n boxShadow: \"0 2px 8px rgba(0, 0, 0, 0.25)\",\n ...numberOfProductsInCartOptions?.style,\n }}\n >\n {numberOfProductsInCart}\n </div>\n )}\n </button>\n <InstrumentProvider value={instrument}>\n <CartComponent\n isVisible={isCartVisible}\n locale={locale}\n appearance={appearance}\n texts={texts}\n panelId={panelId}\n shouldHide={() => {\n hideCart();\n }}\n />\n </InstrumentProvider>\n </>\n );\n}\n\nexport default BitsnapCart;\n","import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport * as Dialog from \"@radix-ui/react-dialog\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@/src/lib/utils\";\nimport {\n CheckoutAppearanceProvider,\n useCheckoutAppearance,\n useCheckoutSlot,\n} from \"./appearance.context\";\nimport type { CheckoutAppearance } from \"./appearance\";\nimport CartComponentContent from \"./CartComponentContent\";\nimport CartProvider from \"./CartProvider\";\nimport { CheckoutTextsProvider, useCheckoutText } from \"./texts.context\";\nimport type { CheckoutTexts } from \"./texts\";\n\ninterface Props {\n isVisible: boolean;\n shouldHide: () => void;\n locale?: string;\n appearance?: CheckoutAppearance;\n texts?: Partial<CheckoutTexts>;\n /** DOM id of the panel, for `aria-controls` of the button that opens it. */\n panelId?: string;\n}\n\nfunction CartComponent({ isVisible, shouldHide, panelId, locale }: Props) {\n const [parent] = useAutoAnimate(/* optional config */);\n // The drawer renders inside the checkout root: the stylesheet is scoped to `.bitsnap-react`.\n const [rootElement, setRootElement] = useState<HTMLDivElement | null>(null);\n const rootRef = useCallback(\n (element: HTMLDivElement | null) => {\n parent(element);\n setRootElement(element);\n },\n [parent],\n );\n // The trigger lives outside of the dialog, so Radix does not know which element to give the focus back to.\n const returnFocusTo = useRef<HTMLElement | null>(null);\n const { boundaryClassName, boundaryStyle } = useCheckoutAppearance();\n const root = useCheckoutSlot(\"root\");\n const overlay = useCheckoutSlot(\"overlay\");\n const panel = useCheckoutSlot(\"panel\");\n const header = useCheckoutSlot(\"header\");\n const title = useCheckoutSlot(\"title\");\n const closeButton = useCheckoutSlot(\"closeButton\");\n const cartText = useCheckoutText(\"cart\");\n const closeText = useCheckoutText(\"close\");\n\n return (\n <div\n ref={rootRef}\n data-bitsnap-checkout=\"root\"\n data-bitsnap-checkout-slot=\"root\"\n className={cn(\"bitsnap-react\", boundaryClassName, root.className)}\n style={{ zIndex: 999999, ...boundaryStyle, ...root.style }}\n >\n {rootElement != null && (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(open) => {\n if (!open) {\n shouldHide();\n }\n }}\n >\n <Dialog.Portal container={rootElement}>\n <Dialog.Overlay\n data-bitsnap-checkout-slot=\"overlay\"\n aria-hidden=\"true\"\n className={cn(\n \"fixed top-0 right-0 left-0 bottom-0 cursor-pointer z-10\",\n overlay.className,\n )}\n style={overlay.style}\n onClick={shouldHide}\n />\n <Dialog.Content\n id={panelId}\n data-bitsnap-checkout-slot=\"panel\"\n aria-modal=\"true\"\n aria-describedby={undefined}\n onOpenAutoFocus={() => {\n const active = document.activeElement;\n returnFocusTo.current = active instanceof HTMLElement ? active : null;\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n returnFocusTo.current?.focus();\n returnFocusTo.current = null;\n }}\n className={cn(\n // Scrolls when the summary and the payment choice do not fit (small phones).\n \"fixed z-20 top-0 right-0 bottom-0 w-full md:w-[350px] xl:w-[420px] flex flex-col overflow-y-auto\",\n panel.className,\n )}\n style={panel.style}\n // The overlay closes the drawer on click; a close on pointer down would let the click through.\n onPointerDownOutside={(event) => event.preventDefault()}\n >\n <div\n data-bitsnap-checkout-slot=\"header\"\n className={cn(\n \"mx-3 mt-7 flex justify-between items-center\",\n header.className,\n )}\n style={header.style}\n >\n <Dialog.Title asChild>\n <h1\n data-bitsnap-checkout-slot=\"title\"\n className={cn(\"text-2xl font-medium\", title.className)}\n style={title.style}\n >\n {cartText}\n </h1>\n </Dialog.Title>\n <button\n type=\"button\"\n data-bitsnap-checkout-slot=\"closeButton\"\n className={cn(\n \"rounded-xl p-2 transition\",\n closeButton.className,\n )}\n style={closeButton.style}\n aria-label={closeText}\n onClick={shouldHide}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-x\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n\n <CartComponentContent className={\"grow\"} locale={locale} />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )}\n </div>\n );\n}\n\nconst WrapperCartComponent = (props: Props) => {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n return createPortal(\n <CheckoutAppearanceProvider appearance={props.appearance}>\n <CheckoutTextsProvider texts={props.texts} locale={props.locale}>\n <CartProvider locale={props.locale}>\n <CartComponent {...props} />\n </CartProvider>\n </CheckoutTextsProvider>\n </CheckoutAppearanceProvider>,\n document.body,\n );\n};\n\nexport default WrapperCartComponent;\n","import { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n getCheckoutSlotAppearance,\n resolveCheckoutAppearance,\n type CheckoutAppearance,\n type CheckoutSlotAppearance,\n type CheckoutSlotName,\n type ResolvedCheckoutAppearance,\n} from \"./appearance\";\n\nconst CheckoutAppearanceContext = createContext<ResolvedCheckoutAppearance>(\n resolveCheckoutAppearance(),\n);\n\n/**\n * Checkout scoped appearance provider. It only wraps the checkout drawer, so\n * the configuration never leaks into the panel, the notifications or any\n * global state.\n */\nexport function CheckoutAppearanceProvider({\n appearance,\n children,\n}: {\n appearance?: CheckoutAppearance;\n children: ReactNode;\n}) {\n const resolved = useMemo(\n () => resolveCheckoutAppearance(appearance),\n [appearance],\n );\n\n return (\n <CheckoutAppearanceContext.Provider value={resolved}>\n {children}\n </CheckoutAppearanceContext.Provider>\n );\n}\n\nexport function useCheckoutAppearance(): ResolvedCheckoutAppearance {\n return useContext(CheckoutAppearanceContext);\n}\n\n/**\n * Returns the caller overrides for a slot. The values are meant to be merged\n * with the built-in presentation:\n *\n * ```tsx\n * const slot = useCheckoutSlot(\"title\");\n *\n * return <h1 className={cn(\"text-2xl font-medium\", slot.className)} style={slot.style} />;\n * ```\n */\nexport function useCheckoutSlot(\n slot: CheckoutSlotName,\n): CheckoutSlotAppearance {\n const resolved = useCheckoutAppearance();\n\n return getCheckoutSlotAppearance(resolved, slot) ?? {};\n}\n","import type { CSSProperties } from \"react\";\nimport {\n getSlotAppearance,\n resolveAppearanceCore,\n type AppearanceElements,\n type ShadcnVariableMapping,\n type SlotAppearance,\n} from \"@/src/lib/appearance-core\";\n\n/**\n * Checkout appearance API.\n *\n * `CheckoutAppearance` is resolved once per render into plain data: a theme\n * name, the tokens that are actually in effect, the per-slot overrides and the\n * inline style that both theme boundaries (the drawer root and the portalled\n * country dropdown) have to receive. Everything here is pure so it can be\n * tested without a DOM.\n *\n * Backward compatibility: the resolver never invents values. A token is only\n * present in the resolved output when the caller provided it or when the\n * caller explicitly selected a theme preset, so every unset token keeps falling\n * back to the value the checkout renders today (see `checkout.css`).\n */\n\nexport type CheckoutTheme = \"dark\" | \"light\";\n\nexport type CheckoutAppearanceTokens = {\n /** Checkout wide font family. The library never loads fonts. */\n fontFamily?: string;\n /** Base font size of the checkout. */\n fontSize?: string;\n /** Panel background. */\n background?: string;\n /** Raised surfaces: country dropdown, search bar, loading skeletons. */\n surface?: string;\n /** Main text color. */\n foreground?: string;\n /** Secondary text: empty cart, delivery info, country label, search input. */\n mutedForeground?: string;\n /** Borders: country trigger, dropdown, product separators. */\n border?: string;\n /** Checkout button background. */\n buttonBackground?: string;\n /** Checkout button text. */\n buttonForeground?: string;\n /** Checkout button background on hover. */\n buttonHoverBackground?: string;\n /** Hover and selected surfaces: close button, country options. */\n hoverSurface?: string;\n /** Focus ring color. Also applied to shared UI primitives through `--ring`. */\n focusRing?: string;\n /** Error and unavailable state color. */\n error?: string;\n /** Drawer backdrop color. */\n overlay?: string;\n /** Corner radius, applied through `--radius`. */\n radius?: string;\n};\n\n/**\n * Stable slot names. They are exposed as `data-bitsnap-checkout-slot`\n * attributes so they can also be targeted from plain CSS.\n */\nexport const CHECKOUT_SLOT_NAMES = [\n \"root\",\n \"overlay\",\n \"panel\",\n \"header\",\n \"title\",\n \"closeButton\",\n \"productList\",\n \"product\",\n \"productImage\",\n \"productName\",\n \"productPrice\",\n \"quantityControl\",\n \"quantityInput\",\n \"quantityButton\",\n \"removeButton\",\n \"summary\",\n \"totalLabel\",\n \"totalValue\",\n \"deliveryText\",\n \"summaryNote\",\n \"countryLabel\",\n \"countryTrigger\",\n \"countryDropdown\",\n \"countrySearch\",\n \"countryOption\",\n \"paymentButtons\",\n \"paymentMethods\",\n \"paymentMethodOption\",\n \"checkoutButton\",\n \"emptyState\",\n \"error\",\n \"skeleton\",\n] as const;\n\nexport type CheckoutSlotName = (typeof CHECKOUT_SLOT_NAMES)[number];\n\nexport type CheckoutSlotAppearance = SlotAppearance;\n\nexport type CheckoutAppearanceElements = AppearanceElements<CheckoutSlotName>;\n\nexport type CheckoutAppearance = {\n /**\n * `\"dark\"` keeps the current presentation, `\"light\"` applies the light preset.\n * Omitted means `\"dark\"`.\n */\n theme?: CheckoutTheme;\n /** Partial overrides. Anything omitted keeps today's value. */\n tokens?: CheckoutAppearanceTokens;\n /** Per element `className`/`style` overrides. */\n elements?: CheckoutAppearanceElements;\n};\n\nexport type ResolvedCheckoutAppearance = {\n theme: CheckoutTheme;\n /**\n * `true` as soon as the caller passed anything through `appearance`. The\n * country dropdown is portalled outside of the checkout root, so it only\n * receives the checkout boundary when the caller opted in - an omitted or\n * empty `appearance` keeps the previous (unthemed) dropdown untouched.\n */\n isCustomized: boolean;\n /** Tokens that are in effect. Empty entries were dropped. */\n tokens: CheckoutAppearanceTokens;\n elements: CheckoutAppearanceElements;\n /** Theme marker class for the theme boundaries. */\n boundaryClassName: string;\n /** Inline custom properties applied to the drawer root. */\n boundaryStyle: CSSProperties;\n /**\n * Extra properties for the portalled country dropdown. The shared select\n * content paints itself with `bg-popover`/`text-popover-foreground`, so those\n * variables have to carry the checkout colors over to the portal. They are\n * resolved eagerly because the dropdown is the only place where the built-in\n * defaults differ from the drawer.\n */\n dropdownStyle: CSSProperties;\n};\n\n/** CSS custom property used for each token. */\nexport const CHECKOUT_TOKEN_VARIABLES = {\n fontFamily: \"--bitsnap-checkout-font-family\",\n fontSize: \"--bitsnap-checkout-font-size\",\n background: \"--bitsnap-checkout-background\",\n surface: \"--bitsnap-checkout-surface\",\n foreground: \"--bitsnap-checkout-foreground\",\n mutedForeground: \"--bitsnap-checkout-muted-foreground\",\n border: \"--bitsnap-checkout-border\",\n buttonBackground: \"--bitsnap-checkout-button-background\",\n buttonForeground: \"--bitsnap-checkout-button-foreground\",\n buttonHoverBackground: \"--bitsnap-checkout-button-hover-background\",\n hoverSurface: \"--bitsnap-checkout-hover-surface\",\n focusRing: \"--bitsnap-checkout-focus-ring\",\n error: \"--bitsnap-checkout-error\",\n overlay: \"--bitsnap-checkout-overlay\",\n radius: \"--bitsnap-checkout-radius\",\n} as const;\n\nexport type CheckoutTokenName = keyof typeof CHECKOUT_TOKEN_VARIABLES;\n\n/**\n * Theme presets are intentionally partial. `\"dark\"` is empty because every\n * default already renders the current dark presentation; `\"light\"` only carries\n * the colors that have to change for a light checkout, so typography is never\n * reset implicitly.\n */\nexport const CHECKOUT_THEME_PRESETS: Record<\n CheckoutTheme,\n CheckoutAppearanceTokens\n> = {\n dark: {},\n light: {\n background: \"#ffffff\",\n surface: \"#f9fafb\",\n foreground: \"#18181b\",\n mutedForeground: \"#71717a\",\n border: \"#e4e4e7\",\n buttonBackground: \"#18181b\",\n buttonForeground: \"#fafafa\",\n buttonHoverBackground: \"#000000\",\n hoverSurface: \"#e4e4e7\",\n focusRing: \"#71717a\",\n error: \"#dc2626\",\n overlay: \"rgb(0 0 0 / 0.35)\",\n },\n};\n\n/**\n * Some shared UI primitives (`Button`, `SelectTrigger`, ...) read the shadcn\n * theme variables instead of checkout tokens. Those are remapped so a themed\n * dropdown and themed primitives stay consistent. They are only written when\n * the matching token is in effect, so untouched tokens change nothing.\n */\nconst CHECKOUT_SHADCN_VARIABLES: ShadcnVariableMapping<CheckoutTokenName> = [\n { token: \"background\", variable: \"--background\" },\n { token: \"foreground\", variable: \"--foreground\" },\n { token: \"surface\", variable: \"--card\" },\n { token: \"surface\", variable: \"--popover\" },\n { token: \"foreground\", variable: \"--popover-foreground\" },\n { token: \"mutedForeground\", variable: \"--muted-foreground\" },\n { token: \"border\", variable: \"--border\" },\n { token: \"border\", variable: \"--input\" },\n { token: \"focusRing\", variable: \"--ring\" },\n { token: \"error\", variable: \"--destructive\" },\n { token: \"radius\", variable: \"--radius\" },\n];\n\n/**\n * The portalled dropdown renders `bg-popover`/`text-popover-foreground` from the\n * shared primitives, so those two variables are resolved eagerly: without a\n * token they fall back to the dark values the checkout has always used.\n */\nfunction resolveDropdownStyle(tokens: CheckoutAppearanceTokens): CSSProperties {\n return {\n \"--popover\": tokens.surface ?? \"var(--color-neutral-800)\",\n \"--popover-foreground\": tokens.foreground ?? \"var(--color-neutral-200)\",\n } as CSSProperties;\n}\n\nexport function resolveCheckoutAppearance(\n appearance?: CheckoutAppearance,\n): ResolvedCheckoutAppearance {\n const resolved = resolveAppearanceCore<\n CheckoutTokenName,\n CheckoutTheme,\n CheckoutSlotName\n >(appearance, {\n defaultTheme: \"dark\",\n presets: CHECKOUT_THEME_PRESETS,\n variables: CHECKOUT_TOKEN_VARIABLES,\n shadcnVariables: CHECKOUT_SHADCN_VARIABLES,\n });\n\n return {\n theme: resolved.theme,\n isCustomized: resolved.isCustomized,\n tokens: resolved.tokens,\n elements: resolved.elements,\n boundaryClassName: resolved.theme,\n boundaryStyle: resolved.boundaryStyle,\n dropdownStyle: resolveDropdownStyle(resolved.tokens),\n };\n}\n\n/** Caller overrides for a single slot, if any were provided. */\nexport function getCheckoutSlotAppearance(\n resolved: ResolvedCheckoutAppearance,\n slot: CheckoutSlotName,\n): CheckoutSlotAppearance | undefined {\n return getSlotAppearance(resolved.elements, slot);\n}\n","import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport React from \"react\";\nimport { useInstrumentContext } from \"@/src/analytics/instrument\";\nimport { getCartLines, getProjectID, useCartProvider } from \"./CartProvider\";\nimport CountrySelector from \"./CountrySelector\";\nimport { isErr } from \"./lib/err\";\nimport { formatCurrency } from \"./lib/round.number\";\nimport LoadingIndicator from \"./LoadingIndicator\";\nimport SingleProduct from \"./SingleProduct\";\nimport { Skeleton } from \"./Skeleton\";\nimport { ApplePayButton, GooglePayButton } from \"..\";\nimport { Spinner } from \"@/src/ui/spinner\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { cn } from \"@/src/lib/utils\";\nimport { sendAnalyticEvent } from \"./frontent.analytics\";\nimport { getLocale } from \"./locale\";\nimport { buyErrorText } from \"./buy-error\";\nimport { useCheckoutText, useCheckoutTextResolver } from \"./texts.context\";\nimport { useCheckoutSlot } from \"./appearance.context\";\nimport { rememberPendingOrder } from \"./pending-order\";\nimport { useCheckoutStore } from \"./state\";\nimport { PaymentMethodChoice } from \"./PaymentMethodChoice\";\nimport {\n effectivePaymentMethod,\n withoutCod,\n type PaymentMethod,\n type PaymentMethodChoice as Choice,\n} from \"./payment-method\";\n\nconst CartComponentContent = ({\n className,\n locale,\n}: {\n className: string;\n locale?: string;\n}) => {\n const provider = useCartProvider();\n const instrument = useInstrumentContext();\n const currentLocale = locale ?? getLocale();\n\n const productList = useCheckoutSlot(\"productList\");\n const summary = useCheckoutSlot(\"summary\");\n const totalLabel = useCheckoutSlot(\"totalLabel\");\n const totalValue = useCheckoutSlot(\"totalValue\");\n const deliveryText = useCheckoutSlot(\"deliveryText\");\n const summaryNote = useCheckoutSlot(\"summaryNote\");\n const countryLabel = useCheckoutSlot(\"countryLabel\");\n const paymentButtons = useCheckoutSlot(\"paymentButtons\");\n const checkoutButton = useCheckoutSlot(\"checkoutButton\");\n const emptyState = useCheckoutSlot(\"emptyState\");\n const error = useCheckoutSlot(\"error\");\n const skeleton = useCheckoutSlot(\"skeleton\");\n\n const unavailableProductsText = useCheckoutText(\"unavailableProducts\");\n const resolveCheckoutText = useCheckoutTextResolver();\n const emptyCartText = useCheckoutText(\"emptyCart\");\n const totalText = useCheckoutText(\"total\");\n const deliveryCopy = useCheckoutText(\"delivery\");\n const chooseCountryText = useCheckoutText(\"chooseCountry\");\n const nextStepText = useCheckoutText(\"nextStep\");\n const loadFailedText = useCheckoutText(\"loadFailed\");\n const retryText = useCheckoutText(\"retry\");\n const countryRequiredText = useCheckoutText(\"countryRequired\");\n const extrasCalculatedNextText = useCheckoutText(\"extrasCalculatedNext\");\n const countrySelectorId = React.useId();\n const countryHintId = React.useId();\n\n const { mutateAsync: removeProduct } = useMutation({\n mutationFn: provider.removeProductFromCart,\n });\n const { mutateAsync: updateQuantity } = useMutation({\n mutationFn: provider.updateQuantity,\n });\n const { mutateAsync: setCountryAsync } = useMutation({\n mutationFn: provider.setCountry,\n });\n const { mutateAsync: clearCart } = useMutation({\n mutationFn: provider.clearCart,\n });\n\n const [errMsg, setErrMsg] = React.useState(\"\");\n // Raised outside of the drawer (for example a failed redirect of `window.cart.buyProduct`).\n const notice = useCheckoutStore((state) => state.notice);\n React.useEffect(\n () => () => useCheckoutStore.getState().setNotice(undefined),\n [],\n );\n const shownError = errMsg.length > 0 ? errMsg : (notice ?? \"\");\n const [missingItemIds, setMissingItemIds] = React.useState<string[]>([]);\n\n const [isCountryOpen, setIsCountryOpen] = React.useState(false);\n\n const {\n mutateAsync: continueToCheckoutAsync,\n isPending: isContinueToCheckoutLoading,\n } = useMutation({\n mutationFn: provider.redirectToNextStep,\n });\n\n const { data: availableCountries } = useQuery({\n queryKey: [\"cart-available-countries\"],\n queryFn: provider.getAvailableCountries,\n });\n const { data: isApplePayAvailable } = useQuery({\n queryKey: [\"cart-one-click-payment\"],\n queryFn: provider.checkIfApplePayIsAvailable,\n });\n const { data, isLoading, isError, refetch } = useQuery({\n queryKey: [\"cart\", currentLocale],\n queryFn: provider.getProducts,\n });\n const { data: countryData, refetch: refetchCountry } = useQuery({\n queryKey: [\"cart-country\"],\n queryFn: provider.getCountry,\n });\n\n const [productsParent] = useAutoAnimate(/* optional config */);\n\n const products = isErr(data) ? undefined : data;\n\n const selectedCountry =\n countryData != null && !isErr(countryData) && countryData != \"\"\n ? countryData\n : undefined;\n\n // Whether the shop lets the buyer pay by hand (transfer / BLIK to a phone)\n // or on delivery for this cart. Asked once per cart content and country\n // (cash on delivery is for Poland only); any failure means \"no choice\".\n // Without a country \"Next step\" is disabled, so there is nothing to ask yet.\n // Until a new country or cart is answered, the last choice stays on screen\n // without cash on delivery, which the new answer may not offer.\n const queryClient = useQueryClient();\n const cartSignature =\n products == null || products.length === 0 || selectedCountry == null\n ? undefined\n : products\n .map((el) => `${el.productID}:${el.quantity}`)\n .sort()\n .join(\",\");\n const paymentMethodsQuery = {\n queryKey: [\n \"cart-payment-methods\",\n getProjectID(),\n currentLocale,\n selectedCountry,\n cartSignature,\n ],\n queryFn: async (): Promise<Choice | null> =>\n provider.getPaymentMethodChoice().catch(() => null),\n staleTime: 60_000,\n retry: false,\n } as const;\n const {\n data: paymentMethodChoiceData,\n isPlaceholderData: isPaymentMethodChoicePlaceholder,\n } = useQuery({\n ...paymentMethodsQuery,\n enabled: cartSignature != null,\n placeholderData: (previous: Choice | null | undefined) =>\n previous === undefined ? undefined : withoutCod(previous),\n });\n const paymentMethodChoice =\n cartSignature != null ? (paymentMethodChoiceData ?? null) : null;\n const [selectedPaymentMethod, setSelectedPaymentMethod] = React.useState<\n PaymentMethod | undefined\n >(undefined);\n const [isWaitingForChoice, setIsWaitingForChoice] = React.useState(false);\n const paymentMethodsRef = React.useRef<HTMLDivElement>(null);\n const hasLoadFailed = !isLoading && (isError || isErr(data));\n\n const countries = isErr(availableCountries) ? [] : availableCountries;\n\n const sumOfProducts =\n products?.reduce((prev, curr) => {\n if (curr.details == null) {\n return prev;\n }\n return prev + (curr.details.pricing?.effectivePrice ?? curr.details.price) * curr.quantity;\n }, 0) ?? 0;\n const currency = products?.[0]?.details?.currency ?? \"PLN\";\n\n const isSomeProductDeliverable =\n products?.some((product) => product.details?.isDeliverable === true) ??\n false;\n\n // The hint waits for the answer: the country is read asynchronously.\n const isCountryMissing = countryData !== undefined && selectedCountry == null;\n\n // A stored country the shop does not ship to (or none at all) would leave the checkout button disabled.\n const autoSelectedCountry = React.useRef(false);\n React.useEffect(() => {\n if (\n autoSelectedCountry.current ||\n countries == null ||\n countries.length === 0 ||\n countryData == null ||\n (selectedCountry != null &&\n countries.some((el) => el.code === selectedCountry))\n ) {\n return;\n }\n autoSelectedCountry.current = true;\n setCountryAsync(countries[0].code)\n .then(() => refetchCountry())\n .catch(() => {});\n }, [countries, countryData, selectedCountry]);\n\n // One `cart_opened` per opening of the drawer, once the cart is loaded.\n const opened = React.useRef(false);\n React.useEffect(() => {\n if (opened.current || isLoading) {\n return;\n }\n opened.current = true;\n instrument.track(\"cart_opened\", {\n item_count: products?.reduce((sum, el) => sum + el.quantity, 0) ?? 0,\n value_minor: sumOfProducts,\n currency,\n });\n }, [isLoading, instrument, products, sumOfProducts, currency]);\n\n const reportedQuantity = React.useRef(new Map<string, number>());\n React.useEffect(() => {\n reportedQuantity.current.clear();\n }, [products]);\n\n /** `add_to_cart` / `remove_from_cart` for a quantity change in the drawer. */\n function trackQuantityChange(id: string, newQuantity: number) {\n const line = products?.find((el) => el.id === id);\n if (line?.details == null) {\n return;\n }\n // Quick clicks arrive before the cart is reloaded: count from the last reported quantity.\n const delta = newQuantity - (reportedQuantity.current.get(id) ?? line.quantity);\n reportedQuantity.current.set(id, newQuantity);\n if (delta === 0) {\n return;\n }\n const price = line.details.pricing?.effectivePrice ?? line.details.price;\n const productID = line.catalogProductID ?? line.productID;\n instrument.track(\n delta > 0 ? \"add_to_cart\" : \"remove_from_cart\",\n {\n qty: Math.abs(delta),\n value_minor: Math.round(price * Math.abs(delta)),\n currency: line.details.currency,\n },\n {\n product_id: productID,\n variant_id: productID !== line.productID ? line.productID : null,\n },\n );\n }\n\n const startedCheckout = React.useRef(false);\n\n /** Rejects when the cart could not be changed; the cart is reloaded either way. */\n async function shouldUpdate(id: string, newQuantity?: number) {\n if (newQuantity == null) {\n return;\n }\n trackQuantityChange(id, Math.max(0, newQuantity));\n try {\n const result =\n newQuantity <= 0\n ? await removeProduct({ id: id })\n : await updateQuantity({ id: id, quantity: newQuantity });\n if (isErr(result)) {\n throw new Error(`cannot change the cart: ${result.error}`);\n }\n } finally {\n await refetch().catch(() => undefined);\n }\n }\n\n async function continueToCheckout() {\n try {\n setErrMsg(\"\");\n setMissingItemIds([]);\n useCheckoutStore.getState().setNotice(undefined);\n\n // A click before the choice arrived waits for it (at most the request\n // timeout); a choice the buyer has not seen yet is shown, not used. The\n // last choice shown in the meantime is used if the new one still offers\n // the selected method.\n let choice = paymentMethodChoice;\n let paymentMethod =\n choice != null\n ? effectivePaymentMethod(choice, selectedPaymentMethod)\n : undefined;\n if (\n cartSignature != null &&\n (paymentMethodChoiceData === undefined || isPaymentMethodChoicePlaceholder)\n ) {\n setIsWaitingForChoice(true);\n try {\n choice = await queryClient\n .fetchQuery(paymentMethodsQuery)\n .catch(() => null);\n } finally {\n setIsWaitingForChoice(false);\n }\n if (choice == null) {\n paymentMethod = undefined;\n } else if (paymentMethod == null || !choice.methods.includes(paymentMethod)) {\n // Let the buyer see the options first; focus moves to the selected one.\n window.setTimeout(() => {\n paymentMethodsRef.current\n ?.querySelector<HTMLInputElement>(\"input:checked\")\n ?.focus();\n }, 0);\n return;\n }\n }\n\n if (products != null) {\n if (!startedCheckout.current && products.length > 0) {\n startedCheckout.current = true;\n instrument.track(\"checkout_started\", {\n item_count: products.reduce((sum, el) => sum + el.quantity, 0),\n checkout_type: \"cart\",\n value_minor: sumOfProducts,\n currency,\n });\n }\n try {\n sendAnalyticEvent({\n event: \"initiateCheckout\",\n items: products?.map((el) => ({\n id: el.productID,\n name: el.details?.name ?? \"\",\n price: el.details?.price ?? 0,\n quantity: el.quantity,\n currency: el.details?.currency ?? \"PLN\",\n })),\n });\n } catch (e) {}\n }\n\n // What this order is made of; only these lines go once it is paid.\n const cartLinesBeforeBuy = getCartLines();\n const response = await continueToCheckoutAsync(\n paymentMethod != null ? { paymentMethod } : undefined,\n );\n\n if (isErr(response)) {\n // The seller may have changed the payment methods in the meantime.\n void queryClient.invalidateQueries({ queryKey: [\"cart-payment-methods\"] });\n if (response.error == \"item-ids-not-found\") {\n setErrMsg(unavailableProductsText);\n if (\"data\" in response && Array.isArray(response.data)) {\n setMissingItemIds(response.data as string[]);\n }\n } else if (\n paymentMethod === \"cod\" &&\n response.error == \"gateway-not-configured\"\n ) {\n // The shop turned cash on delivery off, or this cart does not qualify.\n setErrMsg(resolveCheckoutText(\"paymentMethodCodUnavailable\"));\n } else {\n setErrMsg(buyErrorText(response, resolveCheckoutText));\n }\n return;\n }\n\n // The cart stays until the order is paid (or placed, for cash on\n // delivery); without an order to ask about it is cleared now.\n if (\n !rememberPendingOrder(response, {\n cartProjectId: getProjectID(),\n lines: cartLinesBeforeBuy,\n })\n ) {\n await clearCart();\n }\n window.location.href = response.url;\n } catch (e: unknown) {\n console.warn(\"checkout failed\", e);\n setErrMsg(resolveCheckoutText(\"checkoutFailed\"));\n }\n }\n\n return (\n <div className={`${className} flex flex-col`} ref={productsParent}>\n {isLoading && (\n <div className={\"relative flex w-full justify-center flex-col gap-4\"}>\n <Skeleton\n data-bitsnap-checkout-slot=\"skeleton\"\n className={cn(\"w-full h-32\", skeleton.className)}\n style={skeleton.style}\n />\n <Skeleton\n data-bitsnap-checkout-slot=\"skeleton\"\n className={cn(\"w-full h-32\", skeleton.className)}\n style={skeleton.style}\n />\n </div>\n )}\n\n {hasLoadFailed && (\n <div className={\"flex flex-col items-start gap-3 p-4\"}>\n <p\n role=\"alert\"\n data-bitsnap-checkout-slot=\"error\"\n className={cn(error.className)}\n style={error.style}\n >\n {loadFailedText}\n </p>\n {notice != null && notice.length > 0 && (\n <p\n role=\"alert\"\n data-bitsnap-checkout-slot=\"error\"\n className={cn(\"text-sm\", error.className)}\n style={error.style}\n >\n {notice}\n </p>\n )}\n <button\n type=\"button\"\n data-bitsnap-checkout-slot=\"checkoutButton\"\n onClick={() => {\n refetch().then().catch();\n }}\n className={cn(\n \"px-3 py-2 rounded-md transition font-bold\",\n checkoutButton.className,\n )}\n style={checkoutButton.style}\n >\n {retryText}\n </button>\n </div>\n )}\n\n {!isLoading && !hasLoadFailed && (products == null || products.length == 0) && (\n <div className={\"flex flex-col gap-4 p-4\"}>\n <p\n data-bitsnap-checkout-slot=\"emptyState\"\n className={cn(emptyState.className)}\n style={emptyState.style}\n >\n {emptyCartText}\n </p>\n {notice != null && notice.length > 0 && (\n <p\n role=\"alert\"\n data-bitsnap-checkout-slot=\"error\"\n className={cn(\"text-sm\", error.className)}\n style={error.style}\n >\n {notice}\n </p>\n )}\n </div>\n )}\n\n <div\n data-bitsnap-checkout-slot=\"productList\"\n className={cn(\n \"max-h-[70vh] overflow-clip overflow-y-scroll\",\n productList.className,\n )}\n style={productList.style}\n >\n {products != null && products.length > 0 && (\n <ul className={\"mt-5\"}>\n {products.map((product) => (\n <React.Fragment key={product.id}>\n {product.details != null && (\n <li className={\"mb-3\"}>\n <SingleProduct\n isNotAvailable={missingItemIds.includes(\n product.productID,\n )}\n quantity={product.quantity}\n details={product.details}\n url={product.url}\n shouldUpdate={(newQuantity) =>\n shouldUpdate(product.id, newQuantity)\n }\n />\n <hr className=\"h-1\" />\n </li>\n )}\n </React.Fragment>\n ))}\n </ul>\n )}\n </div>\n\n <div className=\"grow\"></div>\n\n {sumOfProducts > 0 && currency != null && (\n <>\n <div\n data-bitsnap-checkout-slot=\"summary\"\n className={cn(\"mx-3 flex flex-col\", summary.className)}\n style={summary.style}\n >\n <div className={\"flex flex-row justify-between text-lg\"}>\n <p\n data-bitsnap-checkout-slot=\"totalLabel\"\n className={cn(\"text-xl\", totalLabel.className)}\n style={totalLabel.style}\n >\n {totalText}\n </p>\n <div className={\"flex flex-col items-end\"}>\n <p\n data-bitsnap-checkout-slot=\"totalValue\"\n className={cn(\"font-medium\", totalValue.className)}\n style={totalValue.style}\n >\n {formatCurrency(sumOfProducts, currency)}\n </p>\n {isSomeProductDeliverable && (\n <p\n data-bitsnap-checkout-slot=\"deliveryText\"\n className={cn(\n \"opacity-70 text-right text-base\",\n deliveryText.className,\n )}\n style={deliveryText.style}\n >\n {deliveryCopy}\n </p>\n )}\n </div>\n </div>\n <p\n data-bitsnap-checkout-slot=\"summaryNote\"\n className={cn(\"opacity-70 text-sm\", summaryNote.className)}\n style={summaryNote.style}\n >\n {extrasCalculatedNextText}\n </p>\n </div>\n\n {countries && countries?.length > 1 && (\n <div>\n <h4\n data-bitsnap-checkout-slot=\"countryLabel\"\n className={cn(\"ml-3 text-sm\", countryLabel.className)}\n style={countryLabel.style}\n >\n {chooseCountryText}\n </h4>\n <CountrySelector\n id={countrySelectorId}\n open={isCountryOpen}\n onToggle={() => {\n setIsCountryOpen(!isCountryOpen);\n }}\n onChange={(newValue) => {\n setCountryAsync(newValue).then(() => {\n refetchCountry().then().catch();\n });\n }}\n selectedValue={selectedCountry ?? \"\"}\n countries={countries}\n />\n </div>\n )}\n\n <div className={\"mb-3 flex flex-col\"}>\n {isApplePayAvailable && products != null && products.length > 0 && (\n <div\n data-bitsnap-checkout-slot=\"paymentButtons\"\n className={cn(\"w-full px-2\", paymentButtons.className)}\n style={paymentButtons.style}\n >\n <ApplePayButton\n colorType=\"white\"\n style={{ width: \"100%\" }}\n items={products?.map((el) => ({\n name: el.details?.name ?? \"\",\n id: el.productID,\n price: el.details?.pricing?.effectivePrice ?? el.details?.price ?? 0,\n currency: el.details?.currency,\n quantity: el.quantity,\n isDeliverable: el.details?.isDeliverable ?? false,\n metadata: el.metadata,\n }))}\n />\n </div>\n )}\n {products != null && products.length > 0 && (\n <div\n data-bitsnap-checkout-slot=\"paymentButtons\"\n className={cn(\"w-full px-2\", paymentButtons.className)}\n style={paymentButtons.style}\n >\n <GooglePayButton\n buttonSizeMode=\"fill\"\n buttonColor=\"white\"\n style={{ width: \"100%\" }}\n items={products?.map((el) => ({\n name: el.details?.name ?? \"\",\n id: el.productID,\n price: el.details?.pricing?.effectivePrice ?? el.details?.price ?? 0,\n quantity: el.quantity,\n isDeliverable: el.details?.isDeliverable ?? false,\n metadata: el.metadata,\n }))}\n />\n </div>\n )}\n {paymentMethodChoice != null && (\n <div ref={paymentMethodsRef} className=\"contents\">\n <PaymentMethodChoice\n choice={paymentMethodChoice}\n selected={effectivePaymentMethod(\n paymentMethodChoice,\n selectedPaymentMethod,\n )}\n onChange={setSelectedPaymentMethod}\n disabled={isContinueToCheckoutLoading}\n />\n </div>\n )}\n <button\n data-bitsnap-checkout-slot=\"checkoutButton\"\n onClick={continueToCheckout}\n disabled={\n isLoading ||\n isContinueToCheckoutLoading ||\n isWaitingForChoice ||\n selectedCountry == null\n }\n aria-describedby={isCountryMissing ? countryHintId : undefined}\n className={cn(\n \"px-3 py-2 my-2 mx-2 rounded-md disabled:opacity-40 disabled:cursor-not-allowed transition font-bold\",\n checkoutButton.className,\n )}\n style={checkoutButton.style}\n >\n {isContinueToCheckoutLoading || isWaitingForChoice ? (\n <Spinner />\n ) : (\n nextStepText\n )}\n </button>\n {isCountryMissing && (\n <p\n id={countryHintId}\n className={\"text-sm text-center opacity-70\"}\n >\n {countryRequiredText}\n </p>\n )}\n {shownError.length > 0 && (\n <p\n role=\"alert\"\n data-bitsnap-checkout-slot=\"error\"\n className={cn(\"text-sm text-center\", error.className)}\n style={error.style}\n >\n {shownError}\n </p>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport default CartComponentContent;\n","import { useEffect, useState } from \"react\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/src/ui/select\";\nimport { cn } from \"@/src/lib/utils\";\nimport { useCheckoutAppearance, useCheckoutSlot } from \"./appearance.context\";\nimport { useCheckoutText } from \"./texts.context\";\n\nexport interface CountrySelectorProps {\n id: string;\n open: boolean;\n disabled?: boolean;\n onToggle: () => void;\n onChange: (value: string) => void;\n selectedValue: string;\n countries: { name: string; code: string }[];\n}\n\nfunction CountrySelector({\n id,\n open,\n disabled = false,\n onToggle,\n onChange,\n selectedValue,\n countries,\n}: CountrySelectorProps) {\n const [query, setQuery] = useState(\"\");\n\n const {\n isCustomized,\n boundaryClassName,\n boundaryStyle,\n dropdownStyle,\n } = useCheckoutAppearance();\n const countryTrigger = useCheckoutSlot(\"countryTrigger\");\n const countryDropdown = useCheckoutSlot(\"countryDropdown\");\n const countrySearch = useCheckoutSlot(\"countrySearch\");\n const countryOption = useCheckoutSlot(\"countryOption\");\n const searchCountryText = useCheckoutText(\"searchCountry\");\n const noCountriesFoundText = useCheckoutText(\"noCountriesFound\");\n\n useEffect(() => {\n if (selectedValue == null && countries.length > 0) {\n onChange(countries[0].code);\n }\n }, []);\n\n const filteredCountries = countries.filter((country) =>\n country.name.toLowerCase().startsWith(query.toLowerCase()),\n );\n\n const selectedCountry = countries.find((el) => el.code === selectedValue);\n\n return (\n <Select\n value={selectedValue}\n onValueChange={(value) => {\n onChange(value);\n setQuery(\"\");\n }}\n open={open}\n onOpenChange={(isOpen) => {\n if (isOpen !== open) {\n onToggle();\n }\n if (!isOpen) {\n setQuery(\"\");\n }\n }}\n disabled={disabled}\n >\n <SelectTrigger\n data-bitsnap-checkout-slot=\"countryTrigger\"\n theme=\"bare\"\n className={cn(\n disabled\n ? \"bg-neutral-100 dark:bg-neutral-800 dark:border-neutral-700\"\n : \"\",\n \"w-full rounded-md\",\n countryTrigger.className,\n )}\n style={countryTrigger.style}\n >\n <SelectValue>\n {selectedCountry && (\n <span className=\"truncate flex items-center\">\n <img\n alt={selectedValue}\n src={`https://purecatamphetamine.github.io/country-flag-icons/3x2/${selectedValue}.svg`}\n className=\"inline mr-2 h-4 rounded-sm\"\n />\n {selectedCountry.name}\n </span>\n )}\n </SelectValue>\n </SelectTrigger>\n <SelectContent\n data-bitsnap-checkout={isCustomized ? \"dropdown\" : undefined}\n data-bitsnap-checkout-slot={isCustomized ? \"countryDropdown\" : undefined}\n className={cn(\n // The dropdown is portalled outside of the checkout root, so it only\n // joins the checkout theme boundary once the caller opts into an\n // appearance. Without it the content renders exactly as before.\n isCustomized ? \"bitsnap-react\" : \"\",\n boundaryClassName,\n \"w-full max-h-80 max-w-[350px] z-[999999]\",\n countryDropdown.className,\n )}\n style={{\n ...(isCustomized ? { ...boundaryStyle, ...dropdownStyle } : undefined),\n ...countryDropdown.style,\n }}\n position=\"popper\"\n >\n <div\n data-bitsnap-checkout-slot=\"countrySearch\"\n className={cn(\"sticky top-0 z-10 p-1 border-b\", countrySearch.className)}\n style={countrySearch.style}\n >\n <input\n type=\"search\"\n name=\"search\"\n autoComplete=\"off\"\n className=\"block w-full outline-none sm:text-body-regular bg-transparent rounded-md px-2 py-1.5\"\n placeholder={searchCountryText}\n aria-label={searchCountryText}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto\">\n {filteredCountries.length === 0 ? (\n <div className=\"cursor-default select-none relative py-2 pl-3 pr-9 text-sm\">\n {noCountriesFoundText}\n </div>\n ) : (\n filteredCountries.map((country) => (\n <SelectItem\n key={`${id}-${country.code}`}\n data-bitsnap-checkout-slot=\"countryOption\"\n value={country.code}\n className={cn(\n \"cursor-default select-none relative py-2 pl-3 pr-9 flex items-center transition\",\n countryOption.className,\n )}\n style={countryOption.style}\n >\n <img\n alt={country.code}\n src={`https://purecatamphetamine.github.io/country-flag-icons/3x2/${country.code}.svg`}\n className=\"inline mr-2 h-4 rounded-sm\"\n />\n <span className=\"font-normal truncate\">{country.name}</span>\n </SelectItem>\n ))\n )}\n </div>\n </SelectContent>\n </Select>\n );\n}\n\nexport default CountrySelector;\n","import * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\n/**\n * Colors owned by the shared shadcn theme. They live in Tailwind's\n * `utilities` layer, so plain CSS can never win against them. Components that\n * theme themselves through their own stylesheet (the checkout and its\n * `appearance` tokens) opt out with `theme=\"bare\"`, which keeps the colors the\n * checkout owns (`background-color`, `border-color`) and leaves the rest alone.\n * The default is unchanged.\n */\nconst selectTriggerThemeClasses =\n \"border-input dark:bg-input/30 dark:hover:bg-input/50 bg-transparent\"\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n theme = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\"\n theme?: \"default\" | \"bare\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex w-fit items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n theme === \"bare\" ? \"\" : selectTriggerThemeClasses,\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"popper\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type { SingleProduct } from \"./product.details.model\";\nimport { Button } from \"@/src/ui/button\";\nimport { MinusIcon, PlusIcon } from \"lucide-react\";\nimport { ButtonGroup } from \"@/src/ui/button-group\";\nimport { cn } from \"@/src/lib/utils\";\nimport { useCheckoutSlot } from \"./appearance.context\";\nimport { ProductPrice } from \"./ProductPrice\";\nimport { useCheckoutText } from \"./texts.context\";\nimport { clampQuantity, quantityFromInput } from \"./quantity\";\n\nconst SingleProduct = ({\n isNotAvailable,\n quantity,\n details,\n url,\n shouldUpdate,\n}: {\n isNotAvailable: boolean;\n quantity: number;\n metadata?: { [key: string]: string | undefined };\n /** Product page; the image and the name link to it. */\n url?: string;\n details: SingleProduct;\n /** Rejects when the cart could not be changed. */\n shouldUpdate: (newQuantity?: number) => Promise<unknown> | void;\n}) => {\n const product = useCheckoutSlot(\"product\");\n const productImage = useCheckoutSlot(\"productImage\");\n const productName = useCheckoutSlot(\"productName\");\n const productPrice = useCheckoutSlot(\"productPrice\");\n const removeButton = useCheckoutSlot(\"removeButton\");\n const removeText = useCheckoutText(\"remove\");\n\n const imageUrl = details.image_url ?? details.images?.[0];\n const [brokenImageUrl, setBrokenImageUrl] = useState<string | undefined>();\n const showImage =\n imageUrl != null && imageUrl.length > 0 && imageUrl !== brokenImageUrl;\n const name = details.baseName ?? details.name;\n\n return (\n <div\n data-bitsnap-checkout-slot=\"product\"\n data-bitsnap-checkout-unavailable={isNotAvailable ? \"\" : undefined}\n className={cn(\n \"flex items-center gap-3 mx-3\",\n isNotAvailable ? \"outline outline-1 rounded-md m-1\" : \"\",\n product.className,\n )}\n style={product.style}\n >\n {showImage && (\n <ProductLink\n url={url}\n // The name links to the same page; one link per item for keyboards.\n tabIndex={-1}\n aria-hidden=\"true\"\n className=\"contents\"\n >\n <img\n data-bitsnap-checkout-slot=\"productImage\"\n className={cn(\n \"aspect-auto max-w-[30%] max-w-32 max-h-32 py-2 overflow-hidden\",\n productImage.className,\n )}\n style={productImage.style}\n src={imageUrl}\n alt=\"\"\n onError={() => setBrokenImageUrl(imageUrl)}\n />\n </ProductLink>\n )}\n\n <div className={\"flex flex-col w-full\"}>\n <p\n data-bitsnap-checkout-slot=\"productName\"\n className={cn(\"font-medium\", productName.className)}\n style={productName.style}\n >\n <ProductLink\n url={url}\n className=\"text-inherit no-underline hover:underline\"\n >\n {name}\n </ProductLink>\n </p>\n {details.variantName != null && details.variantName.length > 0 && (\n <p className=\"text-sm opacity-70\">{details.variantName}</p>\n )}\n <p\n data-bitsnap-checkout-slot=\"productPrice\"\n className={cn(\"text-sm\", productPrice.className)}\n style={productPrice.style}\n suppressHydrationWarning\n >\n <ProductPrice\n price={details.price}\n currency={details.currency}\n pricing={details.pricing}\n quantity={quantity}\n />\n </p>\n <div className={\"flex justify-between\"}>\n <QuantityComponent\n className={\"\"}\n quantity={quantity}\n shouldUpdate={shouldUpdate}\n />\n <Button\n data-bitsnap-checkout-slot=\"removeButton\"\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={removeButton.className}\n style={removeButton.style}\n aria-label={`${removeText}: ${details.name}`}\n onClick={() => {\n Promise.resolve(shouldUpdate(0)).catch(() => undefined);\n }}\n >\n {removeText}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SingleProduct;\n\n/** The children as a link to the product page, or as they are without one. */\nconst ProductLink = ({\n url,\n children,\n ...props\n}: React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n url?: string;\n children: React.ReactNode;\n}) => {\n if (url == null) {\n return <>{children}</>;\n }\n return (\n <a href={url} {...props}>\n {children}\n </a>\n );\n};\n\nconst QuantityComponent = ({\n quantity,\n shouldUpdate,\n className,\n}: {\n quantity: number;\n shouldUpdate: (newQuantity: number) => Promise<unknown> | void;\n className: string;\n}) => {\n const [quantityString, setQuantityString] = useState(quantity.toString());\n // The last quantity sent, so quick clicks count from it before the cart reloads.\n const sent = useRef(quantity);\n\n const quantityControl = useCheckoutSlot(\"quantityControl\");\n const quantityInput = useCheckoutSlot(\"quantityInput\");\n const quantityButton = useCheckoutSlot(\"quantityButton\");\n const quantityText = useCheckoutText(\"quantity\");\n const increaseText = useCheckoutText(\"increaseQuantity\");\n const decreaseText = useCheckoutText(\"decreaseQuantity\");\n\n const shownQuantity = useRef(quantity);\n shownQuantity.current = quantity;\n\n // The cart is the source of truth once it has reloaded.\n useEffect(() => {\n sent.current = quantity;\n setQuantityString(quantity.toString());\n }, [quantity]);\n\n function commit(newQuantity: number) {\n setQuantityString(newQuantity.toString());\n if (newQuantity !== sent.current) {\n sent.current = newQuantity;\n Promise.resolve(shouldUpdate(newQuantity)).catch(() => {\n // The cart rejected it: show what the cart has.\n if (sent.current === newQuantity) {\n sent.current = shownQuantity.current;\n setQuantityString(shownQuantity.current.toString());\n }\n });\n }\n }\n\n return (\n <div\n data-bitsnap-checkout-slot=\"quantityControl\"\n className={cn(\"flex\", className, quantityControl.className)}\n style={quantityControl.style}\n >\n <ButtonGroup aria-label={quantityText}>\n <Button\n data-bitsnap-checkout-slot=\"quantityButton\"\n type=\"button\"\n className={quantityButton.className}\n style={quantityButton.style}\n aria-label={decreaseText}\n onClick={() => commit(clampQuantity(sent.current - 1))}\n >\n <MinusIcon aria-hidden=\"true\" />\n </Button>\n <input\n data-bitsnap-checkout-slot=\"quantityInput\"\n className={cn(\"w-8 bg-transparent text-center\", quantityInput.className)}\n style={quantityInput.style}\n value={quantityString}\n aria-label={quantityText}\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n onChange={(e) => setQuantityString(e.currentTarget.value)}\n onBlur={(e) => commit(quantityFromInput(e.currentTarget.value, sent.current))}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n commit(quantityFromInput(e.currentTarget.value, sent.current));\n }\n }}\n type=\"text\"\n />\n <Button\n data-bitsnap-checkout-slot=\"quantityButton\"\n type=\"button\"\n className={quantityButton.className}\n style={quantityButton.style}\n aria-label={increaseText}\n onClick={() => commit(clampQuantity(sent.current + 1))}\n >\n <PlusIcon aria-hidden=\"true\" />\n </Button>\n </ButtonGroup>\n </div>\n );\n};\n","import { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/src/lib/utils\";\nimport { Separator } from \"@/src/ui/separator\";\n\nconst buttonGroupVariants = cva(\n \"flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2\",\n {\n variants: {\n orientation: {\n horizontal:\n \"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\",\n vertical:\n \"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none\",\n },\n },\n defaultVariants: {\n orientation: \"horizontal\",\n },\n }\n);\n\nfunction ButtonGroup({\n className,\n orientation,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"button-group\"\n data-orientation={orientation}\n className={cn(buttonGroupVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupText({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot : \"div\";\n\n return (\n <Comp\n className={cn(\n \"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"button-group-separator\"\n orientation={orientation}\n className={cn(\n \"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n ButtonGroup,\n ButtonGroupSeparator,\n ButtonGroupText,\n buttonGroupVariants,\n};\n","import type { ProductPricing } from \"./product.details.model\";\nimport { formatCurrency } from \"./lib/round.number\";\nimport { useCheckoutText } from \"./texts.context\";\n\nexport function ProductPrice({\n price,\n currency,\n pricing,\n quantity = 1,\n}: {\n price: number;\n currency: string;\n pricing?: ProductPricing;\n quantity?: number;\n}) {\n const lowestPriceText = useCheckoutText(\"lowestPrice30Days\");\n const noPriceHistoryText = useCheckoutText(\"noPriceHistory\");\n const regular = pricing?.regularPrice ?? price;\n const effective = pricing?.effectivePrice ?? price;\n const onSale = pricing?.discount?.status === \"ACTIVE\" && effective < regular;\n\n return (\n <span>\n {onSale ? (\n <>\n <span className=\"mr-2 text-neutral-500 line-through\">\n {formatCurrency(regular * quantity, currency)}\n </span>\n <span className=\"font-semibold text-red-700\">\n {formatCurrency(effective * quantity, currency)}\n </span>\n <span className=\"mt-1 block text-xs text-neutral-600\">\n {pricing?.referencePrice.historyAvailable && pricing.referencePrice.amount != null\n ? `${lowestPriceText} ${formatCurrency(pricing.referencePrice.amount, currency)}`\n : noPriceHistoryText}\n </span>\n </>\n ) : (\n formatCurrency(effective * quantity, currency)\n )}\n </span>\n );\n}\n","export const MIN_QUANTITY = 1;\nexport const MAX_QUANTITY = 99;\n\n/** Keeps a quantity a whole number in 1..99. */\nexport function clampQuantity(value: number): number {\n if (!Number.isFinite(value)) {\n return MIN_QUANTITY;\n }\n return Math.min(MAX_QUANTITY, Math.max(MIN_QUANTITY, Math.trunc(value)));\n}\n\n/**\n * The quantity a typed value stands for. An empty or non-numeric value keeps\n * the `current` one; anything else is clamped to 1..99.\n */\nexport function quantityFromInput(raw: string, current: number): number {\n const parsed = parseInt(raw, 10);\n return Number.isNaN(parsed) ? current : clampQuantity(parsed);\n}\n","function Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={\"bg-neutral-700 animate-pulse rounded-md\" + ' ' + className}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n","import React from \"react\";\nimport { cn } from \"@/src/lib/utils\";\nimport { useCheckoutSlot } from \"./appearance.context\";\nimport {\n manualPaymentTitleKey,\n type PaymentMethod,\n type PaymentMethodChoice as Choice,\n} from \"./payment-method\";\nimport { useCheckoutTextResolver } from \"./texts.context\";\n\n/**\n * \"Pay online\", \"transfer / BLIK to the seller's phone\" or \"cash on delivery\",\n * shown above the checkout button when the shop offers two or more of them.\n * Native radios give the group semantics and the arrow-key navigation; the\n * whole card is the label.\n */\nexport function PaymentMethodChoice({\n choice,\n selected,\n onChange,\n disabled,\n}: {\n choice: Choice;\n selected: PaymentMethod;\n onChange: (method: PaymentMethod) => void;\n disabled?: boolean;\n}) {\n const text = useCheckoutTextResolver();\n const group = useCheckoutSlot(\"paymentMethods\");\n const option = useCheckoutSlot(\"paymentMethodOption\");\n const name = React.useId();\n const legendId = React.useId();\n\n const hasBlik =\n choice.manualAccountTypes.length === 0 ||\n choice.manualAccountTypes.includes(\"blik\");\n\n const options: Record<\n PaymentMethod,\n { title: string; description: string; note?: string }\n > = {\n online: {\n title: text(\"paymentMethodOnline\"),\n description: text(\"paymentMethodOnlineDescription\"),\n },\n manual: {\n title: text(manualPaymentTitleKey(choice.manualAccountTypes)),\n description: text(\"paymentMethodManualDescription\"),\n note: hasBlik ? text(\"paymentMethodManualBlikNote\") : undefined,\n },\n cod: {\n title: text(\"paymentMethodCod\"),\n description: text(\"paymentMethodCodDescription\"),\n },\n };\n\n return (\n <fieldset\n data-bitsnap-checkout-slot=\"paymentMethods\"\n aria-labelledby={legendId}\n className={cn(\"mx-2 mt-4 mb-2 flex min-w-0 flex-col gap-2 border-0 p-0\", group.className)}\n style={group.style}\n disabled={disabled}\n >\n <legend id={legendId} className=\"mb-1 px-1 text-sm font-medium\">\n {text(\"paymentMethodLegend\")}\n </legend>\n {choice.methods.map((method) => {\n const card = options[method];\n const isSelected = method === selected;\n const descriptionId = `${name}-${method}-description`;\n return (\n <label\n key={method}\n data-bitsnap-checkout-slot=\"paymentMethodOption\"\n data-payment-method={method}\n data-selected={isSelected ? \"\" : undefined}\n className={cn(\n \"flex cursor-pointer items-start gap-3 rounded-md border px-3 py-2.5 transition-colors\",\n option.className,\n )}\n style={option.style}\n >\n <input\n type=\"radio\"\n name={name}\n value={method}\n checked={isSelected}\n onChange={() => onChange(method)}\n aria-describedby={descriptionId}\n className=\"mt-0.5 size-4 shrink-0 cursor-pointer\"\n />\n <span className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"text-sm font-semibold leading-snug\">{card.title}</span>\n <span\n id={descriptionId}\n data-bitsnap-checkout-payment-method-description=\"\"\n className=\"text-xs leading-snug\"\n >\n {card.description}\n {isSelected && card.note != null && (\n <span className=\"mt-1 block font-medium\">{card.note}</span>\n )}\n </span>\n </span>\n </label>\n );\n })}\n </fieldset>\n );\n}\n","import GooglePayButton from \"@google-pay/button-react\";\nimport CartProvider, { useCartProvider } from \"./CartProvider\";\nimport { isErr } from \"./lib/err\";\nimport { currentProjectID } from \"./project-id\";\nimport { Spinner } from \"@/src/ui/spinner\";\nimport { useQuery, useMutation } from \"@tanstack/react-query\";\nimport { sendAnalyticEvent } from \"./frontent.analytics\";\nimport {\n InstrumentProvider,\n useInstrument,\n useInstrumentContext,\n type AnalyticsOption,\n} from \"@/src/analytics/instrument\";\n\nexport type Props = {\n test?: boolean;\n buttonSizeMode?: \"static\" | \"fill\";\n buttonColor?: \"white\" | \"black\";\n style?: {\n width?: string;\n };\n items: {\n name: string;\n id: string;\n price: number;\n quantity: number;\n isDeliverable?: boolean;\n metadata?: { [key: string]: string | undefined };\n }[];\n /**\n * Usage statistics for your Bitsnap dashboard. On by default; `false` turns\n * it off. Inside `<BitsnapCheckout>` the checkout's setting applies unless\n * this is given.\n */\n analytics?: AnalyticsOption;\n};\n\nfunction GooglePayButtonComponent({\n items,\n style,\n buttonColor,\n buttonSizeMode,\n test,\n}: Props) {\n const {\n getGooglePayConfiguration,\n completeGooglePayPayment,\n setCountry,\n setCouponCodeIfPossible,\n setDeliveryMethod,\n setEmail,\n setPostalCode,\n clearCart,\n } = useCartProvider();\n\n const instrument = useInstrumentContext();\n const { data: googlePayConfiguration } = useQuery({\n queryKey: [\n \"get-google-pay-configuration\",\n items.map((el) => el.id).join(\",\"),\n ],\n queryFn: () =>\n getGooglePayConfiguration({\n items: items.map((el) => ({\n ...el,\n id: undefined,\n productID: el.id,\n })),\n }),\n });\n\n const { mutateAsync: completeGooglePayPaymentAsync, isPending } = useMutation(\n {\n mutationFn: completeGooglePayPayment,\n }\n );\n if (\n googlePayConfiguration == null ||\n googlePayConfiguration.isAvailable != true\n ) {\n console.log(\n \"google pay configuration is not available\",\n googlePayConfiguration\n );\n return null;\n }\n\n return (\n <>\n <GooglePayButton\n buttonSizeMode={buttonSizeMode}\n buttonColor={buttonColor}\n style={style}\n existingPaymentMethodRequired={true}\n onClick={() =>\n instrument.track(\"payment_method_selected\", {\n gateway: \"google_pay\",\n method: \"google_pay\",\n })\n }\n environment={test === true ? \"TEST\" : \"PRODUCTION\"}\n onPaymentDataChanged={async (paymentData) => {\n sendAnalyticEvent({\n event: \"initiateCheckout\",\n items: items.map((el) => ({\n id: el.id,\n name: el.name,\n price: el.price,\n quantity: el.quantity,\n currency: \"PLN\",\n })),\n });\n console.log(\"payment data changed\", paymentData);\n if (paymentData.shippingAddress?.postalCode != null) {\n await setPostalCode(paymentData.shippingAddress?.postalCode);\n }\n if (paymentData.shippingAddress?.countryCode != null) {\n await setCountry(paymentData.shippingAddress?.countryCode);\n }\n if (paymentData.shippingOptionData?.id != null) {\n await setDeliveryMethod(paymentData.shippingOptionData.id);\n }\n\n const config = await getGooglePayConfiguration({ items: [] });\n console.log(\"PAYMENT DATA CHANGED CONFIG\", config);\n if (config.isAvailable) {\n return {\n error: undefined,\n newShippingOptionParameters:\n config.config.shippingOptionParameters,\n newTransactionInfo: config.config.transactionInfo,\n };\n }\n\n return {\n error: undefined,\n };\n }}\n paymentRequest={googlePayConfiguration.config}\n onLoadPaymentData={async (paymentRequest) => {\n instrument.track(\"payment_submitted\", {\n gateway: \"google_pay\",\n method: \"google_pay\",\n });\n try {\n const result = await completeGooglePayPaymentAsync({\n paymentData: paymentRequest,\n });\n if (isErr(result)) {\n console.log(\"apple pay error\", result);\n return;\n }\n\n result.isSuccess && clearCart();\n if (result.redirectURL) {\n open(result.redirectURL, \"_self\");\n }\n } catch (e) {\n console.warn(\"error completing google pay payment\", e);\n }\n }}\n />\n {isPending ? <Spinner /> : null}\n </>\n );\n}\n\nfunction Wrapper(props: Props) {\n const instrument = useInstrument(\n currentProjectID(),\n props.analytics,\n \"cart\",\n );\n return (\n <InstrumentProvider value={instrument}>\n <CartProvider>\n <GooglePayButtonComponent {...props} />\n </CartProvider>\n </InstrumentProvider>\n );\n}\n\nexport default Wrapper;\n","import { useReducer, useRef, useEffect, useState } from \"react\";\nimport { cn } from \"@/src/lib/utils\";\nimport {\n rpcProvider,\n RpcProvider,\n useMutation,\n useQuery,\n} from \"src/rpc-provider\";\nimport { useQuery as UQ, useQueryClient } from \"@tanstack/react-query\";\nimport { Settings, X } from \"lucide-react\";\nimport type {\n NotificationsComponentPublicProps,\n NotificationGroup,\n CustomizationTexts,\n ComponentClassNames,\n PublicNotificationGroup,\n} from \"./types\";\nexport type {\n NotificationGroup,\n CustomizationTexts,\n ComponentClassNames,\n} from \"./types\";\nexport type Props = NotificationsComponentPublicProps;\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport { NotificationHeader } from \"./NotificationHeader\";\nimport { NotificationGroupsList } from \"./NotificationGroupsList\";\nimport { QRCodeSection } from \"./QRCodeSection\";\nimport { AddUserToGroups } from \"./AddUserToGroups\";\nimport { ManageMyData } from \"./ManageMyData\";\nimport { LoginScreen } from \"./LoginScreen\";\nimport { useLoginBranding } from \"@/src/ui/email-code-login/LoginBrandLogo\";\nimport { Button } from \"@/src/ui/button\";\nimport { getProjectID } from \"../checkout/CartProvider\";\nimport { currentProjectID } from \"../checkout/project-id\";\nimport { useInstrument } from \"@/src/analytics/instrument\";\nimport { NotificationGroupHowOften } from \"@/src/gen/proto/common/v1/push_notifications_pb\";\nimport { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { Spinner } from \"@/src/ui/spinner\";\n\ninterface State {\n isLoading: boolean;\n isUserGroupsUpdated: boolean;\n wasChanged: boolean;\n groupsProvided?: PublicNotificationGroup[];\n groups: NotificationGroup[];\n showSettings: boolean;\n isLoggedIn: boolean;\n userID: string | undefined;\n}\n\ntype Action =\n | { type: \"SET_IS_LOGGED_IN\"; value: boolean }\n | { type: \"SET_USER_ID\"; value: string | undefined }\n | { type: \"SET_LOADING\"; value: boolean }\n | { type: \"TOGGLE_GROUP\"; groupID: string }\n | { type: \"CHECK_ALL_GROUPS\" }\n | { type: \"SET_WAS_CHANGED\"; value: boolean }\n | { type: \"SET_IS_USER_GROUPS_UPDATED\"; value: boolean }\n | { type: \"RESET_UPDATE_STATE\" }\n | { type: \"SHOW_SETTINGS\" }\n | { type: \"SET_GROUPS\"; value: NotificationGroup[] }\n | { type: \"SET_PUBLIC_GROUPS\"; value?: PublicNotificationGroup[] }\n | { type: \"HIDE_SETTINGS\" };\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case \"SET_IS_LOGGED_IN\": {\n return {\n ...state,\n isLoggedIn: action.value,\n };\n }\n case \"SET_USER_ID\": {\n return {\n ...state,\n userID: action.value,\n };\n }\n case \"SET_LOADING\": {\n return {\n ...state,\n isLoading: action.value,\n };\n }\n case \"SET_PUBLIC_GROUPS\": {\n return {\n ...state,\n groupsProvided: action.value,\n groups:\n action.value != null && action.value.length > 0\n ? state.groups.filter(\n (group) => action.value?.find((g) => g.id === group.id) != null,\n )\n : state.groups,\n };\n }\n case \"SET_GROUPS\": {\n const isDefaultOn =\n state.isLoggedIn == false || state.groupsProvided != null;\n const newGroupsWithIsOn = action.value.map((group) => {\n if (state.isLoggedIn == true) {\n return group;\n }\n return {\n ...group,\n isOn:\n state.groupsProvided?.find((g) => g.id === group.id)?.isOn ??\n isDefaultOn,\n };\n });\n\n return {\n ...state,\n groups: newGroupsWithIsOn,\n };\n }\n case \"TOGGLE_GROUP\": {\n const updatedGroups = state.groups.map((group) => {\n if (group.id === action.groupID) {\n return {\n ...group,\n isOn: !group.isOn,\n };\n }\n return group;\n });\n return {\n ...state,\n wasChanged: true,\n groups: updatedGroups,\n };\n }\n case \"CHECK_ALL_GROUPS\": {\n const updated = state.groups.map((group) => {\n return {\n ...group,\n isOn: true,\n };\n });\n return {\n ...state,\n groups: updated,\n wasChanged: true,\n };\n }\n case \"SET_WAS_CHANGED\":\n return {\n ...state,\n wasChanged: action.value,\n };\n case \"SET_IS_USER_GROUPS_UPDATED\":\n return {\n ...state,\n isUserGroupsUpdated: action.value,\n };\n case \"RESET_UPDATE_STATE\":\n return {\n ...state,\n wasChanged: false,\n isUserGroupsUpdated: true,\n };\n case \"SHOW_SETTINGS\":\n return {\n ...state,\n showSettings: true,\n };\n case \"HIDE_SETTINGS\":\n return {\n ...state,\n showSettings: false,\n };\n default:\n return state;\n }\n}\n\nfunction NotificationsComponentPublic({\n slug: slugProp,\n userID,\n productID,\n projectID,\n analytics,\n projectName,\n projectLogo,\n projectLogoDark,\n showLoginLogo,\n groups,\n isManaging = false,\n texts,\n showQRCode = false,\n showPhoneInput = false,\n hiddenGroupIds = [],\n className,\n}: NotificationsComponentPublicProps) {\n const [parent] = useAutoAnimate();\n const instrument = useInstrument(\n projectID ?? currentProjectID(),\n analytics,\n );\n let slug =\n slugProp ??\n getProjectID() ??\n (typeof window !== \"undefined\" ? window.location.hostname : \"\");\n\n // The login dialog shows the shop logo: read it now, so it is there when\n // the dialog opens (LoginBrandLogo reuses this query).\n useLoginBranding(\n slug.trim(),\n showLoginLogo !== false &&\n !projectLogo &&\n !projectLogoDark &&\n slug.trim() !== \"\",\n );\n\n const { mutateAsync: updateUserGroups, isPending: isUpdating } = useMutation(\n rpcProvider.notifications.updateUserGroups,\n );\n\n const { data: userInfo, refetch: refetchAccessToken } = UQ({\n queryKey: [\"notifications_accessToken\"],\n queryFn: () => {\n if (typeof window !== \"undefined\") {\n return {\n accessToken:\n localStorage.getItem(\"notifications_accessToken\") ?? undefined,\n userID: localStorage.getItem(\"notifications_userID\") ?? undefined,\n };\n }\n return undefined;\n },\n });\n\n const {\n data: groupsDownloaded,\n isPending: isGroupsDownloading,\n refetch: refetchGroups,\n } = useQuery(rpcProvider.notifications.getUserGroups, {\n slug: slug,\n accessToken: userInfo?.accessToken,\n });\n\n const [state, dispatch] = useReducer(reducer, {\n isLoading: isGroupsDownloading,\n isUserGroupsUpdated: false,\n wasChanged: false,\n groupsProvided: groups,\n groups: [],\n showSettings: userInfo != null && isManaging == true,\n isLoggedIn: userInfo != null,\n userID: undefined,\n });\n\n useEffect(() => {\n dispatch({ type: \"SET_LOADING\", value: isUpdating || isGroupsDownloading });\n }, [isUpdating, isGroupsDownloading]);\n\n useEffect(() => {\n dispatch({\n type: \"SET_IS_LOGGED_IN\",\n value: userInfo?.accessToken != null,\n });\n dispatch({ type: \"SET_USER_ID\", value: userInfo?.userID });\n if (userInfo?.accessToken != null && isManaging == true) {\n dispatch({ type: \"SHOW_SETTINGS\" });\n }\n }, [userInfo, isManaging]);\n\n useEffect(() => {\n if (groupsDownloaded == null) {\n return;\n }\n let newGroups = groupsDownloaded.groups.map((group) => {\n let howOften = \"rarely\";\n switch (group.howOften) {\n case NotificationGroupHowOften.RARELY:\n howOften = \"rarely\";\n break;\n case NotificationGroupHowOften.OFTEN:\n howOften = \"often\";\n break;\n case NotificationGroupHowOften.VERY_OFTEN:\n howOften = \"veryOften\";\n break;\n }\n return {\n id: group.id,\n name: group.name,\n description: group.description,\n howOften: howOften,\n isOn: group.isOn ?? undefined,\n };\n });\n dispatch({ type: \"SET_GROUPS\", value: newGroups });\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [groupsDownloaded, isGroupsDownloading, groups]);\n\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n let preparedGroups = groups?.map((el) => {\n if (el.id.startsWith(\"group_\")) {\n return el;\n }\n el.id = `group_${el.id}`;\n return el;\n });\n\n dispatch({ type: \"SET_PUBLIC_GROUPS\", value: preparedGroups });\n }, [groups]);\n\n const mergedTexts = { ...DEFAULT_TEXTS, ...texts };\n\n async function updateGroups() {\n await updateUserGroups({\n accessToken: userInfo?.accessToken,\n slug: slug,\n userId: userID,\n groupIds: state.groups\n .filter((el) => el.isOn === true)\n .map((el) => el.id),\n });\n dispatch({ type: \"RESET_UPDATE_STATE\" });\n\n // Clear existing timeout if any\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n // Set timeout to reset isUserGroupsUpdated after 2 seconds\n timeoutRef.current = setTimeout(() => {\n dispatch({ type: \"SET_IS_USER_GROUPS_UPDATED\", value: false });\n }, 2000);\n }\n\n function toggleGroup(groupID: string) {\n dispatch({ type: \"TOGGLE_GROUP\", groupID });\n }\n\n function checkAllGroups() {\n dispatch({ type: \"CHECK_ALL_GROUPS\" });\n }\n\n function handleSettingsClick() {\n dispatch({ type: \"SHOW_SETTINGS\" });\n }\n\n function handleCloseSettings() {\n dispatch({ type: \"HIDE_SETTINGS\" });\n }\n\n function handleLogout() {\n localStorage.removeItem(\"notifications_accessToken\");\n localStorage.removeItem(\"notifications_userID\");\n refetchAccessToken();\n dispatch({ type: \"SET_USER_ID\", value: undefined });\n dispatch({ type: \"SET_IS_LOGGED_IN\", value: false });\n dispatch({ type: \"HIDE_SETTINGS\" });\n }\n\n async function handleLoginSuccess(\n userID: string | undefined,\n accessToken: string,\n ) {\n if (typeof window !== \"undefined\") {\n localStorage.setItem(\"notifications_accessToken\", accessToken);\n if (userID != null) {\n localStorage.setItem(\"notifications_userID\", userID);\n }\n }\n dispatch({ type: \"SET_USER_ID\", value: userID });\n try {\n await refetchAccessToken();\n refetchGroups()\n .then()\n .catch()\n .finally(() => {\n if (isManaging == true) {\n // Automatically switch to managing view\n dispatch({ type: \"SHOW_SETTINGS\" });\n }\n });\n } catch (e) {\n console.log(`Error: ${e}`);\n }\n }\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n const isManagingEnabled =\n isManaging == true && state.userID != null && userInfo?.accessToken != null;\n\n return (\n <main className={cn(\"bitsnap-react relative\", className?.container)}>\n {mergedTexts.title != null && (\n <h1 className=\"text-2xl font-semibold text-black md:text-3xl lg:text-4xl xl:text-5xl dark:text-neutral-100\">\n {mergedTexts.title}\n </h1>\n )}\n\n {/* Floating Settings Icon */}\n {!state.showSettings && isManaging && (\n <Button\n onClick={handleSettingsClick}\n variant=\"outline\"\n size=\"icon\"\n className=\"absolute bottom-6 right-6 z-50 h-12 w-12 rounded-full shadow-lg hover:shadow-xl md:bottom-8 md:right-8\"\n aria-label=\"Settings\"\n >\n <Settings className=\"h-5 w-5\" />\n </Button>\n )}\n\n <div\n className={cn(\n \"md:pt8 relative z-0 mt-6 overflow-hidden rounded-2xl bg-white px-3 pt-6 pb-3 md:px-5 md:pb-5 dark:bg-neutral-800\",\n className?.header,\n )}\n >\n {state.showSettings ? (\n // Settings View\n <div className=\"space-y-6\">\n {state.isLoggedIn && (\n // Managing Groups View (logged in)\n <div\n className={cn(\n \"grid grid-cols-1 gap-3 lg:gap-6\",\n isManagingEnabled ? \"md:grid-cols-2\" : \"\",\n )}\n >\n <div className={className?.groupsContainer}>\n <NotificationHeader\n projectName={projectName}\n projectLogo={projectLogo}\n projectLogoDark={projectLogoDark}\n description={mergedTexts.managingDescription}\n className={className}\n onLogout={handleLogout}\n />\n {isGroupsDownloading && (\n <div className=\"flex justify-center items-center py-8\">\n <Spinner />\n </div>\n )}\n\n <NotificationGroupsList\n groups={state.groups}\n hiddenGroupIds={hiddenGroupIds}\n isManaging={isManaging}\n onToggle={toggleGroup}\n onCheckAll={checkAllGroups}\n onUpdate={updateGroups}\n isUpdating={isUpdating}\n wasChanged={state.wasChanged}\n isUserGroupsUpdated={state.isUserGroupsUpdated}\n className={className}\n texts={mergedTexts}\n />\n </div>\n {isManagingEnabled && (\n <ManageMyData\n accessToken={userInfo.accessToken ?? \"\"}\n slug={slug}\n userID={state.userID ?? \"\"}\n className={className}\n texts={mergedTexts}\n />\n )}\n\n {showQRCode != false && (\n <QRCodeSection\n showQRCode={showQRCode}\n isManaging={true}\n className={className}\n texts={mergedTexts}\n />\n )}\n </div>\n )}\n </div>\n ) : (\n // Default View (Form only)\n <div className={cn(\"grid grid-cols-1 gap-3 lg:gap-6\")}>\n <AddUserToGroups\n slug={slug}\n onToggle={(id) => {\n dispatch({ type: \"TOGGLE_GROUP\", groupID: id });\n }}\n onCheckAll={() => {\n dispatch({ type: \"CHECK_ALL_GROUPS\" });\n }}\n onSuccess={(userAlreadyExists, userID, accessToken) => {\n instrument.track(\n \"availability_signup\",\n {},\n { product_id: productID ?? null },\n );\n if (accessToken != null) {\n handleLoginSuccess(userID, accessToken);\n }\n if (userAlreadyExists) {\n dispatch({ type: \"SHOW_SETTINGS\" });\n }\n }}\n groups={state.groups}\n showPhoneInput={showPhoneInput}\n agreementText={mergedTexts.agreementText}\n className={className}\n texts={mergedTexts}\n wasChanged={state.wasChanged}\n isUpdating={isUpdating}\n />\n </div>\n )}\n </div>\n <LoginScreen\n isOpen={state.showSettings && !state.isLoggedIn}\n slug={slug}\n onSuccess={handleLoginSuccess}\n texts={mergedTexts}\n onClose={handleCloseSettings}\n projectName={projectName}\n projectLogo={projectLogo}\n projectLogoDark={projectLogoDark}\n showLogo={showLoginLogo}\n />\n </main>\n );\n}\n\nfunction Wrapper({\n slug,\n userID,\n productID,\n projectID,\n analytics,\n projectName,\n projectLogo,\n projectLogoDark,\n showLoginLogo,\n groups,\n isManaging,\n texts,\n showQRCode,\n showPhoneInput,\n hiddenGroupIds,\n className,\n}: Props) {\n return (\n <RpcProvider>\n <NotificationsComponentPublic\n slug={slug}\n userID={userID}\n productID={productID}\n projectID={projectID}\n analytics={analytics}\n projectName={projectName}\n projectLogo={projectLogo}\n projectLogoDark={projectLogoDark}\n showLoginLogo={showLoginLogo}\n groups={groups}\n isManaging={isManaging}\n texts={texts}\n showQRCode={showQRCode}\n showPhoneInput={showPhoneInput}\n hiddenGroupIds={hiddenGroupIds}\n className={className}\n />\n </RpcProvider>\n );\n}\nexport default Wrapper;\n","import { EMAIL_CODE_TEXT_TABLES } from \"@/src/ui/email-code-login/texts\";\nimport type { CustomizationTexts } from \"./types\";\n\nconst LOGIN = EMAIL_CODE_TEXT_TABLES.pl;\n\nexport const DEFAULT_TEXTS: Required<CustomizationTexts> = {\n title: null,\n description: null,\n managingDescription:\n \"Zarządzaj rodzajami powiadomień i sposobem dostarczania.\",\n formTitle: \"Podaj Email aby zapisać się do powiadomień\",\n formEmailLabel: \"Email\",\n formPhoneLabel: \"Numer telefonu\",\n formPhoneOptional: \"(opcjonalnie)\",\n formEmailPlaceholder: \"np. mail@gmail...\",\n formPhonePlaceholder: \"np. 663...\",\n formSubmitButton: \"Zapisz się\",\n formSuccessMessage: \"Zapisałeś się do powiadomień.\",\n agreementText: (\n <>\n <span style={{ color: \"red\" }}>*</span>\n Wyrażam zgodę na przetwarzanie moich danych w celach marketingowych\n zgodnie z{\" \"}\n <a\n href=\"/regulations/polityka-prywatnosci\"\n target=\"_blank\"\n className=\"cursor-alias font-bold hover:font-medium\"\n >\n regulaminem\n </a>{\" \"}\n <span className=\"text-xs font-light\">\n (zgodę można w każdej chwili wycofać)\n </span>\n </>\n ),\n qrCodeTitle: \"lub zainstaluj aplikację mobilną\",\n qrCodeSubtitle: \"Aplikacja mobilna\",\n qrCodeScanText: \"zeskanuj kod QR\",\n groupsNoSelectionWarning:\n \"Jeśli żadna z grup nie jest zaznaczona, nie otrzymasz żadnych powiadomień.\",\n groupsSelectAllButton: \"Zaznacz wszystkie\",\n groupsUpdateButton: \"Aktualizuj\",\n groupsUpdateSuccess: \"Zaktualizowano pomyślnie.\",\n groupsTitle: \"Zarządzaj grupami z których chcesz otrzymywać powiadomienia\",\n manageDataTitle: \"Ustawienia powiadomień\",\n manageDataDescription: \"W jaki sposób chcesz otrzymywać powiadomienia?\",\n manageDataUnsubscribeButton: \"Odsubskrybuj\",\n manageDataUpdatedMessage: \"Zaktualizowano\",\n manageDataUnsubscribeDescription:\n \"Wypisz mnie z wszystkich powiadomień i grup.\",\n loginEmailLabel: \"Email\",\n loginEmailPlaceholder: \"Wprowadź swój email\",\n loginSendCodeButton: \"Wyślij kod weryfikacyjny\",\n loginSendingButton: \"Wysyłanie...\",\n loginCodeLabel: \"Wprowadź kod weryfikacyjny\",\n loginCodeSentMessage: \"Wysłaliśmy kod weryfikacyjny na adres\",\n loginChangeEmailButton: \"Popraw email\",\n loginResendCodeButton: \"Wyślij kod ponownie\",\n loginInvalidEmailError: \"Wprowadź prawidłowy adres email\",\n loginSlugRequiredError: \"Wymagany jest identyfikator projektu\",\n loginInvalidCodeError: \"Nieprawidłowy kod weryfikacyjny\",\n loginVerificationFailedError:\n \"Weryfikacja nie powiodła się. Sprawdź swój kod.\",\n loginSendEmailError: \"Nie udało się wysłać kodu weryfikacyjnego\",\n loginVerifyCodeError: \"Nie udało się zweryfikować kodu\",\n loginResendEmailError: \"Nie udało się ponownie wysłać kodu weryfikacyjnego\",\n loginTitle: \"Wpisz email aby zarządzać powiadomieniami\",\n loginDescription: \"Dostaniesz kod weryfikacyjny na email.\",\n loginIHaveCode: \"Mam już kod\",\n loginVerifyButton: \"Potwierdź\",\n loginResendInText: LOGIN.resendIn,\n loginResentMessage: LOGIN.resent,\n loginExpiredError: LOGIN.expired,\n loginTooManyAttemptsError: LOGIN.tooManyAttempts,\n loginRateLimitedError: LOGIN.rateLimited,\n loginNetworkError: LOGIN.network,\n loginSpamHint: LOGIN.spamHint,\n loginValidityHint: LOGIN.validity,\n loginVerifyingButton: LOGIN.verifying,\n loginStepEmailHint: LOGIN.stepEmail,\n loginStepCodeHint: LOGIN.stepCode,\n loginAlreadySentMessage: LOGIN.alreadySent,\n loginEmailNotFoundError: LOGIN.emailNotFound,\n loginDeliveryUnavailableError: LOGIN.deliveryUnavailable,\n loginResendNewCodeButton: LOGIN.resendNew,\n loginNoCodeButton: LOGIN.noCode,\n loginCodeIncompleteError: LOGIN.codeIncomplete,\n};\n","import { cn } from \"@/src/lib/utils\";\nimport type { ComponentClassNames } from \"./types\";\nimport { Button } from \"@/src/ui/button\";\nimport { LogOutIcon } from \"lucide-react\";\n\ninterface NotificationHeaderProps {\n projectName?: string;\n projectLogo?: string;\n projectLogoDark?: string;\n description: string | null;\n className?: ComponentClassNames;\n onLogout?: () => void;\n}\n\nexport function NotificationHeader({\n projectName,\n projectLogo,\n projectLogoDark,\n description,\n className,\n onLogout,\n}: NotificationHeaderProps) {\n return (\n <>\n {projectLogo != null ||\n (projectName != null && (\n <h2\n className={cn(\n \"flex max-w-44 items-center gap-3 text-lg font-medium text-black sm:max-w-none md:text-xl lg:text-2xl xl:text-3xl dark:text-neutral-100\",\n className?.headerTitle\n )}\n >\n {projectLogo != null && (\n <>\n <img\n src={projectLogo}\n alt=\"\"\n className={cn(\n \"h-12 w-auto dark:hidden\",\n className?.headerLogo\n )}\n />\n <img\n src={projectLogoDark ?? projectLogo}\n alt=\"\"\n className={cn(\n \"hidden h-12 w-auto dark:inline\",\n className?.headerLogo\n )}\n />\n </>\n )}\n <span>{projectName}</span>\n </h2>\n ))}\n <div className=\"flex items-center gap-2\">\n {description && (\n <p\n className={cn(\n \"mt-4 font-medium text-left\",\n className?.headerDescription\n )}\n >\n {description}\n </p>\n )}\n <div className=\"grow\"></div>\n {onLogout && (\n <Button variant=\"ghost\" size=\"icon-sm\" onClick={onLogout}>\n <LogOutIcon className=\"h-5 w-5\" />\n </Button>\n )}\n </div>\n </>\n );\n}\n","import * as React from \"react\"\nimport * as SwitchPrimitive from \"@radix-ui/react-switch\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Switch({\n className,\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n \"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n \"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0\"\n )}\n />\n </SwitchPrimitive.Root>\n )\n}\n\nexport { Switch }\n","import { Switch } from \"@/src/ui/switch\";\nimport { cn } from \"@/src/lib/utils\";\nimport { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { CheckCircleIcon, TriangleAlertIcon } from \"lucide-react\";\nimport { Button } from \"@/src/ui/button\";\nimport { Spinner } from \"@/src/ui/spinner\";\nimport type {\n NotificationGroup,\n ComponentClassNames,\n CustomizationTexts,\n} from \"./types\";\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport { HowOftenComponent } from \"./HowOftenComponent\";\nimport { rpcProvider, useQuery } from \"@/src/rpc-provider\";\nimport { NotificationGroupHowOften } from \"@/src/gen/proto/common/v1/push_notifications_pb\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/src/ui/card\";\n\ninterface NotificationGroupsListProps {\n groups: NotificationGroup[];\n hiddenGroupIds?: string[];\n isManaging?: boolean;\n onToggle: (groupID: string) => void;\n onCheckAll: () => void;\n onUpdate?: () => void;\n isUpdating?: boolean;\n wasChanged?: boolean;\n isUserGroupsUpdated?: boolean;\n className?: ComponentClassNames;\n texts?: CustomizationTexts;\n}\n\nexport function NotificationGroupsList({\n groups = [],\n isManaging,\n onToggle,\n onCheckAll,\n onUpdate,\n isUpdating,\n wasChanged,\n isUserGroupsUpdated,\n className,\n texts,\n}: NotificationGroupsListProps) {\n const [groupsParent] = useAutoAnimate();\n const [updateGroupsParent] = useAutoAnimate();\n\n const hasNoSelection =\n groups.filter((group) => group.isOn === false).length > 0;\n const hasUnchecked =\n groups.filter((group) => group.isOn === false).length > 0;\n\n if (groups.length <= 1 && isManaging != true) {\n return null;\n }\n\n const content = (\n <div\n ref={groupsParent}\n className={cn(\"my-5 flex flex-col gap-3\", className?.groupsList)}\n >\n {groups.map((group) => (\n <div\n id={group.id}\n role=\"button\"\n key={group.id}\n className={cn(\n group.isOn\n ? \"bg-neutral-50 hover:bg-transparent shadow-sm border-transparent dark:bg-neutral-800\"\n : \"border-neutral-200 hover:bg-neutral-50 dark:hover:border-neutral-800 shadow-sm dark:border-neutral-800\",\n \"active:bg-beige-300 flex w-full cursor-pointer items-center gap-3 rounded-xl border px-3 py-2 transition active:dark:bg-neutral-900\",\n className?.groupItem\n )}\n onClick={(e) => {\n if (e.target instanceof HTMLButtonElement) {\n return;\n }\n onToggle(group.id);\n }}\n >\n <Switch\n checked={group.isOn}\n className=\"data-[state=checked]:bg-blue-500 dark:data-[state=unchecked]:bg-neutral-700\"\n onCheckedChange={() => {\n onToggle(group.id);\n }}\n />\n <div className=\"flex flex-col items-start justify-start\">\n <p className=\"font-medium text-sm\">{group.name}</p>\n {group.description && (\n <p className=\"text-xs font-light\">{group.description}</p>\n )}\n </div>\n <div className=\"grow\"></div>\n {group.howOften && <HowOftenComponent regularity={group.howOften} />}\n </div>\n ))}\n <div className=\"flex gap-2\">\n {isManaging === true && (\n <>\n <div\n ref={updateGroupsParent}\n className=\"flex flex-col items-start justify-start\"\n >\n {wasChanged && (\n <Button\n variant=\"default\"\n size=\"sm\"\n className=\"relative\"\n disabled={isUpdating}\n onClick={onUpdate}\n >\n {texts?.groupsUpdateButton ??\n DEFAULT_TEXTS.groupsUpdateButton}\n {isUpdating && (\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n <Spinner />\n </div>\n )}\n </Button>\n )}\n {isUserGroupsUpdated && (\n <p className=\"mt-3 flex items-center gap-2 text-sm text-green-500\">\n <CheckCircleIcon color=\"var(--color-green-500\" size={16} />{\" \"}\n {texts?.groupsUpdateSuccess ??\n DEFAULT_TEXTS.groupsUpdateSuccess}\n </p>\n )}\n </div>\n <div className=\"grow\"></div>\n </>\n )}\n {hasUnchecked && (\n <div className=\"flex justify-start\">\n <Button\n className=\"cursor-pointer dark:bg-neutral-700\"\n onClick={onCheckAll}\n size=\"sm\"\n variant=\"secondary\"\n type=\"button\"\n >\n {texts?.groupsSelectAllButton ??\n DEFAULT_TEXTS.groupsSelectAllButton}\n </Button>\n </div>\n )}\n </div>\n {hasNoSelection && (\n <div className=\"flex text-left gap-2 text-xs text-yellow-500\">\n <TriangleAlertIcon color=\"orange\" size={16} />\n {texts?.groupsNoSelectionWarning ??\n DEFAULT_TEXTS.groupsNoSelectionWarning}\n </div>\n )}\n </div>\n );\n\n if (isManaging == true) {\n return (\n <Card className=\"mt-5 text-left\">\n <CardHeader>\n <CardTitle>\n {texts?.groupsTitle ?? DEFAULT_TEXTS.groupsTitle}\n </CardTitle>\n </CardHeader>\n <CardContent>{content}</CardContent>\n </Card>\n );\n }\n\n return content;\n}\n","import * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverAnchor({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n","import { Popover, PopoverContent, PopoverTrigger } from \"@/src/ui/popover\";\nimport { ClockIcon } from \"lucide-react\";\n\nexport function HowOftenComponent({ regularity }: { regularity: string }) {\n let text = \"\";\n switch (regularity) {\n case \"rarely\":\n text = \"rzadko\";\n break;\n case \"often\":\n text = \"często\";\n break;\n case \"very_often\":\n text = \"codzienne\";\n break;\n }\n\n return (\n <Popover>\n <PopoverTrigger\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n <button\n type=\"button\"\n className=\"flex w-[30%] cursor-help flex-col items-center justify-center text-xs md:w-[25%] xl:w-[20%]\"\n >\n <ClockIcon size={12} />\n <span>{text}</span>\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"w-80\">\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <h4 className=\"leading-none font-medium\">Co to oznacza?</h4>\n <ul className=\"list-inside list-disc text-sm\">\n <li>\n <span className=\"font-semibold\">Rzadko</span> – powiadomienia\n będą wysyłane maksymalnie kilka razy w miesiącu.\n </li>\n <li>\n <span className=\"font-semibold\">Często</span> – powiadomienia\n mogę być wysyłane kilka razy w tygodniu.\n </li>\n <li>\n <span className=\"font-semibold\">Codzienne</span> – powiadomienia\n będą wysyłane nawet codziennie.\n </li>\n </ul>\n </div>\n <div className=\"grid gap-2\"></div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n","import { cn } from \"@/src/lib/utils\";\nimport type { ComponentClassNames, CustomizationTexts } from \"./types\";\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport { HOST } from \"../checkout/constants\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/src/ui/card\";\n\ninterface QRCodeSectionProps {\n showQRCode?: boolean;\n isManaging?: boolean;\n className?: ComponentClassNames;\n texts?: CustomizationTexts;\n}\n\nexport function QRCodeSection({\n showQRCode = true,\n isManaging: _isManaging,\n className,\n texts,\n}: QRCodeSectionProps) {\n const isBrowser = typeof window !== \"undefined\";\n const darkMode = isBrowser\n ? window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ? true\n : false\n : false;\n\n function getURL(isBrowser: boolean) {\n if (isBrowser) {\n return window.location.href;\n }\n return \"\";\n }\n\n if (!showQRCode) {\n return null;\n }\n\n return (\n <Card\n className={cn(\n \"bg-beige-100 rounded-xl p-4 dark:bg-neutral-700\",\n className?.qrCodeSection\n )}\n >\n <CardHeader>\n <CardTitle\n className={cn(\n \"mb-3 text-base font-medium lg:text-lg\",\n className?.qrCodeTitle\n )}\n >\n {texts?.qrCodeSubtitle ?? DEFAULT_TEXTS.qrCodeSubtitle}\n {\" \" + (texts?.qrCodeTitle ?? DEFAULT_TEXTS.qrCodeTitle)}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-col items-center gap-2\">\n <div className=\"mt-1.5 mb-3 flex items-center gap-x-2\">\n <a\n href=\"https://apps.apple.com/us/app/bitsnap/id6741902807\"\n target=\"_blank\"\n className=\"max-w-28 flex-1 basis-1/2 lg:max-w-36\"\n >\n <img\n className=\"h-auto w-full\"\n src={HOST + \"/app-store-logo.png\"}\n alt=\"Download on App Store\"\n />\n </a>\n <a\n href=\"https://play.google.com/store/apps/details?id=com.bitsnap.Bitsnap&pli=1\"\n target=\"_blank\"\n className=\"max-w-28 flex-1 basis-1/2 lg:max-w-36\"\n >\n <img\n className=\"h-auto w-full\"\n src={HOST + \"/google-play-logo.png\"}\n alt=\"Get in on Google Play\"\n />\n </a>\n </div>\n {isBrowser && (\n <div className=\"flex items-center justify-center\">\n <div\n className={cn(\n \"flex min-w-[40%] flex-col items-center gap-2 rounded-xl bg-white p-2 dark:bg-neutral-900\",\n className?.qrCodeContainer\n )}\n >\n <img\n className=\"mt-3 w-[80%] p-1 pt-3\"\n src={\n HOST +\n `/api/qr-gen?url=${getURL(isBrowser)}&bgColor=${\n !darkMode ? \"F6F4F0\" : \"171717\"\n }&textColor=${!darkMode ? \"000000\" : \"ffffff\"}&margin=0`\n }\n />\n <p className=\"text-xs md:text-sm\">\n {texts?.qrCodeScanText ?? DEFAULT_TEXTS.qrCodeScanText}\n </p>\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","import { useState } from \"react\";\nimport { isValidPhoneNumber } from \"react-phone-number-input\";\nimport { cn } from \"@/src/lib/utils\";\nimport { rpcProvider, useMutation } from \"src/rpc-provider\";\nimport { FailureMessage } from \"@/src/gen/proto/dashboard/v1/notifications_pb\";\nimport type {\n ComponentClassNames,\n CustomizationTexts,\n NotificationGroup,\n} from \"./types\";\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport { FormInput } from \"./FormInput\";\nimport type { ReactNode } from \"react\";\nimport { NotificationGroupsList } from \"./NotificationGroupsList\";\n\nconst emailRegex =\n /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n\ninterface AddUserToGroupsProps {\n slug: string;\n groups: NotificationGroup[];\n isUpdating?: boolean;\n wasChanged?: boolean;\n onToggle?: (id: string) => void;\n onCheckAll?: () => void;\n showPhoneInput?: boolean;\n agreementText?: string | ReactNode;\n className?: ComponentClassNames;\n texts?: CustomizationTexts;\n onSuccess?: (\n userAlreadyExists: boolean,\n userID: string | undefined,\n accessToken: string | undefined\n ) => void;\n}\n\nexport function AddUserToGroups({\n groups,\n onToggle,\n onCheckAll,\n slug,\n showPhoneInput = false,\n agreementText,\n className,\n texts,\n isUpdating,\n wasChanged,\n onSuccess,\n}: AddUserToGroupsProps) {\n const [errMsg, setErrMsg] = useState(\"\");\n const [warnMsg, setWarnMsg] = useState(\"\");\n const [isSubmited, setIsSubmited] = useState(false);\n const [agreementLack, setAgreementLack] = useState(false);\n const [emailLack, setEmailLack] = useState(false);\n const {\n mutateAsync: createNotificationUserMutation,\n isPending: isCreateNotificationUserPending,\n } = useMutation(rpcProvider.notifications.createNotificationUser);\n\n function validatePhoneNumber(phone: string): boolean {\n if (phone == null) {\n return false;\n }\n return isValidPhoneNumber(phone, \"PL\");\n }\n\n async function save(email: string, phone: string, agreement: boolean) {\n setErrMsg(\"\");\n setWarnMsg(\"\");\n setEmailLack(false);\n setIsSubmited(false);\n setAgreementLack(false);\n\n if (!agreement) {\n setAgreementLack(true);\n const msg = \"Zgoda w tym przypadku jest wymagana.\";\n setErrMsg(msg);\n return;\n }\n\n if (emailRegex.test(email) === false) {\n setErrMsg(\"Email jest nieprawidłowy.\");\n setEmailLack(true);\n return;\n }\n\n if (phone.length > 0) {\n if (validatePhoneNumber(phone) === false) {\n const msg =\n \"Numer telefonu może być nieprawidłowy. Zapisaliśmy go ale jeśli jest nieprawidłowy to wpisz jeszcze raz i kliknij przycisk.\";\n setWarnMsg(msg);\n }\n }\n\n try {\n const newNotificationUser = await createNotificationUserMutation({\n slug: slug,\n email: email,\n phone: phone,\n groups: groups.filter((el) => el.isOn == true).map((el) => el.id),\n mobileNotificationEnabled: true,\n emailNotificationEnabled: true,\n smsNotificationEnabled: true,\n });\n\n if (newNotificationUser.result.case === \"success\") {\n setIsSubmited(true);\n setTimeout(() => {\n onSuccess?.(\n false,\n newNotificationUser.userId,\n newNotificationUser.accessToken\n );\n }, 1000);\n return;\n } else {\n setIsSubmited(true);\n const failureMessage = newNotificationUser.result.value;\n\n if (failureMessage != null) {\n if (\n failureMessage == FailureMessage.NOTIFICATION_USER_ALREADY_EXIST\n ) {\n onSuccess?.(true, undefined, undefined);\n return;\n }\n console.log(`Code error: ${FailureMessage[failureMessage]}`);\n setErrMsg(\"Wystąpił błąd: \" + FailureMessage[failureMessage]);\n return;\n }\n\n return;\n }\n } catch (e) {\n setErrMsg(\"Wystąpił błąd podczas zapisywania. Spróbuj ponownie.\");\n console.log(`Error: ${e}`);\n }\n }\n\n const text = texts?.formTitle ?? DEFAULT_TEXTS.formTitle;\n\n return (\n <div\n className={cn(\n \"bg-beige-100 rounded-xl p-4 dark:bg-neutral-700\",\n className?.formSection\n )}\n >\n {text.length > 0 && (\n <h3\n className={cn(\n \"mb-3 text-base font-medium lg:text-lg\",\n className?.formTitle\n )}\n >\n {text}\n </h3>\n )}\n\n <NotificationGroupsList\n groups={groups}\n isManaging={false}\n onToggle={onToggle ?? (() => {})}\n onCheckAll={onCheckAll ?? (() => {})}\n isUpdating={isUpdating ?? false}\n wasChanged={wasChanged ?? false}\n isUserGroupsUpdated={false}\n className={className}\n texts={texts}\n />\n\n <FormInput\n errMsg={errMsg}\n emailLack={emailLack}\n warnMsg={warnMsg}\n submit={save}\n isLoading={isCreateNotificationUserPending}\n isSubmited={isSubmited}\n agreementLack={agreementLack}\n showPhoneInput={showPhoneInput}\n agreementText={\n agreementText ?? texts?.agreementText ?? DEFAULT_TEXTS.agreementText\n }\n className={className}\n texts={texts}\n />\n </div>\n );\n}\n","import { Input } from \"@/src/ui/input\";\nimport { cn } from \"@/src/lib/utils\";\nimport { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { Label } from \"@radix-ui/react-label\";\nimport {\n CheckCircleIcon,\n CircleAlertIcon,\n TriangleAlertIcon,\n} from \"lucide-react\";\nimport { useState, type FormEvent } from \"react\";\nimport { Button } from \"@/src/ui/button\";\nimport { Spinner } from \"@/src/ui/spinner\";\nimport type { ComponentClassNames, CustomizationTexts } from \"./types\";\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport type { ReactNode } from \"react\";\n\ninterface FormInputProps {\n isLoading: boolean;\n submit: (email: string, phone: string, agreement: boolean) => void;\n errMsg: string;\n agreementLack?: boolean;\n emailLack?: boolean;\n warnMsg: string;\n isSubmited: boolean;\n showPhoneInput?: boolean;\n agreementText?: string | ReactNode;\n className?: ComponentClassNames;\n texts?: CustomizationTexts;\n}\n\nexport function FormInput({\n submit,\n isLoading,\n errMsg,\n emailLack,\n warnMsg,\n isSubmited,\n agreementLack,\n showPhoneInput = false,\n agreementText,\n className,\n texts,\n}: FormInputProps) {\n const [email, setEmail] = useState(\"\");\n const [phone, setPhone] = useState(\"\");\n const [isChecked, setIsChecked] = useState(false);\n\n const [parent] = useAutoAnimate();\n\n function submitForm(e: FormEvent) {\n e.preventDefault();\n submit(email, phone, isChecked);\n }\n\n return (\n <form\n ref={parent}\n onSubmit={submitForm}\n className={cn(\"flex flex-col gap-3 text-left\", className?.formContainer)}\n >\n <div className=\"flex flex-col gap-1 text-left\">\n <Label className=\"text-sm\" htmlFor=\"bts-notifications-form-email\">\n {texts?.formEmailLabel ?? DEFAULT_TEXTS.formEmailLabel}\n </Label>\n <Input\n value={email}\n onChange={(newVal) => {\n setEmail(newVal.currentTarget.value);\n }}\n id=\"bts-notifications-form-email\"\n className={cn(emailLack === true ? \"border-red-400\" : \"\")}\n type=\"email\"\n placeholder={\n texts?.formEmailPlaceholder ?? DEFAULT_TEXTS.formEmailPlaceholder\n }\n />\n </div>\n\n {showPhoneInput && (\n <div className=\"flex flex-col gap-1 text-left\">\n <Label className=\"text-sm\" htmlFor=\"bts-notifications-form-phone\">\n {texts?.formPhoneLabel ?? DEFAULT_TEXTS.formPhoneLabel}{\" \"}\n <span className=\"text-neutral-500 dark:text-neutral-500\">\n {texts?.formPhoneOptional ?? DEFAULT_TEXTS.formPhoneOptional}\n </span>\n </Label>\n <Input\n value={phone}\n onChange={(newVal) => {\n setPhone(newVal.currentTarget.value);\n }}\n id=\"bts-notifications-form-phone\"\n className=\"\"\n type=\"tel\"\n autoComplete=\"tel\"\n autoCorrect=\"off\"\n placeholder={\n texts?.formPhonePlaceholder ?? DEFAULT_TEXTS.formPhonePlaceholder\n }\n />\n </div>\n )}\n <div className=\"flex items-start gap-x-1.5\">\n <input\n className=\"cursor-pointer\"\n id=\"bts-notifications-form-marketing-consent\"\n type=\"checkbox\"\n checked={isChecked}\n onChange={() => {\n setIsChecked(!isChecked);\n }}\n />\n <label\n htmlFor=\"bts-notifications-form-marketing-consent\"\n className={cn(\n \"cursor-pointer text-xs leading-4 transition-colors md:text-sm md:leading-4\",\n agreementLack === true ? \"text-yellow-700\" : \"\"\n )}\n >\n {agreementText}\n </label>\n </div>\n {errMsg.length > 0 && (\n <p className=\"mb-3 flex items-center gap-1 text-sm text-red-400\">\n <TriangleAlertIcon color=\"#ff6467\" size={16} /> {errMsg}\n </p>\n )}\n {warnMsg.length > 0 && (\n <p className=\"mb-3 flex items-center gap-1 text-sm text-amber-400\">\n <CircleAlertIcon color=\"var(--color-amber-400)\" size={16} /> {warnMsg}\n </p>\n )}\n {isSubmited == false && (\n <div className=\"flex justify-start\">\n <Button\n variant=\"default\"\n disabled={isLoading}\n className={cn(\n isLoading ? \"cursor-not-allowed text-transparent\" : \"\",\n \"relative\"\n )}\n >\n {texts?.formSubmitButton ?? DEFAULT_TEXTS.formSubmitButton}\n {isLoading && (\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n <Spinner />\n </div>\n )}\n </Button>\n </div>\n )}\n {isSubmited && (\n <div className=\"flex items-center gap-3 text-sm text-green-400\">\n <CheckCircleIcon size={16} />{\" \"}\n {texts?.formSuccessMessage ?? DEFAULT_TEXTS.formSuccessMessage}\n </div>\n )}\n </form>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { Skeleton } from \"@/src/ui/skeleton\";\nimport { Switch } from \"@/src/ui/switch\";\nimport { cn } from \"@/src/lib/utils\";\nimport { Label } from \"@radix-ui/react-label\";\nimport { MessageCircleWarningIcon } from \"lucide-react\";\nimport { rpcProvider, useMutation, useQuery } from \"src/rpc-provider\";\nimport { useDebouncedCallback } from \"use-debounce\";\nimport { UnsubscribeDialog } from \"./UnsubscribeDialog\";\nimport { Button } from \"@/src/ui/button\";\nimport { Spinner } from \"@/src/ui/spinner\";\nimport type { ComponentClassNames, CustomizationTexts } from \"./types\";\nimport { DEFAULT_TEXTS } from \"./constants\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/src/ui/card\";\nimport { useAutoAnimate } from \"@formkit/auto-animate/react\";\n\ninterface ManageMyDataProps {\n accessToken: string;\n slug: string;\n userID: string;\n className?: ComponentClassNames;\n texts?: CustomizationTexts;\n}\n\nexport function ManageMyData({\n accessToken,\n slug,\n userID,\n className,\n texts,\n}: ManageMyDataProps) {\n const [parent] = useAutoAnimate();\n const [parentCard] = useAutoAnimate();\n const { mutateAsync: deleteMyData, isPending: isDeleting } = useMutation(\n rpcProvider.notifications.deleteNotificationUser\n );\n const { mutateAsync: updateNotificationUser, isPending: isUpdating } =\n useMutation(rpcProvider.notifications.updateNotificationUser);\n\n const { data: userSettings, isFetching: isLoading } = useQuery(\n rpcProvider.notifications.getNotificationUserSettings,\n {\n userId: userID,\n slug: slug,\n accessToken: accessToken,\n }\n );\n\n const [email, setEmail] = useState(false);\n const [phone, setPhone] = useState(false);\n const [isDataUpdated, setIsDataUpdated] = useState(false);\n const [push, setPush] = useState(false);\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n\n const details =\n userSettings?.result.case === \"success\"\n ? userSettings?.result?.value\n : undefined;\n\n function deleteData() {\n setIsDialogOpen(true);\n }\n\n async function handleConfirmDelete() {\n await deleteMyData({\n accessToken: accessToken,\n slug: slug,\n userId: userID,\n });\n setIsDialogOpen(false);\n }\n\n async function updateData() {\n await updateNotificationUser({\n accessToken: accessToken,\n slug: slug,\n notificationUserId: userID,\n mobileNotificationEnabled: push,\n emailNotificationEnabled: email,\n smsNotificationEnabled: phone,\n });\n setIsDataUpdated(true);\n setTimeout(() => {\n setIsDataUpdated(false);\n }, 3000);\n }\n const debouncedUpdateData = useDebouncedCallback((_: boolean) => {\n updateData();\n }, 300);\n\n useEffect(() => {\n const details =\n userSettings?.result.case === \"success\"\n ? userSettings?.result?.value\n : undefined;\n\n setEmail(details?.emailNotificationEnabled ?? false);\n setPhone(details?.smsNotificationEnabled ?? false);\n setPush(details?.mobileNotificationEnabled ?? false);\n }, [userSettings]);\n\n function setData(key: \"email\" | \"phone\" | \"push\", value: boolean) {\n if (key === \"email\") {\n setEmail(value);\n }\n if (key === \"phone\") {\n setPhone(value);\n }\n if (key === \"push\") {\n setPush(value);\n }\n debouncedUpdateData(true);\n }\n\n return (\n <div\n className={cn(\n \"bg-beige-100 rounded-xl p-4 dark:bg-neutral-700\",\n className?.manageDataSection\n )}\n >\n <div className=\"flex justify-start\">\n <h3\n className={cn(\n \"mb-3 text-base font-medium lg:text-lg\",\n className?.manageDataTitle\n )}\n >\n {texts?.manageDataTitle ?? DEFAULT_TEXTS.manageDataTitle}\n </h3>\n </div>\n\n {isLoading ? (\n <Skeleton className=\"h-64 w-full\" />\n ) : (\n <Card ref={parentCard} className={cn(isUpdating && \"relative\")}>\n <CardHeader>\n <CardTitle>\n <p className=\"text-sm text-left\">\n {texts?.manageDataDescription ??\n DEFAULT_TEXTS.manageDataDescription}\n </p>\n </CardTitle>\n </CardHeader>\n <CardContent ref={parent}>\n <div\n className={cn(\n isUpdating && \"opacity-50 pointer-events-none\",\n \"flex flex-col gap-2\"\n )}\n >\n <div className=\"flex flex-col items-start gap-5 gap-x-2\">\n {details?.emailNotificationAvailable && (\n <div className=\"flex items-center gap-3\">\n <Switch\n id=\"email-enabled\"\n className=\"data-[state=checked]:bg-blue-500 dark:data-[state=unchecked]:bg-neutral-600\"\n checked={email}\n onCheckedChange={() => {\n setData(\"email\", !email);\n }}\n />\n <Label htmlFor=\"email-enabled\" className=\"text-sm\">\n Email\n </Label>\n </div>\n )}\n {details?.smsNotificationAvailable && (\n <div className=\"flex items-center gap-3\">\n <Switch\n id=\"sms-enabled\"\n className=\"data-[state=checked]:bg-blue-500 dark:data-[state=unchecked]:bg-neutral-600\"\n checked={phone}\n onCheckedChange={() => {\n setData(\"phone\", !phone);\n }}\n />\n <Label htmlFor=\"sms-enabled\" className=\"text-sm\">\n SMS\n </Label>\n </div>\n )}\n {details?.mobileNotificationAvailable && (\n <>\n <div className=\"flex items-center gap-3\">\n <Switch\n id=\"push-enabled\"\n className=\"data-[state=checked]:bg-blue-500 dark:data-[state=unchecked]:bg-neutral-600\"\n checked={push}\n onCheckedChange={() => {\n setData(\"push\", !push);\n }}\n />\n <Label htmlFor=\"push-enabled\" className=\"text-sm\">\n Powiadomienia na telefon\n </Label>\n </div>\n {details?.hasUserInstalledApp === false && (\n <div className=\"flex items-center gap-3\">\n <MessageCircleWarningIcon\n color=\"var(--color-amber-500)\"\n size={26}\n />\n <p className=\"text-xs text-amber-500\">\n Wygląda na to, że nie masz zainstalowanej aplikacji\n mobilnej. Zainstaluj i wyraź zgodę na otrzymywanie\n powiadomień na telefon.\n </p>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n\n <div className=\"mt-5 flex flex-col gap-2 text-left\">\n <hr />\n {isDataUpdated && (\n <p className=\"text-xs text-green-500\">\n {texts?.manageDataUpdatedMessage ??\n DEFAULT_TEXTS.manageDataUpdatedMessage}\n </p>\n )}\n <div className=\"flex items-center gap-x-2\">\n <Button\n size=\"sm\"\n variant=\"link\"\n className={cn(\n \"pl-0 ml-0\",\n isDeleting && \"cursor-not-allowed\"\n )}\n onClick={deleteData}\n >\n {texts?.manageDataUnsubscribeButton ??\n DEFAULT_TEXTS.manageDataUnsubscribeButton}\n {isDeleting && (\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n <Spinner />\n </div>\n )}\n </Button>\n </div>\n </div>\n </CardContent>\n {isUpdating && (\n <div className=\"bg-black/30 absolute inset-0 rounded-xl\">\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n <Spinner />\n </div>\n </div>\n )}\n </Card>\n )}\n <UnsubscribeDialog\n open={isDialogOpen}\n onOpenChange={setIsDialogOpen}\n onConfirm={handleConfirmDelete}\n isDeleting={isDeleting}\n />\n </div>\n );\n}\n","import { cn } from \"../../lib/utils\";\nimport { TriangleAlertIcon, XIcon } from \"lucide-react\";\nimport { createPortal } from \"react-dom\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"@/src/ui/button\";\n\ninterface UnsubscribeDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onConfirm: () => void;\n isDeleting?: boolean;\n}\n\nexport function UnsubscribeDialog({\n open,\n onOpenChange,\n onConfirm,\n isDeleting = false,\n}: UnsubscribeDialogProps) {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n useEffect(() => {\n if (open) {\n document.body.style.overflow = \"hidden\";\n } else {\n document.body.style.overflow = \"\";\n }\n return () => {\n document.body.style.overflow = \"\";\n };\n }, [open]);\n\n if (!mounted || !open) {\n return null;\n }\n\n const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) {\n onOpenChange(false);\n }\n };\n\n const handleConfirm = () => {\n onConfirm();\n };\n\n return createPortal(\n <div\n className=\"fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 p-4\"\n onClick={handleBackdropClick}\n >\n <div\n className={cn(\n \"relative w-full max-w-md rounded-2xl bg-white p-6 shadow-lg\",\n \"dark:bg-neutral-800\",\n \"animate-in fade-in-0 zoom-in-95 duration-200\"\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <button\n onClick={() => onOpenChange(false)}\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none dark:ring-offset-neutral-950 dark:focus:ring-neutral-300\"\n disabled={isDeleting}\n >\n <XIcon className=\"h-4 w-4\" />\n <span className=\"sr-only\">Zamknij</span>\n </button>\n\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-shrink-0\">\n <TriangleAlertIcon\n className=\"h-6 w-6 text-amber-500\"\n aria-hidden=\"true\"\n />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-lg font-semibold text-black dark:text-neutral-100\">\n Czy na pewno chcesz się wypisać?\n </h2>\n </div>\n </div>\n\n <p className=\"text-sm text-neutral-600 dark:text-neutral-400\">\n Kliknięcie tego przycisku spowoduje wypisanie z wszelkich\n powiadomień i grup, które zapisałeś.\n </p>\n\n <div className=\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => onOpenChange(false)}\n disabled={isDeleting}\n className=\"sm:min-w-[100px]\"\n >\n Anuluj\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={handleConfirm}\n disabled={isDeleting}\n className={cn(\n isDeleting && \"cursor-not-allowed text-transparent\",\n \"relative sm:min-w-[100px]\"\n )}\n >\n Usuń\n {isDeleting && (\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n <div className=\"h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent\" />\n </div>\n )}\n </Button>\n </div>\n </div>\n </div>\n </div>,\n document.body\n );\n}\n","import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { useMemo, useRef } from \"react\";\nimport { rpcProvider, RpcProvider, useMutation } from \"src/rpc-provider\";\nimport { Button } from \"@/src/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n} from \"@/src/ui/dialog\";\nimport { EmailCodeLoginForm } from \"@/src/ui/email-code-login/EmailCodeLoginForm\";\nimport { LoginBrandLogo } from \"@/src/ui/email-code-login/LoginBrandLogo\";\nimport { pendingLoginKey } from \"@/src/ui/email-code-login/pending\";\nimport { useEmailCodeLogin } from \"@/src/ui/email-code-login/useEmailCodeLogin\";\nimport {\n createNotificationsAdapter,\n notificationsLoginTexts,\n type NotificationsLoginResult,\n} from \"./login-adapter\";\nimport type { LoginScreenTexts } from \"./types\";\n\nexport type { LoginScreenTexts };\n\ninterface LoginScreenProps {\n /**\n * Unique identifier for the project (if not provided, productID will be used via CartProvider).\n */\n slug: string;\n\n /**\n * Callback function called when login is successful with the access token.\n */\n onSuccess?: (userID: string | undefined, accessToken: string) => void;\n\n /**\n * Callback function called when an error occurs.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback function called when the close button is clicked.\n */\n onClose?: () => void;\n\n /**\n * If true, the dialog is open.\n */\n isOpen: boolean;\n\n /**\n * Custom CSS class names for styling.\n */\n className?: string;\n\n /**\n * Custom texts used throughout the component for i18n or personalisation.\n */\n texts: LoginScreenTexts;\n\n /** Name and logos of the project, when the page already has them. */\n projectName?: string;\n projectLogo?: string;\n projectLogoDark?: string;\n\n /** `false` hides the logo above the login. Default `true`. */\n showLogo?: boolean;\n}\n\n/**\n * The dialog content. It mounts each time the dialog opens, so a finished or\n * abandoned login never leaves a locked form behind; a pending code step is\n * restored from `sessionStorage`.\n */\nfunction LoginDialogBody({\n slug,\n onSuccess,\n onError,\n texts,\n projectName,\n projectLogo,\n projectLogoDark,\n showLogo,\n}: Pick<\n LoginScreenProps,\n | \"slug\"\n | \"onSuccess\"\n | \"onError\"\n | \"texts\"\n | \"projectName\"\n | \"projectLogo\"\n | \"projectLogoDark\"\n | \"showLogo\"\n>) {\n const [parentHeader] = useAutoAnimate();\n const { mutateAsync: verifyUserEmail } = useMutation(\n rpcProvider.notifications.verifyUserEmail,\n );\n\n const loginTexts = useMemo(() => notificationsLoginTexts(texts), [texts]);\n const [before, after] = loginTexts.codeSentTo.split(\"{email}\");\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const adapter = useMemo(() => {\n const base = createNotificationsAdapter(\n (request) => verifyUserEmail(request),\n slug,\n texts,\n );\n return {\n ...base,\n // The hook reports every failure but a wrong code; `onError` always\n // got that one too, so keep it.\n async verify(input) {\n const outcome = await base.verify(input);\n if (!outcome.ok && outcome.kind === \"wrongCode\") {\n onErrorRef.current?.(\n outcome.cause instanceof Error\n ? outcome.cause\n : new Error(outcome.message ?? \"wrongCode\"),\n );\n }\n return outcome;\n },\n } satisfies typeof base;\n }, [verifyUserEmail, slug, texts]);\n\n const login = useEmailCodeLogin<NotificationsLoginResult>({\n adapter,\n texts: loginTexts,\n storageKey: slug ? pendingLoginKey(\"notifications\", slug) : undefined,\n onVerified: ({ userId, accessToken }) => onSuccess?.(userId, accessToken),\n onFailure: (kind, cause) =>\n onError?.(cause instanceof Error ? cause : new Error(kind)),\n });\n\n const onCodeStep = login.step === \"code\";\n // The title of the code step is the code label, as before.\n const title =\n onCodeStep && !login.needsEmail\n ? texts.loginCodeLabel ?? \"\"\n : texts.loginTitle ?? \"\";\n\n return (\n <div className=\"flex h-full flex-col\">\n <LoginBrandLogo\n projectId={slug}\n name={projectName}\n showLogo={showLogo}\n logoUrl={projectLogo}\n logoDarkUrl={projectLogoDark}\n className=\"text-foreground mb-3\"\n />\n <div ref={parentHeader} className=\"mb-2 flex items-start gap-2\">\n {onCodeStep && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"-mt-2 -ml-2 size-11 shrink-0\"\n aria-label={loginTexts.changeEmail}\n disabled={login.isBusy}\n onClick={login.changeEmail}\n >\n <ArrowLeft className=\"h-5 w-5\" aria-hidden />\n </Button>\n )}\n <DialogTitle className=\"text-lg leading-6 font-semibold\">\n {title}\n </DialogTitle>\n </div>\n {/* The form announces \"step 2 of 2\" itself; the description of the\n code step is the address, so nothing is read twice. */}\n <DialogDescription className={onCodeStep ? \"sr-only\" : \"mb-4\"}>\n {onCodeStep\n ? `${before}${login.email}${after ?? \"\"}`\n : texts.loginDescription ?? \"\"}\n </DialogDescription>\n <EmailCodeLoginForm login={login} texts={loginTexts} />\n </div>\n );\n}\n\nexport function LoginScreen({\n slug,\n onSuccess,\n onError,\n className: _className,\n isOpen,\n onClose,\n texts,\n projectName,\n projectLogo,\n projectLogoDark,\n showLogo,\n}: LoginScreenProps) {\n return (\n <Dialog open={isOpen} onOpenChange={onClose}>\n <DialogContent className=\"max-h-[100dvh] overflow-y-auto sm:max-w-[425px]\">\n <LoginDialogBody\n slug={slug}\n onSuccess={onSuccess}\n onError={onError}\n texts={texts}\n projectName={projectName}\n projectLogo={projectLogo}\n projectLogoDark={projectLogoDark}\n showLogo={showLogo}\n />\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction Wrapper(props: LoginScreenProps) {\n return (\n <RpcProvider>\n <LoginScreen {...props} />\n </RpcProvider>\n );\n}\n\nexport default Wrapper;\n","import * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { kindFromRpcError } from \"@/src/ui/email-code-login/errors\";\nimport {\n resolveEmailCodeTexts,\n type EmailCodeTexts,\n} from \"@/src/ui/email-code-login/texts\";\nimport type {\n EmailCodeAdapter,\n FailureKind,\n SendOutcome,\n VerifyOutcome,\n} from \"@/src/ui/email-code-login/useEmailCodeLogin\";\nimport type { LoginScreenTexts } from \"./types\";\n\nexport type NotificationsLoginResult = {\n userId: string | undefined;\n accessToken: string;\n};\n\n/** The one RPC both calls use (`VerifyUserEmail`), reduced to what is read. */\nexport type VerifyUserEmailCall = (request: {\n email?: string;\n code?: string;\n slug: string;\n}) => Promise<{\n ok?: boolean;\n accessToken?: string;\n userId?: string;\n retryIn?: number;\n /** `false`: a throttled resend, nothing went out. Absent (old servers): sent. */\n sent?: boolean;\n}>;\n\n/** Login texts of the notifications component mapped onto the shared ones. */\nexport function notificationsLoginTexts(\n texts: LoginScreenTexts,\n locale = \"pl\",\n): EmailCodeTexts {\n const sentTo = texts.loginCodeSentMessage;\n const overrides: Partial<EmailCodeTexts> = {\n emailLabel: texts.loginEmailLabel,\n emailPlaceholder: texts.loginEmailPlaceholder,\n sendCode: texts.loginSendCodeButton,\n sending: texts.loginSendingButton,\n invalidEmail: texts.loginInvalidEmailError,\n codeSentTo: sentTo != null ? `${sentTo} {email}.` : undefined,\n changeEmail: texts.loginChangeEmailButton,\n verify: texts.loginVerifyButton,\n spamHint: texts.loginSpamHint,\n validity: texts.loginValidityHint,\n resend: texts.loginResendCodeButton,\n resendIn: texts.loginResendInText,\n resent: texts.loginResentMessage,\n haveCodePrompt: \"\",\n haveCode: texts.loginIHaveCode,\n wrongCode: texts.loginInvalidCodeError,\n expired: texts.loginExpiredError,\n tooManyAttempts: texts.loginTooManyAttemptsError,\n rateLimited: texts.loginRateLimitedError,\n network: texts.loginNetworkError,\n generic: texts.loginVerifyCodeError,\n deliveryFailed: texts.loginSendEmailError,\n verifying: texts.loginVerifyingButton,\n stepEmail: texts.loginStepEmailHint,\n stepCode: texts.loginStepCodeHint,\n alreadySent: texts.loginAlreadySentMessage,\n emailNotFound: texts.loginEmailNotFoundError,\n deliveryUnavailable: texts.loginDeliveryUnavailableError,\n resendNew: texts.loginResendNewCodeButton,\n noCode: texts.loginNoCodeButton,\n codeIncomplete: texts.loginCodeIncompleteError,\n };\n return resolveEmailCodeTexts(locale, overrides);\n}\n\n/**\n * Kind of failure for an error thrown by `VerifyUserEmail`. The backend answers\n * a wrong code with \"Invalid code\" and the fifth wrong one (and per-IP limits)\n * with `ResourceExhausted`, \"Too many attempts\" for the former.\n */\nexport function notificationsFailureKind(error: unknown): FailureKind {\n const connect = ConnectError.from(error);\n const message = connect.rawMessage || connect.message;\n if (connect.code === Code.ResourceExhausted) {\n return /too many attempts/i.test(message) ? \"tooManyAttempts\" : \"rateLimited\";\n }\n if (/invalid code/i.test(message)) return \"wrongCode\";\n if (/expired/i.test(message)) return \"expired\";\n // Redis outage on the backend: not the customer's connection, so the\n // generic \"try again shortly\" copy.\n if (connect.code === Code.Unavailable) return \"unknown\";\n return kindFromRpcError(error);\n}\n\nexport function createNotificationsAdapter(\n call: VerifyUserEmailCall,\n slug: string,\n texts: LoginScreenTexts,\n): EmailCodeAdapter<NotificationsLoginResult> {\n return {\n async send(email, { resend }): Promise<SendOutcome> {\n if (!slug) {\n return { ok: false, kind: \"unknown\", message: texts.loginSlugRequiredError };\n }\n try {\n const response = await call({ email, slug });\n if (response.ok === false) {\n // `retryIn` without `ok`: the per-IP limit, nothing was sent. (A\n // throttled resend of a code that went out is `ok: true`.)\n return response.retryIn != null && response.retryIn > 0\n ? { ok: false, kind: \"rateLimited\", retryIn: response.retryIn }\n : {\n ok: false,\n kind: \"deliveryFailed\",\n message: resend ? texts.loginResendEmailError : texts.loginSendEmailError,\n };\n }\n if (response.sent === false) {\n // Throttled: an earlier code is still valid and `retryIn` is the\n // time left until a new one may be requested.\n return {\n ok: false,\n kind: \"alreadySent\",\n retryIn: response.retryIn || undefined,\n };\n }\n return { ok: true, retryIn: response.retryIn || undefined };\n } catch (cause) {\n const kind = notificationsFailureKind(cause);\n return {\n ok: false,\n kind,\n cause,\n message:\n kind === \"unknown\"\n ? resend\n ? texts.loginResendEmailError\n : texts.loginSendEmailError\n : undefined,\n };\n }\n },\n async verify({ email, code }): Promise<VerifyOutcome<NotificationsLoginResult>> {\n try {\n const response = await call({ email, code, slug });\n if (response.ok && response.accessToken) {\n return {\n ok: true,\n value: { userId: response.userId, accessToken: response.accessToken },\n };\n }\n return {\n ok: false,\n kind: \"wrongCode\",\n message: texts.loginVerificationFailedError,\n };\n } catch (cause) {\n return { ok: false, kind: notificationsFailureKind(cause), cause };\n }\n },\n };\n}\n"],"mappings":"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","names":["ApplePayButtonModule","currentProjectID","getProjectID","useQuery","jsx","ApplePayButton","ApplePayButtonModule","ApplePayButtonComponent","style","buttonType","colorType","items","onClick","checkIfApplePayIsAvailable","getApplePayPaymentRequest","completeApplePayPayment","setCountry","setCouponCodeIfPossible","setDeliveryMethod","setEmail","setPostalCode","clearCart","getApplePayPreview","useCartProvider","instrument","useInstrumentContext","paymentForCartText","useCheckoutText","isApplePayAvailable","useQuery","itemsKey","el","selection","getCheckoutSelection","preview","loadedPreview","isErr","round","acc","item","expectedItems","beginSession","reported","report","outcome","sendAnalyticEvent","requiresShipping","session","apRequest","event","result","PublicApiClient","HOST","getProjectID","error","Wrapper","props","useInstrument","currentProjectID","InstrumentProvider","CartProvider_default","ApplePay_default","useEffect","useId","useRef","zod","useAutoAnimate","Dialog","useCallback","useRef","useState","createPortal","createContext","useContext","useMemo","CHECKOUT_SLOT_NAMES","CHECKOUT_TOKEN_VARIABLES","CHECKOUT_THEME_PRESETS","CHECKOUT_SHADCN_VARIABLES","resolveDropdownStyle","tokens","resolveCheckoutAppearance","appearance","resolved","resolveAppearanceCore","getCheckoutSlotAppearance","slot","getSlotAppearance","jsx","CheckoutAppearanceContext","createContext","resolveCheckoutAppearance","CheckoutAppearanceProvider","appearance","children","resolved","useMemo","useCheckoutAppearance","useContext","useCheckoutSlot","slot","getCheckoutSlotAppearance","useAutoAnimate","React","useEffect","useState","SelectPrimitive","CheckIcon","ChevronDownIcon","ChevronUpIcon","jsx","jsxs","Select","props","SelectValue","props","jsx","selectTriggerThemeClasses","SelectTrigger","className","size","theme","children","jsxs","cn","ChevronDownIcon","SelectContent","position","align","SelectScrollUpButton","SelectScrollDownButton","SelectItem","className","children","props","jsxs","cn","jsx","CheckIcon","SelectScrollUpButton","className","props","jsx","cn","ChevronUpIcon","SelectScrollDownButton","ChevronDownIcon","jsx","jsxs","CountrySelector","id","open","disabled","onToggle","onChange","selectedValue","countries","query","setQuery","useState","isCustomized","boundaryClassName","boundaryStyle","dropdownStyle","useCheckoutAppearance","countryTrigger","useCheckoutSlot","countryDropdown","countrySearch","countryOption","searchCountryText","useCheckoutText","noCountriesFoundText","useEffect","filteredCountries","country","selectedCountry","el","Select","value","isOpen","SelectTrigger","cn","SelectValue","SelectContent","e","SelectItem","CountrySelector_default","useEffect","useRef","useState","MinusIcon","PlusIcon","Slot","cva","jsx","buttonGroupVariants","cva","ButtonGroup","className","orientation","props","cn","Fragment","jsx","jsxs","ProductPrice","price","currency","pricing","quantity","lowestPriceText","useCheckoutText","noPriceHistoryText","regular","effective","onSale","formatCurrency","clampQuantity","value","quantityFromInput","raw","current","parsed","Fragment","jsx","jsxs","SingleProduct","isNotAvailable","quantity","details","url","shouldUpdate","product","useCheckoutSlot","productImage","productName","productPrice","removeButton","removeText","useCheckoutText","imageUrl","brokenImageUrl","setBrokenImageUrl","useState","showImage","name","cn","ProductLink","ProductPrice","QuantityComponent","Button","SingleProduct_default","children","props","className","quantityString","setQuantityString","sent","useRef","quantityControl","quantityInput","quantityButton","quantityText","increaseText","decreaseText","shownQuantity","useEffect","commit","newQuantity","ButtonGroup","clampQuantity","MinusIcon","e","quantityFromInput","PlusIcon","jsx","Skeleton","className","props","useMutation","useQuery","useQueryClient","React","jsx","jsxs","PaymentMethodChoice","choice","selected","onChange","disabled","text","useCheckoutTextResolver","group","useCheckoutSlot","option","name","React","legendId","hasBlik","options","manualPaymentTitleKey","cn","method","card","isSelected","descriptionId","Fragment","jsx","jsxs","CartComponentContent","className","locale","provider","useCartProvider","instrument","useInstrumentContext","currentLocale","getLocale","productList","useCheckoutSlot","summary","totalLabel","totalValue","deliveryText","summaryNote","countryLabel","paymentButtons","checkoutButton","emptyState","error","skeleton","unavailableProductsText","useCheckoutText","resolveCheckoutText","useCheckoutTextResolver","emptyCartText","totalText","deliveryCopy","chooseCountryText","nextStepText","loadFailedText","retryText","countryRequiredText","extrasCalculatedNextText","countrySelectorId","React","countryHintId","removeProduct","useMutation","updateQuantity","setCountryAsync","clearCart","errMsg","setErrMsg","notice","useCheckoutStore","state","shownError","missingItemIds","setMissingItemIds","isCountryOpen","setIsCountryOpen","continueToCheckoutAsync","isContinueToCheckoutLoading","availableCountries","useQuery","isApplePayAvailable","data","isLoading","isError","refetch","countryData","refetchCountry","productsParent","useAutoAnimate","products","isErr","selectedCountry","queryClient","useQueryClient","cartSignature","el","paymentMethodsQuery","getProjectID","paymentMethodChoiceData","isPaymentMethodChoicePlaceholder","previous","withoutCod","paymentMethodChoice","selectedPaymentMethod","setSelectedPaymentMethod","isWaitingForChoice","setIsWaitingForChoice","paymentMethodsRef","hasLoadFailed","countries","sumOfProducts","prev","curr","currency","isSomeProductDeliverable","product","isCountryMissing","autoSelectedCountry","opened","sum","reportedQuantity","trackQuantityChange","id","newQuantity","line","delta","price","productID","startedCheckout","shouldUpdate","result","continueToCheckout","choice","paymentMethod","effectivePaymentMethod","sendAnalyticEvent","cartLinesBeforeBuy","getCartLines","response","buyErrorText","rememberPendingOrder","e","Skeleton","cn","SingleProduct_default","formatCurrency","CountrySelector_default","newValue","ApplePay_default","GooglePay_default","PaymentMethodChoice","Spinner","CartComponentContent_default","jsx","jsxs","CartComponent","isVisible","shouldHide","panelId","locale","parent","useAutoAnimate","rootElement","setRootElement","useState","rootRef","useCallback","element","returnFocusTo","useRef","boundaryClassName","boundaryStyle","useCheckoutAppearance","root","useCheckoutSlot","overlay","panel","header","title","closeButton","cartText","useCheckoutText","closeText","cn","open","active","event","CartComponentContent_default","WrapperCartComponent","props","createPortal","CheckoutAppearanceProvider","CheckoutTextsProvider","CartProvider_default","CartComponent_default","Fragment","jsx","jsxs","cartAddToCartSchema","zod","visuallyHidden","BitsnapCart","projectID","locale","children","onVisibleChange","className","numberOfProductsInCartOptions","appearance","texts","analytics","instrument","useInstrument","useCartInstrument","isCartVisible","showCart","hideCart","numberOfProductsInCart","useCheckoutStore","panelId","useId","text","key","getCheckoutText","getLocale","textRef","useRef","showCartNotice","sentPostMessageToIframe","msg","iframe","useEffect","sendAnalyticEvent","setProjectID","setLocale","getProjectID","args","payload","methods","getCheckoutMethods","products","isErr","el","result","e","handleAddingToCart","id","data","handleAddingSubscriptionToCart","event","setupEventListener","type","parsedParams","refLink","jsxs","Fragment","jsx","InstrumentProvider","CartComponent_default","BitsnapCart_default","GooglePayButton","useQuery","useMutation","Fragment","jsx","jsxs","GooglePayButtonComponent","items","style","buttonColor","buttonSizeMode","test","getGooglePayConfiguration","completeGooglePayPayment","setCountry","setCouponCodeIfPossible","setDeliveryMethod","setEmail","setPostalCode","clearCart","useCartProvider","instrument","useInstrumentContext","googlePayConfiguration","useQuery","el","completeGooglePayPaymentAsync","isPending","useMutation","GooglePayButton","paymentData","sendAnalyticEvent","config","paymentRequest","result","isErr","e","Spinner","Wrapper","props","useInstrument","currentProjectID","InstrumentProvider","CartProvider_default","GooglePay_default","useReducer","useRef","useEffect","UQ","Settings","Fragment","jsx","jsxs","LOGIN","EMAIL_CODE_TEXT_TABLES","DEFAULT_TEXTS","LogOutIcon","Fragment","jsx","jsxs","NotificationHeader","projectName","projectLogo","projectLogoDark","description","className","onLogout","cn","Button","SwitchPrimitive","jsx","Switch","className","props","cn","useAutoAnimate","CheckCircleIcon","TriangleAlertIcon","PopoverPrimitive","jsx","Popover","props","PopoverTrigger","PopoverContent","className","align","sideOffset","cn","ClockIcon","jsx","jsxs","HowOftenComponent","regularity","text","Popover","PopoverTrigger","e","PopoverContent","Fragment","jsx","jsxs","NotificationGroupsList","groups","isManaging","onToggle","onCheckAll","onUpdate","isUpdating","wasChanged","isUserGroupsUpdated","className","texts","groupsParent","useAutoAnimate","updateGroupsParent","hasNoSelection","group","hasUnchecked","content","cn","e","Switch","HowOftenComponent","Button","DEFAULT_TEXTS","Spinner","CheckCircleIcon","TriangleAlertIcon","Card","CardHeader","CardTitle","CardContent","jsx","jsxs","QRCodeSection","showQRCode","_isManaging","className","texts","isBrowser","darkMode","getURL","Card","cn","CardHeader","CardTitle","DEFAULT_TEXTS","CardContent","HOST","useState","isValidPhoneNumber","useAutoAnimate","Label","CheckCircleIcon","CircleAlertIcon","TriangleAlertIcon","useState","jsx","jsxs","FormInput","submit","isLoading","errMsg","emailLack","warnMsg","isSubmited","agreementLack","showPhoneInput","agreementText","className","texts","email","setEmail","useState","phone","setPhone","isChecked","setIsChecked","parent","useAutoAnimate","submitForm","e","cn","Label","DEFAULT_TEXTS","Input","newVal","TriangleAlertIcon","CircleAlertIcon","Button","Spinner","CheckCircleIcon","jsx","jsxs","emailRegex","AddUserToGroups","groups","onToggle","onCheckAll","slug","showPhoneInput","agreementText","className","texts","isUpdating","wasChanged","onSuccess","errMsg","setErrMsg","useState","warnMsg","setWarnMsg","isSubmited","setIsSubmited","agreementLack","setAgreementLack","emailLack","setEmailLack","createNotificationUserMutation","isCreateNotificationUserPending","useMutation","rpcProvider","validatePhoneNumber","phone","isValidPhoneNumber","save","email","agreement","newNotificationUser","el","failureMessage","FailureMessage","e","text","DEFAULT_TEXTS","cn","NotificationGroupsList","FormInput","useEffect","useState","Label","MessageCircleWarningIcon","useDebouncedCallback","TriangleAlertIcon","XIcon","createPortal","useEffect","useState","jsx","jsxs","UnsubscribeDialog","open","onOpenChange","onConfirm","isDeleting","mounted","setMounted","useState","useEffect","handleBackdropClick","e","handleConfirm","createPortal","cn","XIcon","TriangleAlertIcon","Button","useAutoAnimate","Fragment","jsx","jsxs","ManageMyData","accessToken","slug","userID","className","texts","parent","parentCard","deleteMyData","isDeleting","useMutation","rpcProvider","updateNotificationUser","isUpdating","userSettings","isLoading","useQuery","email","setEmail","useState","phone","setPhone","isDataUpdated","setIsDataUpdated","push","setPush","isDialogOpen","setIsDialogOpen","details","deleteData","handleConfirmDelete","updateData","debouncedUpdateData","useDebouncedCallback","_","useEffect","setData","key","value","cn","DEFAULT_TEXTS","Skeleton","Card","CardHeader","CardTitle","CardContent","Switch","Label","MessageCircleWarningIcon","Button","Spinner","UnsubscribeDialog","useAutoAnimate","ArrowLeft","useMemo","useRef","DialogPrimitive","XIcon","jsx","jsxs","Dialog","props","DialogPortal","props","jsx","DialogOverlay","className","props","jsx","cn","DialogContent","children","showCloseButton","jsxs","DialogPortal","XIcon","DialogTitle","className","props","jsx","cn","DialogDescription","Code","ConnectError","notificationsLoginTexts","texts","locale","sentTo","overrides","resolveEmailCodeTexts","notificationsFailureKind","error","connect","ConnectError","message","Code","kindFromRpcError","createNotificationsAdapter","call","slug","email","resend","response","cause","kind","code","jsx","jsxs","LoginDialogBody","slug","onSuccess","onError","texts","projectName","projectLogo","projectLogoDark","showLogo","parentHeader","useAutoAnimate","verifyUserEmail","useMutation","rpcProvider","loginTexts","useMemo","notificationsLoginTexts","before","after","onErrorRef","useRef","adapter","base","createNotificationsAdapter","request","input","outcome","login","useEmailCodeLogin","pendingLoginKey","userId","accessToken","kind","cause","onCodeStep","title","LoginBrandLogo","Button","ArrowLeft","DialogTitle","DialogDescription","EmailCodeLoginForm","LoginScreen","_className","isOpen","onClose","Dialog","DialogContent","useAutoAnimate","jsx","jsxs","reducer","state","action","group","g","isDefaultOn","newGroupsWithIsOn","updatedGroups","updated","NotificationsComponentPublic","slugProp","userID","productID","projectID","analytics","projectName","projectLogo","projectLogoDark","showLoginLogo","groups","isManaging","texts","showQRCode","showPhoneInput","hiddenGroupIds","className","parent","useAutoAnimate","instrument","useInstrument","currentProjectID","slug","getProjectID","useLoginBranding","updateUserGroups","isUpdating","useMutation","rpcProvider","userInfo","refetchAccessToken","UQ","groupsDownloaded","isGroupsDownloading","refetchGroups","useQuery","dispatch","useReducer","useEffect","newGroups","howOften","timeoutRef","useRef","preparedGroups","el","mergedTexts","DEFAULT_TEXTS","updateGroups","toggleGroup","groupID","checkAllGroups","handleSettingsClick","handleCloseSettings","handleLogout","handleLoginSuccess","accessToken","e","isManagingEnabled","cn","Button","Settings","NotificationHeader","Spinner","NotificationGroupsList","ManageMyData","QRCodeSection","AddUserToGroups","id","userAlreadyExists","LoginScreen","Wrapper","RpcProvider","NotificationsComponentPublic_default"]}
1
+ {"version":3,"sources":["../src/chat/lazy.tsx"],"sourcesContent":["import { lazy, Suspense } from \"react\";\nimport type { ChannelProps, ChatThreadProps } from \"./widgets\";\n\n// The chat view is a separate chunk: shops without chat never load it.\nconst LazyThread = lazy(() =>\n import(\"./index\").then((module) => ({ default: module.ChatThread })),\n);\nconst LazyChannel = lazy(() =>\n import(\"./index\").then((module) => ({ default: module.Channel })),\n);\n\nfunction Fallback() {\n return (\n <div className=\"bitsnap-react h-full\">\n <div\n role=\"status\"\n aria-busy=\"true\"\n className=\"h-full min-h-[28rem] w-full rounded-xl border border-neutral-200 bg-white motion-safe:animate-pulse dark:border-neutral-800 dark:bg-neutral-900\"\n />\n </div>\n );\n}\n\n/**\n * A buyer's pack thread for one service product. Loads the chat on demand;\n * the same component is exported eagerly from `bitsnap-react/chat`.\n */\nexport function ChatThread(props: ChatThreadProps) {\n return (\n <Suspense fallback={<Fallback />}>\n <LazyThread {...props} />\n </Suspense>\n );\n}\n\n/**\n * A community channel. Loads the chat on demand; the same component is\n * exported eagerly from `bitsnap-react/chat`.\n */\nexport function Channel(props: ChannelProps) {\n return (\n <Suspense fallback={<Fallback />}>\n <LazyChannel {...props} />\n </Suspense>\n );\n}\n"],"mappings":"uhCAAA,OAAS,QAAAA,EAAM,YAAAC,MAAgB,QAczB,cAAAC,MAAA,oBAVN,IAAMC,EAAaH,EAAK,IACtB,OAAO,YAAS,EAAE,KAAMI,IAAY,CAAE,QAASA,EAAO,UAAW,EAAE,CACrE,EACMC,EAAcL,EAAK,IACvB,OAAO,YAAS,EAAE,KAAMI,IAAY,CAAE,QAASA,EAAO,OAAQ,EAAE,CAClE,EAEA,SAASE,GAAW,CAClB,OACEJ,EAAC,OAAI,UAAU,uBACb,SAAAA,EAAC,OACC,KAAK,SACL,YAAU,OACV,UAAU,kJACZ,EACF,CAEJ,CAMO,SAASK,EAAWC,EAAwB,CACjD,OACEN,EAACD,EAAA,CAAS,SAAUC,EAACI,EAAA,EAAS,EAC5B,SAAAJ,EAACC,EAAA,CAAY,GAAGK,EAAO,EACzB,CAEJ,CAMO,SAASC,EAAQD,EAAqB,CAC3C,OACEN,EAACD,EAAA,CAAS,SAAUC,EAACI,EAAA,EAAS,EAC5B,SAAAJ,EAACG,EAAA,CAAa,GAAGG,EAAO,EAC1B,CAEJ","names":["lazy","Suspense","jsx","LazyThread","module","LazyChannel","Fallback","ChatThread","props","Channel"]}