import { useState, useCallback, useRef, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { adminEmailTemplatesApi, EmailTemplateType, EmailTemplateDetail, EmailTemplateLanguageData, } from '../api/adminEmailTemplates'; import { AdminBackButton, BackIcon } from '../components/admin'; import { useIsTelegram } from '../platform/hooks/usePlatform'; import { useNotify } from '@/platform'; // Hook to check if on mobile function useIsMobile() { const [isMobile, setIsMobile] = useState(() => { if (typeof window === 'undefined') return false; return window.innerWidth < 1024; }); useEffect(() => { const check = () => setIsMobile(window.innerWidth < 1024); window.addEventListener('resize', check); return () => window.removeEventListener('resize', check); }, []); return isMobile; } // Icons const MailIcon = () => ( ); const SaveIcon = () => ( ); const EyeIcon = () => ( ); const SendIcon = () => ( ); const ResetIcon = () => ( ); const LANG_LABELS: Record = { ru: 'RU', en: 'EN', zh: 'ZH', ua: 'UA', }; const LANG_FULL_LABELS: Record = { ru: 'Русский', en: 'English', zh: '中文', ua: 'Українська', }; // ============ Template List View ============ function TemplateCard({ template, currentLang, onClick, }: { template: EmailTemplateType; currentLang: string; onClick: () => void; }) { const label = template.label[currentLang] || template.label['en'] || template.type; const description = template.description[currentLang] || template.description['en'] || ''; const customCount = Object.values(template.languages).filter((l) => l.has_custom).length; return ( ); } // ============ Template Editor ============ function TemplateEditor({ detail, onClose, currentLang: interfaceLang, }: { detail: EmailTemplateDetail; onClose: () => void; currentLang: string; }) { const { t } = useTranslation(); const navigate = useNavigate(); const queryClient = useQueryClient(); const notify = useNotify(); const isTelegram = useIsTelegram(); const isMobile = useIsMobile(); const isPreviewDisabled = isTelegram || isMobile; const [activeLang, setActiveLang] = useState('ru'); const [editSubject, setEditSubject] = useState(''); const [editBody, setEditBody] = useState(''); const [isDirty, setIsDirty] = useState(false); const [toast, setToast] = useState<{ type: 'success' | 'error' | 'info'; message: string; } | null>(null); const textareaRef = useRef(null); const langData: EmailTemplateLanguageData | undefined = detail.languages[activeLang]; // Load data for current language useEffect(() => { if (langData) { setEditSubject(langData.subject); setEditBody(langData.is_default ? langData.body_html : langData.body_html); setIsDirty(false); } }, [activeLang, langData]); const showToast = useCallback((type: 'success' | 'error' | 'info', message: string) => { setToast({ type, message }); setTimeout(() => setToast(null), 3000); }, []); // Extract body content from full HTML (strip base template wrapper) const extractBodyContent = useCallback((html: string): string => { // If it's wrapped in the base template, extract just the content div const contentMatch = html.match( /
\s*([\s\S]*?)\s*<\/div>\s*