@fluid-app/portal-sdk 0.1.289 → 0.1.290
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/{ProfileScreen-BH0A6Y3R.mjs → ProfileScreen-CRY3xyq8.mjs} +1 -1
- package/dist/{ProfileScreen-DrTa9Boy.cjs → ProfileScreen-DA4MpM0y.cjs} +1 -1
- package/dist/{ProfileScreen-BDvruZ90.mjs → ProfileScreen-DbkcSkj5.mjs} +18 -6
- package/dist/{ProfileScreen-BDvruZ90.mjs.map → ProfileScreen-DbkcSkj5.mjs.map} +1 -1
- package/dist/{ProfileScreen-CT5nLt3E.cjs → ProfileScreen-DuPvRoOI.cjs} +18 -6
- package/dist/ProfileScreen-DuPvRoOI.cjs.map +1 -0
- package/dist/{SubscriptionsScreen-BpiWZf9J.cjs → SubscriptionsScreen-CtuCGj3h.cjs} +1 -1
- package/dist/{SubscriptionsScreen-B9_Cmmrc.mjs → SubscriptionsScreen-Dj7B4dIu.mjs} +17 -6
- package/dist/{SubscriptionsScreen-B9_Cmmrc.mjs.map → SubscriptionsScreen-Dj7B4dIu.mjs.map} +1 -1
- package/dist/{SubscriptionsScreen-5IsYJnvc.cjs → SubscriptionsScreen-yN3hvtab.cjs} +17 -6
- package/dist/{SubscriptionsScreen-5IsYJnvc.cjs.map → SubscriptionsScreen-yN3hvtab.cjs.map} +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +6 -6
- package/package.json +7 -7
- package/dist/ProfileScreen-CT5nLt3E.cjs.map +0 -1
|
@@ -42,5 +42,5 @@ import "./VideoWidget-DlnwYXlo.mjs";
|
|
|
42
42
|
import "./ScreenHeaderContext-Dn12BZyj.mjs";
|
|
43
43
|
import "./AddressAutocompleteInput-C_H7gSJt.mjs";
|
|
44
44
|
import "./use-mysite-portal-DnA8j1xD.mjs";
|
|
45
|
-
import { n as profileScreenPropertySchema, t as ProfileScreen } from "./ProfileScreen-
|
|
45
|
+
import { n as profileScreenPropertySchema, t as ProfileScreen } from "./ProfileScreen-DbkcSkj5.mjs";
|
|
46
46
|
export { ProfileScreen, profileScreenPropertySchema };
|
|
@@ -43,6 +43,6 @@ require("./VideoWidget-BQvtiY5_.cjs");
|
|
|
43
43
|
require("./ScreenHeaderContext-CsfhnuJk.cjs");
|
|
44
44
|
require("./AddressAutocompleteInput-tZX9kPwb.cjs");
|
|
45
45
|
require("./use-mysite-portal-BMo64_Dx.cjs");
|
|
46
|
-
const require_ProfileScreen = require("./ProfileScreen-
|
|
46
|
+
const require_ProfileScreen = require("./ProfileScreen-DuPvRoOI.cjs");
|
|
47
47
|
exports.ProfileScreen = require_ProfileScreen.ProfileScreen;
|
|
48
48
|
exports.profileScreenPropertySchema = require_ProfileScreen.profileScreenPropertySchema;
|
|
@@ -833,11 +833,22 @@ function ProfileContentScreen({ onToast }) {
|
|
|
833
833
|
}
|
|
834
834
|
});
|
|
835
835
|
const addCreditCardMutation = useMutation({
|
|
836
|
-
mutationFn: (data) => payApi.createPaymentMethod({
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
836
|
+
mutationFn: (data) => payApi.createPaymentMethod({
|
|
837
|
+
payment_method: {
|
|
838
|
+
type: "card",
|
|
839
|
+
token: data.payment_method.token,
|
|
840
|
+
default: data.default_payment_method
|
|
841
|
+
},
|
|
842
|
+
...data.billing_address && { billing_address: {
|
|
843
|
+
country: data.billing_address.country_code,
|
|
844
|
+
name: data.billing_address.name ?? null,
|
|
845
|
+
street1: data.billing_address.address1,
|
|
846
|
+
street2: data.billing_address.address2 ?? null,
|
|
847
|
+
city: data.billing_address.city,
|
|
848
|
+
state: data.billing_address.state,
|
|
849
|
+
zip: data.billing_address.zip
|
|
850
|
+
} }
|
|
851
|
+
}),
|
|
841
852
|
onSuccess: () => {
|
|
842
853
|
queryClient.invalidateQueries({ queryKey: payKeys.paymentMethods.all });
|
|
843
854
|
onToast("Payment method added", "success");
|
|
@@ -1125,6 +1136,7 @@ function ProfileContentScreen({ onToast }) {
|
|
|
1125
1136
|
isOpen: true,
|
|
1126
1137
|
onClose: () => setEditPaymentMethod(null),
|
|
1127
1138
|
paymentMethod: editPaymentMethod,
|
|
1139
|
+
billingAddress: editPaymentMethod.billing_address,
|
|
1128
1140
|
countries: countryOptions,
|
|
1129
1141
|
onSubmit: (data) => {
|
|
1130
1142
|
updatePaymentMethodMutation.mutate({
|
|
@@ -1229,4 +1241,4 @@ const profileScreenPropertySchema = {
|
|
|
1229
1241
|
//#endregion
|
|
1230
1242
|
export { profileScreenPropertySchema as n, ProfileScreen as t };
|
|
1231
1243
|
|
|
1232
|
-
//# sourceMappingURL=ProfileScreen-
|
|
1244
|
+
//# sourceMappingURL=ProfileScreen-DbkcSkj5.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileScreen-BDvruZ90.mjs","names":[],"sources":["../src/screens/profile/derive-last-name.ts","../src/screens/profile/ProfileLayout.tsx","../src/screens/ProfileContentScreen.tsx","../src/screens/ProfileScreen.tsx"],"sourcesContent":["export function deriveLastName(firstName: string, fullName: string): string {\n if (!firstName) return \"\";\n const prefix = `${firstName} `;\n return fullName.startsWith(prefix) ? fullName.slice(prefix.length) : \"\";\n}\n","import { type JSX, type ReactNode, useState, type ComponentType } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"@fluid-app/ui-primitives\";\nimport {\n Sparkles,\n Pencil,\n Plus,\n Copy,\n Link2,\n MapPin,\n User,\n Mail,\n Phone,\n Quote,\n Linkedin,\n Facebook,\n Twitter,\n Instagram,\n Youtube,\n Globe,\n LogOut,\n} from \"lucide-react\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport type { PointsLedger } from \"@fluid-app/profile-core\";\nimport { EllipsesDropdown } from \"@fluid-app/profile-ui\";\nimport type { AccountRep } from \"@fluid-app/portal-core/account-types\";\n\ninterface ProfileLayoutProps {\n account: AccountRep;\n pointsBalance: number | undefined;\n pointsLedger?: PointsLedger[];\n rewardsEnabled?: boolean;\n addresses: fluidPay.CustomerAddress[];\n paymentMethods: fluidPay.CustomerPaymentMethod[];\n mySiteDisplayUrl: string;\n socialLinks: Partial<Record<SocialKey, string>>;\n onEditPersonalInfo: () => void;\n onAddAddress: () => void;\n onEditAddress: (address: fluidPay.CustomerAddress) => void;\n onDeleteAddress: (address: fluidPay.CustomerAddress) => void;\n onAddPaymentMethod: () => void;\n onEditPaymentMethod: (method: fluidPay.CustomerPaymentMethod) => void;\n onCopyMySiteLink: () => void;\n onEditMySiteLink?: () => void;\n onConnectSocial: (key: SocialKey) => void;\n onSignOut?: () => void;\n}\n\nexport function ProfileLayout(props: ProfileLayoutProps): JSX.Element {\n const {\n account,\n pointsBalance,\n pointsLedger,\n rewardsEnabled,\n addresses,\n paymentMethods,\n mySiteDisplayUrl,\n socialLinks,\n onEditPersonalInfo,\n onAddAddress,\n onEditAddress,\n onDeleteAddress,\n onAddPaymentMethod,\n onEditPaymentMethod,\n onCopyMySiteLink,\n onEditMySiteLink,\n onConnectSocial,\n onSignOut,\n } = props;\n\n const fullName =\n `${account.first_name ?? \"\"} ${account.last_name ?? \"\"}`.trim();\n const heroFirstName = (account.first_name || \"\").trim().split(\" \")[0] || \"\";\n const heroDisplay =\n heroFirstName || account.email?.split(\"@\")[0] || \"Account\";\n const connectedSocialCount = Object.values(socialLinks).filter(\n (v) => typeof v === \"string\" && v.length > 0,\n ).length;\n const [isPointsHistoryOpen, setIsPointsHistoryOpen] = useState(false);\n const POINTS_PREVIEW_COUNT = 4;\n const ledger = pointsLedger ?? [];\n const ledgerPreview = ledger.slice(0, POINTS_PREVIEW_COUNT);\n const hasMoreLedger = ledger.length > POINTS_PREVIEW_COUNT;\n\n return (\n <div className=\"relative\">\n <div className=\"max-w-profile-container relative mx-auto px-5 pt-8 pb-20 md:px-8\">\n {/* Hero */}\n <section className=\"flex items-center gap-3.5\">\n <div className=\"size-profile-avatar-sm md:size-profile-avatar relative shrink-0 overflow-hidden rounded-full ring-1 ring-black/5\">\n {account.avatar_url ? (\n <img\n src={account.avatar_url}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"bg-profile-dark text-profile-dark-foreground flex h-full w-full items-center justify-center text-lg font-semibold\">\n {heroDisplay.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"text-profile-hero tracking-profile-hero text-profile-text md:text-profile-hero-lg truncate font-bold\">\n {heroDisplay}\n </h1>\n <p className=\"text-profile-sm-plus text-profile-text-muted mt-0.5 truncate\">\n {account.email}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {rewardsEnabled && (\n <div className=\"ring-profile-border bg-profile-card text-profile-xs-plus text-profile-text inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 font-semibold ring-1\">\n <Sparkles\n className=\"text-profile-accent size-3\"\n strokeWidth={2.25}\n />\n {(pointsBalance ?? 0).toLocaleString()} pts\n </div>\n )}\n </div>\n </section>\n\n {/* Personal information */}\n <SectionHeader\n title=\"Personal information\"\n action={\n <PillButton\n onClick={onEditPersonalInfo}\n icon={Pencil}\n label=\"Edit\"\n />\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n <FieldRow\n icon={User}\n label=\"Name\"\n value={fullName || account.first_name || \"\"}\n />\n <FieldRow icon={Mail} label=\"Email\" value={account.email ?? \"\"} />\n <FieldRow\n icon={Phone}\n label=\"Phone\"\n value={account.phone ?? \"\"}\n placeholder=\"Add phone number\"\n />\n <FieldRow\n icon={Quote}\n label=\"Bio\"\n value={account.bio ?? \"\"}\n placeholder=\"Add a short bio\"\n multiline\n isLast\n />\n </div>\n\n {/* Payment methods */}\n <SectionHeader title=\"Payment methods\" />\n <div className=\"mt-2.5 grid grid-cols-1 gap-2.5 sm:grid-cols-3\">\n {paymentMethods.map((method) => (\n <PaymentCardVisual\n key={method.id}\n method={method}\n onClick={() => onEditPaymentMethod(method)}\n />\n ))}\n <AddPaymentTile onClick={onAddPaymentMethod} />\n </div>\n\n {/* Points history */}\n {rewardsEnabled && (\n <>\n <SectionHeader\n title=\"Points history\"\n action={\n <span className=\"text-profile-xs text-profile-text-faint\">\n {(pointsBalance ?? 0).toLocaleString()} pts available\n </span>\n }\n />\n {ledger.length > 0 ? (\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n {ledgerPreview.map((entry, i) => (\n <PointsLedgerRow\n key={entry.id}\n entry={entry}\n isLast={!hasMoreLedger && i === ledgerPreview.length - 1}\n />\n ))}\n {hasMoreLedger && (\n <button\n type=\"button\"\n onClick={() => setIsPointsHistoryOpen(true)}\n className=\"text-profile-xs text-profile-text hover:bg-profile-pill-hover flex w-full items-center justify-center gap-1 px-4 py-3 font-bold transition-colors\"\n >\n See all {ledger.length} transactions\n </button>\n )}\n </div>\n ) : (\n <div className=\"ring-dashed ring-profile-dashed-border bg-profile-card mt-2.5 flex flex-col items-center justify-center gap-1 rounded-2xl px-4 py-8 text-center ring-1\">\n <Sparkles\n className=\"text-profile-text-faint size-5\"\n strokeWidth={1.75}\n />\n <div className=\"text-profile-base text-profile-text font-bold\">\n No points yet\n </div>\n <div className=\"text-profile-xs text-profile-text-muted\">\n Earn points on every order to unlock rewards.\n </div>\n </div>\n )}\n </>\n )}\n\n {/* Your MySite link */}\n <SectionHeader\n title=\"Your MySite link\"\n action={\n onEditMySiteLink ? (\n <PillButton\n onClick={onEditMySiteLink}\n icon={Pencil}\n label=\"Edit link\"\n />\n ) : undefined\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 flex items-center gap-3 rounded-2xl p-3.5 ring-1\">\n <div className=\"size-profile-mysite-icon bg-profile-icon-bg text-profile-text flex shrink-0 items-center justify-center rounded-full\">\n <Link2 className=\"size-[18px]\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-2xs tracking-profile-uppercase-1 text-profile-text-faint font-bold uppercase\">\n Public link\n </div>\n <div className=\"text-profile-base text-profile-text mt-0.5 truncate font-mono font-semibold\">\n {mySiteDisplayUrl || \"Set your MySite link\"}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onCopyMySiteLink}\n disabled={!mySiteDisplayUrl}\n className=\"ring-profile-border bg-profile-card text-profile-xs text-profile-text hover:bg-profile-pill-hover inline-flex items-center gap-1 rounded-md px-3 py-1.5 font-bold ring-1 transition-all disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <Copy className=\"size-3\" strokeWidth={2.25} />\n Copy\n </button>\n </div>\n\n {/* Shipping addresses */}\n <SectionHeader title=\"Shipping addresses\" />\n <div className=\"mt-2.5 grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n {addresses.map((address) => (\n <AddressCard\n key={address.id}\n address={address}\n onEdit={() => onEditAddress(address)}\n onDelete={\n address.default ? undefined : () => onDeleteAddress(address)\n }\n />\n ))}\n <AddAddressTile onClick={onAddAddress} />\n </div>\n\n {/* Social media */}\n <SectionHeader\n title=\"Social media\"\n action={\n <span className=\"text-profile-xs text-profile-text-faint\">\n {connectedSocialCount} connected\n </span>\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n {SOCIAL_ENTRIES.map((entry, i) => (\n <SocialRow\n key={entry.key}\n entry={entry}\n handle={socialLinks[entry.key] ?? \"\"}\n isLast={i === SOCIAL_ENTRIES.length - 1}\n onConnect={() => onConnectSocial(entry.key)}\n />\n ))}\n </div>\n\n <Dialog\n open={isPointsHistoryOpen}\n onOpenChange={setIsPointsHistoryOpen}\n >\n <DialogContent className=\"max-w-md md:max-w-lg\">\n <DialogHeader>\n <DialogTitle>Points history</DialogTitle>\n </DialogHeader>\n <div className=\"ring-profile-border bg-profile-card max-h-[60vh] overflow-y-auto rounded-2xl ring-1\">\n {ledger.map((entry, i) => (\n <PointsLedgerRow\n key={entry.id}\n entry={entry}\n isLast={i === ledger.length - 1}\n />\n ))}\n </div>\n </DialogContent>\n </Dialog>\n\n {onSignOut && (\n <div className=\"ring-profile-border bg-profile-card mt-8 flex flex-wrap items-center justify-between gap-3 rounded-2xl p-3.5 ring-1\">\n <div className=\"flex items-center gap-3\">\n <div className=\"bg-profile-danger-bg flex size-9 items-center justify-center rounded-md\">\n <LogOut\n className=\"text-profile-danger-icon size-4\"\n strokeWidth={2.25}\n />\n </div>\n <div>\n <div className=\"text-profile-base text-profile-text font-bold\">\n Sign out\n </div>\n <div className=\"text-profile-xs-plus text-profile-text-muted\">\n You can sign back in any time\n </div>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"bg-profile-danger-button-bg text-profile-sm text-profile-danger-button-text hover:bg-profile-danger-button-hover rounded-md px-4 py-2 font-bold transition-colors\"\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SectionHeader({\n title,\n action,\n}: {\n title: string;\n action?: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"mt-8 flex items-end justify-between\">\n <h2 className=\"text-profile-lg tracking-profile-heading text-profile-text font-bold\">\n {title}\n </h2>\n {action ?? null}\n </div>\n );\n}\n\nfunction PillButton({\n onClick,\n icon: Icon,\n label,\n disabled,\n}: {\n onClick: () => void;\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n label: string;\n disabled?: boolean;\n}): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className=\"ring-profile-border bg-profile-card text-profile-xs text-profile-text hover:bg-profile-pill-hover inline-flex items-center gap-1 rounded-md px-3 py-1.5 font-bold ring-1 transition-all disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <Icon className=\"size-3\" strokeWidth={2.25} />\n {label}\n </button>\n );\n}\n\nfunction PointsLedgerRow({\n entry,\n isLast,\n}: {\n entry: PointsLedger;\n isLast: boolean;\n}): JSX.Element {\n const isCredit = entry.amount >= 0;\n const sign = isCredit ? \"+\" : \"−\";\n const magnitude = Math.abs(entry.amount).toLocaleString();\n const amountColor = isCredit\n ? \"text-emerald-600\"\n : \"text-profile-danger-icon\";\n const sourceName = entry.metadata?.source?.name?.trim();\n const transactionType = entry.metadata?.transaction_type;\n const label =\n sourceName ||\n (transactionType\n ? transactionType.charAt(0).toUpperCase() + transactionType.slice(1)\n : isCredit\n ? \"Points earned\"\n : \"Points redeemed\");\n const dateLabel = formatLedgerDate(entry.created_at);\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3.5 ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Sparkles\n className={`size-4 ${isCredit ? \"text-profile-accent\" : \"text-profile-text-muted\"}`}\n strokeWidth={2}\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-md text-profile-text truncate font-medium\">\n {label}\n </div>\n <div className=\"text-profile-xs text-profile-text-muted\">\n {dateLabel}\n </div>\n </div>\n <div\n className={`text-profile-md shrink-0 font-mono font-bold tabular-nums ${amountColor}`}\n >\n {sign}\n {magnitude}\n </div>\n </div>\n );\n}\n\nfunction formatLedgerDate(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n } catch {\n return iso;\n }\n}\n\nfunction FieldRow({\n icon: Icon,\n label,\n value,\n placeholder,\n isLast,\n multiline,\n}: {\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n label: string;\n value: string;\n placeholder?: string;\n isLast?: boolean;\n multiline?: boolean;\n}): JSX.Element {\n const display = value || placeholder || \"\";\n const isPlaceholder = !value && Boolean(placeholder);\n const valueClasses = multiline ? \"whitespace-pre-line\" : \"truncate\";\n return (\n <div\n className={`flex gap-3 px-4 py-3.5 ${multiline ? \"items-start\" : \"items-center\"} ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg text-profile-text-muted flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Icon className=\"size-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-2xs tracking-profile-uppercase-1 text-profile-text-faint font-bold uppercase\">\n {label}\n </div>\n <div\n className={`mt-0.5 ${valueClasses} text-profile-md font-medium ${isPlaceholder ? \"text-profile-text-placeholder\" : \"text-profile-text\"}`}\n >\n {display}\n </div>\n </div>\n </div>\n );\n}\n\nconst CARD_BRAND_LABEL: Record<string, string> = {\n amex: \"AMERICAN EXPRESS\",\n visa: \"VISA\",\n mastercard: \"MASTERCARD\",\n discover: \"DISCOVER\",\n diners: \"DINERS CLUB\",\n jcb: \"JCB\",\n unionpay: \"UNIONPAY\",\n};\n\nconst CARD_BRAND_BADGE: Record<string, string> = {\n amex: \"AMEX\",\n visa: \"VISA\",\n mastercard: \"MC\",\n discover: \"DISC\",\n diners: \"DC\",\n jcb: \"JCB\",\n unionpay: \"UPI\",\n};\n\nfunction PaymentCardVisual({\n method,\n onClick,\n}: {\n method: fluidPay.CustomerPaymentMethod;\n onClick: () => void;\n}): JSX.Element {\n const brand = (method.details.card_brand || \"\").toLowerCase();\n const brandLabel =\n CARD_BRAND_LABEL[brand] || (brand ? brand.toUpperCase() : \"CARD\");\n const badge = CARD_BRAND_BADGE[brand] || \"CARD\";\n const last4 = method.details.last_four ?? \"••••\";\n const expMonth = String(method.details.exp_month ?? \"\").padStart(2, \"0\");\n const expYear = String(method.details.exp_year ?? \"\").slice(-2);\n const exp = expMonth && expYear ? `${expMonth}/${expYear}` : \"\";\n const holder = method.billing_address?.name ?? \"\";\n const badgeBg =\n brand === \"visa\"\n ? \"bg-[#1A1F71]\"\n : brand === \"mastercard\"\n ? \"bg-[#EB001B]\"\n : \"bg-[#0064D2]\";\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group bg-foreground text-background ring-foreground/10 relative flex aspect-[1.586/1] flex-col justify-between overflow-hidden rounded-xl p-4 text-left shadow-sm ring-1 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg\"\n >\n <div\n aria-hidden\n className=\"absolute inset-0 bg-[repeating-linear-gradient(135deg,transparent_0px,transparent_22px,currentColor_22px,currentColor_24px)] opacity-[0.04]\"\n />\n <div className=\"relative flex items-start justify-between\">\n <div>\n <div className=\"text-profile-micro tracking-profile-uppercase-2 text-background/50 font-semibold uppercase\">\n {brandLabel}\n </div>\n <div className=\"text-profile-hero tracking-profile-mono text-background mt-1 font-mono font-bold\">\n {last4}\n </div>\n </div>\n {method.default && (\n <span className=\"text-profile-micro bg-background/10 text-background/80 rounded-md px-2 py-0.5 font-bold tracking-wider uppercase\">\n Default\n </span>\n )}\n </div>\n <div className=\"relative flex items-end justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-nano tracking-profile-uppercase-2 text-background/40 font-semibold uppercase\">\n Cardholder\n </div>\n <div className=\"text-profile-xs-plus text-background truncate font-semibold\">\n {holder || \" \"}\n </div>\n </div>\n <div>\n <div className=\"text-profile-nano tracking-profile-uppercase-2 text-background/40 font-semibold uppercase\">\n Expires\n </div>\n <div className=\"text-profile-xs-plus text-background font-mono font-semibold\">\n {exp}\n </div>\n </div>\n <div\n className={`text-profile-micro shrink-0 rounded px-1.5 py-0.5 font-bold tracking-wider text-white ${badgeBg}`}\n >\n {badge}\n </div>\n </div>\n </button>\n );\n}\n\nfunction AddPaymentTile({ onClick }: { onClick: () => void }): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group ring-dashed ring-profile-dashed-border bg-profile-card text-profile-text-muted hover:bg-profile-canvas hover:text-profile-text flex aspect-[1.586/1] flex-col items-center justify-center gap-1.5 rounded-xl ring-1 transition-colors\"\n >\n <div className=\"ring-profile-border bg-profile-card flex size-9 items-center justify-center rounded-full ring-1\">\n <Plus className=\"size-4\" strokeWidth={2.25} />\n </div>\n <div className=\"text-profile-sm text-profile-text font-bold\">\n Add payment method\n </div>\n <div className=\"text-profile-2xs-plus text-profile-text-faint\">\n Visa, Mastercard, Amex\n </div>\n </button>\n );\n}\n\nfunction AddressCard({\n address,\n onEdit,\n onDelete,\n}: {\n address: fluidPay.CustomerAddress;\n onEdit: () => void;\n onDelete?: () => void;\n}): JSX.Element {\n const label = address.name?.trim() || \"Address\";\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n return (\n <div className=\"ring-profile-border bg-profile-card hover:bg-profile-pill-hover focus-within:ring-profile-text/40 relative flex flex-col rounded-2xl ring-1 transition-all duration-200 focus-within:ring-2 hover:ring-2\">\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"flex w-full flex-col rounded-2xl p-4 pr-12 text-left focus-visible:outline-none\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"bg-profile-icon-bg flex size-8 items-center justify-center rounded-full\">\n <MapPin\n className=\"text-profile-text-muted size-4\"\n strokeWidth={2}\n />\n </div>\n <div className=\"text-profile-md text-profile-text font-bold\">\n {label}\n </div>\n </div>\n {address.default && (\n <span className=\"bg-profile-dark text-profile-micro text-profile-dark-foreground rounded-md px-2 py-0.5 font-bold tracking-wider uppercase\">\n Default\n </span>\n )}\n </div>\n <div className=\"text-profile-sm-plus text-profile-text mt-3 space-y-0.5 leading-snug\">\n {address.address1 && <div>{address.address1}</div>}\n {address.address2 && <div>{address.address2}</div>}\n {cityLine && <div>{cityLine}</div>}\n {address.country_code && (\n <div className=\"text-profile-text-muted\">\n {address.country_code}\n </div>\n )}\n </div>\n </button>\n {onDelete && (\n <div className=\"absolute top-2 right-2 z-10\">\n <EllipsesDropdown\n onEdit={onEdit}\n onDelete={onDelete}\n editLabel=\"Edit\"\n deleteLabel=\"Delete\"\n />\n </div>\n )}\n </div>\n );\n}\n\nfunction AddAddressTile({ onClick }: { onClick: () => void }): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group ring-dashed ring-profile-dashed-border min-h-profile-tile-min-h bg-profile-card text-profile-text-muted hover:bg-profile-canvas hover:text-profile-text flex flex-col items-center justify-center gap-1.5 rounded-2xl ring-1 transition-colors\"\n >\n <div className=\"ring-profile-border bg-profile-card flex size-9 items-center justify-center rounded-full ring-1\">\n <Plus className=\"size-4\" strokeWidth={2.25} />\n </div>\n <div className=\"text-profile-base text-profile-text font-bold\">\n Add an address\n </div>\n </button>\n );\n}\n\ntype SocialKey =\n | \"linkedin\"\n | \"facebook\"\n | \"x\"\n | \"instagram\"\n | \"youtube\"\n | \"pinterest\"\n | \"tiktok\";\n\ninterface SocialEntry {\n key: SocialKey;\n label: string;\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n placeholder: string;\n}\n\nconst SOCIAL_ENTRIES: readonly SocialEntry[] = [\n {\n key: \"linkedin\",\n label: \"LinkedIn\",\n icon: Linkedin,\n placeholder: \"linkedin.com/in/username\",\n },\n {\n key: \"facebook\",\n label: \"Facebook\",\n icon: Facebook,\n placeholder: \"facebook.com/username\",\n },\n { key: \"x\", label: \"X\", icon: Twitter, placeholder: \"x.com/username\" },\n {\n key: \"instagram\",\n label: \"Instagram\",\n icon: Instagram,\n placeholder: \"instagram.com/username\",\n },\n {\n key: \"youtube\",\n label: \"YouTube\",\n icon: Youtube,\n placeholder: \"youtube.com/@channel\",\n },\n {\n key: \"pinterest\",\n label: \"Pinterest\",\n icon: Globe,\n placeholder: \"pinterest.com/username\",\n },\n {\n key: \"tiktok\",\n label: \"TikTok\",\n icon: Globe,\n placeholder: \"tiktok.com/@username\",\n },\n] as const;\n\nfunction SocialRow({\n entry,\n handle,\n isLast,\n onConnect,\n}: {\n entry: SocialEntry;\n handle: string;\n isLast: boolean;\n onConnect: () => void;\n}): JSX.Element {\n const Icon = entry.icon;\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3.5 ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg text-profile-text flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Icon className=\"size-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-base text-profile-text font-bold\">\n {entry.label}\n </div>\n <div\n className={`text-profile-sm truncate ${handle ? \"text-profile-text-muted\" : \"text-profile-text-placeholder\"}`}\n >\n {handle || entry.placeholder}\n </div>\n </div>\n <PillButton\n onClick={onConnect}\n icon={handle ? Pencil : Plus}\n label={handle ? \"Edit\" : \"Connect\"}\n />\n </div>\n );\n}\n\nexport type { SocialKey };\n","import { useCallback, useMemo, useState } from \"react\";\nimport { z } from \"zod\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\nimport type { Language, PointsLedger } from \"@fluid-app/profile-core\";\nimport {\n AddressFormDialog,\n ConfirmActionDialog,\n CreditCardFormDialog,\n EditPaymentMethodDialog,\n UserInfoDialog,\n socialFields,\n} from \"@fluid-app/profile-ui\";\nimport type {\n UserFormData,\n EditPaymentMethodFormData,\n} from \"@fluid-app/profile-ui\";\nimport {\n FluidPayCoreProvider,\n type fluidPay,\n type State,\n} from \"@fluid-app/fluid-pay-core\";\nimport type { PayAddress } from \"@fluid-app/portal-core/pay-types\";\nimport {\n createFluidPayApiAdapter,\n mapToFluidPayPaymentMethod,\n} from \"../adapters/fluid-pay-api-adapter\";\nimport type { AccountRep } from \"@fluid-app/portal-core/account-types\";\nimport { useAccountApi } from \"@fluid-app/portal-core/account-api-context\";\nimport { usePayApi } from \"@fluid-app/portal-core/pay-api-context\";\nimport { usePortalMySiteProfile } from \"@fluid-app/mysite-ui/portal/hooks/use-mysite-portal\";\nimport { useCountriesApi } from \"@fluid-app/store-core/countries-api-context\";\nimport { useLanguagesApi } from \"@fluid-app/store-core/languages-api-context\";\nimport { AddressAutocompleteInput } from \"@fluid-app/address-autocomplete/components/AddressAutocompleteInput\";\nimport { accountKeys, payKeys, storeKeys } from \"../account/query-keys\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { deriveLastName } from \"./profile/derive-last-name\";\nimport { ProfileLayout, type SocialKey } from \"./profile/ProfileLayout\";\n\ninterface ProfileContentScreenProps {\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n countryIso: string;\n}\n\nfunction mapAccountToCustomerAccount(\n raw: AccountRep,\n): fluidPay.CustomerAccount {\n return {\n fluid_pay_account: {\n id: raw.id,\n email: raw.email,\n address_count: 0,\n payment_methods_count: 0,\n language_iso: null,\n },\n customer: {\n id: raw.id,\n active: true,\n active_subscriptions_count: 0,\n display_total_spent: \"0\",\n email: raw.email,\n first_name: raw.first_name,\n full_name: `${raw.first_name} ${raw.last_name}`.trim(),\n inactive_subscriptions_count: 0,\n is_rep: raw.member_type === \"rep\",\n phone: raw.phone,\n orders_count: 0,\n },\n };\n}\n\nfunction composeAddressName(\n firstName: string,\n lastName: string,\n): string | null {\n const combined = `${firstName} ${lastName}`.trim();\n return combined.length > 0 ? combined : null;\n}\n\nfunction mapToFluidPayAddress(raw: PayAddress): fluidPay.CustomerAddress {\n return {\n id: raw.id,\n address1: raw.street1,\n address2: raw.street2,\n city: raw.city,\n country_code: raw.country,\n default: raw.default,\n name: raw.name,\n postal_code: raw.zip,\n state: raw.state,\n subdivision_code: null,\n };\n}\n\ntype SocialFieldKey = (typeof socialFields)[number][\"name\"];\n\nconst SOCIAL_KEY_TO_FIELD: Record<SocialKey, SocialFieldKey | null> = {\n linkedin: \"linkedin\" as SocialFieldKey,\n facebook: \"facebook\" as SocialFieldKey,\n x: \"twitter\" as SocialFieldKey,\n instagram: \"instagram\" as SocialFieldKey,\n youtube: \"youtube\" as SocialFieldKey,\n pinterest: null,\n tiktok: \"tiktok\" as SocialFieldKey,\n};\n\nconst SOCIAL_LABELS: Record<SocialKey, string> = {\n linkedin: \"LinkedIn\",\n facebook: \"Facebook\",\n x: \"X\",\n instagram: \"Instagram\",\n youtube: \"YouTube\",\n pinterest: \"Pinterest\",\n tiktok: \"TikTok\",\n};\n\nconst SOCIAL_PLACEHOLDERS: Record<SocialKey, string> = {\n linkedin: \"linkedin.com/in/username\",\n facebook: \"facebook.com/username\",\n x: \"x.com/username\",\n instagram: \"instagram.com/username\",\n youtube: \"youtube.com/@channel\",\n pinterest: \"pinterest.com/username\",\n tiktok: \"tiktok.com/@username\",\n};\n\nexport function ProfileContentScreen({\n onToast,\n}: ProfileContentScreenProps): React.JSX.Element {\n const { t } = useProfileTranslation();\n const payApi = usePayApi();\n const accountApi = useAccountApi();\n const queryClient = useQueryClient();\n const fluidPayShim = useMemo(\n () => createFluidPayApiAdapter(payApi),\n [payApi],\n );\n\n const { data: mySiteProfile } = usePortalMySiteProfile();\n\n const mySiteUrl = mySiteProfile?.mysite_url ?? \"\";\n const mySiteDisplayUrl = mySiteUrl\n ? mySiteUrl.replace(/^https?:\\/\\//, \"\")\n : \"\";\n\n // Reuse the app-wide useAccount() cache entry shared with AppShell/PageRouter.\n const {\n data: accountRep,\n isLoading: isLoadingAccount,\n isError: isAccountError,\n } = useAccount();\n\n const accountData = useMemo(\n () => (accountRep ? mapAccountToCustomerAccount(accountRep) : undefined),\n [accountRep],\n );\n\n const { data: addressesData } = useQuery({\n queryKey: payKeys.addresses.list(),\n queryFn: async () => {\n const response = await payApi.fetchAddresses();\n return response.addresses.map(mapToFluidPayAddress);\n },\n enabled: true,\n });\n\n const { data: paymentMethodsData } = useQuery({\n queryKey: payKeys.paymentMethods.list(),\n queryFn: async () => {\n const response = await payApi.fetchPaymentMethods();\n return response.payment_methods.map(mapToFluidPayPaymentMethod);\n },\n enabled: true,\n });\n\n const countriesAdapter = useCountriesApi();\n const languagesAdapter = useLanguagesApi();\n\n const { data: countriesData } = useQuery({\n queryKey: storeKeys.countries(),\n queryFn: () => countriesAdapter.listCountries(),\n enabled: true,\n });\n\n const { data: languagesData } = useQuery({\n queryKey: storeKeys.languages(),\n queryFn: () => languagesAdapter.listLanguages(),\n enabled: true,\n });\n\n const { data: pointsLedgerData, isError: isPointsLedgerError } = useQuery({\n queryKey: payKeys.pointsLedgers.list(),\n queryFn: () => payApi.fetchPointsLedgers(),\n enabled: true,\n retry: (failureCount, error) => {\n if (\n error instanceof Error &&\n \"status\" in error &&\n (error as { status: number }).status === 403\n ) {\n return false;\n }\n return failureCount < 1;\n },\n });\n\n const rewardPointsEnabled = !isPointsLedgerError && pointsLedgerData != null;\n\n const adaptedPointsLedger: PointsLedger[] = useMemo(() => {\n return (pointsLedgerData?.points_ledgers ?? []).map((entry) => {\n const meta = entry.metadata as {\n transaction_type?: string | null;\n source?: {\n name: string;\n email?: string;\n reason?: string;\n user_id?: number;\n } | null;\n } | null;\n return {\n id: entry.id,\n amount: entry.amount,\n company_id: 0,\n created_at: entry.created_at,\n customer_id: 0,\n metadata: {\n transaction_type: meta?.transaction_type ?? undefined,\n source: meta?.source ?? undefined,\n },\n total_balance: entry.total_balance,\n updated_at: entry.created_at,\n };\n });\n }, [pointsLedgerData]);\n\n const updateCustomerMutation = useMutation({\n mutationFn: async (data: UserFormData) => {\n await accountApi.updateAccount({\n account: {\n first_name: data.first_name,\n last_name: data.last_name,\n phone: data.phone_number,\n bio: data.bio,\n },\n });\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: accountKeys.all });\n onToast(\"Profile updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update profile\", \"error\");\n },\n });\n\n const deletePaymentMethodMutation = useMutation({\n mutationFn: (paymentMethodId: number) =>\n payApi.deletePaymentMethod(paymentMethodId),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n },\n onError: () => {\n onToast(\"Failed to delete payment method\", \"error\");\n },\n });\n\n const updatePaymentMethodMutation = useMutation({\n mutationFn: ({\n paymentMethodId,\n data,\n }: {\n paymentMethodId: number;\n data: EditPaymentMethodFormData;\n }) =>\n payApi.updatePaymentMethod(paymentMethodId, {\n payment_method: {\n default: data.set_as_default,\n billing_address: {\n name: data.billing_address.name,\n street1: data.billing_address.address1,\n street2: data.billing_address.address2 ?? null,\n city: data.billing_address.city,\n state: data.billing_address.state,\n zip: data.billing_address.zip,\n country: data.billing_address.country_code,\n },\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n },\n onError: () => {\n onToast(\"Failed to update payment method\", \"error\");\n },\n });\n\n const createAddressMutation = useMutation({\n mutationFn: (body: fluidPay.CreateAddressBody) =>\n payApi.createAddress({\n address: {\n name: composeAddressName(\n body.address.first_name,\n body.address.last_name,\n ),\n street1: body.address.address1,\n street2: body.address.address2,\n city: body.address.city,\n state: body.address.state,\n zip: body.address.postal_code,\n country: body.address.country_code,\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address created\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to create address\", \"error\");\n },\n });\n\n const updateAddressMutation = useMutation({\n mutationFn: ({\n addressId,\n body,\n }: {\n addressId: number;\n body: fluidPay.CreateAddressBody;\n }) =>\n payApi.updateAddress(addressId, {\n address: {\n name: composeAddressName(\n body.address.first_name,\n body.address.last_name,\n ),\n street1: body.address.address1,\n street2: body.address.address2,\n city: body.address.city,\n state: body.address.state,\n zip: body.address.postal_code,\n country: body.address.country_code,\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update address\", \"error\");\n },\n });\n\n const deleteAddressMutation = useMutation({\n mutationFn: (addressId: number) => payApi.deleteAddress(addressId),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address deleted\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to delete address\", \"error\");\n },\n });\n\n const addCreditCardMutation = useMutation({\n mutationFn: (data: fluidPay.AddCreditCardData) =>\n payApi.createPaymentMethod({\n payment_method: {\n type: \"card\",\n token: data.payment_method.token,\n default: data.default_payment_method,\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n onToast(\"Payment method added\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to add payment method\", \"error\");\n },\n });\n\n const addresses = addressesData ?? [];\n const paymentMethods = paymentMethodsData ?? [];\n\n const adaptedLanguages: Language[] = (languagesData?.languages ?? []).map(\n (l, i) => ({ id: i, name: l.name, iso: l.code }),\n );\n\n const countries = countriesData?.countries;\n\n const countryOptions = useMemo(\n () =>\n [...(countries ?? [])]\n .map((c) => ({ iso: c.code, name: c.name }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [countries],\n );\n\n const statesByCountry = useMemo(() => {\n const map = new Map<string, State[]>();\n for (const c of countries ?? []) {\n map.set(\n c.code,\n c.states.map((s) => ({ name: s.name, isoCode: s.code })),\n );\n }\n return map;\n }, [countries]);\n\n const fetchStatesFromCountries = useCallback(\n (countryCode: string): Promise<State[]> =>\n Promise.resolve(statesByCountry.get(countryCode) ?? []),\n [statesByCountry],\n );\n\n // Dialog open state\n const [isInfoDialogOpen, setIsInfoDialogOpen] = useState(false);\n const [addressDialog, setAddressDialog] = useState<{\n open: boolean;\n selected: fluidPay.CustomerAddress | null;\n }>({ open: false, selected: null });\n const [deletingAddress, setDeletingAddress] =\n useState<fluidPay.CustomerAddress | null>(null);\n const [isAddCardOpen, setIsAddCardOpen] = useState(false);\n const [editPaymentMethod, setEditPaymentMethod] =\n useState<fluidPay.CustomerPaymentMethod | null>(null);\n\n // User-info form (for the existing dialog)\n const userInfoLanguage = useMemo(() => {\n return (\n adaptedLanguages.find(\n (l) => l.iso === accountData?.fluid_pay_account.language_iso,\n )?.name ?? \"English\"\n );\n }, [adaptedLanguages, accountData]);\n\n const derivedLastName = useMemo(() => {\n if (!accountData) return \"\";\n const { first_name, full_name } = accountData.customer;\n return deriveLastName(first_name, full_name);\n }, [accountData]);\n\n const userInfoSchema = useMemo(\n () =>\n 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 phone_number: z.string().optional(),\n language: z.string().min(1, \"Language is required\"),\n bio: z.string().optional(),\n }),\n [],\n );\n\n const userInfoForm = useZodForm<UserFormData>(userInfoSchema, {\n defaultValues: {\n first_name: accountData?.customer.first_name ?? \"\",\n last_name: derivedLastName,\n phone_number: accountData?.customer.phone ?? \"\",\n language: userInfoLanguage,\n bio: accountRep?.bio ?? \"\",\n },\n });\n\n const handleOpenInfoDialog = useCallback(() => {\n userInfoForm.reset({\n first_name: accountData?.customer.first_name ?? \"\",\n last_name: derivedLastName,\n phone_number: accountData?.customer.phone ?? \"\",\n language: userInfoLanguage,\n bio: accountRep?.bio ?? \"\",\n });\n setIsInfoDialogOpen(true);\n }, [\n accountData,\n accountRep,\n derivedLastName,\n userInfoLanguage,\n userInfoForm,\n ]);\n\n const onSubmitUserInfo = userInfoForm.handleSubmit(async (data) => {\n try {\n await updateCustomerMutation.mutateAsync(data);\n setIsInfoDialogOpen(false);\n } catch {\n // toast surfaced via onError\n }\n });\n\n const socialLinks = useMemo<Partial<Record<SocialKey, string>>>(() => {\n const src: Partial<Record<SocialFieldKey, string>> =\n accountRep?.social_links ?? {};\n const result: Partial<Record<SocialKey, string>> = {};\n for (const [key, field] of Object.entries(SOCIAL_KEY_TO_FIELD) as [\n SocialKey,\n SocialFieldKey | null,\n ][]) {\n if (!field) continue;\n const v = src[field];\n if (typeof v === \"string\" && v.length > 0) {\n result[key] = v;\n }\n }\n return result;\n }, [accountRep]);\n\n const handleCopyMySiteLink = useCallback(async () => {\n if (!mySiteUrl) return;\n try {\n await navigator.clipboard.writeText(mySiteUrl);\n onToast(\"MySite link copied\", \"success\");\n } catch {\n onToast(\"Failed to copy link\", \"error\");\n }\n }, [mySiteUrl, onToast]);\n\n const [editingSocial, setEditingSocial] = useState<SocialKey | null>(null);\n const [socialDraft, setSocialDraft] = useState(\"\");\n\n const handleConnectSocial = useCallback(\n (key: SocialKey) => {\n const field = SOCIAL_KEY_TO_FIELD[key];\n if (!field) {\n onToast(\"This platform isn't editable yet\", \"warning\");\n return;\n }\n const current = accountRep?.social_links?.[field] ?? \"\";\n setSocialDraft(current);\n setEditingSocial(key);\n },\n [accountRep, onToast],\n );\n\n const updateSocialMutation = useMutation({\n mutationFn: async ({\n field,\n value,\n }: {\n field: SocialFieldKey;\n value: string;\n }) => {\n const current = accountRep?.social_links ?? {};\n await accountApi.updateAccount({\n account: {\n social_links: { ...current, [field]: value },\n },\n });\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: accountKeys.all });\n onToast(\"Social link updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update social link\", \"error\");\n },\n });\n\n const handleSubmitSocial = useCallback(async () => {\n if (!editingSocial) return;\n const field = SOCIAL_KEY_TO_FIELD[editingSocial];\n if (!field) return;\n await updateSocialMutation.mutateAsync({\n field,\n value: socialDraft.trim(),\n });\n setEditingSocial(null);\n }, [editingSocial, socialDraft, updateSocialMutation]);\n\n if (isAccountError && !isLoadingAccount) {\n return (\n <div className=\"px-4 py-8 sm:px-9\">\n <div className=\"text-muted-foreground text-center text-sm\">\n Unable to load account data. Please try again later.\n </div>\n </div>\n );\n }\n\n if (isLoadingAccount || !accountData || !accountRep) {\n return (\n <div className=\"px-4 pt-4 sm:px-9 md:pt-8\">\n <div className=\"space-y-4\">\n <div className=\"bg-muted h-16 animate-pulse rounded\" />\n <div className=\"bg-muted h-32 animate-pulse rounded\" />\n <div className=\"bg-muted h-32 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n const pointsBalance = rewardPointsEnabled\n ? (pointsLedgerData?.points_ledgers?.[0]?.total_balance ?? 0)\n : undefined;\n\n return (\n <FluidPayCoreProvider api={fluidPayShim}>\n <ProfileLayout\n account={accountRep}\n pointsBalance={pointsBalance}\n pointsLedger={adaptedPointsLedger}\n rewardsEnabled={rewardPointsEnabled}\n addresses={addresses}\n paymentMethods={paymentMethods}\n mySiteDisplayUrl={mySiteDisplayUrl}\n socialLinks={socialLinks}\n onEditPersonalInfo={handleOpenInfoDialog}\n onAddAddress={() => setAddressDialog({ open: true, selected: null })}\n onEditAddress={(address) =>\n setAddressDialog({ open: true, selected: address })\n }\n onDeleteAddress={(address) => setDeletingAddress(address)}\n onAddPaymentMethod={() => setIsAddCardOpen(true)}\n onEditPaymentMethod={(pm) => setEditPaymentMethod(pm)}\n onCopyMySiteLink={handleCopyMySiteLink}\n onConnectSocial={handleConnectSocial}\n />\n\n <UserInfoDialog\n control={userInfoForm.control}\n isOpen={isInfoDialogOpen}\n onSubmit={onSubmitUserInfo}\n handleClose={() => setIsInfoDialogOpen(false)}\n languageOptions={adaptedLanguages.map((l) => ({\n name: l.name,\n value: l.name,\n }))}\n errorMsg={undefined}\n isSubmitting={updateCustomerMutation.isPending}\n email={accountRep.email ?? \"\"}\n />\n\n <AddressFormDialog\n isOpen={addressDialog.open}\n onClose={() => setAddressDialog({ open: false, selected: null })}\n selectedAddress={addressDialog.selected}\n t={(key: string) => t(key as never)}\n onSubmit={async (formData) => {\n if (addressDialog.selected) {\n await updateAddressMutation.mutateAsync({\n addressId: addressDialog.selected.id,\n body: formData,\n });\n } else {\n await createAddressMutation.mutateAsync(formData);\n }\n setAddressDialog({ open: false, selected: null });\n }}\n isSubmitting={\n createAddressMutation.isPending || updateAddressMutation.isPending\n }\n onDelete={\n addressDialog.selected && !addressDialog.selected.default\n ? async () => {\n if (!addressDialog.selected) return;\n try {\n await deleteAddressMutation.mutateAsync(\n addressDialog.selected.id,\n );\n setAddressDialog({ open: false, selected: null });\n } catch {\n // toast surfaced via onError\n }\n }\n : undefined\n }\n isDeleting={deleteAddressMutation.isPending}\n countries={countryOptions}\n fetchStates={fetchStatesFromCountries}\n renderAddressAutocomplete={({ control, setValue, countryCode }) => (\n <AddressAutocompleteInput\n control={control}\n setValue={setValue}\n countryIso={countryCode}\n addressLineField=\"address1\"\n cityField=\"city\"\n stateField=\"state\"\n postalCodeField=\"postal_code\"\n placeholder={t(\"address_line_1\")}\n />\n )}\n />\n\n <ConfirmActionDialog\n title={t(\"delete_address\")}\n description={t(\"delete_address_message\")}\n openDialog={deletingAddress !== null}\n setOpenDialog={(open) => {\n if (!open) setDeletingAddress(null);\n }}\n onAction={async () => {\n if (!deletingAddress) return;\n try {\n await deleteAddressMutation.mutateAsync(deletingAddress.id);\n setDeletingAddress(null);\n } catch {\n // toast surfaced via onError\n }\n }}\n isLoading={deleteAddressMutation.isPending}\n actionText={t(\"delete\")}\n />\n\n <CreditCardFormDialog\n isOpen={isAddCardOpen}\n onClose={() => setIsAddCardOpen(false)}\n t={(key: string) => t(key as never)}\n onSubmit={async (data) => {\n try {\n await addCreditCardMutation.mutateAsync(data);\n setIsAddCardOpen(false);\n } catch {\n // toast surfaced via onError\n }\n }}\n isSubmitting={addCreditCardMutation.isPending}\n countries={countryOptions}\n jwt=\"\"\n renderAddressAutocomplete={({ control, setValue, countryCode }) => (\n <AddressAutocompleteInput\n control={control}\n setValue={setValue}\n countryIso={countryCode}\n addressLineField=\"address1\"\n cityField=\"city\"\n stateField=\"state\"\n postalCodeField=\"zip\"\n placeholder={t(\"address_line_1\")}\n />\n )}\n />\n\n {editPaymentMethod && (\n <EditPaymentMethodDialog\n isOpen\n onClose={() => setEditPaymentMethod(null)}\n paymentMethod={editPaymentMethod}\n countries={countryOptions}\n onSubmit={(data) => {\n updatePaymentMethodMutation.mutate(\n { paymentMethodId: editPaymentMethod.id, data },\n { onSuccess: () => setEditPaymentMethod(null) },\n );\n }}\n isSubmitting={updatePaymentMethodMutation.isPending}\n onDelete={() => {\n deletePaymentMethodMutation.mutate(editPaymentMethod.id, {\n onSuccess: () => setEditPaymentMethod(null),\n });\n }}\n isDeleting={deletePaymentMethodMutation.isPending}\n />\n )}\n\n <Dialog\n open={editingSocial !== null}\n onOpenChange={(open) => !open && setEditingSocial(null)}\n >\n <DialogContent className=\"max-w-sm md:max-w-md\">\n <DialogHeader>\n <DialogTitle>\n {editingSocial\n ? `Edit ${SOCIAL_LABELS[editingSocial]} link`\n : \"Edit social link\"}\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-2 pt-2\">\n <Label\n htmlFor=\"social-handle\"\n className=\"mb-1.5 block text-sm font-medium\"\n >\n URL\n </Label>\n <Input\n id=\"social-handle\"\n value={socialDraft}\n onChange={(e) => setSocialDraft(e.target.value)}\n placeholder={\n editingSocial ? SOCIAL_PLACEHOLDERS[editingSocial] : \"\"\n }\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void handleSubmitSocial();\n }\n }}\n autoFocus\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setEditingSocial(null)}\n disabled={updateSocialMutation.isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={() => {\n void handleSubmitSocial();\n }}\n disabled={updateSocialMutation.isPending}\n >\n {updateSocialMutation.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </FluidPayCoreProvider>\n );\n}\n","import type { ComponentProps } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n fluidToast,\n} from \"@fluid-app/ui-primitives\";\nimport { ScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useFluidContext } from \"../providers/FluidProvider\";\nimport { ProfileTranslationBridge } from \"../providers/ProfileTranslationBridge\";\nimport { ProfileContentScreen } from \"./ProfileContentScreen\";\n\ntype ProfileScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function ProfileScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProfileScreenProps): React.JSX.Element {\n const { config } = useFluidContext();\n const effectiveToast = onToast ?? defaultToast;\n const countryIso = config.countryIso ?? \"US\";\n\n return (\n <ProfileTranslationBridge>\n <ProfileScreenContent\n onToast={effectiveToast}\n countryIso={countryIso}\n divProps={divProps}\n />\n </ProfileTranslationBridge>\n );\n}\n\nfunction ProfileScreenContent({\n onToast,\n countryIso,\n divProps,\n}: {\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n countryIso: string;\n divProps: ComponentProps<\"div\">;\n}): React.JSX.Element {\n const { t } = useProfileTranslation();\n\n return (\n <>\n <ScreenHeaderBreadcrumbs>\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n {t(\"breadcrumb\")}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </ScreenHeaderBreadcrumbs>\n <div {...divProps}>\n <ProfileContentScreen onToast={onToast} countryIso={countryIso} />\n </div>\n </>\n );\n}\n\nexport const profileScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProfileScreen\",\n displayName: \"Profile Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProfileScreen-DbkcSkj5.mjs","names":[],"sources":["../src/screens/profile/derive-last-name.ts","../src/screens/profile/ProfileLayout.tsx","../src/screens/ProfileContentScreen.tsx","../src/screens/ProfileScreen.tsx"],"sourcesContent":["export function deriveLastName(firstName: string, fullName: string): string {\n if (!firstName) return \"\";\n const prefix = `${firstName} `;\n return fullName.startsWith(prefix) ? fullName.slice(prefix.length) : \"\";\n}\n","import { type JSX, type ReactNode, useState, type ComponentType } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"@fluid-app/ui-primitives\";\nimport {\n Sparkles,\n Pencil,\n Plus,\n Copy,\n Link2,\n MapPin,\n User,\n Mail,\n Phone,\n Quote,\n Linkedin,\n Facebook,\n Twitter,\n Instagram,\n Youtube,\n Globe,\n LogOut,\n} from \"lucide-react\";\nimport type { fluidPay } from \"@fluid-app/fluid-pay-core\";\nimport type { PointsLedger } from \"@fluid-app/profile-core\";\nimport { EllipsesDropdown } from \"@fluid-app/profile-ui\";\nimport type { AccountRep } from \"@fluid-app/portal-core/account-types\";\n\ninterface ProfileLayoutProps {\n account: AccountRep;\n pointsBalance: number | undefined;\n pointsLedger?: PointsLedger[];\n rewardsEnabled?: boolean;\n addresses: fluidPay.CustomerAddress[];\n paymentMethods: fluidPay.CustomerPaymentMethod[];\n mySiteDisplayUrl: string;\n socialLinks: Partial<Record<SocialKey, string>>;\n onEditPersonalInfo: () => void;\n onAddAddress: () => void;\n onEditAddress: (address: fluidPay.CustomerAddress) => void;\n onDeleteAddress: (address: fluidPay.CustomerAddress) => void;\n onAddPaymentMethod: () => void;\n onEditPaymentMethod: (method: fluidPay.CustomerPaymentMethod) => void;\n onCopyMySiteLink: () => void;\n onEditMySiteLink?: () => void;\n onConnectSocial: (key: SocialKey) => void;\n onSignOut?: () => void;\n}\n\nexport function ProfileLayout(props: ProfileLayoutProps): JSX.Element {\n const {\n account,\n pointsBalance,\n pointsLedger,\n rewardsEnabled,\n addresses,\n paymentMethods,\n mySiteDisplayUrl,\n socialLinks,\n onEditPersonalInfo,\n onAddAddress,\n onEditAddress,\n onDeleteAddress,\n onAddPaymentMethod,\n onEditPaymentMethod,\n onCopyMySiteLink,\n onEditMySiteLink,\n onConnectSocial,\n onSignOut,\n } = props;\n\n const fullName =\n `${account.first_name ?? \"\"} ${account.last_name ?? \"\"}`.trim();\n const heroFirstName = (account.first_name || \"\").trim().split(\" \")[0] || \"\";\n const heroDisplay =\n heroFirstName || account.email?.split(\"@\")[0] || \"Account\";\n const connectedSocialCount = Object.values(socialLinks).filter(\n (v) => typeof v === \"string\" && v.length > 0,\n ).length;\n const [isPointsHistoryOpen, setIsPointsHistoryOpen] = useState(false);\n const POINTS_PREVIEW_COUNT = 4;\n const ledger = pointsLedger ?? [];\n const ledgerPreview = ledger.slice(0, POINTS_PREVIEW_COUNT);\n const hasMoreLedger = ledger.length > POINTS_PREVIEW_COUNT;\n\n return (\n <div className=\"relative\">\n <div className=\"max-w-profile-container relative mx-auto px-5 pt-8 pb-20 md:px-8\">\n {/* Hero */}\n <section className=\"flex items-center gap-3.5\">\n <div className=\"size-profile-avatar-sm md:size-profile-avatar relative shrink-0 overflow-hidden rounded-full ring-1 ring-black/5\">\n {account.avatar_url ? (\n <img\n src={account.avatar_url}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"bg-profile-dark text-profile-dark-foreground flex h-full w-full items-center justify-center text-lg font-semibold\">\n {heroDisplay.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"text-profile-hero tracking-profile-hero text-profile-text md:text-profile-hero-lg truncate font-bold\">\n {heroDisplay}\n </h1>\n <p className=\"text-profile-sm-plus text-profile-text-muted mt-0.5 truncate\">\n {account.email}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {rewardsEnabled && (\n <div className=\"ring-profile-border bg-profile-card text-profile-xs-plus text-profile-text inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 font-semibold ring-1\">\n <Sparkles\n className=\"text-profile-accent size-3\"\n strokeWidth={2.25}\n />\n {(pointsBalance ?? 0).toLocaleString()} pts\n </div>\n )}\n </div>\n </section>\n\n {/* Personal information */}\n <SectionHeader\n title=\"Personal information\"\n action={\n <PillButton\n onClick={onEditPersonalInfo}\n icon={Pencil}\n label=\"Edit\"\n />\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n <FieldRow\n icon={User}\n label=\"Name\"\n value={fullName || account.first_name || \"\"}\n />\n <FieldRow icon={Mail} label=\"Email\" value={account.email ?? \"\"} />\n <FieldRow\n icon={Phone}\n label=\"Phone\"\n value={account.phone ?? \"\"}\n placeholder=\"Add phone number\"\n />\n <FieldRow\n icon={Quote}\n label=\"Bio\"\n value={account.bio ?? \"\"}\n placeholder=\"Add a short bio\"\n multiline\n isLast\n />\n </div>\n\n {/* Payment methods */}\n <SectionHeader title=\"Payment methods\" />\n <div className=\"mt-2.5 grid grid-cols-1 gap-2.5 sm:grid-cols-3\">\n {paymentMethods.map((method) => (\n <PaymentCardVisual\n key={method.id}\n method={method}\n onClick={() => onEditPaymentMethod(method)}\n />\n ))}\n <AddPaymentTile onClick={onAddPaymentMethod} />\n </div>\n\n {/* Points history */}\n {rewardsEnabled && (\n <>\n <SectionHeader\n title=\"Points history\"\n action={\n <span className=\"text-profile-xs text-profile-text-faint\">\n {(pointsBalance ?? 0).toLocaleString()} pts available\n </span>\n }\n />\n {ledger.length > 0 ? (\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n {ledgerPreview.map((entry, i) => (\n <PointsLedgerRow\n key={entry.id}\n entry={entry}\n isLast={!hasMoreLedger && i === ledgerPreview.length - 1}\n />\n ))}\n {hasMoreLedger && (\n <button\n type=\"button\"\n onClick={() => setIsPointsHistoryOpen(true)}\n className=\"text-profile-xs text-profile-text hover:bg-profile-pill-hover flex w-full items-center justify-center gap-1 px-4 py-3 font-bold transition-colors\"\n >\n See all {ledger.length} transactions\n </button>\n )}\n </div>\n ) : (\n <div className=\"ring-dashed ring-profile-dashed-border bg-profile-card mt-2.5 flex flex-col items-center justify-center gap-1 rounded-2xl px-4 py-8 text-center ring-1\">\n <Sparkles\n className=\"text-profile-text-faint size-5\"\n strokeWidth={1.75}\n />\n <div className=\"text-profile-base text-profile-text font-bold\">\n No points yet\n </div>\n <div className=\"text-profile-xs text-profile-text-muted\">\n Earn points on every order to unlock rewards.\n </div>\n </div>\n )}\n </>\n )}\n\n {/* Your MySite link */}\n <SectionHeader\n title=\"Your MySite link\"\n action={\n onEditMySiteLink ? (\n <PillButton\n onClick={onEditMySiteLink}\n icon={Pencil}\n label=\"Edit link\"\n />\n ) : undefined\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 flex items-center gap-3 rounded-2xl p-3.5 ring-1\">\n <div className=\"size-profile-mysite-icon bg-profile-icon-bg text-profile-text flex shrink-0 items-center justify-center rounded-full\">\n <Link2 className=\"size-[18px]\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-2xs tracking-profile-uppercase-1 text-profile-text-faint font-bold uppercase\">\n Public link\n </div>\n <div className=\"text-profile-base text-profile-text mt-0.5 truncate font-mono font-semibold\">\n {mySiteDisplayUrl || \"Set your MySite link\"}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onCopyMySiteLink}\n disabled={!mySiteDisplayUrl}\n className=\"ring-profile-border bg-profile-card text-profile-xs text-profile-text hover:bg-profile-pill-hover inline-flex items-center gap-1 rounded-md px-3 py-1.5 font-bold ring-1 transition-all disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <Copy className=\"size-3\" strokeWidth={2.25} />\n Copy\n </button>\n </div>\n\n {/* Shipping addresses */}\n <SectionHeader title=\"Shipping addresses\" />\n <div className=\"mt-2.5 grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n {addresses.map((address) => (\n <AddressCard\n key={address.id}\n address={address}\n onEdit={() => onEditAddress(address)}\n onDelete={\n address.default ? undefined : () => onDeleteAddress(address)\n }\n />\n ))}\n <AddAddressTile onClick={onAddAddress} />\n </div>\n\n {/* Social media */}\n <SectionHeader\n title=\"Social media\"\n action={\n <span className=\"text-profile-xs text-profile-text-faint\">\n {connectedSocialCount} connected\n </span>\n }\n />\n <div className=\"ring-profile-border bg-profile-card mt-2.5 overflow-hidden rounded-2xl ring-1\">\n {SOCIAL_ENTRIES.map((entry, i) => (\n <SocialRow\n key={entry.key}\n entry={entry}\n handle={socialLinks[entry.key] ?? \"\"}\n isLast={i === SOCIAL_ENTRIES.length - 1}\n onConnect={() => onConnectSocial(entry.key)}\n />\n ))}\n </div>\n\n <Dialog\n open={isPointsHistoryOpen}\n onOpenChange={setIsPointsHistoryOpen}\n >\n <DialogContent className=\"max-w-md md:max-w-lg\">\n <DialogHeader>\n <DialogTitle>Points history</DialogTitle>\n </DialogHeader>\n <div className=\"ring-profile-border bg-profile-card max-h-[60vh] overflow-y-auto rounded-2xl ring-1\">\n {ledger.map((entry, i) => (\n <PointsLedgerRow\n key={entry.id}\n entry={entry}\n isLast={i === ledger.length - 1}\n />\n ))}\n </div>\n </DialogContent>\n </Dialog>\n\n {onSignOut && (\n <div className=\"ring-profile-border bg-profile-card mt-8 flex flex-wrap items-center justify-between gap-3 rounded-2xl p-3.5 ring-1\">\n <div className=\"flex items-center gap-3\">\n <div className=\"bg-profile-danger-bg flex size-9 items-center justify-center rounded-md\">\n <LogOut\n className=\"text-profile-danger-icon size-4\"\n strokeWidth={2.25}\n />\n </div>\n <div>\n <div className=\"text-profile-base text-profile-text font-bold\">\n Sign out\n </div>\n <div className=\"text-profile-xs-plus text-profile-text-muted\">\n You can sign back in any time\n </div>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"bg-profile-danger-button-bg text-profile-sm text-profile-danger-button-text hover:bg-profile-danger-button-hover rounded-md px-4 py-2 font-bold transition-colors\"\n >\n Sign out\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SectionHeader({\n title,\n action,\n}: {\n title: string;\n action?: ReactNode;\n}): JSX.Element {\n return (\n <div className=\"mt-8 flex items-end justify-between\">\n <h2 className=\"text-profile-lg tracking-profile-heading text-profile-text font-bold\">\n {title}\n </h2>\n {action ?? null}\n </div>\n );\n}\n\nfunction PillButton({\n onClick,\n icon: Icon,\n label,\n disabled,\n}: {\n onClick: () => void;\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n label: string;\n disabled?: boolean;\n}): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className=\"ring-profile-border bg-profile-card text-profile-xs text-profile-text hover:bg-profile-pill-hover inline-flex items-center gap-1 rounded-md px-3 py-1.5 font-bold ring-1 transition-all disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <Icon className=\"size-3\" strokeWidth={2.25} />\n {label}\n </button>\n );\n}\n\nfunction PointsLedgerRow({\n entry,\n isLast,\n}: {\n entry: PointsLedger;\n isLast: boolean;\n}): JSX.Element {\n const isCredit = entry.amount >= 0;\n const sign = isCredit ? \"+\" : \"−\";\n const magnitude = Math.abs(entry.amount).toLocaleString();\n const amountColor = isCredit\n ? \"text-emerald-600\"\n : \"text-profile-danger-icon\";\n const sourceName = entry.metadata?.source?.name?.trim();\n const transactionType = entry.metadata?.transaction_type;\n const label =\n sourceName ||\n (transactionType\n ? transactionType.charAt(0).toUpperCase() + transactionType.slice(1)\n : isCredit\n ? \"Points earned\"\n : \"Points redeemed\");\n const dateLabel = formatLedgerDate(entry.created_at);\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3.5 ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Sparkles\n className={`size-4 ${isCredit ? \"text-profile-accent\" : \"text-profile-text-muted\"}`}\n strokeWidth={2}\n />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-md text-profile-text truncate font-medium\">\n {label}\n </div>\n <div className=\"text-profile-xs text-profile-text-muted\">\n {dateLabel}\n </div>\n </div>\n <div\n className={`text-profile-md shrink-0 font-mono font-bold tabular-nums ${amountColor}`}\n >\n {sign}\n {magnitude}\n </div>\n </div>\n );\n}\n\nfunction formatLedgerDate(iso: string): string {\n try {\n const d = new Date(iso);\n return d.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n } catch {\n return iso;\n }\n}\n\nfunction FieldRow({\n icon: Icon,\n label,\n value,\n placeholder,\n isLast,\n multiline,\n}: {\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n label: string;\n value: string;\n placeholder?: string;\n isLast?: boolean;\n multiline?: boolean;\n}): JSX.Element {\n const display = value || placeholder || \"\";\n const isPlaceholder = !value && Boolean(placeholder);\n const valueClasses = multiline ? \"whitespace-pre-line\" : \"truncate\";\n return (\n <div\n className={`flex gap-3 px-4 py-3.5 ${multiline ? \"items-start\" : \"items-center\"} ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg text-profile-text-muted flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Icon className=\"size-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-2xs tracking-profile-uppercase-1 text-profile-text-faint font-bold uppercase\">\n {label}\n </div>\n <div\n className={`mt-0.5 ${valueClasses} text-profile-md font-medium ${isPlaceholder ? \"text-profile-text-placeholder\" : \"text-profile-text\"}`}\n >\n {display}\n </div>\n </div>\n </div>\n );\n}\n\nconst CARD_BRAND_LABEL: Record<string, string> = {\n amex: \"AMERICAN EXPRESS\",\n visa: \"VISA\",\n mastercard: \"MASTERCARD\",\n discover: \"DISCOVER\",\n diners: \"DINERS CLUB\",\n jcb: \"JCB\",\n unionpay: \"UNIONPAY\",\n};\n\nconst CARD_BRAND_BADGE: Record<string, string> = {\n amex: \"AMEX\",\n visa: \"VISA\",\n mastercard: \"MC\",\n discover: \"DISC\",\n diners: \"DC\",\n jcb: \"JCB\",\n unionpay: \"UPI\",\n};\n\nfunction PaymentCardVisual({\n method,\n onClick,\n}: {\n method: fluidPay.CustomerPaymentMethod;\n onClick: () => void;\n}): JSX.Element {\n const brand = (method.details.card_brand || \"\").toLowerCase();\n const brandLabel =\n CARD_BRAND_LABEL[brand] || (brand ? brand.toUpperCase() : \"CARD\");\n const badge = CARD_BRAND_BADGE[brand] || \"CARD\";\n const last4 = method.details.last_four ?? \"••••\";\n const expMonth = String(method.details.exp_month ?? \"\").padStart(2, \"0\");\n const expYear = String(method.details.exp_year ?? \"\").slice(-2);\n const exp = expMonth && expYear ? `${expMonth}/${expYear}` : \"\";\n const holder = method.billing_address?.name ?? \"\";\n const badgeBg =\n brand === \"visa\"\n ? \"bg-[#1A1F71]\"\n : brand === \"mastercard\"\n ? \"bg-[#EB001B]\"\n : \"bg-[#0064D2]\";\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group bg-foreground text-background ring-foreground/10 relative flex aspect-[1.586/1] flex-col justify-between overflow-hidden rounded-xl p-4 text-left shadow-sm ring-1 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg\"\n >\n <div\n aria-hidden\n className=\"absolute inset-0 bg-[repeating-linear-gradient(135deg,transparent_0px,transparent_22px,currentColor_22px,currentColor_24px)] opacity-[0.04]\"\n />\n <div className=\"relative flex items-start justify-between\">\n <div>\n <div className=\"text-profile-micro tracking-profile-uppercase-2 text-background/50 font-semibold uppercase\">\n {brandLabel}\n </div>\n <div className=\"text-profile-hero tracking-profile-mono text-background mt-1 font-mono font-bold\">\n {last4}\n </div>\n </div>\n {method.default && (\n <span className=\"text-profile-micro bg-background/10 text-background/80 rounded-md px-2 py-0.5 font-bold tracking-wider uppercase\">\n Default\n </span>\n )}\n </div>\n <div className=\"relative flex items-end justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-nano tracking-profile-uppercase-2 text-background/40 font-semibold uppercase\">\n Cardholder\n </div>\n <div className=\"text-profile-xs-plus text-background truncate font-semibold\">\n {holder || \" \"}\n </div>\n </div>\n <div>\n <div className=\"text-profile-nano tracking-profile-uppercase-2 text-background/40 font-semibold uppercase\">\n Expires\n </div>\n <div className=\"text-profile-xs-plus text-background font-mono font-semibold\">\n {exp}\n </div>\n </div>\n <div\n className={`text-profile-micro shrink-0 rounded px-1.5 py-0.5 font-bold tracking-wider text-white ${badgeBg}`}\n >\n {badge}\n </div>\n </div>\n </button>\n );\n}\n\nfunction AddPaymentTile({ onClick }: { onClick: () => void }): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group ring-dashed ring-profile-dashed-border bg-profile-card text-profile-text-muted hover:bg-profile-canvas hover:text-profile-text flex aspect-[1.586/1] flex-col items-center justify-center gap-1.5 rounded-xl ring-1 transition-colors\"\n >\n <div className=\"ring-profile-border bg-profile-card flex size-9 items-center justify-center rounded-full ring-1\">\n <Plus className=\"size-4\" strokeWidth={2.25} />\n </div>\n <div className=\"text-profile-sm text-profile-text font-bold\">\n Add payment method\n </div>\n <div className=\"text-profile-2xs-plus text-profile-text-faint\">\n Visa, Mastercard, Amex\n </div>\n </button>\n );\n}\n\nfunction AddressCard({\n address,\n onEdit,\n onDelete,\n}: {\n address: fluidPay.CustomerAddress;\n onEdit: () => void;\n onDelete?: () => void;\n}): JSX.Element {\n const label = address.name?.trim() || \"Address\";\n const cityLine = [address.city, address.state, address.postal_code]\n .filter(Boolean)\n .join(\", \");\n return (\n <div className=\"ring-profile-border bg-profile-card hover:bg-profile-pill-hover focus-within:ring-profile-text/40 relative flex flex-col rounded-2xl ring-1 transition-all duration-200 focus-within:ring-2 hover:ring-2\">\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"flex w-full flex-col rounded-2xl p-4 pr-12 text-left focus-visible:outline-none\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"bg-profile-icon-bg flex size-8 items-center justify-center rounded-full\">\n <MapPin\n className=\"text-profile-text-muted size-4\"\n strokeWidth={2}\n />\n </div>\n <div className=\"text-profile-md text-profile-text font-bold\">\n {label}\n </div>\n </div>\n {address.default && (\n <span className=\"bg-profile-dark text-profile-micro text-profile-dark-foreground rounded-md px-2 py-0.5 font-bold tracking-wider uppercase\">\n Default\n </span>\n )}\n </div>\n <div className=\"text-profile-sm-plus text-profile-text mt-3 space-y-0.5 leading-snug\">\n {address.address1 && <div>{address.address1}</div>}\n {address.address2 && <div>{address.address2}</div>}\n {cityLine && <div>{cityLine}</div>}\n {address.country_code && (\n <div className=\"text-profile-text-muted\">\n {address.country_code}\n </div>\n )}\n </div>\n </button>\n {onDelete && (\n <div className=\"absolute top-2 right-2 z-10\">\n <EllipsesDropdown\n onEdit={onEdit}\n onDelete={onDelete}\n editLabel=\"Edit\"\n deleteLabel=\"Delete\"\n />\n </div>\n )}\n </div>\n );\n}\n\nfunction AddAddressTile({ onClick }: { onClick: () => void }): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group ring-dashed ring-profile-dashed-border min-h-profile-tile-min-h bg-profile-card text-profile-text-muted hover:bg-profile-canvas hover:text-profile-text flex flex-col items-center justify-center gap-1.5 rounded-2xl ring-1 transition-colors\"\n >\n <div className=\"ring-profile-border bg-profile-card flex size-9 items-center justify-center rounded-full ring-1\">\n <Plus className=\"size-4\" strokeWidth={2.25} />\n </div>\n <div className=\"text-profile-base text-profile-text font-bold\">\n Add an address\n </div>\n </button>\n );\n}\n\ntype SocialKey =\n | \"linkedin\"\n | \"facebook\"\n | \"x\"\n | \"instagram\"\n | \"youtube\"\n | \"pinterest\"\n | \"tiktok\";\n\ninterface SocialEntry {\n key: SocialKey;\n label: string;\n icon: ComponentType<{ className?: string; strokeWidth?: number }>;\n placeholder: string;\n}\n\nconst SOCIAL_ENTRIES: readonly SocialEntry[] = [\n {\n key: \"linkedin\",\n label: \"LinkedIn\",\n icon: Linkedin,\n placeholder: \"linkedin.com/in/username\",\n },\n {\n key: \"facebook\",\n label: \"Facebook\",\n icon: Facebook,\n placeholder: \"facebook.com/username\",\n },\n { key: \"x\", label: \"X\", icon: Twitter, placeholder: \"x.com/username\" },\n {\n key: \"instagram\",\n label: \"Instagram\",\n icon: Instagram,\n placeholder: \"instagram.com/username\",\n },\n {\n key: \"youtube\",\n label: \"YouTube\",\n icon: Youtube,\n placeholder: \"youtube.com/@channel\",\n },\n {\n key: \"pinterest\",\n label: \"Pinterest\",\n icon: Globe,\n placeholder: \"pinterest.com/username\",\n },\n {\n key: \"tiktok\",\n label: \"TikTok\",\n icon: Globe,\n placeholder: \"tiktok.com/@username\",\n },\n] as const;\n\nfunction SocialRow({\n entry,\n handle,\n isLast,\n onConnect,\n}: {\n entry: SocialEntry;\n handle: string;\n isLast: boolean;\n onConnect: () => void;\n}): JSX.Element {\n const Icon = entry.icon;\n return (\n <div\n className={`flex items-center gap-3 px-4 py-3.5 ${isLast ? \"\" : \"border-profile-divider border-b\"}`}\n >\n <div className=\"bg-profile-icon-bg text-profile-text flex size-9 shrink-0 items-center justify-center rounded-full\">\n <Icon className=\"size-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-profile-base text-profile-text font-bold\">\n {entry.label}\n </div>\n <div\n className={`text-profile-sm truncate ${handle ? \"text-profile-text-muted\" : \"text-profile-text-placeholder\"}`}\n >\n {handle || entry.placeholder}\n </div>\n </div>\n <PillButton\n onClick={onConnect}\n icon={handle ? Pencil : Plus}\n label={handle ? \"Edit\" : \"Connect\"}\n />\n </div>\n );\n}\n\nexport type { SocialKey };\n","import { useCallback, useMemo, useState } from \"react\";\nimport { z } from \"zod\";\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n Label,\n useZodForm,\n} from \"@fluid-app/ui-primitives\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\nimport type { Language, PointsLedger } from \"@fluid-app/profile-core\";\nimport {\n AddressFormDialog,\n ConfirmActionDialog,\n CreditCardFormDialog,\n EditPaymentMethodDialog,\n UserInfoDialog,\n socialFields,\n} from \"@fluid-app/profile-ui\";\nimport type {\n UserFormData,\n EditPaymentMethodFormData,\n} from \"@fluid-app/profile-ui\";\nimport {\n FluidPayCoreProvider,\n type fluidPay,\n type State,\n} from \"@fluid-app/fluid-pay-core\";\nimport type { PayAddress } from \"@fluid-app/portal-core/pay-types\";\nimport {\n createFluidPayApiAdapter,\n mapToFluidPayPaymentMethod,\n} from \"../adapters/fluid-pay-api-adapter\";\nimport type { AccountRep } from \"@fluid-app/portal-core/account-types\";\nimport { useAccountApi } from \"@fluid-app/portal-core/account-api-context\";\nimport { usePayApi } from \"@fluid-app/portal-core/pay-api-context\";\nimport { usePortalMySiteProfile } from \"@fluid-app/mysite-ui/portal/hooks/use-mysite-portal\";\nimport { useCountriesApi } from \"@fluid-app/store-core/countries-api-context\";\nimport { useLanguagesApi } from \"@fluid-app/store-core/languages-api-context\";\nimport { AddressAutocompleteInput } from \"@fluid-app/address-autocomplete/components/AddressAutocompleteInput\";\nimport { accountKeys, payKeys, storeKeys } from \"../account/query-keys\";\nimport { useAccount } from \"../hooks/use-account\";\nimport { deriveLastName } from \"./profile/derive-last-name\";\nimport { ProfileLayout, type SocialKey } from \"./profile/ProfileLayout\";\n\ninterface ProfileContentScreenProps {\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n countryIso: string;\n}\n\nfunction mapAccountToCustomerAccount(\n raw: AccountRep,\n): fluidPay.CustomerAccount {\n return {\n fluid_pay_account: {\n id: raw.id,\n email: raw.email,\n address_count: 0,\n payment_methods_count: 0,\n language_iso: null,\n },\n customer: {\n id: raw.id,\n active: true,\n active_subscriptions_count: 0,\n display_total_spent: \"0\",\n email: raw.email,\n first_name: raw.first_name,\n full_name: `${raw.first_name} ${raw.last_name}`.trim(),\n inactive_subscriptions_count: 0,\n is_rep: raw.member_type === \"rep\",\n phone: raw.phone,\n orders_count: 0,\n },\n };\n}\n\nfunction composeAddressName(\n firstName: string,\n lastName: string,\n): string | null {\n const combined = `${firstName} ${lastName}`.trim();\n return combined.length > 0 ? combined : null;\n}\n\nfunction mapToFluidPayAddress(raw: PayAddress): fluidPay.CustomerAddress {\n return {\n id: raw.id,\n address1: raw.street1,\n address2: raw.street2,\n city: raw.city,\n country_code: raw.country,\n default: raw.default,\n name: raw.name,\n postal_code: raw.zip,\n state: raw.state,\n subdivision_code: null,\n };\n}\n\ntype SocialFieldKey = (typeof socialFields)[number][\"name\"];\n\nconst SOCIAL_KEY_TO_FIELD: Record<SocialKey, SocialFieldKey | null> = {\n linkedin: \"linkedin\" as SocialFieldKey,\n facebook: \"facebook\" as SocialFieldKey,\n x: \"twitter\" as SocialFieldKey,\n instagram: \"instagram\" as SocialFieldKey,\n youtube: \"youtube\" as SocialFieldKey,\n pinterest: null,\n tiktok: \"tiktok\" as SocialFieldKey,\n};\n\nconst SOCIAL_LABELS: Record<SocialKey, string> = {\n linkedin: \"LinkedIn\",\n facebook: \"Facebook\",\n x: \"X\",\n instagram: \"Instagram\",\n youtube: \"YouTube\",\n pinterest: \"Pinterest\",\n tiktok: \"TikTok\",\n};\n\nconst SOCIAL_PLACEHOLDERS: Record<SocialKey, string> = {\n linkedin: \"linkedin.com/in/username\",\n facebook: \"facebook.com/username\",\n x: \"x.com/username\",\n instagram: \"instagram.com/username\",\n youtube: \"youtube.com/@channel\",\n pinterest: \"pinterest.com/username\",\n tiktok: \"tiktok.com/@username\",\n};\n\nexport function ProfileContentScreen({\n onToast,\n}: ProfileContentScreenProps): React.JSX.Element {\n const { t } = useProfileTranslation();\n const payApi = usePayApi();\n const accountApi = useAccountApi();\n const queryClient = useQueryClient();\n const fluidPayShim = useMemo(\n () => createFluidPayApiAdapter(payApi),\n [payApi],\n );\n\n const { data: mySiteProfile } = usePortalMySiteProfile();\n\n const mySiteUrl = mySiteProfile?.mysite_url ?? \"\";\n const mySiteDisplayUrl = mySiteUrl\n ? mySiteUrl.replace(/^https?:\\/\\//, \"\")\n : \"\";\n\n // Reuse the app-wide useAccount() cache entry shared with AppShell/PageRouter.\n const {\n data: accountRep,\n isLoading: isLoadingAccount,\n isError: isAccountError,\n } = useAccount();\n\n const accountData = useMemo(\n () => (accountRep ? mapAccountToCustomerAccount(accountRep) : undefined),\n [accountRep],\n );\n\n const { data: addressesData } = useQuery({\n queryKey: payKeys.addresses.list(),\n queryFn: async () => {\n const response = await payApi.fetchAddresses();\n return response.addresses.map(mapToFluidPayAddress);\n },\n enabled: true,\n });\n\n const { data: paymentMethodsData } = useQuery({\n queryKey: payKeys.paymentMethods.list(),\n queryFn: async () => {\n const response = await payApi.fetchPaymentMethods();\n return response.payment_methods.map(mapToFluidPayPaymentMethod);\n },\n enabled: true,\n });\n\n const countriesAdapter = useCountriesApi();\n const languagesAdapter = useLanguagesApi();\n\n const { data: countriesData } = useQuery({\n queryKey: storeKeys.countries(),\n queryFn: () => countriesAdapter.listCountries(),\n enabled: true,\n });\n\n const { data: languagesData } = useQuery({\n queryKey: storeKeys.languages(),\n queryFn: () => languagesAdapter.listLanguages(),\n enabled: true,\n });\n\n const { data: pointsLedgerData, isError: isPointsLedgerError } = useQuery({\n queryKey: payKeys.pointsLedgers.list(),\n queryFn: () => payApi.fetchPointsLedgers(),\n enabled: true,\n retry: (failureCount, error) => {\n if (\n error instanceof Error &&\n \"status\" in error &&\n (error as { status: number }).status === 403\n ) {\n return false;\n }\n return failureCount < 1;\n },\n });\n\n const rewardPointsEnabled = !isPointsLedgerError && pointsLedgerData != null;\n\n const adaptedPointsLedger: PointsLedger[] = useMemo(() => {\n return (pointsLedgerData?.points_ledgers ?? []).map((entry) => {\n const meta = entry.metadata as {\n transaction_type?: string | null;\n source?: {\n name: string;\n email?: string;\n reason?: string;\n user_id?: number;\n } | null;\n } | null;\n return {\n id: entry.id,\n amount: entry.amount,\n company_id: 0,\n created_at: entry.created_at,\n customer_id: 0,\n metadata: {\n transaction_type: meta?.transaction_type ?? undefined,\n source: meta?.source ?? undefined,\n },\n total_balance: entry.total_balance,\n updated_at: entry.created_at,\n };\n });\n }, [pointsLedgerData]);\n\n const updateCustomerMutation = useMutation({\n mutationFn: async (data: UserFormData) => {\n await accountApi.updateAccount({\n account: {\n first_name: data.first_name,\n last_name: data.last_name,\n phone: data.phone_number,\n bio: data.bio,\n },\n });\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: accountKeys.all });\n onToast(\"Profile updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update profile\", \"error\");\n },\n });\n\n const deletePaymentMethodMutation = useMutation({\n mutationFn: (paymentMethodId: number) =>\n payApi.deletePaymentMethod(paymentMethodId),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n },\n onError: () => {\n onToast(\"Failed to delete payment method\", \"error\");\n },\n });\n\n const updatePaymentMethodMutation = useMutation({\n mutationFn: ({\n paymentMethodId,\n data,\n }: {\n paymentMethodId: number;\n data: EditPaymentMethodFormData;\n }) =>\n payApi.updatePaymentMethod(paymentMethodId, {\n payment_method: {\n default: data.set_as_default,\n billing_address: {\n name: data.billing_address.name,\n street1: data.billing_address.address1,\n street2: data.billing_address.address2 ?? null,\n city: data.billing_address.city,\n state: data.billing_address.state,\n zip: data.billing_address.zip,\n country: data.billing_address.country_code,\n },\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n },\n onError: () => {\n onToast(\"Failed to update payment method\", \"error\");\n },\n });\n\n const createAddressMutation = useMutation({\n mutationFn: (body: fluidPay.CreateAddressBody) =>\n payApi.createAddress({\n address: {\n name: composeAddressName(\n body.address.first_name,\n body.address.last_name,\n ),\n street1: body.address.address1,\n street2: body.address.address2,\n city: body.address.city,\n state: body.address.state,\n zip: body.address.postal_code,\n country: body.address.country_code,\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address created\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to create address\", \"error\");\n },\n });\n\n const updateAddressMutation = useMutation({\n mutationFn: ({\n addressId,\n body,\n }: {\n addressId: number;\n body: fluidPay.CreateAddressBody;\n }) =>\n payApi.updateAddress(addressId, {\n address: {\n name: composeAddressName(\n body.address.first_name,\n body.address.last_name,\n ),\n street1: body.address.address1,\n street2: body.address.address2,\n city: body.address.city,\n state: body.address.state,\n zip: body.address.postal_code,\n country: body.address.country_code,\n },\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update address\", \"error\");\n },\n });\n\n const deleteAddressMutation = useMutation({\n mutationFn: (addressId: number) => payApi.deleteAddress(addressId),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: payKeys.addresses.all });\n onToast(\"Address deleted\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to delete address\", \"error\");\n },\n });\n\n const addCreditCardMutation = useMutation({\n mutationFn: (data: fluidPay.AddCreditCardData) =>\n payApi.createPaymentMethod({\n payment_method: {\n type: \"card\",\n token: data.payment_method.token,\n default: data.default_payment_method,\n },\n ...(data.billing_address && {\n billing_address: {\n country: data.billing_address.country_code,\n name: data.billing_address.name ?? null,\n street1: data.billing_address.address1,\n street2: data.billing_address.address2 ?? null,\n city: data.billing_address.city,\n state: data.billing_address.state,\n zip: data.billing_address.zip,\n },\n }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: payKeys.paymentMethods.all,\n });\n onToast(\"Payment method added\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to add payment method\", \"error\");\n },\n });\n\n const addresses = addressesData ?? [];\n const paymentMethods = paymentMethodsData ?? [];\n\n const adaptedLanguages: Language[] = (languagesData?.languages ?? []).map(\n (l, i) => ({ id: i, name: l.name, iso: l.code }),\n );\n\n const countries = countriesData?.countries;\n\n const countryOptions = useMemo(\n () =>\n [...(countries ?? [])]\n .map((c) => ({ iso: c.code, name: c.name }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [countries],\n );\n\n const statesByCountry = useMemo(() => {\n const map = new Map<string, State[]>();\n for (const c of countries ?? []) {\n map.set(\n c.code,\n c.states.map((s) => ({ name: s.name, isoCode: s.code })),\n );\n }\n return map;\n }, [countries]);\n\n const fetchStatesFromCountries = useCallback(\n (countryCode: string): Promise<State[]> =>\n Promise.resolve(statesByCountry.get(countryCode) ?? []),\n [statesByCountry],\n );\n\n // Dialog open state\n const [isInfoDialogOpen, setIsInfoDialogOpen] = useState(false);\n const [addressDialog, setAddressDialog] = useState<{\n open: boolean;\n selected: fluidPay.CustomerAddress | null;\n }>({ open: false, selected: null });\n const [deletingAddress, setDeletingAddress] =\n useState<fluidPay.CustomerAddress | null>(null);\n const [isAddCardOpen, setIsAddCardOpen] = useState(false);\n const [editPaymentMethod, setEditPaymentMethod] =\n useState<fluidPay.CustomerPaymentMethod | null>(null);\n\n // User-info form (for the existing dialog)\n const userInfoLanguage = useMemo(() => {\n return (\n adaptedLanguages.find(\n (l) => l.iso === accountData?.fluid_pay_account.language_iso,\n )?.name ?? \"English\"\n );\n }, [adaptedLanguages, accountData]);\n\n const derivedLastName = useMemo(() => {\n if (!accountData) return \"\";\n const { first_name, full_name } = accountData.customer;\n return deriveLastName(first_name, full_name);\n }, [accountData]);\n\n const userInfoSchema = useMemo(\n () =>\n 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 phone_number: z.string().optional(),\n language: z.string().min(1, \"Language is required\"),\n bio: z.string().optional(),\n }),\n [],\n );\n\n const userInfoForm = useZodForm<UserFormData>(userInfoSchema, {\n defaultValues: {\n first_name: accountData?.customer.first_name ?? \"\",\n last_name: derivedLastName,\n phone_number: accountData?.customer.phone ?? \"\",\n language: userInfoLanguage,\n bio: accountRep?.bio ?? \"\",\n },\n });\n\n const handleOpenInfoDialog = useCallback(() => {\n userInfoForm.reset({\n first_name: accountData?.customer.first_name ?? \"\",\n last_name: derivedLastName,\n phone_number: accountData?.customer.phone ?? \"\",\n language: userInfoLanguage,\n bio: accountRep?.bio ?? \"\",\n });\n setIsInfoDialogOpen(true);\n }, [\n accountData,\n accountRep,\n derivedLastName,\n userInfoLanguage,\n userInfoForm,\n ]);\n\n const onSubmitUserInfo = userInfoForm.handleSubmit(async (data) => {\n try {\n await updateCustomerMutation.mutateAsync(data);\n setIsInfoDialogOpen(false);\n } catch {\n // toast surfaced via onError\n }\n });\n\n const socialLinks = useMemo<Partial<Record<SocialKey, string>>>(() => {\n const src: Partial<Record<SocialFieldKey, string>> =\n accountRep?.social_links ?? {};\n const result: Partial<Record<SocialKey, string>> = {};\n for (const [key, field] of Object.entries(SOCIAL_KEY_TO_FIELD) as [\n SocialKey,\n SocialFieldKey | null,\n ][]) {\n if (!field) continue;\n const v = src[field];\n if (typeof v === \"string\" && v.length > 0) {\n result[key] = v;\n }\n }\n return result;\n }, [accountRep]);\n\n const handleCopyMySiteLink = useCallback(async () => {\n if (!mySiteUrl) return;\n try {\n await navigator.clipboard.writeText(mySiteUrl);\n onToast(\"MySite link copied\", \"success\");\n } catch {\n onToast(\"Failed to copy link\", \"error\");\n }\n }, [mySiteUrl, onToast]);\n\n const [editingSocial, setEditingSocial] = useState<SocialKey | null>(null);\n const [socialDraft, setSocialDraft] = useState(\"\");\n\n const handleConnectSocial = useCallback(\n (key: SocialKey) => {\n const field = SOCIAL_KEY_TO_FIELD[key];\n if (!field) {\n onToast(\"This platform isn't editable yet\", \"warning\");\n return;\n }\n const current = accountRep?.social_links?.[field] ?? \"\";\n setSocialDraft(current);\n setEditingSocial(key);\n },\n [accountRep, onToast],\n );\n\n const updateSocialMutation = useMutation({\n mutationFn: async ({\n field,\n value,\n }: {\n field: SocialFieldKey;\n value: string;\n }) => {\n const current = accountRep?.social_links ?? {};\n await accountApi.updateAccount({\n account: {\n social_links: { ...current, [field]: value },\n },\n });\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: accountKeys.all });\n onToast(\"Social link updated\", \"success\");\n },\n onError: () => {\n onToast(\"Failed to update social link\", \"error\");\n },\n });\n\n const handleSubmitSocial = useCallback(async () => {\n if (!editingSocial) return;\n const field = SOCIAL_KEY_TO_FIELD[editingSocial];\n if (!field) return;\n await updateSocialMutation.mutateAsync({\n field,\n value: socialDraft.trim(),\n });\n setEditingSocial(null);\n }, [editingSocial, socialDraft, updateSocialMutation]);\n\n if (isAccountError && !isLoadingAccount) {\n return (\n <div className=\"px-4 py-8 sm:px-9\">\n <div className=\"text-muted-foreground text-center text-sm\">\n Unable to load account data. Please try again later.\n </div>\n </div>\n );\n }\n\n if (isLoadingAccount || !accountData || !accountRep) {\n return (\n <div className=\"px-4 pt-4 sm:px-9 md:pt-8\">\n <div className=\"space-y-4\">\n <div className=\"bg-muted h-16 animate-pulse rounded\" />\n <div className=\"bg-muted h-32 animate-pulse rounded\" />\n <div className=\"bg-muted h-32 animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n const pointsBalance = rewardPointsEnabled\n ? (pointsLedgerData?.points_ledgers?.[0]?.total_balance ?? 0)\n : undefined;\n\n return (\n <FluidPayCoreProvider api={fluidPayShim}>\n <ProfileLayout\n account={accountRep}\n pointsBalance={pointsBalance}\n pointsLedger={adaptedPointsLedger}\n rewardsEnabled={rewardPointsEnabled}\n addresses={addresses}\n paymentMethods={paymentMethods}\n mySiteDisplayUrl={mySiteDisplayUrl}\n socialLinks={socialLinks}\n onEditPersonalInfo={handleOpenInfoDialog}\n onAddAddress={() => setAddressDialog({ open: true, selected: null })}\n onEditAddress={(address) =>\n setAddressDialog({ open: true, selected: address })\n }\n onDeleteAddress={(address) => setDeletingAddress(address)}\n onAddPaymentMethod={() => setIsAddCardOpen(true)}\n onEditPaymentMethod={(pm) => setEditPaymentMethod(pm)}\n onCopyMySiteLink={handleCopyMySiteLink}\n onConnectSocial={handleConnectSocial}\n />\n\n <UserInfoDialog\n control={userInfoForm.control}\n isOpen={isInfoDialogOpen}\n onSubmit={onSubmitUserInfo}\n handleClose={() => setIsInfoDialogOpen(false)}\n languageOptions={adaptedLanguages.map((l) => ({\n name: l.name,\n value: l.name,\n }))}\n errorMsg={undefined}\n isSubmitting={updateCustomerMutation.isPending}\n email={accountRep.email ?? \"\"}\n />\n\n <AddressFormDialog\n isOpen={addressDialog.open}\n onClose={() => setAddressDialog({ open: false, selected: null })}\n selectedAddress={addressDialog.selected}\n t={(key: string) => t(key as never)}\n onSubmit={async (formData) => {\n if (addressDialog.selected) {\n await updateAddressMutation.mutateAsync({\n addressId: addressDialog.selected.id,\n body: formData,\n });\n } else {\n await createAddressMutation.mutateAsync(formData);\n }\n setAddressDialog({ open: false, selected: null });\n }}\n isSubmitting={\n createAddressMutation.isPending || updateAddressMutation.isPending\n }\n onDelete={\n addressDialog.selected && !addressDialog.selected.default\n ? async () => {\n if (!addressDialog.selected) return;\n try {\n await deleteAddressMutation.mutateAsync(\n addressDialog.selected.id,\n );\n setAddressDialog({ open: false, selected: null });\n } catch {\n // toast surfaced via onError\n }\n }\n : undefined\n }\n isDeleting={deleteAddressMutation.isPending}\n countries={countryOptions}\n fetchStates={fetchStatesFromCountries}\n renderAddressAutocomplete={({ control, setValue, countryCode }) => (\n <AddressAutocompleteInput\n control={control}\n setValue={setValue}\n countryIso={countryCode}\n addressLineField=\"address1\"\n cityField=\"city\"\n stateField=\"state\"\n postalCodeField=\"postal_code\"\n placeholder={t(\"address_line_1\")}\n />\n )}\n />\n\n <ConfirmActionDialog\n title={t(\"delete_address\")}\n description={t(\"delete_address_message\")}\n openDialog={deletingAddress !== null}\n setOpenDialog={(open) => {\n if (!open) setDeletingAddress(null);\n }}\n onAction={async () => {\n if (!deletingAddress) return;\n try {\n await deleteAddressMutation.mutateAsync(deletingAddress.id);\n setDeletingAddress(null);\n } catch {\n // toast surfaced via onError\n }\n }}\n isLoading={deleteAddressMutation.isPending}\n actionText={t(\"delete\")}\n />\n\n <CreditCardFormDialog\n isOpen={isAddCardOpen}\n onClose={() => setIsAddCardOpen(false)}\n t={(key: string) => t(key as never)}\n onSubmit={async (data) => {\n try {\n await addCreditCardMutation.mutateAsync(data);\n setIsAddCardOpen(false);\n } catch {\n // toast surfaced via onError\n }\n }}\n isSubmitting={addCreditCardMutation.isPending}\n countries={countryOptions}\n jwt=\"\"\n renderAddressAutocomplete={({ control, setValue, countryCode }) => (\n <AddressAutocompleteInput\n control={control}\n setValue={setValue}\n countryIso={countryCode}\n addressLineField=\"address1\"\n cityField=\"city\"\n stateField=\"state\"\n postalCodeField=\"zip\"\n placeholder={t(\"address_line_1\")}\n />\n )}\n />\n\n {editPaymentMethod && (\n <EditPaymentMethodDialog\n isOpen\n onClose={() => setEditPaymentMethod(null)}\n paymentMethod={editPaymentMethod}\n billingAddress={editPaymentMethod.billing_address}\n countries={countryOptions}\n onSubmit={(data) => {\n updatePaymentMethodMutation.mutate(\n { paymentMethodId: editPaymentMethod.id, data },\n { onSuccess: () => setEditPaymentMethod(null) },\n );\n }}\n isSubmitting={updatePaymentMethodMutation.isPending}\n onDelete={() => {\n deletePaymentMethodMutation.mutate(editPaymentMethod.id, {\n onSuccess: () => setEditPaymentMethod(null),\n });\n }}\n isDeleting={deletePaymentMethodMutation.isPending}\n />\n )}\n\n <Dialog\n open={editingSocial !== null}\n onOpenChange={(open) => !open && setEditingSocial(null)}\n >\n <DialogContent className=\"max-w-sm md:max-w-md\">\n <DialogHeader>\n <DialogTitle>\n {editingSocial\n ? `Edit ${SOCIAL_LABELS[editingSocial]} link`\n : \"Edit social link\"}\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-2 pt-2\">\n <Label\n htmlFor=\"social-handle\"\n className=\"mb-1.5 block text-sm font-medium\"\n >\n URL\n </Label>\n <Input\n id=\"social-handle\"\n value={socialDraft}\n onChange={(e) => setSocialDraft(e.target.value)}\n placeholder={\n editingSocial ? SOCIAL_PLACEHOLDERS[editingSocial] : \"\"\n }\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void handleSubmitSocial();\n }\n }}\n autoFocus\n />\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setEditingSocial(null)}\n disabled={updateSocialMutation.isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={() => {\n void handleSubmitSocial();\n }}\n disabled={updateSocialMutation.isPending}\n >\n {updateSocialMutation.isPending ? \"Saving...\" : \"Save\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </FluidPayCoreProvider>\n );\n}\n","import type { ComponentProps } from \"react\";\nimport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbPage,\n fluidToast,\n} from \"@fluid-app/ui-primitives\";\nimport { ScreenHeaderBreadcrumbs } from \"@fluid-app/portal-react/shell/ScreenHeaderContext\";\nimport { useProfileTranslation } from \"@fluid-app/profile-core/translation-api-context\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport { useFluidContext } from \"../providers/FluidProvider\";\nimport { ProfileTranslationBridge } from \"../providers/ProfileTranslationBridge\";\nimport { ProfileContentScreen } from \"./ProfileContentScreen\";\n\ntype ProfileScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n onToast?: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n};\n\nfunction defaultToast(message: string, type: \"success\" | \"error\" | \"warning\") {\n fluidToast({ title: message, type });\n}\n\nexport function ProfileScreen({\n onToast,\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProfileScreenProps): React.JSX.Element {\n const { config } = useFluidContext();\n const effectiveToast = onToast ?? defaultToast;\n const countryIso = config.countryIso ?? \"US\";\n\n return (\n <ProfileTranslationBridge>\n <ProfileScreenContent\n onToast={effectiveToast}\n countryIso={countryIso}\n divProps={divProps}\n />\n </ProfileTranslationBridge>\n );\n}\n\nfunction ProfileScreenContent({\n onToast,\n countryIso,\n divProps,\n}: {\n onToast: (message: string, type: \"success\" | \"error\" | \"warning\") => void;\n countryIso: string;\n divProps: ComponentProps<\"div\">;\n}): React.JSX.Element {\n const { t } = useProfileTranslation();\n\n return (\n <>\n <ScreenHeaderBreadcrumbs>\n <Breadcrumb>\n <BreadcrumbList className=\"text-lg\">\n <BreadcrumbItem>\n <BreadcrumbPage className=\"font-semibold\">\n {t(\"breadcrumb\")}\n </BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </ScreenHeaderBreadcrumbs>\n <div {...divProps}>\n <ProfileContentScreen onToast={onToast} countryIso={countryIso} />\n </div>\n </>\n );\n}\n\nexport const profileScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProfileScreen\",\n displayName: \"Profile Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|
|
@@ -834,11 +834,22 @@ function ProfileContentScreen({ onToast }) {
|
|
|
834
834
|
}
|
|
835
835
|
});
|
|
836
836
|
const addCreditCardMutation = (0, _tanstack_react_query.useMutation)({
|
|
837
|
-
mutationFn: (data) => payApi.createPaymentMethod({
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
837
|
+
mutationFn: (data) => payApi.createPaymentMethod({
|
|
838
|
+
payment_method: {
|
|
839
|
+
type: "card",
|
|
840
|
+
token: data.payment_method.token,
|
|
841
|
+
default: data.default_payment_method
|
|
842
|
+
},
|
|
843
|
+
...data.billing_address && { billing_address: {
|
|
844
|
+
country: data.billing_address.country_code,
|
|
845
|
+
name: data.billing_address.name ?? null,
|
|
846
|
+
street1: data.billing_address.address1,
|
|
847
|
+
street2: data.billing_address.address2 ?? null,
|
|
848
|
+
city: data.billing_address.city,
|
|
849
|
+
state: data.billing_address.state,
|
|
850
|
+
zip: data.billing_address.zip
|
|
851
|
+
} }
|
|
852
|
+
}),
|
|
842
853
|
onSuccess: () => {
|
|
843
854
|
queryClient.invalidateQueries({ queryKey: require_query_keys.payKeys.paymentMethods.all });
|
|
844
855
|
onToast("Payment method added", "success");
|
|
@@ -1126,6 +1137,7 @@ function ProfileContentScreen({ onToast }) {
|
|
|
1126
1137
|
isOpen: true,
|
|
1127
1138
|
onClose: () => setEditPaymentMethod(null),
|
|
1128
1139
|
paymentMethod: editPaymentMethod,
|
|
1140
|
+
billingAddress: editPaymentMethod.billing_address,
|
|
1129
1141
|
countries: countryOptions,
|
|
1130
1142
|
onSubmit: (data) => {
|
|
1131
1143
|
updatePaymentMethodMutation.mutate({
|
|
@@ -1241,4 +1253,4 @@ Object.defineProperty(exports, "profileScreenPropertySchema", {
|
|
|
1241
1253
|
}
|
|
1242
1254
|
});
|
|
1243
1255
|
|
|
1244
|
-
//# sourceMappingURL=ProfileScreen-
|
|
1256
|
+
//# sourceMappingURL=ProfileScreen-DuPvRoOI.cjs.map
|