@fluid-app/portal-sdk 0.1.239 → 0.1.241

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 (83) hide show
  1. package/dist/{CalendarWidget-BXxNxHDV.mjs → CalendarWidget-C03VcDLQ.mjs} +2 -2
  2. package/dist/{CalendarWidget-BXxNxHDV.mjs.map → CalendarWidget-C03VcDLQ.mjs.map} +1 -1
  3. package/dist/{CalendarWidget-VjQXZW8B.cjs → CalendarWidget-C4Dv_TUk.cjs} +2 -2
  4. package/dist/{CalendarWidget-VjQXZW8B.cjs.map → CalendarWidget-C4Dv_TUk.cjs.map} +1 -1
  5. package/dist/{CardWidget-BNkMlxQ3.mjs → CardWidget-2wcjCf2M.mjs} +2 -2
  6. package/dist/{CardWidget-BNkMlxQ3.mjs.map → CardWidget-2wcjCf2M.mjs.map} +1 -1
  7. package/dist/{CardWidget-CraWMttj.cjs → CardWidget-BQl-8Xrt.cjs} +3 -3
  8. package/dist/{CardWidget-C3I9OwgS.cjs → CardWidget-D-KEikO_.cjs} +2 -2
  9. package/dist/{CardWidget-C3I9OwgS.cjs.map → CardWidget-D-KEikO_.cjs.map} +1 -1
  10. package/dist/{CarouselWidget-p8Z6L-G5.mjs → CarouselWidget-Cn5P4FVN.mjs} +92 -83
  11. package/dist/CarouselWidget-Cn5P4FVN.mjs.map +1 -0
  12. package/dist/{CarouselWidget-CiKlooUF.cjs → CarouselWidget-Cu1b3ERq.cjs} +92 -83
  13. package/dist/CarouselWidget-Cu1b3ERq.cjs.map +1 -0
  14. package/dist/{CatchUpWidget-B9DQlzd_.mjs → CatchUpWidget-B9CI7lq0.mjs} +2 -2
  15. package/dist/{CatchUpWidget-B9DQlzd_.mjs.map → CatchUpWidget-B9CI7lq0.mjs.map} +1 -1
  16. package/dist/{CatchUpWidget-SY7hOHk6.cjs → CatchUpWidget-BzgybvuC.cjs} +2 -2
  17. package/dist/{CatchUpWidget-SY7hOHk6.cjs.map → CatchUpWidget-BzgybvuC.cjs.map} +1 -1
  18. package/dist/ContainerWidget-CDbB8c0E.cjs +8 -0
  19. package/dist/{ContainerWidget-CpwvcxFm.mjs → ContainerWidget-DNenbORS.mjs} +2 -2
  20. package/dist/{ContainerWidget-CpwvcxFm.mjs.map → ContainerWidget-DNenbORS.mjs.map} +1 -1
  21. package/dist/{ContainerWidget-BXpdj06u.cjs → ContainerWidget-DbAhQKbY.cjs} +2 -2
  22. package/dist/{ContainerWidget-BXpdj06u.cjs.map → ContainerWidget-DbAhQKbY.cjs.map} +1 -1
  23. package/dist/{FluidProvider-DL5rChtj.mjs → FluidProvider-BwMwMCxW.mjs} +23 -23
  24. package/dist/{FluidProvider-DL5rChtj.mjs.map → FluidProvider-BwMwMCxW.mjs.map} +1 -1
  25. package/dist/{FluidProvider-D_PHVlUU.cjs → FluidProvider-eT4gA6Io.cjs} +23 -23
  26. package/dist/{FluidProvider-D_PHVlUU.cjs.map → FluidProvider-eT4gA6Io.cjs.map} +1 -1
  27. package/dist/{LayoutWidget-BIfNHlVE.cjs → LayoutWidget-Bt2I2XMy.cjs} +2 -2
  28. package/dist/{LayoutWidget-BIfNHlVE.cjs.map → LayoutWidget-Bt2I2XMy.cjs.map} +1 -1
  29. package/dist/{LayoutWidget-LdF_cKrB.cjs → LayoutWidget-DKqZgCMu.cjs} +3 -3
  30. package/dist/{LayoutWidget-CC3oK78H.mjs → LayoutWidget-UI5fbsx4.mjs} +2 -2
  31. package/dist/{LayoutWidget-CC3oK78H.mjs.map → LayoutWidget-UI5fbsx4.mjs.map} +1 -1
  32. package/dist/{MessagingScreen-Dxy2VQbO.cjs → MessagingScreen-BHYX1Kc6.cjs} +14 -14
  33. package/dist/{MessagingScreen-mt1u3Bs1.mjs → MessagingScreen-CZddjqma.mjs} +2 -2
  34. package/dist/{MessagingScreen-mt1u3Bs1.mjs.map → MessagingScreen-CZddjqma.mjs.map} +1 -1
  35. package/dist/{MessagingScreen-Dkh3Dsp7.cjs → MessagingScreen-D3S230Ba.cjs} +2 -2
  36. package/dist/{MessagingScreen-Dkh3Dsp7.cjs.map → MessagingScreen-D3S230Ba.cjs.map} +1 -1
  37. package/dist/{MySiteWidget-BnjPrQxE.mjs → MySiteWidget-CQNASVaF.mjs} +2 -2
  38. package/dist/{MySiteWidget-BnjPrQxE.mjs.map → MySiteWidget-CQNASVaF.mjs.map} +1 -1
  39. package/dist/{MySiteWidget-C8eFWHOT.cjs → MySiteWidget-CYiH2lmX.cjs} +2 -2
  40. package/dist/{MySiteWidget-C8eFWHOT.cjs.map → MySiteWidget-CYiH2lmX.cjs.map} +1 -1
  41. package/dist/{PointsWidget-C2KB4k48.mjs → PointsWidget-BwA6aGVZ.mjs} +5 -8
  42. package/dist/PointsWidget-BwA6aGVZ.mjs.map +1 -0
  43. package/dist/{PointsWidget-DLp-PYus.cjs → PointsWidget-D1FV8l1h.cjs} +5 -8
  44. package/dist/PointsWidget-D1FV8l1h.cjs.map +1 -0
  45. package/dist/{ProfileScreen-ChCZZ91o.cjs → ProfileScreen-BYJj4D1W.cjs} +14 -14
  46. package/dist/{ProfileScreen-BMe-dQi7.cjs → ProfileScreen-DAujb81k.cjs} +2 -2
  47. package/dist/{ProfileScreen-BMe-dQi7.cjs.map → ProfileScreen-DAujb81k.cjs.map} +1 -1
  48. package/dist/{ProfileScreen-_1GlBr7z.mjs → ProfileScreen-DlMEqXXg.mjs} +2 -2
  49. package/dist/{ProfileScreen-_1GlBr7z.mjs.map → ProfileScreen-DlMEqXXg.mjs.map} +1 -1
  50. package/dist/{RecentActivityWidget-DelPdiwR.mjs → RecentActivityWidget-D1AlZgfV.mjs} +2 -2
  51. package/dist/{RecentActivityWidget-DelPdiwR.mjs.map → RecentActivityWidget-D1AlZgfV.mjs.map} +1 -1
  52. package/dist/{RecentActivityWidget-BNW9aFT4.cjs → RecentActivityWidget-DNyhUZNs.cjs} +2 -2
  53. package/dist/{RecentActivityWidget-BNW9aFT4.cjs.map → RecentActivityWidget-DNyhUZNs.cjs.map} +1 -1
  54. package/dist/{ScreenRenderer-ClYgfQf_.mjs → ScreenRenderer-Cl2aAJ7D.mjs} +2 -2
  55. package/dist/{ScreenRenderer-ClYgfQf_.mjs.map → ScreenRenderer-Cl2aAJ7D.mjs.map} +1 -1
  56. package/dist/{ScreenRenderer-Ct1w4PNu.cjs → ScreenRenderer-xH01YkEQ.cjs} +2 -2
  57. package/dist/{ScreenRenderer-Ct1w4PNu.cjs.map → ScreenRenderer-xH01YkEQ.cjs.map} +1 -1
  58. package/dist/{ShopScreen-DWLGH2gt.cjs → ShopScreen-1yvcCk7l.cjs} +6 -2
  59. package/dist/ShopScreen-1yvcCk7l.cjs.map +1 -0
  60. package/dist/{ShopScreen-CZ_290EP.cjs → ShopScreen-6nEKrNjK.cjs} +14 -14
  61. package/dist/{ShopScreen-BBfOte5o.mjs → ShopScreen-U7G6Jf67.mjs} +6 -2
  62. package/dist/ShopScreen-U7G6Jf67.mjs.map +1 -0
  63. package/dist/{ToDoWidget-CYDsZA0Z.mjs → ToDoWidget-BciI_D70.mjs} +2 -2
  64. package/dist/{ToDoWidget-CYDsZA0Z.mjs.map → ToDoWidget-BciI_D70.mjs.map} +1 -1
  65. package/dist/{ToDoWidget-Bjoan2Rm.cjs → ToDoWidget-OxT9z59F.cjs} +2 -2
  66. package/dist/{ToDoWidget-Bjoan2Rm.cjs.map → ToDoWidget-OxT9z59F.cjs.map} +1 -1
  67. package/dist/{ToDoWidget-C_CvWdLi.cjs → ToDoWidget-mSGQgnu3.cjs} +2 -2
  68. package/dist/index.cjs +22 -22
  69. package/dist/index.d.cts.map +1 -1
  70. package/dist/index.d.mts.map +1 -1
  71. package/dist/index.mjs +22 -22
  72. package/dist/{registry-context-BahYMRqn.mjs → registry-context-CTHUCfEc.mjs} +6 -5
  73. package/dist/{registry-context-bf52ZIJX.cjs.map → registry-context-CTHUCfEc.mjs.map} +1 -1
  74. package/dist/{registry-context-bf52ZIJX.cjs → registry-context-CcZYS15Q.cjs} +6 -5
  75. package/dist/{registry-context-BahYMRqn.mjs.map → registry-context-CcZYS15Q.cjs.map} +1 -1
  76. package/package.json +10 -10
  77. package/dist/CarouselWidget-CiKlooUF.cjs.map +0 -1
  78. package/dist/CarouselWidget-p8Z6L-G5.mjs.map +0 -1
  79. package/dist/ContainerWidget-CyfPYEAv.cjs +0 -8
  80. package/dist/PointsWidget-C2KB4k48.mjs.map +0 -1
  81. package/dist/PointsWidget-DLp-PYus.cjs.map +0 -1
  82. package/dist/ShopScreen-BBfOte5o.mjs.map +0 -1
  83. package/dist/ShopScreen-DWLGH2gt.cjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as __exportAll } from "./es-BXxGlAp6.mjs";
2
- import { n as useDataSourceRegistryConfig } from "./registry-context-BahYMRqn.mjs";
2
+ import { n as useDataSourceRegistryConfig } from "./registry-context-CTHUCfEc.mjs";
3
3
  import { i as useWidgetsApi, n as useWidgetPreviewContext, t as ErrorState } from "./error-state-DYzHx8tt.mjs";
4
4
  import { l as getColorField, o as getBorderRadiusField } from "./registries-Ct8o2YRe.mjs";
5
5
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -557,4 +557,4 @@ const mySiteWidgetPropertySchema = {
557
557
  //#endregion
558
558
  export { MySiteWidget_exports as n, mySiteWidgetPropertySchema as r, MySiteWidget as t };
559
559
 
560
- //# sourceMappingURL=MySiteWidget-BnjPrQxE.mjs.map
560
+ //# sourceMappingURL=MySiteWidget-CQNASVaF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MySiteWidget-BnjPrQxE.mjs","names":[],"sources":["../../widgets/src/hooks/use-mysite.preview.ts","../../widgets/src/hooks/use-mysite.ts","../../widgets/src/widgets/MySiteWidget.tsx"],"sourcesContent":["import type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const PREVIEW_DATA: MySiteData = {\n url: \"https://mysite.example.com\",\n views: 1248,\n leads: 43,\n userName: \"Jane\",\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-mysite.preview\";\nimport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useMySite(): UseQueryResult<MySiteData, Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: [\n \"portal-widget-use\",\n \"mysite\",\n isPreview ? \"preview\" : baseUrl,\n ] as const,\n queryFn: ({ signal }) => widgetsApi.fetchMySite(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { getBorderRadiusField, getColorField } from \"../core/fields\";\nimport { useMySite, type MySiteData } from \"../hooks/use-mysite\";\nimport { ErrorState } from \"../components/error-state\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { ArrowUpRight, Check, Copy, Globe } from \"lucide-react\";\n\ntype MySiteWidgetProps = ComponentProps<\"div\"> & {\n // Design\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display toggles\n showPreview?: boolean;\n showAnalytics?: boolean;\n showLiveBadge?: boolean;\n showQR?: boolean;\n};\n\nconst formatCompactNumber = (n: number | undefined): string => {\n const value = n ?? 0;\n if (value < 1000) return value.toLocaleString();\n if (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n if (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n return `${(value / 1_000_000).toFixed(1)}m`;\n};\n\nconst splitUrl = (url: string): { prefix: string; path: string } => {\n try {\n const parsed = new URL(url);\n return {\n prefix: `${parsed.protocol}//${parsed.host}`,\n path:\n `${parsed.pathname}${parsed.search}${parsed.hash}`.replace(\n /^\\/$/,\n \"\",\n ) || \"\",\n };\n } catch {\n return { prefix: \"\", path: url };\n }\n};\n\nexport function MySiteWidget({\n background = { type: \"solid\", color: \"background\" },\n textColor = \"foreground\",\n accentColor = \"primary\",\n borderRadius = \"xl\",\n\n showPreview = true,\n showAnalytics = true,\n showLiveBadge = true,\n showQR = true,\n\n className,\n ...props\n}: MySiteWidgetProps): React.JSX.Element | null {\n const { copyState, markCopied } = useTimedCopyState(1600);\n const { rootRef: widgetRootRef, isWide } = useIsContainerWide(720);\n const {\n frameRef: previewFrameRef,\n scale,\n iframeHeight,\n } = useScaledIframePreview({\n viewportWidth: 1280,\n minIframeHeight: 500,\n });\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n const { data: mySite, isLoading, isError } = useMySite();\n const { isPreview } = useWidgetPreviewContext();\n const realMySite = useRealMySiteData(mySite, isPreview);\n const { hasRealSite, url, views, leads } = realMySite;\n const { previewUrl, hostLabel, urlPrefix, urlPath } =\n useMySiteDisplayUrls(url);\n const showDashboardLayout = isWide && hasRealSite;\n const showStats = showAnalytics && hasRealSite;\n const showFooter = hasRealSite;\n\n const handleCopy = async () => {\n if (!url) return;\n try {\n await navigator.clipboard.writeText(url);\n markCopied();\n } catch (error) {\n console.error(\"Failed to copy MySite URL:\", error);\n }\n };\n\n if (!isLoading && !isError && !isPreview && !hasRealSite) {\n return null;\n }\n\n // Hairline divider color — subtle, theme-aware\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div\n ref={widgetRootRef}\n className={`@container relative overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n style={{\n backgroundImage,\n boxShadow: `0 1px 2px rgba(15,23,42,0.04), 0 20px 40px -24px rgba(15,23,42,0.16), inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 7%, transparent)`,\n }}\n {...props}\n >\n {isLoading ? (\n <MySiteSkeleton\n textColor={textColor}\n accentColor={accentColor}\n borderRadius={borderRadius}\n />\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState />\n </div>\n ) : showDashboardLayout ? (\n <div className=\"flex items-stretch\">\n {/* Left: site preview */}\n {showPreview && (\n <div\n className=\"relative isolate shrink-0 bg-white\"\n style={{\n width: \"45%\",\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <div\n ref={previewFrameRef}\n className=\"relative h-full w-full overflow-hidden bg-white\"\n >\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {showLiveBadge && (\n <div className=\"absolute top-4 left-4\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Right: dashboard column */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-3.5 p-5 sm:p-6\">\n <div>\n <span\n className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n >\n Your Storefront\n </span>\n <h2\n className={`mt-1 text-[22px] leading-[1.1] font-bold tracking-[-0.02em] text-${textColor}`}\n >\n You&rsquo;re live\n </h2>\n </div>\n\n {hasRealSite && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex items-center gap-2.5 rounded-${borderRadius} px-3 py-2 text-[13px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <Globe className={`size-3.5 shrink-0 text-${textColor}/55`} />\n <span\n className={`min-w-0 flex-1 truncate text-left font-semibold tabular-nums text-${textColor}`}\n >\n {hostLabel}\n {urlPath}\n </span>\n <span\n className={`flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor} text-${backgroundColor}`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n )}\n\n {showStats && (\n <>\n <div\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Visitors\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(views)}\n </div>\n </div>\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Leads\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(leads)}\n </div>\n </div>\n </div>\n </>\n )}\n\n {hasRealSite && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`group/visit mt-auto inline-flex items-center justify-between gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_12px_28px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <span>Open the live site</span>\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n )}\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* Card body: site preview — flush to the top of the card */}\n {showPreview && (hasRealSite || isPreview) && (\n <div className=\"relative isolate bg-white\">\n <div\n ref={previewFrameRef}\n className=\"relative aspect-[16/10] w-full overflow-hidden bg-white\"\n >\n {isPreview || !hasRealSite ? (\n <MySitePreviewPlaceholder hostLabel={hostLabel} />\n ) : (\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n )}\n {/* Very subtle top-edge sheen for polish */}\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {/* LIVE badge — quiet, not blinking */}\n {showLiveBadge && hasRealSite && (\n <div className=\"absolute top-3 right-3\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2 py-1 text-[9px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Card footer — distinct tinted surface, QR column + right column */}\n {showFooter && (\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR column — spans the full footer height */}\n {showQR && hasRealSite && (\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`flex flex-col items-center gap-1.5 rounded-${borderRadius} bg-white p-2.5`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.05), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n role=\"img\"\n aria-label=\"QR code for your site\"\n >\n <QRCodeSVG\n value={url}\n size={64}\n level=\"H\"\n bgColor=\"#ffffff\"\n fgColor=\"#0f172a\"\n />\n </div>\n </div>\n )}\n\n {/* Right column */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Stats row */}\n {showStats && (\n <div className=\"grid grid-cols-2\">\n <StatCell\n label=\"Visitors\"\n value={formatCompactNumber(views)}\n textColor={textColor}\n />\n <StatCell\n label=\"Leads\"\n value={formatCompactNumber(leads)}\n textColor={textColor}\n leftDivider\n />\n </div>\n )}\n\n {/* Action row */}\n {hasRealSite && (\n <div\n className=\"flex items-center gap-2 px-4 py-3\"\n style={showStats ? divider : undefined}\n >\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex min-w-0 flex-1 items-center justify-between gap-2 rounded-${borderRadius} px-3 py-2 text-left text-[12px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <span\n className={`min-w-0 flex-1 truncate font-medium text-${textColor}`}\n >\n {urlPrefix && (\n <span className={`text-${textColor}/45`}>\n {urlPrefix}\n </span>\n )}\n <span className=\"font-semibold\">{urlPath || \"/\"}</span>\n </span>\n <span\n className={`flex size-6 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `scale-105 bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor}/10 text-${textColor} group-hover/copy:bg-${textColor}/20`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Visit site\"\n className={`group/visit inline-flex size-9 shrink-0 items-center justify-center rounded-${borderRadius} bg-${accentColor} text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_10px_24px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ntype MySitePreviewPlaceholderProps = {\n hostLabel: string;\n};\n\n// Static placeholder shown in builder/preview contexts. Preview mode keeps\n// placeholder API values out of visible widget content.\nfunction MySitePreviewPlaceholder({\n hostLabel,\n}: MySitePreviewPlaceholderProps): React.JSX.Element {\n return (\n <div className=\"bg-muted/30 absolute inset-0 flex flex-col items-center justify-center gap-3 p-4 text-center\">\n <div className=\"bg-muted flex h-10 w-10 items-center justify-center rounded-full\">\n <Globe className=\"text-muted-foreground h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-foreground text-sm font-medium\">My Site</p>\n {hostLabel && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{hostLabel}</p>\n )}\n </div>\n </div>\n );\n}\n\ntype StatCellProps = {\n label: string;\n value: string;\n textColor: ColorOptions;\n leftDivider?: boolean;\n};\n\nfunction StatCell({ label, value, textColor, leftDivider }: StatCellProps) {\n const leftDividerStyle: CSSProperties | undefined = leftDivider\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-1.5 px-5 py-4\" style={leftDividerStyle}>\n <span\n className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n >\n {label}\n </span>\n <span\n className={`text-[22px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {value}\n </span>\n </div>\n );\n}\n\ntype MySiteSkeletonProps = {\n textColor: ColorOptions;\n accentColor: ColorOptions;\n borderRadius: BorderRadiusOptions;\n};\n\nfunction MySiteSkeleton({\n textColor,\n accentColor,\n borderRadius,\n}: MySiteSkeletonProps) {\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div className=\"flex animate-pulse flex-col\" aria-busy=\"true\">\n <div\n className={`relative aspect-[16/10] w-full overflow-hidden bg-${textColor}/5`}\n />\n\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR placeholder column */}\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`size-[84px] rounded-${borderRadius} bg-${textColor}/10`}\n />\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"grid grid-cols-2\">\n {[0, 1].map((i) => (\n <div\n key={i}\n className=\"flex flex-col gap-2 px-5 py-4\"\n style={\n i > 0\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined\n }\n >\n <div className={`h-2 w-14 rounded-full bg-${textColor}/10`} />\n <div className={`h-5 w-16 rounded-full bg-${textColor}/15`} />\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2 px-4 py-3\" style={divider}>\n <div\n className={`h-8 flex-1 rounded-${borderRadius} bg-${textColor}/10`}\n />\n <div\n className={`size-9 shrink-0 rounded-${borderRadius} bg-${accentColor}/30`}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ----- Hooks -----\n\ntype CopyState = \"idle\" | \"copied\";\n\nfunction useRealMySiteData(mySite: MySiteData | undefined, isPreview: boolean) {\n return useMemo(() => {\n if (isPreview || !mySite?.url) {\n return {\n hasRealSite: false,\n url: \"\",\n views: 0,\n leads: 0,\n userName: \"\",\n };\n }\n\n return {\n hasRealSite: true,\n url: mySite.url,\n views: mySite.views,\n leads: mySite.leads,\n userName: mySite.userName,\n };\n }, [isPreview, mySite]);\n}\n\nfunction useMySiteDisplayUrls(url: string) {\n const previewUrl = useMemo(() => {\n if (!url) return \"\";\n try {\n const urlObj = new URL(url);\n urlObj.searchParams.set(\"preview\", \"true\");\n return urlObj.toString();\n } catch {\n return url;\n }\n }, [url]);\n\n const hostLabel = useMemo(() => {\n if (!url) return \"\";\n try {\n return new URL(url).host;\n } catch {\n return url.replace(/^https?:\\/\\//, \"\");\n }\n }, [url]);\n\n const { prefix: urlPrefix, path: urlPath } = useMemo(\n () => (url ? splitUrl(url) : { prefix: \"\", path: \"\" }),\n [url],\n );\n\n return { previewUrl, hostLabel, urlPrefix, urlPath };\n}\n\nfunction useTimedCopyState(timeoutMs: number) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n\n useEffect(() => {\n if (copyState !== \"copied\") return;\n const id = window.setTimeout(() => setCopyState(\"idle\"), timeoutMs);\n return () => window.clearTimeout(id);\n }, [copyState, timeoutMs]);\n\n const markCopied = useCallback(() => {\n setCopyState(\"copied\");\n }, []);\n\n return { copyState, markCopied };\n}\n\n// useLayoutEffect warns on the server. Widgets are client-rendered, but guard\n// for parity with the rest of the codebase.\nconst useIsoLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n// Switches to a \"wide\" layout once the container reaches `threshold` px.\n// Uses useLayoutEffect so the initial measurement and state-flip land\n// synchronously before paint, avoiding a narrow→wide flash on mount.\nfunction useIsContainerWide(threshold: number) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [isWide, setIsWide] = useState(false);\n\n useIsoLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n const update = () => setIsWide(el.clientWidth >= threshold);\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [threshold]);\n\n return { rootRef, isWide };\n}\n\ntype ScaledIframePreviewOptions = {\n viewportWidth: number;\n minIframeHeight: number;\n};\n\n// Renders the iframe at a real desktop viewport (`viewportWidth`) and scales\n// it to fit the actual container. The iframe's rendered height is computed\n// dynamically so it fills the container in both aspect-locked compact mode\n// AND the height-driven wide mode (no whitespace gap below the preview).\nfunction useScaledIframePreview({\n viewportWidth,\n minIframeHeight,\n}: ScaledIframePreviewOptions) {\n const [metrics, setMetrics] = useState({\n scale: 0.5,\n iframeHeight: minIframeHeight,\n });\n\n const frameRef = useCallback(\n (el: HTMLDivElement | null) => {\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) {\n const scale = w / viewportWidth;\n const iframeHeight = Math.max(minIframeHeight, h / scale);\n setMetrics((prev) =>\n prev.scale === scale && prev.iframeHeight === iframeHeight\n ? prev\n : { scale, iframeHeight },\n );\n }\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n },\n [viewportWidth, minIframeHeight],\n );\n\n return { frameRef, scale: metrics.scale, iframeHeight: metrics.iframeHeight };\n}\n\nexport const mySiteWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"MySiteWidget\",\n displayName: \"MySite Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Display group\n {\n key: \"showPreview\",\n label: \"Show Site Preview\",\n type: \"boolean\",\n description: \"Show the live iframe preview of the storefront\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showAnalytics\",\n label: \"Show Stats\",\n type: \"boolean\",\n description: \"Visitors and Leads grid in the footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showLiveBadge\",\n label: \"Show LIVE Badge\",\n type: \"boolean\",\n description: \"Small 'Live' chip in the preview corner\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showQR\",\n label: \"Show QR Code\",\n type: \"boolean\",\n description: \"Show a scannable QR code in the card footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Primary text, hairline, and neutral chip color\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Drives the Live dot, conversion ring, and Visit CTA\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Corner radius for the widget and inner chips\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
1
+ {"version":3,"file":"MySiteWidget-CQNASVaF.mjs","names":[],"sources":["../../widgets/src/hooks/use-mysite.preview.ts","../../widgets/src/hooks/use-mysite.ts","../../widgets/src/widgets/MySiteWidget.tsx"],"sourcesContent":["import type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const PREVIEW_DATA: MySiteData = {\n url: \"https://mysite.example.com\",\n views: 1248,\n leads: 43,\n userName: \"Jane\",\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-mysite.preview\";\nimport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useMySite(): UseQueryResult<MySiteData, Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: [\n \"portal-widget-use\",\n \"mysite\",\n isPreview ? \"preview\" : baseUrl,\n ] as const,\n queryFn: ({ signal }) => widgetsApi.fetchMySite(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { getBorderRadiusField, getColorField } from \"../core/fields\";\nimport { useMySite, type MySiteData } from \"../hooks/use-mysite\";\nimport { ErrorState } from \"../components/error-state\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { ArrowUpRight, Check, Copy, Globe } from \"lucide-react\";\n\ntype MySiteWidgetProps = ComponentProps<\"div\"> & {\n // Design\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display toggles\n showPreview?: boolean;\n showAnalytics?: boolean;\n showLiveBadge?: boolean;\n showQR?: boolean;\n};\n\nconst formatCompactNumber = (n: number | undefined): string => {\n const value = n ?? 0;\n if (value < 1000) return value.toLocaleString();\n if (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n if (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n return `${(value / 1_000_000).toFixed(1)}m`;\n};\n\nconst splitUrl = (url: string): { prefix: string; path: string } => {\n try {\n const parsed = new URL(url);\n return {\n prefix: `${parsed.protocol}//${parsed.host}`,\n path:\n `${parsed.pathname}${parsed.search}${parsed.hash}`.replace(\n /^\\/$/,\n \"\",\n ) || \"\",\n };\n } catch {\n return { prefix: \"\", path: url };\n }\n};\n\nexport function MySiteWidget({\n background = { type: \"solid\", color: \"background\" },\n textColor = \"foreground\",\n accentColor = \"primary\",\n borderRadius = \"xl\",\n\n showPreview = true,\n showAnalytics = true,\n showLiveBadge = true,\n showQR = true,\n\n className,\n ...props\n}: MySiteWidgetProps): React.JSX.Element | null {\n const { copyState, markCopied } = useTimedCopyState(1600);\n const { rootRef: widgetRootRef, isWide } = useIsContainerWide(720);\n const {\n frameRef: previewFrameRef,\n scale,\n iframeHeight,\n } = useScaledIframePreview({\n viewportWidth: 1280,\n minIframeHeight: 500,\n });\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n const { data: mySite, isLoading, isError } = useMySite();\n const { isPreview } = useWidgetPreviewContext();\n const realMySite = useRealMySiteData(mySite, isPreview);\n const { hasRealSite, url, views, leads } = realMySite;\n const { previewUrl, hostLabel, urlPrefix, urlPath } =\n useMySiteDisplayUrls(url);\n const showDashboardLayout = isWide && hasRealSite;\n const showStats = showAnalytics && hasRealSite;\n const showFooter = hasRealSite;\n\n const handleCopy = async () => {\n if (!url) return;\n try {\n await navigator.clipboard.writeText(url);\n markCopied();\n } catch (error) {\n console.error(\"Failed to copy MySite URL:\", error);\n }\n };\n\n if (!isLoading && !isError && !isPreview && !hasRealSite) {\n return null;\n }\n\n // Hairline divider color — subtle, theme-aware\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div\n ref={widgetRootRef}\n className={`@container relative overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n style={{\n backgroundImage,\n boxShadow: `0 1px 2px rgba(15,23,42,0.04), 0 20px 40px -24px rgba(15,23,42,0.16), inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 7%, transparent)`,\n }}\n {...props}\n >\n {isLoading ? (\n <MySiteSkeleton\n textColor={textColor}\n accentColor={accentColor}\n borderRadius={borderRadius}\n />\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState />\n </div>\n ) : showDashboardLayout ? (\n <div className=\"flex items-stretch\">\n {/* Left: site preview */}\n {showPreview && (\n <div\n className=\"relative isolate shrink-0 bg-white\"\n style={{\n width: \"45%\",\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <div\n ref={previewFrameRef}\n className=\"relative h-full w-full overflow-hidden bg-white\"\n >\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {showLiveBadge && (\n <div className=\"absolute top-4 left-4\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Right: dashboard column */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-3.5 p-5 sm:p-6\">\n <div>\n <span\n className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n >\n Your Storefront\n </span>\n <h2\n className={`mt-1 text-[22px] leading-[1.1] font-bold tracking-[-0.02em] text-${textColor}`}\n >\n You&rsquo;re live\n </h2>\n </div>\n\n {hasRealSite && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex items-center gap-2.5 rounded-${borderRadius} px-3 py-2 text-[13px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <Globe className={`size-3.5 shrink-0 text-${textColor}/55`} />\n <span\n className={`min-w-0 flex-1 truncate text-left font-semibold tabular-nums text-${textColor}`}\n >\n {hostLabel}\n {urlPath}\n </span>\n <span\n className={`flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor} text-${backgroundColor}`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n )}\n\n {showStats && (\n <>\n <div\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Visitors\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(views)}\n </div>\n </div>\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Leads\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(leads)}\n </div>\n </div>\n </div>\n </>\n )}\n\n {hasRealSite && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`group/visit mt-auto inline-flex items-center justify-between gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_12px_28px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <span>Open the live site</span>\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n )}\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* Card body: site preview — flush to the top of the card */}\n {showPreview && (hasRealSite || isPreview) && (\n <div className=\"relative isolate bg-white\">\n <div\n ref={previewFrameRef}\n className=\"relative aspect-[16/10] w-full overflow-hidden bg-white\"\n >\n {isPreview || !hasRealSite ? (\n <MySitePreviewPlaceholder hostLabel={hostLabel} />\n ) : (\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n )}\n {/* Very subtle top-edge sheen for polish */}\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {/* LIVE badge — quiet, not blinking */}\n {showLiveBadge && hasRealSite && (\n <div className=\"absolute top-3 right-3\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2 py-1 text-[9px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Card footer — distinct tinted surface, QR column + right column */}\n {showFooter && (\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR column — spans the full footer height */}\n {showQR && hasRealSite && (\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`flex flex-col items-center gap-1.5 rounded-${borderRadius} bg-white p-2.5`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.05), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n role=\"img\"\n aria-label=\"QR code for your site\"\n >\n <QRCodeSVG\n value={url}\n size={64}\n level=\"H\"\n bgColor=\"#ffffff\"\n fgColor=\"#0f172a\"\n />\n </div>\n </div>\n )}\n\n {/* Right column */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Stats row */}\n {showStats && (\n <div className=\"grid grid-cols-2\">\n <StatCell\n label=\"Visitors\"\n value={formatCompactNumber(views)}\n textColor={textColor}\n />\n <StatCell\n label=\"Leads\"\n value={formatCompactNumber(leads)}\n textColor={textColor}\n leftDivider\n />\n </div>\n )}\n\n {/* Action row */}\n {hasRealSite && (\n <div\n className=\"flex items-center gap-2 px-4 py-3\"\n style={showStats ? divider : undefined}\n >\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex min-w-0 flex-1 items-center justify-between gap-2 rounded-${borderRadius} px-3 py-2 text-left text-[12px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <span\n className={`min-w-0 flex-1 truncate font-medium text-${textColor}`}\n >\n {urlPrefix && (\n <span className={`text-${textColor}/45`}>\n {urlPrefix}\n </span>\n )}\n <span className=\"font-semibold\">{urlPath || \"/\"}</span>\n </span>\n <span\n className={`flex size-6 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `scale-105 bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor}/10 text-${textColor} group-hover/copy:bg-${textColor}/20`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Visit site\"\n className={`group/visit inline-flex size-9 shrink-0 items-center justify-center rounded-${borderRadius} bg-${accentColor} text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_10px_24px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ntype MySitePreviewPlaceholderProps = {\n hostLabel: string;\n};\n\n// Static placeholder shown in builder/preview contexts. Preview mode keeps\n// placeholder API values out of visible widget content.\nfunction MySitePreviewPlaceholder({\n hostLabel,\n}: MySitePreviewPlaceholderProps): React.JSX.Element {\n return (\n <div className=\"bg-muted/30 absolute inset-0 flex flex-col items-center justify-center gap-3 p-4 text-center\">\n <div className=\"bg-muted flex h-10 w-10 items-center justify-center rounded-full\">\n <Globe className=\"text-muted-foreground h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-foreground text-sm font-medium\">My Site</p>\n {hostLabel && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{hostLabel}</p>\n )}\n </div>\n </div>\n );\n}\n\ntype StatCellProps = {\n label: string;\n value: string;\n textColor: ColorOptions;\n leftDivider?: boolean;\n};\n\nfunction StatCell({ label, value, textColor, leftDivider }: StatCellProps) {\n const leftDividerStyle: CSSProperties | undefined = leftDivider\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-1.5 px-5 py-4\" style={leftDividerStyle}>\n <span\n className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n >\n {label}\n </span>\n <span\n className={`text-[22px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {value}\n </span>\n </div>\n );\n}\n\ntype MySiteSkeletonProps = {\n textColor: ColorOptions;\n accentColor: ColorOptions;\n borderRadius: BorderRadiusOptions;\n};\n\nfunction MySiteSkeleton({\n textColor,\n accentColor,\n borderRadius,\n}: MySiteSkeletonProps) {\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div className=\"flex animate-pulse flex-col\" aria-busy=\"true\">\n <div\n className={`relative aspect-[16/10] w-full overflow-hidden bg-${textColor}/5`}\n />\n\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR placeholder column */}\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`size-[84px] rounded-${borderRadius} bg-${textColor}/10`}\n />\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"grid grid-cols-2\">\n {[0, 1].map((i) => (\n <div\n key={i}\n className=\"flex flex-col gap-2 px-5 py-4\"\n style={\n i > 0\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined\n }\n >\n <div className={`h-2 w-14 rounded-full bg-${textColor}/10`} />\n <div className={`h-5 w-16 rounded-full bg-${textColor}/15`} />\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2 px-4 py-3\" style={divider}>\n <div\n className={`h-8 flex-1 rounded-${borderRadius} bg-${textColor}/10`}\n />\n <div\n className={`size-9 shrink-0 rounded-${borderRadius} bg-${accentColor}/30`}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ----- Hooks -----\n\ntype CopyState = \"idle\" | \"copied\";\n\nfunction useRealMySiteData(mySite: MySiteData | undefined, isPreview: boolean) {\n return useMemo(() => {\n if (isPreview || !mySite?.url) {\n return {\n hasRealSite: false,\n url: \"\",\n views: 0,\n leads: 0,\n userName: \"\",\n };\n }\n\n return {\n hasRealSite: true,\n url: mySite.url,\n views: mySite.views,\n leads: mySite.leads,\n userName: mySite.userName,\n };\n }, [isPreview, mySite]);\n}\n\nfunction useMySiteDisplayUrls(url: string) {\n const previewUrl = useMemo(() => {\n if (!url) return \"\";\n try {\n const urlObj = new URL(url);\n urlObj.searchParams.set(\"preview\", \"true\");\n return urlObj.toString();\n } catch {\n return url;\n }\n }, [url]);\n\n const hostLabel = useMemo(() => {\n if (!url) return \"\";\n try {\n return new URL(url).host;\n } catch {\n return url.replace(/^https?:\\/\\//, \"\");\n }\n }, [url]);\n\n const { prefix: urlPrefix, path: urlPath } = useMemo(\n () => (url ? splitUrl(url) : { prefix: \"\", path: \"\" }),\n [url],\n );\n\n return { previewUrl, hostLabel, urlPrefix, urlPath };\n}\n\nfunction useTimedCopyState(timeoutMs: number) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n\n useEffect(() => {\n if (copyState !== \"copied\") return;\n const id = window.setTimeout(() => setCopyState(\"idle\"), timeoutMs);\n return () => window.clearTimeout(id);\n }, [copyState, timeoutMs]);\n\n const markCopied = useCallback(() => {\n setCopyState(\"copied\");\n }, []);\n\n return { copyState, markCopied };\n}\n\n// useLayoutEffect warns on the server. Widgets are client-rendered, but guard\n// for parity with the rest of the codebase.\nconst useIsoLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n// Switches to a \"wide\" layout once the container reaches `threshold` px.\n// Uses useLayoutEffect so the initial measurement and state-flip land\n// synchronously before paint, avoiding a narrow→wide flash on mount.\nfunction useIsContainerWide(threshold: number) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [isWide, setIsWide] = useState(false);\n\n useIsoLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n const update = () => setIsWide(el.clientWidth >= threshold);\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [threshold]);\n\n return { rootRef, isWide };\n}\n\ntype ScaledIframePreviewOptions = {\n viewportWidth: number;\n minIframeHeight: number;\n};\n\n// Renders the iframe at a real desktop viewport (`viewportWidth`) and scales\n// it to fit the actual container. The iframe's rendered height is computed\n// dynamically so it fills the container in both aspect-locked compact mode\n// AND the height-driven wide mode (no whitespace gap below the preview).\nfunction useScaledIframePreview({\n viewportWidth,\n minIframeHeight,\n}: ScaledIframePreviewOptions) {\n const [metrics, setMetrics] = useState({\n scale: 0.5,\n iframeHeight: minIframeHeight,\n });\n\n const frameRef = useCallback(\n (el: HTMLDivElement | null) => {\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) {\n const scale = w / viewportWidth;\n const iframeHeight = Math.max(minIframeHeight, h / scale);\n setMetrics((prev) =>\n prev.scale === scale && prev.iframeHeight === iframeHeight\n ? prev\n : { scale, iframeHeight },\n );\n }\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n },\n [viewportWidth, minIframeHeight],\n );\n\n return { frameRef, scale: metrics.scale, iframeHeight: metrics.iframeHeight };\n}\n\nexport const mySiteWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"MySiteWidget\",\n displayName: \"MySite Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Display group\n {\n key: \"showPreview\",\n label: \"Show Site Preview\",\n type: \"boolean\",\n description: \"Show the live iframe preview of the storefront\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showAnalytics\",\n label: \"Show Stats\",\n type: \"boolean\",\n description: \"Visitors and Leads grid in the footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showLiveBadge\",\n label: \"Show LIVE Badge\",\n type: \"boolean\",\n description: \"Small 'Live' chip in the preview corner\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showQR\",\n label: \"Show QR Code\",\n type: \"boolean\",\n description: \"Show a scannable QR code in the card footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Primary text, hairline, and neutral chip color\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Drives the Live dot, conversion ring, and Visit CTA\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Corner radius for the widget and inner chips\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
- const require_registry_context = require("./registry-context-bf52ZIJX.cjs");
2
+ const require_registry_context = require("./registry-context-CcZYS15Q.cjs");
3
3
  const require_error_state = require("./error-state-BDhSltIa.cjs");
4
4
  const require_registries = require("./registries-DBb6VjAX.cjs");
5
5
  let react = require("react");
@@ -574,4 +574,4 @@ Object.defineProperty(exports, "mySiteWidgetPropertySchema", {
574
574
  }
575
575
  });
576
576
 
577
- //# sourceMappingURL=MySiteWidget-C8eFWHOT.cjs.map
577
+ //# sourceMappingURL=MySiteWidget-CYiH2lmX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MySiteWidget-C8eFWHOT.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetPreviewContext","ErrorState","Globe","Check","Copy","ArrowUpRight","QRCodeSVG","useLayoutEffect","useEffect","getColorField","getBorderRadiusField"],"sources":["../../widgets/src/hooks/use-mysite.preview.ts","../../widgets/src/hooks/use-mysite.ts","../../widgets/src/widgets/MySiteWidget.tsx"],"sourcesContent":["import type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const PREVIEW_DATA: MySiteData = {\n url: \"https://mysite.example.com\",\n views: 1248,\n leads: 43,\n userName: \"Jane\",\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-mysite.preview\";\nimport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useMySite(): UseQueryResult<MySiteData, Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: [\n \"portal-widget-use\",\n \"mysite\",\n isPreview ? \"preview\" : baseUrl,\n ] as const,\n queryFn: ({ signal }) => widgetsApi.fetchMySite(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { getBorderRadiusField, getColorField } from \"../core/fields\";\nimport { useMySite, type MySiteData } from \"../hooks/use-mysite\";\nimport { ErrorState } from \"../components/error-state\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { ArrowUpRight, Check, Copy, Globe } from \"lucide-react\";\n\ntype MySiteWidgetProps = ComponentProps<\"div\"> & {\n // Design\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display toggles\n showPreview?: boolean;\n showAnalytics?: boolean;\n showLiveBadge?: boolean;\n showQR?: boolean;\n};\n\nconst formatCompactNumber = (n: number | undefined): string => {\n const value = n ?? 0;\n if (value < 1000) return value.toLocaleString();\n if (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n if (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n return `${(value / 1_000_000).toFixed(1)}m`;\n};\n\nconst splitUrl = (url: string): { prefix: string; path: string } => {\n try {\n const parsed = new URL(url);\n return {\n prefix: `${parsed.protocol}//${parsed.host}`,\n path:\n `${parsed.pathname}${parsed.search}${parsed.hash}`.replace(\n /^\\/$/,\n \"\",\n ) || \"\",\n };\n } catch {\n return { prefix: \"\", path: url };\n }\n};\n\nexport function MySiteWidget({\n background = { type: \"solid\", color: \"background\" },\n textColor = \"foreground\",\n accentColor = \"primary\",\n borderRadius = \"xl\",\n\n showPreview = true,\n showAnalytics = true,\n showLiveBadge = true,\n showQR = true,\n\n className,\n ...props\n}: MySiteWidgetProps): React.JSX.Element | null {\n const { copyState, markCopied } = useTimedCopyState(1600);\n const { rootRef: widgetRootRef, isWide } = useIsContainerWide(720);\n const {\n frameRef: previewFrameRef,\n scale,\n iframeHeight,\n } = useScaledIframePreview({\n viewportWidth: 1280,\n minIframeHeight: 500,\n });\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n const { data: mySite, isLoading, isError } = useMySite();\n const { isPreview } = useWidgetPreviewContext();\n const realMySite = useRealMySiteData(mySite, isPreview);\n const { hasRealSite, url, views, leads } = realMySite;\n const { previewUrl, hostLabel, urlPrefix, urlPath } =\n useMySiteDisplayUrls(url);\n const showDashboardLayout = isWide && hasRealSite;\n const showStats = showAnalytics && hasRealSite;\n const showFooter = hasRealSite;\n\n const handleCopy = async () => {\n if (!url) return;\n try {\n await navigator.clipboard.writeText(url);\n markCopied();\n } catch (error) {\n console.error(\"Failed to copy MySite URL:\", error);\n }\n };\n\n if (!isLoading && !isError && !isPreview && !hasRealSite) {\n return null;\n }\n\n // Hairline divider color — subtle, theme-aware\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div\n ref={widgetRootRef}\n className={`@container relative overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n style={{\n backgroundImage,\n boxShadow: `0 1px 2px rgba(15,23,42,0.04), 0 20px 40px -24px rgba(15,23,42,0.16), inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 7%, transparent)`,\n }}\n {...props}\n >\n {isLoading ? (\n <MySiteSkeleton\n textColor={textColor}\n accentColor={accentColor}\n borderRadius={borderRadius}\n />\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState />\n </div>\n ) : showDashboardLayout ? (\n <div className=\"flex items-stretch\">\n {/* Left: site preview */}\n {showPreview && (\n <div\n className=\"relative isolate shrink-0 bg-white\"\n style={{\n width: \"45%\",\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <div\n ref={previewFrameRef}\n className=\"relative h-full w-full overflow-hidden bg-white\"\n >\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {showLiveBadge && (\n <div className=\"absolute top-4 left-4\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Right: dashboard column */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-3.5 p-5 sm:p-6\">\n <div>\n <span\n className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n >\n Your Storefront\n </span>\n <h2\n className={`mt-1 text-[22px] leading-[1.1] font-bold tracking-[-0.02em] text-${textColor}`}\n >\n You&rsquo;re live\n </h2>\n </div>\n\n {hasRealSite && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex items-center gap-2.5 rounded-${borderRadius} px-3 py-2 text-[13px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <Globe className={`size-3.5 shrink-0 text-${textColor}/55`} />\n <span\n className={`min-w-0 flex-1 truncate text-left font-semibold tabular-nums text-${textColor}`}\n >\n {hostLabel}\n {urlPath}\n </span>\n <span\n className={`flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor} text-${backgroundColor}`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n )}\n\n {showStats && (\n <>\n <div\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Visitors\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(views)}\n </div>\n </div>\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Leads\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(leads)}\n </div>\n </div>\n </div>\n </>\n )}\n\n {hasRealSite && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`group/visit mt-auto inline-flex items-center justify-between gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_12px_28px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <span>Open the live site</span>\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n )}\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* Card body: site preview — flush to the top of the card */}\n {showPreview && (hasRealSite || isPreview) && (\n <div className=\"relative isolate bg-white\">\n <div\n ref={previewFrameRef}\n className=\"relative aspect-[16/10] w-full overflow-hidden bg-white\"\n >\n {isPreview || !hasRealSite ? (\n <MySitePreviewPlaceholder hostLabel={hostLabel} />\n ) : (\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n )}\n {/* Very subtle top-edge sheen for polish */}\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {/* LIVE badge — quiet, not blinking */}\n {showLiveBadge && hasRealSite && (\n <div className=\"absolute top-3 right-3\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2 py-1 text-[9px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Card footer — distinct tinted surface, QR column + right column */}\n {showFooter && (\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR column — spans the full footer height */}\n {showQR && hasRealSite && (\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`flex flex-col items-center gap-1.5 rounded-${borderRadius} bg-white p-2.5`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.05), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n role=\"img\"\n aria-label=\"QR code for your site\"\n >\n <QRCodeSVG\n value={url}\n size={64}\n level=\"H\"\n bgColor=\"#ffffff\"\n fgColor=\"#0f172a\"\n />\n </div>\n </div>\n )}\n\n {/* Right column */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Stats row */}\n {showStats && (\n <div className=\"grid grid-cols-2\">\n <StatCell\n label=\"Visitors\"\n value={formatCompactNumber(views)}\n textColor={textColor}\n />\n <StatCell\n label=\"Leads\"\n value={formatCompactNumber(leads)}\n textColor={textColor}\n leftDivider\n />\n </div>\n )}\n\n {/* Action row */}\n {hasRealSite && (\n <div\n className=\"flex items-center gap-2 px-4 py-3\"\n style={showStats ? divider : undefined}\n >\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex min-w-0 flex-1 items-center justify-between gap-2 rounded-${borderRadius} px-3 py-2 text-left text-[12px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <span\n className={`min-w-0 flex-1 truncate font-medium text-${textColor}`}\n >\n {urlPrefix && (\n <span className={`text-${textColor}/45`}>\n {urlPrefix}\n </span>\n )}\n <span className=\"font-semibold\">{urlPath || \"/\"}</span>\n </span>\n <span\n className={`flex size-6 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `scale-105 bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor}/10 text-${textColor} group-hover/copy:bg-${textColor}/20`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Visit site\"\n className={`group/visit inline-flex size-9 shrink-0 items-center justify-center rounded-${borderRadius} bg-${accentColor} text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_10px_24px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ntype MySitePreviewPlaceholderProps = {\n hostLabel: string;\n};\n\n// Static placeholder shown in builder/preview contexts. Preview mode keeps\n// placeholder API values out of visible widget content.\nfunction MySitePreviewPlaceholder({\n hostLabel,\n}: MySitePreviewPlaceholderProps): React.JSX.Element {\n return (\n <div className=\"bg-muted/30 absolute inset-0 flex flex-col items-center justify-center gap-3 p-4 text-center\">\n <div className=\"bg-muted flex h-10 w-10 items-center justify-center rounded-full\">\n <Globe className=\"text-muted-foreground h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-foreground text-sm font-medium\">My Site</p>\n {hostLabel && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{hostLabel}</p>\n )}\n </div>\n </div>\n );\n}\n\ntype StatCellProps = {\n label: string;\n value: string;\n textColor: ColorOptions;\n leftDivider?: boolean;\n};\n\nfunction StatCell({ label, value, textColor, leftDivider }: StatCellProps) {\n const leftDividerStyle: CSSProperties | undefined = leftDivider\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-1.5 px-5 py-4\" style={leftDividerStyle}>\n <span\n className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n >\n {label}\n </span>\n <span\n className={`text-[22px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {value}\n </span>\n </div>\n );\n}\n\ntype MySiteSkeletonProps = {\n textColor: ColorOptions;\n accentColor: ColorOptions;\n borderRadius: BorderRadiusOptions;\n};\n\nfunction MySiteSkeleton({\n textColor,\n accentColor,\n borderRadius,\n}: MySiteSkeletonProps) {\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div className=\"flex animate-pulse flex-col\" aria-busy=\"true\">\n <div\n className={`relative aspect-[16/10] w-full overflow-hidden bg-${textColor}/5`}\n />\n\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR placeholder column */}\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`size-[84px] rounded-${borderRadius} bg-${textColor}/10`}\n />\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"grid grid-cols-2\">\n {[0, 1].map((i) => (\n <div\n key={i}\n className=\"flex flex-col gap-2 px-5 py-4\"\n style={\n i > 0\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined\n }\n >\n <div className={`h-2 w-14 rounded-full bg-${textColor}/10`} />\n <div className={`h-5 w-16 rounded-full bg-${textColor}/15`} />\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2 px-4 py-3\" style={divider}>\n <div\n className={`h-8 flex-1 rounded-${borderRadius} bg-${textColor}/10`}\n />\n <div\n className={`size-9 shrink-0 rounded-${borderRadius} bg-${accentColor}/30`}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ----- Hooks -----\n\ntype CopyState = \"idle\" | \"copied\";\n\nfunction useRealMySiteData(mySite: MySiteData | undefined, isPreview: boolean) {\n return useMemo(() => {\n if (isPreview || !mySite?.url) {\n return {\n hasRealSite: false,\n url: \"\",\n views: 0,\n leads: 0,\n userName: \"\",\n };\n }\n\n return {\n hasRealSite: true,\n url: mySite.url,\n views: mySite.views,\n leads: mySite.leads,\n userName: mySite.userName,\n };\n }, [isPreview, mySite]);\n}\n\nfunction useMySiteDisplayUrls(url: string) {\n const previewUrl = useMemo(() => {\n if (!url) return \"\";\n try {\n const urlObj = new URL(url);\n urlObj.searchParams.set(\"preview\", \"true\");\n return urlObj.toString();\n } catch {\n return url;\n }\n }, [url]);\n\n const hostLabel = useMemo(() => {\n if (!url) return \"\";\n try {\n return new URL(url).host;\n } catch {\n return url.replace(/^https?:\\/\\//, \"\");\n }\n }, [url]);\n\n const { prefix: urlPrefix, path: urlPath } = useMemo(\n () => (url ? splitUrl(url) : { prefix: \"\", path: \"\" }),\n [url],\n );\n\n return { previewUrl, hostLabel, urlPrefix, urlPath };\n}\n\nfunction useTimedCopyState(timeoutMs: number) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n\n useEffect(() => {\n if (copyState !== \"copied\") return;\n const id = window.setTimeout(() => setCopyState(\"idle\"), timeoutMs);\n return () => window.clearTimeout(id);\n }, [copyState, timeoutMs]);\n\n const markCopied = useCallback(() => {\n setCopyState(\"copied\");\n }, []);\n\n return { copyState, markCopied };\n}\n\n// useLayoutEffect warns on the server. Widgets are client-rendered, but guard\n// for parity with the rest of the codebase.\nconst useIsoLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n// Switches to a \"wide\" layout once the container reaches `threshold` px.\n// Uses useLayoutEffect so the initial measurement and state-flip land\n// synchronously before paint, avoiding a narrow→wide flash on mount.\nfunction useIsContainerWide(threshold: number) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [isWide, setIsWide] = useState(false);\n\n useIsoLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n const update = () => setIsWide(el.clientWidth >= threshold);\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [threshold]);\n\n return { rootRef, isWide };\n}\n\ntype ScaledIframePreviewOptions = {\n viewportWidth: number;\n minIframeHeight: number;\n};\n\n// Renders the iframe at a real desktop viewport (`viewportWidth`) and scales\n// it to fit the actual container. The iframe's rendered height is computed\n// dynamically so it fills the container in both aspect-locked compact mode\n// AND the height-driven wide mode (no whitespace gap below the preview).\nfunction useScaledIframePreview({\n viewportWidth,\n minIframeHeight,\n}: ScaledIframePreviewOptions) {\n const [metrics, setMetrics] = useState({\n scale: 0.5,\n iframeHeight: minIframeHeight,\n });\n\n const frameRef = useCallback(\n (el: HTMLDivElement | null) => {\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) {\n const scale = w / viewportWidth;\n const iframeHeight = Math.max(minIframeHeight, h / scale);\n setMetrics((prev) =>\n prev.scale === scale && prev.iframeHeight === iframeHeight\n ? prev\n : { scale, iframeHeight },\n );\n }\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n },\n [viewportWidth, minIframeHeight],\n );\n\n return { frameRef, scale: metrics.scale, iframeHeight: metrics.iframeHeight };\n}\n\nexport const mySiteWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"MySiteWidget\",\n displayName: \"MySite Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Display group\n {\n key: \"showPreview\",\n label: \"Show Site Preview\",\n type: \"boolean\",\n description: \"Show the live iframe preview of the storefront\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showAnalytics\",\n label: \"Show Stats\",\n type: \"boolean\",\n description: \"Visitors and Leads grid in the footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showLiveBadge\",\n label: \"Show LIVE Badge\",\n type: \"boolean\",\n description: \"Small 'Live' chip in the preview corner\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showQR\",\n label: \"Show QR Code\",\n type: \"boolean\",\n description: \"Show a scannable QR code in the card footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Primary text, hairline, and neutral chip color\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Drives the Live dot, conversion ring, and Visit CTA\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Corner radius for the widget and inner chips\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EAGD;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}
1
+ {"version":3,"file":"MySiteWidget-CYiH2lmX.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetPreviewContext","ErrorState","Globe","Check","Copy","ArrowUpRight","QRCodeSVG","useLayoutEffect","useEffect","getColorField","getBorderRadiusField"],"sources":["../../widgets/src/hooks/use-mysite.preview.ts","../../widgets/src/hooks/use-mysite.ts","../../widgets/src/widgets/MySiteWidget.tsx"],"sourcesContent":["import type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const PREVIEW_DATA: MySiteData = {\n url: \"https://mysite.example.com\",\n views: 1248,\n leads: 43,\n userName: \"Jane\",\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-mysite.preview\";\nimport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useMySite(): UseQueryResult<MySiteData, Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: [\n \"portal-widget-use\",\n \"mysite\",\n isPreview ? \"preview\" : baseUrl,\n ] as const,\n queryFn: ({ signal }) => widgetsApi.fetchMySite(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { getBorderRadiusField, getColorField } from \"../core/fields\";\nimport { useMySite, type MySiteData } from \"../hooks/use-mysite\";\nimport { ErrorState } from \"../components/error-state\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { ArrowUpRight, Check, Copy, Globe } from \"lucide-react\";\n\ntype MySiteWidgetProps = ComponentProps<\"div\"> & {\n // Design\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n borderRadius?: BorderRadiusOptions;\n\n // Display toggles\n showPreview?: boolean;\n showAnalytics?: boolean;\n showLiveBadge?: boolean;\n showQR?: boolean;\n};\n\nconst formatCompactNumber = (n: number | undefined): string => {\n const value = n ?? 0;\n if (value < 1000) return value.toLocaleString();\n if (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n if (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n return `${(value / 1_000_000).toFixed(1)}m`;\n};\n\nconst splitUrl = (url: string): { prefix: string; path: string } => {\n try {\n const parsed = new URL(url);\n return {\n prefix: `${parsed.protocol}//${parsed.host}`,\n path:\n `${parsed.pathname}${parsed.search}${parsed.hash}`.replace(\n /^\\/$/,\n \"\",\n ) || \"\",\n };\n } catch {\n return { prefix: \"\", path: url };\n }\n};\n\nexport function MySiteWidget({\n background = { type: \"solid\", color: \"background\" },\n textColor = \"foreground\",\n accentColor = \"primary\",\n borderRadius = \"xl\",\n\n showPreview = true,\n showAnalytics = true,\n showLiveBadge = true,\n showQR = true,\n\n className,\n ...props\n}: MySiteWidgetProps): React.JSX.Element | null {\n const { copyState, markCopied } = useTimedCopyState(1600);\n const { rootRef: widgetRootRef, isWide } = useIsContainerWide(720);\n const {\n frameRef: previewFrameRef,\n scale,\n iframeHeight,\n } = useScaledIframePreview({\n viewportWidth: 1280,\n minIframeHeight: 500,\n });\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n const { data: mySite, isLoading, isError } = useMySite();\n const { isPreview } = useWidgetPreviewContext();\n const realMySite = useRealMySiteData(mySite, isPreview);\n const { hasRealSite, url, views, leads } = realMySite;\n const { previewUrl, hostLabel, urlPrefix, urlPath } =\n useMySiteDisplayUrls(url);\n const showDashboardLayout = isWide && hasRealSite;\n const showStats = showAnalytics && hasRealSite;\n const showFooter = hasRealSite;\n\n const handleCopy = async () => {\n if (!url) return;\n try {\n await navigator.clipboard.writeText(url);\n markCopied();\n } catch (error) {\n console.error(\"Failed to copy MySite URL:\", error);\n }\n };\n\n if (!isLoading && !isError && !isPreview && !hasRealSite) {\n return null;\n }\n\n // Hairline divider color — subtle, theme-aware\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div\n ref={widgetRootRef}\n className={`@container relative overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n style={{\n backgroundImage,\n boxShadow: `0 1px 2px rgba(15,23,42,0.04), 0 20px 40px -24px rgba(15,23,42,0.16), inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 7%, transparent)`,\n }}\n {...props}\n >\n {isLoading ? (\n <MySiteSkeleton\n textColor={textColor}\n accentColor={accentColor}\n borderRadius={borderRadius}\n />\n ) : isError ? (\n <div className=\"p-6\">\n <ErrorState />\n </div>\n ) : showDashboardLayout ? (\n <div className=\"flex items-stretch\">\n {/* Left: site preview */}\n {showPreview && (\n <div\n className=\"relative isolate shrink-0 bg-white\"\n style={{\n width: \"45%\",\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <div\n ref={previewFrameRef}\n className=\"relative h-full w-full overflow-hidden bg-white\"\n >\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {showLiveBadge && (\n <div className=\"absolute top-4 left-4\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Right: dashboard column */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-3.5 p-5 sm:p-6\">\n <div>\n <span\n className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n >\n Your Storefront\n </span>\n <h2\n className={`mt-1 text-[22px] leading-[1.1] font-bold tracking-[-0.02em] text-${textColor}`}\n >\n You&rsquo;re live\n </h2>\n </div>\n\n {hasRealSite && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex items-center gap-2.5 rounded-${borderRadius} px-3 py-2 text-[13px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n >\n <Globe className={`size-3.5 shrink-0 text-${textColor}/55`} />\n <span\n className={`min-w-0 flex-1 truncate text-left font-semibold tabular-nums text-${textColor}`}\n >\n {hostLabel}\n {urlPath}\n </span>\n <span\n className={`flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor} text-${backgroundColor}`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n )}\n\n {showStats && (\n <>\n <div\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n }}\n />\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Visitors\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(views)}\n </div>\n </div>\n <div>\n <div\n className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n >\n Leads\n </div>\n <div\n className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {formatCompactNumber(leads)}\n </div>\n </div>\n </div>\n </>\n )}\n\n {hasRealSite && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`group/visit mt-auto inline-flex items-center justify-between gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_12px_28px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <span>Open the live site</span>\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n )}\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {/* Card body: site preview — flush to the top of the card */}\n {showPreview && (hasRealSite || isPreview) && (\n <div className=\"relative isolate bg-white\">\n <div\n ref={previewFrameRef}\n className=\"relative aspect-[16/10] w-full overflow-hidden bg-white\"\n >\n {isPreview || !hasRealSite ? (\n <MySitePreviewPlaceholder hostLabel={hostLabel} />\n ) : (\n <iframe\n className=\"pointer-events-none absolute top-0 left-0 origin-top-left bg-white\"\n src={previewUrl}\n title={`${hostLabel} preview`}\n loading=\"lazy\"\n style={{\n width: \"1280px\",\n height: `${iframeHeight}px`,\n transform: `scale(${scale})`,\n }}\n />\n )}\n {/* Very subtle top-edge sheen for polish */}\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n style={{\n background:\n \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n }}\n />\n </div>\n\n {/* LIVE badge — quiet, not blinking */}\n {showLiveBadge && hasRealSite && (\n <div className=\"absolute top-3 right-3\">\n <span\n className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2 py-1 text-[9px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n className={`bg-${accentColor} size-1.5 rounded-full`}\n />\n Live\n </span>\n </div>\n )}\n </div>\n )}\n\n {/* Card footer — distinct tinted surface, QR column + right column */}\n {showFooter && (\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR column — spans the full footer height */}\n {showQR && hasRealSite && (\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`flex flex-col items-center gap-1.5 rounded-${borderRadius} bg-white p-2.5`}\n style={{\n boxShadow:\n \"0 2px 8px rgba(15,23,42,0.05), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n }}\n role=\"img\"\n aria-label=\"QR code for your site\"\n >\n <QRCodeSVG\n value={url}\n size={64}\n level=\"H\"\n bgColor=\"#ffffff\"\n fgColor=\"#0f172a\"\n />\n </div>\n </div>\n )}\n\n {/* Right column */}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {/* Stats row */}\n {showStats && (\n <div className=\"grid grid-cols-2\">\n <StatCell\n label=\"Visitors\"\n value={formatCompactNumber(views)}\n textColor={textColor}\n />\n <StatCell\n label=\"Leads\"\n value={formatCompactNumber(leads)}\n textColor={textColor}\n leftDivider\n />\n </div>\n )}\n\n {/* Action row */}\n {hasRealSite && (\n <div\n className=\"flex items-center gap-2 px-4 py-3\"\n style={showStats ? divider : undefined}\n >\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n copyState === \"copied\"\n ? \"Copied to clipboard\"\n : \"Copy site link\"\n }\n className={`group/copy flex min-w-0 flex-1 items-center justify-between gap-2 rounded-${borderRadius} px-3 py-2 text-left text-[12px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n style={{\n boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <span\n className={`min-w-0 flex-1 truncate font-medium text-${textColor}`}\n >\n {urlPrefix && (\n <span className={`text-${textColor}/45`}>\n {urlPrefix}\n </span>\n )}\n <span className=\"font-semibold\">{urlPath || \"/\"}</span>\n </span>\n <span\n className={`flex size-6 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `scale-105 bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor}/10 text-${textColor} group-hover/copy:bg-${textColor}/20`}`}\n >\n {copyState === \"copied\" ? (\n <Check className=\"size-3\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </span>\n </button>\n\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Visit site\"\n className={`group/visit inline-flex size-9 shrink-0 items-center justify-center rounded-${borderRadius} bg-${accentColor} text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_10px_24px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n >\n <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n </a>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\ntype MySitePreviewPlaceholderProps = {\n hostLabel: string;\n};\n\n// Static placeholder shown in builder/preview contexts. Preview mode keeps\n// placeholder API values out of visible widget content.\nfunction MySitePreviewPlaceholder({\n hostLabel,\n}: MySitePreviewPlaceholderProps): React.JSX.Element {\n return (\n <div className=\"bg-muted/30 absolute inset-0 flex flex-col items-center justify-center gap-3 p-4 text-center\">\n <div className=\"bg-muted flex h-10 w-10 items-center justify-center rounded-full\">\n <Globe className=\"text-muted-foreground h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-foreground text-sm font-medium\">My Site</p>\n {hostLabel && (\n <p className=\"text-muted-foreground mt-0.5 text-xs\">{hostLabel}</p>\n )}\n </div>\n </div>\n );\n}\n\ntype StatCellProps = {\n label: string;\n value: string;\n textColor: ColorOptions;\n leftDivider?: boolean;\n};\n\nfunction StatCell({ label, value, textColor, leftDivider }: StatCellProps) {\n const leftDividerStyle: CSSProperties | undefined = leftDivider\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined;\n\n return (\n <div className=\"flex flex-col gap-1.5 px-5 py-4\" style={leftDividerStyle}>\n <span\n className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n >\n {label}\n </span>\n <span\n className={`text-[22px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n >\n {value}\n </span>\n </div>\n );\n}\n\ntype MySiteSkeletonProps = {\n textColor: ColorOptions;\n accentColor: ColorOptions;\n borderRadius: BorderRadiusOptions;\n};\n\nfunction MySiteSkeleton({\n textColor,\n accentColor,\n borderRadius,\n}: MySiteSkeletonProps) {\n const divider: CSSProperties = {\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n };\n\n return (\n <div className=\"flex animate-pulse flex-col\" aria-busy=\"true\">\n <div\n className={`relative aspect-[16/10] w-full overflow-hidden bg-${textColor}/5`}\n />\n\n <div\n className=\"flex items-stretch\"\n style={{\n borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n }}\n >\n {/* QR placeholder column */}\n <div\n className=\"flex shrink-0 items-center justify-center p-4\"\n style={{\n borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }}\n >\n <div\n className={`size-[84px] rounded-${borderRadius} bg-${textColor}/10`}\n />\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"grid grid-cols-2\">\n {[0, 1].map((i) => (\n <div\n key={i}\n className=\"flex flex-col gap-2 px-5 py-4\"\n style={\n i > 0\n ? {\n borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n }\n : undefined\n }\n >\n <div className={`h-2 w-14 rounded-full bg-${textColor}/10`} />\n <div className={`h-5 w-16 rounded-full bg-${textColor}/15`} />\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2 px-4 py-3\" style={divider}>\n <div\n className={`h-8 flex-1 rounded-${borderRadius} bg-${textColor}/10`}\n />\n <div\n className={`size-9 shrink-0 rounded-${borderRadius} bg-${accentColor}/30`}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\n// ----- Hooks -----\n\ntype CopyState = \"idle\" | \"copied\";\n\nfunction useRealMySiteData(mySite: MySiteData | undefined, isPreview: boolean) {\n return useMemo(() => {\n if (isPreview || !mySite?.url) {\n return {\n hasRealSite: false,\n url: \"\",\n views: 0,\n leads: 0,\n userName: \"\",\n };\n }\n\n return {\n hasRealSite: true,\n url: mySite.url,\n views: mySite.views,\n leads: mySite.leads,\n userName: mySite.userName,\n };\n }, [isPreview, mySite]);\n}\n\nfunction useMySiteDisplayUrls(url: string) {\n const previewUrl = useMemo(() => {\n if (!url) return \"\";\n try {\n const urlObj = new URL(url);\n urlObj.searchParams.set(\"preview\", \"true\");\n return urlObj.toString();\n } catch {\n return url;\n }\n }, [url]);\n\n const hostLabel = useMemo(() => {\n if (!url) return \"\";\n try {\n return new URL(url).host;\n } catch {\n return url.replace(/^https?:\\/\\//, \"\");\n }\n }, [url]);\n\n const { prefix: urlPrefix, path: urlPath } = useMemo(\n () => (url ? splitUrl(url) : { prefix: \"\", path: \"\" }),\n [url],\n );\n\n return { previewUrl, hostLabel, urlPrefix, urlPath };\n}\n\nfunction useTimedCopyState(timeoutMs: number) {\n const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n\n useEffect(() => {\n if (copyState !== \"copied\") return;\n const id = window.setTimeout(() => setCopyState(\"idle\"), timeoutMs);\n return () => window.clearTimeout(id);\n }, [copyState, timeoutMs]);\n\n const markCopied = useCallback(() => {\n setCopyState(\"copied\");\n }, []);\n\n return { copyState, markCopied };\n}\n\n// useLayoutEffect warns on the server. Widgets are client-rendered, but guard\n// for parity with the rest of the codebase.\nconst useIsoLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n// Switches to a \"wide\" layout once the container reaches `threshold` px.\n// Uses useLayoutEffect so the initial measurement and state-flip land\n// synchronously before paint, avoiding a narrow→wide flash on mount.\nfunction useIsContainerWide(threshold: number) {\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [isWide, setIsWide] = useState(false);\n\n useIsoLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n const update = () => setIsWide(el.clientWidth >= threshold);\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, [threshold]);\n\n return { rootRef, isWide };\n}\n\ntype ScaledIframePreviewOptions = {\n viewportWidth: number;\n minIframeHeight: number;\n};\n\n// Renders the iframe at a real desktop viewport (`viewportWidth`) and scales\n// it to fit the actual container. The iframe's rendered height is computed\n// dynamically so it fills the container in both aspect-locked compact mode\n// AND the height-driven wide mode (no whitespace gap below the preview).\nfunction useScaledIframePreview({\n viewportWidth,\n minIframeHeight,\n}: ScaledIframePreviewOptions) {\n const [metrics, setMetrics] = useState({\n scale: 0.5,\n iframeHeight: minIframeHeight,\n });\n\n const frameRef = useCallback(\n (el: HTMLDivElement | null) => {\n if (!el) return;\n const update = () => {\n const w = el.clientWidth;\n const h = el.clientHeight;\n if (w > 0 && h > 0) {\n const scale = w / viewportWidth;\n const iframeHeight = Math.max(minIframeHeight, h / scale);\n setMetrics((prev) =>\n prev.scale === scale && prev.iframeHeight === iframeHeight\n ? prev\n : { scale, iframeHeight },\n );\n }\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n },\n [viewportWidth, minIframeHeight],\n );\n\n return { frameRef, scale: metrics.scale, iframeHeight: metrics.iframeHeight };\n}\n\nexport const mySiteWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"MySiteWidget\",\n displayName: \"MySite Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Display group\n {\n key: \"showPreview\",\n label: \"Show Site Preview\",\n type: \"boolean\",\n description: \"Show the live iframe preview of the storefront\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showAnalytics\",\n label: \"Show Stats\",\n type: \"boolean\",\n description: \"Visitors and Leads grid in the footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showLiveBadge\",\n label: \"Show LIVE Badge\",\n type: \"boolean\",\n description: \"Small 'Live' chip in the preview corner\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n {\n key: \"showQR\",\n label: \"Show QR Code\",\n type: \"boolean\",\n description: \"Show a scannable QR code in the card footer\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Display\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Primary text, hairline, and neutral chip color\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Drives the Live dot, conversion ring, and Visit CTA\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Corner radius for the widget and inner chips\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EAGD;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}
@@ -1,5 +1,5 @@
1
1
  import { r as __exportAll } from "./es-BXxGlAp6.mjs";
2
- import { n as useDataSourceRegistryConfig } from "./registry-context-BahYMRqn.mjs";
2
+ import { n as useDataSourceRegistryConfig } from "./registry-context-CTHUCfEc.mjs";
3
3
  import { i as useWidgetsApi, n as useWidgetPreviewContext, t as ErrorState } from "./error-state-DYzHx8tt.mjs";
4
4
  import { i as getBorderColorField, l as getColorField, m as getPaddingField, n as borderWidthClasses, o as getBorderRadiusField, s as getBorderWidthField, t as borderColorClasses, u as getFontSizeField } from "./registries-Ct8o2YRe.mjs";
5
5
  import { useId, useState } from "react";
@@ -54,13 +54,10 @@ function usePointsLedger() {
54
54
  "portal-widget-use",
55
55
  POINTS_LEDGER_QUERY_KEY,
56
56
  isPreview ? "preview" : baseUrl,
57
- customerId
57
+ customerId ?? null
58
58
  ],
59
- queryFn: ({ signal }) => {
60
- if (!customerId) throw new Error("customerId is required");
61
- return widgetsApi.fetchPointsLedger(customerId, signal);
62
- },
63
- enabled: !isPreview && !!customerId,
59
+ queryFn: ({ signal }) => widgetsApi.fetchPointsLedger(customerId ?? "", signal),
60
+ enabled: !isPreview,
64
61
  ...isPreview && { placeholderData: PREVIEW_DATA }
65
62
  });
66
63
  }
@@ -297,4 +294,4 @@ const pointsWidgetPropertySchema = {
297
294
  //#endregion
298
295
  export { PointsWidget_exports as n, pointsWidgetPropertySchema as r, PointsWidget as t };
299
296
 
300
- //# sourceMappingURL=PointsWidget-C2KB4k48.mjs.map
297
+ //# sourceMappingURL=PointsWidget-BwA6aGVZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PointsWidget-BwA6aGVZ.mjs","names":[],"sources":["../../widgets/src/hooks/use-points-ledger.preview.ts","../../widgets/src/hooks/use-points-ledger.ts","../../widgets/src/widgets/PointsWidget.tsx"],"sourcesContent":["import type { PointsData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction daysAgo(days: number): string {\n return new Date(now.getTime() - days * 86_400_000).toISOString();\n}\n\nexport const PREVIEW_DATA: PointsData = {\n balance: 25,\n entries: [\n {\n id: 1,\n description: \"Purchase March 3rd\",\n amount: 20,\n createdAt: daysAgo(3),\n },\n {\n id: 2,\n description: \"Referral Bonus\",\n amount: 50,\n createdAt: daysAgo(14),\n },\n {\n id: 3,\n description: \"Points Redemption\",\n amount: -75,\n createdAt: daysAgo(60),\n },\n {\n id: 4,\n description: \"Welcome Reward\",\n amount: 30,\n createdAt: daysAgo(90),\n },\n ],\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-points-ledger.preview\";\nimport type { PointsData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type {\n PointsData,\n PointsEntry,\n} from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const POINTS_LEDGER_QUERY_KEY = \"points-ledger\" as const;\n\nexport function usePointsLedger(): UseQueryResult<PointsData, Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const registryConfig = useDataSourceRegistryConfig();\n const { baseUrl } = registryConfig;\n const customerId = registryConfig.variables?.customer_id;\n\n // Contract: the BFF adapter (portal app, composite factory spreads BFF over\n // legacy) ignores customerId and infers the customer from the JWT, so the\n // portal renders this widget with no registry-variable plumbing. The legacy\n // adapter (fluid-admin) builds /v202506/customers/{customerId}/points_ledgers\n // and MUST receive a real id; that consumer always supplies one via registry\n // variables, so empty string never reaches the legacy URL in practice. If a\n // future caller wires this hook to a legacy-only adapter, configure\n // registry variables.customer_id at the provider — otherwise the request\n // would 404 on /customers//points_ledgers.\n return useQuery({\n queryKey: [\n \"portal-widget-use\",\n POINTS_LEDGER_QUERY_KEY,\n isPreview ? \"preview\" : baseUrl,\n customerId ?? null,\n ] as const,\n queryFn: ({ signal }) =>\n widgetsApi.fetchPointsLedger(customerId ?? \"\", signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import { useId, useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n getColorField,\n getFontSizeField,\n getPaddingField,\n borderWidthClasses,\n borderColorClasses,\n} from \"../core/fields\";\nimport { usePointsLedger, type PointsEntry } from \"../hooks/use-points-ledger\";\nimport { ErrorState } from \"../components/error-state\";\nimport { ChevronDown, Coins } from \"lucide-react\";\n\nconst formatRelativeTime = (dateString: string): string => {\n const now = new Date();\n const date = new Date(dateString);\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / 86_400_000);\n\n if (diffDays < 1) return \"Today\";\n if (diffDays === 1) return \"1 day ago\";\n if (diffDays < 7) return `${diffDays} days ago`;\n if (diffDays < 14) return \"1 week ago\";\n if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`;\n if (diffDays < 60) return \"1 month ago\";\n return `${Math.floor(diffDays / 30)} months ago`;\n};\n\nconst formatBalance = (balance: number): string => {\n return balance.toLocaleString(\"en-US\");\n};\n\ntype PointsWidgetProps = ComponentProps<\"div\"> & {\n // Title\n titleEnabled?: boolean;\n title?: string;\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n\n // Balance\n balanceColor?: ColorOptions;\n\n // History\n historyEnabled?: boolean;\n historyTitle?: string;\n\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n};\n\nfunction PointsEntryRow({\n entry,\n textColor,\n accentColor,\n}: {\n entry: PointsEntry;\n textColor: ColorOptions;\n accentColor: ColorOptions;\n}) {\n const sign = entry.amount >= 0 ? \"+\" : \"-\";\n return (\n <div className=\"flex w-full items-center gap-3\">\n <div className=\"min-w-0 flex-1\">\n <p className={`text-sm text-${textColor} truncate`}>\n {entry.description}\n </p>\n <p className={`text-[10px] text-${textColor} leading-tight opacity-70`}>\n {formatRelativeTime(entry.createdAt)}\n </p>\n </div>\n <div className={`bg-${accentColor}/20 shrink-0 rounded-md px-1.5`}>\n <span className={`text-xs font-medium text-${accentColor} opacity-70`}>\n {sign}\n {Math.abs(entry.amount).toLocaleString(\"en-US\")}pts\n </span>\n </div>\n </div>\n );\n}\n\nexport function PointsWidget({\n // Title\n titleEnabled = true,\n title = \"Points\",\n titleFontSize = \"md\",\n titleColor = \"foreground\",\n\n // Balance\n balanceColor = \"primary\",\n\n // History\n historyEnabled = true,\n historyTitle = \"History\",\n\n // Styling\n background = { type: \"solid\", color: \"background\" },\n textColor = \"foreground\",\n accentColor = \"primary\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n\n className,\n ...props\n}: PointsWidgetProps): React.JSX.Element {\n const [historyOpen, setHistoryOpen] = useState(false);\n const historyPanelId = useId();\n\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n\n const { data, isLoading, isError } = usePointsLedger();\n\n return (\n <div\n className={`@container overflow-hidden rounded-${borderRadius} bg-${backgroundColor} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n <div className={`p-${padding} flex flex-col gap-2.5`}>\n {/* Header: Title + Balance */}\n {titleEnabled && (\n <h2\n className={`text-${titleFontSize} font-header font-bold text-${titleColor}`}\n >\n {title}\n </h2>\n )}\n {!isLoading && data && (\n <span\n className={`text-3xl font-semibold text-${balanceColor} font-header leading-snug`}\n >\n {formatBalance(data.balance)}\n </span>\n )}\n\n {/* Loading */}\n {isLoading ? (\n <div className=\"flex min-h-[60px] items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n </div>\n ) : isError ? (\n <ErrorState />\n ) : historyEnabled && (!data || data.entries.length === 0) ? (\n /* Empty state — only shown when history is enabled but no entries */\n <div className=\"flex min-h-[60px] flex-col items-center justify-center gap-2\">\n <Coins className={`size-10 text-${textColor} opacity-30`} />\n <p className={`text-sm font-semibold text-${textColor} opacity-50`}>\n No Points Activity\n </p>\n </div>\n ) : historyEnabled && data && data.entries.length > 0 ? (\n /* History dropdown */\n <div className=\"flex flex-col gap-2\">\n {/* Dropdown toggle */}\n <button\n type=\"button\"\n aria-expanded={historyOpen}\n aria-controls={historyPanelId}\n onClick={() => setHistoryOpen((prev) => !prev)}\n className={`flex w-full items-center text-xs font-semibold text-${textColor} cursor-pointer`}\n >\n <span className=\"flex-1 text-left\">{historyTitle}</span>\n <ChevronDown\n className={`size-4 transition-transform duration-200 ${historyOpen ? \"rotate-180\" : \"\"}`}\n />\n </button>\n <div className={`bg-${textColor}/20 h-px w-full`} />\n\n {/* Collapsible entries */}\n <div\n id={historyPanelId}\n className={`flex flex-col gap-3 ${!historyOpen ? \"hidden\" : \"\"}`}\n >\n {data.entries.map((entry) => (\n <PointsEntryRow\n key={entry.id}\n entry={entry}\n textColor={textColor}\n accentColor={accentColor}\n />\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport const pointsWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"PointsWidget\",\n displayName: \"Points\",\n fields: [\n // Title group\n {\n key: \"titleEnabled\",\n label: \"Show Title\",\n type: \"boolean\",\n description: \"Toggle title visibility\",\n defaultValue: true,\n\n group: \"Title\",\n },\n {\n key: \"title\",\n label: \"Title\",\n type: \"text\",\n description: \"Title text displayed above the balance\",\n defaultValue: \"Points\",\n\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleFontSize\",\n label: \"Title Font Size\",\n description: \"Font size for the title\",\n defaultValue: \"md\",\n\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the title\",\n defaultValue: \"foreground\",\n\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Balance group\n getColorField({\n key: \"balanceColor\",\n label: \"Balance Color\",\n description: \"Color for the points balance number\",\n defaultValue: \"primary\",\n\n group: \"Balance\",\n }),\n\n // History group\n {\n key: \"historyEnabled\",\n label: \"Show History\",\n type: \"boolean\",\n description: \"Show a collapsible history dropdown below the balance\",\n defaultValue: true,\n\n group: \"History\",\n },\n {\n key: \"historyTitle\",\n label: \"History Title\",\n type: \"text\",\n description: \"Title for the history dropdown\",\n defaultValue: \"History\",\n\n group: \"History\",\n requiresKeyToBeTrue: \"historyEnabled\",\n },\n\n // Design group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget\",\n defaultValue: \"background\",\n\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Default text color\",\n defaultValue: \"foreground\",\n\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Color for points badges and highlights\",\n defaultValue: \"primary\",\n\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Widget padding\",\n defaultValue: 4,\n\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Widget border radius\",\n defaultValue: \"md\",\n\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Widget border width\",\n defaultValue: \"none\",\n\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Widget border color\",\n defaultValue: \"muted\",\n\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
- const require_registry_context = require("./registry-context-bf52ZIJX.cjs");
2
+ const require_registry_context = require("./registry-context-CcZYS15Q.cjs");
3
3
  const require_error_state = require("./error-state-BDhSltIa.cjs");
4
4
  const require_registries = require("./registries-DBb6VjAX.cjs");
5
5
  let react = require("react");
@@ -54,13 +54,10 @@ function usePointsLedger() {
54
54
  "portal-widget-use",
55
55
  POINTS_LEDGER_QUERY_KEY,
56
56
  isPreview ? "preview" : baseUrl,
57
- customerId
57
+ customerId ?? null
58
58
  ],
59
- queryFn: ({ signal }) => {
60
- if (!customerId) throw new Error("customerId is required");
61
- return widgetsApi.fetchPointsLedger(customerId, signal);
62
- },
63
- enabled: !isPreview && !!customerId,
59
+ queryFn: ({ signal }) => widgetsApi.fetchPointsLedger(customerId ?? "", signal),
60
+ enabled: !isPreview,
64
61
  ...isPreview && { placeholderData: PREVIEW_DATA }
65
62
  });
66
63
  }
@@ -314,4 +311,4 @@ Object.defineProperty(exports, "pointsWidgetPropertySchema", {
314
311
  }
315
312
  });
316
313
 
317
- //# sourceMappingURL=PointsWidget-DLp-PYus.cjs.map
314
+ //# sourceMappingURL=PointsWidget-D1FV8l1h.cjs.map