import { useState, useEffect, useCallback } from 'react'; import { Link } from 'react-router-dom'; import { adminData } from '@/lib/adminApi'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { Button } from '@/components/ui/button'; import { PaginationControls } from '@/components/ui/pagination'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Pencil, Eye } from 'lucide-react'; import { format } from 'date-fns'; import { toast } from 'sonner'; import { StrokeCanvas, type StrokeSegment } from '@/components/content/StrokeCanvas'; interface LiveDrawSession { couple_id: string; revision: number; updated_by: string; created_at: string; updated_at: string; } interface Profile { id: string; name: string | null; email: string | null; couple_id: string | null; } export function LiveDrawSessionsPage() { const [sessions, setSessions] = useState([]); const [membersByCouple, setMembersByCouple] = useState>({}); const [loading, setLoading] = useState(true); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(25); const [total, setTotal] = useState(0); const [selectedCoupleId, setSelectedCoupleId] = useState(null); const [strokes, setStrokes] = useState([]); const [strokesLoading, setStrokesLoading] = useState(false); const fetchSessions = useCallback(async () => { setLoading(true); try { const from = (page - 1) * pageSize; const to = from + pageSize - 1; const { data, error, count } = await adminData .from('live_draw_sessions') .select('couple_id, revision, updated_by, created_at, updated_at', { count: 'exact' }) .order('updated_at', { ascending: false }) .range(from, to); if (error) throw error; const rows = data || []; setSessions(rows); setTotal(count || 0); const coupleIds = rows.map((row) => row.couple_id); if (coupleIds.length > 0) { const { data: profiles } = await adminData .from('profiles') .select('id, name, email, couple_id') .in('couple_id', coupleIds); const grouped: Record = {}; (profiles || []).forEach((profile) => { if (!profile.couple_id) return; (grouped[profile.couple_id] ??= []).push(profile); }); setMembersByCouple(grouped); } else { setMembersByCouple({}); } } catch (error) { console.error('Failed to load live draw sessions:', error); toast.error('Failed to load live draw sessions'); } finally { setLoading(false); } }, [page, pageSize]); useEffect(() => { fetchSessions(); }, [fetchSessions]); useEffect(() => { const totalPages = Math.max(1, Math.ceil(total / pageSize)); if (page > totalPages) setPage(totalPages); }, [page, pageSize, total]); const previewSession = async (coupleId: string) => { setSelectedCoupleId(coupleId); setStrokesLoading(true); setStrokes([]); try { const { data, error } = await adminData .from('live_draw_sessions') .select('strokes') .eq('couple_id', coupleId) .maybeSingle(); if (error) throw error; setStrokes((data?.strokes as StrokeSegment[]) || []); } catch (error) { console.error('Failed to load drawing:', error); toast.error('Failed to load drawing'); } finally { setStrokesLoading(false); } }; const renderMembers = (coupleId: string) => { const members = membersByCouple[coupleId] || []; if (members.length === 0) return Unknown couple; return (
{members.map((member) => ( {member.name || member.email || member.id} ))}
); }; return (

Live Draw Sessions

Recent live-draw activity across couples, most recently updated first

Couple Revision Created Last Updated Actions {loading ? (
) : sessions.length === 0 ? ( No live draw sessions yet. ) : ( sessions.map((session) => ( {renderMembers(session.couple_id)} {session.revision} {format(new Date(session.created_at), 'MMM d, yyyy')} {format(new Date(session.updated_at), 'MMM d, yyyy HH:mm')} )) )}
{total > 0 && ( { setPage(1); setPageSize(size); }} /> )} {selectedCoupleId && ( Drawing Preview Read-only snapshot of the couple's shared canvas {strokesLoading ? ( ) : strokes.length === 0 ? (

No strokes to show

) : ( )}
)}
); }