@fluid-app/portal-sdk 0.1.357 → 0.1.358

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 (90) hide show
  1. package/dist/{AddressAutocompleteInput-M2F-m-Nh.cjs → AddressAutocompleteInput-DV1DS05i.cjs} +2 -2
  2. package/dist/{AddressAutocompleteInput-M2F-m-Nh.cjs.map → AddressAutocompleteInput-DV1DS05i.cjs.map} +1 -1
  3. package/dist/{AddressAutocompleteInput-DmrGdv0d.mjs → AddressAutocompleteInput-Z80mEIXZ.mjs} +2 -2
  4. package/dist/{AddressAutocompleteInput-DmrGdv0d.mjs.map → AddressAutocompleteInput-Z80mEIXZ.mjs.map} +1 -1
  5. package/dist/{CalendarWidget-CbS9AsMH.mjs → CalendarWidget-CQJfz8Jn.mjs} +2 -2
  6. package/dist/{CalendarWidget-CbS9AsMH.mjs.map → CalendarWidget-CQJfz8Jn.mjs.map} +1 -1
  7. package/dist/{CalendarWidget-B8ZIA_pe.cjs → CalendarWidget-z0It6f_7.cjs} +2 -2
  8. package/dist/{CalendarWidget-B8ZIA_pe.cjs.map → CalendarWidget-z0It6f_7.cjs.map} +1 -1
  9. package/dist/{CardWidget-B4LEZKbB.mjs → CardWidget-BpzZMsvX.mjs} +2 -2
  10. package/dist/{CardWidget-B4LEZKbB.mjs.map → CardWidget-BpzZMsvX.mjs.map} +1 -1
  11. package/dist/{CardWidget-BNW0Yqgd.cjs → CardWidget-Ccmmph6S.cjs} +2 -2
  12. package/dist/{CardWidget-BNW0Yqgd.cjs.map → CardWidget-Ccmmph6S.cjs.map} +1 -1
  13. package/dist/{CardWidget-CyNXwk60.cjs → CardWidget-D_3rdNrP.cjs} +3 -3
  14. package/dist/{CatchUpWidget-Cj10cTha.mjs → CatchUpWidget-BCe8hmdk.mjs} +2 -2
  15. package/dist/{CatchUpWidget-Cj10cTha.mjs.map → CatchUpWidget-BCe8hmdk.mjs.map} +1 -1
  16. package/dist/{CatchUpWidget-CiVhawuh.cjs → CatchUpWidget-DCDoIckB.cjs} +2 -2
  17. package/dist/{CatchUpWidget-CiVhawuh.cjs.map → CatchUpWidget-DCDoIckB.cjs.map} +1 -1
  18. package/dist/ContainerWidget-B8Ckbqiq.cjs +8 -0
  19. package/dist/{ContainerWidget-Dpt2viZ0.cjs → ContainerWidget-BEHBqh0a.cjs} +2 -2
  20. package/dist/{ContainerWidget-Dpt2viZ0.cjs.map → ContainerWidget-BEHBqh0a.cjs.map} +1 -1
  21. package/dist/{ContainerWidget-DSQ151lW.mjs → ContainerWidget-Bdq6CaDc.mjs} +2 -2
  22. package/dist/{ContainerWidget-DSQ151lW.mjs.map → ContainerWidget-Bdq6CaDc.mjs.map} +1 -1
  23. package/dist/{FluidProvider-BGn3iZIK.mjs → FluidProvider-DV227FL2.mjs} +20 -20
  24. package/dist/{FluidProvider-BGn3iZIK.mjs.map → FluidProvider-DV227FL2.mjs.map} +1 -1
  25. package/dist/{FluidProvider-BYP7L-lk.cjs → FluidProvider-Dgy4onF4.cjs} +20 -20
  26. package/dist/{FluidProvider-BYP7L-lk.cjs.map → FluidProvider-Dgy4onF4.cjs.map} +1 -1
  27. package/dist/{LayoutWidget-DCHpM0WT.cjs → LayoutWidget-DDviSQKj.cjs} +3 -3
  28. package/dist/{LayoutWidget-D8oT-Xnt.cjs → LayoutWidget-DOz-WOsy.cjs} +2 -2
  29. package/dist/{LayoutWidget-D8oT-Xnt.cjs.map → LayoutWidget-DOz-WOsy.cjs.map} +1 -1
  30. package/dist/{LayoutWidget-Byp1iMxL.mjs → LayoutWidget-DsXDBXSO.mjs} +2 -2
  31. package/dist/{LayoutWidget-Byp1iMxL.mjs.map → LayoutWidget-DsXDBXSO.mjs.map} +1 -1
  32. package/dist/{MessagingScreen-DyckzPKi.cjs → MessagingScreen-C69BJ8Fz.cjs} +2 -2
  33. package/dist/{MessagingScreen-DyckzPKi.cjs.map → MessagingScreen-C69BJ8Fz.cjs.map} +1 -1
  34. package/dist/{MessagingScreen-BvtYIaz1.mjs → MessagingScreen-CCb05_Wj.mjs} +2 -2
  35. package/dist/{MessagingScreen-BvtYIaz1.mjs.map → MessagingScreen-CCb05_Wj.mjs.map} +1 -1
  36. package/dist/{MessagingScreen-CVMKVllz.cjs → MessagingScreen-DiaV8xau.cjs} +13 -13
  37. package/dist/{MessagingScreen-B-HQlj-7.mjs → MessagingScreen-r732O1LD.mjs} +13 -13
  38. package/dist/{MySiteWidget-C_qQJaPH.mjs → MySiteWidget-BvFHv9me.mjs} +2 -2
  39. package/dist/{MySiteWidget-C_qQJaPH.mjs.map → MySiteWidget-BvFHv9me.mjs.map} +1 -1
  40. package/dist/{MySiteWidget-CGWlrGMu.cjs → MySiteWidget-BwmprXJj.cjs} +2 -2
  41. package/dist/{MySiteWidget-CGWlrGMu.cjs.map → MySiteWidget-BwmprXJj.cjs.map} +1 -1
  42. package/dist/{OrdersScreen-90pl5JDi.cjs → OrdersScreen-BlP4uKE8.cjs} +2 -2
  43. package/dist/{OrdersScreen-90pl5JDi.cjs.map → OrdersScreen-BlP4uKE8.cjs.map} +1 -1
  44. package/dist/{OrdersScreen-DVdSKNXt.mjs → OrdersScreen-CZEhg3LN.mjs} +13 -13
  45. package/dist/{OrdersScreen-B9MdErRH.cjs → OrdersScreen-DYyG4PZG.cjs} +13 -13
  46. package/dist/{OrdersScreen-Cv-FDSUM.mjs → OrdersScreen-S4YnUuzD.mjs} +2 -2
  47. package/dist/{OrdersScreen-Cv-FDSUM.mjs.map → OrdersScreen-S4YnUuzD.mjs.map} +1 -1
  48. package/dist/{PointsWidget-D_wPrx7u.mjs → PointsWidget-BvLIjvRG.mjs} +2 -2
  49. package/dist/{PointsWidget-D_wPrx7u.mjs.map → PointsWidget-BvLIjvRG.mjs.map} +1 -1
  50. package/dist/{PointsWidget-Cj3Vlk8M.cjs → PointsWidget-Q3s6gojq.cjs} +2 -2
  51. package/dist/{PointsWidget-Cj3Vlk8M.cjs.map → PointsWidget-Q3s6gojq.cjs.map} +1 -1
  52. package/dist/{ProfileScreen-dmneGRbC.mjs → ProfileScreen-BJUYFJ_D.mjs} +3 -3
  53. package/dist/{ProfileScreen-dmneGRbC.mjs.map → ProfileScreen-BJUYFJ_D.mjs.map} +1 -1
  54. package/dist/{ProfileScreen-hadK4_ku.mjs → ProfileScreen-CmqHo3UG.mjs} +14 -14
  55. package/dist/{ProfileScreen-BSN9JbnZ.cjs → ProfileScreen-DFiM2Iv_.cjs} +14 -14
  56. package/dist/{ProfileScreen-DmjL6T2t.cjs → ProfileScreen-Dta2L4BA.cjs} +3 -3
  57. package/dist/{ProfileScreen-DmjL6T2t.cjs.map → ProfileScreen-Dta2L4BA.cjs.map} +1 -1
  58. package/dist/{RecentActivityWidget-BwRBJmUU.cjs → RecentActivityWidget-NkdK9KfL.cjs} +2 -2
  59. package/dist/{RecentActivityWidget-BwRBJmUU.cjs.map → RecentActivityWidget-NkdK9KfL.cjs.map} +1 -1
  60. package/dist/{RecentActivityWidget-YZNGdnXV.mjs → RecentActivityWidget-ziAimCYB.mjs} +2 -2
  61. package/dist/{RecentActivityWidget-YZNGdnXV.mjs.map → RecentActivityWidget-ziAimCYB.mjs.map} +1 -1
  62. package/dist/{ScreenRenderer-CWjMFFLJ.mjs → ScreenRenderer-BTSp4KZp.mjs} +2 -2
  63. package/dist/{ScreenRenderer-CWjMFFLJ.mjs.map → ScreenRenderer-BTSp4KZp.mjs.map} +1 -1
  64. package/dist/{ScreenRenderer-V_7y2I2L.cjs → ScreenRenderer-DowNn61T.cjs} +2 -2
  65. package/dist/{ScreenRenderer-V_7y2I2L.cjs.map → ScreenRenderer-DowNn61T.cjs.map} +1 -1
  66. package/dist/{ShopScreen-DFnN5NbE.cjs → ShopScreen-Bqup6l0o.cjs} +2 -2
  67. package/dist/{ShopScreen-DFnN5NbE.cjs.map → ShopScreen-Bqup6l0o.cjs.map} +1 -1
  68. package/dist/{ShopScreen-DL6UTc0q.mjs → ShopScreen-CC0t8ZDI.mjs} +13 -13
  69. package/dist/{ShopScreen--lr0_Etl.mjs → ShopScreen-CzYB_rpN.mjs} +2 -2
  70. package/dist/{ShopScreen--lr0_Etl.mjs.map → ShopScreen-CzYB_rpN.mjs.map} +1 -1
  71. package/dist/{ShopScreen-Cvt6SX-5.cjs → ShopScreen-D3Celpra.cjs} +13 -13
  72. package/dist/{SubscriptionsScreen-CRRnyUHm.cjs → SubscriptionsScreen-BJ8Qsjec.cjs} +14 -14
  73. package/dist/{SubscriptionsScreen-DRKv5sy7.cjs → SubscriptionsScreen-BMVXwFoz.cjs} +3 -3
  74. package/dist/{SubscriptionsScreen-DRKv5sy7.cjs.map → SubscriptionsScreen-BMVXwFoz.cjs.map} +1 -1
  75. package/dist/{SubscriptionsScreen-DpU1lqP5.mjs → SubscriptionsScreen-DRRbvg51.mjs} +3 -3
  76. package/dist/{SubscriptionsScreen-DpU1lqP5.mjs.map → SubscriptionsScreen-DRRbvg51.mjs.map} +1 -1
  77. package/dist/{SubscriptionsScreen-DulSZ0V7.mjs → SubscriptionsScreen-DRcs0JF5.mjs} +14 -14
  78. package/dist/{ToDoWidget-DWegq3Rs.mjs → ToDoWidget-C6Kk46b7.mjs} +2 -2
  79. package/dist/{ToDoWidget-DWegq3Rs.mjs.map → ToDoWidget-C6Kk46b7.mjs.map} +1 -1
  80. package/dist/{ToDoWidget-BZi0xnAv.cjs → ToDoWidget-Szg7F0yS.cjs} +2 -2
  81. package/dist/{ToDoWidget-BZi0xnAv.cjs.map → ToDoWidget-Szg7F0yS.cjs.map} +1 -1
  82. package/dist/{ToDoWidget-BDOZr5av.cjs → ToDoWidget-YlUL-lNO.cjs} +2 -2
  83. package/dist/index.cjs +28 -28
  84. package/dist/index.mjs +28 -28
  85. package/dist/{registry-context-BISkmKM2.cjs → registry-context-BliPhkUQ.cjs} +7 -3
  86. package/dist/{registry-context-DWAhoLQA.mjs.map → registry-context-BliPhkUQ.cjs.map} +1 -1
  87. package/dist/{registry-context-DWAhoLQA.mjs → registry-context-CSsT6Rtk.mjs} +7 -3
  88. package/dist/{registry-context-BISkmKM2.cjs.map → registry-context-CSsT6Rtk.mjs.map} +1 -1
  89. package/package.json +14 -14
  90. package/dist/ContainerWidget-CEZnuIbT.cjs +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"PointsWidget-D_wPrx7u.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 amount: 20,\n createdAt: daysAgo(3),\n transactionType: \"new_order\",\n hasSource: true,\n },\n {\n id: 2,\n amount: 50,\n createdAt: daysAgo(14),\n transactionType: \"referral_bonus\",\n hasSource: true,\n },\n {\n id: 3,\n amount: -75,\n createdAt: daysAgo(60),\n transactionType: null,\n hasSource: true,\n },\n {\n id: 4,\n amount: 30,\n createdAt: daysAgo(90),\n transactionType: \"welcome_reward\",\n hasSource: true,\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 formatBalance = (balance: number): string => {\n return balance.toLocaleString(\"en-US\");\n};\n\nfunction formatTransactionType(entry: PointsEntry): string {\n if (entry.transactionType) {\n return entry.transactionType\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n }\n if (entry.hasSource) {\n return entry.amount > 0 ? \"Points Awarded\" : \"Points Redeemed\";\n }\n return \"Transaction\";\n}\n\nfunction formatEntryDate(dateString: string): string {\n if (!dateString) return \"\";\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\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 isLast,\n textColor,\n accentColor,\n backgroundColor,\n}: {\n entry: PointsEntry;\n isLast: boolean;\n textColor: ColorOptions;\n accentColor: ColorOptions;\n backgroundColor: ColorOptions;\n}) {\n const isPositive = entry.amount >= 0;\n const prefix = isPositive ? \"+\" : \"\";\n return (\n <div className=\"flex flex-row items-stretch gap-3\">\n <div className=\"relative flex w-2 flex-col items-center\">\n {!isLast && (\n <div\n className={`bg-${textColor}/40 absolute top-3 -bottom-3 left-1/2 w-px -translate-x-1/2`}\n />\n )}\n <div\n className={`border-${textColor}/60 bg-${backgroundColor} relative mt-3 h-2 w-2 shrink-0 rounded-full border`}\n />\n </div>\n <div className=\"flex flex-1 flex-row items-start justify-between py-1.5\">\n <div className=\"flex min-w-0 flex-col\">\n <div className={`text-sm font-medium text-${textColor} truncate`}>\n {formatTransactionType(entry)}\n </div>\n <div className={`text-sm text-${textColor} opacity-70`}>\n {formatEntryDate(entry.createdAt)}\n </div>\n </div>\n <div\n className={`text-sm font-medium ${isPositive ? `text-${accentColor}` : \"text-destructive\"}`}\n >\n {prefix}\n {entry.amount.toLocaleString(\"en-US\")}\n </div>\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 ${!historyOpen ? \"hidden\" : \"\"}`}\n >\n {data.entries.map((entry, index) => (\n <PointsEntryRow\n key={entry.id}\n entry={entry}\n isLast={index === data.entries.length - 1}\n textColor={textColor}\n accentColor={accentColor}\n backgroundColor={backgroundColor}\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 positive points amounts\",\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
+ {"version":3,"file":"PointsWidget-BvLIjvRG.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 amount: 20,\n createdAt: daysAgo(3),\n transactionType: \"new_order\",\n hasSource: true,\n },\n {\n id: 2,\n amount: 50,\n createdAt: daysAgo(14),\n transactionType: \"referral_bonus\",\n hasSource: true,\n },\n {\n id: 3,\n amount: -75,\n createdAt: daysAgo(60),\n transactionType: null,\n hasSource: true,\n },\n {\n id: 4,\n amount: 30,\n createdAt: daysAgo(90),\n transactionType: \"welcome_reward\",\n hasSource: true,\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 formatBalance = (balance: number): string => {\n return balance.toLocaleString(\"en-US\");\n};\n\nfunction formatTransactionType(entry: PointsEntry): string {\n if (entry.transactionType) {\n return entry.transactionType\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n }\n if (entry.hasSource) {\n return entry.amount > 0 ? \"Points Awarded\" : \"Points Redeemed\";\n }\n return \"Transaction\";\n}\n\nfunction formatEntryDate(dateString: string): string {\n if (!dateString) return \"\";\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\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 isLast,\n textColor,\n accentColor,\n backgroundColor,\n}: {\n entry: PointsEntry;\n isLast: boolean;\n textColor: ColorOptions;\n accentColor: ColorOptions;\n backgroundColor: ColorOptions;\n}) {\n const isPositive = entry.amount >= 0;\n const prefix = isPositive ? \"+\" : \"\";\n return (\n <div className=\"flex flex-row items-stretch gap-3\">\n <div className=\"relative flex w-2 flex-col items-center\">\n {!isLast && (\n <div\n className={`bg-${textColor}/40 absolute top-3 -bottom-3 left-1/2 w-px -translate-x-1/2`}\n />\n )}\n <div\n className={`border-${textColor}/60 bg-${backgroundColor} relative mt-3 h-2 w-2 shrink-0 rounded-full border`}\n />\n </div>\n <div className=\"flex flex-1 flex-row items-start justify-between py-1.5\">\n <div className=\"flex min-w-0 flex-col\">\n <div className={`text-sm font-medium text-${textColor} truncate`}>\n {formatTransactionType(entry)}\n </div>\n <div className={`text-sm text-${textColor} opacity-70`}>\n {formatEntryDate(entry.createdAt)}\n </div>\n </div>\n <div\n className={`text-sm font-medium ${isPositive ? `text-${accentColor}` : \"text-destructive\"}`}\n >\n {prefix}\n {entry.amount.toLocaleString(\"en-US\")}\n </div>\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 ${!historyOpen ? \"hidden\" : \"\"}`}\n >\n {data.entries.map((entry, index) => (\n <PointsEntryRow\n key={entry.id}\n entry={entry}\n isLast={index === data.entries.length - 1}\n textColor={textColor}\n accentColor={accentColor}\n backgroundColor={backgroundColor}\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 positive points amounts\",\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-BISkmKM2.cjs");
2
+ const require_registry_context = require("./registry-context-BliPhkUQ.cjs");
3
3
  const require_error_state = require("./error-state-CBV4TJ60.cjs");
4
4
  const require_registries = require("./registries-BWdQbKof.cjs");
5
5
  const require_preview_context = require("./preview-context-BVJqoAhR.cjs");
@@ -318,4 +318,4 @@ Object.defineProperty(exports, "pointsWidgetPropertySchema", {
318
318
  }
319
319
  });
320
320
 
321
- //# sourceMappingURL=PointsWidget-Cj3Vlk8M.cjs.map
321
+ //# sourceMappingURL=PointsWidget-Q3s6gojq.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PointsWidget-Cj3Vlk8M.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","borderWidthClasses","borderColorClasses","ErrorState","Coins","ChevronDown","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"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 amount: 20,\n createdAt: daysAgo(3),\n transactionType: \"new_order\",\n hasSource: true,\n },\n {\n id: 2,\n amount: 50,\n createdAt: daysAgo(14),\n transactionType: \"referral_bonus\",\n hasSource: true,\n },\n {\n id: 3,\n amount: -75,\n createdAt: daysAgo(60),\n transactionType: null,\n hasSource: true,\n },\n {\n id: 4,\n amount: 30,\n createdAt: daysAgo(90),\n transactionType: \"welcome_reward\",\n hasSource: true,\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 formatBalance = (balance: number): string => {\n return balance.toLocaleString(\"en-US\");\n};\n\nfunction formatTransactionType(entry: PointsEntry): string {\n if (entry.transactionType) {\n return entry.transactionType\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n }\n if (entry.hasSource) {\n return entry.amount > 0 ? \"Points Awarded\" : \"Points Redeemed\";\n }\n return \"Transaction\";\n}\n\nfunction formatEntryDate(dateString: string): string {\n if (!dateString) return \"\";\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\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 isLast,\n textColor,\n accentColor,\n backgroundColor,\n}: {\n entry: PointsEntry;\n isLast: boolean;\n textColor: ColorOptions;\n accentColor: ColorOptions;\n backgroundColor: ColorOptions;\n}) {\n const isPositive = entry.amount >= 0;\n const prefix = isPositive ? \"+\" : \"\";\n return (\n <div className=\"flex flex-row items-stretch gap-3\">\n <div className=\"relative flex w-2 flex-col items-center\">\n {!isLast && (\n <div\n className={`bg-${textColor}/40 absolute top-3 -bottom-3 left-1/2 w-px -translate-x-1/2`}\n />\n )}\n <div\n className={`border-${textColor}/60 bg-${backgroundColor} relative mt-3 h-2 w-2 shrink-0 rounded-full border`}\n />\n </div>\n <div className=\"flex flex-1 flex-row items-start justify-between py-1.5\">\n <div className=\"flex min-w-0 flex-col\">\n <div className={`text-sm font-medium text-${textColor} truncate`}>\n {formatTransactionType(entry)}\n </div>\n <div className={`text-sm text-${textColor} opacity-70`}>\n {formatEntryDate(entry.createdAt)}\n </div>\n </div>\n <div\n className={`text-sm font-medium ${isPositive ? `text-${accentColor}` : \"text-destructive\"}`}\n >\n {prefix}\n {entry.amount.toLocaleString(\"en-US\")}\n </div>\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 ${!historyOpen ? \"hidden\" : \"\"}`}\n >\n {data.entries.map((entry, index) => (\n <PointsEntryRow\n key={entry.id}\n entry={entry}\n isLast={index === data.entries.length - 1}\n textColor={textColor}\n accentColor={accentColor}\n backgroundColor={backgroundColor}\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 positive points amounts\",\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":";;;;;;;;;;AAEA,MAAM,sBAAM,IAAI,MAAM;AAEtB,SAAS,QAAQ,MAAsB;AACrC,yBAAO,IAAI,KAAK,IAAI,SAAS,GAAG,OAAO,MAAW,EAAC,aAAa;;AAGlE,MAAa,eAA2B;CACtC,SAAS;CACT,SAAS;EACP;GACE,IAAI;GACJ,QAAQ;GACR,WAAW,QAAQ,EAAE;GACrB,iBAAiB;GACjB,WAAW;GACZ;EACD;GACE,IAAI;GACJ,QAAQ;GACR,WAAW,QAAQ,GAAG;GACtB,iBAAiB;GACjB,WAAW;GACZ;EACD;GACE,IAAI;GACJ,QAAQ;GACR,WAAW,QAAQ,GAAG;GACtB,iBAAiB;GACjB,WAAW;GACZ;EACD;GACE,IAAI;GACJ,QAAQ;GACR,WAAW,QAAQ,GAAG;GACtB,iBAAiB;GACjB,WAAW;GACZ;EACF;CACF;;;AC5BD,MAAa,0BAA0B;AAEvC,SAAgB,kBAAqD;CACnE,MAAM,aAAaA,oBAAAA,eAAe;CAClC,MAAM,EAAE,cAAcC,wBAAAA,yBAAyB;CAC/C,MAAM,iBAAiBC,yBAAAA,6BAA6B;CACpD,MAAM,EAAE,YAAY;CACpB,MAAM,aAAa,eAAe,WAAW;AAW7C,SAAA,GAAA,sBAAA,UAAgB;EACd,UAAU;GACR;GACA;GACA,YAAY,YAAY;GACxB,cAAc;GACf;EACD,UAAU,EAAE,aACV,WAAW,kBAAkB,cAAc,IAAI,OAAO;EACxD,SAAS,CAAC;EACV,GAAI,aAAa,EAAE,iBAAiB,cAAc;EACnD,CAAC;;;;;;;;AChBJ,MAAM,iBAAiB,YAA4B;AACjD,QAAO,QAAQ,eAAe,QAAQ;;AAGxC,SAAS,sBAAsB,OAA4B;AACzD,KAAI,MAAM,gBACR,QAAO,MAAM,gBACV,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,IAAI;AAEd,KAAI,MAAM,UACR,QAAO,MAAM,SAAS,IAAI,mBAAmB;AAE/C,QAAO;;AAGT,SAAS,gBAAgB,YAA4B;AACnD,KAAI,CAAC,WAAY,QAAO;AAExB,QADa,IAAI,KAAK,WAAW,CACrB,mBAAmB,KAAA,GAAW;EACxC,OAAO;EACP,KAAK;EACL,MAAM;EACP,CAAC;;AA2BJ,SAAS,eAAe,EACtB,OACA,QACA,WACA,aACA,mBAOC;CACD,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,SAAS,aAAa,MAAM;AAClC,QACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EAAK,WAAU;YAAf,CACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;GAAK,WAAU;aAAf,CACG,CAAC,UACA,iBAAA,GAAA,kBAAA,KAAC,OAAD,EACE,WAAW,MAAM,UAAU,8DAC3B,CAAA,EAEJ,iBAAA,GAAA,kBAAA,KAAC,OAAD,EACE,WAAW,UAAU,UAAU,SAAS,gBAAgB,sDACxD,CAAA,CACE;MACN,iBAAA,GAAA,kBAAA,MAAC,OAAD;GAAK,WAAU;aAAf,CACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;IAAK,WAAU;cAAf,CACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;KAAK,WAAW,4BAA4B,UAAU;eACnD,sBAAsB,MAAM;KACzB,CAAA,EACN,iBAAA,GAAA,kBAAA,KAAC,OAAD;KAAK,WAAW,gBAAgB,UAAU;eACvC,gBAAgB,MAAM,UAAU;KAC7B,CAAA,CACF;OACN,iBAAA,GAAA,kBAAA,MAAC,OAAD;IACE,WAAW,uBAAuB,aAAa,QAAQ,gBAAgB;cADzE,CAGG,QACA,MAAM,OAAO,eAAe,QAAQ,CACjC;MACF;KACF;;;AAIV,SAAgB,aAAa,EAE3B,eAAe,MACf,QAAQ,UACR,gBAAgB,MAChB,aAAa,cAGb,eAAe,WAGf,iBAAiB,MACjB,eAAe,WAGf,aAAa;CAAE,MAAM;CAAS,OAAO;CAAc,EACnD,YAAY,cACZ,cAAc,WACd,UAAU,GACV,eAAe,MACf,cAAc,QACd,cAAc,SAEd,WACA,GAAG,SACoC;CACvC,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,UAA2B,MAAM;CACrD,MAAM,kBAAA,GAAA,MAAA,QAAwB;CAE9B,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,mBACH,WAAW,UAAU,aAAa,WAAW,UAAU,aACxD,WAAW,SAAS,UAChB,OAAO,WAAW,SAAS,aAAa,WAAW,SAAS,SAAS,KACrE;CAEN,MAAM,EAAE,MAAM,WAAW,YAAY,iBAAiB;AAEtD,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,WAAW,sCAAsC,aAAa,MAAM,gBAAgB,GAAGC,mBAAAA,mBAAmB,aAAa,GAAG,gBAAgB,SAASC,mBAAAA,mBAAmB,eAAe,GAAG,GAAG,aAAa;EACxM,OAAO,EAAE,iBAAiB;EAC1B,GAAI;YAEJ,iBAAA,GAAA,kBAAA,MAAC,OAAD;GAAK,WAAW,KAAK,QAAQ;aAA7B;IAEG,gBACC,iBAAA,GAAA,kBAAA,KAAC,MAAD;KACE,WAAW,QAAQ,cAAc,8BAA8B;eAE9D;KACE,CAAA;IAEN,CAAC,aAAa,QACb,iBAAA,GAAA,kBAAA,KAAC,QAAD;KACE,WAAW,+BAA+B,aAAa;eAEtD,cAAc,KAAK,QAAQ;KACvB,CAAA;IAIR,YACC,iBAAA,GAAA,kBAAA,KAAC,OAAD;KAAK,WAAU;eACb,iBAAA,GAAA,kBAAA,KAAC,OAAD,EAAK,WAAU,kFAAmF,CAAA;KAC9F,CAAA,GACJ,UACF,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,YAAD,EAAc,CAAA,GACZ,mBAAmB,CAAC,QAAQ,KAAK,QAAQ,WAAW,KAEtD,iBAAA,GAAA,kBAAA,MAAC,OAAD;KAAK,WAAU;eAAf,CACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,OAAD,EAAO,WAAW,gBAAgB,UAAU,cAAgB,CAAA,EAC5D,iBAAA,GAAA,kBAAA,KAAC,KAAD;MAAG,WAAW,8BAA8B,UAAU;gBAAc;MAEhE,CAAA,CACA;SACJ,kBAAkB,QAAQ,KAAK,QAAQ,SAAS,IAElD,iBAAA,GAAA,kBAAA,MAAC,OAAD;KAAK,WAAU;eAAf;MAEE,iBAAA,GAAA,kBAAA,MAAC,UAAD;OACE,MAAK;OACL,iBAAe;OACf,iBAAe;OACf,eAAe,gBAAgB,SAAS,CAAC,KAAK;OAC9C,WAAW,uDAAuD,UAAU;iBAL9E,CAOE,iBAAA,GAAA,kBAAA,KAAC,QAAD;QAAM,WAAU;kBAAoB;QAAoB,CAAA,EACxD,iBAAA,GAAA,kBAAA,KAACC,aAAAA,aAAD,EACE,WAAW,4CAA4C,cAAc,eAAe,MACpF,CAAA,CACK;;MACT,iBAAA,GAAA,kBAAA,KAAC,OAAD,EAAK,WAAW,MAAM,UAAU,kBAAoB,CAAA;MAGpD,iBAAA,GAAA,kBAAA,KAAC,OAAD;OACE,IAAI;OACJ,WAAW,iBAAiB,CAAC,cAAc,WAAW;iBAErD,KAAK,QAAQ,KAAK,OAAO,UACxB,iBAAA,GAAA,kBAAA,KAAC,gBAAD;QAES;QACP,QAAQ,UAAU,KAAK,QAAQ,SAAS;QAC7B;QACE;QACI;QACjB,EANK,MAAM,GAMX,CACF;OACE,CAAA;MACF;SACJ;IACA;;EACF,CAAA;;AAIV,MAAa,6BAAmD;CAC9D,YAAY;CACZ,aAAa;CACb,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GAEd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GAEd,OAAO;GACP,qBAAqB;GACtB;EACDC,mBAAAA,iBAAiB;GACf,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACP,qBAAqB;GACtB,CAAC;EACFC,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACP,qBAAqB;GACtB,CAAC;EAGFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EAGF;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GAEd,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GAEd,OAAO;GACP,qBAAqB;GACtB;EAGD;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR;EACDA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GAEP,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACFC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GAEd,OAAO;GACR,CAAC;EACH;CACF"}
1
+ {"version":3,"file":"PointsWidget-Q3s6gojq.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","borderWidthClasses","borderColorClasses","ErrorState","Coins","ChevronDown","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"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 amount: 20,\n createdAt: daysAgo(3),\n transactionType: \"new_order\",\n hasSource: true,\n },\n {\n id: 2,\n amount: 50,\n createdAt: daysAgo(14),\n transactionType: \"referral_bonus\",\n hasSource: true,\n },\n {\n id: 3,\n amount: -75,\n createdAt: daysAgo(60),\n transactionType: null,\n hasSource: true,\n },\n {\n id: 4,\n amount: 30,\n createdAt: daysAgo(90),\n transactionType: \"welcome_reward\",\n hasSource: true,\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 formatBalance = (balance: number): string => {\n return balance.toLocaleString(\"en-US\");\n};\n\nfunction formatTransactionType(entry: PointsEntry): string {\n if (entry.transactionType) {\n return entry.transactionType\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n }\n if (entry.hasSource) {\n return entry.amount > 0 ? \"Points Awarded\" : \"Points Redeemed\";\n }\n return \"Transaction\";\n}\n\nfunction formatEntryDate(dateString: string): string {\n if (!dateString) return \"\";\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\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 isLast,\n textColor,\n accentColor,\n backgroundColor,\n}: {\n entry: PointsEntry;\n isLast: boolean;\n textColor: ColorOptions;\n accentColor: ColorOptions;\n backgroundColor: ColorOptions;\n}) {\n const isPositive = entry.amount >= 0;\n const prefix = isPositive ? \"+\" : \"\";\n return (\n <div className=\"flex flex-row items-stretch gap-3\">\n <div className=\"relative flex w-2 flex-col items-center\">\n {!isLast && (\n <div\n className={`bg-${textColor}/40 absolute top-3 -bottom-3 left-1/2 w-px -translate-x-1/2`}\n />\n )}\n <div\n className={`border-${textColor}/60 bg-${backgroundColor} relative mt-3 h-2 w-2 shrink-0 rounded-full border`}\n />\n </div>\n <div className=\"flex flex-1 flex-row items-start justify-between py-1.5\">\n <div className=\"flex min-w-0 flex-col\">\n <div className={`text-sm font-medium text-${textColor} truncate`}>\n {formatTransactionType(entry)}\n </div>\n <div className={`text-sm text-${textColor} opacity-70`}>\n {formatEntryDate(entry.createdAt)}\n </div>\n </div>\n <div\n className={`text-sm font-medium ${isPositive ? `text-${accentColor}` : \"text-destructive\"}`}\n >\n {prefix}\n {entry.amount.toLocaleString(\"en-US\")}\n </div>\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 ${!historyOpen ? \"hidden\" : \"\"}`}\n >\n {data.entries.map((entry, index) => (\n <PointsEntryRow\n key={entry.id}\n entry={entry}\n isLast={index === data.entries.length - 1}\n textColor={textColor}\n accentColor={accentColor}\n backgroundColor={backgroundColor}\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 positive points amounts\",\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,12 +1,12 @@
1
1
  import { mt as useAccountApi } from "./portal_tenant_content-XFmQhJPT.mjs";
2
- import { H as usePayApi, V as useLanguagesApi, n as useFluidContext } from "./FluidProvider-BGn3iZIK.mjs";
2
+ import { H as usePayApi, V as useLanguagesApi, n as useFluidContext } from "./FluidProvider-DV227FL2.mjs";
3
3
  import { i as useCountriesApi } from "./ContactsTranslationBridge-nXi8boqu.mjs";
4
4
  import { a as useActiveLocale } from "./static-dict-adapter-DpHMB055.mjs";
5
5
  import { B as Label, Bn as useZodForm, En as Button, Q as Dialog, dn as Breadcrumb, et as DialogContent, fn as BreadcrumbItem, hn as BreadcrumbPage, j as Input, mn as BreadcrumbList, nt as DialogFooter, ot as DialogTitle, p as fluidToast, rt as DialogHeader } from "./src-Cn1_6Nn3.mjs";
6
6
  import { n as ScreenHeaderBreadcrumbs } from "./ScreenHeaderContext-CyTaQp-O.mjs";
7
7
  import { n as payKeys, r as storeKeys, t as accountKeys } from "./query-keys-xJy_fapN.mjs";
8
8
  import { t as useAccount } from "./use-account-DEj6E1PK.mjs";
9
- import { a as AddressFormDialog, d as UserInfoDialog, f as ConfirmActionDialog, h as useProfileTranslation, i as CreditCardFormDialog, m as ProfileTranslationBridge, n as createFluidPayApiAdapter, o as EditPaymentMethodDialog, p as EllipsesDropdown, r as mapToFluidPayPaymentMethod, s as FluidPayCoreProvider, t as AddressAutocompleteInput } from "./AddressAutocompleteInput-DmrGdv0d.mjs";
9
+ import { a as AddressFormDialog, d as UserInfoDialog, f as ConfirmActionDialog, h as useProfileTranslation, i as CreditCardFormDialog, m as ProfileTranslationBridge, n as createFluidPayApiAdapter, o as EditPaymentMethodDialog, p as EllipsesDropdown, r as mapToFluidPayPaymentMethod, s as FluidPayCoreProvider, t as AddressAutocompleteInput } from "./AddressAutocompleteInput-Z80mEIXZ.mjs";
10
10
  import { f as usePortalUpdateSettings, s as usePortalMySiteProfile } from "./use-mysite-portal-DOUSRysS.mjs";
11
11
  import { useCallback, useMemo, useState } from "react";
12
12
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
@@ -1364,4 +1364,4 @@ const profileScreenPropertySchema = {
1364
1364
  //#endregion
1365
1365
  export { profileScreenPropertySchema as n, ProfileScreen as t };
1366
1366
 
1367
- //# sourceMappingURL=ProfileScreen-dmneGRbC.mjs.map
1367
+ //# sourceMappingURL=ProfileScreen-BJUYFJ_D.mjs.map