@burdenoff/microfe-billing 2026.623.3 → 2026.624.1

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 (35) hide show
  1. package/dist/billing/BillingUserRoutes.js +3 -3
  2. package/dist/billing/BillingUserRoutes.js.map +1 -1
  3. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +34 -34
  4. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  5. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +94 -94
  6. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  7. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +40 -40
  8. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  9. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +10 -10
  10. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  11. package/dist/billing/modules/billing/pages/TransactionsPage.js +62 -62
  12. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  13. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +7 -7
  14. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  15. package/dist/billing/modules/earnings/pages/EarningsPage.js +21 -21
  16. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  17. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +4 -4
  18. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  19. package/dist/billing/modules/earnings/pages/PayoutsPage.js +33 -33
  20. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  21. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +4 -4
  22. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  23. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +4 -4
  24. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  25. package/dist/billing/modules/settings/pages/SettingsPage.js +57 -57
  26. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  27. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +33 -33
  28. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  29. package/dist/billing/shared/components/AccessDenied.js +4 -4
  30. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  31. package/dist/billing/shared/components/ActorIdentity.js +8 -8
  32. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  33. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +11 -11
  34. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  35. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AccessDenied.js","names":[],"sources":["../../../../src/billing/shared/components/AccessDenied.tsx"],"sourcesContent":["/**\n * Shared Access Denied Component\n * Displays when user lacks permission to view a page\n */\n\nimport type { FC } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface AccessDeniedProps {\n message?: string;\n}\n\nexport const AccessDenied: FC<AccessDeniedProps> = ({ message }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const displayMessage =\n message ??\n tr('billing.accessDenied.defaultMessage', \"You don't have permission to access this page.\");\n\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-muted flex items-center justify-center\">\n <svg\n className=\"size-6 text-muted-foreground\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.accessDenied.title', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground max-w-sm\">{displayMessage}</p>\n </div>\n </div>\n );\n};\n"],"mappings":";;;AAYA,IAAa,KAAuC,EAAE,iBAAc;CAClE,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAGnC,IACJ,KACA,EAAG,uCAAuC,iDAAiD;AAE7F,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MACE,WAAU;MACV,MAAK;MACL,SAAQ;MACR,QAAO;gBAEP,kBAAC,QAAD;OACE,eAAc;OACd,gBAAe;OACf,aAAa;OACb,GAAE;OACF,CAAA;MACE,CAAA;KACF,CAAA;IACN,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,8BAA8B,gBAAgB;KAC/C,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAA0C;KAAmB,CAAA;IACtE;;EACF,CAAA"}
1
+ {"version":3,"file":"AccessDenied.js","names":[],"sources":["../../../../src/billing/shared/components/AccessDenied.tsx"],"sourcesContent":["/**\n * Shared Access Denied Component\n * Displays when user lacks permission to view a page\n */\n\nimport type { FC } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface AccessDeniedProps {\n message?: string;\n}\n\nexport const AccessDenied: FC<AccessDeniedProps> = ({ message }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const displayMessage =\n message ??\n tr('billing.accessDenied.defaultMessage', \"You don't have permission to access this page.\");\n\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.accessDenied.title', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary max-w-sm\">{displayMessage}</p>\n </div>\n </div>\n );\n};\n"],"mappings":";;;AAYA,IAAa,KAAuC,EAAE,iBAAc;CAClE,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAGnC,IACJ,KACA,EAAG,uCAAuC,iDAAiD;AAE7F,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MACE,WAAU;MACV,MAAK;MACL,SAAQ;MACR,QAAO;gBAEP,kBAAC,QAAD;OACE,eAAc;OACd,gBAAe;OACf,aAAa;OACb,GAAE;OACF,CAAA;MACE,CAAA;KACF,CAAA;IACN,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,8BAA8B,gBAAgB;KAC/C,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAAwC;KAAmB,CAAA;IACpE;;EACF,CAAA"}
@@ -15,10 +15,10 @@ var s = ({ profile: s, variant: c = "cell" }) => {
15
15
  });
16
16
  }, f = c === "chip", p = c === "inline";
17
17
  return /* @__PURE__ */ a("div", {
18
- className: f ? "inline-flex items-center gap-2 rounded-full border border-border bg-muted/40 px-2 py-1" : p ? "inline-flex items-center gap-2" : "flex items-center gap-3",
18
+ className: f ? "inline-flex items-center gap-2 rounded-full border border-border-subtle bg-bg-sunken/40 px-2 py-1" : p ? "inline-flex items-center gap-2" : "flex items-center gap-3",
19
19
  children: [
20
20
  /* @__PURE__ */ i("div", {
21
- className: f ? "flex size-6 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary" : "flex size-9 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary",
21
+ className: f ? "flex size-6 items-center justify-center rounded-full bg-action-primary-bg/10 text-[10px] font-semibold text-primary" : "flex size-9 items-center justify-center rounded-full bg-action-primary-bg/10 text-xs font-semibold text-primary",
22
22
  "aria-hidden": "true",
23
23
  children: s.avatarUrl ? /* @__PURE__ */ i("img", {
24
24
  src: s.avatarUrl,
@@ -32,27 +32,27 @@ var s = ({ profile: s, variant: c = "cell" }) => {
32
32
  /* @__PURE__ */ a("div", {
33
33
  className: "min-w-0 flex-1",
34
34
  children: [/* @__PURE__ */ i("p", {
35
- className: f ? "text-xs font-medium text-foreground" : "truncate text-sm font-medium text-foreground",
35
+ className: f ? "text-xs font-medium text-text-primary" : "truncate text-sm font-medium text-text-primary",
36
36
  children: s.displayName
37
37
  }), f ? null : /* @__PURE__ */ i("p", {
38
- className: "truncate text-xs text-muted-foreground",
38
+ className: "truncate text-xs text-text-secondary",
39
39
  children: s.email ?? s.secondaryLabel
40
40
  })]
41
41
  }),
42
42
  !f && !p ? /* @__PURE__ */ a("details", {
43
43
  className: "group",
44
44
  children: [/* @__PURE__ */ i("summary", {
45
- className: "cursor-pointer text-[10px] uppercase tracking-wider text-muted-foreground hover:text-foreground",
45
+ className: "cursor-pointer text-[10px] uppercase tracking-wider text-text-secondary hover:text-text-primary",
46
46
  children: "ID"
47
47
  }), /* @__PURE__ */ a("div", {
48
- className: "mt-1 flex items-center gap-2 rounded-md border border-border bg-card px-2 py-1",
48
+ className: "mt-1 flex items-center gap-2 rounded-md border border-border-subtle bg-bg-surface px-2 py-1",
49
49
  children: [/* @__PURE__ */ i("span", {
50
- className: "font-mono text-[11px] text-muted-foreground",
50
+ className: "font-mono text-[11px] text-text-secondary",
51
51
  children: s.actorId
52
52
  }), /* @__PURE__ */ i("button", {
53
53
  type: "button",
54
54
  onClick: d,
55
- className: "text-muted-foreground transition hover:text-foreground",
55
+ className: "text-text-secondary transition hover:text-text-primary",
56
56
  "aria-label": "Copy actor ID",
57
57
  children: i(l ? t : n, { className: "size-3.5" })
58
58
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"ActorIdentity.js","names":[],"sources":["../../../../src/billing/shared/components/ActorIdentity.tsx"],"sourcesContent":["import { useState, type FC } from 'react';\nimport { Check, Copy, User2 } from 'lucide-react';\nimport type { ActorProfile } from '../hooks/useActorProfiles';\n\ninterface ActorIdentityProps {\n profile: ActorProfile;\n variant?: 'cell' | 'inline' | 'chip';\n}\n\nfunction initials(displayName: string): string {\n const cleaned = displayName.trim();\n if (!cleaned) return '?';\n const parts = cleaned.split(/\\s+/).filter(Boolean);\n if (parts.length === 1) return parts[0].charAt(0).toUpperCase();\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\nexport const ActorIdentity: FC<ActorIdentityProps> = ({ profile, variant = 'cell' }) => {\n const [copied, setCopied] = useState(false);\n\n const onCopy = () => {\n if (typeof navigator === 'undefined' || !navigator.clipboard) return;\n void navigator.clipboard.writeText(profile.actorId).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n };\n\n const isChip = variant === 'chip';\n const isInline = variant === 'inline';\n\n return (\n <div\n className={\n isChip\n ? 'inline-flex items-center gap-2 rounded-full border border-border bg-muted/40 px-2 py-1'\n : isInline\n ? 'inline-flex items-center gap-2'\n : 'flex items-center gap-3'\n }\n >\n <div\n className={\n isChip\n ? 'flex size-6 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary'\n : 'flex size-9 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary'\n }\n aria-hidden=\"true\"\n >\n {profile.avatarUrl ? (\n <img src={profile.avatarUrl} alt=\"\" className=\"size-full rounded-full object-cover\" />\n ) : profile.resolved ? (\n initials(profile.displayName)\n ) : (\n <User2 className=\"size-4\" aria-hidden=\"true\" />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p\n className={\n isChip\n ? 'text-xs font-medium text-foreground'\n : 'truncate text-sm font-medium text-foreground'\n }\n >\n {profile.displayName}\n </p>\n {!isChip ? (\n <p className=\"truncate text-xs text-muted-foreground\">\n {profile.email ?? profile.secondaryLabel}\n </p>\n ) : null}\n </div>\n {!isChip && !isInline ? (\n <details className=\"group\">\n <summary className=\"cursor-pointer text-[10px] uppercase tracking-wider text-muted-foreground hover:text-foreground\">\n ID\n </summary>\n <div className=\"mt-1 flex items-center gap-2 rounded-md border border-border bg-card px-2 py-1\">\n <span className=\"font-mono text-[11px] text-muted-foreground\">{profile.actorId}</span>\n <button\n type=\"button\"\n onClick={onCopy}\n className=\"text-muted-foreground transition hover:text-foreground\"\n aria-label=\"Copy actor ID\"\n >\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n </button>\n </div>\n </details>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AASA,SAAS,EAAS,GAA6B;CAC7C,IAAM,IAAU,EAAY,MAAM;AAClC,KAAI,CAAC,EAAS,QAAO;CACrB,IAAM,IAAQ,EAAQ,MAAM,MAAM,CAAC,OAAO,QAAQ;AAElD,QADI,EAAM,WAAW,IAAU,EAAM,GAAG,OAAO,EAAE,CAAC,aAAa,IACvD,EAAM,GAAG,OAAO,EAAE,GAAG,EAAM,EAAM,SAAS,GAAG,OAAO,EAAE,EAAE,aAAa;;AAG/E,IAAa,KAAyC,EAAE,YAAS,aAAU,aAAa;CACtF,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EAErC,UAAe;AACf,SAAO,YAAc,OAAe,CAAC,UAAU,aAC9C,UAAU,UAAU,UAAU,EAAQ,QAAQ,CAAC,WAAW;AAE7D,GADA,EAAU,GAAK,EACf,iBAAiB,EAAU,GAAM,EAAE,KAAK;IACxC;IAGE,IAAS,MAAY,QACrB,IAAW,MAAY;AAE7B,QACE,kBAAC,OAAD;EACE,WACE,IACI,2FACA,IACE,mCACA;YANV;GASE,kBAAC,OAAD;IACE,WACE,IACI,8GACA;IAEN,eAAY;cAEX,EAAQ,YACP,kBAAC,OAAD;KAAK,KAAK,EAAQ;KAAW,KAAI;KAAG,WAAU;KAAwC,CAAA,GACpF,EAAQ,WACV,EAAS,EAAQ,YAAY,GAE7B,kBAAC,GAAD;KAAO,WAAU;KAAS,eAAY;KAAS,CAAA;IAE7C,CAAA;GACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KACE,WACE,IACI,wCACA;eAGL,EAAQ;KACP,CAAA,EACF,IAIE,OAHF,kBAAC,KAAD;KAAG,WAAU;eACV,EAAQ,SAAS,EAAQ;KACxB,CAAA,CAEF;;GACL,CAAC,KAAU,CAAC,IACX,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,WAAD;KAAS,WAAU;eAAkG;KAE3G,CAAA,EACV,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAA+C,EAAQ;MAAe,CAAA,EACtF,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAW;gBAED,EAAT,IAAU,IAAiC,GAAlC,EAAO,WAAU,YAAa,CAAgC;MACjE,CAAA,CACL;OACE;QACR;GACA"}
1
+ {"version":3,"file":"ActorIdentity.js","names":[],"sources":["../../../../src/billing/shared/components/ActorIdentity.tsx"],"sourcesContent":["import { useState, type FC } from 'react';\nimport { Check, Copy, User2 } from 'lucide-react';\nimport type { ActorProfile } from '../hooks/useActorProfiles';\n\ninterface ActorIdentityProps {\n profile: ActorProfile;\n variant?: 'cell' | 'inline' | 'chip';\n}\n\nfunction initials(displayName: string): string {\n const cleaned = displayName.trim();\n if (!cleaned) return '?';\n const parts = cleaned.split(/\\s+/).filter(Boolean);\n if (parts.length === 1) return parts[0].charAt(0).toUpperCase();\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\nexport const ActorIdentity: FC<ActorIdentityProps> = ({ profile, variant = 'cell' }) => {\n const [copied, setCopied] = useState(false);\n\n const onCopy = () => {\n if (typeof navigator === 'undefined' || !navigator.clipboard) return;\n void navigator.clipboard.writeText(profile.actorId).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n });\n };\n\n const isChip = variant === 'chip';\n const isInline = variant === 'inline';\n\n return (\n <div\n className={\n isChip\n ? 'inline-flex items-center gap-2 rounded-full border border-border-subtle bg-bg-sunken/40 px-2 py-1'\n : isInline\n ? 'inline-flex items-center gap-2'\n : 'flex items-center gap-3'\n }\n >\n <div\n className={\n isChip\n ? 'flex size-6 items-center justify-center rounded-full bg-action-primary-bg/10 text-[10px] font-semibold text-primary'\n : 'flex size-9 items-center justify-center rounded-full bg-action-primary-bg/10 text-xs font-semibold text-primary'\n }\n aria-hidden=\"true\"\n >\n {profile.avatarUrl ? (\n <img src={profile.avatarUrl} alt=\"\" className=\"size-full rounded-full object-cover\" />\n ) : profile.resolved ? (\n initials(profile.displayName)\n ) : (\n <User2 className=\"size-4\" aria-hidden=\"true\" />\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p\n className={\n isChip\n ? 'text-xs font-medium text-text-primary'\n : 'truncate text-sm font-medium text-text-primary'\n }\n >\n {profile.displayName}\n </p>\n {!isChip ? (\n <p className=\"truncate text-xs text-text-secondary\">\n {profile.email ?? profile.secondaryLabel}\n </p>\n ) : null}\n </div>\n {!isChip && !isInline ? (\n <details className=\"group\">\n <summary className=\"cursor-pointer text-[10px] uppercase tracking-wider text-text-secondary hover:text-text-primary\">\n ID\n </summary>\n <div className=\"mt-1 flex items-center gap-2 rounded-md border border-border-subtle bg-bg-surface px-2 py-1\">\n <span className=\"font-mono text-[11px] text-text-secondary\">{profile.actorId}</span>\n <button\n type=\"button\"\n onClick={onCopy}\n className=\"text-text-secondary transition hover:text-text-primary\"\n aria-label=\"Copy actor ID\"\n >\n {copied ? <Check className=\"size-3.5\" /> : <Copy className=\"size-3.5\" />}\n </button>\n </div>\n </details>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AASA,SAAS,EAAS,GAA6B;CAC7C,IAAM,IAAU,EAAY,MAAM;AAClC,KAAI,CAAC,EAAS,QAAO;CACrB,IAAM,IAAQ,EAAQ,MAAM,MAAM,CAAC,OAAO,QAAQ;AAElD,QADI,EAAM,WAAW,IAAU,EAAM,GAAG,OAAO,EAAE,CAAC,aAAa,IACvD,EAAM,GAAG,OAAO,EAAE,GAAG,EAAM,EAAM,SAAS,GAAG,OAAO,EAAE,EAAE,aAAa;;AAG/E,IAAa,KAAyC,EAAE,YAAS,aAAU,aAAa;CACtF,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EAErC,UAAe;AACf,SAAO,YAAc,OAAe,CAAC,UAAU,aAC9C,UAAU,UAAU,UAAU,EAAQ,QAAQ,CAAC,WAAW;AAE7D,GADA,EAAU,GAAK,EACf,iBAAiB,EAAU,GAAM,EAAE,KAAK;IACxC;IAGE,IAAS,MAAY,QACrB,IAAW,MAAY;AAE7B,QACE,kBAAC,OAAD;EACE,WACE,IACI,sGACA,IACE,mCACA;YANV;GASE,kBAAC,OAAD;IACE,WACE,IACI,wHACA;IAEN,eAAY;cAEX,EAAQ,YACP,kBAAC,OAAD;KAAK,KAAK,EAAQ;KAAW,KAAI;KAAG,WAAU;KAAwC,CAAA,GACpF,EAAQ,WACV,EAAS,EAAQ,YAAY,GAE7B,kBAAC,GAAD;KAAO,WAAU;KAAS,eAAY;KAAS,CAAA;IAE7C,CAAA;GACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KACE,WACE,IACI,0CACA;eAGL,EAAQ;KACP,CAAA,EACF,IAIE,OAHF,kBAAC,KAAD;KAAG,WAAU;eACV,EAAQ,SAAS,EAAQ;KACxB,CAAA,CAEF;;GACL,CAAC,KAAU,CAAC,IACX,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,WAAD;KAAS,WAAU;eAAkG;KAE3G,CAAA,EACV,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD;MAAM,WAAU;gBAA6C,EAAQ;MAAe,CAAA,EACpF,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAW;gBAED,EAAT,IAAU,IAAiC,GAAlC,EAAO,WAAU,YAAa,CAAgC;MACjE,CAAA,CACL;OACE;QACR;GACA"}
@@ -134,22 +134,22 @@ var r = [
134
134
  }]);
135
135
  }, f = i.length;
136
136
  return /* @__PURE__ */ n("div", {
137
- className: "border border-border rounded-lg bg-card overflow-hidden",
137
+ className: "border border-border-subtle rounded-lg bg-bg-surface overflow-hidden",
138
138
  children: [/* @__PURE__ */ n("button", {
139
139
  type: "button",
140
140
  onClick: () => c((e) => !e),
141
- className: "w-full p-4 border-b border-border bg-muted/30 flex items-center justify-between hover:bg-muted/50 transition-colors",
141
+ className: "w-full p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between hover:bg-bg-sunken/50 transition-colors",
142
142
  children: [/* @__PURE__ */ n("div", {
143
143
  className: "flex items-center gap-2",
144
144
  children: [/* @__PURE__ */ t("h2", {
145
- className: "font-semibold text-foreground",
145
+ className: "font-semibold text-text-primary",
146
146
  children: "Currency Price Overrides"
147
147
  }), f > 0 && /* @__PURE__ */ n("span", {
148
- className: "px-2 py-0.5 text-xs font-medium bg-primary/10 text-primary rounded-full",
148
+ className: "px-2 py-0.5 text-xs font-medium bg-action-primary-bg/10 text-primary rounded-full",
149
149
  children: [f, " set"]
150
150
  })]
151
151
  }), /* @__PURE__ */ n("div", {
152
- className: "flex items-center gap-2 text-sm text-muted-foreground",
152
+ className: "flex items-center gap-2 text-sm text-text-secondary",
153
153
  children: [/* @__PURE__ */ n("span", { children: [s ? "Hide" : "Show", " (leave blank to use auto-calculated exchange rates)"] }), /* @__PURE__ */ t("svg", {
154
154
  className: `w-4 h-4 transition-transform ${s ? "rotate-180" : ""}`,
155
155
  fill: "none",
@@ -167,7 +167,7 @@ var r = [
167
167
  className: "p-4",
168
168
  children: [
169
169
  /* @__PURE__ */ t("p", {
170
- className: "text-xs text-muted-foreground mb-4",
170
+ className: "text-xs text-text-secondary mb-4",
171
171
  children: "Set a specific price for any currency. Leave a field empty to auto-calculate from the USD base price using live exchange rates."
172
172
  }),
173
173
  /* @__PURE__ */ t("div", {
@@ -177,15 +177,15 @@ var r = [
177
177
  return /* @__PURE__ */ n("div", {
178
178
  className: "space-y-1",
179
179
  children: [/* @__PURE__ */ n("label", {
180
- className: "flex items-center gap-1 text-xs font-medium text-foreground",
180
+ className: "flex items-center gap-1 text-xs font-medium text-text-primary",
181
181
  children: [
182
182
  /* @__PURE__ */ t("span", {
183
- className: "text-muted-foreground",
183
+ className: "text-text-secondary",
184
184
  children: i
185
185
  }),
186
186
  /* @__PURE__ */ t("span", { children: e }),
187
187
  /* @__PURE__ */ n("span", {
188
- className: "text-muted-foreground font-normal truncate",
188
+ className: "text-text-secondary font-normal truncate",
189
189
  children: [
190
190
  "(",
191
191
  r,
@@ -202,7 +202,7 @@ var r = [
202
202
  value: a?.amount ?? "",
203
203
  onChange: (t) => u(e, t.target.value),
204
204
  placeholder: "auto",
205
- className: `px-2 py-1.5 text-sm border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-muted-foreground ${o ? "flex-1 min-w-0" : "w-full"} ${a?.amount === void 0 ? "" : "border-primary/50"}`
205
+ className: `px-2 py-1.5 text-sm border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-text-secondary ${o ? "flex-1 min-w-0" : "w-full"} ${a?.amount === void 0 ? "" : "border-primary/50"}`
206
206
  }), o && /* @__PURE__ */ t("input", {
207
207
  type: "number",
208
208
  step: "0.01",
@@ -212,7 +212,7 @@ var r = [
212
212
  placeholder: "/seat",
213
213
  disabled: !a,
214
214
  title: "Per-seat amount (requires flat amount to be set first)",
215
- className: "flex-1 min-w-0 px-2 py-1.5 text-sm border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-muted-foreground disabled:opacity-40"
215
+ className: "flex-1 min-w-0 px-2 py-1.5 text-sm border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-text-secondary disabled:opacity-40"
216
216
  })]
217
217
  })]
218
218
  }, e);
@@ -1 +1 @@
1
- {"version":3,"file":"CurrencyPriceOverridesEditor.js","names":[],"sources":["../../../../src/billing/shared/components/CurrencyPriceOverridesEditor.tsx"],"sourcesContent":["import { useState, type FC } from 'react';\n\nimport type { CurrencyPriceOverrideInput } from '../types';\n\ninterface CurrencyPriceOverridesEditorProps {\n overrides: CurrencyPriceOverrideInput[];\n onChange: (overrides: CurrencyPriceOverrideInput[]) => void;\n showPerSeatAmount?: boolean;\n}\n\nconst PRICING_CURRENCIES: { code: string; name: string; symbol: string }[] = [\n { code: 'EUR', name: 'Euro', symbol: '€' },\n { code: 'GBP', name: 'British Pound', symbol: '£' },\n { code: 'INR', name: 'Indian Rupee', symbol: '₹' },\n { code: 'AUD', name: 'Australian Dollar', symbol: 'A$' },\n { code: 'CAD', name: 'Canadian Dollar', symbol: 'C$' },\n { code: 'SGD', name: 'Singapore Dollar', symbol: 'S$' },\n { code: 'JPY', name: 'Japanese Yen', symbol: '¥' },\n { code: 'MXN', name: 'Mexican Peso', symbol: 'MX$' },\n { code: 'BRL', name: 'Brazilian Real', symbol: 'R$' },\n { code: 'CHF', name: 'Swiss Franc', symbol: 'Fr' },\n { code: 'CNY', name: 'Chinese Yuan', symbol: '¥' },\n { code: 'HKD', name: 'Hong Kong Dollar', symbol: 'HK$' },\n { code: 'NZD', name: 'New Zealand Dollar', symbol: 'NZ$' },\n { code: 'SEK', name: 'Swedish Krona', symbol: 'kr' },\n { code: 'KRW', name: 'South Korean Won', symbol: '₩' },\n { code: 'NOK', name: 'Norwegian Krone', symbol: 'kr' },\n { code: 'DKK', name: 'Danish Krone', symbol: 'kr' },\n { code: 'PLN', name: 'Polish Złoty', symbol: 'zł' },\n { code: 'THB', name: 'Thai Baht', symbol: '฿' },\n { code: 'MYR', name: 'Malaysian Ringgit', symbol: 'RM' },\n];\n\nexport const CurrencyPriceOverridesEditor: FC<CurrencyPriceOverridesEditorProps> = ({\n overrides,\n onChange,\n showPerSeatAmount = false,\n}) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const getOverride = (currency: string): CurrencyPriceOverrideInput | undefined =>\n overrides.find((o) => o.currency === currency);\n\n const handleAmountChange = (currency: string, value: string) => {\n const trimmed = value.trim();\n const existing = overrides.filter((o) => o.currency !== currency);\n\n if (trimmed === '') {\n onChange(existing);\n return;\n }\n\n const amount = parseFloat(trimmed);\n if (isNaN(amount) || amount < 0) return;\n\n const currentOverride = getOverride(currency);\n onChange([\n ...existing,\n {\n currency,\n amount,\n ...(currentOverride?.perSeatAmount !== undefined\n ? { perSeatAmount: currentOverride.perSeatAmount }\n : {}),\n },\n ]);\n };\n\n const handlePerSeatChange = (currency: string, value: string) => {\n const trimmed = value.trim();\n const existing = overrides.filter((o) => o.currency !== currency);\n const currentOverride = getOverride(currency);\n\n if (!currentOverride) return;\n\n if (trimmed === '') {\n onChange([...existing, { currency, amount: currentOverride.amount }]);\n return;\n }\n\n const perSeatAmount = parseFloat(trimmed);\n if (isNaN(perSeatAmount) || perSeatAmount < 0) return;\n\n onChange([...existing, { ...currentOverride, perSeatAmount }]);\n };\n\n const overrideCount = overrides.length;\n\n return (\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setIsExpanded((v) => !v)}\n className=\"w-full p-4 border-b border-border bg-muted/30 flex items-center justify-between hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-2\">\n <h2 className=\"font-semibold text-foreground\">Currency Price Overrides</h2>\n {overrideCount > 0 && (\n <span className=\"px-2 py-0.5 text-xs font-medium bg-primary/10 text-primary rounded-full\">\n {overrideCount} set\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <span>\n {isExpanded ? 'Hide' : 'Show'} (leave blank to use auto-calculated exchange rates)\n </span>\n <svg\n className={`w-4 h-4 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </div>\n </button>\n\n {isExpanded && (\n <div className=\"p-4\">\n <p className=\"text-xs text-muted-foreground mb-4\">\n Set a specific price for any currency. Leave a field empty to auto-calculate from the\n USD base price using live exchange rates.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3\">\n {PRICING_CURRENCIES.map(({ code, name, symbol }) => {\n const override = getOverride(code);\n return (\n <div key={code} className=\"space-y-1\">\n <label className=\"flex items-center gap-1 text-xs font-medium text-foreground\">\n <span className=\"text-muted-foreground\">{symbol}</span>\n <span>{code}</span>\n <span className=\"text-muted-foreground font-normal truncate\">({name})</span>\n </label>\n <div className={showPerSeatAmount ? 'flex gap-1' : ''}>\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={override?.amount ?? ''}\n onChange={(e) => handleAmountChange(code, e.target.value)}\n placeholder=\"auto\"\n className={`px-2 py-1.5 text-sm border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-muted-foreground ${\n showPerSeatAmount ? 'flex-1 min-w-0' : 'w-full'\n } ${override?.amount !== undefined ? 'border-primary/50' : ''}`}\n />\n {showPerSeatAmount && (\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={override?.perSeatAmount ?? ''}\n onChange={(e) => handlePerSeatChange(code, e.target.value)}\n placeholder=\"/seat\"\n disabled={!override}\n title=\"Per-seat amount (requires flat amount to be set first)\"\n className=\"flex-1 min-w-0 px-2 py-1.5 text-sm border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-muted-foreground disabled:opacity-40\"\n />\n )}\n </div>\n </div>\n );\n })}\n </div>\n {overrideCount > 0 && (\n <button\n type=\"button\"\n onClick={() => onChange([])}\n className=\"mt-4 text-xs text-status-error-text hover:underline\"\n >\n Clear all overrides\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;AAUA,IAAM,IAAuE;CAC3E;EAAE,MAAM;EAAO,MAAM;EAAQ,QAAQ;EAAK;CAC1C;EAAE,MAAM;EAAO,MAAM;EAAiB,QAAQ;EAAK;CACnD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAK;CAClD;EAAE,MAAM;EAAO,MAAM;EAAqB,QAAQ;EAAM;CACxD;EAAE,MAAM;EAAO,MAAM;EAAmB,QAAQ;EAAM;CACtD;EAAE,MAAM;EAAO,MAAM;EAAoB,QAAQ;EAAM;CACvD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAK;CAClD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAO;CACpD;EAAE,MAAM;EAAO,MAAM;EAAkB,QAAQ;EAAM;CACrD;EAAE,MAAM;EAAO,MAAM;EAAe,QAAQ;EAAM;CAClD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAK;CAClD;EAAE,MAAM;EAAO,MAAM;EAAoB,QAAQ;EAAO;CACxD;EAAE,MAAM;EAAO,MAAM;EAAsB,QAAQ;EAAO;CAC1D;EAAE,MAAM;EAAO,MAAM;EAAiB,QAAQ;EAAM;CACpD;EAAE,MAAM;EAAO,MAAM;EAAoB,QAAQ;EAAK;CACtD;EAAE,MAAM;EAAO,MAAM;EAAmB,QAAQ;EAAM;CACtD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAM;CACnD;EAAE,MAAM;EAAO,MAAM;EAAgB,QAAQ;EAAM;CACnD;EAAE,MAAM;EAAO,MAAM;EAAa,QAAQ;EAAK;CAC/C;EAAE,MAAM;EAAO,MAAM;EAAqB,QAAQ;EAAM;CACzD,EAEY,KAAuE,EAClF,cACA,aACA,uBAAoB,SAChB;CACJ,IAAM,CAAC,GAAY,KAAiB,EAAS,GAAM,EAE7C,KAAe,MACnB,EAAU,MAAM,MAAM,EAAE,aAAa,EAAS,EAE1C,KAAsB,GAAkB,MAAkB;EAC9D,IAAM,IAAU,EAAM,MAAM,EACtB,IAAW,EAAU,QAAQ,MAAM,EAAE,aAAa,EAAS;AAEjE,MAAI,MAAY,IAAI;AAClB,KAAS,EAAS;AAClB;;EAGF,IAAM,IAAS,WAAW,EAAQ;AAClC,MAAI,MAAM,EAAO,IAAI,IAAS,EAAG;EAEjC,IAAM,IAAkB,EAAY,EAAS;AAC7C,IAAS,CACP,GAAG,GACH;GACE;GACA;GACA,GAAI,GAAiB,kBAAkB,KAAA,IAEnC,EAAE,GADF,EAAE,eAAe,EAAgB,eAAe;GAErD,CACF,CAAC;IAGE,KAAuB,GAAkB,MAAkB;EAC/D,IAAM,IAAU,EAAM,MAAM,EACtB,IAAW,EAAU,QAAQ,MAAM,EAAE,aAAa,EAAS,EAC3D,IAAkB,EAAY,EAAS;AAE7C,MAAI,CAAC,EAAiB;AAEtB,MAAI,MAAY,IAAI;AAClB,KAAS,CAAC,GAAG,GAAU;IAAE;IAAU,QAAQ,EAAgB;IAAQ,CAAC,CAAC;AACrE;;EAGF,IAAM,IAAgB,WAAW,EAAQ;AACrC,QAAM,EAAc,IAAI,IAAgB,KAE5C,EAAS,CAAC,GAAG,GAAU;GAAE,GAAG;GAAiB;GAAe,CAAC,CAAC;IAG1D,IAAgB,EAAU;AAEhC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,GAAe,MAAM,CAAC,EAAE;GACvC,WAAU;aAHZ,CAKE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAgC;KAA6B,CAAA,EAC1E,IAAgB,KACf,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACG,GAAc,OACV;OAEL;OACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD,EAAA,UAAA,CACG,IAAa,SAAS,QAAO,uDACzB,EAAA,CAAA,EACP,kBAAC,OAAD;KACE,WAAW,gCAAgC,IAAa,eAAe;KACvE,MAAK;KACL,SAAQ;KACR,QAAO;eAEP,kBAAC,QAAD;MAAM,eAAc;MAAQ,gBAAe;MAAQ,aAAa;MAAG,GAAE;MAAmB,CAAA;KACpF,CAAA,CACF;MACC;MAER,KACC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eAAqC;KAG9C,CAAA;IACJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAmB,KAAK,EAAE,SAAM,SAAM,gBAAa;MAClD,IAAM,IAAW,EAAY,EAAK;AAClC,aACE,kBAAC,OAAD;OAAgB,WAAU;iBAA1B,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAjB;SACE,kBAAC,QAAD;UAAM,WAAU;oBAAyB;UAAc,CAAA;SACvD,kBAAC,QAAD,EAAA,UAAO,GAAY,CAAA;SACnB,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WAA6D;WAAE;WAAK;WAAQ;;SACtE;WACR,kBAAC,OAAD;QAAK,WAAW,IAAoB,eAAe;kBAAnD,CACE,kBAAC,SAAD;SACE,MAAK;SACL,MAAK;SACL,KAAI;SACJ,OAAO,GAAU,UAAU;SAC3B,WAAW,MAAM,EAAmB,GAAM,EAAE,OAAO,MAAM;SACzD,aAAY;SACZ,WAAW,0KACT,IAAoB,mBAAmB,SACxC,GAAG,GAAU,WAAW,KAAA,IAAkC,KAAtB;SACrC,CAAA,EACD,KACC,kBAAC,SAAD;SACE,MAAK;SACL,MAAK;SACL,KAAI;SACJ,OAAO,GAAU,iBAAiB;SAClC,WAAW,MAAM,EAAoB,GAAM,EAAE,OAAO,MAAM;SAC1D,aAAY;SACZ,UAAU,CAAC;SACX,OAAM;SACN,WAAU;SACV,CAAA,CAEA;UACF;SAhCI,EAgCJ;OAER;KACE,CAAA;IACL,IAAgB,KACf,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,EAAE,CAAC;KAC3B,WAAU;eACX;KAEQ,CAAA;IAEP;KAEJ"}
1
+ {"version":3,"file":"CurrencyPriceOverridesEditor.js","names":[],"sources":["../../../../src/billing/shared/components/CurrencyPriceOverridesEditor.tsx"],"sourcesContent":["import { useState, type FC } from 'react';\n\nimport type { CurrencyPriceOverrideInput } from '../types';\n\ninterface CurrencyPriceOverridesEditorProps {\n overrides: CurrencyPriceOverrideInput[];\n onChange: (overrides: CurrencyPriceOverrideInput[]) => void;\n showPerSeatAmount?: boolean;\n}\n\nconst PRICING_CURRENCIES: { code: string; name: string; symbol: string }[] = [\n { code: 'EUR', name: 'Euro', symbol: '€' },\n { code: 'GBP', name: 'British Pound', symbol: '£' },\n { code: 'INR', name: 'Indian Rupee', symbol: '₹' },\n { code: 'AUD', name: 'Australian Dollar', symbol: 'A$' },\n { code: 'CAD', name: 'Canadian Dollar', symbol: 'C$' },\n { code: 'SGD', name: 'Singapore Dollar', symbol: 'S$' },\n { code: 'JPY', name: 'Japanese Yen', symbol: '¥' },\n { code: 'MXN', name: 'Mexican Peso', symbol: 'MX$' },\n { code: 'BRL', name: 'Brazilian Real', symbol: 'R$' },\n { code: 'CHF', name: 'Swiss Franc', symbol: 'Fr' },\n { code: 'CNY', name: 'Chinese Yuan', symbol: '¥' },\n { code: 'HKD', name: 'Hong Kong Dollar', symbol: 'HK$' },\n { code: 'NZD', name: 'New Zealand Dollar', symbol: 'NZ$' },\n { code: 'SEK', name: 'Swedish Krona', symbol: 'kr' },\n { code: 'KRW', name: 'South Korean Won', symbol: '₩' },\n { code: 'NOK', name: 'Norwegian Krone', symbol: 'kr' },\n { code: 'DKK', name: 'Danish Krone', symbol: 'kr' },\n { code: 'PLN', name: 'Polish Złoty', symbol: 'zł' },\n { code: 'THB', name: 'Thai Baht', symbol: '฿' },\n { code: 'MYR', name: 'Malaysian Ringgit', symbol: 'RM' },\n];\n\nexport const CurrencyPriceOverridesEditor: FC<CurrencyPriceOverridesEditorProps> = ({\n overrides,\n onChange,\n showPerSeatAmount = false,\n}) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const getOverride = (currency: string): CurrencyPriceOverrideInput | undefined =>\n overrides.find((o) => o.currency === currency);\n\n const handleAmountChange = (currency: string, value: string) => {\n const trimmed = value.trim();\n const existing = overrides.filter((o) => o.currency !== currency);\n\n if (trimmed === '') {\n onChange(existing);\n return;\n }\n\n const amount = parseFloat(trimmed);\n if (isNaN(amount) || amount < 0) return;\n\n const currentOverride = getOverride(currency);\n onChange([\n ...existing,\n {\n currency,\n amount,\n ...(currentOverride?.perSeatAmount !== undefined\n ? { perSeatAmount: currentOverride.perSeatAmount }\n : {}),\n },\n ]);\n };\n\n const handlePerSeatChange = (currency: string, value: string) => {\n const trimmed = value.trim();\n const existing = overrides.filter((o) => o.currency !== currency);\n const currentOverride = getOverride(currency);\n\n if (!currentOverride) return;\n\n if (trimmed === '') {\n onChange([...existing, { currency, amount: currentOverride.amount }]);\n return;\n }\n\n const perSeatAmount = parseFloat(trimmed);\n if (isNaN(perSeatAmount) || perSeatAmount < 0) return;\n\n onChange([...existing, { ...currentOverride, perSeatAmount }]);\n };\n\n const overrideCount = overrides.length;\n\n return (\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setIsExpanded((v) => !v)}\n className=\"w-full p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-2\">\n <h2 className=\"font-semibold text-text-primary\">Currency Price Overrides</h2>\n {overrideCount > 0 && (\n <span className=\"px-2 py-0.5 text-xs font-medium bg-action-primary-bg/10 text-primary rounded-full\">\n {overrideCount} set\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>\n {isExpanded ? 'Hide' : 'Show'} (leave blank to use auto-calculated exchange rates)\n </span>\n <svg\n className={`w-4 h-4 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </div>\n </button>\n\n {isExpanded && (\n <div className=\"p-4\">\n <p className=\"text-xs text-text-secondary mb-4\">\n Set a specific price for any currency. Leave a field empty to auto-calculate from the\n USD base price using live exchange rates.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3\">\n {PRICING_CURRENCIES.map(({ code, name, symbol }) => {\n const override = getOverride(code);\n return (\n <div key={code} className=\"space-y-1\">\n <label className=\"flex items-center gap-1 text-xs font-medium text-text-primary\">\n <span className=\"text-text-secondary\">{symbol}</span>\n <span>{code}</span>\n <span className=\"text-text-secondary font-normal truncate\">({name})</span>\n </label>\n <div className={showPerSeatAmount ? 'flex gap-1' : ''}>\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={override?.amount ?? ''}\n onChange={(e) => handleAmountChange(code, e.target.value)}\n placeholder=\"auto\"\n className={`px-2 py-1.5 text-sm border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-text-secondary ${\n showPerSeatAmount ? 'flex-1 min-w-0' : 'w-full'\n } ${override?.amount !== undefined ? 'border-primary/50' : ''}`}\n />\n {showPerSeatAmount && (\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={override?.perSeatAmount ?? ''}\n onChange={(e) => handlePerSeatChange(code, e.target.value)}\n placeholder=\"/seat\"\n disabled={!override}\n title=\"Per-seat amount (requires flat amount to be set first)\"\n className=\"flex-1 min-w-0 px-2 py-1.5 text-sm border border-border-subtle rounded-md bg-bg-surface text-text-primary focus:outline-none focus:ring-1 focus:ring-primary placeholder:text-text-secondary disabled:opacity-40\"\n />\n )}\n </div>\n </div>\n );\n })}\n </div>\n {overrideCount > 0 && (\n <button\n type=\"button\"\n onClick={() => onChange([])}\n className=\"mt-4 text-xs text-status-error-text hover:underline\"\n >\n Clear all overrides\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-billing",
3
- "version": "2026.623.3",
3
+ "version": "2026.624.1",
4
4
  "description": "Billing microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [