@carlonicora/nextjs-jsonapi 5.4.0 → 5.5.0
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/{BlockNoteEditor-YQL2SGFR.mjs → BlockNoteEditor-GVQCKRMU.mjs} +5 -5
- package/dist/{BlockNoteEditor-4YCAIEPT.js → BlockNoteEditor-THBJH2UR.js} +20 -20
- package/dist/{BlockNoteEditor-4YCAIEPT.js.map → BlockNoteEditor-THBJH2UR.js.map} +1 -1
- package/dist/{BlockNoteViewer-AEJKJ27Q.mjs → BlockNoteViewer-U6E3DS4F.mjs} +3 -3
- package/dist/{BlockNoteViewer-YL3J7J2Y.js → BlockNoteViewer-VZOVKTFO.js} +4 -4
- package/dist/{BlockNoteViewer-YL3J7J2Y.js.map → BlockNoteViewer-VZOVKTFO.js.map} +1 -1
- package/dist/billing/index.js +442 -442
- package/dist/billing/index.mjs +4 -4
- package/dist/{chunk-XCHSX3VC.mjs → chunk-3CGROPF3.mjs} +2 -2
- package/dist/{chunk-QMYQRPQC.mjs → chunk-6SQYXUVP.mjs} +2 -2
- package/dist/{chunk-NFBOSPNJ.js → chunk-G6UE6MEP.js} +59 -19
- package/dist/chunk-G6UE6MEP.js.map +1 -0
- package/dist/{chunk-YNCQSWQW.js → chunk-S4YJ5WCW.js} +8 -8
- package/dist/{chunk-YNCQSWQW.js.map → chunk-S4YJ5WCW.js.map} +1 -1
- package/dist/{chunk-3NLAXVIN.js → chunk-TY5FYP3G.js} +917 -881
- package/dist/chunk-TY5FYP3G.js.map +1 -0
- package/dist/{chunk-WC63PJSC.mjs → chunk-VC5A3AUZ.mjs} +61 -21
- package/dist/chunk-VC5A3AUZ.mjs.map +1 -0
- package/dist/{chunk-6DC2WVVB.mjs → chunk-W7F5BDSV.mjs} +2 -2
- package/dist/{chunk-5PPG6PL7.js → chunk-WPYT4UKJ.js} +3 -3
- package/dist/{chunk-5PPG6PL7.js.map → chunk-WPYT4UKJ.js.map} +1 -1
- package/dist/{chunk-EUKTBOI2.mjs → chunk-X5WIUUNG.mjs} +1471 -1435
- package/dist/chunk-X5WIUUNG.mjs.map +1 -0
- package/dist/{chunk-YW4ZCEWB.js → chunk-YDYVJM4I.js} +4 -4
- package/dist/{chunk-YW4ZCEWB.js.map → chunk-YDYVJM4I.js.map} +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -4
- package/dist/components/editors/server.d.mts +15 -0
- package/dist/components/editors/server.d.ts +15 -0
- package/dist/components/editors/server.js +38 -0
- package/dist/components/editors/server.js.map +1 -0
- package/dist/components/editors/server.mjs +38 -0
- package/dist/components/editors/server.mjs.map +1 -0
- package/dist/components/index.d.mts +33 -10
- package/dist/components/index.d.ts +33 -10
- package/dist/components/index.js +7 -5
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +8 -6
- package/dist/contexts/index.d.mts +9 -1
- package/dist/contexts/index.d.ts +9 -1
- package/dist/contexts/index.js +5 -5
- package/dist/contexts/index.mjs +4 -4
- package/dist/core/index.js +4 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +3 -3
- package/dist/email-automations/index.d.mts +3 -0
- package/dist/email-automations/index.d.ts +3 -0
- package/dist/email-automations/index.js +99 -95
- package/dist/email-automations/index.js.map +1 -1
- package/dist/email-automations/index.mjs +30 -26
- package/dist/email-automations/index.mjs.map +1 -1
- package/dist/features/analytics/index.d.mts +11 -4
- package/dist/features/analytics/index.d.ts +11 -4
- package/dist/features/analytics/index.js +127 -135
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/index.mjs +16 -24
- package/dist/features/analytics/index.mjs.map +1 -1
- package/dist/features/analytics/server.d.mts +5 -2
- package/dist/features/analytics/server.d.ts +5 -2
- package/dist/features/analytics/server.js +7 -7
- package/dist/features/analytics/server.js.map +1 -1
- package/dist/features/analytics/server.mjs +5 -5
- package/dist/features/analytics/server.mjs.map +1 -1
- package/dist/features/blog/index.d.mts +12 -2
- package/dist/features/blog/index.d.ts +12 -2
- package/dist/features/blog/index.js +206 -195
- package/dist/features/blog/index.js.map +1 -1
- package/dist/features/blog/index.mjs +71 -60
- package/dist/features/blog/index.mjs.map +1 -1
- package/dist/features/blog/server.d.mts +4 -1
- package/dist/features/blog/server.d.ts +4 -1
- package/dist/features/blog/server.js +49 -21
- package/dist/features/blog/server.js.map +1 -1
- package/dist/features/blog/server.mjs +36 -8
- package/dist/features/blog/server.mjs.map +1 -1
- package/dist/features/help/index.js +38 -38
- package/dist/features/help/index.mjs +4 -4
- package/dist/features/tokenusage/index.d.mts +1 -3
- package/dist/features/tokenusage/index.d.ts +1 -3
- package/dist/features/tokenusage/index.js +127 -135
- package/dist/features/tokenusage/index.js.map +1 -1
- package/dist/features/tokenusage/index.mjs +10 -18
- package/dist/features/tokenusage/index.mjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/server/index.js +4 -4
- package/dist/server/index.mjs +3 -3
- package/package.json +9 -1
- package/src/components/editors/server/BlockNoteServerContent.tsx +28 -0
- package/src/components/editors/server/__tests__/renderBlockNoteHTML.spec.ts +44 -0
- package/src/components/editors/server/renderBlockNoteHTML.ts +26 -0
- package/src/components/editors/server-entry.ts +7 -0
- package/src/components/index.ts +1 -0
- package/src/components/viewers/BlockNoteStaticViewer.tsx +44 -0
- package/src/features/administration/components/AdminIndexContainer.tsx +61 -33
- package/src/features/administration/components/__tests__/AdminIndexContainer.spec.tsx +61 -1
- package/src/features/administration/components/index.ts +2 -1
- package/src/features/administration/contexts/AdministrationContext.tsx +11 -3
- package/src/features/administration/contexts/__tests__/AdministrationContext.spec.tsx +40 -0
- package/src/features/ai-connection/ai-connection.module.ts +2 -0
- package/src/features/ai-connection/contexts/AiConnectionsContext.tsx +3 -16
- package/src/features/ai-connection/contexts/__tests__/AiConnectionsContext.spec.tsx +33 -0
- package/src/features/analytics/__tests__/server-entry.spec.tsx +2 -1
- package/src/features/analytics/analytics.modules.ts +22 -5
- package/src/features/analytics/components/AnalyticsAdminContainer.tsx +4 -3
- package/src/features/analytics/components/AnalyticsAdminPageContainer.tsx +6 -3
- package/src/features/analytics/components/AnalyticsJourneyContainer.tsx +4 -3
- package/src/features/analytics/components/__tests__/AnalyticsJourneyContainer.spec.tsx +11 -0
- package/src/features/analytics/components/__tests__/AnalyticsPageContainers.spec.tsx +12 -1
- package/src/features/analytics/components/server/AnalyticsAdminPage.tsx +6 -3
- package/src/features/analytics/contexts/AnalyticsAdminContext.tsx +8 -17
- package/src/features/analytics/contexts/__tests__/AnalyticsAdminContext.spec.tsx +17 -0
- package/src/features/billing/stripe-price/stripe-price.module.ts +2 -0
- package/src/features/billing/stripe-product/stripe-product.module.ts +2 -0
- package/src/features/blog/components/admin/BlogAdminContainer.tsx +13 -6
- package/src/features/blog/components/admin/BlogCategoriesList.tsx +1 -1
- package/src/features/blog/components/admin/BlogCoverImageField.tsx +1 -1
- package/src/features/blog/components/admin/BlogPostContainer.tsx +0 -1
- package/src/features/blog/components/admin/BlogPostEditor.tsx +42 -33
- package/src/features/blog/components/admin/BlogPostTranslationEditor.tsx +12 -4
- package/src/features/blog/components/admin/BlogPostsList.tsx +1 -1
- package/src/features/blog/components/public/BlogPostCard.tsx +2 -9
- package/src/features/blog/components/public/BlogPostMeta.tsx +2 -2
- package/src/features/blog/components/public/BlogPostView.tsx +9 -3
- package/src/features/blog/components/public/__tests__/BlogList.spec.tsx +2 -0
- package/src/features/blog/components/public/__tests__/BlogPostView.spec.tsx +17 -11
- package/src/features/blog/server/fetchers.ts +57 -8
- package/src/features/email-automation/components/containers/EmailAutomationsListContainer.tsx +12 -3
- package/src/features/rbac/contexts/RbacContext.tsx +4 -7
- package/src/features/rbac/contexts/__tests__/RbacContext.spec.tsx +42 -0
- package/src/features/tokenusage/components/TokenUsageAdminContainer.tsx +4 -3
- package/src/features/tokenusage/contexts/TokenUsageAdminContext.tsx +3 -18
- package/src/features/tokenusage/contexts/__tests__/TokenUsageAdminContext.spec.tsx +17 -0
- package/src/features/tokenusage/tokenusage-admin.module.ts +4 -3
- package/src/features/tokenusage/tokenusage.modules.ts +12 -2
- package/src/features/user/contexts/UserContext.tsx +18 -3
- package/src/features/user/contexts/__tests__/UserContext.spec.tsx +95 -0
- package/dist/chunk-3NLAXVIN.js.map +0 -1
- package/dist/chunk-EUKTBOI2.mjs.map +0 -1
- package/dist/chunk-NFBOSPNJ.js.map +0 -1
- package/dist/chunk-WC63PJSC.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-YQL2SGFR.mjs.map → BlockNoteEditor-GVQCKRMU.mjs.map} +0 -0
- /package/dist/{BlockNoteViewer-AEJKJ27Q.mjs.map → BlockNoteViewer-U6E3DS4F.mjs.map} +0 -0
- /package/dist/{chunk-XCHSX3VC.mjs.map → chunk-3CGROPF3.mjs.map} +0 -0
- /package/dist/{chunk-QMYQRPQC.mjs.map → chunk-6SQYXUVP.mjs.map} +0 -0
- /package/dist/{chunk-6DC2WVVB.mjs.map → chunk-W7F5BDSV.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/features/email-automation/components/lists/EmailAutomationsList.tsx","../../src/features/email-automation/components/forms/EmailAutomationEditor.tsx","../../src/features/email-automation/components/containers/EmailAutomationsListContainer.tsx","../../src/features/email-automation/components/containers/EmailAutomationContainer.tsx","../../src/features/email-automation/contexts/EmailAutomationContext.tsx","../../src/features/email-automation/components/canvas/EmailAutomationActiveSwitch.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvasTab.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvas.tsx","../../src/features/email-automation/components/canvas/shared/CanvasToolbar.tsx","../../src/features/email-automation/components/canvas/shared/EmptyCanvas.tsx","../../src/features/email-automation/components/canvas/shared/autoLayout.ts","../../src/features/email-automation/components/canvas/shared/longPress.ts","../../src/features/email-automation/components/canvas/buildCanvasGraph.ts","../../src/features/email-automation/components/canvas/edges/DelayEdge.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvasInspector.tsx","../../src/features/email-automation/components/forms/EmailStepEditor.tsx","../../src/features/email-automation/components/canvas/nodes/EmailStepNode.tsx","../../src/features/email-automation/components/canvas/nodes/TriggerNode.tsx","../../src/features/email-automation/components/lists/EmailAutomationRecipientsList.tsx","../../src/features/email-automation/components/unsubscribe/EmailUnsubscribe.tsx","../../src/features/email-automation/hooks/useEmailAutomationTableStructure.tsx","../../src/features/email-automation/hooks/useEmailAutomationEnrollmentTableStructure.tsx"],"sourcesContent":["\"use client\";\n\nimport { MailIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { ContentListTable } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { DataListRetriever, useDataListRetriever } from \"../../../../hooks\";\nimport { EmptyState } from \"../../../../shadcnui\";\nimport { EmailAutomationFields } from \"../../data/email-automation.fields\";\nimport { EmailAutomationInterface } from \"../../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\nimport { EmailAutomationTriggerInterface } from \"../../data/EmailAutomationTriggerInterface\";\nimport EmailAutomationEditor from \"../forms/EmailAutomationEditor\";\n\ntype EmailAutomationsListProps = {\n /**\n * Pass this whenever the list is the page's own content inside a\n * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in\n * `rounded-md border`, drawing a second bordered card inside the page's\n * rounded shell.\n */\n fullWidth?: boolean;\n};\n\nexport function EmailAutomationsList({ fullWidth }: EmailAutomationsListProps = {}) {\n const t = useTranslations();\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n\n const data: DataListRetriever<EmailAutomationInterface> = useDataListRetriever({\n retriever: (params) => EmailAutomationService.findMany(params),\n retrieverParams: {},\n module: Modules.EmailAutomation,\n });\n\n // The trigger column shows the label the app declares, not the stored key.\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const triggerLabels = useMemo(\n () => Object.fromEntries(triggers.map((trigger) => [trigger.key, trigger.label])),\n [triggers],\n );\n\n const functions: ReactNode[] = [<EmailAutomationEditor key=\"create-email-automation\" />];\n\n return (\n <ContentListTable\n data={data}\n fields={[\n EmailAutomationFields.name,\n EmailAutomationFields.trigger,\n EmailAutomationFields.status,\n EmailAutomationFields.steps,\n EmailAutomationFields.active,\n EmailAutomationFields.completed,\n EmailAutomationFields.unsubscribed,\n ]}\n tableGeneratorType={Modules.EmailAutomation}\n functions={functions}\n fullWidth={fullWidth}\n title={t(\"emailAutomations.admin.title\")}\n context={{ triggerLabels }}\n emptyState={<EmptyState icon={MailIcon} title={t(\"emailAutomations.admin.empty\")} />}\n />\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { EditorSheet, FormInput, FormSelect, FormSwitch } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { useI18nRouter } from \"../../../../i18n\";\nimport { EmailAutomationInput, EmailAutomationInterface } from \"../../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\nimport { EmailAutomationTriggerInterface } from \"../../data/EmailAutomationTriggerInterface\";\n\nexport type EmailAutomationEditorProps = {\n automation?: EmailAutomationInterface;\n propagateChanges?: (automation: EmailAutomationInterface) => void;\n onSuccess?: () => void | Promise<void>;\n trigger?: ReactNode;\n forceShow?: boolean;\n onClose?: () => void;\n dialogOpen?: boolean;\n onDialogOpenChange?: (open: boolean) => void;\n};\n\nfunction EmailAutomationEditorInternal({\n automation,\n propagateChanges,\n onSuccess,\n trigger,\n forceShow,\n onClose,\n dialogOpen,\n onDialogOpenChange,\n}: EmailAutomationEditorProps) {\n const t = useTranslations();\n const router = useI18nRouter();\n const isEdit = !!automation;\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n\n // Trigger labels are plain strings from the app config, not i18n keys.\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const triggerValues = useMemo(() => triggers.map((entry) => ({ id: entry.key, text: entry.label })), [triggers]);\n\n const formSchema = useMemo(\n () =>\n z.object({\n id: z.uuidv4(),\n name: z.string().min(1, { message: t(\"emailAutomations.fields.name.error\") }),\n trigger: z.string().optional(),\n exitTrigger: z.string().optional(),\n replyTo: z.string().refine((value) => value === \"\" || z.email().safeParse(value).success, {\n message: t(\"emailAutomations.fields.replyTo.error\"),\n }),\n isActive: z.boolean(),\n }),\n [t],\n );\n\n const getDefaultValues = useCallback(\n () => ({\n id: automation?.id ?? v4(),\n name: automation?.name ?? \"\",\n trigger: automation?.trigger ?? \"\",\n exitTrigger: automation?.exitTrigger ?? \"\",\n replyTo: automation?.replyTo ?? \"\",\n isActive: automation?.isActive ?? false,\n }),\n [automation],\n );\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: getDefaultValues(),\n });\n\n return (\n <EditorSheet\n form={form}\n entityType={t(\"emailAutomations.admin.title\")}\n entityName={automation?.name}\n title={isEdit ? t(\"emailAutomations.admin.editAutomation\") : t(\"emailAutomations.admin.newAutomation\")}\n isEdit={isEdit}\n module={Modules.EmailAutomation}\n size=\"md\"\n propagateChanges={propagateChanges}\n onSuccess={onSuccess}\n onNavigate={(url) => router.push(url)}\n onSubmit={async (values) => {\n const payload: EmailAutomationInput = {\n id: values.id,\n name: values.name,\n trigger: values.trigger || undefined,\n exitTrigger: values.exitTrigger || undefined,\n replyTo: values.replyTo || undefined,\n isActive: values.isActive,\n };\n return isEdit ? await EmailAutomationService.update(payload) : await EmailAutomationService.create(payload);\n }}\n onReset={getDefaultValues}\n trigger={trigger}\n forceShow={forceShow}\n onClose={onClose}\n dialogOpen={dialogOpen}\n onDialogOpenChange={onDialogOpenChange}\n >\n <div className=\"flex w-full flex-col gap-y-4\">\n <FormInput form={form} id=\"name\" name={t(\"emailAutomations.fields.name.label\")} isRequired />\n <FormSelect\n form={form}\n id=\"trigger\"\n name={t(\"emailAutomations.fields.trigger.label\")}\n placeholder={t(\"emailAutomations.fields.trigger.none\")}\n values={triggerValues}\n allowEmpty\n />\n <FormSelect\n form={form}\n id=\"exitTrigger\"\n name={t(\"emailAutomations.fields.exitTrigger.label\")}\n placeholder={t(\"emailAutomations.fields.trigger.none\")}\n values={triggerValues}\n allowEmpty\n />\n <FormInput form={form} id=\"replyTo\" name={t(\"emailAutomations.fields.replyTo.label\")} />\n <FormSwitch\n form={form}\n id=\"isActive\"\n name={t(\"emailAutomations.fields.isActive.label\")}\n description={t(\"emailAutomations.fields.isActive.help\")}\n />\n </div>\n </EditorSheet>\n );\n}\n\nexport function EmailAutomationEditor(props: EmailAutomationEditorProps) {\n return <EmailAutomationEditorInternal {...props} />;\n}\n\nexport default EmailAutomationEditor;\n","\"use client\";\n\nimport { RoundPageContainer } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { AdministrationProvider } from \"../../../administration/contexts/AdministrationContext\";\nimport { EmailAutomationsList } from \"../lists/EmailAutomationsList\";\n\n/**\n * Page container for the administrative email-automation list.\n *\n * Client component by necessity: `module={Modules.EmailAutomation}` is a\n * registry entry carrying an icon component and methods, which a Server\n * Component cannot pass across the boundary. Routes mount this container\n * instead — the same shape as every other list page.\n *\n * No `forceHeader`: ContentListTable draws its own header row with the title\n * and the create action, exactly as the company and user list pages do.\n */\nexport function EmailAutomationsListContainer() {\n return (\n <AdministrationProvider>\n <RoundPageContainer module={Modules.EmailAutomation} fullWidth>\n <EmailAutomationsList fullWidth />\n </RoundPageContainer>\n </AdministrationProvider>\n );\n}\n","\"use client\";\n\nimport { useTranslations } from \"next-intl\";\nimport { RoundPageContainer } from \"../../../../components\";\nimport { SharedProvider } from \"../../../../contexts/SharedContext\";\nimport { Modules } from \"../../../../core\";\nimport { usePageUrlGenerator } from \"../../../../hooks\";\nimport { BreadcrumbItemData } from \"../../../../interfaces\";\nimport { EmailAutomationProvider, useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationActiveSwitch } from \"../canvas/EmailAutomationActiveSwitch\";\nimport { EmailAutomationCanvasTab } from \"../canvas/EmailAutomationCanvasTab\";\nimport { EmailAutomationEditor } from \"../forms/EmailAutomationEditor\";\nimport { EmailAutomationRecipientsList } from \"../lists/EmailAutomationRecipientsList\";\n\nexport type EmailAutomationContainerProps = {\n automationId: string;\n};\n\nexport function EmailAutomationContainer({ automationId }: EmailAutomationContainerProps) {\n return (\n <EmailAutomationProvider automationId={automationId}>\n <EmailAutomationShell />\n </EmailAutomationProvider>\n );\n}\n\nfunction EmailAutomationShell() {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const { automation, reload } = useEmailAutomation();\n\n if (!automation) return null;\n\n const breadcrumbs: BreadcrumbItemData[] = [\n { name: t(\"emailAutomations.admin.title\"), href: generateUrl({ page: Modules.EmailAutomation }) },\n { name: automation.name },\n ];\n\n // The page chrome (title + header functions) is published here rather than by\n // AdministrationProvider: SharedProvider replaces its value for the subtree,\n // so this one carries the administration title type plus the automation name.\n return (\n <SharedProvider\n value={{\n breadcrumbs,\n title: {\n type: t(\"emailAutomations.admin.title\"),\n element: automation.name,\n functions: [\n <EmailAutomationActiveSwitch key=\"emailAutomationActiveSwitch\" />,\n <EmailAutomationEditor key=\"emailAutomationEditor\" automation={automation} onSuccess={reload} />,\n ],\n },\n }}\n >\n <RoundPageContainer\n module={Modules.EmailAutomation}\n id={automation.id}\n fullWidth\n forceHeader\n // The canvas is sized h-full: it needs the viewport-bound shell and a\n // fillHeight tab, or it resolves to zero height.\n scroll=\"fixed\"\n tabs={[\n {\n sectionKey: \"canvas\",\n label: t(\"emailAutomations.tabs.canvas\"),\n content: <EmailAutomationCanvasTab />,\n fillHeight: true,\n },\n {\n sectionKey: \"recipients\",\n label: t(\"emailAutomations.tabs.recipients\"),\n content: <EmailAutomationRecipientsList />,\n },\n ]}\n />\n </SharedProvider>\n );\n}\n","\"use client\";\n\nimport { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useState } from \"react\";\nimport { v4 } from \"uuid\";\nimport { EmailAutomationInterface } from \"../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../data/EmailAutomationService\";\nimport { EmailAutomationStepInput, EmailAutomationStepInterface } from \"../data/EmailAutomationStepInterface\";\nimport { EmailAutomationStepService } from \"../data/EmailAutomationStepService\";\nimport { EmailAutomationTriggerInterface } from \"../data/EmailAutomationTriggerInterface\";\n\n/** A new step: the provider always sets `automationId` and, when absent, a fresh `id`. */\nexport type EmailAutomationStepCreateInput = Omit<EmailAutomationStepInput, \"id\" | \"automationId\"> & {\n id?: string;\n automationId?: string;\n};\n/** A step update: the provider always sets `automationId`. */\nexport type EmailAutomationStepUpdateInput = Omit<EmailAutomationStepInput, \"automationId\"> & { automationId?: string };\n\nexport interface EmailAutomationContextType {\n automation: EmailAutomationInterface | undefined;\n steps: EmailAutomationStepInterface[];\n reload: () => Promise<void>;\n selectedStepId: string | null;\n select: (id: string | null) => void;\n createStep: (input: EmailAutomationStepCreateInput) => Promise<EmailAutomationStepInterface>;\n updateStep: (input: EmailAutomationStepUpdateInput) => Promise<EmailAutomationStepInterface>;\n deleteStep: (id: string) => Promise<void>;\n setNext: (stepId: string, nextStepId: string | null) => Promise<void>;\n updatePosition: (stepId: string, x: number, y: number) => Promise<void>;\n tidy: () => Promise<void>;\n triggers: EmailAutomationTriggerInterface[];\n}\n\nconst EmailAutomationContext = createContext<EmailAutomationContextType | undefined>(undefined);\n\nexport type EmailAutomationProviderProps = {\n automationId: string;\n children: ReactNode;\n};\n\nexport const EmailAutomationProvider = ({ automationId, children }: EmailAutomationProviderProps) => {\n const [automation, setAutomation] = useState<EmailAutomationInterface | undefined>(undefined);\n const [steps, setSteps] = useState<EmailAutomationStepInterface[]>([]);\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n const [selectedStepId, setSelectedStepId] = useState<string | null>(null);\n\n const reload = useCallback(async () => {\n const [loadedAutomation, loadedSteps] = await Promise.all([\n EmailAutomationService.findOne({ id: automationId }),\n EmailAutomationStepService.findByAutomation({ automationId }),\n ]);\n setAutomation(loadedAutomation);\n setSteps(loadedSteps);\n }, [automationId]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const select = useCallback((id: string | null) => setSelectedStepId(id), []);\n\n const createStep = useCallback(\n async (input: EmailAutomationStepCreateInput) => {\n const saved = await EmailAutomationStepService.create({ ...input, id: input.id ?? v4(), automationId });\n await reload();\n return saved;\n },\n [automationId, reload],\n );\n\n const updateStep = useCallback(\n async (input: EmailAutomationStepUpdateInput) => {\n const saved = await EmailAutomationStepService.update({ ...input, automationId });\n await reload();\n return saved;\n },\n [automationId, reload],\n );\n\n const deleteStep = useCallback(\n async (id: string) => {\n await EmailAutomationStepService.delete({ id });\n if (selectedStepId === id) setSelectedStepId(null);\n await reload();\n },\n [reload, selectedStepId],\n );\n\n const setNext = useCallback(\n async (stepId: string, nextStepId: string | null) => {\n if (nextStepId) await EmailAutomationStepService.setNext({ stepId, nextStepId });\n else await EmailAutomationStepService.clearNext({ stepId });\n await reload();\n },\n [reload],\n );\n\n // PATCH with the step's current attributes plus the new position: the step\n // input type requires subject and body, and sending them unchanged is a no-op.\n const updatePosition = useCallback(\n async (stepId: string, x: number, y: number) => {\n const step = steps.find((candidate) => candidate.id === stepId);\n if (!step) return;\n await EmailAutomationStepService.update({\n id: step.id,\n automationId,\n subject: step.subject,\n body: step.body,\n delayHours: step.delayHours,\n positionX: x,\n positionY: y,\n });\n await reload();\n },\n [automationId, reload, steps],\n );\n\n const tidy = useCallback(async () => {\n await EmailAutomationService.tidy({ id: automationId });\n await reload();\n }, [automationId, reload]);\n\n const value = useMemo<EmailAutomationContextType>(\n () => ({\n automation,\n steps,\n reload,\n selectedStepId,\n select,\n createStep,\n updateStep,\n deleteStep,\n setNext,\n updatePosition,\n tidy,\n triggers,\n }),\n [\n automation,\n steps,\n reload,\n selectedStepId,\n select,\n createStep,\n updateStep,\n deleteStep,\n setNext,\n updatePosition,\n tidy,\n triggers,\n ],\n );\n\n return <EmailAutomationContext.Provider value={value}>{children}</EmailAutomationContext.Provider>;\n};\n\nexport const useEmailAutomation = (): EmailAutomationContextType => {\n const context = useContext(EmailAutomationContext);\n if (context === undefined) {\n throw new Error(\"useEmailAutomation must be used within an EmailAutomationProvider\");\n }\n return context;\n};\n","\"use client\";\n\nimport { useTranslations } from \"next-intl\";\nimport { useState } from \"react\";\nimport { errorToast } from \"../../../../components\";\nimport { Switch, Tooltip, TooltipContent, TooltipTrigger } from \"../../../../shadcnui\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\n\n/**\n * Inline on/off for the automation page header, so pausing never needs the\n * editor sheet. Off holds every enrolment in place (spec § \"Sending\" 3).\n */\nexport function EmailAutomationActiveSwitch() {\n const t = useTranslations();\n const { automation, reload } = useEmailAutomation();\n const [saving, setSaving] = useState<boolean>(false);\n\n if (!automation) return null;\n\n const toggle = async (checked: boolean) => {\n setSaving(true);\n try {\n await EmailAutomationService.update({\n id: automation.id,\n name: automation.name,\n trigger: automation.trigger,\n exitTrigger: automation.exitTrigger,\n replyTo: automation.replyTo,\n isActive: checked,\n });\n await reload();\n } catch (error) {\n errorToast({ title: t(\"common.errors.error\"), error });\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Tooltip>\n <TooltipTrigger render={<label className=\"flex items-center gap-x-2\" />}>\n <Switch checked={automation.isActive} onCheckedChange={(checked) => void toggle(checked)} disabled={saving} />\n <span className=\"text-xs\">{t(\"emailAutomations.fields.isActive.label\")}</span>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs\">{t(\"emailAutomations.fields.isActive.help\")}</TooltipContent>\n </Tooltip>\n );\n}\n","\"use client\";\n\nimport { ReactFlowProvider } from \"@xyflow/react\";\nimport { useEffect } from \"react\";\nimport { useSidebar } from \"../../../../shadcnui\";\nimport { EmailAutomationCanvas } from \"./EmailAutomationCanvas\";\n\nexport function EmailAutomationCanvasTab() {\n const { open, setOpen } = useSidebar();\n\n // Performance mode: collapse the app sidebar on mount; restore on unmount.\n // Mirrors the app's ScenarioCanvasPage shell.\n useEffect(() => {\n const prev = open;\n if (prev) setOpen(false);\n return () => {\n if (prev) setOpen(true);\n };\n }, []);\n\n return (\n <main className=\"flex h-full w-full overflow-hidden\">\n {/* The canvas column keeps `relative` so CanvasToolbar's absolute\n positioning anchors to the canvas, not to the whole row. */}\n <div className=\"relative h-full min-w-0 flex-1\">\n <ReactFlowProvider>\n <EmailAutomationCanvas />\n </ReactFlowProvider>\n </div>\n </main>\n );\n}\n","\"use client\";\n\nimport {\n Background,\n Connection,\n Edge,\n EdgeChange,\n FinalConnectionState,\n Node,\n NodeChange,\n OnConnectStart,\n OnNodeDrag,\n ReactFlow,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport { PlusIcon, Trash2Icon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { errorToast } from \"../../../../components/errors\";\nimport { ConfirmDialog, ContextMenu, ContextMenuContent, ContextMenuItem } from \"../../../../shadcnui\";\nimport { useIsMobile } from \"../../../../utils/use-mobile\";\nimport { showError } from \"../../../../utils/toast\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationEditor } from \"../forms/EmailAutomationEditor\";\nimport {\n STEP_NODE_HEIGHT,\n STEP_NODE_PREFIX,\n STEP_NODE_WIDTH,\n STEP_SOURCE_HANDLE_PREFIX,\n STEP_TARGET_HANDLE_PREFIX,\n TRIGGER_NODE_ID,\n TRIGGER_SOURCE_HANDLE,\n buildCanvasGraph,\n} from \"./buildCanvasGraph\";\nimport { DelayEdge } from \"./edges/DelayEdge\";\nimport { EmailAutomationCanvasInspector, useUserClosedGuard } from \"./EmailAutomationCanvasInspector\";\nimport { EmailStepNode } from \"./nodes/EmailStepNode\";\nimport { TriggerNode } from \"./nodes/TriggerNode\";\nimport { CanvasToolbar, EmptyCanvas, createLongPressTracker } from \"./shared\";\n\nconst DEFAULT_DELAY_HOURS = 24;\n\ntype PendingPaneMenu = {\n flowX: number;\n flowY: number;\n screenX: number;\n screenY: number;\n};\n\ntype PendingNodeMenu = {\n stepId: string;\n screenX: number;\n screenY: number;\n};\n\nconst pointAnchor = (screenX: number, screenY: number) => ({\n getBoundingClientRect: () =>\n ({\n x: screenX,\n y: screenY,\n top: screenY,\n left: screenX,\n right: screenX,\n bottom: screenY,\n width: 0,\n height: 0,\n toJSON: () => ({}),\n }) as DOMRect,\n});\n\nconst stepIdOf = (nodeId: string | null | undefined): string | null =>\n nodeId?.startsWith(STEP_NODE_PREFIX) ? nodeId.slice(STEP_NODE_PREFIX.length) : null;\n\nexport function EmailAutomationCanvas() {\n const { automation, steps, triggers, select, reload, createStep, deleteStep, setNext, updatePosition, tidy } =\n useEmailAutomation();\n const t = useTranslations();\n // Phone-only: a looser zoom-out floor so \"Fit to view\" can show the whole\n // graph. Desktop keeps React Flow's defaults untouched.\n const isMobile = useIsMobile();\n\n const [nodes, setNodes] = useState<Node[]>([]);\n const [edges, setEdges] = useState<Edge[]>([]);\n const { screenToFlowPosition } = useReactFlow();\n const connectingFromRef = useRef<{ nodeId: string | null; handleId: string | null } | null>(null);\n const [paneMenu, setPaneMenu] = useState<PendingPaneMenu | null>(null);\n const [nodeMenu, setNodeMenu] = useState<PendingNodeMenu | null>(null);\n const [pendingDeleteStepId, setPendingDeleteStepId] = useState<string | null>(null);\n const [automationEditorOpen, setAutomationEditorOpen] = useState<boolean>(false);\n\n const triggerLabel = useMemo(\n () =>\n triggers.find((trigger) => trigger.key === automation?.trigger)?.label ?? t(\"emailAutomations.canvas.noTrigger\"),\n [triggers, automation?.trigger, t],\n );\n\n const { laidNodes, laidEdges } = useMemo(() => {\n const graph = buildCanvasGraph(steps, triggerLabel);\n return { laidNodes: graph.nodes, laidEdges: graph.edges };\n }, [steps, triggerLabel]);\n\n useEffect(() => {\n setNodes(laidNodes);\n setEdges(laidEdges);\n }, [laidNodes, laidEdges]);\n\n const onNodesChange = useCallback((changes: NodeChange[]) => setNodes((nds) => applyNodeChanges(changes, nds)), []);\n const onEdgesChange = useCallback((changes: EdgeChange[]) => setEdges((eds) => applyEdgeChanges(changes, eds)), []);\n\n // The trigger has no stored position: only steps are persisted.\n const onNodeDragStop: OnNodeDrag = useCallback(\n (_e, node) => {\n const stepId = stepIdOf(node.id);\n if (!stepId) return;\n void updatePosition(stepId, node.position.x, node.position.y);\n },\n [updatePosition],\n );\n\n const onConnectStart: OnConnectStart = useCallback((_e, params) => {\n connectingFromRef.current = { nodeId: params.nodeId ?? null, handleId: params.handleId ?? null };\n }, []);\n\n /** A rejected link (self-link, loop, step already linked) reloads the true chain. */\n const linkSteps = useCallback(\n async (stepId: string, nextStepId: string) => {\n try {\n await setNext(stepId, nextStepId);\n } catch (error) {\n errorToast({ title: t(\"emailAutomations.canvas.chainError\"), error });\n await reload();\n }\n },\n [setNext, reload, t],\n );\n\n // onConnect fires only when React Flow finds a valid target handle.\n const onConnect = useCallback(\n async (conn: Connection) => {\n const from = connectingFromRef.current;\n connectingFromRef.current = null;\n if (!from || !from.handleId) return;\n if (!conn.targetHandle?.startsWith(STEP_TARGET_HANDLE_PREFIX)) return;\n const targetStepId = conn.targetHandle.slice(STEP_TARGET_HANDLE_PREFIX.length);\n\n // The trigger→head link is not stored: the API derives the head as the\n // oldest step with no incoming NEXT. A drag from the trigger onto a step\n // therefore cannot be saved, so it is refused with the chain error and\n // nothing changes.\n if (from.handleId === TRIGGER_SOURCE_HANDLE) {\n showError(t(\"emailAutomations.canvas.chainError\"));\n return;\n }\n\n if (!from.handleId.startsWith(STEP_SOURCE_HANDLE_PREFIX)) return;\n const sourceStepId = from.handleId.slice(STEP_SOURCE_HANDLE_PREFIX.length);\n await linkSteps(sourceStepId, targetStepId);\n },\n [linkSteps, t],\n );\n\n /** Creates a step centred on a flow point and returns its id. */\n const createStepAt = useCallback(\n async (flowX: number, flowY: number): Promise<string | null> => {\n if (!automation) return null;\n const id = uuidv4();\n await createStep({\n id,\n automationId: automation.id,\n subject: t(\"emailAutomations.step.title\"),\n body: \"\",\n delayHours: DEFAULT_DELAY_HOURS,\n positionX: flowX - STEP_NODE_WIDTH / 2,\n positionY: flowY - STEP_NODE_HEIGHT / 2,\n });\n return id;\n },\n [automation, createStep, t],\n );\n\n // onConnectEnd fires for EVERY drag end. If onConnect already cleared the\n // ref, it handled the case. Otherwise a drop on empty canvas creates a new\n // step there: from a step it is linked as that step's next; from the\n // trigger it is simply the first step when none existed, otherwise an\n // orphan (the trigger→head link is derived, never stored).\n const onConnectEnd = useCallback(\n async (event: MouseEvent | TouchEvent, connectionState: FinalConnectionState) => {\n const from = connectingFromRef.current;\n if (!from || !from.handleId || !automation) return;\n connectingFromRef.current = null;\n // Dropped on a node but not on its handle: not an empty-canvas drop.\n if (connectionState.toNode) return;\n\n const clientX =\n \"clientX\" in event ? (event as MouseEvent).clientX : ((event as TouchEvent).changedTouches[0]?.clientX ?? 0);\n const clientY =\n \"clientY\" in event ? (event as MouseEvent).clientY : ((event as TouchEvent).changedTouches[0]?.clientY ?? 0);\n const flowPos = screenToFlowPosition({ x: clientX, y: clientY });\n\n const sourceStepId = from.handleId.startsWith(STEP_SOURCE_HANDLE_PREFIX)\n ? from.handleId.slice(STEP_SOURCE_HANDLE_PREFIX.length)\n : null;\n if (!sourceStepId && from.handleId !== TRIGGER_SOURCE_HANDLE) return;\n\n const newStepId = await createStepAt(flowPos.x, flowPos.y);\n if (!newStepId) return;\n if (sourceStepId) await linkSteps(sourceStepId, newStepId);\n select(newStepId);\n },\n [automation, screenToFlowPosition, createStepAt, linkSteps, select],\n );\n\n // --- Pane context menu ---\n\n const handlePaneContextMenu = useCallback(\n (event: React.MouseEvent | MouseEvent) => {\n if (!automation) return;\n event.preventDefault();\n const clientX = (event as MouseEvent).clientX;\n const clientY = (event as MouseEvent).clientY;\n const flowPos = screenToFlowPosition({ x: clientX, y: clientY });\n setPaneMenu({\n flowX: flowPos.x,\n flowY: flowPos.y,\n screenX: clientX,\n screenY: clientY,\n });\n },\n [automation, screenToFlowPosition],\n );\n\n const handleCreateStepFromPane = useCallback(async () => {\n const menu = paneMenu;\n if (!menu) return;\n setPaneMenu(null);\n const newStepId = await createStepAt(menu.flowX, menu.flowY);\n if (newStepId) select(newStepId);\n }, [paneMenu, createStepAt, select]);\n\n // --- Node context menu ---\n //\n // Rendered through the same portal-based ContextMenu + fixed-anchor\n // technique as the pane menu: Base UI menus do NOT work when mounted inside\n // a React Flow node, so the menu lives outside the canvas and is anchored\n // to the click coordinates. The trigger node has no menu.\n const openNodeMenu = useCallback((nodeId: string | undefined, screenX: number, screenY: number) => {\n const stepId = stepIdOf(nodeId);\n if (!stepId) return;\n setNodeMenu({ stepId, screenX, screenY });\n }, []);\n\n const handleNodeContextMenu = useCallback(\n (event: React.MouseEvent, node: Node) => {\n event.preventDefault();\n openNodeMenu(node.id, event.clientX, event.clientY);\n },\n [openNodeMenu],\n );\n\n // --- Touch: long-press a node opens the same node menu ---\n //\n // Touch screens have no right-click. A ~500ms finger hold on a step node\n // opens the menu at the finger; moving the finger (pan / node drag) cancels\n // it, and the click produced by lifting the finger is swallowed so the hold\n // does not also open the step editor.\n const openNodeMenuRef = useRef(openNodeMenu);\n openNodeMenuRef.current = openNodeMenu;\n const longPress = useMemo(\n () =>\n createLongPressTracker({\n onLongPress: ({ target, clientX, clientY }) => {\n openNodeMenuRef.current(target, clientX, clientY);\n },\n }),\n [],\n );\n useEffect(() => () => longPress.cancel(), [longPress]);\n\n const handleTouchPointerDown = useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType !== \"touch\") return;\n const el = event.target as Element | null;\n // A press on a connection handle starts a link drag, never a menu.\n if (!el || el.closest(\".react-flow__handle\")) return;\n const nodeId = el.closest(\".react-flow__node\")?.getAttribute(\"data-id\");\n if (!stepIdOf(nodeId)) return;\n longPress.down(nodeId!, event.clientX, event.clientY);\n },\n [longPress],\n );\n\n const handleNodeClick = useCallback(\n (_event: React.MouseEvent, node: Node) => {\n if (node.id === TRIGGER_NODE_ID) {\n setAutomationEditorOpen(true);\n return;\n }\n const stepId = stepIdOf(node.id);\n if (stepId) select(stepId);\n },\n [select],\n );\n\n const handleDeleteStep = useCallback(async () => {\n const stepId = pendingDeleteStepId;\n if (!stepId) return;\n try {\n await deleteStep(stepId);\n } catch (error) {\n errorToast({ title: t(\"emailAutomations.canvas.deleteEmail\"), error });\n throw error; // keeps the dialog open — ConfirmDialog swallows rejections\n }\n }, [pendingDeleteStepId, deleteStep, t]);\n\n const nodeTypes = useMemo(() => ({ triggerNode: TriggerNode, emailStepNode: EmailStepNode }), []);\n const edgeTypes = useMemo(() => ({ delayEdge: DelayEdge }), []);\n\n return (\n <>\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnectStart={onConnectStart}\n onConnect={onConnect}\n onConnectEnd={onConnectEnd}\n onPaneContextMenu={handlePaneContextMenu}\n onNodeContextMenu={handleNodeContextMenu}\n onNodeClick={handleNodeClick}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n // Built-in React Flow click handler — independent of EdgeLabelRenderer\n // pointer-events. The label button calls `select` too; either path\n // produces the same selection state.\n onEdgeClick={(_event, edge) => {\n const targetStepId = (edge.data as { targetStepId?: string } | undefined)?.targetStepId;\n if (targetStepId) select(targetStepId);\n }}\n fitView\n // Never zoom past 100% on fit: with no emails the trigger is the only\n // node, and the default ceiling (2x) blows it up over the empty state.\n fitViewOptions={{ maxZoom: 1 }}\n // React Flow's default floor is 0.5, which on a phone stops \"Fit to\n // view\" before the graph fits. undefined keeps the desktop default.\n minZoom={isMobile ? 0.15 : undefined}\n onPointerDownCapture={handleTouchPointerDown}\n onPointerMoveCapture={(event) => {\n if (event.pointerType === \"touch\") longPress.move(event.clientX, event.clientY);\n }}\n onPointerUpCapture={() => longPress.up()}\n onPointerCancelCapture={() => longPress.cancel()}\n onClickCapture={(event) => {\n if (!longPress.consumeClick()) return;\n event.preventDefault();\n event.stopPropagation();\n }}\n proOptions={{ hideAttribution: true }}\n >\n <Background gap={16} size={1} />\n </ReactFlow>\n {steps.length === 0 && (\n // The canvas stays mounted under the empty state: the first email is\n // added by right-clicking it or dragging from the trigger.\n // Lower half only, so the text sits below the centred trigger node.\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 h-1/2\">\n <EmptyCanvas>\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">{t(\"emailAutomations.canvas.emptyTitle\")}</span>\n <span className=\"text-xs/relaxed\">{t(\"emailAutomations.canvas.emptyBody\")}</span>\n </div>\n </EmptyCanvas>\n </div>\n )}\n <CanvasToolbar onTidy={tidy} />\n <EmailAutomationCanvasInspector />\n {automationEditorOpen && automation && (\n <TriggerAutomationEditor\n automation={automation}\n onSaved={reload}\n onClose={() => setAutomationEditorOpen(false)}\n />\n )}\n <ConfirmDialog\n open={pendingDeleteStepId !== null}\n onOpenChange={(open) => {\n if (!open) setPendingDeleteStepId(null);\n }}\n title={t(\"emailAutomations.canvas.deleteEmail\")}\n description={t(\"emailAutomations.canvas.deleteEmailConfirm\")}\n confirmLabel={t(\"emailAutomations.canvas.deleteEmail\")}\n cancelLabel={t(\"ui.buttons.cancel\")}\n destructive\n onConfirm={handleDeleteStep}\n />\n {paneMenu && (\n <ContextMenu\n open={true}\n onOpenChange={(open) => {\n if (!open) setPaneMenu(null);\n }}\n >\n <ContextMenuContent\n anchor={pointAnchor(paneMenu.screenX, paneMenu.screenY)}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n >\n <ContextMenuItem onClick={handleCreateStepFromPane}>\n <PlusIcon />\n {t(\"emailAutomations.canvas.addEmail\")}\n </ContextMenuItem>\n </ContextMenuContent>\n </ContextMenu>\n )}\n {nodeMenu && (\n <ContextMenu\n open={true}\n onOpenChange={(open) => {\n if (!open) setNodeMenu(null);\n }}\n >\n <ContextMenuContent\n anchor={pointAnchor(nodeMenu.screenX, nodeMenu.screenY)}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n >\n <ContextMenuItem\n onClick={() => {\n const menu = nodeMenu;\n setNodeMenu(null);\n if (menu) setPendingDeleteStepId(menu.stepId);\n }}\n >\n <Trash2Icon />\n {t(\"emailAutomations.canvas.deleteEmail\")}\n </ContextMenuItem>\n </ContextMenuContent>\n </ContextMenu>\n )}\n </>\n );\n}\n\n/**\n * The trigger node's click opens the automation's own EditorSheet, controlled\n * the same way the inspector controls the step editor.\n */\nfunction TriggerAutomationEditor(props: {\n automation: NonNullable<ReturnType<typeof useEmailAutomation>[\"automation\"]>;\n onSaved: () => Promise<void> | void;\n onClose: () => void;\n}) {\n const onDialogOpenChange = useUserClosedGuard(props.onClose);\n\n return (\n <EmailAutomationEditor\n automation={props.automation}\n forceShow\n dialogOpen\n onDialogOpenChange={onDialogOpenChange}\n onSuccess={async () => {\n await props.onSaved();\n props.onClose();\n }}\n />\n );\n}\n","\"use client\";\n\nimport { useReactFlow } from \"@xyflow/react\";\nimport { ListRestartIcon, MaximizeIcon, MinusIcon, PlusIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { Button } from \"../../../../../shadcnui\";\n\nexport function CanvasToolbar({ onTidy }: { onTidy: () => void | Promise<void> }) {\n const t = useTranslations();\n const { zoomIn, zoomOut, fitView } = useReactFlow();\n\n return (\n <div data-help=\"canvas.toolbar\" className=\"absolute end-2 top-2 z-10 flex flex-col gap-1 max-md:top-14\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoomIn()}\n aria-label={t(\"canvas.toolbar.zoomIn\")}\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoomOut()}\n aria-label={t(\"canvas.toolbar.zoomOut\")}\n >\n <MinusIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => fitView({ duration: 300 })}\n aria-label={t(\"canvas.toolbar.fitView\")}\n >\n <MaximizeIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => void onTidy()}\n title={t(\"canvas.toolbar.tidyTooltip\")}\n aria-label={t(\"canvas.toolbar.tidy\")}\n >\n <ListRestartIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nexport function EmptyCanvas({ children }: { children: ReactNode }) {\n return (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center px-6 text-center text-sm\">\n {children}\n </div>\n );\n}\n","import dagre from \"dagre\";\n\nexport type LayoutNode = {\n id: string;\n /** node body dimensions in canvas px — used by dagre to allocate space */\n width: number;\n height: number;\n /** if true, dagre leaves position alone and uses these (x, y) verbatim */\n manuallyPositioned: boolean;\n x?: number;\n y?: number;\n};\n\nexport type LayoutEdge = {\n source: string;\n target: string;\n};\n\nexport type LayoutResult = Record<string, { x: number; y: number }>;\n\n/**\n * Deterministic LR layout. Pinned nodes keep their (x, y). Unpinned nodes\n * are laid out by dagre and returned in the result map.\n */\nexport function autoLayout(nodes: LayoutNode[], edges: LayoutEdge[]): LayoutResult {\n const g = new dagre.graphlib.Graph();\n g.setGraph({ rankdir: \"LR\", nodesep: 60, ranksep: 100, marginx: 24, marginy: 24 });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const n of nodes) {\n g.setNode(n.id, { width: n.width, height: n.height });\n }\n for (const e of edges) {\n if (g.hasNode(e.source) && g.hasNode(e.target)) {\n g.setEdge(e.source, e.target);\n }\n }\n\n dagre.layout(g);\n\n const result: LayoutResult = {};\n for (const n of nodes) {\n if (n.manuallyPositioned && typeof n.x === \"number\" && typeof n.y === \"number\") {\n result[n.id] = { x: n.x, y: n.y };\n } else {\n const laid = g.node(n.id);\n // dagre returns center coords; React Flow expects top-left, so subtract half dims.\n result[n.id] = {\n x: laid.x - n.width / 2,\n y: laid.y - n.height / 2,\n };\n }\n }\n return result;\n}\n","export const LONG_PRESS_MS = 500;\nexport const LONG_PRESS_MOVE_TOLERANCE_PX = 10;\n\n/**\n * Touch long-press detector for canvas nodes. A finger held still for\n * LONG_PRESS_MS on a node fires `onLongPress` with the press point; any move\n * beyond the tolerance (a pan or a node drag), a lift or a cancel aborts it.\n * After a fired press, `consumeClick()` returns true once, so the caller can\n * swallow the click that the finger lift produces.\n */\nexport function createLongPressTracker(params: {\n onLongPress: (press: { target: string; clientX: number; clientY: number }) => void;\n delayMs?: number;\n moveTolerancePx?: number;\n setTimer?: (fn: () => void, ms: number) => unknown;\n clearTimer?: (handle: unknown) => void;\n}) {\n const delay = params.delayMs ?? LONG_PRESS_MS;\n const tolerance = params.moveTolerancePx ?? LONG_PRESS_MOVE_TOLERANCE_PX;\n const setTimer = params.setTimer ?? ((fn: () => void, ms: number) => setTimeout(fn, ms));\n const clearTimer = params.clearTimer ?? ((handle: unknown) => clearTimeout(handle as ReturnType<typeof setTimeout>));\n\n let timer: unknown = null;\n let start: { x: number; y: number } | null = null;\n let fired = false;\n\n const cancel = () => {\n if (timer !== null) clearTimer(timer);\n timer = null;\n start = null;\n };\n\n return {\n down(target: string, clientX: number, clientY: number) {\n cancel();\n fired = false;\n start = { x: clientX, y: clientY };\n timer = setTimer(() => {\n timer = null;\n start = null;\n fired = true;\n params.onLongPress({ target, clientX, clientY });\n }, delay);\n },\n move(clientX: number, clientY: number) {\n if (!start) return;\n if (Math.hypot(clientX - start.x, clientY - start.y) > tolerance) cancel();\n },\n up: cancel,\n cancel,\n consumeClick(): boolean {\n const wasFired = fired;\n fired = false;\n return wasFired;\n },\n };\n}\n","import type { Edge, Node } from \"@xyflow/react\";\nimport { autoLayout, LayoutEdge, LayoutNode } from \"./shared\";\n\nexport const TRIGGER_NODE_ID = \"trigger\";\nexport const TRIGGER_SOURCE_HANDLE = \"trigger-source\";\nexport const STEP_NODE_PREFIX = \"step:\";\nexport const STEP_SOURCE_HANDLE_PREFIX = \"step-source-\";\nexport const STEP_TARGET_HANDLE_PREFIX = \"step-target-\";\n\nexport const TRIGGER_NODE_WIDTH = 200;\nexport const TRIGGER_NODE_HEIGHT = 56;\nexport const STEP_NODE_WIDTH = 200;\nexport const STEP_NODE_HEIGHT = 72;\n\n/**\n * The fields the canvas reads from a step. `EmailAutomationStepInterface`\n * satisfies it structurally; the narrow shape keeps this function pure and\n * testable with plain objects.\n */\nexport type CanvasStep = {\n id: string;\n subject: string;\n delayHours: number;\n positionX?: number;\n positionY?: number;\n sentCount: number;\n next?: { id: string };\n};\n\nexport type TriggerNodeData = { label: string };\n\nexport type EmailStepNodeData = {\n stepId: string;\n subject: string;\n sentCount: number;\n orphan: boolean;\n manuallyPositioned: boolean;\n};\n\nexport type DelayEdgeData = { targetStepId: string; delayHours: number };\n\nexport type CanvasGraph = { nodes: Node[]; edges: Edge[]; orphanIds: string[] };\n\n/**\n * The head is the oldest step with no incoming NEXT, exactly as the API picks\n * it (`findHead`). `steps` arrive ordered by createdAt ASC from\n * `findByAutomation`, so the first step nobody points at is the head.\n */\nexport function findHeadStepId(steps: CanvasStep[]): string | null {\n const pointedAt = new Set(steps.map((s) => s.next?.id).filter((id): id is string => !!id));\n return steps.find((s) => !pointedAt.has(s.id))?.id ?? null;\n}\n\nconst stepNodeId = (stepId: string) => `${STEP_NODE_PREFIX}${stepId}`;\n\n/**\n * Turns the automation's steps into React Flow nodes and edges: the trigger\n * node, one node per step, a trigger→head edge, and one edge per NEXT link.\n * Steps not reachable from the head (walking next→next) are orphans: they\n * never send and render dashed.\n */\nexport function buildCanvasGraph(steps: CanvasStep[], triggerLabel: string): CanvasGraph {\n const byId = new Map(steps.map((s) => [s.id, s]));\n const headId = findHeadStepId(steps);\n\n const chain = new Set<string>();\n let cursor = headId ? byId.get(headId) : undefined;\n while (cursor && !chain.has(cursor.id)) {\n chain.add(cursor.id);\n cursor = cursor.next ? byId.get(cursor.next.id) : undefined;\n }\n const orphanIds = steps.filter((s) => !chain.has(s.id)).map((s) => s.id);\n\n const layoutNodes: LayoutNode[] = [\n { id: TRIGGER_NODE_ID, width: TRIGGER_NODE_WIDTH, height: TRIGGER_NODE_HEIGHT, manuallyPositioned: false },\n ...steps.map((s) => ({\n id: stepNodeId(s.id),\n width: STEP_NODE_WIDTH,\n height: STEP_NODE_HEIGHT,\n manuallyPositioned: typeof s.positionX === \"number\" && typeof s.positionY === \"number\",\n x: s.positionX,\n y: s.positionY,\n })),\n ];\n\n const edges: Edge[] = [];\n const layoutEdges: LayoutEdge[] = [];\n\n const pushEdge = (source: string, sourceHandle: string, target: CanvasStep) => {\n const data: DelayEdgeData = { targetStepId: target.id, delayHours: target.delayHours };\n edges.push({\n id: `next:${source}->${target.id}`,\n source,\n sourceHandle,\n target: stepNodeId(target.id),\n targetHandle: `${STEP_TARGET_HANDLE_PREFIX}${target.id}`,\n type: \"delayEdge\",\n label: `${target.delayHours}h`,\n data,\n });\n layoutEdges.push({ source, target: stepNodeId(target.id) });\n };\n\n const head = headId ? byId.get(headId) : undefined;\n if (head) pushEdge(TRIGGER_NODE_ID, TRIGGER_SOURCE_HANDLE, head);\n for (const s of steps) {\n const next = s.next ? byId.get(s.next.id) : undefined;\n if (next) pushEdge(stepNodeId(s.id), `${STEP_SOURCE_HANDLE_PREFIX}${s.id}`, next);\n }\n\n const positions = autoLayout(layoutNodes, layoutEdges);\n\n const nodes: Node[] = [\n {\n id: TRIGGER_NODE_ID,\n type: \"triggerNode\",\n position: positions[TRIGGER_NODE_ID],\n deletable: false,\n data: { data: { label: triggerLabel } satisfies TriggerNodeData },\n },\n ...steps.map((s) => {\n const id = stepNodeId(s.id);\n return {\n id,\n type: \"emailStepNode\",\n position: positions[id],\n data: {\n data: {\n stepId: s.id,\n subject: s.subject,\n sentCount: s.sentCount,\n orphan: !chain.has(s.id),\n manuallyPositioned: typeof s.positionX === \"number\" && typeof s.positionY === \"number\",\n } satisfies EmailStepNodeData,\n },\n } satisfies Node;\n }),\n ];\n\n return { nodes, edges, orphanIds };\n}\n","\"use client\";\n\nimport { BaseEdge, Edge, EdgeLabelRenderer, EdgeProps, getBezierPath } from \"@xyflow/react\";\nimport { useEmailAutomation } from \"../../../contexts/EmailAutomationContext\";\nimport { DelayEdgeData } from \"../buildCanvasGraph\";\n\ntype DelayEdgeType = Edge<DelayEdgeData>;\n\n/**\n * ClueEdge recipe: a bezier with a label chip at its midpoint. The chip shows\n * the target step's delay and opens that step's editor. It is a plain\n * <button>: Base UI popovers do not work inside the React Flow canvas.\n */\nexport function DelayEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n label,\n data,\n}: EdgeProps<DelayEdgeType>) {\n const { select } = useEmailAutomation();\n const [edgePath, labelX, labelY] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const targetStepId = data?.targetStepId;\n\n return (\n <>\n <BaseEdge id={id} path={edgePath} className=\"stroke-foreground/60\" interactionWidth={24} />\n <EdgeLabelRenderer>\n {/* Inline position + pointer-events per React Flow docs: the label\n portal sets pointer-events:none, so the label sets it back to\n 'all' and carries `nodrag nopan nowheel` for event isolation. */}\n <div\n className=\"nodrag nopan nowheel\"\n style={{\n position: \"absolute\",\n transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,\n pointerEvents: \"all\",\n zIndex: 1000,\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"nodrag nopan bg-background hover:bg-accent text-foreground border-border h-auto rounded border px-2 py-1 text-xs tabular-nums shadow-sm\"\n onClick={(e) => {\n e.stopPropagation();\n if (targetStepId) select(targetStepId);\n }}\n >\n {label}\n </button>\n </div>\n </EdgeLabelRenderer>\n </>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailStepEditor } from \"../forms/EmailStepEditor\";\nimport { findHeadStepId } from \"./buildCanvasGraph\";\n\n/**\n * Mounts EmailStepEditor (the EditorSheet the step uses everywhere) on top of\n * the canvas, driven by `selectedStepId` from EmailAutomationContext. Copy of\n * the app's ScenarioCanvasInspector with one branch.\n *\n * - We control open state via `forceShow + dialogOpen + onDialogOpenChange`.\n * - On `onSuccess` we reload the canvas.\n * - The step comes from the context's `steps` (already loaded for the\n * canvas), so there is no per-step fetch.\n */\nexport function EmailAutomationCanvasInspector() {\n const { automation, steps, selectedStepId, select, reload } = useEmailAutomation();\n\n const close = useCallback(() => select(null), [select]);\n const onSaved = useCallback(async () => {\n await reload();\n }, [reload]);\n\n const headStepId = useMemo(() => findHeadStepId(steps), [steps]);\n const step = useMemo(() => steps.find((s) => s.id === selectedStepId) ?? null, [steps, selectedStepId]);\n\n if (!automation || !selectedStepId || !step) return null;\n\n return (\n <StepEditor\n key={step.id}\n step={step}\n automationId={automation.id}\n isHead={step.id === headStepId}\n onSaved={onSaved}\n onClose={close}\n />\n );\n}\n\n/**\n * Build an `onDialogOpenChange` callback that ignores the editor's\n * initial `open=false` notification. `useEditorDialog` (the hook\n * inside every EditorSheet) initialises `open` to `false`, then in\n * an effect sets it to `dialogOpen` (true). The \"open=false\" effect\n * fires synchronously on mount and would otherwise wipe our canvas\n * selection before the editor ever paints.\n */\nexport function useUserClosedGuard(onClose: () => void) {\n const wasOpenRef = useRef(false);\n return useCallback(\n (open: boolean) => {\n if (open) {\n wasOpenRef.current = true;\n return;\n }\n // open === false; only treat as \"user closed\" once we've seen open=true.\n if (wasOpenRef.current) onClose();\n },\n [onClose],\n );\n}\n\nfunction StepEditor(props: {\n step: ReturnType<typeof useEmailAutomation>[\"steps\"][number];\n automationId: string;\n isHead: boolean;\n onSaved: () => Promise<void>;\n onClose: () => void;\n}) {\n const onDialogOpenChange = useUserClosedGuard(props.onClose);\n\n return (\n <EmailStepEditor\n step={props.step}\n automationId={props.automationId}\n isHead={props.isHead}\n forceShow\n dialogOpen\n onDialogOpenChange={onDialogOpenChange}\n onSuccess={async () => {\n await props.onSaved();\n props.onClose();\n }}\n />\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useCallback, useMemo } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { EditorSheet, FormInput, FormTextarea } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationStepInput, EmailAutomationStepInterface } from \"../../data/EmailAutomationStepInterface\";\nimport { EmailAutomationStepService } from \"../../data/EmailAutomationStepService\";\n\n/** The fixed variable set the renderer fills (spec § \"Rendering\"). */\nconst TEMPLATE_VARIABLES = [\"{{name}}\", \"{{email}}\", \"{{url}}\", \"{{unsubscribeUrl}}\", \"{{unsubscribeAllUrl}}\"];\n\nexport type EmailStepEditorProps = {\n step?: EmailAutomationStepInterface;\n automationId: string;\n /** Canvas position for a step created from the editor. */\n initialPosition?: { x: number; y: number };\n /** The head step's delay counts from entering the automation, not from a previous email. */\n isHead?: boolean;\n trigger?: ReactNode;\n forceShow?: boolean;\n onClose?: () => void;\n dialogOpen?: boolean;\n onDialogOpenChange?: (open: boolean) => void;\n onSuccess?: () => void | Promise<void>;\n};\n\nfunction EmailStepEditorInternal({\n step,\n automationId,\n initialPosition,\n isHead,\n trigger,\n forceShow,\n onClose,\n dialogOpen,\n onDialogOpenChange,\n onSuccess,\n}: EmailStepEditorProps) {\n const t = useTranslations();\n const { reload } = useEmailAutomation();\n const isEdit = !!step;\n\n const formSchema = useMemo(\n () =>\n z.object({\n id: z.uuidv4(),\n subject: z.string().min(1, { message: t(\"emailAutomations.step.fields.subject.error\") }),\n delayHours: z.number().int().min(0),\n body: z.string().min(1, { message: t(\"emailAutomations.step.fields.body.error\") }),\n }),\n [t],\n );\n\n const getDefaultValues = useCallback(\n () => ({\n id: step?.id ?? v4(),\n subject: step?.subject ?? \"\",\n delayHours: step?.delayHours ?? 24,\n body: step?.body ?? \"\",\n }),\n [step],\n );\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: getDefaultValues(),\n });\n\n return (\n <EditorSheet\n form={form}\n entityType={t(\"emailAutomations.step.title\")}\n entityName={step?.subject}\n title={isEdit ? t(\"emailAutomations.step.editTitle\") : t(\"emailAutomations.step.title\")}\n isEdit={isEdit}\n module={Modules.EmailAutomationStep}\n size=\"lg\"\n onSubmit={async (values) => {\n const payload: EmailAutomationStepInput = {\n id: values.id,\n automationId,\n subject: values.subject,\n body: values.body,\n delayHours: values.delayHours,\n positionX: step ? step.positionX : initialPosition?.x,\n positionY: step ? step.positionY : initialPosition?.y,\n };\n return isEdit\n ? await EmailAutomationStepService.update(payload)\n : await EmailAutomationStepService.create(payload);\n }}\n // Save → reload the canvas, then whatever the caller adds.\n onSuccess={async () => {\n await reload();\n await onSuccess?.();\n }}\n onReset={getDefaultValues}\n trigger={trigger}\n forceShow={forceShow}\n onClose={onClose}\n dialogOpen={dialogOpen}\n onDialogOpenChange={onDialogOpenChange}\n >\n <div className=\"flex w-full flex-col gap-y-4\">\n <FormInput form={form} id=\"subject\" name={t(\"emailAutomations.step.fields.subject.label\")} isRequired />\n <FormInput\n form={form}\n id=\"delayHours\"\n type=\"number\"\n name={t(\"emailAutomations.step.fields.delayHours.label\")}\n description={\n isHead ? t(\"emailAutomations.canvas.hoursAfterEntering\") : t(\"emailAutomations.canvas.hoursAfterPrevious\")\n }\n />\n {/* FormTextarea has no `rows` prop; min-h-72 is the height of ~14 rows. */}\n <FormTextarea\n form={form}\n id=\"body\"\n name={t(\"emailAutomations.step.fields.body.label\")}\n className=\"min-h-72\"\n isRequired\n description={\n <>\n <span className=\"block\">\n {t(\"emailAutomations.step.variablesHint\")}{\" \"}\n {TEMPLATE_VARIABLES.map((variable) => (\n <span key={variable} className=\"me-2 text-foreground\">\n {variable}\n </span>\n ))}\n </span>\n <span className=\"mt-1 block\">{t(\"emailAutomations.step.unsubscribeHint\")}</span>\n </>\n }\n />\n </div>\n </EditorSheet>\n );\n}\n\nexport function EmailStepEditor(props: EmailStepEditorProps) {\n return <EmailStepEditorInternal {...props} />;\n}\n\nexport default EmailStepEditor;\n","\"use client\";\n\nimport { Handle, Node, NodeProps, Position } from \"@xyflow/react\";\nimport { MailIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { EmailStepNodeData, STEP_SOURCE_HANDLE_PREFIX, STEP_TARGET_HANDLE_PREFIX } from \"../buildCanvasGraph\";\n\ntype EmailStepNodeType = Node<{ data: EmailStepNodeData }>;\n\n/**\n * 200px card (SceneNode recipe): subject bold, \"sent N\" muted. An orphan (not\n * reachable from the trigger, so it never sends) is the dashed, faded variant\n * with a caption. Plain elements only: Base UI menus/popovers do not work\n * inside React Flow nodes; clicks and context menus are handled by the canvas.\n */\nexport function EmailStepNode({ data }: NodeProps<EmailStepNodeType>) {\n const d = data.data;\n const t = useTranslations();\n\n const shellClass = d.orphan\n ? \"border border-dashed border-foreground/30 bg-muted/40 opacity-60\"\n : \"border bg-background border-foreground/25 text-foreground\";\n\n return (\n <div className={`w-[200px] cursor-pointer rounded-md p-2 shadow-sm ${shellClass}`}>\n <Handle type=\"target\" position={Position.Left} id={`${STEP_TARGET_HANDLE_PREFIX}${d.stepId}`} />\n <Handle type=\"source\" position={Position.Right} id={`${STEP_SOURCE_HANDLE_PREFIX}${d.stepId}`} />\n\n <div className=\"flex items-center gap-1 text-sm font-medium\">\n <MailIcon className=\"size-3 shrink-0\" />\n <span className=\"truncate\">{d.subject}</span>\n </div>\n\n <div className=\"text-muted-foreground mt-1 text-xs tabular-nums\">\n {t(\"emailAutomations.canvas.sent\", { count: d.sentCount })}\n </div>\n\n {d.orphan && (\n <div className=\"text-muted-foreground mt-1 text-xs italic\">{t(\"emailAutomations.canvas.orphan\")}</div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { Handle, Node, NodeProps, Position } from \"@xyflow/react\";\nimport { ZapIcon } from \"lucide-react\";\nimport { TRIGGER_SOURCE_HANDLE, TriggerNodeData } from \"../buildCanvasGraph\";\n\n// React Flow v12 requires the Node generic to carry the data shape.\ntype TriggerNodeType = Node<{ data: TriggerNodeData }>;\n\n/**\n * The fixed head of the chain (SecretTargetNode recipe). Source handle only:\n * people enter here. Plain element, no Base UI inside the node; the click that\n * opens EmailAutomationEditor is handled by the canvas (`onNodeClick`).\n */\nexport function TriggerNode({ data }: NodeProps<TriggerNodeType>) {\n return (\n <div className=\"bg-foreground text-background flex w-[200px] cursor-pointer items-center justify-center gap-1 rounded-full px-4 py-2 text-center shadow-md\">\n <ZapIcon className=\"size-3 shrink-0 opacity-60\" />\n <div className=\"truncate text-sm font-medium\">{data.data.label}</div>\n <Handle type=\"source\" position={Position.Right} id={TRIGGER_SOURCE_HANDLE} />\n </div>\n );\n}\n","\"use client\";\n\nimport { RefreshCw } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useMemo, useState } from \"react\";\nimport { ContentListTable } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { DataListRetriever, useDataListRetriever } from \"../../../../hooks\";\nimport { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../shadcnui\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationEnrollmentFields } from \"../../data/email-automation-enrollment.fields\";\nimport { EmailAutomationEnrollmentInterface } from \"../../data/EmailAutomationEnrollmentInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\n\n/**\n * Read-only list of the people in this automation (owner decision 6: no row\n * actions). Rendered inside a tab, so it keeps its own bordered card (no\n * `fullWidth`), as PricesList does inside ProductContainer.\n */\nexport function EmailAutomationRecipientsList() {\n const t = useTranslations();\n const { automation } = useEmailAutomation();\n const [statusFilter, setStatusFilter] = useState<string>(\"all\");\n\n const data: DataListRetriever<EmailAutomationEnrollmentInterface> = useDataListRetriever({\n retriever: (params) => EmailAutomationService.findEnrollments(params),\n retrieverParams: { automationId: automation?.id },\n module: Modules.EmailAutomationEnrollment,\n });\n\n const handleStatusChange = (value: string | null) => {\n const status = value ?? \"all\";\n setStatusFilter(status);\n data.addAdditionalParameter(\"status\", status === \"all\" ? null : status);\n };\n\n const statusItems = useMemo(\n () => ({\n all: t(\"emailAutomations.recipients.status.all\"),\n active: t(\"emailAutomations.recipients.status.active\"),\n completed: t(\"emailAutomations.recipients.status.completed\"),\n unsubscribed: t(\"emailAutomations.recipients.status.unsubscribed\"),\n exited: t(\"emailAutomations.recipients.status.exited\"),\n failed: t(\"emailAutomations.recipients.status.failed\"),\n }),\n [t],\n );\n\n const filters = (\n <div className=\"flex items-center gap-4\">\n <Select items={statusItems} value={statusFilter} onValueChange={handleStatusChange}>\n <SelectTrigger className=\"w-40\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{t(\"emailAutomations.recipients.status.all\")}</SelectItem>\n <SelectItem value=\"active\">{t(\"emailAutomations.recipients.status.active\")}</SelectItem>\n <SelectItem value=\"completed\">{t(\"emailAutomations.recipients.status.completed\")}</SelectItem>\n <SelectItem value=\"unsubscribed\">{t(\"emailAutomations.recipients.status.unsubscribed\")}</SelectItem>\n <SelectItem value=\"exited\">{t(\"emailAutomations.recipients.status.exited\")}</SelectItem>\n <SelectItem value=\"failed\">{t(\"emailAutomations.recipients.status.failed\")}</SelectItem>\n </SelectContent>\n </Select>\n\n <Button variant=\"outline\" size=\"icon\" onClick={() => void data.refresh()} disabled={!data.isLoaded}>\n <RefreshCw className={`h-4 w-4 ${!data.isLoaded ? \"animate-spin\" : \"\"}`} />\n </Button>\n </div>\n );\n\n return (\n <ContentListTable\n data={data}\n fields={[\n EmailAutomationEnrollmentFields.email,\n EmailAutomationEnrollmentFields.name,\n EmailAutomationEnrollmentFields.status,\n EmailAutomationEnrollmentFields.currentStep,\n EmailAutomationEnrollmentFields.nextSendAt,\n EmailAutomationEnrollmentFields.sentCount,\n ]}\n tableGeneratorType={Modules.EmailAutomationEnrollment}\n filters={filters}\n /* The enrolments endpoint takes no search term, so rendering the box would\n give the page a control that silently does nothing. */\n allowSearch={false}\n emptyState={t(\"emailAutomations.recipients.empty\")}\n />\n );\n}\n","\"use client\";\n\nimport { CheckCircle, Loader2, XCircle } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"../../../../shadcnui\";\nimport { SectionHeader } from \"../../../../components/typography\";\nimport { EmailAutomationEnrollmentService } from \"../../data/EmailAutomationEnrollmentService\";\n\ntype UnsubscribeScope = \"automation\" | \"all\";\n\ninterface Props {\n token: string;\n scope: UnsubscribeScope;\n}\n\ntype UnsubscribeState = \"loading\" | \"success\" | \"error\";\n\nexport function EmailUnsubscribe({ token, scope }: Props) {\n const t = useTranslations();\n const [state, setState] = useState<UnsubscribeState>(\"loading\");\n const [stoppedScope, setStoppedScope] = useState<UnsubscribeScope>(scope);\n const [automationName, setAutomationName] = useState<string>(\"\");\n const [isStoppingAll, setIsStoppingAll] = useState<boolean>(false);\n\n useEffect(() => {\n async function unsubscribe() {\n try {\n const enrollment = await EmailAutomationEnrollmentService.unsubscribe({ token, scope });\n setAutomationName(enrollment?.automation?.name ?? \"\");\n setStoppedScope(scope);\n setState(\"success\");\n } catch {\n setState(\"error\");\n }\n }\n\n unsubscribe();\n }, [token, scope]);\n\n const stopAll = async () => {\n setIsStoppingAll(true);\n try {\n await EmailAutomationEnrollmentService.unsubscribe({ token, scope: \"all\" });\n setStoppedScope(\"all\");\n } catch {\n setState(\"error\");\n } finally {\n setIsStoppingAll(false);\n }\n };\n\n if (state === \"loading\") {\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <Loader2 className=\"text-primary h-12 w-12 animate-spin\" />\n <p className=\"text-muted-foreground text-sm\">{t(\"emailAutomations.unsubscribe.loading\")}</p>\n </div>\n );\n }\n\n if (state === \"error\") {\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <div className=\"bg-destructive/10 rounded-full p-4\">\n <XCircle className=\"text-destructive h-12 w-12\" />\n </div>\n <SectionHeader level={2}>{t(\"emailAutomations.unsubscribe.invalidTitle\")}</SectionHeader>\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.invalidBody\")}\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <div className=\"bg-primary/10 rounded-full p-4\">\n <CheckCircle className=\"text-primary h-12 w-12\" />\n </div>\n <SectionHeader level={2}>{t(\"emailAutomations.unsubscribe.title\")}</SectionHeader>\n {stoppedScope === \"all\" ? (\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.stoppedAll\")}\n </p>\n ) : (\n <>\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.stoppedAutomation\", { name: automationName })}\n </p>\n <Button variant=\"secondary\" onClick={stopAll} disabled={isStoppingAll}>\n {isStoppingAll && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {t(\"emailAutomations.unsubscribe.alsoStopAll\")}\n </Button>\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { ColumnDef } from \"@tanstack/react-table\";\nimport { useTranslations } from \"next-intl\";\nimport { useMemo } from \"react\";\nimport { Badge, Link } from \"../../../shadcnui\";\nimport { Modules } from \"../../../core\";\nimport { registerTableGenerator, TableContent, usePageUrlGenerator, UseTableStructureHook } from \"../../../hooks\";\nimport { EmailAutomationFields } from \"../data/email-automation.fields\";\nimport { EmailAutomationInterface } from \"../data/EmailAutomationInterface\";\n\n/**\n * `context.triggerLabels` maps a trigger key to the label the API declares for\n * it (EmailAutomationsList loads them). A key the app no longer declares falls\n * back to the raw key, so a stale automation stays readable.\n */\nexport const useEmailAutomationTableStructure: UseTableStructureHook<\n EmailAutomationInterface,\n EmailAutomationFields\n> = (params) => {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const triggerLabels: Record<string, string> = params.context?.triggerLabels ?? {};\n\n const tableData = useMemo(() => {\n return params.data.map((automation: EmailAutomationInterface) => {\n const entry: TableContent<EmailAutomationInterface> = { jsonApiData: automation };\n params.fields.forEach((field) => {\n entry[field] = (automation as any)[field as keyof EmailAutomationInterface];\n });\n return entry;\n });\n }, [params.data, params.fields]);\n\n // Typography role 15 (numeric): tabular-nums, end-aligned. NEVER\n // font-mono — no monospace font is loaded in these apps.\n const numericColumn = (\n field: EmailAutomationFields,\n header: string,\n read: (a: EmailAutomationInterface) => number,\n ) => ({\n id: field,\n accessorKey: field,\n header: header,\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return <span className=\"block text-xs tabular-nums text-end\">{read(automation) ?? 0}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n });\n\n const fieldColumnMap: Partial<Record<EmailAutomationFields, () => any>> = {\n [EmailAutomationFields.name]: () => ({\n id: \"name\",\n accessorKey: \"name\",\n header: t(\"emailAutomations.list.columns.name\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return <Link href={generateUrl({ page: Modules.EmailAutomation, id: automation.id })}>{automation.name}</Link>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.trigger]: () => ({\n id: \"trigger\",\n accessorKey: \"trigger\",\n header: t(\"emailAutomations.list.columns.trigger\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n if (!automation.trigger) return <span className=\"text-muted-foreground text-xs\">—</span>;\n return <span className=\"text-sm\">{triggerLabels[automation.trigger] ?? automation.trigger}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.status]: () => ({\n id: \"status\",\n accessorKey: \"status\",\n header: t(\"emailAutomations.list.columns.status\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return automation.isActive ? (\n <Badge variant=\"softGreen\">{t(\"emailAutomations.list.status.on\")}</Badge>\n ) : (\n <Badge variant=\"softGray\">{t(\"emailAutomations.list.status.off\")}</Badge>\n );\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.steps]: () =>\n numericColumn(EmailAutomationFields.steps, t(\"emailAutomations.list.columns.steps\"), (a) => a.stepCount),\n [EmailAutomationFields.active]: () =>\n numericColumn(EmailAutomationFields.active, t(\"emailAutomations.list.columns.active\"), (a) => a.activeCount),\n [EmailAutomationFields.completed]: () =>\n numericColumn(\n EmailAutomationFields.completed,\n t(\"emailAutomations.list.columns.completed\"),\n (a) => a.completedCount,\n ),\n [EmailAutomationFields.unsubscribed]: () =>\n numericColumn(\n EmailAutomationFields.unsubscribed,\n t(\"emailAutomations.list.columns.unsubscribed\"),\n (a) => a.unsubscribedCount,\n ),\n };\n\n const columns = useMemo(() => {\n return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<\n TableContent<EmailAutomationInterface>\n >[];\n }, [params.fields, fieldColumnMap, t, generateUrl]);\n\n return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);\n};\n\nregisterTableGenerator(\"email-automations\", useEmailAutomationTableStructure);\n","\"use client\";\n\nimport { ColumnDef } from \"@tanstack/react-table\";\nimport { useLocale, useTranslations } from \"next-intl\";\nimport { useMemo } from \"react\";\nimport { Badge } from \"../../../shadcnui\";\nimport { registerTableGenerator, TableContent, UseTableStructureHook } from \"../../../hooks\";\nimport { dateFormatLocale, formatDate } from \"../../../utils/date-formatter\";\nimport { EmailAutomationEnrollmentFields } from \"../data/email-automation-enrollment.fields\";\nimport { EmailAutomationEnrollmentInterface } from \"../data/EmailAutomationEnrollmentInterface\";\n\nconst STATUS_VARIANTS: Record<string, \"softGreen\" | \"softBlue\" | \"softGray\" | \"softRed\"> = {\n active: \"softGreen\",\n completed: \"softBlue\",\n unsubscribed: \"softGray\",\n exited: \"softGray\",\n failed: \"softRed\",\n};\n\nexport const useEmailAutomationEnrollmentTableStructure: UseTableStructureHook<\n EmailAutomationEnrollmentInterface,\n EmailAutomationEnrollmentFields\n> = (params) => {\n const t = useTranslations();\n const locale = dateFormatLocale(useLocale());\n\n const tableData = useMemo(() => {\n return params.data.map((enrollment: EmailAutomationEnrollmentInterface) => {\n const entry: TableContent<EmailAutomationEnrollmentInterface> = { jsonApiData: enrollment };\n params.fields.forEach((field) => {\n entry[field] = (enrollment as any)[field as keyof EmailAutomationEnrollmentInterface];\n });\n return entry;\n });\n }, [params.data, params.fields]);\n\n const empty = <span className=\"text-muted-foreground text-xs\">—</span>;\n\n const fieldColumnMap: Partial<Record<EmailAutomationEnrollmentFields, () => any>> = {\n [EmailAutomationEnrollmentFields.email]: () => ({\n id: \"email\",\n accessorKey: \"email\",\n header: t(\"emailAutomations.recipients.columns.email\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return <span className=\"text-sm\">{enrollment.email}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.name]: () => ({\n id: \"name\",\n accessorKey: \"name\",\n header: t(\"emailAutomations.recipients.columns.name\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return enrollment.name ? <span className=\"text-sm\">{enrollment.name}</span> : empty;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.status]: () => ({\n id: \"status\",\n accessorKey: \"status\",\n header: t(\"emailAutomations.recipients.columns.status\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return (\n <Badge\n variant={STATUS_VARIANTS[enrollment.status] ?? \"softGray\"}\n title={enrollment.status === \"failed\" ? enrollment.lastError : undefined}\n >\n {t(`emailAutomations.recipients.status.${enrollment.status}`)}\n </Badge>\n );\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.currentStep]: () => ({\n id: \"currentStep\",\n accessorKey: \"currentStep\",\n header: t(\"emailAutomations.recipients.columns.currentStep\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return enrollment.currentStepSubject ? <span className=\"text-sm\">{enrollment.currentStepSubject}</span> : empty;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.nextSendAt]: () => ({\n id: \"nextSendAt\",\n accessorKey: \"nextSendAt\",\n header: t(\"emailAutomations.recipients.columns.nextSendAt\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n if (!enrollment.nextSendAt) return empty;\n return <span className=\"text-xs tabular-nums\">{formatDate(enrollment.nextSendAt, \"dateTime\", locale)}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.sentCount]: () => ({\n id: \"sentCount\",\n accessorKey: \"sentCount\",\n header: t(\"emailAutomations.recipients.columns.sentCount\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n // Typography role 15 (numeric): tabular-nums, end-aligned.\n return <span className=\"block text-xs tabular-nums text-end\">{enrollment.sentCount ?? 0}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n };\n\n const columns = useMemo(() => {\n return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<\n TableContent<EmailAutomationEnrollmentInterface>\n >[];\n }, [params.fields, fieldColumnMap, t, locale]);\n\n return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);\n};\n\nregisterTableGenerator(\"email-automation-enrollments\", useEmailAutomationEnrollmentTableStructure);\n"],"mappings":"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","names":["useTranslations","useEffect","useMemo","useState","jsx","useTranslations","useState","useEffect","useMemo","jsx","useTranslations","useCallback","useEffect","useMemo","useState","v4","jsx","useState","useCallback","useEffect","v4","useMemo","useTranslations","useState","jsx","jsxs","useTranslations","useState","useEffect","useReactFlow","PlusIcon","useTranslations","useCallback","useEffect","useMemo","useRef","useState","useTranslations","jsx","jsxs","useTranslations","jsx","jsx","jsxs","useCallback","useMemo","zodResolver","useTranslations","useCallback","useMemo","useForm","v4","z","Fragment","jsx","jsxs","useTranslations","useMemo","z","useCallback","v4","useForm","zodResolver","jsx","useCallback","useMemo","MailIcon","useTranslations","jsx","jsxs","useTranslations","MailIcon","Handle","Position","jsx","jsxs","Handle","Position","Fragment","jsx","jsxs","useTranslations","useState","useReactFlow","useRef","useMemo","useEffect","useCallback","PlusIcon","jsx","useEffect","useTranslations","useMemo","useState","jsx","jsxs","useTranslations","useState","useMemo","jsx","useTranslations","useTranslations","useEffect","useState","Fragment","jsx","jsxs","useTranslations","useState","useEffect","useTranslations","useMemo","jsx","useTranslations","useMemo","useTranslations","useMemo","jsx","useTranslations","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../../src/features/email-automation/components/containers/EmailAutomationsListContainer.tsx","../../src/features/email-automation/components/lists/EmailAutomationsList.tsx","../../src/features/email-automation/components/forms/EmailAutomationEditor.tsx","../../src/features/email-automation/components/containers/EmailAutomationContainer.tsx","../../src/features/email-automation/contexts/EmailAutomationContext.tsx","../../src/features/email-automation/components/canvas/EmailAutomationActiveSwitch.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvasTab.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvas.tsx","../../src/features/email-automation/components/canvas/shared/CanvasToolbar.tsx","../../src/features/email-automation/components/canvas/shared/EmptyCanvas.tsx","../../src/features/email-automation/components/canvas/shared/autoLayout.ts","../../src/features/email-automation/components/canvas/shared/longPress.ts","../../src/features/email-automation/components/canvas/buildCanvasGraph.ts","../../src/features/email-automation/components/canvas/edges/DelayEdge.tsx","../../src/features/email-automation/components/canvas/EmailAutomationCanvasInspector.tsx","../../src/features/email-automation/components/forms/EmailStepEditor.tsx","../../src/features/email-automation/components/canvas/nodes/EmailStepNode.tsx","../../src/features/email-automation/components/canvas/nodes/TriggerNode.tsx","../../src/features/email-automation/components/lists/EmailAutomationRecipientsList.tsx","../../src/features/email-automation/components/unsubscribe/EmailUnsubscribe.tsx","../../src/features/email-automation/hooks/useEmailAutomationTableStructure.tsx","../../src/features/email-automation/hooks/useEmailAutomationEnrollmentTableStructure.tsx"],"sourcesContent":["\"use client\";\n\nimport { useTranslations } from \"next-intl\";\nimport { RoundPageContainer } from \"../../../../components\";\nimport { SharedProvider } from \"../../../../contexts/SharedContext\";\nimport { Modules } from \"../../../../core\";\nimport { BreadcrumbItemData } from \"../../../../interfaces\";\nimport { EmailAutomationsList } from \"../lists/EmailAutomationsList\";\n\n/**\n * Page container for the administrative email-automation list.\n *\n * Client component by necessity: `module={Modules.EmailAutomation}` is a\n * registry entry carrying an icon component and methods, which a Server\n * Component cannot pass across the boundary. Routes mount this container\n * instead — the same shape as every other list page.\n *\n * No `forceHeader`: ContentListTable draws its own header row with the title\n * and the create action, exactly as the company and user list pages do.\n *\n * Publishes its own breadcrumb, as CompanyProvider does for the companies list:\n * the list root comes first and has no href because it is the current page.\n */\nexport function EmailAutomationsListContainer() {\n const t = useTranslations();\n\n const breadcrumbs: BreadcrumbItemData[] = [{ name: t(\"emailAutomations.admin.title\") }];\n\n return (\n <SharedProvider value={{ breadcrumbs, title: { type: t(\"emailAutomations.admin.title\") } }}>\n <RoundPageContainer module={Modules.EmailAutomation} fullWidth>\n <EmailAutomationsList fullWidth />\n </RoundPageContainer>\n </SharedProvider>\n );\n}\n","\"use client\";\n\nimport { MailIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useEffect, useMemo, useState } from \"react\";\nimport { ContentListTable } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { DataListRetriever, useDataListRetriever } from \"../../../../hooks\";\nimport { EmptyState } from \"../../../../shadcnui\";\nimport { EmailAutomationFields } from \"../../data/email-automation.fields\";\nimport { EmailAutomationInterface } from \"../../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\nimport { EmailAutomationTriggerInterface } from \"../../data/EmailAutomationTriggerInterface\";\nimport EmailAutomationEditor from \"../forms/EmailAutomationEditor\";\n\ntype EmailAutomationsListProps = {\n /**\n * Pass this whenever the list is the page's own content inside a\n * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in\n * `rounded-md border`, drawing a second bordered card inside the page's\n * rounded shell.\n */\n fullWidth?: boolean;\n};\n\nexport function EmailAutomationsList({ fullWidth }: EmailAutomationsListProps = {}) {\n const t = useTranslations();\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n\n const data: DataListRetriever<EmailAutomationInterface> = useDataListRetriever({\n retriever: (params) => EmailAutomationService.findMany(params),\n retrieverParams: {},\n module: Modules.EmailAutomation,\n });\n\n // The trigger column shows the label the app declares, not the stored key.\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const triggerLabels = useMemo(\n () => Object.fromEntries(triggers.map((trigger) => [trigger.key, trigger.label])),\n [triggers],\n );\n\n const functions: ReactNode[] = [<EmailAutomationEditor key=\"create-email-automation\" />];\n\n return (\n <ContentListTable\n data={data}\n fields={[\n EmailAutomationFields.name,\n EmailAutomationFields.trigger,\n EmailAutomationFields.status,\n EmailAutomationFields.steps,\n EmailAutomationFields.active,\n EmailAutomationFields.completed,\n EmailAutomationFields.unsubscribed,\n ]}\n tableGeneratorType={Modules.EmailAutomation}\n functions={functions}\n fullWidth={fullWidth}\n title={t(\"emailAutomations.admin.title\")}\n context={{ triggerLabels }}\n emptyState={<EmptyState icon={MailIcon} title={t(\"emailAutomations.admin.empty\")} />}\n />\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { EditorSheet, FormInput, FormSelect, FormSwitch } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { useI18nRouter } from \"../../../../i18n\";\nimport { EmailAutomationInput, EmailAutomationInterface } from \"../../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\nimport { EmailAutomationTriggerInterface } from \"../../data/EmailAutomationTriggerInterface\";\n\nexport type EmailAutomationEditorProps = {\n automation?: EmailAutomationInterface;\n propagateChanges?: (automation: EmailAutomationInterface) => void;\n onSuccess?: () => void | Promise<void>;\n trigger?: ReactNode;\n forceShow?: boolean;\n onClose?: () => void;\n dialogOpen?: boolean;\n onDialogOpenChange?: (open: boolean) => void;\n};\n\nfunction EmailAutomationEditorInternal({\n automation,\n propagateChanges,\n onSuccess,\n trigger,\n forceShow,\n onClose,\n dialogOpen,\n onDialogOpenChange,\n}: EmailAutomationEditorProps) {\n const t = useTranslations();\n const router = useI18nRouter();\n const isEdit = !!automation;\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n\n // Trigger labels are plain strings from the app config, not i18n keys.\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const triggerValues = useMemo(() => triggers.map((entry) => ({ id: entry.key, text: entry.label })), [triggers]);\n\n const formSchema = useMemo(\n () =>\n z.object({\n id: z.uuidv4(),\n name: z.string().min(1, { message: t(\"emailAutomations.fields.name.error\") }),\n trigger: z.string().optional(),\n exitTrigger: z.string().optional(),\n replyTo: z.string().refine((value) => value === \"\" || z.email().safeParse(value).success, {\n message: t(\"emailAutomations.fields.replyTo.error\"),\n }),\n isActive: z.boolean(),\n }),\n [t],\n );\n\n const getDefaultValues = useCallback(\n () => ({\n id: automation?.id ?? v4(),\n name: automation?.name ?? \"\",\n trigger: automation?.trigger ?? \"\",\n exitTrigger: automation?.exitTrigger ?? \"\",\n replyTo: automation?.replyTo ?? \"\",\n isActive: automation?.isActive ?? false,\n }),\n [automation],\n );\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: getDefaultValues(),\n });\n\n return (\n <EditorSheet\n form={form}\n entityType={t(\"emailAutomations.admin.title\")}\n entityName={automation?.name}\n title={isEdit ? t(\"emailAutomations.admin.editAutomation\") : t(\"emailAutomations.admin.newAutomation\")}\n isEdit={isEdit}\n module={Modules.EmailAutomation}\n size=\"md\"\n propagateChanges={propagateChanges}\n onSuccess={onSuccess}\n onNavigate={(url) => router.push(url)}\n onSubmit={async (values) => {\n const payload: EmailAutomationInput = {\n id: values.id,\n name: values.name,\n trigger: values.trigger || undefined,\n exitTrigger: values.exitTrigger || undefined,\n replyTo: values.replyTo || undefined,\n isActive: values.isActive,\n };\n return isEdit ? await EmailAutomationService.update(payload) : await EmailAutomationService.create(payload);\n }}\n onReset={getDefaultValues}\n trigger={trigger}\n forceShow={forceShow}\n onClose={onClose}\n dialogOpen={dialogOpen}\n onDialogOpenChange={onDialogOpenChange}\n >\n <div className=\"flex w-full flex-col gap-y-4\">\n <FormInput form={form} id=\"name\" name={t(\"emailAutomations.fields.name.label\")} isRequired />\n <FormSelect\n form={form}\n id=\"trigger\"\n name={t(\"emailAutomations.fields.trigger.label\")}\n placeholder={t(\"emailAutomations.fields.trigger.none\")}\n values={triggerValues}\n allowEmpty\n />\n <FormSelect\n form={form}\n id=\"exitTrigger\"\n name={t(\"emailAutomations.fields.exitTrigger.label\")}\n placeholder={t(\"emailAutomations.fields.trigger.none\")}\n values={triggerValues}\n allowEmpty\n />\n <FormInput form={form} id=\"replyTo\" name={t(\"emailAutomations.fields.replyTo.label\")} />\n <FormSwitch\n form={form}\n id=\"isActive\"\n name={t(\"emailAutomations.fields.isActive.label\")}\n description={t(\"emailAutomations.fields.isActive.help\")}\n />\n </div>\n </EditorSheet>\n );\n}\n\nexport function EmailAutomationEditor(props: EmailAutomationEditorProps) {\n return <EmailAutomationEditorInternal {...props} />;\n}\n\nexport default EmailAutomationEditor;\n","\"use client\";\n\nimport { useTranslations } from \"next-intl\";\nimport { RoundPageContainer } from \"../../../../components\";\nimport { SharedProvider } from \"../../../../contexts/SharedContext\";\nimport { Modules } from \"../../../../core\";\nimport { usePageUrlGenerator } from \"../../../../hooks\";\nimport { BreadcrumbItemData } from \"../../../../interfaces\";\nimport { EmailAutomationProvider, useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationActiveSwitch } from \"../canvas/EmailAutomationActiveSwitch\";\nimport { EmailAutomationCanvasTab } from \"../canvas/EmailAutomationCanvasTab\";\nimport { EmailAutomationEditor } from \"../forms/EmailAutomationEditor\";\nimport { EmailAutomationRecipientsList } from \"../lists/EmailAutomationRecipientsList\";\n\nexport type EmailAutomationContainerProps = {\n automationId: string;\n};\n\nexport function EmailAutomationContainer({ automationId }: EmailAutomationContainerProps) {\n return (\n <EmailAutomationProvider automationId={automationId}>\n <EmailAutomationShell />\n </EmailAutomationProvider>\n );\n}\n\nfunction EmailAutomationShell() {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const { automation, reload } = useEmailAutomation();\n\n if (!automation) return null;\n\n const breadcrumbs: BreadcrumbItemData[] = [\n { name: t(\"emailAutomations.admin.title\"), href: generateUrl({ page: Modules.EmailAutomation }) },\n { name: automation.name },\n ];\n\n // The page chrome (title + header functions) is published here rather than by\n // AdministrationProvider: SharedProvider replaces its value for the subtree,\n // so this one carries the administration title type plus the automation name.\n return (\n <SharedProvider\n value={{\n breadcrumbs,\n title: {\n type: t(\"emailAutomations.admin.title\"),\n element: automation.name,\n functions: [\n <EmailAutomationActiveSwitch key=\"emailAutomationActiveSwitch\" />,\n <EmailAutomationEditor key=\"emailAutomationEditor\" automation={automation} onSuccess={reload} />,\n ],\n },\n }}\n >\n <RoundPageContainer\n module={Modules.EmailAutomation}\n id={automation.id}\n fullWidth\n forceHeader\n // The canvas is sized h-full: it needs the viewport-bound shell and a\n // fillHeight tab, or it resolves to zero height.\n scroll=\"fixed\"\n tabs={[\n {\n sectionKey: \"canvas\",\n label: t(\"emailAutomations.tabs.canvas\"),\n content: <EmailAutomationCanvasTab />,\n fillHeight: true,\n },\n {\n sectionKey: \"recipients\",\n label: t(\"emailAutomations.tabs.recipients\"),\n content: <EmailAutomationRecipientsList />,\n },\n ]}\n />\n </SharedProvider>\n );\n}\n","\"use client\";\n\nimport { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useState } from \"react\";\nimport { v4 } from \"uuid\";\nimport { EmailAutomationInterface } from \"../data/EmailAutomationInterface\";\nimport { EmailAutomationService } from \"../data/EmailAutomationService\";\nimport { EmailAutomationStepInput, EmailAutomationStepInterface } from \"../data/EmailAutomationStepInterface\";\nimport { EmailAutomationStepService } from \"../data/EmailAutomationStepService\";\nimport { EmailAutomationTriggerInterface } from \"../data/EmailAutomationTriggerInterface\";\n\n/** A new step: the provider always sets `automationId` and, when absent, a fresh `id`. */\nexport type EmailAutomationStepCreateInput = Omit<EmailAutomationStepInput, \"id\" | \"automationId\"> & {\n id?: string;\n automationId?: string;\n};\n/** A step update: the provider always sets `automationId`. */\nexport type EmailAutomationStepUpdateInput = Omit<EmailAutomationStepInput, \"automationId\"> & { automationId?: string };\n\nexport interface EmailAutomationContextType {\n automation: EmailAutomationInterface | undefined;\n steps: EmailAutomationStepInterface[];\n reload: () => Promise<void>;\n selectedStepId: string | null;\n select: (id: string | null) => void;\n createStep: (input: EmailAutomationStepCreateInput) => Promise<EmailAutomationStepInterface>;\n updateStep: (input: EmailAutomationStepUpdateInput) => Promise<EmailAutomationStepInterface>;\n deleteStep: (id: string) => Promise<void>;\n setNext: (stepId: string, nextStepId: string | null) => Promise<void>;\n updatePosition: (stepId: string, x: number, y: number) => Promise<void>;\n tidy: () => Promise<void>;\n triggers: EmailAutomationTriggerInterface[];\n}\n\nconst EmailAutomationContext = createContext<EmailAutomationContextType | undefined>(undefined);\n\nexport type EmailAutomationProviderProps = {\n automationId: string;\n children: ReactNode;\n};\n\nexport const EmailAutomationProvider = ({ automationId, children }: EmailAutomationProviderProps) => {\n const [automation, setAutomation] = useState<EmailAutomationInterface | undefined>(undefined);\n const [steps, setSteps] = useState<EmailAutomationStepInterface[]>([]);\n const [triggers, setTriggers] = useState<EmailAutomationTriggerInterface[]>([]);\n const [selectedStepId, setSelectedStepId] = useState<string | null>(null);\n\n const reload = useCallback(async () => {\n const [loadedAutomation, loadedSteps] = await Promise.all([\n EmailAutomationService.findOne({ id: automationId }),\n EmailAutomationStepService.findByAutomation({ automationId }),\n ]);\n setAutomation(loadedAutomation);\n setSteps(loadedSteps);\n }, [automationId]);\n\n useEffect(() => {\n void reload();\n }, [reload]);\n\n useEffect(() => {\n let active = true;\n EmailAutomationService.findTriggers()\n .then((list) => {\n if (active) setTriggers(list);\n })\n .catch(() => {});\n return () => {\n active = false;\n };\n }, []);\n\n const select = useCallback((id: string | null) => setSelectedStepId(id), []);\n\n const createStep = useCallback(\n async (input: EmailAutomationStepCreateInput) => {\n const saved = await EmailAutomationStepService.create({ ...input, id: input.id ?? v4(), automationId });\n await reload();\n return saved;\n },\n [automationId, reload],\n );\n\n const updateStep = useCallback(\n async (input: EmailAutomationStepUpdateInput) => {\n const saved = await EmailAutomationStepService.update({ ...input, automationId });\n await reload();\n return saved;\n },\n [automationId, reload],\n );\n\n const deleteStep = useCallback(\n async (id: string) => {\n await EmailAutomationStepService.delete({ id });\n if (selectedStepId === id) setSelectedStepId(null);\n await reload();\n },\n [reload, selectedStepId],\n );\n\n const setNext = useCallback(\n async (stepId: string, nextStepId: string | null) => {\n if (nextStepId) await EmailAutomationStepService.setNext({ stepId, nextStepId });\n else await EmailAutomationStepService.clearNext({ stepId });\n await reload();\n },\n [reload],\n );\n\n // PATCH with the step's current attributes plus the new position: the step\n // input type requires subject and body, and sending them unchanged is a no-op.\n const updatePosition = useCallback(\n async (stepId: string, x: number, y: number) => {\n const step = steps.find((candidate) => candidate.id === stepId);\n if (!step) return;\n await EmailAutomationStepService.update({\n id: step.id,\n automationId,\n subject: step.subject,\n body: step.body,\n delayHours: step.delayHours,\n positionX: x,\n positionY: y,\n });\n await reload();\n },\n [automationId, reload, steps],\n );\n\n const tidy = useCallback(async () => {\n await EmailAutomationService.tidy({ id: automationId });\n await reload();\n }, [automationId, reload]);\n\n const value = useMemo<EmailAutomationContextType>(\n () => ({\n automation,\n steps,\n reload,\n selectedStepId,\n select,\n createStep,\n updateStep,\n deleteStep,\n setNext,\n updatePosition,\n tidy,\n triggers,\n }),\n [\n automation,\n steps,\n reload,\n selectedStepId,\n select,\n createStep,\n updateStep,\n deleteStep,\n setNext,\n updatePosition,\n tidy,\n triggers,\n ],\n );\n\n return <EmailAutomationContext.Provider value={value}>{children}</EmailAutomationContext.Provider>;\n};\n\nexport const useEmailAutomation = (): EmailAutomationContextType => {\n const context = useContext(EmailAutomationContext);\n if (context === undefined) {\n throw new Error(\"useEmailAutomation must be used within an EmailAutomationProvider\");\n }\n return context;\n};\n","\"use client\";\n\nimport { useTranslations } from \"next-intl\";\nimport { useState } from \"react\";\nimport { errorToast } from \"../../../../components\";\nimport { Switch, Tooltip, TooltipContent, TooltipTrigger } from \"../../../../shadcnui\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\n\n/**\n * Inline on/off for the automation page header, so pausing never needs the\n * editor sheet. Off holds every enrolment in place (spec § \"Sending\" 3).\n */\nexport function EmailAutomationActiveSwitch() {\n const t = useTranslations();\n const { automation, reload } = useEmailAutomation();\n const [saving, setSaving] = useState<boolean>(false);\n\n if (!automation) return null;\n\n const toggle = async (checked: boolean) => {\n setSaving(true);\n try {\n await EmailAutomationService.update({\n id: automation.id,\n name: automation.name,\n trigger: automation.trigger,\n exitTrigger: automation.exitTrigger,\n replyTo: automation.replyTo,\n isActive: checked,\n });\n await reload();\n } catch (error) {\n errorToast({ title: t(\"common.errors.error\"), error });\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Tooltip>\n <TooltipTrigger render={<label className=\"flex items-center gap-x-2\" />}>\n <Switch checked={automation.isActive} onCheckedChange={(checked) => void toggle(checked)} disabled={saving} />\n <span className=\"text-xs\">{t(\"emailAutomations.fields.isActive.label\")}</span>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-xs\">{t(\"emailAutomations.fields.isActive.help\")}</TooltipContent>\n </Tooltip>\n );\n}\n","\"use client\";\n\nimport { ReactFlowProvider } from \"@xyflow/react\";\nimport { useEffect } from \"react\";\nimport { useSidebar } from \"../../../../shadcnui\";\nimport { EmailAutomationCanvas } from \"./EmailAutomationCanvas\";\n\nexport function EmailAutomationCanvasTab() {\n const { open, setOpen } = useSidebar();\n\n // Performance mode: collapse the app sidebar on mount; restore on unmount.\n // Mirrors the app's ScenarioCanvasPage shell.\n useEffect(() => {\n const prev = open;\n if (prev) setOpen(false);\n return () => {\n if (prev) setOpen(true);\n };\n }, []);\n\n return (\n <main className=\"flex h-full w-full overflow-hidden\">\n {/* The canvas column keeps `relative` so CanvasToolbar's absolute\n positioning anchors to the canvas, not to the whole row. */}\n <div className=\"relative h-full min-w-0 flex-1\">\n <ReactFlowProvider>\n <EmailAutomationCanvas />\n </ReactFlowProvider>\n </div>\n </main>\n );\n}\n","\"use client\";\n\nimport {\n Background,\n Connection,\n Edge,\n EdgeChange,\n FinalConnectionState,\n Node,\n NodeChange,\n OnConnectStart,\n OnNodeDrag,\n ReactFlow,\n applyEdgeChanges,\n applyNodeChanges,\n useReactFlow,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport { PlusIcon, Trash2Icon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { errorToast } from \"../../../../components/errors\";\nimport { ConfirmDialog, ContextMenu, ContextMenuContent, ContextMenuItem } from \"../../../../shadcnui\";\nimport { useIsMobile } from \"../../../../utils/use-mobile\";\nimport { showError } from \"../../../../utils/toast\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationEditor } from \"../forms/EmailAutomationEditor\";\nimport {\n STEP_NODE_HEIGHT,\n STEP_NODE_PREFIX,\n STEP_NODE_WIDTH,\n STEP_SOURCE_HANDLE_PREFIX,\n STEP_TARGET_HANDLE_PREFIX,\n TRIGGER_NODE_ID,\n TRIGGER_SOURCE_HANDLE,\n buildCanvasGraph,\n} from \"./buildCanvasGraph\";\nimport { DelayEdge } from \"./edges/DelayEdge\";\nimport { EmailAutomationCanvasInspector, useUserClosedGuard } from \"./EmailAutomationCanvasInspector\";\nimport { EmailStepNode } from \"./nodes/EmailStepNode\";\nimport { TriggerNode } from \"./nodes/TriggerNode\";\nimport { CanvasToolbar, EmptyCanvas, createLongPressTracker } from \"./shared\";\n\nconst DEFAULT_DELAY_HOURS = 24;\n\ntype PendingPaneMenu = {\n flowX: number;\n flowY: number;\n screenX: number;\n screenY: number;\n};\n\ntype PendingNodeMenu = {\n stepId: string;\n screenX: number;\n screenY: number;\n};\n\nconst pointAnchor = (screenX: number, screenY: number) => ({\n getBoundingClientRect: () =>\n ({\n x: screenX,\n y: screenY,\n top: screenY,\n left: screenX,\n right: screenX,\n bottom: screenY,\n width: 0,\n height: 0,\n toJSON: () => ({}),\n }) as DOMRect,\n});\n\nconst stepIdOf = (nodeId: string | null | undefined): string | null =>\n nodeId?.startsWith(STEP_NODE_PREFIX) ? nodeId.slice(STEP_NODE_PREFIX.length) : null;\n\nexport function EmailAutomationCanvas() {\n const { automation, steps, triggers, select, reload, createStep, deleteStep, setNext, updatePosition, tidy } =\n useEmailAutomation();\n const t = useTranslations();\n // Phone-only: a looser zoom-out floor so \"Fit to view\" can show the whole\n // graph. Desktop keeps React Flow's defaults untouched.\n const isMobile = useIsMobile();\n\n const [nodes, setNodes] = useState<Node[]>([]);\n const [edges, setEdges] = useState<Edge[]>([]);\n const { screenToFlowPosition } = useReactFlow();\n const connectingFromRef = useRef<{ nodeId: string | null; handleId: string | null } | null>(null);\n const [paneMenu, setPaneMenu] = useState<PendingPaneMenu | null>(null);\n const [nodeMenu, setNodeMenu] = useState<PendingNodeMenu | null>(null);\n const [pendingDeleteStepId, setPendingDeleteStepId] = useState<string | null>(null);\n const [automationEditorOpen, setAutomationEditorOpen] = useState<boolean>(false);\n\n const triggerLabel = useMemo(\n () =>\n triggers.find((trigger) => trigger.key === automation?.trigger)?.label ?? t(\"emailAutomations.canvas.noTrigger\"),\n [triggers, automation?.trigger, t],\n );\n\n const { laidNodes, laidEdges } = useMemo(() => {\n const graph = buildCanvasGraph(steps, triggerLabel);\n return { laidNodes: graph.nodes, laidEdges: graph.edges };\n }, [steps, triggerLabel]);\n\n useEffect(() => {\n setNodes(laidNodes);\n setEdges(laidEdges);\n }, [laidNodes, laidEdges]);\n\n const onNodesChange = useCallback((changes: NodeChange[]) => setNodes((nds) => applyNodeChanges(changes, nds)), []);\n const onEdgesChange = useCallback((changes: EdgeChange[]) => setEdges((eds) => applyEdgeChanges(changes, eds)), []);\n\n // The trigger has no stored position: only steps are persisted.\n const onNodeDragStop: OnNodeDrag = useCallback(\n (_e, node) => {\n const stepId = stepIdOf(node.id);\n if (!stepId) return;\n void updatePosition(stepId, node.position.x, node.position.y);\n },\n [updatePosition],\n );\n\n const onConnectStart: OnConnectStart = useCallback((_e, params) => {\n connectingFromRef.current = { nodeId: params.nodeId ?? null, handleId: params.handleId ?? null };\n }, []);\n\n /** A rejected link (self-link, loop, step already linked) reloads the true chain. */\n const linkSteps = useCallback(\n async (stepId: string, nextStepId: string) => {\n try {\n await setNext(stepId, nextStepId);\n } catch (error) {\n errorToast({ title: t(\"emailAutomations.canvas.chainError\"), error });\n await reload();\n }\n },\n [setNext, reload, t],\n );\n\n // onConnect fires only when React Flow finds a valid target handle.\n const onConnect = useCallback(\n async (conn: Connection) => {\n const from = connectingFromRef.current;\n connectingFromRef.current = null;\n if (!from || !from.handleId) return;\n if (!conn.targetHandle?.startsWith(STEP_TARGET_HANDLE_PREFIX)) return;\n const targetStepId = conn.targetHandle.slice(STEP_TARGET_HANDLE_PREFIX.length);\n\n // The trigger→head link is not stored: the API derives the head as the\n // oldest step with no incoming NEXT. A drag from the trigger onto a step\n // therefore cannot be saved, so it is refused with the chain error and\n // nothing changes.\n if (from.handleId === TRIGGER_SOURCE_HANDLE) {\n showError(t(\"emailAutomations.canvas.chainError\"));\n return;\n }\n\n if (!from.handleId.startsWith(STEP_SOURCE_HANDLE_PREFIX)) return;\n const sourceStepId = from.handleId.slice(STEP_SOURCE_HANDLE_PREFIX.length);\n await linkSteps(sourceStepId, targetStepId);\n },\n [linkSteps, t],\n );\n\n /** Creates a step centred on a flow point and returns its id. */\n const createStepAt = useCallback(\n async (flowX: number, flowY: number): Promise<string | null> => {\n if (!automation) return null;\n const id = uuidv4();\n await createStep({\n id,\n automationId: automation.id,\n subject: t(\"emailAutomations.step.title\"),\n body: \"\",\n delayHours: DEFAULT_DELAY_HOURS,\n positionX: flowX - STEP_NODE_WIDTH / 2,\n positionY: flowY - STEP_NODE_HEIGHT / 2,\n });\n return id;\n },\n [automation, createStep, t],\n );\n\n // onConnectEnd fires for EVERY drag end. If onConnect already cleared the\n // ref, it handled the case. Otherwise a drop on empty canvas creates a new\n // step there: from a step it is linked as that step's next; from the\n // trigger it is simply the first step when none existed, otherwise an\n // orphan (the trigger→head link is derived, never stored).\n const onConnectEnd = useCallback(\n async (event: MouseEvent | TouchEvent, connectionState: FinalConnectionState) => {\n const from = connectingFromRef.current;\n if (!from || !from.handleId || !automation) return;\n connectingFromRef.current = null;\n // Dropped on a node but not on its handle: not an empty-canvas drop.\n if (connectionState.toNode) return;\n\n const clientX =\n \"clientX\" in event ? (event as MouseEvent).clientX : ((event as TouchEvent).changedTouches[0]?.clientX ?? 0);\n const clientY =\n \"clientY\" in event ? (event as MouseEvent).clientY : ((event as TouchEvent).changedTouches[0]?.clientY ?? 0);\n const flowPos = screenToFlowPosition({ x: clientX, y: clientY });\n\n const sourceStepId = from.handleId.startsWith(STEP_SOURCE_HANDLE_PREFIX)\n ? from.handleId.slice(STEP_SOURCE_HANDLE_PREFIX.length)\n : null;\n if (!sourceStepId && from.handleId !== TRIGGER_SOURCE_HANDLE) return;\n\n const newStepId = await createStepAt(flowPos.x, flowPos.y);\n if (!newStepId) return;\n if (sourceStepId) await linkSteps(sourceStepId, newStepId);\n select(newStepId);\n },\n [automation, screenToFlowPosition, createStepAt, linkSteps, select],\n );\n\n // --- Pane context menu ---\n\n const handlePaneContextMenu = useCallback(\n (event: React.MouseEvent | MouseEvent) => {\n if (!automation) return;\n event.preventDefault();\n const clientX = (event as MouseEvent).clientX;\n const clientY = (event as MouseEvent).clientY;\n const flowPos = screenToFlowPosition({ x: clientX, y: clientY });\n setPaneMenu({\n flowX: flowPos.x,\n flowY: flowPos.y,\n screenX: clientX,\n screenY: clientY,\n });\n },\n [automation, screenToFlowPosition],\n );\n\n const handleCreateStepFromPane = useCallback(async () => {\n const menu = paneMenu;\n if (!menu) return;\n setPaneMenu(null);\n const newStepId = await createStepAt(menu.flowX, menu.flowY);\n if (newStepId) select(newStepId);\n }, [paneMenu, createStepAt, select]);\n\n // --- Node context menu ---\n //\n // Rendered through the same portal-based ContextMenu + fixed-anchor\n // technique as the pane menu: Base UI menus do NOT work when mounted inside\n // a React Flow node, so the menu lives outside the canvas and is anchored\n // to the click coordinates. The trigger node has no menu.\n const openNodeMenu = useCallback((nodeId: string | undefined, screenX: number, screenY: number) => {\n const stepId = stepIdOf(nodeId);\n if (!stepId) return;\n setNodeMenu({ stepId, screenX, screenY });\n }, []);\n\n const handleNodeContextMenu = useCallback(\n (event: React.MouseEvent, node: Node) => {\n event.preventDefault();\n openNodeMenu(node.id, event.clientX, event.clientY);\n },\n [openNodeMenu],\n );\n\n // --- Touch: long-press a node opens the same node menu ---\n //\n // Touch screens have no right-click. A ~500ms finger hold on a step node\n // opens the menu at the finger; moving the finger (pan / node drag) cancels\n // it, and the click produced by lifting the finger is swallowed so the hold\n // does not also open the step editor.\n const openNodeMenuRef = useRef(openNodeMenu);\n openNodeMenuRef.current = openNodeMenu;\n const longPress = useMemo(\n () =>\n createLongPressTracker({\n onLongPress: ({ target, clientX, clientY }) => {\n openNodeMenuRef.current(target, clientX, clientY);\n },\n }),\n [],\n );\n useEffect(() => () => longPress.cancel(), [longPress]);\n\n const handleTouchPointerDown = useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType !== \"touch\") return;\n const el = event.target as Element | null;\n // A press on a connection handle starts a link drag, never a menu.\n if (!el || el.closest(\".react-flow__handle\")) return;\n const nodeId = el.closest(\".react-flow__node\")?.getAttribute(\"data-id\");\n if (!stepIdOf(nodeId)) return;\n longPress.down(nodeId!, event.clientX, event.clientY);\n },\n [longPress],\n );\n\n const handleNodeClick = useCallback(\n (_event: React.MouseEvent, node: Node) => {\n if (node.id === TRIGGER_NODE_ID) {\n setAutomationEditorOpen(true);\n return;\n }\n const stepId = stepIdOf(node.id);\n if (stepId) select(stepId);\n },\n [select],\n );\n\n const handleDeleteStep = useCallback(async () => {\n const stepId = pendingDeleteStepId;\n if (!stepId) return;\n try {\n await deleteStep(stepId);\n } catch (error) {\n errorToast({ title: t(\"emailAutomations.canvas.deleteEmail\"), error });\n throw error; // keeps the dialog open — ConfirmDialog swallows rejections\n }\n }, [pendingDeleteStepId, deleteStep, t]);\n\n const nodeTypes = useMemo(() => ({ triggerNode: TriggerNode, emailStepNode: EmailStepNode }), []);\n const edgeTypes = useMemo(() => ({ delayEdge: DelayEdge }), []);\n\n return (\n <>\n <ReactFlow\n nodes={nodes}\n edges={edges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnectStart={onConnectStart}\n onConnect={onConnect}\n onConnectEnd={onConnectEnd}\n onPaneContextMenu={handlePaneContextMenu}\n onNodeContextMenu={handleNodeContextMenu}\n onNodeClick={handleNodeClick}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\n // Built-in React Flow click handler — independent of EdgeLabelRenderer\n // pointer-events. The label button calls `select` too; either path\n // produces the same selection state.\n onEdgeClick={(_event, edge) => {\n const targetStepId = (edge.data as { targetStepId?: string } | undefined)?.targetStepId;\n if (targetStepId) select(targetStepId);\n }}\n fitView\n // Never zoom past 100% on fit: with no emails the trigger is the only\n // node, and the default ceiling (2x) blows it up over the empty state.\n fitViewOptions={{ maxZoom: 1 }}\n // React Flow's default floor is 0.5, which on a phone stops \"Fit to\n // view\" before the graph fits. undefined keeps the desktop default.\n minZoom={isMobile ? 0.15 : undefined}\n onPointerDownCapture={handleTouchPointerDown}\n onPointerMoveCapture={(event) => {\n if (event.pointerType === \"touch\") longPress.move(event.clientX, event.clientY);\n }}\n onPointerUpCapture={() => longPress.up()}\n onPointerCancelCapture={() => longPress.cancel()}\n onClickCapture={(event) => {\n if (!longPress.consumeClick()) return;\n event.preventDefault();\n event.stopPropagation();\n }}\n proOptions={{ hideAttribution: true }}\n >\n <Background gap={16} size={1} />\n </ReactFlow>\n {steps.length === 0 && (\n // The canvas stays mounted under the empty state: the first email is\n // added by right-clicking it or dragging from the trigger.\n // Lower half only, so the text sits below the centred trigger node.\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 h-1/2\">\n <EmptyCanvas>\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">{t(\"emailAutomations.canvas.emptyTitle\")}</span>\n <span className=\"text-xs/relaxed\">{t(\"emailAutomations.canvas.emptyBody\")}</span>\n </div>\n </EmptyCanvas>\n </div>\n )}\n <CanvasToolbar onTidy={tidy} />\n <EmailAutomationCanvasInspector />\n {automationEditorOpen && automation && (\n <TriggerAutomationEditor\n automation={automation}\n onSaved={reload}\n onClose={() => setAutomationEditorOpen(false)}\n />\n )}\n <ConfirmDialog\n open={pendingDeleteStepId !== null}\n onOpenChange={(open) => {\n if (!open) setPendingDeleteStepId(null);\n }}\n title={t(\"emailAutomations.canvas.deleteEmail\")}\n description={t(\"emailAutomations.canvas.deleteEmailConfirm\")}\n confirmLabel={t(\"emailAutomations.canvas.deleteEmail\")}\n cancelLabel={t(\"ui.buttons.cancel\")}\n destructive\n onConfirm={handleDeleteStep}\n />\n {paneMenu && (\n <ContextMenu\n open={true}\n onOpenChange={(open) => {\n if (!open) setPaneMenu(null);\n }}\n >\n <ContextMenuContent\n anchor={pointAnchor(paneMenu.screenX, paneMenu.screenY)}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n >\n <ContextMenuItem onClick={handleCreateStepFromPane}>\n <PlusIcon />\n {t(\"emailAutomations.canvas.addEmail\")}\n </ContextMenuItem>\n </ContextMenuContent>\n </ContextMenu>\n )}\n {nodeMenu && (\n <ContextMenu\n open={true}\n onOpenChange={(open) => {\n if (!open) setNodeMenu(null);\n }}\n >\n <ContextMenuContent\n anchor={pointAnchor(nodeMenu.screenX, nodeMenu.screenY)}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n >\n <ContextMenuItem\n onClick={() => {\n const menu = nodeMenu;\n setNodeMenu(null);\n if (menu) setPendingDeleteStepId(menu.stepId);\n }}\n >\n <Trash2Icon />\n {t(\"emailAutomations.canvas.deleteEmail\")}\n </ContextMenuItem>\n </ContextMenuContent>\n </ContextMenu>\n )}\n </>\n );\n}\n\n/**\n * The trigger node's click opens the automation's own EditorSheet, controlled\n * the same way the inspector controls the step editor.\n */\nfunction TriggerAutomationEditor(props: {\n automation: NonNullable<ReturnType<typeof useEmailAutomation>[\"automation\"]>;\n onSaved: () => Promise<void> | void;\n onClose: () => void;\n}) {\n const onDialogOpenChange = useUserClosedGuard(props.onClose);\n\n return (\n <EmailAutomationEditor\n automation={props.automation}\n forceShow\n dialogOpen\n onDialogOpenChange={onDialogOpenChange}\n onSuccess={async () => {\n await props.onSaved();\n props.onClose();\n }}\n />\n );\n}\n","\"use client\";\n\nimport { useReactFlow } from \"@xyflow/react\";\nimport { ListRestartIcon, MaximizeIcon, MinusIcon, PlusIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { Button } from \"../../../../../shadcnui\";\n\nexport function CanvasToolbar({ onTidy }: { onTidy: () => void | Promise<void> }) {\n const t = useTranslations();\n const { zoomIn, zoomOut, fitView } = useReactFlow();\n\n return (\n <div data-help=\"canvas.toolbar\" className=\"absolute end-2 top-2 z-10 flex flex-col gap-1 max-md:top-14\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoomIn()}\n aria-label={t(\"canvas.toolbar.zoomIn\")}\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoomOut()}\n aria-label={t(\"canvas.toolbar.zoomOut\")}\n >\n <MinusIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => fitView({ duration: 300 })}\n aria-label={t(\"canvas.toolbar.fitView\")}\n >\n <MaximizeIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => void onTidy()}\n title={t(\"canvas.toolbar.tidyTooltip\")}\n aria-label={t(\"canvas.toolbar.tidy\")}\n >\n <ListRestartIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nexport function EmptyCanvas({ children }: { children: ReactNode }) {\n return (\n <div className=\"text-muted-foreground flex h-full w-full items-center justify-center px-6 text-center text-sm\">\n {children}\n </div>\n );\n}\n","import dagre from \"dagre\";\n\nexport type LayoutNode = {\n id: string;\n /** node body dimensions in canvas px — used by dagre to allocate space */\n width: number;\n height: number;\n /** if true, dagre leaves position alone and uses these (x, y) verbatim */\n manuallyPositioned: boolean;\n x?: number;\n y?: number;\n};\n\nexport type LayoutEdge = {\n source: string;\n target: string;\n};\n\nexport type LayoutResult = Record<string, { x: number; y: number }>;\n\n/**\n * Deterministic LR layout. Pinned nodes keep their (x, y). Unpinned nodes\n * are laid out by dagre and returned in the result map.\n */\nexport function autoLayout(nodes: LayoutNode[], edges: LayoutEdge[]): LayoutResult {\n const g = new dagre.graphlib.Graph();\n g.setGraph({ rankdir: \"LR\", nodesep: 60, ranksep: 100, marginx: 24, marginy: 24 });\n g.setDefaultEdgeLabel(() => ({}));\n\n for (const n of nodes) {\n g.setNode(n.id, { width: n.width, height: n.height });\n }\n for (const e of edges) {\n if (g.hasNode(e.source) && g.hasNode(e.target)) {\n g.setEdge(e.source, e.target);\n }\n }\n\n dagre.layout(g);\n\n const result: LayoutResult = {};\n for (const n of nodes) {\n if (n.manuallyPositioned && typeof n.x === \"number\" && typeof n.y === \"number\") {\n result[n.id] = { x: n.x, y: n.y };\n } else {\n const laid = g.node(n.id);\n // dagre returns center coords; React Flow expects top-left, so subtract half dims.\n result[n.id] = {\n x: laid.x - n.width / 2,\n y: laid.y - n.height / 2,\n };\n }\n }\n return result;\n}\n","export const LONG_PRESS_MS = 500;\nexport const LONG_PRESS_MOVE_TOLERANCE_PX = 10;\n\n/**\n * Touch long-press detector for canvas nodes. A finger held still for\n * LONG_PRESS_MS on a node fires `onLongPress` with the press point; any move\n * beyond the tolerance (a pan or a node drag), a lift or a cancel aborts it.\n * After a fired press, `consumeClick()` returns true once, so the caller can\n * swallow the click that the finger lift produces.\n */\nexport function createLongPressTracker(params: {\n onLongPress: (press: { target: string; clientX: number; clientY: number }) => void;\n delayMs?: number;\n moveTolerancePx?: number;\n setTimer?: (fn: () => void, ms: number) => unknown;\n clearTimer?: (handle: unknown) => void;\n}) {\n const delay = params.delayMs ?? LONG_PRESS_MS;\n const tolerance = params.moveTolerancePx ?? LONG_PRESS_MOVE_TOLERANCE_PX;\n const setTimer = params.setTimer ?? ((fn: () => void, ms: number) => setTimeout(fn, ms));\n const clearTimer = params.clearTimer ?? ((handle: unknown) => clearTimeout(handle as ReturnType<typeof setTimeout>));\n\n let timer: unknown = null;\n let start: { x: number; y: number } | null = null;\n let fired = false;\n\n const cancel = () => {\n if (timer !== null) clearTimer(timer);\n timer = null;\n start = null;\n };\n\n return {\n down(target: string, clientX: number, clientY: number) {\n cancel();\n fired = false;\n start = { x: clientX, y: clientY };\n timer = setTimer(() => {\n timer = null;\n start = null;\n fired = true;\n params.onLongPress({ target, clientX, clientY });\n }, delay);\n },\n move(clientX: number, clientY: number) {\n if (!start) return;\n if (Math.hypot(clientX - start.x, clientY - start.y) > tolerance) cancel();\n },\n up: cancel,\n cancel,\n consumeClick(): boolean {\n const wasFired = fired;\n fired = false;\n return wasFired;\n },\n };\n}\n","import type { Edge, Node } from \"@xyflow/react\";\nimport { autoLayout, LayoutEdge, LayoutNode } from \"./shared\";\n\nexport const TRIGGER_NODE_ID = \"trigger\";\nexport const TRIGGER_SOURCE_HANDLE = \"trigger-source\";\nexport const STEP_NODE_PREFIX = \"step:\";\nexport const STEP_SOURCE_HANDLE_PREFIX = \"step-source-\";\nexport const STEP_TARGET_HANDLE_PREFIX = \"step-target-\";\n\nexport const TRIGGER_NODE_WIDTH = 200;\nexport const TRIGGER_NODE_HEIGHT = 56;\nexport const STEP_NODE_WIDTH = 200;\nexport const STEP_NODE_HEIGHT = 72;\n\n/**\n * The fields the canvas reads from a step. `EmailAutomationStepInterface`\n * satisfies it structurally; the narrow shape keeps this function pure and\n * testable with plain objects.\n */\nexport type CanvasStep = {\n id: string;\n subject: string;\n delayHours: number;\n positionX?: number;\n positionY?: number;\n sentCount: number;\n next?: { id: string };\n};\n\nexport type TriggerNodeData = { label: string };\n\nexport type EmailStepNodeData = {\n stepId: string;\n subject: string;\n sentCount: number;\n orphan: boolean;\n manuallyPositioned: boolean;\n};\n\nexport type DelayEdgeData = { targetStepId: string; delayHours: number };\n\nexport type CanvasGraph = { nodes: Node[]; edges: Edge[]; orphanIds: string[] };\n\n/**\n * The head is the oldest step with no incoming NEXT, exactly as the API picks\n * it (`findHead`). `steps` arrive ordered by createdAt ASC from\n * `findByAutomation`, so the first step nobody points at is the head.\n */\nexport function findHeadStepId(steps: CanvasStep[]): string | null {\n const pointedAt = new Set(steps.map((s) => s.next?.id).filter((id): id is string => !!id));\n return steps.find((s) => !pointedAt.has(s.id))?.id ?? null;\n}\n\nconst stepNodeId = (stepId: string) => `${STEP_NODE_PREFIX}${stepId}`;\n\n/**\n * Turns the automation's steps into React Flow nodes and edges: the trigger\n * node, one node per step, a trigger→head edge, and one edge per NEXT link.\n * Steps not reachable from the head (walking next→next) are orphans: they\n * never send and render dashed.\n */\nexport function buildCanvasGraph(steps: CanvasStep[], triggerLabel: string): CanvasGraph {\n const byId = new Map(steps.map((s) => [s.id, s]));\n const headId = findHeadStepId(steps);\n\n const chain = new Set<string>();\n let cursor = headId ? byId.get(headId) : undefined;\n while (cursor && !chain.has(cursor.id)) {\n chain.add(cursor.id);\n cursor = cursor.next ? byId.get(cursor.next.id) : undefined;\n }\n const orphanIds = steps.filter((s) => !chain.has(s.id)).map((s) => s.id);\n\n const layoutNodes: LayoutNode[] = [\n { id: TRIGGER_NODE_ID, width: TRIGGER_NODE_WIDTH, height: TRIGGER_NODE_HEIGHT, manuallyPositioned: false },\n ...steps.map((s) => ({\n id: stepNodeId(s.id),\n width: STEP_NODE_WIDTH,\n height: STEP_NODE_HEIGHT,\n manuallyPositioned: typeof s.positionX === \"number\" && typeof s.positionY === \"number\",\n x: s.positionX,\n y: s.positionY,\n })),\n ];\n\n const edges: Edge[] = [];\n const layoutEdges: LayoutEdge[] = [];\n\n const pushEdge = (source: string, sourceHandle: string, target: CanvasStep) => {\n const data: DelayEdgeData = { targetStepId: target.id, delayHours: target.delayHours };\n edges.push({\n id: `next:${source}->${target.id}`,\n source,\n sourceHandle,\n target: stepNodeId(target.id),\n targetHandle: `${STEP_TARGET_HANDLE_PREFIX}${target.id}`,\n type: \"delayEdge\",\n label: `${target.delayHours}h`,\n data,\n });\n layoutEdges.push({ source, target: stepNodeId(target.id) });\n };\n\n const head = headId ? byId.get(headId) : undefined;\n if (head) pushEdge(TRIGGER_NODE_ID, TRIGGER_SOURCE_HANDLE, head);\n for (const s of steps) {\n const next = s.next ? byId.get(s.next.id) : undefined;\n if (next) pushEdge(stepNodeId(s.id), `${STEP_SOURCE_HANDLE_PREFIX}${s.id}`, next);\n }\n\n const positions = autoLayout(layoutNodes, layoutEdges);\n\n const nodes: Node[] = [\n {\n id: TRIGGER_NODE_ID,\n type: \"triggerNode\",\n position: positions[TRIGGER_NODE_ID],\n deletable: false,\n data: { data: { label: triggerLabel } satisfies TriggerNodeData },\n },\n ...steps.map((s) => {\n const id = stepNodeId(s.id);\n return {\n id,\n type: \"emailStepNode\",\n position: positions[id],\n data: {\n data: {\n stepId: s.id,\n subject: s.subject,\n sentCount: s.sentCount,\n orphan: !chain.has(s.id),\n manuallyPositioned: typeof s.positionX === \"number\" && typeof s.positionY === \"number\",\n } satisfies EmailStepNodeData,\n },\n } satisfies Node;\n }),\n ];\n\n return { nodes, edges, orphanIds };\n}\n","\"use client\";\n\nimport { BaseEdge, Edge, EdgeLabelRenderer, EdgeProps, getBezierPath } from \"@xyflow/react\";\nimport { useEmailAutomation } from \"../../../contexts/EmailAutomationContext\";\nimport { DelayEdgeData } from \"../buildCanvasGraph\";\n\ntype DelayEdgeType = Edge<DelayEdgeData>;\n\n/**\n * ClueEdge recipe: a bezier with a label chip at its midpoint. The chip shows\n * the target step's delay and opens that step's editor. It is a plain\n * <button>: Base UI popovers do not work inside the React Flow canvas.\n */\nexport function DelayEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n label,\n data,\n}: EdgeProps<DelayEdgeType>) {\n const { select } = useEmailAutomation();\n const [edgePath, labelX, labelY] = getBezierPath({\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n });\n\n const targetStepId = data?.targetStepId;\n\n return (\n <>\n <BaseEdge id={id} path={edgePath} className=\"stroke-foreground/60\" interactionWidth={24} />\n <EdgeLabelRenderer>\n {/* Inline position + pointer-events per React Flow docs: the label\n portal sets pointer-events:none, so the label sets it back to\n 'all' and carries `nodrag nopan nowheel` for event isolation. */}\n <div\n className=\"nodrag nopan nowheel\"\n style={{\n position: \"absolute\",\n transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,\n pointerEvents: \"all\",\n zIndex: 1000,\n }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className=\"nodrag nopan bg-background hover:bg-accent text-foreground border-border h-auto rounded border px-2 py-1 text-xs tabular-nums shadow-sm\"\n onClick={(e) => {\n e.stopPropagation();\n if (targetStepId) select(targetStepId);\n }}\n >\n {label}\n </button>\n </div>\n </EdgeLabelRenderer>\n </>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailStepEditor } from \"../forms/EmailStepEditor\";\nimport { findHeadStepId } from \"./buildCanvasGraph\";\n\n/**\n * Mounts EmailStepEditor (the EditorSheet the step uses everywhere) on top of\n * the canvas, driven by `selectedStepId` from EmailAutomationContext. Copy of\n * the app's ScenarioCanvasInspector with one branch.\n *\n * - We control open state via `forceShow + dialogOpen + onDialogOpenChange`.\n * - On `onSuccess` we reload the canvas.\n * - The step comes from the context's `steps` (already loaded for the\n * canvas), so there is no per-step fetch.\n */\nexport function EmailAutomationCanvasInspector() {\n const { automation, steps, selectedStepId, select, reload } = useEmailAutomation();\n\n const close = useCallback(() => select(null), [select]);\n const onSaved = useCallback(async () => {\n await reload();\n }, [reload]);\n\n const headStepId = useMemo(() => findHeadStepId(steps), [steps]);\n const step = useMemo(() => steps.find((s) => s.id === selectedStepId) ?? null, [steps, selectedStepId]);\n\n if (!automation || !selectedStepId || !step) return null;\n\n return (\n <StepEditor\n key={step.id}\n step={step}\n automationId={automation.id}\n isHead={step.id === headStepId}\n onSaved={onSaved}\n onClose={close}\n />\n );\n}\n\n/**\n * Build an `onDialogOpenChange` callback that ignores the editor's\n * initial `open=false` notification. `useEditorDialog` (the hook\n * inside every EditorSheet) initialises `open` to `false`, then in\n * an effect sets it to `dialogOpen` (true). The \"open=false\" effect\n * fires synchronously on mount and would otherwise wipe our canvas\n * selection before the editor ever paints.\n */\nexport function useUserClosedGuard(onClose: () => void) {\n const wasOpenRef = useRef(false);\n return useCallback(\n (open: boolean) => {\n if (open) {\n wasOpenRef.current = true;\n return;\n }\n // open === false; only treat as \"user closed\" once we've seen open=true.\n if (wasOpenRef.current) onClose();\n },\n [onClose],\n );\n}\n\nfunction StepEditor(props: {\n step: ReturnType<typeof useEmailAutomation>[\"steps\"][number];\n automationId: string;\n isHead: boolean;\n onSaved: () => Promise<void>;\n onClose: () => void;\n}) {\n const onDialogOpenChange = useUserClosedGuard(props.onClose);\n\n return (\n <EmailStepEditor\n step={props.step}\n automationId={props.automationId}\n isHead={props.isHead}\n forceShow\n dialogOpen\n onDialogOpenChange={onDialogOpenChange}\n onSuccess={async () => {\n await props.onSaved();\n props.onClose();\n }}\n />\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useTranslations } from \"next-intl\";\nimport { ReactNode, useCallback, useMemo } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { EditorSheet, FormInput, FormTextarea } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationStepInput, EmailAutomationStepInterface } from \"../../data/EmailAutomationStepInterface\";\nimport { EmailAutomationStepService } from \"../../data/EmailAutomationStepService\";\n\n/** The fixed variable set the renderer fills (spec § \"Rendering\"). */\nconst TEMPLATE_VARIABLES = [\"{{name}}\", \"{{email}}\", \"{{url}}\", \"{{unsubscribeUrl}}\", \"{{unsubscribeAllUrl}}\"];\n\nexport type EmailStepEditorProps = {\n step?: EmailAutomationStepInterface;\n automationId: string;\n /** Canvas position for a step created from the editor. */\n initialPosition?: { x: number; y: number };\n /** The head step's delay counts from entering the automation, not from a previous email. */\n isHead?: boolean;\n trigger?: ReactNode;\n forceShow?: boolean;\n onClose?: () => void;\n dialogOpen?: boolean;\n onDialogOpenChange?: (open: boolean) => void;\n onSuccess?: () => void | Promise<void>;\n};\n\nfunction EmailStepEditorInternal({\n step,\n automationId,\n initialPosition,\n isHead,\n trigger,\n forceShow,\n onClose,\n dialogOpen,\n onDialogOpenChange,\n onSuccess,\n}: EmailStepEditorProps) {\n const t = useTranslations();\n const { reload } = useEmailAutomation();\n const isEdit = !!step;\n\n const formSchema = useMemo(\n () =>\n z.object({\n id: z.uuidv4(),\n subject: z.string().min(1, { message: t(\"emailAutomations.step.fields.subject.error\") }),\n delayHours: z.number().int().min(0),\n body: z.string().min(1, { message: t(\"emailAutomations.step.fields.body.error\") }),\n }),\n [t],\n );\n\n const getDefaultValues = useCallback(\n () => ({\n id: step?.id ?? v4(),\n subject: step?.subject ?? \"\",\n delayHours: step?.delayHours ?? 24,\n body: step?.body ?? \"\",\n }),\n [step],\n );\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: getDefaultValues(),\n });\n\n return (\n <EditorSheet\n form={form}\n entityType={t(\"emailAutomations.step.title\")}\n entityName={step?.subject}\n title={isEdit ? t(\"emailAutomations.step.editTitle\") : t(\"emailAutomations.step.title\")}\n isEdit={isEdit}\n module={Modules.EmailAutomationStep}\n size=\"lg\"\n onSubmit={async (values) => {\n const payload: EmailAutomationStepInput = {\n id: values.id,\n automationId,\n subject: values.subject,\n body: values.body,\n delayHours: values.delayHours,\n positionX: step ? step.positionX : initialPosition?.x,\n positionY: step ? step.positionY : initialPosition?.y,\n };\n return isEdit\n ? await EmailAutomationStepService.update(payload)\n : await EmailAutomationStepService.create(payload);\n }}\n // Save → reload the canvas, then whatever the caller adds.\n onSuccess={async () => {\n await reload();\n await onSuccess?.();\n }}\n onReset={getDefaultValues}\n trigger={trigger}\n forceShow={forceShow}\n onClose={onClose}\n dialogOpen={dialogOpen}\n onDialogOpenChange={onDialogOpenChange}\n >\n <div className=\"flex w-full flex-col gap-y-4\">\n <FormInput form={form} id=\"subject\" name={t(\"emailAutomations.step.fields.subject.label\")} isRequired />\n <FormInput\n form={form}\n id=\"delayHours\"\n type=\"number\"\n name={t(\"emailAutomations.step.fields.delayHours.label\")}\n description={\n isHead ? t(\"emailAutomations.canvas.hoursAfterEntering\") : t(\"emailAutomations.canvas.hoursAfterPrevious\")\n }\n />\n {/* FormTextarea has no `rows` prop; min-h-72 is the height of ~14 rows. */}\n <FormTextarea\n form={form}\n id=\"body\"\n name={t(\"emailAutomations.step.fields.body.label\")}\n className=\"min-h-72\"\n isRequired\n description={\n <>\n <span className=\"block\">\n {t(\"emailAutomations.step.variablesHint\")}{\" \"}\n {TEMPLATE_VARIABLES.map((variable) => (\n <span key={variable} className=\"me-2 text-foreground\">\n {variable}\n </span>\n ))}\n </span>\n <span className=\"mt-1 block\">{t(\"emailAutomations.step.unsubscribeHint\")}</span>\n </>\n }\n />\n </div>\n </EditorSheet>\n );\n}\n\nexport function EmailStepEditor(props: EmailStepEditorProps) {\n return <EmailStepEditorInternal {...props} />;\n}\n\nexport default EmailStepEditor;\n","\"use client\";\n\nimport { Handle, Node, NodeProps, Position } from \"@xyflow/react\";\nimport { MailIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { EmailStepNodeData, STEP_SOURCE_HANDLE_PREFIX, STEP_TARGET_HANDLE_PREFIX } from \"../buildCanvasGraph\";\n\ntype EmailStepNodeType = Node<{ data: EmailStepNodeData }>;\n\n/**\n * 200px card (SceneNode recipe): subject bold, \"sent N\" muted. An orphan (not\n * reachable from the trigger, so it never sends) is the dashed, faded variant\n * with a caption. Plain elements only: Base UI menus/popovers do not work\n * inside React Flow nodes; clicks and context menus are handled by the canvas.\n */\nexport function EmailStepNode({ data }: NodeProps<EmailStepNodeType>) {\n const d = data.data;\n const t = useTranslations();\n\n const shellClass = d.orphan\n ? \"border border-dashed border-foreground/30 bg-muted/40 opacity-60\"\n : \"border bg-background border-foreground/25 text-foreground\";\n\n return (\n <div className={`w-[200px] cursor-pointer rounded-md p-2 shadow-sm ${shellClass}`}>\n <Handle type=\"target\" position={Position.Left} id={`${STEP_TARGET_HANDLE_PREFIX}${d.stepId}`} />\n <Handle type=\"source\" position={Position.Right} id={`${STEP_SOURCE_HANDLE_PREFIX}${d.stepId}`} />\n\n <div className=\"flex items-center gap-1 text-sm font-medium\">\n <MailIcon className=\"size-3 shrink-0\" />\n <span className=\"truncate\">{d.subject}</span>\n </div>\n\n <div className=\"text-muted-foreground mt-1 text-xs tabular-nums\">\n {t(\"emailAutomations.canvas.sent\", { count: d.sentCount })}\n </div>\n\n {d.orphan && (\n <div className=\"text-muted-foreground mt-1 text-xs italic\">{t(\"emailAutomations.canvas.orphan\")}</div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { Handle, Node, NodeProps, Position } from \"@xyflow/react\";\nimport { ZapIcon } from \"lucide-react\";\nimport { TRIGGER_SOURCE_HANDLE, TriggerNodeData } from \"../buildCanvasGraph\";\n\n// React Flow v12 requires the Node generic to carry the data shape.\ntype TriggerNodeType = Node<{ data: TriggerNodeData }>;\n\n/**\n * The fixed head of the chain (SecretTargetNode recipe). Source handle only:\n * people enter here. Plain element, no Base UI inside the node; the click that\n * opens EmailAutomationEditor is handled by the canvas (`onNodeClick`).\n */\nexport function TriggerNode({ data }: NodeProps<TriggerNodeType>) {\n return (\n <div className=\"bg-foreground text-background flex w-[200px] cursor-pointer items-center justify-center gap-1 rounded-full px-4 py-2 text-center shadow-md\">\n <ZapIcon className=\"size-3 shrink-0 opacity-60\" />\n <div className=\"truncate text-sm font-medium\">{data.data.label}</div>\n <Handle type=\"source\" position={Position.Right} id={TRIGGER_SOURCE_HANDLE} />\n </div>\n );\n}\n","\"use client\";\n\nimport { RefreshCw } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useMemo, useState } from \"react\";\nimport { ContentListTable } from \"../../../../components\";\nimport { Modules } from \"../../../../core\";\nimport { DataListRetriever, useDataListRetriever } from \"../../../../hooks\";\nimport { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"../../../../shadcnui\";\nimport { useEmailAutomation } from \"../../contexts/EmailAutomationContext\";\nimport { EmailAutomationEnrollmentFields } from \"../../data/email-automation-enrollment.fields\";\nimport { EmailAutomationEnrollmentInterface } from \"../../data/EmailAutomationEnrollmentInterface\";\nimport { EmailAutomationService } from \"../../data/EmailAutomationService\";\n\n/**\n * Read-only list of the people in this automation (owner decision 6: no row\n * actions). Rendered inside a tab, so it keeps its own bordered card (no\n * `fullWidth`), as PricesList does inside ProductContainer.\n */\nexport function EmailAutomationRecipientsList() {\n const t = useTranslations();\n const { automation } = useEmailAutomation();\n const [statusFilter, setStatusFilter] = useState<string>(\"all\");\n\n const data: DataListRetriever<EmailAutomationEnrollmentInterface> = useDataListRetriever({\n retriever: (params) => EmailAutomationService.findEnrollments(params),\n retrieverParams: { automationId: automation?.id },\n module: Modules.EmailAutomationEnrollment,\n });\n\n const handleStatusChange = (value: string | null) => {\n const status = value ?? \"all\";\n setStatusFilter(status);\n data.addAdditionalParameter(\"status\", status === \"all\" ? null : status);\n };\n\n const statusItems = useMemo(\n () => ({\n all: t(\"emailAutomations.recipients.status.all\"),\n active: t(\"emailAutomations.recipients.status.active\"),\n completed: t(\"emailAutomations.recipients.status.completed\"),\n unsubscribed: t(\"emailAutomations.recipients.status.unsubscribed\"),\n exited: t(\"emailAutomations.recipients.status.exited\"),\n failed: t(\"emailAutomations.recipients.status.failed\"),\n }),\n [t],\n );\n\n const filters = (\n <div className=\"flex items-center gap-4\">\n <Select items={statusItems} value={statusFilter} onValueChange={handleStatusChange}>\n <SelectTrigger className=\"w-40\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{t(\"emailAutomations.recipients.status.all\")}</SelectItem>\n <SelectItem value=\"active\">{t(\"emailAutomations.recipients.status.active\")}</SelectItem>\n <SelectItem value=\"completed\">{t(\"emailAutomations.recipients.status.completed\")}</SelectItem>\n <SelectItem value=\"unsubscribed\">{t(\"emailAutomations.recipients.status.unsubscribed\")}</SelectItem>\n <SelectItem value=\"exited\">{t(\"emailAutomations.recipients.status.exited\")}</SelectItem>\n <SelectItem value=\"failed\">{t(\"emailAutomations.recipients.status.failed\")}</SelectItem>\n </SelectContent>\n </Select>\n\n <Button variant=\"outline\" size=\"icon\" onClick={() => void data.refresh()} disabled={!data.isLoaded}>\n <RefreshCw className={`h-4 w-4 ${!data.isLoaded ? \"animate-spin\" : \"\"}`} />\n </Button>\n </div>\n );\n\n return (\n <ContentListTable\n data={data}\n fields={[\n EmailAutomationEnrollmentFields.email,\n EmailAutomationEnrollmentFields.name,\n EmailAutomationEnrollmentFields.status,\n EmailAutomationEnrollmentFields.currentStep,\n EmailAutomationEnrollmentFields.nextSendAt,\n EmailAutomationEnrollmentFields.sentCount,\n ]}\n tableGeneratorType={Modules.EmailAutomationEnrollment}\n filters={filters}\n /* The enrolments endpoint takes no search term, so rendering the box would\n give the page a control that silently does nothing. */\n allowSearch={false}\n emptyState={t(\"emailAutomations.recipients.empty\")}\n />\n );\n}\n","\"use client\";\n\nimport { CheckCircle, Loader2, XCircle } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"../../../../shadcnui\";\nimport { SectionHeader } from \"../../../../components/typography\";\nimport { EmailAutomationEnrollmentService } from \"../../data/EmailAutomationEnrollmentService\";\n\ntype UnsubscribeScope = \"automation\" | \"all\";\n\ninterface Props {\n token: string;\n scope: UnsubscribeScope;\n}\n\ntype UnsubscribeState = \"loading\" | \"success\" | \"error\";\n\nexport function EmailUnsubscribe({ token, scope }: Props) {\n const t = useTranslations();\n const [state, setState] = useState<UnsubscribeState>(\"loading\");\n const [stoppedScope, setStoppedScope] = useState<UnsubscribeScope>(scope);\n const [automationName, setAutomationName] = useState<string>(\"\");\n const [isStoppingAll, setIsStoppingAll] = useState<boolean>(false);\n\n useEffect(() => {\n async function unsubscribe() {\n try {\n const enrollment = await EmailAutomationEnrollmentService.unsubscribe({ token, scope });\n setAutomationName(enrollment?.automation?.name ?? \"\");\n setStoppedScope(scope);\n setState(\"success\");\n } catch {\n setState(\"error\");\n }\n }\n\n unsubscribe();\n }, [token, scope]);\n\n const stopAll = async () => {\n setIsStoppingAll(true);\n try {\n await EmailAutomationEnrollmentService.unsubscribe({ token, scope: \"all\" });\n setStoppedScope(\"all\");\n } catch {\n setState(\"error\");\n } finally {\n setIsStoppingAll(false);\n }\n };\n\n if (state === \"loading\") {\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <Loader2 className=\"text-primary h-12 w-12 animate-spin\" />\n <p className=\"text-muted-foreground text-sm\">{t(\"emailAutomations.unsubscribe.loading\")}</p>\n </div>\n );\n }\n\n if (state === \"error\") {\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <div className=\"bg-destructive/10 rounded-full p-4\">\n <XCircle className=\"text-destructive h-12 w-12\" />\n </div>\n <SectionHeader level={2}>{t(\"emailAutomations.unsubscribe.invalidTitle\")}</SectionHeader>\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.invalidBody\")}\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col items-center justify-center space-y-4 py-16 text-center\">\n <div className=\"bg-primary/10 rounded-full p-4\">\n <CheckCircle className=\"text-primary h-12 w-12\" />\n </div>\n <SectionHeader level={2}>{t(\"emailAutomations.unsubscribe.title\")}</SectionHeader>\n {stoppedScope === \"all\" ? (\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.stoppedAll\")}\n </p>\n ) : (\n <>\n <p className=\"text-muted-foreground max-w-md text-sm leading-relaxed\">\n {t(\"emailAutomations.unsubscribe.stoppedAutomation\", { name: automationName })}\n </p>\n <Button variant=\"secondary\" onClick={stopAll} disabled={isStoppingAll}>\n {isStoppingAll && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {t(\"emailAutomations.unsubscribe.alsoStopAll\")}\n </Button>\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { ColumnDef } from \"@tanstack/react-table\";\nimport { useTranslations } from \"next-intl\";\nimport { useMemo } from \"react\";\nimport { Badge, Link } from \"../../../shadcnui\";\nimport { Modules } from \"../../../core\";\nimport { registerTableGenerator, TableContent, usePageUrlGenerator, UseTableStructureHook } from \"../../../hooks\";\nimport { EmailAutomationFields } from \"../data/email-automation.fields\";\nimport { EmailAutomationInterface } from \"../data/EmailAutomationInterface\";\n\n/**\n * `context.triggerLabels` maps a trigger key to the label the API declares for\n * it (EmailAutomationsList loads them). A key the app no longer declares falls\n * back to the raw key, so a stale automation stays readable.\n */\nexport const useEmailAutomationTableStructure: UseTableStructureHook<\n EmailAutomationInterface,\n EmailAutomationFields\n> = (params) => {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const triggerLabels: Record<string, string> = params.context?.triggerLabels ?? {};\n\n const tableData = useMemo(() => {\n return params.data.map((automation: EmailAutomationInterface) => {\n const entry: TableContent<EmailAutomationInterface> = { jsonApiData: automation };\n params.fields.forEach((field) => {\n entry[field] = (automation as any)[field as keyof EmailAutomationInterface];\n });\n return entry;\n });\n }, [params.data, params.fields]);\n\n // Typography role 15 (numeric): tabular-nums, end-aligned. NEVER\n // font-mono — no monospace font is loaded in these apps.\n const numericColumn = (\n field: EmailAutomationFields,\n header: string,\n read: (a: EmailAutomationInterface) => number,\n ) => ({\n id: field,\n accessorKey: field,\n header: header,\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return <span className=\"block text-xs tabular-nums text-end\">{read(automation) ?? 0}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n });\n\n const fieldColumnMap: Partial<Record<EmailAutomationFields, () => any>> = {\n [EmailAutomationFields.name]: () => ({\n id: \"name\",\n accessorKey: \"name\",\n header: t(\"emailAutomations.list.columns.name\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return <Link href={generateUrl({ page: Modules.EmailAutomation, id: automation.id })}>{automation.name}</Link>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.trigger]: () => ({\n id: \"trigger\",\n accessorKey: \"trigger\",\n header: t(\"emailAutomations.list.columns.trigger\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n if (!automation.trigger) return <span className=\"text-muted-foreground text-xs\">—</span>;\n return <span className=\"text-sm\">{triggerLabels[automation.trigger] ?? automation.trigger}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.status]: () => ({\n id: \"status\",\n accessorKey: \"status\",\n header: t(\"emailAutomations.list.columns.status\"),\n cell: ({ row }: { row: TableContent<EmailAutomationInterface> }) => {\n const automation: EmailAutomationInterface = row.original.jsonApiData;\n return automation.isActive ? (\n <Badge variant=\"softGreen\">{t(\"emailAutomations.list.status.on\")}</Badge>\n ) : (\n <Badge variant=\"softGray\">{t(\"emailAutomations.list.status.off\")}</Badge>\n );\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationFields.steps]: () =>\n numericColumn(EmailAutomationFields.steps, t(\"emailAutomations.list.columns.steps\"), (a) => a.stepCount),\n [EmailAutomationFields.active]: () =>\n numericColumn(EmailAutomationFields.active, t(\"emailAutomations.list.columns.active\"), (a) => a.activeCount),\n [EmailAutomationFields.completed]: () =>\n numericColumn(\n EmailAutomationFields.completed,\n t(\"emailAutomations.list.columns.completed\"),\n (a) => a.completedCount,\n ),\n [EmailAutomationFields.unsubscribed]: () =>\n numericColumn(\n EmailAutomationFields.unsubscribed,\n t(\"emailAutomations.list.columns.unsubscribed\"),\n (a) => a.unsubscribedCount,\n ),\n };\n\n const columns = useMemo(() => {\n return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<\n TableContent<EmailAutomationInterface>\n >[];\n }, [params.fields, fieldColumnMap, t, generateUrl]);\n\n return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);\n};\n\nregisterTableGenerator(\"email-automations\", useEmailAutomationTableStructure);\n","\"use client\";\n\nimport { ColumnDef } from \"@tanstack/react-table\";\nimport { useLocale, useTranslations } from \"next-intl\";\nimport { useMemo } from \"react\";\nimport { Badge } from \"../../../shadcnui\";\nimport { registerTableGenerator, TableContent, UseTableStructureHook } from \"../../../hooks\";\nimport { dateFormatLocale, formatDate } from \"../../../utils/date-formatter\";\nimport { EmailAutomationEnrollmentFields } from \"../data/email-automation-enrollment.fields\";\nimport { EmailAutomationEnrollmentInterface } from \"../data/EmailAutomationEnrollmentInterface\";\n\nconst STATUS_VARIANTS: Record<string, \"softGreen\" | \"softBlue\" | \"softGray\" | \"softRed\"> = {\n active: \"softGreen\",\n completed: \"softBlue\",\n unsubscribed: \"softGray\",\n exited: \"softGray\",\n failed: \"softRed\",\n};\n\nexport const useEmailAutomationEnrollmentTableStructure: UseTableStructureHook<\n EmailAutomationEnrollmentInterface,\n EmailAutomationEnrollmentFields\n> = (params) => {\n const t = useTranslations();\n const locale = dateFormatLocale(useLocale());\n\n const tableData = useMemo(() => {\n return params.data.map((enrollment: EmailAutomationEnrollmentInterface) => {\n const entry: TableContent<EmailAutomationEnrollmentInterface> = { jsonApiData: enrollment };\n params.fields.forEach((field) => {\n entry[field] = (enrollment as any)[field as keyof EmailAutomationEnrollmentInterface];\n });\n return entry;\n });\n }, [params.data, params.fields]);\n\n const empty = <span className=\"text-muted-foreground text-xs\">—</span>;\n\n const fieldColumnMap: Partial<Record<EmailAutomationEnrollmentFields, () => any>> = {\n [EmailAutomationEnrollmentFields.email]: () => ({\n id: \"email\",\n accessorKey: \"email\",\n header: t(\"emailAutomations.recipients.columns.email\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return <span className=\"text-sm\">{enrollment.email}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.name]: () => ({\n id: \"name\",\n accessorKey: \"name\",\n header: t(\"emailAutomations.recipients.columns.name\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return enrollment.name ? <span className=\"text-sm\">{enrollment.name}</span> : empty;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.status]: () => ({\n id: \"status\",\n accessorKey: \"status\",\n header: t(\"emailAutomations.recipients.columns.status\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return (\n <Badge\n variant={STATUS_VARIANTS[enrollment.status] ?? \"softGray\"}\n title={enrollment.status === \"failed\" ? enrollment.lastError : undefined}\n >\n {t(`emailAutomations.recipients.status.${enrollment.status}`)}\n </Badge>\n );\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.currentStep]: () => ({\n id: \"currentStep\",\n accessorKey: \"currentStep\",\n header: t(\"emailAutomations.recipients.columns.currentStep\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n return enrollment.currentStepSubject ? <span className=\"text-sm\">{enrollment.currentStepSubject}</span> : empty;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.nextSendAt]: () => ({\n id: \"nextSendAt\",\n accessorKey: \"nextSendAt\",\n header: t(\"emailAutomations.recipients.columns.nextSendAt\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n if (!enrollment.nextSendAt) return empty;\n return <span className=\"text-xs tabular-nums\">{formatDate(enrollment.nextSendAt, \"dateTime\", locale)}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n [EmailAutomationEnrollmentFields.sentCount]: () => ({\n id: \"sentCount\",\n accessorKey: \"sentCount\",\n header: t(\"emailAutomations.recipients.columns.sentCount\"),\n cell: ({ row }: { row: TableContent<EmailAutomationEnrollmentInterface> }) => {\n const enrollment: EmailAutomationEnrollmentInterface = row.original.jsonApiData;\n // Typography role 15 (numeric): tabular-nums, end-aligned.\n return <span className=\"block text-xs tabular-nums text-end\">{enrollment.sentCount ?? 0}</span>;\n },\n enableSorting: false,\n enableHiding: false,\n }),\n };\n\n const columns = useMemo(() => {\n return params.fields.map((field) => fieldColumnMap[field]?.()).filter((col) => col !== undefined) as ColumnDef<\n TableContent<EmailAutomationEnrollmentInterface>\n >[];\n }, [params.fields, fieldColumnMap, t, locale]);\n\n return useMemo(() => ({ data: tableData, columns: columns }), [tableData, columns]);\n};\n\nregisterTableGenerator(\"email-automation-enrollments\", useEmailAutomationEnrollmentTableStructure);\n"],"mappings":"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","names":["useTranslations","useTranslations","useEffect","useMemo","useState","jsx","useTranslations","useState","useEffect","useMemo","jsx","useTranslations","useTranslations","useCallback","useEffect","useMemo","useState","v4","jsx","useState","useCallback","useEffect","v4","useMemo","useTranslations","useState","jsx","jsxs","useTranslations","useState","useEffect","useReactFlow","PlusIcon","useTranslations","useCallback","useEffect","useMemo","useRef","useState","useTranslations","jsx","jsxs","useTranslations","jsx","jsx","jsxs","useCallback","useMemo","zodResolver","useTranslations","useCallback","useMemo","useForm","v4","z","Fragment","jsx","jsxs","useTranslations","useMemo","z","useCallback","v4","useForm","zodResolver","jsx","useCallback","useMemo","MailIcon","useTranslations","jsx","jsxs","useTranslations","MailIcon","Handle","Position","jsx","jsxs","Handle","Position","Fragment","jsx","jsxs","useTranslations","useState","useReactFlow","useRef","useMemo","useEffect","useCallback","PlusIcon","jsx","useEffect","useTranslations","useMemo","useState","jsx","jsxs","useTranslations","useState","useMemo","jsx","useTranslations","useTranslations","useEffect","useState","Fragment","jsx","jsxs","useTranslations","useState","useEffect","useTranslations","useMemo","jsx","useTranslations","useMemo","useTranslations","useMemo","jsx","useTranslations","useMemo"]}
|