@burdenoff/website-sdk 0.0.0-dev

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 (119) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +357 -0
  3. package/dist/analytics/index.d.mts +27 -0
  4. package/dist/analytics/index.d.ts +27 -0
  5. package/dist/analytics/index.js +36 -0
  6. package/dist/analytics/index.js.map +1 -0
  7. package/dist/analytics/index.mjs +34 -0
  8. package/dist/analytics/index.mjs.map +1 -0
  9. package/dist/client/index.d.mts +29 -0
  10. package/dist/client/index.d.ts +29 -0
  11. package/dist/client/index.js +261 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/client/index.mjs +255 -0
  14. package/dist/client/index.mjs.map +1 -0
  15. package/dist/components/contact.d.mts +144 -0
  16. package/dist/components/contact.d.ts +144 -0
  17. package/dist/components/contact.js +806 -0
  18. package/dist/components/contact.js.map +1 -0
  19. package/dist/components/contact.mjs +780 -0
  20. package/dist/components/contact.mjs.map +1 -0
  21. package/dist/components/electron-download.d.mts +32 -0
  22. package/dist/components/electron-download.d.ts +32 -0
  23. package/dist/components/electron-download.js +131 -0
  24. package/dist/components/electron-download.js.map +1 -0
  25. package/dist/components/electron-download.mjs +108 -0
  26. package/dist/components/electron-download.mjs.map +1 -0
  27. package/dist/components/launch-countdown.d.mts +15 -0
  28. package/dist/components/launch-countdown.d.ts +15 -0
  29. package/dist/components/launch-countdown.js +89 -0
  30. package/dist/components/launch-countdown.js.map +1 -0
  31. package/dist/components/launch-countdown.mjs +87 -0
  32. package/dist/components/launch-countdown.mjs.map +1 -0
  33. package/dist/components/newsletter.d.mts +155 -0
  34. package/dist/components/newsletter.d.ts +155 -0
  35. package/dist/components/newsletter.js +880 -0
  36. package/dist/components/newsletter.js.map +1 -0
  37. package/dist/components/newsletter.mjs +854 -0
  38. package/dist/components/newsletter.mjs.map +1 -0
  39. package/dist/components/partners.d.mts +88 -0
  40. package/dist/components/partners.d.ts +88 -0
  41. package/dist/components/partners.js +1169 -0
  42. package/dist/components/partners.js.map +1 -0
  43. package/dist/components/partners.mjs +1143 -0
  44. package/dist/components/partners.mjs.map +1 -0
  45. package/dist/components/pricing.d.mts +194 -0
  46. package/dist/components/pricing.d.ts +194 -0
  47. package/dist/components/pricing.js +813 -0
  48. package/dist/components/pricing.js.map +1 -0
  49. package/dist/components/pricing.mjs +791 -0
  50. package/dist/components/pricing.mjs.map +1 -0
  51. package/dist/components/problems-solved.d.mts +37 -0
  52. package/dist/components/problems-solved.d.ts +37 -0
  53. package/dist/components/problems-solved.js +157 -0
  54. package/dist/components/problems-solved.js.map +1 -0
  55. package/dist/components/problems-solved.mjs +135 -0
  56. package/dist/components/problems-solved.mjs.map +1 -0
  57. package/dist/components/resource-links.d.mts +28 -0
  58. package/dist/components/resource-links.d.ts +28 -0
  59. package/dist/components/resource-links.js +229 -0
  60. package/dist/components/resource-links.js.map +1 -0
  61. package/dist/components/resource-links.mjs +227 -0
  62. package/dist/components/resource-links.mjs.map +1 -0
  63. package/dist/components/social-links.d.mts +37 -0
  64. package/dist/components/social-links.d.ts +37 -0
  65. package/dist/components/social-links.js +268 -0
  66. package/dist/components/social-links.js.map +1 -0
  67. package/dist/components/social-links.mjs +266 -0
  68. package/dist/components/social-links.mjs.map +1 -0
  69. package/dist/components/unsubscribe.d.mts +14 -0
  70. package/dist/components/unsubscribe.d.ts +14 -0
  71. package/dist/components/unsubscribe.js +538 -0
  72. package/dist/components/unsubscribe.js.map +1 -0
  73. package/dist/components/unsubscribe.mjs +517 -0
  74. package/dist/components/unsubscribe.mjs.map +1 -0
  75. package/dist/components/waitlist.d.mts +70 -0
  76. package/dist/components/waitlist.d.ts +70 -0
  77. package/dist/components/waitlist.js +864 -0
  78. package/dist/components/waitlist.js.map +1 -0
  79. package/dist/components/waitlist.mjs +841 -0
  80. package/dist/components/waitlist.mjs.map +1 -0
  81. package/dist/components/website-switcher.d.mts +27 -0
  82. package/dist/components/website-switcher.d.ts +27 -0
  83. package/dist/components/website-switcher.js +168 -0
  84. package/dist/components/website-switcher.js.map +1 -0
  85. package/dist/components/website-switcher.mjs +146 -0
  86. package/dist/components/website-switcher.mjs.map +1 -0
  87. package/dist/content/index.d.mts +247 -0
  88. package/dist/content/index.d.ts +247 -0
  89. package/dist/content/index.js +2458 -0
  90. package/dist/content/index.js.map +1 -0
  91. package/dist/content/index.mjs +2428 -0
  92. package/dist/content/index.mjs.map +1 -0
  93. package/dist/index.d.mts +72 -0
  94. package/dist/index.d.ts +72 -0
  95. package/dist/index.js +6273 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/index.mjs +6204 -0
  98. package/dist/index.mjs.map +1 -0
  99. package/dist/product/index.d.mts +94 -0
  100. package/dist/product/index.d.ts +94 -0
  101. package/dist/product/index.js +282 -0
  102. package/dist/product/index.js.map +1 -0
  103. package/dist/product/index.mjs +278 -0
  104. package/dist/product/index.mjs.map +1 -0
  105. package/dist/provider-D7Rij9UM.d.mts +86 -0
  106. package/dist/provider-D7Rij9UM.d.ts +86 -0
  107. package/dist/seo/index.d.mts +64 -0
  108. package/dist/seo/index.d.ts +64 -0
  109. package/dist/seo/index.js +61 -0
  110. package/dist/seo/index.js.map +1 -0
  111. package/dist/seo/index.mjs +59 -0
  112. package/dist/seo/index.mjs.map +1 -0
  113. package/dist/utils/index.d.mts +21 -0
  114. package/dist/utils/index.d.ts +21 -0
  115. package/dist/utils/index.js +12 -0
  116. package/dist/utils/index.js.map +1 -0
  117. package/dist/utils/index.mjs +10 -0
  118. package/dist/utils/index.mjs.map +1 -0
  119. package/package.json +168 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/security.ts","../../src/client/graphql-client.ts","../../src/client/provider.tsx","../../src/product/product-provider.tsx","../../src/seo/page-head.tsx","../../src/utils/cn.ts","../../src/ui/button.tsx","../../src/ui/input.tsx","../../src/ui/label.tsx","../../src/components/newsletter.tsx"],"names":["createContext","useContext","Helmet","jsx","twMerge","clsx","cva","React","Slot","React2","React3","LabelPrimitive","z","useRef","useState","useEffect","useForm","zodResolver","toast","jsxs","Fragment","ReCAPTCHA"],"mappings":"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","file":"newsletter.js","sourcesContent":["const LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"x-actor-id\",\n \"x-actor-type\",\n \"x-consent-granted-by\",\n \"x-consent-scope\",\n \"x-consent-granted-at\",\n \"x-consent-expires-at\",\n]);\n\nexport function validateGatewayUrl(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Gateway URL must be a valid absolute URL\");\n }\n\n if (url.protocol === \"https:\") {\n return url.toString();\n }\n\n if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n return url.toString();\n }\n\n throw new Error(\"Gateway URL must use HTTPS unless it targets localhost\");\n}\n\nexport function sanitizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([key]) => !RESERVED_HEADERS.has(key.toLowerCase()),\n ),\n );\n}\n","/**\n * Lightweight GraphQL client for the Burdenoff Web SDK.\n * Uses native fetch - zero external dependencies.\n * All calls are unauthenticated (public gateway operations only).\n */\n\nimport { sanitizeHeaders, validateGatewayUrl } from \"./security\";\n\nexport interface WebSDKClientConfig {\n /** Global public gateway URL (e.g. \"https://api.burdenoff.com/global/graphql\") */\n gatewayUrl: string;\n /** Platform product ID for scoping operations */\n productId: string;\n /** Product slug (used for public product queries) */\n productSlug?: string;\n /** reCAPTCHA site key (if not fetched from product config) */\n recaptchaSiteKey?: string;\n /** Rybbit analytics site ID */\n rybbitSiteId?: string;\n /** Custom headers to include in all requests */\n headers?: Record<string, string>;\n}\n\nexport interface GraphQLResponse<T = Record<string, unknown>> {\n data?: T;\n errors?: Array<{\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n }>;\n}\n\nexport class WebSDKClient {\n private config: WebSDKClientConfig;\n private queryCache = new Map<\n string,\n { data: GraphQLResponse<unknown>; ts: number }\n >();\n private inflight = new Map<string, Promise<GraphQLResponse<unknown>>>();\n private static CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n private static MAX_CACHE_ENTRIES = 100;\n\n constructor(config: WebSDKClientConfig) {\n this.config = {\n ...config,\n gatewayUrl: validateGatewayUrl(config.gatewayUrl),\n headers: sanitizeHeaders(config.headers),\n };\n }\n\n getConfig(): WebSDKClientConfig {\n return this.config;\n }\n\n /**\n * Execute a GraphQL query (with deduplication and caching)\n */\n async query<T = Record<string, unknown>>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n const cacheKey = JSON.stringify({ query, variables });\n\n // Return cached response if still valid, evict if expired\n const cached = this.queryCache.get(cacheKey);\n if (cached) {\n if (Date.now() - cached.ts < WebSDKClient.CACHE_TTL) {\n return cached.data as GraphQLResponse<T>;\n }\n this.queryCache.delete(cacheKey);\n }\n\n // Deduplicate: if same query is already in-flight, reuse the promise\n const existing = this.inflight.get(cacheKey);\n if (existing) {\n return existing as Promise<GraphQLResponse<T>>;\n }\n\n const promise = this.request<T>(query, variables)\n .then((result) => {\n // Cache successful responses only\n if (result.data && !result.errors?.length) {\n if (this.queryCache.size >= WebSDKClient.MAX_CACHE_ENTRIES) {\n const oldestEntry = this.queryCache.keys().next().value;\n if (oldestEntry) {\n this.queryCache.delete(oldestEntry);\n }\n }\n this.queryCache.set(cacheKey, { data: result, ts: Date.now() });\n }\n return result;\n })\n .finally(() => {\n this.inflight.delete(cacheKey);\n });\n\n this.inflight.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T = Record<string, unknown>>(\n mutation: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n return this.request<T>(mutation, variables);\n }\n\n private async request<T>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n try {\n const response = await fetch(this.config.gatewayUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-product-id\": this.config.productId,\n ...this.config.headers,\n },\n body: JSON.stringify({ query, variables }),\n });\n\n if (!response.ok) {\n console.error(\n \"[WebSDK] GraphQL request failed\",\n response.status,\n response.statusText,\n );\n return {\n errors: [\n {\n message: `HTTP ${response.status}: ${response.statusText}`,\n extensions: { code: `HTTP_${response.status}` },\n },\n ],\n };\n }\n\n return (await response.json()) as GraphQLResponse<T>;\n } catch (error) {\n console.error(\n \"[WebSDK] Network error\",\n error instanceof Error ? error.message : \"unknown error\",\n );\n return {\n errors: [\n {\n message: error instanceof Error ? error.message : \"Network error\",\n extensions: { code: \"NETWORK_ERROR\" },\n },\n ],\n };\n }\n }\n}\n","/**\n * React context provider for the Web SDK client.\n * Wraps the application with WebSDKClient configuration.\n */\n\"use client\";\n\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { resolveGatewayUrl } from \"./gateway-resolver\";\nimport { WebSDKClient, type WebSDKClientConfig } from \"./graphql-client\";\n\nconst WebSDKContext = createContext<WebSDKClient | null>(null);\n\nexport interface WebSDKProviderProps {\n /** SDK client configuration */\n config: WebSDKClientConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the WebSDKClient available to all child components.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={{\n * gatewayUrl: \"https://api.burdenoff.com/global/graphql\",\n * productId: \"your-product-id\",\n * productSlug: \"your-product\",\n * }}>\n * <App />\n * </WebSDKProvider>\n * ```\n */\nexport function WebSDKProvider({ config, children }: WebSDKProviderProps) {\n const client = useMemo(() => {\n const resolvedConfig = {\n ...config,\n gatewayUrl: resolveGatewayUrl(config.gatewayUrl),\n };\n return new WebSDKClient(resolvedConfig);\n }, [config]);\n\n return (\n <WebSDKContext.Provider value={client}>{children}</WebSDKContext.Provider>\n );\n}\n\n/**\n * Hook to access the WebSDKClient instance.\n * Must be used within a WebSDKProvider.\n */\nexport function useWebSDK(): WebSDKClient {\n const client = useContext(WebSDKContext);\n if (!client) {\n throw new Error(\"useWebSDK must be used within a WebSDKProvider\");\n }\n return client;\n}\n\n/**\n * Hook to access the SDK configuration.\n * Useful for components that need config values like productId, recaptchaSiteKey, etc.\n */\nexport function useWebSDKConfig(): WebSDKClientConfig {\n const client = useWebSDK();\n return client.getConfig();\n}\n","/**\n * Product Provider\n *\n * React context and hooks for accessing product metadata from the global tenant service.\n * Fetches product info (name, logo, SEO, contact, reCAPTCHA key, etc.) on mount\n * and provides it to all child components.\n */\n\"use client\";\n\nimport {\n createContext,\n useContext,\n useState,\n useLayoutEffect,\n useCallback,\n useMemo,\n} from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ProductData {\n id: string;\n name: string;\n slug: string;\n description?: string | null;\n status: string;\n logoUrl?: string | null;\n website?: string | null;\n appUrl?: string | null;\n docsUrl?: string | null;\n contactEmail?: string | null;\n supportEmail?: string | null;\n contactPhone?: string | null;\n contactAddress?: string | null;\n seoTitle?: string | null;\n seoDescription?: string | null;\n seoKeywords?: string | null;\n ogImage?: string | null;\n socialLinks?: Record<string, string> | null;\n /**\n * Resource links for the website footer \"Resources\" column\n * (JSON: { docs, community, careers, team, companies, ... }).\n * Same shape as socialLinks. Free-form keys; the ResourceLinks\n * component renders known keys and silently ignores the rest.\n * Backed by Product.resourceLinks on the backend (global-tenant-svc).\n */\n resourceLinks?: Record<string, string> | null;\n recaptchaSiteKey?: string | null;\n rybbitSiteId?: string | null;\n notificationEmail?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface ProductProviderProps {\n /** Child components */\n children: ReactNode;\n /** Optional fallback product data (used while loading) */\n fallback?: Partial<ProductData>;\n}\n\n// ============================================================================\n// GraphQL Query\n// ============================================================================\n\n/**\n * Body of fields requested for every product fetch — shared by the primary\n * query and the legacy-backend fallback below. Kept as a string fragment\n * (not a real GraphQL `fragment` block) so we can append/strip\n * `resourceLinks` without touching anything else.\n */\nconst PRODUCT_FIELDS_BASE = `\n id\n name\n slug\n description\n status\n logoUrl\n website\n appUrl\n docsUrl\n contactEmail\n supportEmail\n contactPhone\n contactAddress\n seoTitle\n seoDescription\n seoKeywords\n ogImage\n socialLinks\n recaptchaSiteKey\n rybbitSiteId\n notificationEmail\n metadata\n`;\n\n/**\n * Primary query — includes the recently-added `resourceLinks` field.\n * Backends that have run the corresponding `global-tenant-svc` migration\n * (PR #64) expose this field; older ones don't, in which case\n * GraphQL validation rejects the whole query with\n * `Cannot query field \"resourceLinks\" on type \"PublicProduct\"`. The fetch\n * helper detects that specific error and transparently retries the\n * fallback below, so the SDK works on both pre- and post-migration\n * deployments without consumer-side gating.\n */\nconst PUBLIC_PRODUCT_QUERY = `\n query PublicProduct($slug: String!) {\n publicProduct(slug: $slug) {\n ${PRODUCT_FIELDS_BASE}\n resourceLinks\n }\n }\n`;\n\n/**\n * Fallback query for older backend deployments. Identical to the primary\n * minus `resourceLinks`. Consumers see `product.resourceLinks === undefined`\n * and any consumer (e.g. `<ResourceLinks/>`) falls through to prop / default\n * resolution paths.\n */\nconst PUBLIC_PRODUCT_QUERY_FALLBACK = `\n query PublicProductFallback($slug: String!) {\n publicProduct(slug: $slug) {\n ${PRODUCT_FIELDS_BASE}\n }\n }\n`;\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface ProductContextValue {\n product: ProductData | null;\n loading: boolean;\n error: string | null;\n hasProvider: boolean;\n refetch: () => void;\n}\n\nconst ProductContext = createContext<ProductContextValue>({\n product: null,\n loading: true,\n error: null,\n hasProvider: false,\n refetch: () => {},\n});\n\n// ============================================================================\n// Provider\n// ============================================================================\n\n/**\n * ProductProvider fetches and provides product metadata to child components.\n * Uses the product slug from WebSDKConfig to fetch from the public API.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={sdkConfig}>\n * <ProductProvider>\n * <App />\n * </ProductProvider>\n * </WebSDKProvider>\n * ```\n */\nexport function ProductProvider({ children, fallback }: ProductProviderProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const [product, setProduct] = useState<ProductData | null>(\n fallback ? (fallback as ProductData) : null,\n );\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const fetchProduct = useCallback(async () => {\n if (!config.productSlug) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n let result = await client.query<{ publicProduct: ProductData | null }>(\n PUBLIC_PRODUCT_QUERY,\n { slug: config.productSlug },\n );\n\n // Backwards-compat fallback: if the backend's `publicProduct` schema\n // doesn't yet expose `resourceLinks` (deployed before\n // `global-tenant-svc` PR #64), the primary query fails validation\n // with a \"Cannot query field …\" error and `result.data` is null.\n // Retry the fallback query that omits `resourceLinks`; consumers\n // gracefully see `product.resourceLinks === undefined` and fall\n // through their own resolution paths.\n const schemaMissingResourceLinks = result.errors?.some((e) =>\n /Cannot query field [\"']?resourceLinks[\"']?/i.test(e?.message ?? \"\"),\n );\n if (schemaMissingResourceLinks) {\n result = await client.query<{ publicProduct: ProductData | null }>(\n PUBLIC_PRODUCT_QUERY_FALLBACK,\n { slug: config.productSlug },\n );\n }\n\n if (result.errors?.length) {\n setError(result.errors[0]?.message ?? \"Unknown error\");\n } else if (result.data?.publicProduct) {\n setProduct(result.data.publicProduct);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to fetch product\");\n } finally {\n setLoading(false);\n }\n }, [client, config.productSlug]);\n\n // Use useLayoutEffect for earliest possible fetch after commit (before paint).\n // Runs when slug or client changes. Client-side query cache + dedup ensures\n // no duplicate network requests even if React StrictMode fires this twice.\n useLayoutEffect(() => {\n fetchProduct();\n }, [fetchProduct]);\n\n const value = useMemo(\n () => ({\n product,\n loading,\n error,\n hasProvider: true,\n refetch: fetchProduct,\n }),\n [product, loading, error, fetchProduct],\n );\n\n return (\n <ProductContext.Provider value={value}>{children}</ProductContext.Provider>\n );\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * Hook to access the current product data.\n *\n * @example\n * ```tsx\n * const { product, loading } = useProduct();\n * if (loading) return <Loading />;\n * return <h1>{product?.name}</h1>;\n * ```\n */\nexport function useProduct(): ProductContextValue {\n return useContext(ProductContext);\n}\n\n/**\n * Hook to get product-specific configuration.\n * Merges SDK config with fetched product data.\n * Useful for getting reCAPTCHA keys, analytics IDs, etc.\n *\n * @example\n * ```tsx\n * const { recaptchaSiteKey, rybbitSiteId } = useProductConfig();\n * ```\n */\nexport function useProductConfig(): {\n recaptchaSiteKey: string | null;\n rybbitSiteId: string | null;\n contactEmail: string | null;\n supportEmail: string | null;\n notificationEmail: string | null;\n productName: string | null;\n logoUrl: string | null;\n} {\n const { product } = useProduct();\n const config = useWebSDKConfig();\n\n return {\n // Prefer product-level config, fall back to SDK config\n recaptchaSiteKey:\n product?.recaptchaSiteKey ?? config.recaptchaSiteKey ?? null,\n rybbitSiteId: product?.rybbitSiteId ?? config.rybbitSiteId ?? null,\n contactEmail: product?.contactEmail ?? null,\n supportEmail: product?.supportEmail ?? null,\n notificationEmail:\n product?.notificationEmail ?? product?.contactEmail ?? null,\n productName: product?.name ?? null,\n logoUrl: product?.logoUrl ?? null,\n };\n}\n","/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n const fullImageUrl =\n image && !image.startsWith(\"http\") && url\n ? `${url.replace(/\\/$/, \"\")}${image}`\n : image;\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description && <meta name=\"description\" content={description} />}\n {keywords && <meta name=\"keywords\" content={keywords} />}\n <meta name=\"author\" content=\"Burdenoff Consultancy Services Pvt Ltd\" />\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {url && <link rel=\"canonical\" href={url} />}\n\n {/* Favicon */}\n {favicon && <link rel=\"icon\" href={favicon} />}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description && <meta property=\"og:description\" content={description} />}\n {fullImageUrl && <meta property=\"og:image\" content={fullImageUrl} />}\n {url && <meta property=\"og:url\" content={url} />}\n <meta property=\"og:locale\" content={locale} />\n {productName && <meta property=\"og:site_name\" content={productName} />}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description && <meta name=\"twitter:description\" content={description} />}\n {fullImageUrl && <meta name=\"twitter:image\" content={fullImageUrl} />}\n {twitterHandle && <meta name=\"twitter:creator\" content={twitterHandle} />}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {JSON.stringify(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n","/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n","import * as React from \"react\";\n\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","/**\n * Newsletter Component\n * Reusable newsletter subscription component with email validation and rate limiting.\n * Uses GraphQL mutations via the WebSDKClient provider.\n *\n * @example\n * ```tsx\n * import { NewsletterPage } from '@burdenoff/website-sdk/components/newsletter'\n *\n * function Newsletter() {\n * return (\n * <NewsletterPage\n * productName=\"BigConsole\"\n * layout=\"centered\"\n * seoTitle=\"Subscribe to Newsletter\"\n * seoDescription=\"Stay updated with our latest news\"\n * seoKeywords=\"newsletter, updates, news\"\n * />\n * )\n * }\n * ```\n */\n\n\"use client\";\n\nimport { useState, useEffect, useRef } from \"react\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\nimport { z } from \"zod\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { useProduct, useProductConfig } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\n\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\n/**\n * Newsletter page component configuration props\n */\nexport interface NewsletterPageProps {\n /**\n * Product name (used in title and branding).\n * Falls back to SDK config productId if not provided.\n */\n productName?: string;\n /**\n * Layout variant\n * @default 'centered'\n */\n layout?: \"centered\" | \"split\";\n /**\n * Rate limit attempts\n * @default 3\n */\n rateLimitAttempts?: number;\n /**\n * Rate limit window in minutes\n * @default 15\n */\n rateLimitWindowMinutes?: number;\n /**\n * Hero section heading\n * @default 'Stay Updated'\n */\n heroHeading?: string;\n /**\n * Hero section subtitle\n * @default 'Subscribe to our newsletter'\n */\n heroSubtitle?: string;\n /**\n * Hero section description\n */\n heroDescription?: string;\n /**\n * Features to display (for split layout)\n */\n features?: Array<{\n icon: React.ReactNode;\n title: string;\n description: string;\n }>;\n /**\n * Success message after subscription\n * @default 'Successfully subscribed to newsletter!'\n */\n successMessage?: string;\n /**\n * Error message on failure\n * @default 'Failed to subscribe. Please try again.'\n */\n errorMessage?: string;\n /**\n * Rate limit error message\n */\n rateLimitMessage?: string;\n /**\n * Custom CSS class for container\n */\n className?: string;\n /**\n * SEO: Page title (optional, for SEO meta tags)\n */\n seoTitle?: string;\n /**\n * SEO: Page description (optional, for SEO meta tags)\n */\n seoDescription?: string;\n /**\n * SEO: Keywords (optional, for SEO meta tags)\n */\n seoKeywords?: string;\n /**\n * SEO: OG Image URL (optional, for SEO meta tags)\n */\n seoImage?: string;\n /**\n * SEO: Canonical URL (optional, for SEO meta tags)\n */\n seoUrl?: string;\n /**\n * reCAPTCHA site key (optional, falls back to SDK config)\n */\n recaptchaSiteKey?: string;\n}\n\ninterface RateLimitState {\n attempts: number;\n resetTime: number;\n}\n\n// ============================================================================\n// VALIDATION SCHEMA\n// ============================================================================\n\nconst newsletterSchema = z.object({\n email: z.string().email(\"Please enter a valid email address\"),\n});\n\ntype NewsletterFormData = z.infer<typeof newsletterSchema>;\n\n// ============================================================================\n// GRAPHQL MUTATION\n// ============================================================================\n\nconst SUBSCRIBE_MUTATION = /* GraphQL */ `\n mutation Subscribe($input: SubscribeInput!) {\n subscribe(input: $input) {\n id\n email\n alreadySubscribed\n status\n subscribedAt\n }\n }\n`;\n\n// ============================================================================\n// API SERVICE\n// ============================================================================\n\nasync function subscribeNewsletter(\n client: WebSDKClient,\n email: string,\n productId: string,\n recaptchaToken?: string,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n subscribe: {\n id: string;\n email: string;\n status: string;\n alreadySubscribed?: boolean;\n };\n }>(SUBSCRIBE_MUTATION, {\n input: {\n email: email.trim().toLowerCase(),\n platformProductId: productId,\n metadata: {\n source: \"website\",\n referrer: typeof window !== \"undefined\" ? window.location.href : \"\",\n timestamp: new Date().toISOString(),\n ...(recaptchaToken ? { recaptchaToken } : {}),\n },\n },\n });\n\n if (result.errors?.length) {\n const errorMsg = result.errors[0]?.message ?? \"Subscription failed\";\n const code = (result.errors[0] as { extensions?: { code?: string } })\n ?.extensions?.code;\n if (\n code === \"DUPLICATE_SUBSCRIBER\" ||\n errorMsg.toLowerCase().includes(\"already subscribed\")\n ) {\n return {\n success: true,\n message: \"You are already part of this newsletter.\",\n };\n }\n return { success: false, message: errorMsg };\n }\n\n if (result.data?.subscribe?.alreadySubscribed) {\n return {\n success: true,\n message: \"You are already part of this newsletter.\",\n };\n }\n\n return { success: true };\n } catch (error) {\n console.error(\"Newsletter subscription error:\", error);\n return { success: false, message: \"Network error. Please try again.\" };\n }\n}\n\n// ============================================================================\n// RATE LIMITING (in-memory for SSR compatibility)\n// ============================================================================\n\nfunction useRateLimit(maxAttempts: number, windowMinutes: number) {\n const rateLimitRef = useRef<RateLimitState | null>(null);\n const [isLimited, setIsLimited] = useState(false);\n const [resetTime, setResetTime] = useState<Date | null>(null);\n\n useEffect(() => {\n // Check if existing rate limit has expired on mount\n const state = rateLimitRef.current;\n if (state && Date.now() > state.resetTime) {\n rateLimitRef.current = null;\n setIsLimited(false);\n setResetTime(null);\n } else if (state && state.attempts >= maxAttempts) {\n setIsLimited(true);\n setResetTime(new Date(state.resetTime));\n }\n }, [maxAttempts]);\n\n function recordAttempt(): boolean {\n const now = Date.now();\n const state = rateLimitRef.current;\n\n // Reset if window expired\n if (state && now > state.resetTime) {\n rateLimitRef.current = null;\n }\n\n const current = rateLimitRef.current;\n\n if (!current) {\n rateLimitRef.current = {\n attempts: 1,\n resetTime: now + windowMinutes * 60 * 1000,\n };\n return false;\n }\n\n current.attempts += 1;\n\n if (current.attempts >= maxAttempts) {\n setIsLimited(true);\n setResetTime(new Date(current.resetTime));\n return true;\n }\n\n return false;\n }\n\n function checkLimit(): boolean {\n const state = rateLimitRef.current;\n if (!state) return false;\n if (Date.now() > state.resetTime) {\n rateLimitRef.current = null;\n setIsLimited(false);\n setResetTime(null);\n return false;\n }\n return state.attempts >= maxAttempts;\n }\n\n return { isLimited, resetTime, recordAttempt, checkLimit };\n}\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport function NewsletterPage({\n productName,\n layout = \"centered\",\n rateLimitAttempts = 3,\n rateLimitWindowMinutes = 15,\n heroHeading = \"Stay Updated\",\n heroSubtitle = \"Subscribe to our newsletter\",\n heroDescription,\n features,\n successMessage = \"Successfully subscribed to newsletter!\",\n errorMessage = \"Failed to subscribe. Please try again.\",\n rateLimitMessage,\n className,\n seoTitle,\n seoDescription,\n seoKeywords,\n seoImage,\n seoUrl,\n recaptchaSiteKey,\n}: NewsletterPageProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const productConfig = useProductConfig();\n const effectiveProductId = product?.id || config.productId;\n const displayName = productName ?? product?.name ?? config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n productConfig.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isLimited, resetTime, recordAttempt, checkLimit } = useRateLimit(\n rateLimitAttempts,\n rateLimitWindowMinutes,\n );\n\n const {\n register,\n handleSubmit,\n formState: { errors },\n reset,\n } = useForm<NewsletterFormData>({\n resolver: zodResolver(newsletterSchema),\n });\n\n const onSubmit = async (data: NewsletterFormData) => {\n // Check reCAPTCHA\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n\n // Check rate limit\n if (checkLimit()) {\n toast.error(\n rateLimitMessage ??\n `Too many attempts. Please try again after ${resetTime?.toLocaleTimeString()}`,\n );\n return;\n }\n\n setIsSubmitting(true);\n\n try {\n const result = await subscribeNewsletter(\n client,\n data.email,\n effectiveProductId,\n recaptchaToken || undefined,\n );\n\n if (result.success) {\n if (result.message) {\n toast.info(result.message);\n } else {\n toast.success(successMessage);\n }\n reset();\n } else {\n toast.error(result.message ?? errorMessage);\n }\n\n // Record the attempt for rate limiting\n recordAttempt();\n recaptchaRef.current?.reset();\n } catch (_error) {\n toast.error(errorMessage);\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const defaultFeatures = [\n {\n icon: (\n <svg\n className=\"h-6 w-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 10V3L4 14h7v7l9-11h-7z\"\n />\n </svg>\n ),\n title: \"Latest Updates\",\n description: \"Get the latest news and updates delivered to your inbox\",\n },\n {\n icon: (\n <svg\n className=\"h-6 w-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4\"\n />\n </svg>\n ),\n title: \"Exclusive Content\",\n description:\n \"Access exclusive content and insights not available elsewhere\",\n },\n {\n icon: (\n <svg\n className=\"h-6 w-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9\"\n />\n </svg>\n ),\n title: \"Early Access\",\n description:\n \"Be the first to know about new features and product launches\",\n },\n ];\n\n const displayFeatures = features ?? defaultFeatures;\n\n return (\n <>\n {/* SEO Meta Tags */}\n {seoTitle && (\n <PageHead\n title={seoTitle}\n description={seoDescription ?? heroDescription ?? heroSubtitle}\n productName={displayName}\n keywords={seoKeywords}\n image={seoImage}\n url={seoUrl}\n />\n )}\n\n <div className={className}>\n {layout === \"centered\" ? (\n // Centered Layout\n <div className=\"min-h-screen flex items-center justify-center px-4 py-12\">\n <div className=\"max-w-md w-full space-y-8\">\n {/* Header */}\n <div className=\"text-center\">\n <h1 className=\"text-4xl font-bold tracking-tight\">\n {heroHeading}\n </h1>\n <p className=\"mt-2 text-lg text-muted-foreground\">\n {heroSubtitle}\n </p>\n {heroDescription && (\n <p className=\"mt-4 text-sm text-muted-foreground\">\n {heroDescription}\n </p>\n )}\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email address</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n disabled={isSubmitting || isLimited}\n {...register(\"email\")}\n />\n {errors.email && (\n <p className=\"text-sm text-destructive\">\n {errors.email.message}\n </p>\n )}\n </div>\n\n {effectiveRecaptchaSiteKey && (\n <div className=\"flex justify-center\">\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n </div>\n )}\n\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={isSubmitting || isLimited}\n >\n {isSubmitting ? \"Subscribing...\" : \"Subscribe\"}\n </Button>\n\n {isLimited && resetTime && (\n <p className=\"text-sm text-muted-foreground text-center\">\n Rate limit reached. Try again after{\" \"}\n {resetTime.toLocaleTimeString()}\n </p>\n )}\n </form>\n\n {/* Privacy Notice */}\n <p className=\"text-xs text-muted-foreground text-center\">\n By subscribing, you agree to receive emails from {displayName}.\n You can unsubscribe at any time.\n </p>\n </div>\n </div>\n ) : (\n // Split Layout\n <div className=\"min-h-screen grid lg:grid-cols-2\">\n {/* Left Column - Form */}\n <div className=\"flex items-center justify-center px-4 py-12 sm:px-6 lg:px-8\">\n <div className=\"max-w-md w-full space-y-8\">\n {/* Header */}\n <div>\n <h1 className=\"text-4xl font-bold tracking-tight\">\n {heroHeading}\n </h1>\n <p className=\"mt-2 text-lg text-muted-foreground\">\n {heroSubtitle}\n </p>\n {heroDescription && (\n <p className=\"mt-4 text-sm text-muted-foreground\">\n {heroDescription}\n </p>\n )}\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email address</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"you@example.com\"\n disabled={isSubmitting || isLimited}\n {...register(\"email\")}\n />\n {errors.email && (\n <p className=\"text-sm text-destructive\">\n {errors.email.message}\n </p>\n )}\n </div>\n\n {effectiveRecaptchaSiteKey && (\n <div className=\"flex justify-center sm:justify-start\">\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n </div>\n )}\n\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={isSubmitting || isLimited}\n >\n {isSubmitting ? \"Subscribing...\" : \"Subscribe\"}\n </Button>\n\n {isLimited && resetTime && (\n <p className=\"text-sm text-muted-foreground text-center\">\n Rate limit reached. Try again after{\" \"}\n {resetTime.toLocaleTimeString()}\n </p>\n )}\n </form>\n\n {/* Privacy Notice */}\n <p className=\"text-xs text-muted-foreground\">\n By subscribing, you agree to receive emails from {displayName}\n . You can unsubscribe at any time.\n </p>\n </div>\n </div>\n\n {/* Right Column - Features */}\n <div className=\"hidden lg:flex items-center justify-center bg-muted px-4 py-12 sm:px-6 lg:px-8\">\n <div className=\"max-w-md space-y-8\">\n <h2 className=\"text-2xl font-bold\">Why Subscribe?</h2>\n <div className=\"space-y-6\">\n {displayFeatures.map((feature, index) => (\n <div key={index} className=\"flex gap-4\">\n <div className=\"flex-shrink-0 text-primary\">\n {feature.icon}\n </div>\n <div>\n <h3 className=\"font-semibold\">{feature.title}</h3>\n <p className=\"text-sm text-muted-foreground\">\n {feature.description}\n </p>\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n </>\n );\n}\n\n// ============================================================================\n// NEWSLETTER FORM (Inline Component)\n// ============================================================================\n\nexport interface NewsletterFormProps {\n /**\n * Layout variant\n * @default 'inline'\n */\n variant?: \"inline\" | \"stacked\";\n /**\n * Show email label\n * @default false\n */\n showLabel?: boolean;\n /**\n * Show description text\n * @default false\n */\n showDescription?: boolean;\n /**\n * Description text\n * @default 'Subscribe to our newsletter for updates'\n */\n description?: string;\n /**\n * Button text\n * @default 'Subscribe'\n */\n buttonText?: string;\n /**\n * Custom CSS class\n */\n className?: string;\n /**\n * reCAPTCHA site key (optional, falls back to SDK config)\n */\n recaptchaSiteKey?: string;\n}\n\n/**\n * Lightweight newsletter subscription form for inline use (e.g., footers)\n */\nexport function NewsletterForm({\n variant = \"inline\",\n showLabel = false,\n showDescription = false,\n description = \"Subscribe to our newsletter for updates\",\n buttonText = \"Subscribe\",\n className = \"\",\n recaptchaSiteKey,\n}: NewsletterFormProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const productConfig = useProductConfig();\n const effectiveProductId = product?.id || config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n productConfig.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [email, setEmail] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!email || !email.includes(\"@\")) {\n toast.error(\"Please enter a valid email address\");\n return;\n }\n\n // Check reCAPTCHA\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n\n setIsLoading(true);\n\n try {\n const result = await subscribeNewsletter(\n client,\n email,\n effectiveProductId,\n recaptchaToken || undefined,\n );\n\n if (result.success) {\n if (result.message) {\n toast.info(result.message);\n } else {\n toast.success(\"Successfully subscribed!\");\n }\n setEmail(\"\");\n } else {\n toast.error(result.message ?? \"Subscription failed\");\n }\n recaptchaRef.current?.reset();\n } catch (_error) {\n toast.error(\"An error occurred. Please try again.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsLoading(false);\n }\n };\n\n const isInline = variant === \"inline\";\n\n return (\n <div className={className} style={{ overflow: \"visible\" }}>\n {showDescription && (\n <p className=\"text-sm text-muted-foreground mb-3\">{description}</p>\n )}\n <form\n onSubmit={handleSubmit}\n className={isInline ? \"flex flex-col gap-2\" : \"flex flex-col gap-2\"}\n style={{ overflow: \"visible\" }}\n >\n <div\n className={\n isInline && !effectiveRecaptchaSiteKey\n ? \"flex gap-2\"\n : \"flex flex-col gap-2\"\n }\n >\n <div\n className={\n isInline && !effectiveRecaptchaSiteKey ? \"flex-1\" : \"w-full\"\n }\n >\n {showLabel && (\n <Label htmlFor=\"newsletter-email\" className=\"text-sm mb-1 block\">\n Email\n </Label>\n )}\n <Input\n id=\"newsletter-email\"\n type=\"email\"\n placeholder=\"Enter your email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n disabled={isLoading}\n required\n className=\"w-full\"\n />\n </div>\n {!effectiveRecaptchaSiteKey && (\n <Button\n type=\"submit\"\n disabled={isLoading}\n className={isInline ? \"whitespace-nowrap\" : \"w-full\"}\n >\n {isLoading ? \"Subscribing...\" : buttonText}\n </Button>\n )}\n </div>\n {effectiveRecaptchaSiteKey && (\n <>\n <style>{`\n body > div[style*=\"position: absolute\"] > div > iframe[title*=\"recaptcha challenge\"],\n body > div:not([class]):not([id]) > div > iframe[title*=\"recaptcha\"] {\n position: fixed !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%) !important;\n z-index: 99999 !important;\n }\n body > div[style*=\"position: absolute\"]:has(iframe[title*=\"recaptcha challenge\"]) {\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n width: 100vw !important;\n height: 100vh !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n z-index: 99999 !important;\n background: rgba(0,0,0,0.3) !important;\n }\n `}</style>\n <div\n style={{\n position: \"relative\",\n zIndex: 50,\n display: \"flex\",\n justifyContent: \"flex-start\",\n }}\n >\n {/* Normal size (not the cramped compact square), left-aligned to\n the form fields' edge so it reads as a standard checkbox. */}\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n size=\"normal\"\n />\n </div>\n </>\n )}\n {effectiveRecaptchaSiteKey && (\n <Button type=\"submit\" disabled={isLoading} className=\"w-full\">\n {isLoading ? \"Subscribing...\" : buttonText}\n </Button>\n )}\n </form>\n </div>\n );\n}\n"]}