function ListsPage() { const { AppBootstrap } = window.__CRM__; const { Container, Paper, Typography, TextField, Button, Table, TableHead, TableRow, TableCell, TableBody, IconButton, Stack, Pagination, TableContainer, useMediaQuery, Card, CardContent, Divider, Dialog, DialogTitle, DialogContent, DialogActions } = MaterialUI; const isXs = useMediaQuery('(max-width:600px)'); const isSm = useMediaQuery('(max-width:900px)'); const [q, setQ] = React.useState(""); const [rows, setRows] = React.useState([]); const [total, setTotal] = React.useState(0); const [page, setPage] = React.useState(1); const limit = 25; // rename modal const [renameOpen, setRenameOpen] = React.useState(false); const [renameTarget, setRenameTarget] = React.useState({ id: 0, name: "" }); const [newName, setNewName] = React.useState(""); // NEW LIST modal const [newOpen, setNewOpen] = React.useState(false); const [newListName, setNewListName] = React.useState(""); async function load(p = 1) { const offset = (p - 1) * limit; const res = await fetch(`/api/lists_list.php?q=${encodeURIComponent(q)}&limit=${limit}&offset=${offset}`, { credentials: 'include' }); const j = await res.json(); setRows(j.items || []); setTotal(j.total || 0); setPage(p); } React.useEffect(() => { load(1); }, []); // New List (modal) function openNew() { setNewListName(""); setNewOpen(true); } async function createNew() { const name = newListName.trim(); if (!name) return; const fd = new FormData(); fd.append('name', name); const r = await fetch('/api/lists_create.php', { method:'POST', body: fd, credentials:'include' }); const j = await r.json(); if (j.ok) { setNewOpen(false); location.hash = `#/lists/${j.id}`; } } // Rename function openRename(row) { setRenameTarget(row); setNewName(row.name); setRenameOpen(true); } async function doRename() { const name = newName.trim(); if (!name) return; const fd = new FormData(); fd.append('id', String(renameTarget.id)); fd.append('name', name); await fetch('/api/lists_rename.php', { method:'POST', body: fd, credentials:'include' }); setRenameOpen(false); load(page); } // Delete async function onDelete(id) { if (!confirm('Delete this list? This cannot be undone.')) return; const fd = new FormData(); fd.append('id', String(id)); const r = await fetch('/api/lists_delete.php', { method:'POST', body: fd, credentials:'include' }); if (r.status === 409) { alert('Cannot delete. Linked to a campaign.'); return; } if (!r.ok) { alert('Failed to delete'); return; } load(1); } // Download function onDownload(id) { location.href = `/api/lists_export.php?id=${encodeURIComponent(id)}`; } function onEditContacts(id) { location.hash = `#/lists/${id}`; } const pages = Math.max(1, Math.ceil(total/limit)); const CardRow = ({ r }) => ( {r.name} {r.total_contacts} contacts onDownload(r.id)} title="Download CSV">download onEditContacts(r.id)} title="Edit contacts">group openRename(r)} title="Edit name">edit onDelete(r.id)} title="Delete">delete ); return ( Lists setQ(e.target.value)} /> {isXs ? (
{rows.length === 0 ? No lists. : rows.map(r => )}
) : ( Name Total Contacts Actions {rows.map(r => ( {r.name} {r.total_contacts} onDownload(r.id)} title="Download CSV">download onEditContacts(r.id)} title="Edit contacts">group openRename(r)} title="Edit name">edit onDelete(r.id)} title="Delete">delete ))} {rows.length === 0 && ( No lists. )}
)} load(p)} />
{/* New List modal */} setNewOpen(false)} maxWidth="xs" fullWidth> New List setNewListName(e.target.value)} fullWidth autoFocus onKeyDown={(e)=>{ if(e.key==='Enter'){ e.preventDefault(); createNew(); } }} /> {/* Rename dialog */} setRenameOpen(false)} maxWidth="xs" fullWidth> Edit List Name setNewName(e.target.value)} fullWidth autoFocus onKeyDown={(e)=>{ if(e.key==='Enter'){ e.preventDefault(); doRename(); } }} />
); } window.ListsPage = ListsPage;