diff --git a/frontend/src/app/(dashboard)/whatsapp/page.tsx b/frontend/src/app/(dashboard)/whatsapp/page.tsx index 01dc1c1ea..580a8395c 100644 --- a/frontend/src/app/(dashboard)/whatsapp/page.tsx +++ b/frontend/src/app/(dashboard)/whatsapp/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState, useCallback } from 'react'; +import { useEffect, useState, useCallback, useRef } from 'react'; import api from '@/lib/api'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; @@ -49,6 +49,7 @@ import { renderWhatsAppTemplate, buildSampleWhatsAppContext, extractTriggerRule, + insertPlaceholderAtSelection, type WhatsAppAutomationConfig, } from '../../../../../shared/whatsapp-automation'; @@ -322,6 +323,8 @@ export default function WhatsAppPage() { const [automationLoaded, setAutomationLoaded] = useState(false); const [automationLoadError, setAutomationLoadError] = useState(false); const [selectedTemplateId, setSelectedTemplateId] = useState('receipt'); + const templateBodyRef = useRef(null); + const templateSelectionEstablishedRef = useRef(false); const [savingAutomation, setSavingAutomation] = useState(false); const [runningSweep, setRunningSweep] = useState(false); const [broadcasting, setBroadcasting] = useState(false); @@ -478,6 +481,14 @@ export default function WhatsAppPage() { void refreshAutomation(); }, [refreshAutomation]); + useEffect(() => { + templateSelectionEstablishedRef.current = false; + const el = templateBodyRef.current; + if (!el) return; + const end = el.value.length; + el.setSelectionRange(end, end); + }, [selectedTemplateId, effectiveTab]); + const saveAutomation = async () => { if (!automationLoaded || automationLoadError) { toast.error(tCommon('somethingWrong')); @@ -1442,15 +1453,49 @@ export default function WhatsAppPage() { })); }; + const markTemplateSelectionEstablished = () => { + templateSelectionEstablishedRef.current = true; + }; + const resetTemplateToDefault = () => { const def = DEFAULT_WHATSAPP_TEMPLATES.find((d) => d.id === activeTpl.id); if (!def) return; + templateSelectionEstablishedRef.current = false; setAutomationConfig((prev) => ({ ...prev, templates: prev.templates.map((t) => t.id === activeTpl.id ? { ...def } : t, ), })); + requestAnimationFrame(() => { + const el = templateBodyRef.current; + if (!el) return; + el.setSelectionRange(def.body.length, def.body.length); + }); + }; + + const insertTemplatePlaceholder = (token: string) => { + const el = templateBodyRef.current; + const selectionEstablished = + templateSelectionEstablishedRef.current || + (typeof document !== 'undefined' && document.activeElement === el) || + (typeof el?.selectionStart === 'number' && + (el.selectionStart !== 0 || (el.selectionEnd ?? 0) !== 0)); + const { body: nextBody, cursor: nextCursor } = insertPlaceholderAtSelection( + activeTpl.body, + token, + el?.selectionStart, + el?.selectionEnd, + selectionEstablished, + ); + templateSelectionEstablishedRef.current = true; + updateTemplateField('body', nextBody); + requestAnimationFrame(() => { + const target = templateBodyRef.current; + if (!target) return; + target.focus(); + target.setSelectionRange(nextCursor, nextCursor); + }); }; return ( @@ -1489,9 +1534,17 @@ export default function WhatsAppPage() {