import { api } from '../api.js'; import { showToast } from '../components/toast.js'; const API = (url, opts = {}) => fetch('/api' + url, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${localStorage.getItem('token')}`, ...opts.headers }, ...opts }).then(r => r.json()); const HOURS = Array.from({ length: 24 }, (_, i) => i); const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; export async function render(container) { const devices = await api.getDevices(); const content = await api.getContent(); const selectedDevice = devices[0]?.id || ''; const today = new Date(); const weekStart = new Date(today); weekStart.setDate(today.getDate() - today.getDay()); weekStart.setHours(0, 0, 0, 0); container.innerHTML = `
`; let currentWeekStart = new Date(weekStart); let editingId = null; function updateWeekLabel() { const end = new Date(currentWeekStart); end.setDate(end.getDate() + 6); document.getElementById('weekLabel').textContent = `${currentWeekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} - ${end.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}`; } async function loadCalendar() { const deviceId = document.getElementById('schedDevice').value; if (!deviceId) return; updateWeekLabel(); const events = await API(`/schedules/week?date=${currentWeekStart.toISOString()}&device_id=${deviceId}`); const cal = document.getElementById('calendar'); let html = '
'; // Day headers for (let d = 0; d < 7; d++) { const date = new Date(currentWeekStart); date.setDate(date.getDate() + d); const isToday = date.toDateString() === new Date().toDateString(); html += `
${DAYS[d]}
${date.getDate()}
`; } // Hour rows for (const h of HOURS) { html += `
${h === 0 ? '12am' : h < 12 ? h + 'am' : h === 12 ? '12pm' : (h - 12) + 'pm'}
`; for (let d = 0; d < 7; d++) { html += `
`; } } cal.innerHTML = html; // Render events events.forEach(ev => { const start = new Date(ev.instance_start || ev.start_time); const end = new Date(ev.instance_end || ev.end_time); const dayIdx = start.getDay(); const startHour = start.getHours() + start.getMinutes() / 60; const endHour = end.getHours() + end.getMinutes() / 60; const duration = endHour - startHour; const cell = cal.querySelector(`[data-hour="${Math.floor(startHour)}"][data-day="${dayIdx}"]`); if (!cell) return; const block = document.createElement('div'); const topOffset = (startHour - Math.floor(startHour)) * 28; block.style.cssText = `position:absolute;top:${topOffset}px;left:2px;right:2px;height:${Math.max(20, duration * 28)}px; background:${ev.color || '#3B82F6'};border-radius:3px;padding:2px 4px;font-size:10px;color:white;overflow:hidden;cursor:pointer;z-index:1;opacity:0.85`; block.textContent = ev.title || ev.content_name || ev.widget_name || 'Scheduled'; block.title = `${start.toLocaleTimeString()} - ${end.toLocaleTimeString()}`; block.onclick = () => editSchedule(ev); cell.appendChild(block); }); } function editSchedule(ev) { editingId = ev.id; document.getElementById('schedModalTitle').textContent = 'Edit Schedule'; document.getElementById('schedContent').value = ev.content_id || ''; document.getElementById('schedTitle').value = ev.title || ''; const start = new Date(ev.start_time); const end = new Date(ev.end_time); document.getElementById('schedStart').value = `${String(start.getHours()).padStart(2,'0')}:${String(start.getMinutes()).padStart(2,'0')}`; document.getElementById('schedEnd').value = `${String(end.getHours()).padStart(2,'0')}:${String(end.getMinutes()).padStart(2,'0')}`; document.getElementById('schedRepeat').value = ev.recurrence || ''; document.getElementById('schedPriority').value = ev.priority || 0; document.getElementById('schedColor').value = ev.color || '#3B82F6'; document.getElementById('scheduleModal').style.display = 'flex'; } document.getElementById('addScheduleBtn').onclick = () => { editingId = null; document.getElementById('schedModalTitle').textContent = 'Add Schedule'; document.getElementById('schedTitle').value = ''; document.getElementById('scheduleModal').style.display = 'flex'; }; document.getElementById('saveScheduleBtn').onclick = async () => { const deviceId = document.getElementById('schedDevice').value; const contentId = document.getElementById('schedContent').value; const startTime = document.getElementById('schedStart').value; const endTime = document.getElementById('schedEnd').value; const today = new Date().toISOString().split('T')[0]; const data = { device_id: deviceId, content_id: contentId, title: document.getElementById('schedTitle').value, start_time: `${today}T${startTime}:00`, end_time: `${today}T${endTime}:00`, recurrence: document.getElementById('schedRepeat').value || null, priority: parseInt(document.getElementById('schedPriority').value) || 0, color: document.getElementById('schedColor').value, }; try { if (editingId) { await API(`/schedules/${editingId}`, { method: 'PUT', body: JSON.stringify(data) }); } else { await API('/schedules', { method: 'POST', body: JSON.stringify(data) }); } document.getElementById('scheduleModal').style.display = 'none'; showToast('Schedule saved', 'success'); loadCalendar(); } catch (err) { showToast(err.message, 'error'); } }; document.getElementById('schedDevice').onchange = loadCalendar; document.getElementById('prevWeek').onclick = () => { currentWeekStart.setDate(currentWeekStart.getDate() - 7); loadCalendar(); }; document.getElementById('nextWeek').onclick = () => { currentWeekStart.setDate(currentWeekStart.getDate() + 7); loadCalendar(); }; loadCalendar(); } export function cleanup() {}