import { useState, useEffect, useCallback } from 'react'; import { useParams } from 'react-router-dom'; import apiClient from '../api/client'; import WhitelistModal from '../components/WhitelistModal'; import TestSmsModal from '../components/TestSmsModal'; const STATUS_CONFIG = { generated: { label: 'Generated', bg: 'bg-page-bg', text: 'text-text-muted', border: 'border-border-main' }, pending_whitelisting: { label: 'Pending Whitelisting', bg: 'bg-tags-bg', text: 'text-tags-text', border: 'border-tags-border' }, whitelisted: { label: 'Published', bg: 'bg-badge-bg', text: 'text-badge-text', border: 'border-badge-border' }, }; export default function Templates() { const { businessId } = useParams(); const [templates, setTemplates] = useState([]); const [profilesById, setProfilesById] = useState({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [whitelistTarget, setWhitelistTarget] = useState(null); const [testTarget, setTestTarget] = useState(null); const [activeTab, setActiveTab] = useState('published'); // 'published' | 'pending' const loadTemplates = useCallback(async () => { setLoading(true); setError(''); try { const [templatesRes, profilesRes] = await Promise.all([ apiClient.get(`/api/businesses/${businessId}/templates`), apiClient.get(`/api/businesses/${businessId}/global-sms/profiles`).catch(() => ({ data: { profiles: [] } })), ]); const all = (templatesRes.data.templates || []).filter(t => t.selectedTemplate); const profileMap = Object.fromEntries((profilesRes.data.profiles || []).map(profile => [profile.id, profile])); setTemplates(all); setProfilesById(profileMap); } catch { setError('Failed to load templates'); } finally { setLoading(false); } }, [businessId]); useEffect(() => { loadTemplates(); }, [loadTemplates]); async function handleWhitelistSuccess() { setWhitelistTarget(null); await loadTemplates(); } if (loading) { return (
); } return (

Templates

Track whitelisting status and test your SMS templates.

{error && (
{error}
)}
{templates.length === 0 ? (

No Templates Yet

Generate and select templates in the Events section first.

) : (() => { const publishedTabs = templates.filter(t => t.status === 'whitelisted'); const pendingTabs = templates.filter(t => t.status === 'pending_whitelisting'); const visibleTemplates = activeTab === 'published' ? publishedTabs : pendingTabs; if (visibleTemplates.length === 0) { return (

No templates in {activeTab === 'published' ? 'Published' : 'Pending'}.

); } return (
{visibleTemplates.map(tmpl => { const statusCfg = STATUS_CONFIG[tmpl.status] || STATUS_CONFIG.generated; const boundProfile = tmpl.curlProfileId ? profilesById[tmpl.curlProfileId] || null : null; const isBoundProfileMissing = !boundProfile; const boundProfileMessage = tmpl.curlProfileId ? 'The cURL profile used for this template no longer exists. Re-select this template from Events to continue.' : 'This template is not bound to a cURL profile. Re-select it from Events to continue.'; return (

{tmpl.eventLabel || tmpl.eventSlug.replace(/_/g, ' ')}

{tmpl.eventSlug}

{statusCfg.label}
{boundProfile ? (
{boundProfile.name} {boundProfile.id}
) : (
{boundProfileMessage}
)}
{tmpl.selectedTemplate}
{tmpl.templateId && (

{tmpl.templateId}

)} {tmpl.variableMap && Object.keys(tmpl.variableMap).length > 0 && (
{Object.entries(tmpl.variableMap).map(([key, val]) => (
{key} {val}
))}
)}
{!isBoundProfileMissing && tmpl.status === 'pending_whitelisting' && ( )} {!isBoundProfileMissing && tmpl.status === 'whitelisted' && ( )} {tmpl.status === 'pending_whitelisting' && !isBoundProfileMissing && (

Submit to the DLT portal, then complete publish from here.

)}
); })}
); })()} {whitelistTarget && ( setWhitelistTarget(null)} onSuccess={handleWhitelistSuccess} /> )} {testTarget && ( setTestTarget(null)} /> )}
); }