"use client"; import { useId, useMemo } from "react"; import Button from "../../../components/buttons/Button"; import RuleCard from "../../../components/cards/RuleCard"; import TextInput from "../../../components/controls/TextInput"; import List from "../../../components/layout/List"; import type { ListItem, ListSize } from "../../../components/layout/List"; import Icon from "../../../components/asset/Icon"; import Dialog from "../../../components/modals/Dialog"; import Alert from "../../../components/modals/Alert"; import HeaderLockup from "../../../components/type/HeaderLockup"; import { useTranslation } from "../../../contexts/MessagesContext"; import type { CreateFlowState } from "../../create/types"; import type { MyPublishedRule, ServerDraftForProfile, } from "../../../../lib/create/api"; function draftBodyTextFromState( state: CreateFlowState, ): string | undefined { const ctx = state.communityContext?.trim(); if (ctx) return ctx; const summary = state.summary?.trim(); if (summary) return summary; return undefined; } export type ProfilePageViewProps = { userEmail: string; /** `M` below `lg` (1024px); `L` at `lg`+ per Figma Card / Rule. Breakpoints: `md` (640px) → `lg` (1024px) only. */ ruleCardSize: "M" | "L"; /** `true` at `lg` (1024px)+ — welcome uses {@link HeaderLockup} size `L` per `21962:17220`. */ profileLgUp: boolean; /** `m` = {@link List} M; `l` = List L at `xl` per Figma `22143:900256`. */ profileListSize: Extract; rules: MyPublishedRule[]; rulesError: boolean; draft: ServerDraftForProfile | null; showDraftCard: boolean; ruleDeleteOpen: boolean; ruleDeleteBusy: boolean; draftDeleteOpen: boolean; draftDeleteBusy: boolean; accountDeleteOpen: boolean; accountDeleteBusy: boolean; actionError: string | null; profileSuccessMessage: string | null; emailChangeOpen: boolean; emailChangeValue: string; onEmailChangeValueChange: (value: string) => void; emailChangeBusy: boolean; emailChangeRequestSent: boolean; emailChangeModalError: string | null; onDismissEmailChangeModalError: () => void; onOpenEmailChange: () => void; onCloseEmailChange: () => void; onSubmitEmailChange: () => void; onSignOut: () => void; onDeleteRule: (id: string) => void; onCloseDeleteRule: () => void; onConfirmDeleteRule: () => void; onDuplicateRule: (id: string) => void; onContinueDraft: () => void; onDeleteDraft: () => void; onCloseDeleteDraft: () => void; onConfirmDeleteDraft: () => void; onOpenDeleteAccount: () => void; onCloseDeleteAccount: () => void; onConfirmDeleteAccount: () => void; onDismissProfileSuccess: () => void; onDismissActionError: () => void; onDismissRulesError: () => void; }; /** * Figma: Inter 20/28 from `md` to `lg`+ (e.g. `21962:17224`); at `xl` Bricolage 28/36 (`22143:900251`, `22143:900255` — `Medium/Heading`); * mobile: smaller Bricolage. */ const profileSectionHeadingClass = "font-bricolage text-base font-bold leading-[22px] text-[var(--color-content-default-primary)] md:font-inter md:text-xl md:font-bold md:leading-7 xl:font-bricolage-grotesque xl:font-bold xl:text-[28px] xl:leading-9"; /** * Sticky `top` for page content below the product {@link TopNav} (standard variant). * Must match `TopNav.view.tsx`: nav `h` 40px → `lg` 84px → `xl` 88px, plus `header` `border-b` (+1px). */ const stickyBelowTopNavTopClass = "top-[41px] lg:top-[85px] xl:top-[89px]"; export type ProfilePageSignedOutViewProps = { onSignIn: () => void; /** `min-width: 1024px` — welcome uses {@link HeaderLockup} `L` per Figma `21962:17220`. */ profileLgUp: boolean; }; /** * Signed-out profile: same shell as {@link ProfilePageView} * (Figma mobile `22143:900762`, md `22143:900534`, lg `21962:17220` via {@link HeaderLockup}). */ export function ProfilePageSignedOutView({ onSignIn, profileLgUp, }: ProfilePageSignedOutViewProps) { const t = useTranslation("pages.profile"); const titleId = useId(); return (
{profileLgUp ? ( ) : ( <>

{t("pageTitle")}

{t("signInPrompt")}

)}
); } /** * Figma: mobile `22143:900762`; tablet `md` `22143:900534` (`@theme --breakpoint-md` 640px); * desktop `lg` `21962:17220` (`@theme --breakpoint-lg` 1024px); * `xl` `22143:900247` (same content spacing as lg; list + section type at `xl` — `List` L `21844:4405`). */ export function ProfilePageView({ userEmail, ruleCardSize, profileLgUp, profileListSize, rules, rulesError, draft, showDraftCard, ruleDeleteOpen, ruleDeleteBusy, draftDeleteOpen, draftDeleteBusy, accountDeleteOpen, accountDeleteBusy, actionError, profileSuccessMessage, emailChangeOpen, emailChangeValue, onEmailChangeValueChange, emailChangeBusy, emailChangeRequestSent, emailChangeModalError, onDismissEmailChangeModalError, onOpenEmailChange, onCloseEmailChange, onSubmitEmailChange, onSignOut, onDeleteRule, onCloseDeleteRule, onConfirmDeleteRule, onDuplicateRule, onContinueDraft, onDeleteDraft, onCloseDeleteDraft, onConfirmDeleteDraft, onOpenDeleteAccount, onCloseDeleteAccount, onConfirmDeleteAccount, onDismissProfileSuccess, onDismissActionError, onDismissRulesError, }: ProfilePageViewProps) { const t = useTranslation("pages.profile"); const tLogin = useTranslation("pages.login"); const titleId = useId(); const welcomeTitle = t("welcomeTitle").replace(/\{\{name\}\}/g, userEmail); const welcomeBody = rules.length > 0 ? t("welcomeBodyFirstRule") : t("welcomeBodyNoRules"); const profileOptionsItems = useMemo((): ListItem[] => { return [ { id: "create-custom", title: t("optionCreateCustom"), description: "", href: "/create", leadingIcon: "edit", showDescription: false, }, { id: "create-template", title: t("optionCreateTemplate"), description: "", href: "/templates?fromFlow=1", leadingIcon: "content_copy", showDescription: false, }, { id: "logout", title: t("optionLogout"), description: "", onClick: onSignOut, leadingIcon: "log_out", showDescription: false, }, { id: "change-email", title: t("optionChangeEmail"), description: "", onClick: onOpenEmailChange, leadingIcon: "mail", showDescription: false, }, { id: "delete-account", title: t("deleteAccount"), description: "", onClick: onOpenDeleteAccount, leadingIcon: "warning", variant: "danger", showDescription: false, }, ]; }, [t, onSignOut, onOpenDeleteAccount, onOpenEmailChange]); const ruleCardShellClass = "w-full !max-w-full cursor-default !gap-3 !rounded-[12px] shadow-[0_0_48px_rgba(0,0,0,0.1)] lg:!rounded-[24px] lg:shadow-[0_0_24px_rgba(0,0,0,0.1)]"; return ( <>
{profileLgUp ? ( ) : ( <>

{welcomeTitle}

{welcomeBody}

)}

{t("yourRulesHeading")}

{showDraftCard && draft?.hasDraft ? ( { const raw = draft.state.title; const s = typeof raw === "string" ? raw.trim() : ""; return s || t("draftHeading"); })()} description={draftBodyTextFromState(draft.state)} expanded size={ruleCardSize} hasBottomLinks bottomStatusLabel={t("draftInProgressBadge")} bottomLinks={[ { id: "continue", label: t("continueDraft"), onClick: onContinueDraft, }, { id: "delete-draft", label: t("deleteRule"), onClick: onDeleteDraft, }, ]} communityInitials={(() => { const raw = draft.state.title; const s = typeof raw === "string" ? raw.trim() : ""; return s.charAt(0).toUpperCase() || "·"; })()} backgroundColor="bg-[var(--color-surface-invert-brand-teal)]" className={ruleCardShellClass} /> ) : null} {rules.map((rule) => ( onDuplicateRule(rule.id), }, { id: "del", label: t("deleteRule"), onClick: () => onDeleteRule(rule.id), }, ]} communityInitials={ rule.title.trim().charAt(0).toUpperCase() || "·" } backgroundColor="bg-[var(--color-surface-invert-brand-teal)]" className={ruleCardShellClass} /> ))}
{rules.length === 0 && !rulesError && !showDraftCard ? (

{t("yourRulesEmpty")}

) : null}

{t("yourOptionsHeading")}

{ if (!ruleDeleteBusy) onCloseDeleteRule(); }} backdropVariant="blurredYellow" title={t("deleteRuleModalTitle")} description={t("deleteRuleModalBody")} footer={ <> } /> { if (!draftDeleteBusy) onCloseDeleteDraft(); }} backdropVariant="blurredYellow" title={t("deleteDraftModalTitle")} description={t("deleteDraftModalBody")} footer={ <> } /> { if (!accountDeleteBusy) onCloseDeleteAccount(); }} backdropVariant="blurredYellow" title={t("deleteAccountModalTitle")} description={t("deleteAccountModalBody")} footer={ <> } /> { if (!emailChangeBusy) onCloseEmailChange(); }} backdropVariant="blurredYellow" title={ emailChangeRequestSent ? tLogin("successTitle") : t("emailChangeModalTitle") } description={ emailChangeRequestSent ? tLogin("successBody") : t("emailChangeModalDescription") } footer={ emailChangeRequestSent ? ( ) : ( <> ) } > {emailChangeRequestSent ? (
) : ( onEmailChangeValueChange(e.target.value)} disabled={emailChangeBusy} error={Boolean(emailChangeModalError)} autoComplete="email" /> )}
{(profileSuccessMessage || actionError || rulesError) && (
{profileSuccessMessage ? ( ) : null} {actionError ? ( ) : null} {rulesError ? ( ) : null}
)} {emailChangeOpen && emailChangeModalError ? (
) : null} ); }