@fluid-app/portal-sdk 0.1.278 → 0.1.279
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.
- package/dist/{AddressAutocompleteInput-85N8HUb1.cjs → AddressAutocompleteInput-9dgPDN20.cjs} +52 -21
- package/dist/AddressAutocompleteInput-9dgPDN20.cjs.map +1 -0
- package/dist/{AddressAutocompleteInput-BLNSxszN.mjs → AddressAutocompleteInput-B4BtFV1h.mjs} +52 -21
- package/dist/AddressAutocompleteInput-B4BtFV1h.mjs.map +1 -0
- package/dist/{ProfileScreen-Px2RZMSL.mjs → ProfileScreen-3eLPzb8M.mjs} +87 -35
- package/dist/ProfileScreen-3eLPzb8M.mjs.map +1 -0
- package/dist/{ProfileScreen-CEVFamD0.cjs → ProfileScreen-DRkGc-T1.cjs} +2 -2
- package/dist/{ProfileScreen-CdxywpCx.cjs → ProfileScreen-akflb-_8.cjs} +87 -35
- package/dist/ProfileScreen-akflb-_8.cjs.map +1 -0
- package/dist/{ProfileScreen-B0XiGP2X.mjs → ProfileScreen-b9iHBWdL.mjs} +2 -2
- package/dist/{SubscriptionsScreen-BMhy6C22.cjs → SubscriptionsScreen-BhM9OgoI.cjs} +2 -2
- package/dist/{SubscriptionsScreen-BzW_21xH.cjs → SubscriptionsScreen-CUIb5sh7.cjs} +2 -2
- package/dist/{SubscriptionsScreen-BzW_21xH.cjs.map → SubscriptionsScreen-CUIb5sh7.cjs.map} +1 -1
- package/dist/{SubscriptionsScreen-BhN4e_5L.mjs → SubscriptionsScreen-mFxMQy3G.mjs} +2 -2
- package/dist/{SubscriptionsScreen-BhN4e_5L.mjs.map → SubscriptionsScreen-mFxMQy3G.mjs.map} +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.mjs +7 -7
- package/package.json +13 -13
- package/dist/AddressAutocompleteInput-85N8HUb1.cjs.map +0 -1
- package/dist/AddressAutocompleteInput-BLNSxszN.mjs.map +0 -1
- package/dist/ProfileScreen-CdxywpCx.cjs.map +0 -1
- package/dist/ProfileScreen-Px2RZMSL.mjs.map +0 -1
package/dist/{AddressAutocompleteInput-85N8HUb1.cjs → AddressAutocompleteInput-9dgPDN20.cjs}
RENAMED
|
@@ -1195,7 +1195,25 @@ const addressFormSchema = zod.z.object({
|
|
|
1195
1195
|
country_code: zod.z.string().min(1, "Country is required"),
|
|
1196
1196
|
default: zod.z.boolean()
|
|
1197
1197
|
});
|
|
1198
|
-
function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmitting, countries = [], error, renderAddressAutocomplete, fetchStates, t }) {
|
|
1198
|
+
function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmitting, countries = [], error, renderAddressAutocomplete, fetchStates, t, onDelete, isDeleting = false }) {
|
|
1199
|
+
const [confirmDelete, setConfirmDelete] = (0, react.useState)(false);
|
|
1200
|
+
(0, react.useEffect)(() => {
|
|
1201
|
+
if (!isOpen) setConfirmDelete(false);
|
|
1202
|
+
}, [isOpen]);
|
|
1203
|
+
(0, react.useEffect)(() => {
|
|
1204
|
+
if (!confirmDelete) return;
|
|
1205
|
+
const timeoutId = setTimeout(() => setConfirmDelete(false), 3e3);
|
|
1206
|
+
return () => clearTimeout(timeoutId);
|
|
1207
|
+
}, [confirmDelete]);
|
|
1208
|
+
const deleteButtonLabel = (0, react.useMemo)(() => {
|
|
1209
|
+
if (isDeleting) return t("deleting");
|
|
1210
|
+
if (confirmDelete) return t("tap_to_confirm");
|
|
1211
|
+
return t("delete_address");
|
|
1212
|
+
}, [
|
|
1213
|
+
isDeleting,
|
|
1214
|
+
confirmDelete,
|
|
1215
|
+
t
|
|
1216
|
+
]);
|
|
1199
1217
|
const { control, handleSubmit, reset, setValue } = require_src.useZodForm(addressFormSchema, { defaultValues: {
|
|
1200
1218
|
first_name: "",
|
|
1201
1219
|
last_name: "",
|
|
@@ -1368,26 +1386,39 @@ function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmi
|
|
|
1368
1386
|
]
|
|
1369
1387
|
}),
|
|
1370
1388
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1371
|
-
className: "mt-4 flex items-center justify-between",
|
|
1372
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1389
|
+
className: "mt-4 flex flex-wrap items-center justify-between gap-3",
|
|
1390
|
+
children: [onDelete ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
|
|
1391
|
+
type: "button",
|
|
1392
|
+
variant: "ghost",
|
|
1393
|
+
onClick: () => {
|
|
1394
|
+
if (confirmDelete) onDelete();
|
|
1395
|
+
else setConfirmDelete(true);
|
|
1396
|
+
},
|
|
1397
|
+
disabled: isSubmitting || isDeleting,
|
|
1398
|
+
className: "text-destructive hover:bg-destructive/10 hover:text-destructive",
|
|
1399
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "size-4" }), deleteButtonLabel]
|
|
1400
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1401
|
+
className: "flex items-center gap-3",
|
|
1402
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1403
|
+
className: "flex items-center space-x-2",
|
|
1404
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1405
|
+
type: "checkbox",
|
|
1406
|
+
id: "set_as_default_address",
|
|
1407
|
+
checked: isDefault,
|
|
1408
|
+
onChange: () => setValue("default", !isDefault),
|
|
1409
|
+
disabled: isSubmitting || isDeleting,
|
|
1410
|
+
className: "h-4 w-4"
|
|
1411
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1412
|
+
htmlFor: "set_as_default_address",
|
|
1413
|
+
className: "text-sm",
|
|
1414
|
+
children: t("set_as_default_address")
|
|
1415
|
+
})]
|
|
1416
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
|
|
1417
|
+
type: "submit",
|
|
1418
|
+
onClick: handleFormSubmit,
|
|
1419
|
+
disabled: isSubmitting || isDeleting,
|
|
1420
|
+
children: [isSubmitting && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current" }), isSubmitting ? t("saving") : t("save_address")]
|
|
1385
1421
|
})]
|
|
1386
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
|
|
1387
|
-
type: "submit",
|
|
1388
|
-
onClick: handleFormSubmit,
|
|
1389
|
-
disabled: isSubmitting,
|
|
1390
|
-
children: [isSubmitting && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current" }), isSubmitting ? t("saving") : t("save_address")]
|
|
1391
1422
|
})]
|
|
1392
1423
|
}),
|
|
1393
1424
|
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -2276,4 +2307,4 @@ Object.defineProperty(exports, "useProfileTranslation", {
|
|
|
2276
2307
|
}
|
|
2277
2308
|
});
|
|
2278
2309
|
|
|
2279
|
-
//# sourceMappingURL=AddressAutocompleteInput-
|
|
2310
|
+
//# sourceMappingURL=AddressAutocompleteInput-9dgPDN20.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddressAutocompleteInput-9dgPDN20.cjs","names":["createTranslationContext","createDomainTranslations","createStaticDictAdapter","useActiveLocale","useDomainDict","Button","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","Dialog","DialogContent","DialogHeader","DialogTitle","DialogFooter","DialogClose","Button","FormTextField","cn","Label","Input","Textarea","FormSelectField","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Dialog","DialogContent","DialogHeader","DialogTitle","FormTextField","FormSelectField","Input","Info","Button","DialogFooter","z","useZodForm","Dialog","DialogContent","DialogHeader","DialogTitle","FormSelectField","FormTextField","DialogFooter","Button","Trash2","z","cn","Label","Input","cn","Label","Controller","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","z","useZodForm","Dialog","DialogContent","DialogHeader","DialogTitle","Button","Trash2","z","cn","useZodForm","Dialog","DialogContent","DialogHeader","DialogTitle","Button","useAddressAutocompleteApi","Input"],"sources":["../../../profile/core/src/translation-api-context.ts","../../../profile/core/src/translation-dictionary.ts","../../../profile/core/src/translation-adapter.ts","../src/providers/ProfileTranslationBridge.tsx","../../../profile/ui/src/components/ellipses-dropdown.tsx","../../../profile/ui/src/components/confirm-action-dialog.tsx","../../../profile/ui/src/components/form-fields.tsx","../../../profile/ui/src/components/user-info-dialog.tsx","../../../profile/ui/src/components/payment-method-card-internals.tsx","../../../profile/core/src/context.ts","../../../profile/core/src/provider.tsx","../../../fluid-pay/core/src/context.ts","../../../fluid-pay/core/src/provider.tsx","../../../fluid-pay/core/src/utils/country-config.ts","../../../fluid-pay/core/src/hooks/use-country-states.ts","../../../profile/ui/src/components/edit-payment-method-dialog.tsx","../../../profile/ui/src/components/my-site-profile-section.tsx","../../../fluid-pay/ui/src/components/form-fields/FormTextField.tsx","../../../fluid-pay/ui/src/components/form-fields/FormSelectField.tsx","../../../fluid-pay/ui/src/components/AddressFormDialog.tsx","../../../fluid-pay/ui/src/hooks/use-vgs-collect.ts","../../../fluid-pay/ui/src/components/CreditCardFormDialog.tsx","../src/adapters/fluid-pay-api-adapter.ts","../../../platform/address-autocomplete/src/components/AddressAutocompleteInput.tsx"],"sourcesContent":["import { createTranslationContext } from \"@fluid-app/i18n/translation-api-context-factory\";\nimport type { ProfileDict } from \"./translation-dictionary\";\n\nconst { Provider, useTranslation } =\n createTranslationContext<ProfileDict>(\"Profile\");\n\nexport const ProfileTranslationProvider = Provider;\nexport const useProfileTranslation = useTranslation;\n","export const profileEn = {\n breadcrumb: \"Profile\",\n edit_profile: \"Edit Profile\",\n first_name: \"First Name\",\n last_name: \"Last Name\",\n phone_number: \"Phone Number\",\n bio: \"Bio\",\n add_a_short_bio: \"Add a short bio\",\n language: \"Language\",\n first_name_is_required: \"First name is required\",\n last_name_is_required: \"Last name is required\",\n language_is_required: \"Language is required\",\n saving: \"Saving...\",\n save_changes: \"Save Changes\",\n select_an_option: \"Select an option\",\n points_history: \"Points History\",\n points_available: \"Points Available\",\n points_awarded: \"Points Awarded\",\n points_redeemed: \"Points Redeemed\",\n transaction: \"Transaction\",\n no_points_history_found: \"No points history found\",\n email: \"Email\",\n shipping_addresses: \"Shipping Addresses\",\n add_an_address: \"Add an Address\",\n delete_address: \"Delete Address\",\n delete_address_message:\n \"Are you sure you want to delete this address? This action cannot be undone.\",\n delete: \"Delete\",\n no_saved_addresses_found: \"No saved addresses found\",\n add_address: \"Add Address\",\n edit_address: \"Edit Address\",\n set_as_default_address: \"Set as default address\",\n save_address: \"Save Address\",\n card_number: \"Card Number\",\n expiration_date: \"Expiration (MM / YY)\",\n cvc: \"CVC\",\n cardholder_name: \"Cardholder Name\",\n add_credit_card: \"Add Credit Card\",\n save_card: \"Save Card\",\n securing: \"Loading secure form...\",\n payment_methods: \"Payment Methods\",\n add_payment_method: \"Add Payment Method\",\n delete_credit_card: \"Delete Credit Card\",\n delete_credit_card_message:\n \"Are you sure you want to delete this payment method? This action cannot be undone.\",\n delete_card: \"Delete card\",\n deleting: \"Deleting...\",\n tap_to_confirm: \"Tap to confirm\",\n edit_card: \"Card Details\",\n billing_address: \"Billing Address\",\n country: \"Country\",\n name: \"Name\",\n address_line_1: \"Address Line 1\",\n address_line_2: \"Address Line 2\",\n city: \"City\",\n state: \"State\",\n province: \"Province\",\n zip_code: \"Zip Code\",\n postal_code: \"Postal Code\",\n select_state: \"Select state\",\n set_as_default_payment_method: \"Set as default payment method\",\n cancel: \"Cancel\",\n save: \"Save\",\n close: \"Close\",\n edit: \"Edit\",\n default: \"Default\",\n card_expires: \"Expires\",\n no_billing_address: \"No billing address on file\",\n default_payment_method_updated: \"Payment method updated\",\n failed_to_set_default_payment_method: \"Failed to update payment method\",\n} as const satisfies Record<string, string>;\n\nexport type ProfileDict = typeof profileEn;\n","import {\n createDomainTranslations,\n type DomainTranslations,\n} from \"@fluid-app/i18n/translations\";\nimport { createStaticDictAdapter } from \"@fluid-app/i18n/static-dict-adapter\";\nimport type { TranslationApi } from \"@fluid-app/i18n/translation-api\";\nimport { profileEn, type ProfileDict } from \"./translation-dictionary\";\n\nexport const profileDomain: DomainTranslations<ProfileDict> =\n createDomainTranslations<ProfileDict>({\n fallback: profileEn,\n loaders: {\n de: () =>\n import(\"./locale/de.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n el: () =>\n import(\"./locale/el.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n es: () =>\n import(\"./locale/es.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n fr: () =>\n import(\"./locale/fr.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n he: () =>\n import(\"./locale/he.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n hu: () =>\n import(\"./locale/hu.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n id: () =>\n import(\"./locale/id.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n it: () =>\n import(\"./locale/it.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n ja: () =>\n import(\"./locale/ja.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n ko: () =>\n import(\"./locale/ko.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n nl: () =>\n import(\"./locale/nl.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n pl: () =>\n import(\"./locale/pl.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n pt: () =>\n import(\"./locale/pt.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n ro: () =>\n import(\"./locale/ro.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n ru: () =>\n import(\"./locale/ru.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n th: () =>\n import(\"./locale/th.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n tl: () =>\n import(\"./locale/tl.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n tr: () =>\n import(\"./locale/tr.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n zh_CN: () =>\n import(\"./locale/zh_CN.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n zh_TW: () =>\n import(\"./locale/zh_TW.json\").then(\n (m): ProfileDict => m.default as ProfileDict,\n ),\n },\n });\n\nexport function createProfileTranslationAdapter(\n locale: string,\n dict: ProfileDict,\n): TranslationApi<ProfileDict> {\n return createStaticDictAdapter(locale, dict);\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport { useActiveLocale } from \"@fluid-app/i18n/locale-context\";\nimport { useDomainDict } from \"@fluid-app/i18n/use-domain-dict\";\nimport {\n profileDomain,\n createProfileTranslationAdapter,\n} from \"@fluid-app/profile-core/translation-adapter\";\nimport { ProfileTranslationProvider } from \"@fluid-app/profile-core/translation-api-context\";\n\nexport function ProfileTranslationBridge({\n children,\n}: {\n children: ReactNode;\n}): React.JSX.Element {\n const { locale } = useActiveLocale();\n const dict = useDomainDict(profileDomain, locale);\n const api = useMemo(\n () => createProfileTranslationAdapter(locale, dict),\n [locale, dict],\n );\n return (\n <ProfileTranslationProvider value={api}>\n {children}\n </ProfileTranslationProvider>\n );\n}\n","import type { JSX } from \"react\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Button,\n} from \"@fluid-app/ui-primitives\";\n\nexport default function EllipsesDropdown({\n onDelete,\n onEdit,\n onMakeDefault,\n editLabel = \"Edit\",\n deleteLabel = \"Delete\",\n makeDefaultLabel = \"Make Default\",\n disabled = false,\n}: {\n onDelete?: () => void;\n onEdit?: () => void;\n onMakeDefault?: () => void;\n editLabel?: string;\n deleteLabel?: string;\n makeDefaultLabel?: string;\n disabled?: boolean;\n}): JSX.Element {\n if (disabled) {\n return (\n <Button variant=\"ghost\" disabled>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 128 512\"\n className=\"fill-muted-foreground h-4 w-1\"\n >\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\" />\n </svg>\n </Button>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 128 512\"\n className=\"fill-muted-foreground h-4 w-1\"\n >\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\" />\n </svg>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"text-foreground min-w-28 space-y-1 text-sm\">\n {onEdit && (\n <>\n <DropdownMenuItem\n className=\"hover:bg-muted flex cursor-pointer flex-row items-center gap-x-2 rounded px-2\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit();\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"h-3.5 w-3.5 flex-shrink-0\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10\"\n />\n </svg>\n <span>{editLabel}</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n </>\n )}\n {onMakeDefault && (\n <>\n <DropdownMenuItem\n className=\"hover:bg-muted flex cursor-pointer flex-row items-center gap-x-2 rounded px-2\"\n onClick={(e) => {\n e.stopPropagation();\n onMakeDefault();\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"h-3.5 w-3.5 flex-shrink-0\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m4.5 12.75 6 6 9-13.5\"\n />\n </svg>\n <span>{makeDefaultLabel}</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n </>\n )}\n <DropdownMenuItem\n className=\"text-destructive hover:bg-destructive/10 flex cursor-pointer flex-row items-center gap-x-2 rounded px-2\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete?.();\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"h-3.5 w-3.5 flex-shrink-0\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0\"\n />\n </svg>\n <span>{deleteLabel}</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import type { JSX } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DialogClose,\n Button,\n} from \"@fluid-app/ui-primitives\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\n\ntype ConfirmActionDialogProps = {\n title: string;\n description: string;\n onAction: () => void;\n openDialog: boolean;\n setOpenDialog: (open: boolean) => void;\n errorMsg?: string;\n isLoading?: boolean;\n actionText?: string;\n};\n\nexport default function ConfirmActionDialog({\n title,\n description,\n onAction,\n openDialog,\n setOpenDialog,\n errorMsg,\n isLoading,\n actionText = \"Delete\",\n}: ConfirmActionDialogProps): JSX.Element {\n const { t } = useProfileTranslation();\n\n return (\n <Dialog open={openDialog} onOpenChange={setOpenDialog}>\n <DialogContent className=\"max-w-sm md:w-90\">\n <DialogHeader className=\"flex flex-row justify-between\">\n <DialogTitle className=\"w-full text-left\">{title}</DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <p className=\"text-muted-foreground text-left text-sm\">\n {description}\n </p>\n </div>\n\n {errorMsg && <p className=\"text-destructive text-sm\">{errorMsg}</p>}\n\n <DialogFooter>\n <div className=\"flex w-full flex-row justify-between space-x-2\">\n <DialogClose asChild>\n <Button\n variant=\"secondary\"\n className=\"min-w-[70px]\"\n onClick={() => setOpenDialog(false)}\n >\n {t(\"cancel\")}\n </Button>\n </DialogClose>\n <Button\n type=\"button\"\n variant=\"destructive\"\n className=\"min-w-[70px]\"\n onClick={onAction}\n disabled={isLoading}\n >\n {isLoading ? (\n <div className=\"border-primary-foreground h-5 w-5 animate-spin rounded-full border-4 border-t-4 border-t-transparent\" />\n ) : (\n actionText\n )}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","import {\n useController,\n type Control,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\nimport {\n Input,\n Label,\n Select,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectValue,\n Textarea,\n cn,\n} from \"@fluid-app/ui-primitives\";\n\nexport type NameValue = { name: string; value: string | number };\n\nexport function FormTextField<T extends FieldValues>({\n control,\n name,\n label,\n containerClassName,\n ...props\n}: {\n control: Control<T>;\n name: FieldPath<T>;\n label?: string;\n containerClassName?: string;\n} & Omit<React.ComponentProps<\"input\">, \"name\">) {\n const {\n field,\n fieldState: { error },\n } = useController({ name, control });\n return (\n <div className={cn(\"space-y-1\", containerClassName)}>\n {label && (\n <Label htmlFor={name} className=\"mb-1.5 block text-sm font-medium\">\n {label}\n </Label>\n )}\n <Input\n {...field}\n {...props}\n id={name}\n value={field.value ?? \"\"}\n className={cn(error && \"ring-destructive ring-1\", props.className)}\n />\n {error && <p className=\"text-destructive text-sm\">{error.message}</p>}\n </div>\n );\n}\n\nexport function FormTextareaField<T extends FieldValues>({\n control,\n name,\n label,\n containerClassName,\n ...props\n}: {\n control: Control<T>;\n name: FieldPath<T>;\n label?: string;\n containerClassName?: string;\n} & Omit<React.ComponentProps<\"textarea\">, \"name\">) {\n const {\n field,\n fieldState: { error },\n } = useController({ name, control });\n return (\n <div className={cn(\"space-y-1\", containerClassName)}>\n {label && (\n <Label htmlFor={name} className=\"mb-1.5 block text-sm font-medium\">\n {label}\n </Label>\n )}\n <Textarea\n {...field}\n {...props}\n id={name}\n value={field.value ?? \"\"}\n className={cn(error && \"ring-destructive ring-1\", props.className)}\n />\n {error && <p className=\"text-destructive text-sm\">{error.message}</p>}\n </div>\n );\n}\n\nexport function FormSelectField<T extends FieldValues>({\n control,\n name,\n label,\n options,\n placeholder,\n containerClassName,\n onChange,\n}: {\n control: Control<T>;\n name: FieldPath<T>;\n label?: string;\n options?: NameValue[];\n placeholder?: string;\n containerClassName?: string;\n onChange?: (value: string) => void;\n}) {\n const {\n field,\n fieldState: { error },\n } = useController({ name, control });\n return (\n <div className={cn(\"space-y-1\", containerClassName)}>\n {label && (\n <Label htmlFor={name} className=\"block text-sm font-medium\">\n {label}\n </Label>\n )}\n <Select\n value={field.value?.toString() ?? \"\"}\n onValueChange={(val) => {\n field.onChange(val);\n onChange?.(val);\n }}\n >\n <SelectTrigger\n id={name}\n className={cn(\"w-full\", error && \"ring-destructive ring-1\")}\n >\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options?.map((opt) => (\n <SelectItem\n key={`${opt.name}-${opt.value}`}\n value={opt.value.toString()}\n >\n {opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {error && <p className=\"text-destructive text-sm\">{error.message}</p>}\n </div>\n );\n}\n","import { useState, type JSX } from \"react\";\nimport type { Control } from \"react-hook-form\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n Button,\n Input,\n} from \"@fluid-app/ui-primitives\";\nimport { Info } from \"lucide-react\";\nimport {\n FormTextField,\n FormTextareaField,\n FormSelectField,\n type NameValue,\n} from \"./form-fields\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\n\nexport type UserFormData = {\n first_name: string;\n last_name: string;\n phone_number?: string;\n language: string;\n bio?: string;\n};\n\nexport default function UserInfoDialog({\n control,\n isOpen,\n onSubmit,\n handleClose,\n languageOptions,\n errorMsg,\n isSubmitting,\n email,\n onChangeEmail,\n isChangingEmail,\n pendingEmail,\n}: {\n control: Control<UserFormData>;\n isOpen: boolean;\n onSubmit: () => void;\n handleClose: () => void;\n languageOptions?: NameValue[];\n errorMsg: string | undefined;\n isSubmitting: boolean;\n email?: string;\n onChangeEmail?: (newEmail: string) => Promise<void> | void;\n isChangingEmail?: boolean;\n pendingEmail?: string;\n}): JSX.Element {\n const { t } = useProfileTranslation();\n const [isEditingEmail, setIsEditingEmail] = useState(false);\n const [newEmail, setNewEmail] = useState(\"\");\n const [emailError, setEmailError] = useState<string | undefined>(undefined);\n\n const handleEmailSubmit = async () => {\n setEmailError(undefined);\n const trimmed = newEmail.trim();\n if (!trimmed) {\n setEmailError(\"Please enter a new email address\");\n return;\n }\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(trimmed)) {\n setEmailError(\"Please enter a valid email address\");\n return;\n }\n if (email && trimmed.toLowerCase() === email.toLowerCase()) {\n setEmailError(\"New email must be different from your current email\");\n return;\n }\n try {\n await onChangeEmail?.(trimmed);\n setIsEditingEmail(false);\n setNewEmail(\"\");\n } catch (err) {\n setEmailError(\n err instanceof Error ? err.message : \"Failed to initiate email change\",\n );\n }\n };\n\n const handleCancelEmailEdit = () => {\n setIsEditingEmail(false);\n setNewEmail(\"\");\n setEmailError(undefined);\n };\n\n const handleDialogClose = () => {\n handleCancelEmailEdit();\n handleClose();\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && handleDialogClose()}>\n <DialogContent className=\"max-w-sm md:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{t(\"edit_profile\")}</DialogTitle>\n </DialogHeader>\n <div className=\"space-y-4\">\n <FormTextField\n control={control}\n name=\"first_name\"\n label={t(\"first_name\")}\n />\n <FormTextField\n control={control}\n name=\"last_name\"\n label={t(\"last_name\")}\n />\n <FormTextField\n control={control}\n name=\"phone_number\"\n label={t(\"phone_number\")}\n type=\"tel\"\n />\n <FormTextareaField\n control={control}\n name=\"bio\"\n label={t(\"bio\")}\n rows={3}\n placeholder={t(\"add_a_short_bio\")}\n />\n <FormSelectField\n control={control}\n name=\"language\"\n label={t(\"language\")}\n options={languageOptions}\n placeholder={t(\"select_an_option\")}\n />\n </div>\n {email && (\n <div className=\"space-y-2\">\n <label className=\"text-foreground text-sm font-medium\">\n {t(\"email\") || \"Email\"}\n </label>\n {isEditingEmail ? (\n <div className=\"space-y-2\">\n <Input\n type=\"email\"\n placeholder=\"Enter your new email...\"\n value={newEmail}\n onChange={(e) => {\n setNewEmail(e.target.value);\n setEmailError(undefined);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleEmailSubmit();\n }\n if (e.key === \"Escape\") {\n handleCancelEmailEdit();\n }\n }}\n aria-invalid={!!emailError || undefined}\n autoFocus\n />\n {emailError && (\n <p className=\"text-destructive text-xs\">{emailError}</p>\n )}\n <div className=\"bg-muted flex items-start gap-2.5 rounded-md px-3 py-2.5\">\n <Info className=\"text-primary mt-0.5 h-4 w-4 shrink-0\" />\n <p className=\"text-muted-foreground text-xs\">\n We'll send a verification link to your new email. Click\n it to complete the change.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancelEmailEdit}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={handleEmailSubmit}\n disabled={!newEmail.trim() || isChangingEmail}\n >\n {isChangingEmail && (\n <div className=\"mr-2 h-3.5 w-3.5 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isChangingEmail ? \"Sending...\" : \"Send verification\"}\n </Button>\n </div>\n </div>\n ) : pendingEmail ? (\n <div className=\"space-y-2\">\n <div className=\"bg-muted text-muted-foreground min-w-0 rounded-md px-3 py-2 text-sm\">\n {email}\n </div>\n <div className=\"bg-muted flex items-start gap-2.5 rounded-md px-3 py-2.5\">\n <Info className=\"text-primary mt-0.5 h-4 w-4 shrink-0\" />\n <p className=\"text-muted-foreground text-xs\">\n Changing to{\" \"}\n <span className=\"text-foreground font-medium\">\n {pendingEmail}\n </span>\n . Check your new email inbox and click the verification link\n to complete the change.\n </p>\n </div>\n </div>\n ) : (\n <div className=\"flex items-center gap-2\">\n <div className=\"bg-muted text-muted-foreground min-w-0 flex-1 rounded-md px-3 py-2 text-sm\">\n {email}\n </div>\n {onChangeEmail && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setIsEditingEmail(true)}\n className=\"shrink-0\"\n >\n Change\n </Button>\n )}\n </div>\n )}\n </div>\n )}\n {errorMsg && <p className=\"text-destructive text-sm\">{errorMsg}</p>}\n <DialogFooter className=\"flex flex-row items-center justify-end\">\n <div className=\"flex-1 text-right\">\n <Button type=\"button\" onClick={onSubmit}>\n {isSubmitting && (\n <div className=\"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isSubmitting ? t(\"saving\") : t(\"save_changes\")}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","import { useState, type JSX } from \"react\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\n\nconst PAYMENT_ICON_BASE = \"https://assets.fluid.app/images/payment_icons\";\nconst GENERIC_PAYMENT_ICON = `${PAYMENT_ICON_BASE}/generic.svg`;\n\nexport function brandIconUrl(brand: string | null | undefined): string {\n if (!brand) return GENERIC_PAYMENT_ICON;\n const slug = brand.toLowerCase().replace(/\\s+/g, \"_\");\n return `${PAYMENT_ICON_BASE}/${slug}.svg`;\n}\n\nexport function PaymentIcon({\n logoUrl,\n brand,\n alt,\n}: {\n logoUrl?: string;\n brand: string | null | undefined;\n alt: string;\n}): JSX.Element {\n const computedSrc = logoUrl || brandIconUrl(brand);\n const [hasError, setHasError] = useState(false);\n const src = hasError ? GENERIC_PAYMENT_ICON : computedSrc;\n return (\n <img\n src={src}\n alt={alt}\n width={40}\n height={24}\n className=\"object-contain\"\n onError={() => setHasError(true)}\n />\n );\n}\n\nexport function getCardDisplayName(\n paymentMethod: fluidPay.CustomerPaymentMethod,\n): string {\n const lastFour = paymentMethod.details.last_four;\n if (lastFour != null || paymentMethod.payment_type === \"Credit Card\") {\n const brand = paymentMethod.details.card_type || \"Card\";\n return `${brand} •••• ${lastFour || \"••••\"}`;\n }\n return paymentMethod.payment_type;\n}\n\nexport function getCardExpiry(\n paymentMethod: fluidPay.CustomerPaymentMethod,\n): string {\n const { exp_month, exp_year } = paymentMethod.details;\n if (exp_month != null && exp_year != null) {\n return `Expires ${exp_month}/${exp_year}`;\n }\n return \"\";\n}\n","import { createContext, useContext } from \"react\";\n\nexport type TranslationFn = (key: string) => string;\n\nexport interface ProfileUIContextValue {\n t: TranslationFn;\n}\n\nexport const ProfileUIContext = createContext<ProfileUIContextValue | null>(\n null,\n);\n\nexport function useProfileUI(): ProfileUIContextValue {\n const context = useContext(ProfileUIContext);\n if (!context) {\n throw new Error(\"useProfileUI must be used within a ProfileUIProvider\");\n }\n return context;\n}\n","import type { JSX, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport { ProfileUIContext, type TranslationFn } from \"./context\";\n\nexport interface ProfileUIProviderProps {\n t: TranslationFn;\n children: ReactNode;\n}\n\nexport function ProfileUIProvider({\n t,\n children,\n}: ProfileUIProviderProps): JSX.Element {\n const value = useMemo(() => ({ t }), [t]);\n return (\n <ProfileUIContext.Provider value={value}>\n {children}\n </ProfileUIContext.Provider>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { FluidPayApi } from \"./api-interface\";\n\nconst FluidPayApiContext = createContext<FluidPayApi | null>(null);\n\nexport const FluidPayApiProvider = FluidPayApiContext.Provider;\n\nexport function useFluidPayApi(): FluidPayApi {\n const api = useContext(FluidPayApiContext);\n if (!api) {\n throw new Error(\n \"useFluidPayApi must be used within a FluidPayCoreProvider\",\n );\n }\n return api;\n}\n","import type { JSX } from \"react\";\nimport type { FluidPayApi } from \"./api-interface\";\nimport { FluidPayApiProvider } from \"./context\";\n\nexport interface FluidPayCoreProviderProps {\n api: FluidPayApi;\n children: React.ReactNode;\n}\n\nexport function FluidPayCoreProvider({\n api,\n children,\n}: FluidPayCoreProviderProps): JSX.Element {\n return <FluidPayApiProvider value={api}>{children}</FluidPayApiProvider>;\n}\n","export interface State {\n name: string;\n isoCode: string;\n}\n\nexport interface RegionConfig {\n regionLabel: string;\n postalLabel: string;\n}\n\nexport const US_STATES: State[] = [\n { name: \"Alabama\", isoCode: \"AL\" },\n { name: \"Alaska\", isoCode: \"AK\" },\n { name: \"Arizona\", isoCode: \"AZ\" },\n { name: \"Arkansas\", isoCode: \"AR\" },\n { name: \"California\", isoCode: \"CA\" },\n { name: \"Colorado\", isoCode: \"CO\" },\n { name: \"Connecticut\", isoCode: \"CT\" },\n { name: \"Delaware\", isoCode: \"DE\" },\n { name: \"Florida\", isoCode: \"FL\" },\n { name: \"Georgia\", isoCode: \"GA\" },\n { name: \"Hawaii\", isoCode: \"HI\" },\n { name: \"Idaho\", isoCode: \"ID\" },\n { name: \"Illinois\", isoCode: \"IL\" },\n { name: \"Indiana\", isoCode: \"IN\" },\n { name: \"Iowa\", isoCode: \"IA\" },\n { name: \"Kansas\", isoCode: \"KS\" },\n { name: \"Kentucky\", isoCode: \"KY\" },\n { name: \"Louisiana\", isoCode: \"LA\" },\n { name: \"Maine\", isoCode: \"ME\" },\n { name: \"Maryland\", isoCode: \"MD\" },\n { name: \"Massachusetts\", isoCode: \"MA\" },\n { name: \"Michigan\", isoCode: \"MI\" },\n { name: \"Minnesota\", isoCode: \"MN\" },\n { name: \"Mississippi\", isoCode: \"MS\" },\n { name: \"Missouri\", isoCode: \"MO\" },\n { name: \"Montana\", isoCode: \"MT\" },\n { name: \"Nebraska\", isoCode: \"NE\" },\n { name: \"Nevada\", isoCode: \"NV\" },\n { name: \"New Hampshire\", isoCode: \"NH\" },\n { name: \"New Jersey\", isoCode: \"NJ\" },\n { name: \"New Mexico\", isoCode: \"NM\" },\n { name: \"New York\", isoCode: \"NY\" },\n { name: \"North Carolina\", isoCode: \"NC\" },\n { name: \"North Dakota\", isoCode: \"ND\" },\n { name: \"Ohio\", isoCode: \"OH\" },\n { name: \"Oklahoma\", isoCode: \"OK\" },\n { name: \"Oregon\", isoCode: \"OR\" },\n { name: \"Pennsylvania\", isoCode: \"PA\" },\n { name: \"Rhode Island\", isoCode: \"RI\" },\n { name: \"South Carolina\", isoCode: \"SC\" },\n { name: \"South Dakota\", isoCode: \"SD\" },\n { name: \"Tennessee\", isoCode: \"TN\" },\n { name: \"Texas\", isoCode: \"TX\" },\n { name: \"Utah\", isoCode: \"UT\" },\n { name: \"Vermont\", isoCode: \"VT\" },\n { name: \"Virginia\", isoCode: \"VA\" },\n { name: \"Washington\", isoCode: \"WA\" },\n { name: \"West Virginia\", isoCode: \"WV\" },\n { name: \"Wisconsin\", isoCode: \"WI\" },\n { name: \"Wyoming\", isoCode: \"WY\" },\n { name: \"District of Columbia\", isoCode: \"DC\" },\n];\n\nexport const COUNTRY_CONFIGS: Record<string, RegionConfig> = {\n US: { regionLabel: \"State\", postalLabel: \"ZIP Code\" },\n JP: { regionLabel: \"Prefecture\", postalLabel: \"Postal Code\" },\n};\n\nconst DEFAULT_REGION_CONFIG: RegionConfig = {\n regionLabel: \"Province\",\n postalLabel: \"Postal Code\",\n};\n\nexport function getRegionConfig(countryCode: string): RegionConfig {\n return COUNTRY_CONFIGS[countryCode] ?? DEFAULT_REGION_CONFIG;\n}\n\nexport const DEFAULT_ADDRESS_FIELDS = [\n { field: \"first_name\", label: \"First Name\", required: true },\n { field: \"last_name\", label: \"Last Name\", required: true },\n { field: \"address1\", label: \"Address\", required: true },\n { field: \"address2\", label: \"Apartment, suite, etc.\", required: false },\n { field: \"city\", label: \"City\", required: true },\n { field: \"state\", label: \"State\", required: true },\n { field: \"postal_code\", label: \"Postal Code\", required: true },\n { field: \"country_code\", label: \"Country\", required: true },\n];\n","import { useCallback, useState } from \"react\";\nimport {\n US_STATES,\n getRegionConfig,\n type State,\n} from \"../utils/country-config\";\n\nexport default function useCountryStates() {\n const [selectedCountry, setSelectedCountry] = useState<string>(\"US\");\n const [stateOptions, setStateOptions] = useState<State[]>(US_STATES);\n\n const handleCountryChange = useCallback(\n (\n selectedCountryCode: string,\n fetchStates?: (countryCode: string) => Promise<State[]>,\n ) => {\n setSelectedCountry(selectedCountryCode);\n if (selectedCountryCode === \"US\") {\n setStateOptions(US_STATES);\n } else if (fetchStates) {\n fetchStates(selectedCountryCode)\n .then((states) => setStateOptions(states))\n .catch((error) => {\n console.error(\"Failed to fetch states:\", error);\n setStateOptions([]);\n });\n } else {\n setStateOptions([]);\n }\n },\n [],\n );\n\n const config = getRegionConfig(selectedCountry);\n\n return { handleCountryChange, stateOptions, config, selectedCountry };\n}\n","import { useEffect, useMemo, useState, type JSX } from \"react\";\nimport { useWatch } from \"react-hook-form\";\nimport { z } from \"zod\";\nimport { Trash2 } from \"lucide-react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n Button,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport { FormTextField, FormSelectField } from \"./form-fields\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport { useCountryStates } from \"@fluid-app/profile-core\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\nimport type { BillingAddress } from \"./view-payment-method-dialog\";\n\nconst editPaymentMethodFormSchema = z.object({\n billing_address: z.object({\n name: z.string().min(1, \"Name is required\"),\n address1: z.string().min(1, \"Address line 1 is required\"),\n address2: z.string().optional().nullable(),\n city: z.string().min(1, \"City is required\"),\n state: z.string().min(1, \"State is required\"),\n zip: z.string().min(1, \"Zip code is required\"),\n country_code: z.string().min(1, \"Country is required\"),\n }),\n set_as_default: z.boolean(),\n});\n\nexport type EditPaymentMethodFormData = z.infer<\n typeof editPaymentMethodFormSchema\n>;\n\ninterface CountryOption {\n iso: string;\n name: string;\n}\n\ninterface EditPaymentMethodDialogProps {\n isOpen: boolean;\n paymentMethod: fluidPay.CustomerPaymentMethod | null;\n billingAddress?: BillingAddress | null;\n onClose: () => void;\n onSubmit: (data: EditPaymentMethodFormData) => void;\n isSubmitting: boolean;\n error?: string;\n countries?: CountryOption[];\n onDelete?: () => void;\n isDeleting?: boolean;\n}\n\nexport default function EditPaymentMethodDialog({\n isOpen,\n paymentMethod,\n billingAddress,\n onClose,\n onSubmit,\n isSubmitting,\n error,\n countries = [],\n onDelete,\n isDeleting = false,\n}: EditPaymentMethodDialogProps): JSX.Element | null {\n const { t } = useProfileTranslation();\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n useEffect(() => {\n if (!isOpen) setConfirmDelete(false);\n }, [isOpen]);\n\n useEffect(() => {\n if (!confirmDelete) return;\n const timeoutId = setTimeout(() => setConfirmDelete(false), 3000);\n return () => clearTimeout(timeoutId);\n }, [confirmDelete]);\n\n const { control, handleSubmit, reset, setValue } =\n useZodForm<EditPaymentMethodFormData>(editPaymentMethodFormSchema, {\n defaultValues: {\n billing_address: {\n name: \"\",\n address1: \"\",\n address2: \"\",\n city: \"\",\n state: \"\",\n zip: \"\",\n country_code: \"US\",\n },\n set_as_default: false,\n },\n });\n\n const billingCountry = useWatch({\n control,\n name: \"billing_address.country_code\",\n });\n const setAsDefault = useWatch({ control, name: \"set_as_default\" });\n\n const { stateOptions, config, handleCountryChange } = useCountryStates();\n\n const countryOptions = [...countries]\n .map((country) => ({\n name: country.name,\n value: country.iso,\n }))\n .sort((a, b) => {\n if (a.value === billingCountry) return -1;\n if (b.value === billingCountry) return 1;\n return a.name.localeCompare(b.name);\n });\n\n const stateSelectOptions = stateOptions.map((state) => ({\n name: state.name,\n value: state.isoCode,\n }));\n\n useEffect(() => {\n if (paymentMethod && isOpen) {\n reset({\n billing_address: {\n name: billingAddress?.name ?? \"\",\n address1: billingAddress?.address1 ?? \"\",\n address2: billingAddress?.address2 ?? \"\",\n city: billingAddress?.city ?? \"\",\n state: billingAddress?.state ?? \"\",\n zip: billingAddress?.zip ?? \"\",\n country_code: billingAddress?.country_code ?? \"US\",\n },\n set_as_default: paymentMethod.default,\n });\n }\n }, [paymentMethod, billingAddress, isOpen, reset]);\n\n const handleCountrySelect = (countryCode: string) => {\n handleCountryChange(countryCode);\n setValue(\"billing_address.country_code\", countryCode, {\n shouldValidate: true,\n });\n };\n\n const handleFormSubmit = handleSubmit((data) => {\n onSubmit(data);\n });\n\n const deleteButtonLabel = useMemo(() => {\n if (isDeleting) return t(\"deleting\");\n if (confirmDelete) return t(\"tap_to_confirm\");\n return t(\"delete_card\");\n }, [isDeleting, confirmDelete, t]);\n\n if (!paymentMethod) return null;\n\n const { details } = paymentMethod;\n const cardBrand = details.card_type ?? \"Card\";\n const lastFour = details.last_four ?? \"****\";\n const expMonth = details.exp_month;\n const expYear = details.exp_year;\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"max-h-[90vh] max-w-sm overflow-y-auto md:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{t(\"edit_card\")}</DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"bg-muted rounded-lg p-4\">\n <div className=\"flex items-center space-x-3\">\n {details.logo_url && (\n <div className=\"h-6 w-10 flex-shrink-0\">\n <img\n src={details.logo_url}\n alt={cardBrand}\n width={40}\n height={24}\n className=\"object-contain\"\n />\n </div>\n )}\n <div className=\"flex flex-col\">\n <span className=\"text-foreground text-sm font-medium\">\n {cardBrand} •••• {lastFour}\n </span>\n {expMonth != null && expYear != null && (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"card_expires\")} {expMonth}/{expYear}\n </span>\n )}\n </div>\n </div>\n </div>\n\n <div>\n <h3 className=\"text-foreground mb-3 text-sm font-medium\">\n {t(\"billing_address\")}\n </h3>\n <div className=\"space-y-3\">\n <FormSelectField\n control={control}\n name=\"billing_address.country_code\"\n label={t(\"country\")}\n options={countryOptions}\n placeholder={t(\"select_an_option\")}\n onChange={(val) => {\n handleCountrySelect(val);\n }}\n />\n <FormTextField\n control={control}\n name=\"billing_address.name\"\n label={t(\"name\")}\n />\n <FormTextField\n control={control}\n name=\"billing_address.address1\"\n label={t(\"address_line_1\")}\n />\n <FormTextField\n control={control}\n name=\"billing_address.address2\"\n label={t(\"address_line_2\")}\n />\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <FormTextField\n control={control}\n name=\"billing_address.city\"\n label={t(\"city\")}\n />\n <FormSelectField\n control={control}\n name=\"billing_address.state\"\n label={\n config?.regionLabel\n ? t(config.regionLabel as never)\n : t(\"state\")\n }\n options={stateSelectOptions}\n placeholder={t(\"select_state\")}\n />\n <FormTextField\n control={control}\n name=\"billing_address.zip\"\n label={\n config?.postalLabel\n ? t(config.postalLabel as never)\n : t(\"zip_code\")\n }\n />\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"mt-2 flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"set_as_default\"\n checked={setAsDefault}\n onChange={() => setValue(\"set_as_default\", !setAsDefault)}\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"set_as_default\" className=\"text-sm\">\n {t(\"set_as_default_payment_method\")}\n </label>\n </div>\n\n {error && <div className=\"text-destructive text-sm\">{error}</div>}\n\n <DialogFooter className=\"flex flex-row items-center justify-between gap-2\">\n {onDelete ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n if (confirmDelete) {\n onDelete();\n } else {\n setConfirmDelete(true);\n }\n }}\n disabled={isSubmitting || isDeleting}\n className=\"text-destructive hover:bg-destructive/10 hover:text-destructive\"\n >\n <Trash2 className=\"size-4\" />\n {deleteButtonLabel}\n </Button>\n ) : (\n <span />\n )}\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={onClose}\n disabled={isSubmitting || isDeleting}\n >\n {t(\"cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={handleFormSubmit}\n disabled={isSubmitting || isDeleting}\n >\n {isSubmitting && (\n <div className=\"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isSubmitting ? t(\"saving\") : t(\"save_changes\")}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","import type React from \"react\";\nimport { useController, type Control } from \"react-hook-form\";\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Label,\n Textarea,\n cn,\n} from \"@fluid-app/ui-primitives\";\nimport { z } from \"zod\";\nimport { FormTextField } from \"./form-fields\";\n\nfunction normalizeUrl(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed;\n return `https://${trimmed}`;\n}\n\nconst urlField = z\n .string()\n .transform(normalizeUrl)\n .pipe(z.string().url().or(z.literal(\"\")));\n\nexport const mySiteProfileSchema = z.object({\n bio: z.string().optional(),\n linkedin: urlField,\n facebook: urlField,\n twitter: urlField,\n instagram: urlField,\n youtube: urlField,\n pinterest: urlField,\n tiktok: urlField,\n whatsapp: z.string().optional(),\n wechat: z.string().optional(),\n});\n\nexport type MySiteProfileFormData = z.infer<typeof mySiteProfileSchema>;\n\nexport const socialFields = [\n {\n name: \"linkedin\",\n label: \"LinkedIn\",\n placeholder: \"linkedin.com/in/username\",\n },\n { name: \"facebook\", label: \"Facebook\", placeholder: \"facebook.com/username\" },\n { name: \"twitter\", label: \"X (Twitter)\", placeholder: \"x.com/username\" },\n {\n name: \"instagram\",\n label: \"Instagram\",\n placeholder: \"instagram.com/username\",\n },\n { name: \"youtube\", label: \"YouTube\", placeholder: \"youtube.com/@channel\" },\n {\n name: \"pinterest\",\n label: \"Pinterest\",\n placeholder: \"pinterest.com/username\",\n },\n { name: \"tiktok\", label: \"TikTok\", placeholder: \"tiktok.com/@username\" },\n { name: \"whatsapp\", label: \"WhatsApp\", placeholder: \"Phone number or link\" },\n { name: \"wechat\", label: \"WeChat\", placeholder: \"WeChat ID\" },\n] as const satisfies readonly {\n name: keyof Omit<MySiteProfileFormData, \"bio\">;\n label: string;\n placeholder: string;\n}[];\n\nexport interface MySiteProfileSectionProps {\n avatarUrl?: string | null;\n initial?: string;\n control: Control<MySiteProfileFormData>;\n}\n\nfunction BioField({ control }: { control: Control<MySiteProfileFormData> }) {\n const {\n field,\n fieldState: { error },\n } = useController({ name: \"bio\", control });\n return (\n <div className=\"space-y-1\">\n <Label htmlFor=\"mysite-bio\" className=\"block text-sm font-medium\">\n Bio\n </Label>\n <Textarea\n id=\"mysite-bio\"\n rows={4}\n placeholder=\"Tell people a little about yourself...\"\n className={cn(error && \"ring-destructive ring-1\")}\n {...field}\n value={field.value ?? \"\"}\n />\n {error && <p className=\"text-destructive text-sm\">{error.message}</p>}\n </div>\n );\n}\n\nexport function MySiteProfileSection({\n avatarUrl,\n initial,\n control,\n}: MySiteProfileSectionProps): React.JSX.Element {\n return (\n <Card>\n <CardHeader>\n <CardTitle>About Me</CardTitle>\n </CardHeader>\n <CardContent className=\"flex flex-col gap-6 lg:flex-row lg:gap-10\">\n <div className=\"bg-muted relative h-[120px] w-[120px] shrink-0 self-center overflow-hidden rounded-full lg:self-auto\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt=\"Profile\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"bg-background text-foreground flex h-full w-full items-center justify-center text-xl font-semibold\">\n {initial ?? \"U\"}\n </div>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <BioField control={control} />\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport interface MySiteProfileSocialSectionProps {\n control: Control<MySiteProfileFormData>;\n}\n\nexport function MySiteProfileSocialSection({\n control,\n}: MySiteProfileSocialSectionProps): React.JSX.Element {\n return (\n <Card>\n <CardHeader>\n <CardTitle>Social Media Links</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {socialFields.map((field) => (\n <FormTextField\n key={field.name}\n control={control}\n name={field.name}\n label={field.label}\n placeholder={field.placeholder}\n />\n ))}\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport interface MySiteProfileSaveButtonProps {\n isDirty: boolean;\n isPending: boolean;\n onSubmit: () => void;\n}\n\nexport function MySiteProfileSaveButton({\n isDirty,\n isPending,\n onSubmit,\n}: MySiteProfileSaveButtonProps): React.JSX.Element {\n return (\n <div className=\"flex justify-end pb-6\">\n <Button\n type=\"button\"\n onClick={onSubmit}\n disabled={!isDirty || isPending}\n className=\"w-full sm:w-auto\"\n >\n {isPending && (\n <div className=\"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </div>\n );\n}\n","\"use client\";\n\nimport type { Control, FieldPath, FieldValues } from \"react-hook-form\";\nimport { useController } from \"react-hook-form\";\nimport { Input, Label, cn } from \"@fluid-app/ui-primitives\";\n\ninterface FormTextFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n control: Control<TFieldValues>;\n name: TName;\n label?: string;\n placeholder?: string;\n containerClassName?: string;\n type?: React.HTMLInputTypeAttribute;\n disabled?: boolean;\n inputMode?: React.HTMLAttributes<HTMLInputElement>[\"inputMode\"];\n}\n\nexport function FormTextField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n control,\n name,\n label,\n placeholder,\n containerClassName,\n type,\n disabled,\n inputMode,\n}: FormTextFieldProps<TFieldValues, TName>) {\n const {\n field,\n fieldState: { error },\n } = useController({ name, control });\n\n return (\n <div className={cn(\"space-y-1\", containerClassName)}>\n {label && (\n <Label htmlFor={name} className=\"mb-1.5 block text-sm font-medium\">\n {label}\n </Label>\n )}\n <Input\n {...field}\n value={field.value ?? \"\"}\n id={name}\n type={type}\n disabled={disabled}\n inputMode={inputMode}\n placeholder={placeholder}\n aria-invalid={!!error}\n />\n {error?.message && (\n <p className=\"text-destructive text-sm\">{error.message}</p>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport type { Control, FieldPath, FieldValues } from \"react-hook-form\";\nimport { Controller } from \"react-hook-form\";\nimport {\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n cn,\n} from \"@fluid-app/ui-primitives\";\n\ntype NameValue = { name: string; value: string | number };\n\ninterface FormSelectFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n control: Control<TFieldValues>;\n name: TName;\n label?: string;\n placeholder?: string;\n options?: NameValue[];\n containerClassName?: string;\n disabled?: boolean;\n}\n\nexport function FormSelectField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n control,\n name,\n label,\n placeholder = \"Select\",\n options,\n containerClassName,\n disabled,\n}: FormSelectFieldProps<TFieldValues, TName>) {\n return (\n <div className={cn(\"space-y-1\", containerClassName)}>\n {label && (\n <Label htmlFor={name} className=\"mb-1.5 block text-sm font-medium\">\n {label}\n </Label>\n )}\n <Controller\n control={control}\n name={name}\n render={({ field: { onChange, value }, fieldState: { error } }) => (\n <>\n <Select\n value={value?.toString() ?? \"\"}\n onValueChange={onChange}\n disabled={disabled}\n >\n <SelectTrigger\n id={name}\n aria-invalid={!!error}\n className=\"w-full\"\n >\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options && options.length > 0 ? (\n options.map((opt) => (\n <SelectItem\n key={opt.value.toString()}\n value={opt.value.toString()}\n >\n {opt.name}\n </SelectItem>\n ))\n ) : (\n <SelectItem value=\"__empty\" disabled>\n No available options\n </SelectItem>\n )}\n </SelectContent>\n </Select>\n {error?.message && (\n <p className=\"text-destructive text-sm\">{error.message}</p>\n )}\n </>\n )}\n />\n </div>\n );\n}\n","import { type JSX, type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { useWatch, type Control, type UseFormSetValue } from \"react-hook-form\";\nimport { Trash2 } from \"lucide-react\";\nimport { z } from \"zod\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Button,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport { FormTextField } from \"./form-fields/FormTextField\";\nimport { FormSelectField } from \"./form-fields/FormSelectField\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport { useCountryStates, type State } from \"@fluid-app/fluid-pay-core\";\n\nconst addressFormSchema = z.object({\n first_name: z.string().min(1, \"First name is required\"),\n last_name: z.string().min(1, \"Last name is required\"),\n address1: z.string().min(1, \"Address line 1 is required\"),\n address2: z.string().optional().nullable(),\n city: z.string().min(1, \"City is required\"),\n state: z.string().min(1, \"State is required\"),\n postal_code: z.string().min(1, \"Postal code is required\"),\n country_code: z.string().min(1, \"Country is required\"),\n default: z.boolean(),\n});\n\nexport type AddressFormData = z.infer<typeof addressFormSchema>;\n\ninterface CountryOption {\n iso: string;\n name: string;\n}\n\nexport interface AddressAutocompleteRenderProps {\n control: Control<AddressFormData>;\n setValue: UseFormSetValue<AddressFormData>;\n countryCode: string;\n}\n\ninterface AddressFormDialogProps {\n isOpen: boolean;\n onClose: () => void;\n selectedAddress: fluidPay.CustomerAddress | null;\n onSubmit: (data: fluidPay.CreateAddressBody) => void;\n isSubmitting: boolean;\n countries?: CountryOption[];\n error?: string;\n renderAddressAutocomplete?: (\n props: AddressAutocompleteRenderProps,\n ) => ReactNode;\n fetchStates?: (countryCode: string) => Promise<State[]>;\n t: (key: string) => string;\n onDelete?: () => void;\n isDeleting?: boolean;\n}\n\nexport default function AddressFormDialog({\n isOpen,\n onClose,\n selectedAddress,\n onSubmit,\n isSubmitting,\n countries = [],\n error,\n renderAddressAutocomplete,\n fetchStates,\n t,\n onDelete,\n isDeleting = false,\n}: AddressFormDialogProps): JSX.Element {\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n useEffect(() => {\n if (!isOpen) setConfirmDelete(false);\n }, [isOpen]);\n\n useEffect(() => {\n if (!confirmDelete) return;\n const timeoutId = setTimeout(() => setConfirmDelete(false), 3000);\n return () => clearTimeout(timeoutId);\n }, [confirmDelete]);\n\n const deleteButtonLabel = useMemo(() => {\n if (isDeleting) return t(\"deleting\");\n if (confirmDelete) return t(\"tap_to_confirm\");\n return t(\"delete_address\");\n }, [isDeleting, confirmDelete, t]);\n const { control, handleSubmit, reset, setValue } =\n useZodForm<AddressFormData>(addressFormSchema, {\n defaultValues: {\n first_name: \"\",\n last_name: \"\",\n address1: \"\",\n address2: \"\",\n city: \"\",\n state: \"\",\n postal_code: \"\",\n country_code: \"US\",\n default: false,\n },\n });\n\n const selectedCountryCode = useWatch({ control, name: \"country_code\" });\n const isDefault = useWatch({ control, name: \"default\" });\n\n const { stateOptions, config, handleCountryChange } = useCountryStates();\n\n const countrySelectOptions = [...countries]\n .map((country) => ({\n name: country.name,\n value: country.iso,\n }))\n .sort((a, b) => {\n if (a.value === selectedCountryCode) return -1;\n if (b.value === selectedCountryCode) return 1;\n return a.name.localeCompare(b.name);\n });\n\n const stateSelectOptions = stateOptions.map((state) => ({\n name: state.name,\n value: state.isoCode,\n }));\n\n useEffect(() => {\n if (isOpen) {\n if (selectedAddress) {\n const nameParts = (selectedAddress.name ?? \"\").split(\" \");\n const firstName = nameParts[0] ?? \"\";\n const lastName = nameParts.slice(1).join(\" \");\n reset({\n first_name: firstName,\n last_name: lastName,\n address1: selectedAddress.address1,\n address2: selectedAddress.address2 ?? \"\",\n city: selectedAddress.city,\n state: selectedAddress.state,\n postal_code: selectedAddress.postal_code,\n country_code: selectedAddress.country_code ?? \"US\",\n default: selectedAddress.default,\n });\n handleCountryChange(selectedAddress.country_code ?? \"US\", fetchStates);\n } else {\n reset({\n first_name: \"\",\n last_name: \"\",\n address1: \"\",\n address2: \"\",\n city: \"\",\n state: \"\",\n postal_code: \"\",\n country_code: \"US\",\n default: false,\n });\n handleCountryChange(\"US\", fetchStates);\n }\n }\n }, [selectedAddress, isOpen, reset, handleCountryChange, fetchStates]);\n\n useEffect(() => {\n handleCountryChange(selectedCountryCode, fetchStates);\n }, [selectedCountryCode, handleCountryChange, fetchStates]);\n\n const handleFormSubmit = handleSubmit((data) => {\n onSubmit({\n address: {\n first_name: data.first_name,\n last_name: data.last_name,\n address1: data.address1,\n address2: data.address2 ?? null,\n city: data.city,\n state: data.state,\n postal_code: data.postal_code,\n country_code: data.country_code,\n default: data.default,\n },\n });\n });\n\n const isEditMode = selectedAddress !== null;\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"max-h-[90vh] max-w-md overflow-y-auto rounded md:max-w-xl\">\n <DialogHeader>\n <DialogTitle className=\"text-lg font-medium\">\n {isEditMode ? t(\"edit_address\") : t(\"add_an_address\")}\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-3 pt-2\">\n <FormSelectField\n control={control}\n name=\"country_code\"\n label={t(\"country\")}\n placeholder={t(\"select_an_option\")}\n options={countrySelectOptions}\n disabled={isSubmitting}\n />\n <div className=\"flex gap-3\">\n <FormTextField\n control={control}\n name=\"first_name\"\n label={t(\"first_name\")}\n containerClassName=\"flex-1\"\n disabled={isSubmitting}\n />\n <FormTextField\n control={control}\n name=\"last_name\"\n label={t(\"last_name\")}\n containerClassName=\"flex-1\"\n disabled={isSubmitting}\n />\n </div>\n {renderAddressAutocomplete ? (\n renderAddressAutocomplete({\n control,\n setValue,\n countryCode: selectedCountryCode,\n })\n ) : (\n <FormTextField\n control={control}\n name=\"address1\"\n label={t(\"address_line_1\")}\n disabled={isSubmitting}\n />\n )}\n <FormTextField\n control={control}\n name=\"address2\"\n label={t(\"address_line_2\")}\n disabled={isSubmitting}\n />\n <div className=\"flex gap-3\">\n <FormTextField\n control={control}\n name=\"city\"\n label={t(\"city\")}\n containerClassName=\"flex-1\"\n disabled={isSubmitting}\n />\n <FormSelectField\n control={control}\n name=\"state\"\n label={config?.regionLabel ? t(config.regionLabel) : t(\"state\")}\n placeholder={t(\"select_state\")}\n options={stateSelectOptions}\n containerClassName=\"flex-1\"\n disabled={isSubmitting}\n />\n <FormTextField\n control={control}\n name=\"postal_code\"\n label={\n config?.postalLabel ? t(config.postalLabel) : t(\"zip_code\")\n }\n containerClassName=\"flex-1\"\n disabled={isSubmitting}\n />\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-wrap items-center justify-between gap-3\">\n {onDelete ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n if (confirmDelete) {\n onDelete();\n } else {\n setConfirmDelete(true);\n }\n }}\n disabled={isSubmitting || isDeleting}\n className=\"text-destructive hover:bg-destructive/10 hover:text-destructive\"\n >\n <Trash2 className=\"size-4\" />\n {deleteButtonLabel}\n </Button>\n ) : (\n <span />\n )}\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"set_as_default_address\"\n checked={isDefault}\n onChange={() => setValue(\"default\", !isDefault)}\n disabled={isSubmitting || isDeleting}\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"set_as_default_address\" className=\"text-sm\">\n {t(\"set_as_default_address\")}\n </label>\n </div>\n\n <Button\n type=\"submit\"\n onClick={handleFormSubmit}\n disabled={isSubmitting || isDeleting}\n >\n {isSubmitting && (\n <div className=\"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isSubmitting ? t(\"saving\") : t(\"save_address\")}\n </Button>\n </div>\n </div>\n\n {error && <div className=\"text-destructive mt-2 text-sm\">{error}</div>}\n </DialogContent>\n </Dialog>\n );\n}\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\n\nexport type VgsFieldState = {\n isFocused: boolean;\n isValid: boolean;\n isEmpty: boolean;\n};\n\nexport type VgsFormState = {\n [key: string]: VgsFieldState;\n};\n\ninterface VGSCollectForm {\n setRouteId: (routeId: string) => void;\n field: (selector: string, config: Record<string, unknown>) => void;\n submit: (\n path: string,\n options: { headers?: Record<string, string> },\n successCallback: (\n status: number,\n response: fluidPay.VgsCollectSubmitResponse,\n ) => void,\n errorCallback: (errors: Record<string, string[]>) => void,\n ) => void;\n unmount: () => void;\n}\n\ninterface VGSCollectLibrary {\n create: (\n vaultId: string,\n environment: string,\n stateCallback: (state: Record<string, Partial<VgsFieldState>>) => void,\n ) => VGSCollectForm;\n}\n\nconst getVGSCollect = (): VGSCollectLibrary | null => {\n if (typeof window !== \"undefined\") {\n return (\n (window as unknown as { VGSCollect?: VGSCollectLibrary }).VGSCollect ||\n null\n );\n }\n return null;\n};\n\nconst DEFAULT_FIELD_STATE: VgsFormState = {\n card_number: { isFocused: false, isValid: false, isEmpty: true },\n card_exp: { isFocused: false, isValid: false, isEmpty: true },\n card_cvc: { isFocused: false, isValid: false, isEmpty: true },\n card_holder: { isFocused: false, isValid: false, isEmpty: true },\n};\n\nexport function useVgsCollect() {\n const [isFormReady, setIsFormReady] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [isScriptLoaded, setIsScriptLoaded] = useState(false);\n const [scriptLoadError, setScriptLoadError] = useState<string | undefined>(\n undefined,\n );\n\n const [vgsFieldState, setVgsFieldState] =\n useState<VgsFormState>(DEFAULT_FIELD_STATE);\n\n const formRef = useRef<VGSCollectForm | null>(null);\n const onSuccessRef = useRef<\n ((response: fluidPay.VgsCollectSubmitResponse) => void) | null\n >(null);\n const onErrorRef = useRef<((error: string) => void) | null>(null);\n\n // Load VGS Collect script\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const vgsCollect = getVGSCollect();\n if (vgsCollect) {\n const timeoutId = window.setTimeout(() => {\n setIsScriptLoaded(true);\n }, 0);\n return () => window.clearTimeout(timeoutId);\n }\n\n if (isScriptLoaded) return;\n\n const script = document.createElement(\"script\");\n script.src =\n \"https://js.verygoodvault.com/vgs-collect/3.3.0/vgs-collect.js\";\n script.async = true;\n script.onload = () => setIsScriptLoaded(true);\n // Surface load failures both to a registered consumer (if any) and to\n // state, so a consumer mounting after the failure still sees it.\n script.onerror = () => {\n const message = \"Failed to load payment form\";\n setScriptLoadError(message);\n onErrorRef.current?.(message);\n };\n document.head.appendChild(script);\n }, [isScriptLoaded]);\n\n const updateFieldState = useCallback(\n (state: Record<string, Partial<VgsFieldState>>) => {\n if (!state) return;\n\n setVgsFieldState((prev) => {\n const newState: VgsFormState = { ...prev };\n let hasChanges = false;\n\n Object.keys(state).forEach((key) => {\n const field = state[key];\n if (!field) return;\n\n const next: VgsFieldState = {\n isFocused: !!field.isFocused,\n isValid: !!field.isValid,\n isEmpty: !!field.isEmpty,\n };\n\n if (\n !newState[key] ||\n JSON.stringify(newState[key]) !== JSON.stringify(next)\n ) {\n newState[key] = next;\n hasChanges = true;\n }\n });\n\n return hasChanges ? newState : prev;\n });\n },\n [],\n );\n\n const resetVgs = useCallback(() => {\n if (formRef.current) {\n try {\n formRef.current.unmount();\n } catch (e) {\n console.warn(\"VGS unmount error\", e);\n }\n formRef.current = null;\n }\n\n setIsFormReady(false);\n setVgsFieldState({ ...DEFAULT_FIELD_STATE });\n }, []);\n\n const initializeForm = useCallback(\n async (credentials: fluidPay.VaultResponse) => {\n if (!isScriptLoaded) return;\n\n const VGSCollect = getVGSCollect();\n if (!VGSCollect) {\n onErrorRef.current?.(\"Payment script not loaded\");\n return;\n }\n\n try {\n setIsLoading(true);\n\n const vgsEnvironment =\n credentials.vault.environment === \"sandbox\" ? \"sandbox\" : \"live-eu-1\";\n\n const form = VGSCollect.create(\n credentials.vault.vault_id,\n vgsEnvironment,\n (state) => updateFieldState(state),\n );\n\n if (credentials.vault.route_id) {\n form.setRouteId(credentials.vault.route_id);\n }\n\n formRef.current = form;\n\n // Wait for DOM elements\n let retries = 0;\n const maxRetries = 20;\n const retryDelay = 200;\n\n const waitForDom = async (): Promise<boolean> => {\n const allExist = [\n \"vgs-card-number\",\n \"vgs-expiration-date\",\n \"vgs-cvc\",\n \"vgs-card-holder\",\n ].every((id) => {\n const el = document.getElementById(id);\n return el && el.isConnected;\n });\n\n if (allExist) return true;\n if (retries >= maxRetries) return false;\n\n retries++;\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n return waitForDom();\n };\n\n const domReady = await waitForDom();\n if (!domReady) {\n throw new Error(\"Payment form elements not ready\");\n }\n\n // Resolve theme tokens from the wrapper element. The theme engine\n // applies `data-theme` on a subtree element (not <html>), so CSS\n // variables aren't visible on document.documentElement — only on a\n // node inside the themed subtree. Cross-origin iframe contents\n // can't see parent CSS variables, so we resolve concrete values\n // here and pass them to VGS.\n //\n // The `vgs-card-number` element is guaranteed to exist at this\n // point: the `waitForDom` check above blocks until all four VGS\n // wrapper elements are mounted. The hardcoded fallback colors only\n // activate if the CSS variables themselves are unset.\n const themedNode = document.getElementById(\"vgs-card-number\");\n const probeStyle = themedNode ? getComputedStyle(themedNode) : null;\n const foregroundColor =\n probeStyle?.getPropertyValue(\"--color-foreground\").trim() ||\n \"#0a0a0a\";\n const mutedForegroundColor =\n probeStyle?.getPropertyValue(\"--color-muted-foreground\").trim() ||\n \"#737373\";\n\n // Wrapper is `h-9 py-1` (Input primitive). Content area = 36 - 2 (border) - 8 (py-1) = 26px.\n const css = {\n fontSize: \"14px\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n color: foregroundColor,\n background: \"transparent\",\n paddingTop: \"0px\",\n paddingBottom: \"0px\",\n paddingLeft: \"0px\",\n paddingRight: \"0px\",\n boxSizing: \"border-box\",\n lineHeight: \"26px\",\n height: \"100%\",\n width: \"100%\",\n \"&::placeholder\": { color: mutedForegroundColor, opacity: 1 },\n \"&:focus\": { outline: \"none\" },\n };\n\n form.field(\"#vgs-card-number\", {\n type: \"card-number\",\n name: \"card_number\",\n placeholder: \"0000 0000 0000 0000\",\n showCardIcon: true,\n css: { ...css, paddingRight: \"40px\" },\n autoComplete: \"cc-number\",\n validations: [\"required\", \"validCardNumber\"],\n });\n\n form.field(\"#vgs-expiration-date\", {\n type: \"card-expiration-date\",\n name: \"card_exp\",\n yearLength: 2,\n placeholder: \"MM / YY\",\n css,\n autoComplete: \"cc-exp\",\n validations: [\"required\", \"validCardExpirationDate\"],\n });\n\n form.field(\"#vgs-cvc\", {\n type: \"card-security-code\",\n name: \"card_cvc\",\n placeholder: \"123\",\n css,\n autoComplete: \"cc-csc\",\n validations: [\"required\", \"validCardSecurityCode\"],\n });\n\n form.field(\"#vgs-card-holder\", {\n type: \"text\",\n name: \"card_holder\",\n placeholder: \"Full Name\",\n css,\n autoComplete: \"cc-name\",\n validations: [\"required\"],\n });\n\n setIsFormReady(true);\n } catch (error) {\n console.error(\"Failed to initialize VGS:\", error);\n onErrorRef.current?.(\"Failed to initialize payment form\");\n } finally {\n setIsLoading(false);\n }\n },\n [isScriptLoaded, updateFieldState],\n );\n\n const submitCard = useCallback(() => {\n if (!formRef.current) {\n onErrorRef.current?.(\"Form not initialized\");\n return;\n }\n\n formRef.current.submit(\n `/post`,\n {},\n (status: number, response: fluidPay.VgsCollectSubmitResponse) => {\n if (status >= 200 && status < 400) {\n onSuccessRef.current?.(response);\n } else {\n onErrorRef.current?.(\"Payment failed\");\n }\n },\n (errors: Record<string, string[]>) => {\n const allErrors = Object.values(errors)\n .flat()\n .filter(\n (msg) =>\n typeof msg === \"string\" &&\n msg.trim().length > 0 &&\n msg !== \"Required\",\n );\n\n const uniqueErrors = Array.from(new Set(allErrors));\n\n let errorMsg = \"Please verify your payment details.\";\n if (uniqueErrors.length > 0) {\n errorMsg = uniqueErrors.join(\", \");\n } else {\n const rawErrors = Object.values(errors).flat();\n if (rawErrors.length > 0) {\n errorMsg = \"Please fill in all required fields.\";\n }\n }\n\n onErrorRef.current?.(errorMsg);\n },\n );\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (formRef.current) {\n try {\n formRef.current.unmount();\n } catch (e) {\n console.warn(\"VGS unmount error\", e);\n }\n formRef.current = null;\n }\n };\n }, []);\n\n return {\n isFormReady,\n isLoading,\n isScriptLoaded,\n scriptLoadError,\n initializeForm,\n submitCard,\n vgsFieldState,\n resetVgs,\n onSuccessRef,\n onErrorRef,\n };\n}\n","import {\n type JSX,\n type ReactNode,\n useEffect,\n useState,\n useCallback,\n} from \"react\";\nimport { useWatch, type Control, type UseFormSetValue } from \"react-hook-form\";\nimport { z } from \"zod\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Button,\n cn,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport { FormTextField } from \"./form-fields/FormTextField\";\nimport { FormSelectField } from \"./form-fields/FormSelectField\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport { useFluidPayApi, useCountryStates } from \"@fluid-app/fluid-pay-core\";\nimport {\n useVgsCollect,\n type VgsFieldState,\n type VgsFormState,\n} from \"../hooks/use-vgs-collect\";\n\nconst billingAddressSchema = z.object({\n name: z.string().min(1, \"Name is required\"),\n address1: z.string().min(1, \"Address line 1 is required\"),\n address2: z.string().optional().nullable(),\n city: z.string().min(1, \"City is required\"),\n state: z.string().min(1, \"State is required\"),\n zip: z.string().min(1, \"Zip code is required\"),\n country_code: z.string().min(1, \"Country is required\"),\n set_as_default: z.boolean(),\n});\n\ntype BillingAddressFormData = z.infer<typeof billingAddressSchema>;\n\ninterface CountryOption {\n iso: string;\n name: string;\n}\n\nexport interface BillingAddressAutocompleteRenderProps {\n control: Control<BillingAddressFormData>;\n setValue: UseFormSetValue<BillingAddressFormData>;\n countryCode: string;\n}\n\ninterface CreditCardFormDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (data: fluidPay.AddCreditCardData) => void;\n isSubmitting: boolean;\n countries?: CountryOption[];\n error?: string;\n jwt: string;\n renderAddressAutocomplete?: (\n props: BillingAddressAutocompleteRenderProps,\n ) => ReactNode;\n t: (key: string) => string;\n}\n\nfunction VgsInputWrapper({\n id,\n label,\n fieldState,\n className,\n}: {\n id: string;\n label: string;\n fieldState?: VgsFieldState;\n className?: string;\n}) {\n const isInvalid =\n fieldState?.isValid === false &&\n !fieldState?.isFocused &&\n !fieldState?.isEmpty;\n const isFocused = !!fieldState?.isFocused;\n\n // `aria-invalid` is only meaningful on form-control roles. The wrapper is a\n // styling host for a cross-origin VGS iframe (the actual form control), so\n // we use `data-invalid` for visual state and `role=\"group\"` + `aria-label`\n // to give the iframe an accessible name through its parent.\n return (\n <div\n id={id}\n role=\"group\"\n aria-label={label}\n data-invalid={isInvalid ? \"\" : undefined}\n className={cn(\n // Mirrors the Input primitive's className from @fluid-app/ui-primitives\n // because VGS renders a cross-origin iframe inside this wrapper.\n \"border-input selection:bg-primary selection:text-primary-foreground file:text-foreground placeholder:text-muted-foreground h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"data-[invalid]:border-destructive data-[invalid]:ring-destructive/20\",\n // Iframe must fill the wrapper.\n \"[&_iframe]:block! [&_iframe]:h-full! [&_iframe]:w-full! [&_iframe]:border-0!\",\n // Cross-origin iframe focus doesn't trigger :focus-visible on the\n // wrapper, so mirror Input primitive's focus state from VGS-reported state.\n isFocused && \"border-ring ring-ring/50 ring-[3px]\",\n isFocused && isInvalid && \"border-destructive ring-destructive/20\",\n className,\n )}\n />\n );\n}\n\nfunction VgsCardForm({\n vgsFieldState,\n networkError,\n}: {\n vgsFieldState: VgsFormState;\n networkError?: string;\n}) {\n return (\n <div className=\"space-y-4\" aria-label=\"Credit card form\">\n <VgsInputWrapper\n id=\"vgs-card-number\"\n label=\"Card number\"\n fieldState={vgsFieldState[\"card_number\"]}\n />\n\n <div className=\"flex gap-3\">\n <div className=\"flex-1\">\n <VgsInputWrapper\n id=\"vgs-expiration-date\"\n label=\"Expiration date\"\n fieldState={vgsFieldState[\"card_exp\"]}\n />\n </div>\n <div className=\"flex-1\">\n <VgsInputWrapper\n id=\"vgs-cvc\"\n label=\"CVC\"\n fieldState={vgsFieldState[\"card_cvc\"]}\n />\n </div>\n </div>\n\n <VgsInputWrapper\n id=\"vgs-card-holder\"\n label=\"Cardholder name\"\n fieldState={vgsFieldState[\"card_holder\"]}\n />\n\n {networkError && networkError.trim().length > 0 && (\n <div className=\"bg-destructive/10 text-destructive rounded-md p-3 text-sm\">\n {networkError}\n </div>\n )}\n </div>\n );\n}\n\nexport default function CreditCardFormDialog({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting,\n countries = [],\n error,\n jwt,\n renderAddressAutocomplete,\n t,\n}: CreditCardFormDialogProps): JSX.Element {\n const api = useFluidPayApi();\n const [cardError, setCardError] = useState<string | undefined>(undefined);\n const [isVgsSubmitting, setIsVgsSubmitting] = useState(false);\n\n const {\n isFormReady,\n isLoading: isVgsLoading,\n isScriptLoaded,\n scriptLoadError,\n initializeForm,\n submitCard,\n vgsFieldState,\n resetVgs,\n onSuccessRef,\n onErrorRef,\n } = useVgsCollect();\n\n const { control, handleSubmit, reset, setValue } =\n useZodForm<BillingAddressFormData>(billingAddressSchema, {\n defaultValues: {\n name: \"\",\n address1: \"\",\n address2: \"\",\n city: \"\",\n state: \"\",\n zip: \"\",\n country_code: \"US\",\n set_as_default: false,\n },\n });\n\n const billingCountry = useWatch({ control, name: \"country_code\" });\n const setAsDefault = useWatch({ control, name: \"set_as_default\" });\n\n const { stateOptions, config, handleCountryChange } = useCountryStates();\n\n const countrySelectOptions = [...countries]\n .map((country) => ({\n name: country.name,\n value: country.iso,\n }))\n .sort((a, b) => {\n if (a.value === billingCountry) return -1;\n if (b.value === billingCountry) return 1;\n return a.name.localeCompare(b.name);\n });\n\n const stateSelectOptions = stateOptions.map((state) => ({\n name: state.name,\n value: state.isoCode,\n }));\n\n useEffect(() => {\n handleCountryChange(billingCountry);\n }, [billingCountry, handleCountryChange]);\n\n // Initialize VGS when dialog opens\n useEffect(() => {\n if (!isOpen || !isScriptLoaded) return;\n\n let cancelled = false;\n\n const init = async () => {\n try {\n const credentials = await api.vault.fetchCredentials(jwt);\n if (!cancelled) {\n await initializeForm(credentials);\n }\n } catch (err) {\n console.error(\"Failed to fetch vault credentials:\", err);\n if (!cancelled) {\n setCardError(\"Failed to initialize payment form\");\n }\n }\n };\n\n init();\n\n return () => {\n cancelled = true;\n };\n }, [isOpen, isScriptLoaded, jwt, api, initializeForm]);\n\n // Wire up VGS callbacks\n const handleVgsSuccess = useCallback(\n (response: fluidPay.VgsCollectSubmitResponse) => {\n const expValue = response?.card_exp;\n if (!expValue) {\n setCardError(\"Missing expiration date from payment form\");\n setIsVgsSubmitting(false);\n return;\n }\n\n const cleanExp = expValue.replace(/\\s+/g, \"\");\n const [expMonth, expYearShort] = cleanExp.split(\"/\");\n\n if (!expMonth || !expYearShort) {\n setCardError(\"Invalid expiration date format\");\n setIsVgsSubmitting(false);\n return;\n }\n\n const expYear =\n expYearShort.length === 2 ? `20${expYearShort}` : expYearShort;\n\n const cardholderName = response?.card_holder?.trim();\n if (!cardholderName) {\n setCardError(\"Cardholder name is required\");\n setIsVgsSubmitting(false);\n return;\n }\n\n // Read the current form values synchronously via handleSubmit. If the\n // billing form has gone invalid between the user clicking Save and VGS\n // returning, surface that and clear the spinner — otherwise the dialog\n // would stay stuck in the submitting state with no feedback.\n handleSubmit(\n (formData) => {\n const creditCardData: fluidPay.AddCreditCardData = {\n type: \"credit_card\",\n country_code: formData.country_code,\n default_payment_method: formData.set_as_default,\n payment_method: {\n token: response.card_number,\n cvv_token: response.card_cvc,\n exp_month: expMonth,\n exp_year: expYear,\n card_holder: cardholderName,\n billing_zip: formData.zip,\n },\n billing_address: {\n name: formData.name,\n address1: formData.address1,\n address2: formData.address2 ?? undefined,\n city: formData.city,\n state: formData.state,\n zip: formData.zip,\n country_code: formData.country_code,\n },\n };\n\n onSubmit(creditCardData);\n setIsVgsSubmitting(false);\n },\n () => {\n setCardError(\"Please fix the errors in the billing address.\");\n setIsVgsSubmitting(false);\n },\n )();\n },\n [handleSubmit, onSubmit],\n );\n\n const handleVgsError = useCallback((err: string) => {\n setCardError(err);\n setIsVgsSubmitting(false);\n }, []);\n\n useEffect(() => {\n onSuccessRef.current = handleVgsSuccess;\n onErrorRef.current = handleVgsError;\n }, [handleVgsSuccess, handleVgsError, onSuccessRef, onErrorRef]);\n\n const handleClose = () => {\n resetVgs();\n reset();\n setCardError(undefined);\n setIsVgsSubmitting(false);\n onClose();\n };\n\n const handleFormSubmit = handleSubmit(() => {\n setIsVgsSubmitting(true);\n setCardError(undefined);\n submitCard();\n });\n\n const isBusy = isSubmitting || isVgsSubmitting;\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && handleClose()}>\n <DialogContent className=\"max-h-[90vh] max-w-md overflow-y-auto p-0 md:max-w-xl\">\n <div className=\"relative p-6\">\n {(isVgsLoading || !isFormReady) && !scriptLoadError && (\n <div className=\"bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded backdrop-blur-[1px]\">\n <div className=\"flex items-center justify-center\">\n <div className=\"border-primary mr-3 h-5 w-5 animate-spin rounded-full border-2 border-t-2 border-t-transparent\" />\n <p className=\"text-muted-foreground text-sm font-medium\">\n {t(\"securing\")}\n </p>\n </div>\n </div>\n )}\n <DialogHeader>\n <DialogTitle>{t(\"add_credit_card\")}</DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-4 pt-6\">\n <VgsCardForm\n vgsFieldState={vgsFieldState}\n networkError={cardError ?? scriptLoadError ?? error}\n />\n\n <div className=\"space-y-3 pt-2\">\n <h3 className=\"text-muted-foreground text-sm font-medium\">\n {t(\"billing_address\")}\n </h3>\n <FormSelectField\n control={control}\n name=\"country_code\"\n label={t(\"country\")}\n placeholder={t(\"select_an_option\")}\n options={countrySelectOptions}\n disabled={isBusy}\n />\n <FormTextField\n control={control}\n name=\"name\"\n label={t(\"name\")}\n disabled={isBusy}\n />\n {renderAddressAutocomplete ? (\n renderAddressAutocomplete({\n control,\n setValue,\n countryCode: billingCountry,\n })\n ) : (\n <FormTextField\n control={control}\n name=\"address1\"\n label={t(\"address_line_1\")}\n disabled={isBusy}\n />\n )}\n <FormTextField\n control={control}\n name=\"address2\"\n label={t(\"address_line_2\")}\n disabled={isBusy}\n />\n <div className=\"flex gap-3\">\n <FormTextField\n control={control}\n name=\"city\"\n label={t(\"city\")}\n containerClassName=\"flex-1\"\n disabled={isBusy}\n />\n <FormSelectField\n control={control}\n name=\"state\"\n label={\n config?.regionLabel ? t(config.regionLabel) : t(\"state\")\n }\n placeholder={t(\"select_state\")}\n options={stateSelectOptions}\n containerClassName=\"flex-1\"\n disabled={isBusy}\n />\n <FormTextField\n control={control}\n name=\"zip\"\n label={\n config?.postalLabel ? t(config.postalLabel) : t(\"zip_code\")\n }\n containerClassName=\"flex-1\"\n disabled={isBusy}\n />\n </div>\n </div>\n </div>\n\n <div className=\"mt-4 flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"set_as_default_cc\"\n checked={setAsDefault}\n onChange={() => setValue(\"set_as_default\", !setAsDefault)}\n disabled={isBusy}\n className=\"h-4 w-4\"\n />\n <label htmlFor=\"set_as_default_cc\" className=\"text-sm\">\n {t(\"set_as_default_payment_method\")}\n </label>\n </div>\n\n <Button type=\"button\" onClick={handleFormSubmit} disabled={isBusy}>\n {isBusy && (\n <div className=\"mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current\" />\n )}\n {isBusy ? t(\"saving\") : t(\"save_card\")}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n","import { type FluidPayApi, type fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport type { PayApi } from \"@fluid-app/portal-core/pay-api\";\nimport type { PayPaymentMethod } from \"@fluid-app/portal-core/pay-types\";\n\n/**\n * Maps a portal-tenant PayPaymentMethod to the fluidPay shape consumed by\n * profile-ui components (PaymentMethodDropdown, CreditCardFormDialog, etc.).\n * Co-located with the adapter because both speak the portal-tenant ↔ fluid-pay\n * boundary.\n */\nexport function mapToFluidPayPaymentMethod(\n raw: PayPaymentMethod,\n): fluidPay.CustomerPaymentMethod {\n return {\n id: raw.id,\n created_at: raw.created_at ?? \"\",\n default: raw.default,\n details: {\n card_type: raw.brand,\n card_brand: raw.brand,\n last_four: raw.last_four,\n exp_month: raw.exp_month ?? undefined,\n exp_year: raw.exp_year ?? undefined,\n },\n billing_address: raw.billing_address\n ? {\n name: raw.billing_address.name,\n address1: raw.billing_address.street1,\n address2: raw.billing_address.street2,\n city: raw.billing_address.city,\n state: raw.billing_address.state,\n zip: raw.billing_address.zip,\n country_code: raw.billing_address.country,\n }\n : null,\n payment_type: raw.type,\n source: \"\",\n updated_at: raw.updated_at ?? \"\",\n };\n}\n\nconst notImplemented = () => {\n throw new Error(\"Not available in portal-tenant context\");\n};\n\n/**\n * Adapts the portal-tenant PayApi to the FluidPayApi shape required by\n * FluidPayCoreProvider. Only `vault.fetchCredentials` is implemented —\n * the rest of the FluidPayApi surface is not used by the profile-ui\n * components that consume this provider in the portal context.\n */\nexport function createFluidPayApiAdapter(payApi: PayApi): FluidPayApi {\n return {\n customers: { fetchAccount: notImplemented, update: notImplemented },\n addresses: {\n fetchAll: notImplemented,\n create: notImplemented,\n update: notImplemented,\n delete: notImplemented,\n },\n paymentMethods: {\n fetchAll: notImplemented,\n addCreditCard: notImplemented,\n delete: notImplemented,\n updateDefault: notImplemented,\n update: notImplemented,\n },\n vault: {\n fetchCredentials: async () => {\n const response = await payApi.fetchVaultCredentials();\n return {\n vault: {\n vault_id: response.vault.vault_id,\n environment: response.vault.environment,\n route_id: response.vault.route_id ?? \"\",\n requires_3ds: false,\n },\n meta: {\n request_id: response.meta?.request_id ?? \"\",\n timestamp: response.meta?.timestamp ?? \"\",\n },\n } satisfies fluidPay.VaultResponse;\n },\n },\n };\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type JSX,\n} from \"react\";\nimport {\n useController,\n type Control,\n type FieldValues,\n type Path,\n type PathValue,\n type UseFormSetValue,\n} from \"react-hook-form\";\nimport { Input } from \"@fluid-app/ui-primitives\";\nimport { useAddressAutocompleteApi } from \"../api-context\";\nimport type { AddressDetails, AddressSuggestion } from \"../api\";\n\nexport interface AddressAutocompleteInputProps<T extends FieldValues> {\n readonly control: Control<T>;\n readonly setValue: UseFormSetValue<T>;\n readonly countryIso: string;\n readonly addressLineField: Path<T>;\n readonly cityField: Path<T>;\n readonly stateField: Path<T>;\n readonly postalCodeField: Path<T>;\n readonly placeholder?: string;\n readonly disabled?: boolean;\n}\n\nconst SET_OPTS = {\n shouldValidate: true,\n shouldDirty: true,\n shouldTouch: true,\n} as const;\n\nconst DEBOUNCE_MS = 250;\n\nexport function AddressAutocompleteInput<T extends FieldValues>({\n control,\n setValue,\n countryIso,\n addressLineField,\n cityField,\n stateField,\n postalCodeField,\n placeholder = \"Start typing your address...\",\n disabled,\n}: AddressAutocompleteInputProps<T>): JSX.Element {\n const api = useAddressAutocompleteApi();\n const { field } = useController({ name: addressLineField, control });\n const [suggestions, setSuggestions] = useState<readonly AddressSuggestion[]>(\n [],\n );\n const [isOpen, setIsOpen] = useState(false);\n const [needsCountry, setNeedsCountry] = useState(false);\n const containerRef = useRef<HTMLDivElement | null>(null);\n // Monotonically increasing request ID. We only apply a fetch result when its\n // ID still matches the latest issued one — guards against stale responses\n // arriving out of order under network jitter.\n const requestIdRef = useRef(0);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isCountrySelected = useMemo(\n () => Boolean(countryIso && countryIso.trim() !== \"\"),\n [countryIso],\n );\n\n useEffect(() => {\n function onClickOutside(e: MouseEvent) {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setIsOpen(false);\n setNeedsCountry(false);\n }\n }\n document.addEventListener(\"mousedown\", onClickOutside);\n return () => document.removeEventListener(\"mousedown\", onClickOutside);\n }, []);\n\n useEffect(\n () => () => {\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n }\n },\n [],\n );\n\n const populate = useCallback(\n (s: AddressDetails) => {\n setValue(\n addressLineField,\n s.streetLine as PathValue<T, Path<T>>,\n SET_OPTS,\n );\n setValue(cityField, s.city as PathValue<T, Path<T>>, SET_OPTS);\n setValue(stateField, s.state as PathValue<T, Path<T>>, SET_OPTS);\n setValue(\n postalCodeField,\n s.postalCode as PathValue<T, Path<T>>,\n SET_OPTS,\n );\n },\n [addressLineField, cityField, postalCodeField, setValue, stateField],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n field.onChange(value);\n\n // Cancel any pending fetch from a prior keystroke.\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = null;\n }\n\n if (value.length < 1) {\n setIsOpen(false);\n setNeedsCountry(false);\n setSuggestions([]);\n return;\n }\n if (!isCountrySelected) {\n setNeedsCountry(true);\n setIsOpen(true);\n return;\n }\n setNeedsCountry(false);\n\n const requestId = ++requestIdRef.current;\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = null;\n void api.fetchSuggestions({ query: value, countryIso }).then((next) => {\n // Drop stale responses — a newer keystroke has already issued a\n // request, and applying this would clobber its result.\n if (requestId !== requestIdRef.current) return;\n setSuggestions(next);\n setIsOpen(true);\n });\n }, DEBOUNCE_MS);\n },\n [api, countryIso, field, isCountrySelected],\n );\n\n const handleClick = useCallback(\n async (suggestion: AddressSuggestion) => {\n // Cancel any debounced fetch still pending from a recent keystroke and\n // advance the request ID so any in-flight response is dropped — without\n // this, the timer could fire after a selection and re-open the dropdown.\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = null;\n }\n const clickId = ++requestIdRef.current;\n\n if (!suggestion.needsDetailLookup) {\n populate({\n streetLine: suggestion.streetLine ?? suggestion.text,\n city: suggestion.city ?? \"\",\n state: suggestion.state ?? \"\",\n postalCode: suggestion.postalCode ?? \"\",\n });\n setIsOpen(false);\n return;\n }\n const { details, drilldownSuggestions } = await api.fetchDetails({\n suggestion,\n countryIso,\n });\n // Drop the result if the user typed during the network round-trip — a\n // newer keystroke has superseded this click and applying its result\n // would clobber what the user has since entered.\n if (clickId !== requestIdRef.current) return;\n if (details) {\n populate(details);\n setIsOpen(false);\n return;\n }\n setSuggestions(drilldownSuggestions);\n setIsOpen(true);\n },\n [api, countryIso, populate],\n );\n\n return (\n <div ref={containerRef} className=\"relative\">\n <Input\n type=\"text\"\n ref={field.ref}\n value={(field.value as string) ?? \"\"}\n onChange={handleChange}\n onBlur={field.onBlur}\n placeholder={placeholder}\n disabled={disabled}\n />\n {isOpen && needsCountry && (\n <div className=\"bg-muted text-foreground absolute z-50 mt-1 w-full rounded-md px-3 py-2 text-sm shadow-lg\">\n Please select a country first to enable address suggestions\n </div>\n )}\n {isOpen && !needsCountry && suggestions.length > 0 && (\n <div className=\"bg-background text-foreground border-border absolute z-50 mt-1 max-h-60 w-full overflow-y-auto rounded-md border shadow-lg\">\n {suggestions.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n onClick={() => {\n void handleClick(s).catch((err) => {\n // handleClick is async because of fetchDetails — the current\n // Smarty adapter and NULL_API swallow errors, so this is\n // belt-and-suspenders for future adapters that might throw.\n console.error(\"Address autocomplete click failed:\", err);\n });\n }}\n className=\"hover:bg-accent block w-full cursor-pointer px-3 py-2 text-left text-sm\"\n >\n {s.text}\n {s.needsDetailLookup ? \" →\" : \"\"}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/{AddressAutocompleteInput-BLNSxszN.mjs → AddressAutocompleteInput-B4BtFV1h.mjs}
RENAMED
|
@@ -1194,7 +1194,25 @@ const addressFormSchema = z.object({
|
|
|
1194
1194
|
country_code: z.string().min(1, "Country is required"),
|
|
1195
1195
|
default: z.boolean()
|
|
1196
1196
|
});
|
|
1197
|
-
function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmitting, countries = [], error, renderAddressAutocomplete, fetchStates, t }) {
|
|
1197
|
+
function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmitting, countries = [], error, renderAddressAutocomplete, fetchStates, t, onDelete, isDeleting = false }) {
|
|
1198
|
+
const [confirmDelete, setConfirmDelete] = useState(false);
|
|
1199
|
+
useEffect(() => {
|
|
1200
|
+
if (!isOpen) setConfirmDelete(false);
|
|
1201
|
+
}, [isOpen]);
|
|
1202
|
+
useEffect(() => {
|
|
1203
|
+
if (!confirmDelete) return;
|
|
1204
|
+
const timeoutId = setTimeout(() => setConfirmDelete(false), 3e3);
|
|
1205
|
+
return () => clearTimeout(timeoutId);
|
|
1206
|
+
}, [confirmDelete]);
|
|
1207
|
+
const deleteButtonLabel = useMemo(() => {
|
|
1208
|
+
if (isDeleting) return t("deleting");
|
|
1209
|
+
if (confirmDelete) return t("tap_to_confirm");
|
|
1210
|
+
return t("delete_address");
|
|
1211
|
+
}, [
|
|
1212
|
+
isDeleting,
|
|
1213
|
+
confirmDelete,
|
|
1214
|
+
t
|
|
1215
|
+
]);
|
|
1198
1216
|
const { control, handleSubmit, reset, setValue } = useZodForm(addressFormSchema, { defaultValues: {
|
|
1199
1217
|
first_name: "",
|
|
1200
1218
|
last_name: "",
|
|
@@ -1367,26 +1385,39 @@ function AddressFormDialog({ isOpen, onClose, selectedAddress, onSubmit, isSubmi
|
|
|
1367
1385
|
]
|
|
1368
1386
|
}),
|
|
1369
1387
|
/* @__PURE__ */ jsxs("div", {
|
|
1370
|
-
className: "mt-4 flex items-center justify-between",
|
|
1371
|
-
children: [/* @__PURE__ */ jsxs(
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1388
|
+
className: "mt-4 flex flex-wrap items-center justify-between gap-3",
|
|
1389
|
+
children: [onDelete ? /* @__PURE__ */ jsxs(Button, {
|
|
1390
|
+
type: "button",
|
|
1391
|
+
variant: "ghost",
|
|
1392
|
+
onClick: () => {
|
|
1393
|
+
if (confirmDelete) onDelete();
|
|
1394
|
+
else setConfirmDelete(true);
|
|
1395
|
+
},
|
|
1396
|
+
disabled: isSubmitting || isDeleting,
|
|
1397
|
+
className: "text-destructive hover:bg-destructive/10 hover:text-destructive",
|
|
1398
|
+
children: [/* @__PURE__ */ jsx(Trash2, { className: "size-4" }), deleteButtonLabel]
|
|
1399
|
+
}) : /* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsxs("div", {
|
|
1400
|
+
className: "flex items-center gap-3",
|
|
1401
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1402
|
+
className: "flex items-center space-x-2",
|
|
1403
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
1404
|
+
type: "checkbox",
|
|
1405
|
+
id: "set_as_default_address",
|
|
1406
|
+
checked: isDefault,
|
|
1407
|
+
onChange: () => setValue("default", !isDefault),
|
|
1408
|
+
disabled: isSubmitting || isDeleting,
|
|
1409
|
+
className: "h-4 w-4"
|
|
1410
|
+
}), /* @__PURE__ */ jsx("label", {
|
|
1411
|
+
htmlFor: "set_as_default_address",
|
|
1412
|
+
className: "text-sm",
|
|
1413
|
+
children: t("set_as_default_address")
|
|
1414
|
+
})]
|
|
1415
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
1416
|
+
type: "submit",
|
|
1417
|
+
onClick: handleFormSubmit,
|
|
1418
|
+
disabled: isSubmitting || isDeleting,
|
|
1419
|
+
children: [isSubmitting && /* @__PURE__ */ jsx("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current" }), isSubmitting ? t("saving") : t("save_address")]
|
|
1384
1420
|
})]
|
|
1385
|
-
}), /* @__PURE__ */ jsxs(Button, {
|
|
1386
|
-
type: "submit",
|
|
1387
|
-
onClick: handleFormSubmit,
|
|
1388
|
-
disabled: isSubmitting,
|
|
1389
|
-
children: [isSubmitting && /* @__PURE__ */ jsx("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current/30 border-t-current" }), isSubmitting ? t("saving") : t("save_address")]
|
|
1390
1421
|
})]
|
|
1391
1422
|
}),
|
|
1392
1423
|
error && /* @__PURE__ */ jsx("div", {
|
|
@@ -2180,4 +2211,4 @@ function AddressAutocompleteInput({ control, setValue, countryIso, addressLineFi
|
|
|
2180
2211
|
//#endregion
|
|
2181
2212
|
export { AddressFormDialog as a, ProfileUIProvider as c, getCardExpiry as d, UserInfoDialog as f, useProfileTranslation as g, ProfileTranslationBridge as h, CreditCardFormDialog as i, PaymentIcon as l, EllipsesDropdown as m, createFluidPayApiAdapter as n, EditPaymentMethodDialog as o, ConfirmActionDialog as p, mapToFluidPayPaymentMethod as r, FluidPayCoreProvider as s, AddressAutocompleteInput as t, getCardDisplayName as u };
|
|
2182
2213
|
|
|
2183
|
-
//# sourceMappingURL=AddressAutocompleteInput-
|
|
2214
|
+
//# sourceMappingURL=AddressAutocompleteInput-B4BtFV1h.mjs.map
|