2026-10-02 19:51:13 +02:00
|
|
|
|
import { h, mount } from '../dom'
|
|
|
|
|
|
import { getBaseUrl, setBaseUrl, DEFAULT_BASE_URL } from '../config'
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
import {
|
|
|
|
|
|
currentFlash,
|
|
|
|
|
|
currentKlass,
|
|
|
|
|
|
isAdmin,
|
|
|
|
|
|
setFlash,
|
|
|
|
|
|
signOut,
|
|
|
|
|
|
updateClass,
|
|
|
|
|
|
} from '../store'
|
2026-10-02 19:51:13 +02:00
|
|
|
|
import { showToast } from '../toast'
|
|
|
|
|
|
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
const inputClass =
|
|
|
|
|
|
'w-full bg-slate-900/80 border border-slate-700/80 rounded-xl px-3.5 py-2.5 text-sm text-slate-100 placeholder-slate-500 focus:outline-none focus:border-sky-500 transition-colors'
|
|
|
|
|
|
|
|
|
|
|
|
const labelClass = 'block text-[10px] font-black uppercase tracking-wider text-slate-500 mb-1.5'
|
|
|
|
|
|
|
2026-10-02 19:51:13 +02:00
|
|
|
|
export function renderPlus(root: HTMLElement, rerender: () => void): void {
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
const klass = currentKlass()
|
|
|
|
|
|
const flash = currentFlash()
|
|
|
|
|
|
const admin = isAdmin()
|
|
|
|
|
|
|
2026-10-02 19:51:13 +02:00
|
|
|
|
const serverInput = h('input', {
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
class: inputClass,
|
2026-10-02 19:51:13 +02:00
|
|
|
|
value: getBaseUrl(),
|
|
|
|
|
|
autocomplete: 'off',
|
|
|
|
|
|
inputMode: 'url',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
const nameInput = h('input', { class: inputClass, value: klass?.name ?? '', placeholder: 'Terminale S2' })
|
|
|
|
|
|
const levelInput = h('input', { class: inputClass, value: klass?.level ?? '', placeholder: 'Lycée' })
|
|
|
|
|
|
const flashInput = h('textarea', {
|
|
|
|
|
|
class: `${inputClass} min-h-[70px] resize-none`,
|
|
|
|
|
|
placeholder: 'Message du jour pour la classe…',
|
|
|
|
|
|
})
|
|
|
|
|
|
flashInput.value = flash?.message ?? ''
|
|
|
|
|
|
|
2026-10-02 19:51:13 +02:00
|
|
|
|
const legendItems: { icon: string; title: string; accent: string; desc: string }[] = [
|
|
|
|
|
|
{ icon: '☀️', title: 'Grand Soleil', accent: 'text-sky-400', desc: 'Journée calme. Aucun examen répertorié ni suspecté.' },
|
|
|
|
|
|
{ icon: '🌫️', title: 'Brouillard', accent: 'text-purple-400', desc: 'Zone d’incertitude. Rumeur ou sous-entendu d’un professeur.' },
|
|
|
|
|
|
{ icon: '💨', title: 'Coup de vent', accent: 'text-amber-400', desc: 'Interrogation surprise potentielle ou petit QCM (coeff faible).' },
|
|
|
|
|
|
{ icon: '🌩️', title: 'Orage / Pluie', accent: 'text-rose-400', desc: 'Devoir Surveillé (DS) confirmé ou évaluation de chapitre.' },
|
|
|
|
|
|
{ icon: '🚨', title: 'Alerte Rouge / Tempête', accent: 'text-red-500', desc: 'Examen blanc, épreuve commune ou gros devoir de fin de trimestre.' },
|
|
|
|
|
|
]
|
|
|
|
|
|
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
const children: (Node | null)[] = []
|
|
|
|
|
|
|
|
|
|
|
|
// --- Panneau admin ---
|
|
|
|
|
|
if (admin) {
|
|
|
|
|
|
children.push(
|
2026-10-02 19:51:13 +02:00
|
|
|
|
h(
|
|
|
|
|
|
'div',
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
{ class: 'bg-slate-800 border border-slate-700 rounded-2xl p-4 space-y-4' },
|
|
|
|
|
|
h('div', { class: 'flex items-center gap-2' },
|
|
|
|
|
|
h('i', { class: 'fa-solid fa-user-shield text-sky-400' }),
|
|
|
|
|
|
h('h3', { class: 'text-xs font-black text-slate-400 uppercase tracking-wider' }, 'Configuration admin'),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// Flash info
|
|
|
|
|
|
h('div', {},
|
|
|
|
|
|
h('span', { class: labelClass }, 'Flash info du jour'),
|
|
|
|
|
|
flashInput,
|
|
|
|
|
|
h('p', { class: 'text-[10px] text-slate-600 font-semibold mt-1' },
|
|
|
|
|
|
'Message visible par toute la classe sur l’écran Météo.'),
|
|
|
|
|
|
h(
|
|
|
|
|
|
'button',
|
|
|
|
|
|
{
|
|
|
|
|
|
class: 'mt-2 w-full bg-sky-500 text-slate-950 text-xs font-extrabold py-2.5 rounded-xl active:scale-95 transition-transform',
|
|
|
|
|
|
onclick: async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await setFlash(flashInput.value.trim())
|
|
|
|
|
|
showToast('Flash info mis à jour', 'success')
|
|
|
|
|
|
rerender()
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
showToast(error instanceof Error ? error.message : 'Erreur', 'reject')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-10-02 19:51:13 +02:00
|
|
|
|
},
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
'Publier le flash info',
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
// Édition classe
|
|
|
|
|
|
h('div', { class: 'pt-3 border-t border-slate-700/60' },
|
|
|
|
|
|
h('span', { class: labelClass }, 'Nom de la classe'),
|
|
|
|
|
|
h('div', { class: 'grid grid-cols-2 gap-3' }, nameInput, levelInput),
|
|
|
|
|
|
h(
|
|
|
|
|
|
'button',
|
|
|
|
|
|
{
|
|
|
|
|
|
class: 'mt-2 w-full bg-indigo-500 text-white text-xs font-extrabold py-2.5 rounded-xl active:scale-95 transition-transform',
|
|
|
|
|
|
onclick: async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await updateClass(nameInput.value.trim(), levelInput.value.trim() || null)
|
|
|
|
|
|
showToast('Classe mise à jour', 'success')
|
|
|
|
|
|
rerender()
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
showToast(error instanceof Error ? error.message : 'Erreur', 'reject')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
'Enregistrer la classe',
|
|
|
|
|
|
),
|
2026-10-02 19:51:13 +02:00
|
|
|
|
),
|
|
|
|
|
|
),
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- Serveur ---
|
|
|
|
|
|
children.push(
|
|
|
|
|
|
h(
|
|
|
|
|
|
'div',
|
|
|
|
|
|
{ class: 'bg-slate-800 border border-slate-700 rounded-2xl p-4' },
|
|
|
|
|
|
h('h3', { class: 'text-xs font-black text-slate-400 uppercase tracking-wider mb-3' }, 'Serveur API'),
|
|
|
|
|
|
serverInput,
|
|
|
|
|
|
h('p', { class: 'text-[10px] text-slate-500 font-semibold mt-2' },
|
|
|
|
|
|
'Adresse de l’API. Émulateur : 10.0.2.2:8787 · Réseau local : IP du PC · Public : URL Tailscale.'),
|
2026-10-02 19:51:13 +02:00
|
|
|
|
h(
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
'button',
|
|
|
|
|
|
{
|
|
|
|
|
|
class: 'mt-3 w-full bg-sky-500 text-slate-950 text-xs font-extrabold py-2.5 rounded-xl active:scale-95 transition-transform',
|
|
|
|
|
|
onclick: () => {
|
|
|
|
|
|
setBaseUrl(serverInput.value.trim() || DEFAULT_BASE_URL)
|
|
|
|
|
|
showToast('Adresse du serveur enregistrée', 'success')
|
|
|
|
|
|
rerender()
|
2026-10-02 19:51:13 +02:00
|
|
|
|
},
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
},
|
|
|
|
|
|
'Enregistrer l’adresse',
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// --- Session ---
|
|
|
|
|
|
children.push(
|
|
|
|
|
|
h(
|
|
|
|
|
|
'div',
|
|
|
|
|
|
{ class: 'bg-slate-800 border border-slate-700 rounded-2xl p-4' },
|
|
|
|
|
|
h('h3', { class: 'text-xs font-black text-slate-400 uppercase tracking-wider mb-1' }, 'Session'),
|
|
|
|
|
|
h(
|
|
|
|
|
|
'button',
|
|
|
|
|
|
{
|
|
|
|
|
|
class: 'w-full bg-rose-500/10 border border-rose-500/25 text-rose-400 text-xs font-extrabold py-2.5 rounded-xl active:scale-95 transition-transform',
|
|
|
|
|
|
onclick: () => {
|
|
|
|
|
|
signOut()
|
|
|
|
|
|
rerender()
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
h('i', { class: 'fa-solid fa-right-from-bracket mr-1.5' }),
|
|
|
|
|
|
'Se déconnecter',
|
2026-10-02 19:51:13 +02:00
|
|
|
|
),
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// --- Légende ---
|
|
|
|
|
|
children.push(
|
|
|
|
|
|
h('div', {},
|
|
|
|
|
|
h('h3', { class: 'text-xs font-black text-slate-400 uppercase tracking-wider mb-2' }, 'Légende météorologique'),
|
|
|
|
|
|
h('div', { class: 'grid grid-cols-1 gap-2.5' },
|
|
|
|
|
|
...legendItems.map((item) =>
|
|
|
|
|
|
h(
|
|
|
|
|
|
'div',
|
|
|
|
|
|
{ class: 'bg-slate-800/80 border border-slate-700/60 rounded-xl p-3 flex items-center gap-3' },
|
|
|
|
|
|
h('span', { class: 'text-3xl' }, item.icon),
|
|
|
|
|
|
h('div', {},
|
|
|
|
|
|
h('h4', { class: `text-sm font-black ${item.accent}` }, item.title),
|
|
|
|
|
|
h('p', { class: 'text-xs text-slate-300 font-medium' }, item.desc),
|
2026-10-02 19:51:13 +02:00
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
v0.2.0 — config admin (météo forcée, flash info, édition classe) + PWA
- DB : table day_weather (override admin par jour), flash_message sur classes
- API : PUT/DELETE /api/config/day-weather, PUT /api/config/flash, PATCH /api/config/class
- SSE : day_weather.updated/deleted, flash.updated, class.updated
- Front : bandeau flash info, indicateur 'forcé' sur la frise, modale météo admin
- Onglet Plus : panneau admin (flash info + édition classe), tout admin modifiable
- PWA : manifest.webmanifest, service worker, meta Apple, icônes 192/512
- Web version accessible sur iOS via Safari (Ajouter à l'écran d'accueil)
2026-10-04 17:05:56 +02:00
|
|
|
|
|
|
|
|
|
|
children.push(
|
|
|
|
|
|
h(
|
|
|
|
|
|
'p',
|
|
|
|
|
|
{ class: 'text-[10px] text-slate-600 font-semibold text-center' },
|
|
|
|
|
|
'Météo Exam — v0.2.0 · Radar de rumeurs en phase 2',
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
mount(root, ...children.filter((c): c is Node => c !== null))
|
2026-10-02 19:51:13 +02:00
|
|
|
|
}
|