diff --git a/frontend/src/app/forms/edit-form/edit-form.scss b/frontend/src/app/forms/edit-form/edit-form.scss index cbf8e04..1da5abf 100644 --- a/frontend/src/app/forms/edit-form/edit-form.scss +++ b/frontend/src/app/forms/edit-form/edit-form.scss @@ -33,8 +33,15 @@ form { border: 1px solid rgba(0,0,0,0.08); background: #fff; cursor: pointer; + + &:hover{ + background-color: #7fa8d6; + color: #fff; + } } + + .actions { display: flex; gap: 8px; diff --git a/frontend/src/app/forms/edit-form/edit-form.ts b/frontend/src/app/forms/edit-form/edit-form.ts index fdf7434..b703dea 100644 --- a/frontend/src/app/forms/edit-form/edit-form.ts +++ b/frontend/src/app/forms/edit-form/edit-form.ts @@ -16,6 +16,7 @@ export class EditForm implements OnChanges { @Output() saved = new EventEmitter(); @Output() created = new EventEmitter(); @Output() deleted = new EventEmitter(); + @Output() canceled = new EventEmitter(); form: FormGroup; allPresets: Array<{ key: string, label: string, emoji: string, category: string, description?: string, durationHours?: number, properties?: Record }>; @@ -287,6 +288,7 @@ export class EditForm implements OnChanges { }); this.presetValues.set({}); this.status.set({ state: 'idle' }); + this.canceled.emit(); } private toLocalInputValue(d: string | Date): string { diff --git a/frontend/src/app/maps/all-events/all-events.ts b/frontend/src/app/maps/all-events/all-events.ts index a13dd7f..441e0dd 100644 --- a/frontend/src/app/maps/all-events/all-events.ts +++ b/frontend/src/app/maps/all-events/all-events.ts @@ -145,8 +145,8 @@ export class AllEvents implements OnInit, OnDestroy { private showPickedMarker(coords: [number, number]) { const maplibregl = (window as any).maplibregl; const el = document.createElement('div'); - el.style.width = '20px'; - el.style.height = '20px'; + el.style.width = '10px'; + el.style.height = '10px'; el.style.borderRadius = '50%'; el.style.background = '#2196f3'; el.style.border = '2px solid white'; diff --git a/frontend/src/app/pages/agenda/agenda.html b/frontend/src/app/pages/agenda/agenda.html index 1327d2c..a5a4d01 100644 --- a/frontend/src/app/pages/agenda/agenda.html +++ b/frontend/src/app/pages/agenda/agenda.html @@ -5,27 +5,64 @@

Chargement des événements...

} @else { - - - } +
+ - @if (selectedEvent) { -
-
-

Modifier l'événement

- -
-
- - -
+
+ + +
+ + @if (selectedEvent) { +
+
+

Modifier l'événement

+ +
+
+ + +
+
+ }
}
\ No newline at end of file diff --git a/frontend/src/app/pages/agenda/agenda.scss b/frontend/src/app/pages/agenda/agenda.scss index 8afeb41..d455ac4 100644 --- a/frontend/src/app/pages/agenda/agenda.scss +++ b/frontend/src/app/pages/agenda/agenda.scss @@ -35,6 +35,98 @@ margin: 0; } +.agenda-layout { + display: grid; + grid-template-columns: 320px 1fr auto; + grid-template-rows: 1fr; + height: 100vh; +} + +.agenda-sidebar { + background: #ffffff; + border-right: 1px solid #e9ecef; + overflow-y: auto; + padding: 12px; +} + +.sidebar-header { + display: flex; + justify-content: space-between; + align-items: baseline; + padding: 6px 8px 12px 8px; + border-bottom: 1px solid #f1f3f5; +} + +.day-group { + padding: 10px 0; +} + +.day-title { + font-weight: 600; + color: #2c3e50; + font-size: 0.95rem; + margin: 8px 0; +} + +.event-list { + list-style: none; + margin: 0; + padding: 0; +} + +.event-item { + display: flex; + gap: 10px; + padding: 8px; + border-radius: 8px; + cursor: pointer; + transition: background 0.2s ease; +} + +.event-item:hover { + background: #f5f7fb; +} + +.event-item.active { + background: #eef3ff; + border-left: 3px solid #75a0f6; +} + +.event-icon { + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + font-size: 18px; +} + +.event-icon img { + width: 20px; + height: 20px; +} + +.event-meta { + min-width: 0; +} + +.event-title { + font-size: 0.95rem; + color: #243b53; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.event-when { + font-size: 0.8rem; + color: #6b7280; +} + +.agenda-main { + position: relative; +} + .event-edit-panel { position: fixed; top: 0; diff --git a/frontend/src/app/pages/agenda/agenda.ts b/frontend/src/app/pages/agenda/agenda.ts index 2b9d0ca..75b3ab4 100644 --- a/frontend/src/app/pages/agenda/agenda.ts +++ b/frontend/src/app/pages/agenda/agenda.ts @@ -4,6 +4,7 @@ import { FormsModule } from '@angular/forms'; import { OedbApi } from '../../services/oedb-api'; import { EditForm } from '../../forms/edit-form/edit-form'; import { CalendarComponent, CalendarEvent } from './calendar/calendar'; +import oedb from '../../../oedb-types'; interface OedbEvent { id: string; @@ -38,6 +39,8 @@ export class Agenda implements OnInit { selectedEvent: OedbEvent | null = null; isLoading = false; + groupedEvents: Array<{ dateKey: string; date: Date; items: OedbEvent[] }> = []; + ngOnInit() { this.loadEvents(); } @@ -59,6 +62,7 @@ export class Agenda implements OnInit { this.oedbApi.getEvents(params).subscribe((response: any) => { this.events = Array.isArray(response?.features) ? response.features : []; this.convertToCalendarEvents(); + this.buildGroupedEvents(); this.isLoading = false; }); } @@ -126,4 +130,57 @@ export class Agenda implements OnInit { onEventDeleted() { this.loadEvents(); } + + // Sidebar helpers + private getEventStartDate(ev: OedbEvent): Date { + const ds = ev.properties.start || ev.properties.when; + return this.parseEventDate(ds); + } + + private toDateKey(d: Date): string { + const y = d.getFullYear(); + const m = (d.getMonth() + 1).toString().padStart(2, '0'); + const da = d.getDate().toString().padStart(2, '0'); + return `${y}-${m}-${da}`; + } + + buildGroupedEvents() { + const groups: Record = {}; + for (const ev of this.events) { + const d = this.getEventStartDate(ev); + const key = this.toDateKey(d); + if (!groups[key]) groups[key] = { date: new Date(d.getFullYear(), d.getMonth(), d.getDate()), items: [] }; + groups[key].items.push(ev); + } + const result = Object.keys(groups) + .sort((a, b) => groups[a].date.getTime() - groups[b].date.getTime()) + .map(k => ({ dateKey: k, date: groups[k].date, items: groups[k].items.sort((a, b) => this.getEventStartDate(a).getTime() - this.getEventStartDate(b).getTime()) })); + this.groupedEvents = result; + } + + formatDayHeader(d: Date): string { + const days = ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi']; + const months = ['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre']; + return `${days[d.getDay()]} ${d.getDate()} ${months[d.getMonth()]} ${d.getFullYear()}`; + } + + getEmojiForWhat(what?: string): string | null { + if (!what) return null; + const spec: any = (oedb.presets.what as any)[what]; + return spec?.emoji || null; + } + + getImageForWhat(what?: string): string | null { + if (!what) return null; + const spec: any = (oedb.presets.what as any)[what]; + if (spec?.image) { + const img: string = spec.image; + return img.startsWith('/') ? img : `/${img}`; + } + return null; + } + + selectFromSidebar(ev: OedbEvent) { + this.selectedEvent = ev; + } } \ No newline at end of file diff --git a/frontend/src/app/pages/home/home.html b/frontend/src/app/pages/home/home.html index 7ab8aaf..ae4d237 100644 --- a/frontend/src/app/pages/home/home.html +++ b/frontend/src/app/pages/home/home.html @@ -1,9 +1,9 @@
- + @if (isLoading) { - ⏳ Chargement... + }
@@ -73,9 +73,37 @@
- - + @if(showEditForm){ + +
+

Guide

+
    +
  • Créer un évènement: Cliquez sur le bouton "+" pour créer un nouvel évènement. Sélectionnez un preset, remplissez les informations, cliquez quelque part sur la carte pour définir un emplacement. Puis appuyez sur créer.
  • +
  • Mettre à jour un évènement: Sélectionnez un évènement sur la carte ou dans la liste pour le modifier.
  • +
+
+ + } + + @if(selected !== null){ +
+ +

sélectionné:

+ +{{selected.properties.label}} +{{selected.properties.name}} +
+ } +
+ + +
+ + +
+
+
@if (!showTable) {
diff --git a/frontend/src/app/pages/home/home.scss b/frontend/src/app/pages/home/home.scss index 4bd892b..8da2461 100644 --- a/frontend/src/app/pages/home/home.scss +++ b/frontend/src/app/pages/home/home.scss @@ -1,5 +1,21 @@ :host { display: block; + + button{ + background: white; + border: 1px solid rgba(0,0,0,0.06); + border-radius: 10px; + padding: 10px; + cursor: pointer; + &:hover{ + background-color: #f0f0f0; + } + + button{ + margin-left: 10px; + margin-bottom: 10px; + + } + } } .layout { @@ -99,3 +115,30 @@ flex: 1 1 auto; min-height: 0; } + + +.presets{ + position: fixed; + top: 63px; + margin-left: 397px; + width: 50vw; + max-height: 80vh; + display: block; + +} +app-edit-form{ + position: fixed; + top: 135px; + margin-left: 397px; + width: 40vw; + max-height: 77.7vh; + display: block; + overflow: auto; + background: rgba(228, 235, 255, 0.5); + border: 1px solid rgba(0,0,0,0.06); + border-radius: 10px; + padding: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + z-index: 1000; + padding-bottom: 150px; +} \ No newline at end of file diff --git a/frontend/src/app/pages/home/home.ts b/frontend/src/app/pages/home/home.ts index 3e05628..bd50e86 100644 --- a/frontend/src/app/pages/home/home.ts +++ b/frontend/src/app/pages/home/home.ts @@ -33,6 +33,7 @@ export class Home implements OnInit, OnDestroy { selected: any | null = null; showTable = false; showFilters = false; + showEditForm = true; // Nouvelles propriétés pour le rechargement automatique et la sélection de jours autoReloadEnabled = true; @@ -54,6 +55,14 @@ export class Home implements OnInit, OnDestroy { this.stopAutoReload(); } + createEvent() { + this.selected = null; + //this.showTable = false; + //this.showFilters = true; + this.showEditForm = true; + + } + loadEvents() { this.isLoading = true; const today = new Date(); @@ -194,6 +203,10 @@ export class Home implements OnInit, OnDestroy { this.loadEvents(); } + onCanceled() { + this.showEditForm = false; + } + // Menu callbacks ngAfterViewInit() { // Wire menu callbacks if needed via querySelector; left simple for now diff --git a/frontend/src/app/pages/unlocated-events/unlocated-events.html b/frontend/src/app/pages/unlocated-events/unlocated-events.html index 7459ea6..e634522 100644 --- a/frontend/src/app/pages/unlocated-events/unlocated-events.html +++ b/frontend/src/app/pages/unlocated-events/unlocated-events.html @@ -65,7 +65,8 @@ class="input" [(ngModel)]="searchQuery" placeholder="Rechercher un lieu (ex: Paris, France)" - [disabled]="isSearchingLocation"> + [disabled]="isSearchingLocation" + (keyup.enter)="searchLocation()">