// kalender.js - Calendar
// === CALENDAR CLIENT ===
let calEvents = [];
async function loadCalendarEvents() {
if (!await ensureToken()) { updateAuthUI(); return; }
const listEl = document.getElementById('calEventsList') || document.getElementById('callbackList');
try {
const res = await fetch('/api/calendar-proxy.php', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
action: 'list', accessToken: gAccessToken,
timeMin: new Date().toISOString(),
timeMax: new Date(Date.now() + 30*86400000).toISOString(),
maxResults: 50
})
});
const data = await res.json();
if (data.error === 'TOKEN_EXPIRED') { gAccessToken = ''; updateAuthUI(); return; }
calEvents = data.events || [];
renderCalendarEvents();
} catch(e) {}
}
function renderCalendarEvents() {
const embed = document.getElementById('calEmbed');
const listEl = document.getElementById('calEventsList');
// Show event list
if (listEl) {
if (calEvents.length === 0) {
listEl.innerHTML = '<div style="padding:16px;background:#f8fafc;border-radius:10px;color:#94a3b8;text-align:center;font-size:13px">Inga kommande händelser</div>';
} else {
const eventColors = ['#16a34a','#3b82f6','#eab308','#a855f7','#ef4444','#06b6d4'];
listEl.innerHTML = calEvents.slice(0, 20).map((ev, i) => {
const start = ev.allDay ? ev.start : new Date(ev.start).toLocaleString('sv-SE', {weekday:'short', month:'short', day:'numeric', hour:'2-digit', minute:'2-digit'});
const color = eventColors[i % eventColors.length];
return '<div style="display:flex;align-items:center;gap:12px;padding:10px 12px;background:#fff;border-radius:8px;border:1px solid #f1f5f9">'
+ '<div style="width:8px;height:8px;border-radius:50%;background:' + color + ';flex-shrink:0"></div>'
+ '<div style="flex:1;min-width:0">'
+ '<div style="font-size:13px;font-weight:600;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + escHtml(ev.summary) + '</div>'
+ '<div style="font-size:12px;color:#64748b">' + start + (ev.location ? ' · ' + escHtml(ev.location) : '') + '</div>'
+ '</div>'
+ '<a href="' + (ev.htmlLink || '#') + '" target="_blank" style="font-size:11px;color:#3b82f6;text-decoration:none;white-space:nowrap">Öppna</a>'
+ '</div>';
}).join('');
}
}
// Also render in the calendar embed area
if (embed) {
embed.style.display = 'block';
const calendarHtml = buildCalendarView();
embed.innerHTML = calendarHtml;
}
}
function buildCalendarView() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const monthNames = ['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December'];
const dayNames = ['Mån','Tis','Ons','Tor','Fre','Lör','Sön'];
const startDay = (firstDay + 6) % 7;
let html = '<div style="padding:16px">';
html += '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px"><h3 style="font-size:18px;font-weight:700">' + monthNames[month] + ' ' + year + '</h3></div>';
html += '<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:#e5e7eb;border:1px solid #e5e7eb;border-radius:8px;overflow:hidden">';
dayNames.forEach(d => { html += '<div style="padding:8px 4px;text-align:center;font-size:11px;font-weight:600;color:#64748b;background:#f8fafc">' + d + '</div>'; });
for (let i = 0; i < startDay; i++) html += '<div style="padding:8px;background:#fafafa;min-height:60px"></div>';
for (let day = 1; day <= daysInMonth; day++) {
const dateStr = year + '-' + String(month+1).padStart(2,'0') + '-' + String(day).padStart(2,'0');
const isToday = day === now.getDate();
const dayEvents = calEvents.filter(e => (e.start || '').startsWith(dateStr));
html += '<div style="padding:4px 6px;background:' + (isToday ? '#eff6ff' : '#fff') + ';min-height:60px;vertical-align:top">';
html += '<div style="font-size:12px;font-weight:' + (isToday ? '700' : '500') + ';color:' + (isToday ? '#024550' : '#334155') + ';margin-bottom:2px">' + day + '</div>';
dayEvents.slice(0, 2).forEach(e => {
html += '<div style="font-size:10px;padding:1px 4px;background:#dcfce7;border-radius:3px;margin-bottom:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#166534" title="' + escHtml(e.summary) + '">' + escHtml(e.summary) + '</div>';
});
if (dayEvents.length > 2) html += '<div style="font-size:10px;color:#94a3b8">+' + (dayEvents.length - 2) + ' till</div>';
html += '</div>';
}
html += '</div></div>';
return html;
}
async function createCalendarEvent(summary, description, location, startTime, endTime) {
if (!await ensureToken()) return null;
try {
const res = await fetch('/api/calendar-proxy.php', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
action: 'create', accessToken: gAccessToken,
summary, description, location, startTime, endTime
})
});
const data = await res.json();
if (data.success) { loadCalendarEvents(); return data.event; }
throw new Error(data.error);
} catch(e) { alert('Kunde inte skapa event: ' + e.message); return null; }
}