// Content calendar screen — weekly social planner. (() => { const { Card, Badge, Avatar } = window.TechyFuelOSDesignSystem_be0222; const PLAT = { instagram: ['instagram', 'var(--violet-500)'], facebook: ['facebook', 'var(--blue-600)'], linkedin: ['linkedin', 'var(--sky-600)'], twitter: ['twitter', 'var(--sky-400)'], youtube: ['youtube', 'var(--red-500)'], tiktok: ['music', 'var(--slate-900)'], }; const SS = { scheduled: ['success', 'Scheduled'], draft: ['neutral', 'Draft'], approval: ['warning', 'Approval'], published: ['info', 'Published'], rejected: ['danger', 'Rejected'] }; function getWeekDays() { const today = new Date(); const dow = today.getDay(); // 0=Sun const monday = new Date(today); monday.setDate(today.getDate() - (dow === 0 ? 6 : dow - 1)); const days = []; for (let i = 0; i < 7; i++) { const d = new Date(monday); d.setDate(monday.getDate() + i); days.push({ label: d.toLocaleDateString('en', { weekday: 'short', day: 'numeric' }), dateStr: d.toISOString().split('T')[0], dayIndex: i, }); } return days; } const EMPTY_WEEK = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [] }; function PostCard({ post, onStatusChange }) { const [pi, pc] = PLAT[post.platform] || ['image', 'var(--slate-500)']; const [st, sl] = SS[post.status] || ['neutral', post.status]; const [open, setOpen] = React.useState(false); const nextStatuses = ['draft', 'approval', 'scheduled', 'published', 'rejected'].filter(s => s !== post.status); return (
{open && (
{nextStatuses.map(s => { const [tone, label] = SS[s] || ['neutral', s]; return ( ); })}
)}
{post.title}
{post.assigned_to_name && (
{post.assigned_to_name}
)}
); } function ContentCalendar() { useLucide(); const [postMap, setPostMap] = React.useState(EMPTY_WEEK); const [totalPosts, setTotalPosts] = React.useState(0); const days = React.useMemo(() => getWeekDays(), []); const [weekLabel, setWeekLabel] = React.useState('This week'); const [clients, setClients] = React.useState([]); const [team, setTeam] = React.useState([]); const [modalOpen, setModalOpen] = React.useState(false); const [saving, setSaving] = React.useState(false); const [form, setForm] = React.useState({ title: '', platform: 'instagram', status: 'draft', scheduled_at: '', client_id: '', assigned_to: '' }); function set(k, v) { setForm(f => ({ ...f, [k]: v })); } React.useEffect(() => { if (!window.API) return; (async () => { try { const r = await window.API.getContent(); if (r.data && r.data.length > 0) { const startOfWeek = new Date(days[0].dateStr); startOfWeek.setHours(0, 0, 0, 0); const map = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [] }; r.data.forEach(post => { const p = { id: post.id, platform: post.platform, title: post.title, status: post.status, assigned_to_name: post.team_members ? post.team_members.name : null }; if (!post.scheduled_at) { map[0].push(p); return; } const dayDiff = Math.round((new Date(post.scheduled_at) - startOfWeek) / 86400000); if (dayDiff >= 0 && dayDiff < 7) map[dayDiff].push(p); }); setPostMap(map); setTotalPosts(r.data.length); } } catch {} try { const r = await window.API.getClients(); if (r.data) setClients(r.data); } catch {} try { const r = await window.API.getTeam(); if (r.data) setTeam(r.data); } catch {} })(); }, []); async function handleStatusChange(postId, newStatus) { if (!window.API) return; try { await window.API.updatePost(postId, { status: newStatus }); setPostMap(prev => { const next = {}; for (const [day, posts] of Object.entries(prev)) { next[day] = posts.map(p => p.id === postId ? { ...p, status: newStatus } : p); } return next; }); } catch {} } async function handleAddPost() { if (!form.title.trim()) return; setSaving(true); try { const payload = { title: form.title, platform: form.platform, status: form.status }; if (form.scheduled_at) payload.scheduled_at = form.scheduled_at + ':00'; if (form.client_id) payload.client_id = form.client_id; if (form.assigned_to) payload.assigned_to = form.assigned_to; if (window.API) { const { data, error } = await window.API.createPost(payload); if (!error && data) { const assigneeName = team.find(m => m.id === form.assigned_to)?.name || null; const newPost = { id: data.id, platform: data.platform, title: data.title, status: data.status, assigned_to_name: assigneeName }; setPostMap(prev => ({ ...prev, 0: [...(prev[0] || []), newPost] })); setTotalPosts(prev => prev + 1); } } setModalOpen(false); setForm({ title: '', platform: 'instagram', status: 'draft', scheduled_at: '', client_id: '', assigned_to: '' }); } finally { setSaving(false); } } const platforms = new Set( Object.values(postMap).flat().map(p => p.platform).filter(Boolean) ); return (

Content calendar

{weekLabel} · {totalPosts} {totalPosts === 1 ? 'post' : 'posts'} across {platforms.size} {platforms.size === 1 ? 'platform' : 'platforms'}

{weekLabel}
{days.map((day, i) => { const isToday = day.dateStr === new Date().toISOString().split('T')[0]; return (
{day.label}
{(postMap[i] || []).map((p, j) => )}
); })}
setModalOpen(false)} title="Plan post" onSubmit={handleAddPost} loading={saving} submitLabel="Add post"> set('title', e.target.value)} />
set('scheduled_at', e.target.value)} />
); } Object.assign(window, { ContentCalendar }); })();