function formatStatus(status) { const map = { soumis: 'Soumise', prise_en_charge: 'Prise en charge', assigne_technicien: 'Technicien assigné', en_cours: 'En cours', resolu: 'Résolue', ferme: 'Fermée', }; return map[status] || status || '—'; } function getIncidentStats(incidents) { const treatedStatuses = new Set(['resolu', 'ferme']); const total = incidents.length; const treated = incidents.filter((item) => treatedStatuses.has(String(item.status || '').toLowerCase())).length; const inProgress = total - treated; return { total, inProgress, treated }; } function getCompletionRate(stats) { if (!stats.total) { return 0; } return Math.round((stats.treated / stats.total) * 100); } function getStatusTone(status) { const normalized = String(status || '').toLowerCase(); if (normalized === 'resolu' || normalized === 'ferme') { return 'is-treated'; } if (normalized === 'prise_en_charge' || normalized === 'assigne_technicien' || normalized === 'en_cours') { return 'is-progress'; } return 'is-pending'; } export async function renderDashboard(root, { client, incidents = [], unreadCount = 0 }) { const latest = incidents.slice(0, 3); const stats = getIncidentStats(incidents); const completionRate = getCompletionRate(stats); const latestUpdate = latest[0]?.updated_at || latest[0]?.created_at || null; const firstName = escapeHtml((client?.full_name || '').split(' ')[0] || 'client'); root.innerHTML = `
Bonjour ${firstName}

Tableau de bord e-Intervention

Visualisez l'état de vos demandes FTTH, suivez leur prise en charge et accédez rapidement à l'action client la plus utile.

${completionRate}% traités

${stats.treated} incident(s) clôturé(s) ou résolu(s) sur ${stats.total} déclaré(s).

${unreadCount} notification(s) non lue(s) ${escapeHtml(latestUpdate ? formatDateTime(latestUpdate) : 'Aucune mise à jour')}

Tableau de bord incidents

Trois indicateurs prioritaires pour piloter votre espace client en un coup d'oeil.

Nombre total d'incidents ${stats.total} Toutes vos demandes enregistrées dans e-Intervention
Incidents en cours ${stats.inProgress} Demandes en attente, prises en charge ou en traitement
Incidents traités ${stats.treated} Demandes résolues ou fermées
Progression globale ${completionRate}%

Le taux de résolution reflète la part de vos demandes déjà traitées par les équipes.

Tendance actuelle ${stats.inProgress > stats.treated ? 'Suivi en cours' : 'Traitement maîtrisé'}

${stats.inProgress > stats.treated ? 'Vos demandes actives sont encore majoritaires et progressent dans le circuit de prise en charge.' : 'La majorité de vos demandes ont déjà été résolues ou fermées.'}

Dernières déclarations

Les statuts ci-dessous sont mis à jour depuis le module Maintenance FTTH B2B.

Tout voir
${latest.length ? latest.map((item) => `
${escapeHtml(item.subject || 'Incident client')} ${escapeHtml(formatStatus(item.status))}
${escapeHtml(item.ref_code || ('FTTH-' + item.ticket_id))} ${Number(item.photo_count || 0)} photo(s) ${escapeHtml(formatDateTime(item.created_at))}
`).join('') : '
Aucune demande soumise pour le moment.
'}
`; } function formatDateTime(value) { if (!value) { return '—'; } const date = new Date(String(value).replace(' ', 'T')); if (Number.isNaN(date.getTime())) { return value; } return date.toLocaleString('fr-FR', { dateStyle: 'medium', timeStyle: 'short' }); } function escapeHtml(value) { return String(value ?? '') .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", '''); }