style agenda

This commit is contained in:
Tykayn 2025-10-13 10:49:13 +02:00 committed by tykayn
parent 737781e9aa
commit 7dd38624a4
7 changed files with 471 additions and 161 deletions

View file

@ -1,10 +1,6 @@
<div class="agenda-page">
<div class="layout">
<div class="aside">
<app-menu></app-menu>
</div>
<div class="main">
@if (isLoading) {
<div class="loading">
<div class="loading-spinner"></div>
@ -12,31 +8,31 @@
</div>
} @else {
<div class="agenda-layout">
<aside class="agenda-sidebar">
<div class="sidebar-header">
<h3>Agenda</h3>
<small>{{filteredCalendarEvents.length}} évènements</small>
</div>
<div class="sidebar-filters">
<app-what-filter
[label]="'Filtrer par type d\'événement'"
[available]="availableWhatTypes"
[selected]="selectedWhatFilter"
(selectedChange)="onWhatFilterChange($event)"></app-what-filter>
@if (selectedDate) {
<div class="date-filter-info">
<small>Filtré par date: {{formatDayHeader(selectedDate)}}</small>
<button class="btn-reset-date" (click)="clearDateFilter()">Afficher tous les jours</button>
<aside class="agenda-sidebar">
<div class="sidebar-header">
<h3>Agenda</h3>
<small>{{filteredCalendarEvents.length}} évènements</small>
</div>
}
</div>
<div class="day-groups">
@for (group of groupedEvents; track group.dateKey) {
<div class="day-group" [attr.data-date-key]="group.dateKey">
<div class="day-title">{{formatDayHeader(group.date)}}</div>
<ul class="event-list">
@for (ev of group.items; track ev.id) {
<li class="event-item" (click)="selectFromSidebar(ev)" [class.active]="selectedEvent?.id === ev.id">
<div class="sidebar-filters">
<app-what-filter
[label]="'Filtrer par type d\'événement'"
[available]="availableWhatTypes"
[selected]="selectedWhatFilter"
(selectedChange)="onWhatFilterChange($event)"></app-what-filter>
@if (selectedDate) {
<div class="date-filter-info">
<small>Filtré par date: {{formatDayHeader(selectedDate)}}</small>
<button class="btn-reset-date" (click)="clearDateFilter()">Afficher tous les jours</button>
</div>
}
</div>
<div class="day-groups">
@for (group of groupedEvents; track group.dateKey) {
<div class="day-group" [attr.data-date-key]="group.dateKey">
<div class="day-title">{{formatDayHeader(group.date)}}</div>
<ul class="event-list">
@for (ev of group.items; track ev.id) {
<li class="event-item" (click)="selectFromSidebar(ev)" [class.active]="selectedEvent?.id === ev.id">
<span class="event-icon">
@if (getImageForWhat(ev.properties.what)) {
<img [src]="getImageForWhat(ev.properties.what)" alt="" />
@ -46,44 +42,49 @@
📌
}
</span>
<div class="event-meta">
<div class="event-title">{{ev.properties.label || ev.properties.name || 'Événement'}}</div>
<div class="event-when">{{(ev.properties.start || ev.properties.when) || '—'}}</div>
</div>
</li>
}
</ul>
<div class="event-meta">
<div class="event-title">{{ev.properties.label || ev.properties.name || 'Événement'}}</div>
<div class="event-when">{{(ev.properties.start || ev.properties.when) || '—'}}</div>
</div>
</li>
}
</ul>
</div>
}
</div>
</aside>
@if (selectedEvent) {
<div class="event-edit-panel">
<div class="panel-header">
<h3>Modifier l'événement</h3>
<button class="btn-close" (click)="selectedEvent = null">×</button>
</div>
<div class="panel-content">
<app-edit-form
[selected]="selectedEvent"
(saved)="onEventSaved()"
(created)="onEventCreated()"
(deleted)="onEventDeleted()">
</app-edit-form>
</div>
</div>
}
</div>
</aside>
}
</div>
<div class="main">
<main class="agenda-main">
<app-calendar
<app-calendar
[events]="filteredCalendarEvents"
(eventClick)="onEventClick($event)"
(dateClick)="onDateClick($event)">
</app-calendar>
</main>
@if (selectedEvent) {
<div class="event-edit-panel">
<div class="panel-header">
<h3>Modifier l'événement</h3>
<button class="btn-close" (click)="selectedEvent = null">×</button>
</div>
<div class="panel-content">
<app-edit-form
[selected]="selectedEvent"
(saved)="onEventSaved()"
(created)="onEventCreated()"
(deleted)="onEventDeleted()">
</app-edit-form>
</div>
</div>
}
</div>
}
</div>
</div>
</div>
</div>

View file

@ -10,7 +10,7 @@
grid-template-rows: minmax(100vh, auto);
gap: 0;
// min-height: 100vh;
&.is-small {
grid-template-columns: 100px 1fr;
}
@ -220,4 +220,4 @@
.event-edit-panel {
width: 100%;
}
}
}

View file

@ -1,6 +1,6 @@
const oedb = {
presets : {
what : {
presets: {
what: {
'community': {
label: 'Événement de base',
description: 'Événement communautaire',
@ -22,11 +22,11 @@ const oedb = {
description: 'Événement de type Culture ouvert au public',
durationHours: 24,
properties: {
createdate: { label: 'Createdate', writable: true },
lastupdate: { label: 'Lastupdate', writable: true },
start: { label: 'Start', writable: true },
stop: { label: 'Stop', writable: true },
type: { label: 'Type', writable: true }
createdate: {label: 'Createdate', writable: true},
lastupdate: {label: 'Lastupdate', writable: true},
start: {label: 'Start', writable: true},
stop: {label: 'Stop', writable: true},
type: {label: 'Type', writable: true}
}
},
'culture.floss': {
@ -35,15 +35,15 @@ const oedb = {
category: 'Autre',
description: 'Événement de type Culture Floss',
durationHours: 24,
properties: {
}}, 'culture.viparis': {
properties: {}
}, 'culture.viparis': {
emoji: '📅',
label: 'Évènements organisés par Viparis',
category: 'Autre',
description: 'Événement culturel par Viparis, une entreprise qui gère plusieurs grandes salles en Île de France.',
durationHours: 24,
properties: {
}},
properties: {}
},
// Culture / Arts
@ -109,8 +109,8 @@ const oedb = {
description: 'Infrastructure de recharge disponible',
durationHours: 300,
properties: {
"capacity:vehicles": { label: 'Nombre de véhicules qui peuvent actuellement se brancher', writable: true },
"capacity:vehicles:max": { label: 'Nombre de véhicules maximum à pouvoir se brancher', writable: true }
"capacity:vehicles": {label: 'Nombre de véhicules qui peuvent actuellement se brancher', writable: true},
"capacity:vehicles:max": {label: 'Nombre de véhicules maximum à pouvoir se brancher', writable: true}
}
},
'traffic.counter.bicycle': {
@ -162,9 +162,9 @@ const oedb = {
description: 'Accident de la circulation',
durationHours: 6,
properties: {
severity: { label: 'Gravité', writable: true },
lanes_closed: { label: 'Voies fermées', writable: true },
vehicles: { label: 'Nombre de véhicules', writable: true }
severity: {label: 'Gravité', writable: true},
lanes_closed: {label: 'Voies fermées', writable: true},
vehicles: {label: 'Nombre de véhicules', writable: true}
}
},
'traffic.incident': {
@ -193,9 +193,9 @@ const oedb = {
description: 'Travaux sur la chaussée',
durationHours: 72,
properties: {
contractor: { label: 'Entreprise', writable: true },
reason: { label: 'Raison', writable: true },
lanes_affected: { label: 'Voies impactées', writable: true }
contractor: {label: 'Entreprise', writable: true},
reason: {label: 'Raison', writable: true},
lanes_affected: {label: 'Voies impactées', writable: true}
}
},
'traffic.OperatorAction.NetworkManagement.RoadOrCarriagewayOrLaneManagement': {
@ -206,7 +206,7 @@ const oedb = {
description: 'Événement de type Traffic OperatorAction NetworkManagement RoadOrCarriagewayOrLaneManagement',
durationHours: 24,
properties: {
source: { label: 'Source', writable: true },
source: {label: 'Source', writable: true},
}
},
@ -218,7 +218,7 @@ const oedb = {
description: 'Événement de type Traffic OperatorAction NetworkManagement RoadOrCarriagewayOrLaneManagement',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
source: {label: 'Source', writable: true},
}
},
'traffic.OperatorAction.NetworkManagement.ReroutingManagement': {
@ -229,7 +229,7 @@ const oedb = {
description: 'Événement de type Traffic OperatorAction NetworkManagement ReroutingManagement',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
source: {label: 'Source', writable: true},
}
},
'traffic.OperatorAction.ConstructionWorks': {
@ -240,7 +240,7 @@ const oedb = {
description: 'Événement de type Traffic OperatorAction ConstructionWorks',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
source: {label: 'Source', writable: true},
}
},
'traffic.OperatorAction.NetworkManagement.SpeedManagement': {
@ -251,75 +251,75 @@ const oedb = {
description: 'Événement de type Traffic OperatorAction SpeedManagement',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
source: {label: 'Source', writable: true},
}
},
// Gestion générale du réseau
'traffic.OperatorAction.NetworkManagement.GeneralNetworkManagement': {
emoji: '',
'traffic.OperatorAction.NetworkManagement.GeneralNetworkManagement': {
emoji: '',
image: 'static/cone.png',
label: 'Gestion générale du réseau',
category: 'Circulation',
description: 'Événement de type Traffic OperatorAction GeneralNetworkManagement',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
'traffic.closed': {
emoji: '⛔',
label: 'Chaussée fermée',
category: 'Circulation',
description: 'Événement de type Traffic Closed',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
'traffic.TrafficElement.GeneralInstructionOrMessageToRoadUsers': {
emoji: '',
image: 'static/cone.png',
label: 'Instruction ou message aux usagers',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement GeneralInstructionOrMessageToRoadUsers',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
'traffic.TrafficElement.Obstruction.GeneralObstruction': {
emoji: '',
image: 'static/cone.png',
label: 'Obstruction générale',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction GeneralObstruction',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
'traffic.TrafficElement.Obstruction.InfrastructureDamageObstruction': {
emoji: '⛔',
label: 'Gestion générale du réseau',
category: 'Circulation',
description: 'Événement de type Traffic OperatorAction GeneralNetworkManagement',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.closed': {
emoji: '⛔',
label: 'Chaussée fermée',
category: 'Circulation',
description: 'Événement de type Traffic Closed',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.TrafficElement.GeneralInstructionOrMessageToRoadUsers': {
emoji: '',
image: 'static/cone.png',
label: 'Instruction ou message aux usagers',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement GeneralInstructionOrMessageToRoadUsers',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.TrafficElement.Obstruction.GeneralObstruction': {
emoji: '',
image: 'static/cone.png',
label: 'Obstruction générale',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction GeneralObstruction',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.TrafficElement.Obstruction.InfrastructureDamageObstruction': {
emoji: '⛔',
label: 'Obstruction d\'infrastructure',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction InfrastructureDamageObstruction',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
'traffic.TrafficElement.Obstruction.EnvironmentalObstruction': {
emoji: '⛔',
label: 'Obstruction d\'infrastructure',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction InfrastructureDamageObstruction',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.TrafficElement.Obstruction.EnvironmentalObstruction': {
emoji: '⛔',
label: 'Obstruction environnementale',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction EnvironmentalObstruction',
durationHours: 200,
properties: {
source: { label: 'Source', writable: true },
}
},
label: 'Obstruction environnementale',
category: 'Circulation',
description: 'Événement de type Traffic TrafficElement Obstruction EnvironmentalObstruction',
durationHours: 200,
properties: {
source: {label: 'Source', writable: true},
}
},
'traffic.obstacle.flood': {
emoji: '🌊',
label: 'Chaussée inondée',
@ -379,9 +379,9 @@ const oedb = {
description: 'Tempête (vent fort)',
durationHours: 48,
properties: {
wind_speed: { label: 'Vent moyen (km/h)', writable: true },
wind_gust: { label: 'Rafales (km/h)', writable: true },
severity: { label: 'Sévérité', writable: true }
wind_speed: {label: 'Vent moyen (km/h)', writable: true},
wind_gust: {label: 'Rafales (km/h)', writable: true},
severity: {label: 'Sévérité', writable: true}
}
},
'weather.thunder': {
@ -391,7 +391,7 @@ const oedb = {
description: 'Activité orageuse',
durationHours: 12,
properties: {
lightning_count: { label: 'Nombre déclairs', writable: true }
lightning_count: {label: 'Nombre déclairs', writable: true}
}
}, 'weather.flood': {
emoji: '🌊',
@ -400,7 +400,7 @@ const oedb = {
description: 'Inondation',
durationHours: 24,
properties: {
flood_level: { label: 'Niveau d\'inondation', writable: true }
flood_level: {label: 'Niveau d\'inondation', writable: true}
}
},
'weather.snow': {
@ -410,7 +410,7 @@ const oedb = {
description: 'Neige',
durationHours: 12,
properties: {
snow_level: { label: 'Niveau de neige', writable: true }
snow_level: {label: 'Niveau de neige', writable: true}
}
},
'weather.earthquake': {
@ -420,8 +420,8 @@ const oedb = {
description: 'Séisme',
durationHours: 6,
properties: {
magnitude: { label: 'Magnitude (Mw)', writable: true },
depth_km: { label: 'Profondeur (km)', writable: true }
magnitude: {label: 'Magnitude (Mw)', writable: true},
depth_km: {label: 'Profondeur (km)', writable: true}
}
},
@ -433,8 +433,8 @@ const oedb = {
description: 'Interruption d\'itinéraire',
durationHours: 200,
properties: {
reason: { label: 'Raison', writable: true },
route: { label: 'Itinéraire', writable: true },
reason: {label: 'Raison', writable: true},
route: {label: 'Itinéraire', writable: true},
}
},
@ -445,8 +445,8 @@ const oedb = {
description: 'Mauvais sens de circulation',
durationHours: 200,
properties: {
reason: { label: 'Raison', writable: true },
route: { label: 'Itinéraire', writable: true },
reason: {label: 'Raison', writable: true},
route: {label: 'Itinéraire', writable: true},
}
},
@ -457,7 +457,7 @@ const oedb = {
description: 'Contestation d\'itinéraire',
durationHours: 200,
properties: {
route: { label: 'Itinéraire', writable: true },
route: {label: 'Itinéraire', writable: true},
}
}
// ici ajouter d'autres catégories d'évènements à suggérer