diff --git a/frontend/src/app/maps/all-events/all-events.html b/frontend/src/app/maps/all-events/all-events.html
index c0f8348..b0b34ab 100644
--- a/frontend/src/app/maps/all-events/all-events.html
+++ b/frontend/src/app/maps/all-events/all-events.html
@@ -1,6 +1,7 @@
+
diff --git a/frontend/src/app/pages/agenda/agenda.ts b/frontend/src/app/pages/agenda/agenda.ts
index c05365c..67c17a4 100644
--- a/frontend/src/app/pages/agenda/agenda.ts
+++ b/frontend/src/app/pages/agenda/agenda.ts
@@ -6,6 +6,7 @@ import { EditForm } from '../../forms/edit-form/edit-form';
import { CalendarComponent, CalendarEvent } from './calendar/calendar';
import oedb from '../../../oedb-types';
import { WhatFilterComponent } from '../../shared/what-filter/what-filter';
+import { ActivatedRoute } from '@angular/router';
interface OedbEvent {
id: string;
@@ -34,6 +35,7 @@ interface OedbEvent {
})
export class Agenda implements OnInit {
private oedbApi = inject(OedbApi);
+ private route = inject(ActivatedRoute);
events: OedbEvent[] = [];
filteredEvents: OedbEvent[] = [];
@@ -44,13 +46,26 @@ export class Agenda implements OnInit {
groupedEvents: Array<{ dateKey: string; date: Date; items: OedbEvent[] }> = [];
availableWhatTypes: string[] = [];
- selectedWhatFilter = '';
+ selectedWhatFilter = 'culture';
ngOnInit() {
- this.loadEvents();
+ this.route.queryParamMap.subscribe(map => {
+ const id = (map.get('id') || '').trim();
+ const what = (map.get('what') || '').trim();
+ const limitParam = map.get('limit');
+ const limit = limitParam ? Number(limitParam) : null;
+ if (id) {
+ this.loadSingleEvent(id);
+ } else {
+ this.loadEvents({ what: what || undefined, limit: limit || undefined });
+ }
+ if (what) {
+ this.selectedWhatFilter = what;
+ }
+ });
}
- loadEvents() {
+ loadEvents(overrides: { what?: string; limit?: number } = {}) {
this.isLoading = true;
const today = new Date();
const startDate = new Date(today);
@@ -58,11 +73,12 @@ export class Agenda implements OnInit {
const endDate = new Date(today);
endDate.setMonth(today.getMonth() + 3); // Charger 3 mois après
- const params = {
+ const params: any = {
start: startDate.toISOString().split('T')[0],
end: endDate.toISOString().split('T')[0],
- limit: 1000
+ limit: overrides.limit ?? 1000
};
+ if (overrides.what) params.what = overrides.what;
this.oedbApi.getEvents(params).subscribe((response: any) => {
this.events = Array.isArray(response?.features) ? response.features : [];
@@ -72,6 +88,28 @@ export class Agenda implements OnInit {
});
}
+ loadSingleEvent(id: string | number) {
+ this.isLoading = true;
+ this.oedbApi.getEventById(id).subscribe({
+ next: (feature: any) => {
+ const f = (feature && (feature as any).type === 'Feature') ? feature : (feature?.feature || null);
+ this.events = f ? [f] as OedbEvent[] : [];
+ this.filteredEvents = this.events;
+ this.updateAvailableWhatTypes();
+ this.applyWhatFilter();
+ this.isLoading = false;
+ },
+ error: () => {
+ this.events = [];
+ this.filteredEvents = [];
+ this.calendarEvents = [];
+ this.filteredCalendarEvents = [];
+ this.groupedEvents = [];
+ this.isLoading = false;
+ }
+ });
+ }
+
convertToCalendarEvents() {
const source = this.filteredEvents.length ? this.filteredEvents : this.events;
this.calendarEvents = source.map(event => {
@@ -150,7 +188,8 @@ export class Agenda implements OnInit {
applyWhatFilter() {
if (this.selectedWhatFilter) {
- this.filteredEvents = this.events.filter(e => e?.properties?.what === this.selectedWhatFilter);
+ const prefix = this.selectedWhatFilter;
+ this.filteredEvents = this.events.filter(e => String(e?.properties?.what || '').startsWith(prefix));
} else {
this.filteredEvents = [...this.events];
}
diff --git a/frontend/src/app/pages/community-upcoming/community-upcoming.ts b/frontend/src/app/pages/community-upcoming/community-upcoming.ts
index ff259ae..6ee8315 100644
--- a/frontend/src/app/pages/community-upcoming/community-upcoming.ts
+++ b/frontend/src/app/pages/community-upcoming/community-upcoming.ts
@@ -25,8 +25,10 @@ export class CommunityUpcoming {
// when: NEXT7DAYS etc. Utilise le param 'when' déjà supporté par l'API
const d = Math.max(1, Number(this.days()) || 7);
const when = `NEXT${d}DAYS`;
- this.api.getEvents({ when, what: 'commu', limit: 1000 }).subscribe((events: any) => {
- this.features = Array.isArray(events?.features) ? events.features : [];
+ this.api.getEvents({ when, what: 'community', limit: 1000 }).subscribe((events: any) => {
+ const list = Array.isArray(events?.features) ? events.features : [];
+ // Filtrer côté client pour tout ce qui commence par "community"
+ this.features = list.filter((f: any) => String(f?.properties?.what || '').startsWith('community'));
});
}
}
diff --git a/frontend/src/app/pages/events-docs/events-docs.html b/frontend/src/app/pages/events-docs/events-docs.html
index 255ebb2..3bc0278 100644
--- a/frontend/src/app/pages/events-docs/events-docs.html
+++ b/frontend/src/app/pages/events-docs/events-docs.html
@@ -4,7 +4,7 @@
(1000 prochains pour les 30 prochains jours)
-
-
+
@@ -14,4 +14,62 @@
+@if (selectedWhatType && selectedTypeDetails) {
+
+
+
+
+
+
{{ selectedTypeDetails.description || 'Aucune description disponible' }}
+
+ @if (selectedTypeDetails.category) {
+
+ Catégorie: {{ selectedTypeDetails.category }}
+
+ }
+
+ @if (selectedTypeDetails.label && selectedTypeDetails.label !== selectedWhatType) {
+
+ Nom court: {{ selectedTypeDetails.label }}
+
+ }
+
+ @if (selectedTypeDetails.durationHours) {
+
+ Durée par défaut: {{ selectedTypeDetails.durationHours }} heures
+
+ }
+
+ @if (getPropertiesForWhat(selectedWhatType)) {
+
+
Propriétés disponibles:
+
+ @for (prop of getObjectKeys(getPropertiesForWhat(selectedWhatType)); track prop) {
+ -
+ {{ prop }}:
+ {{ getPropertiesForWhat(selectedWhatType)[prop].label || prop }}
+ @if (getPropertiesForWhat(selectedWhatType)[prop].description) {
+ ({{ getPropertiesForWhat(selectedWhatType)[prop].description }})
+ }
+
+ }
+
+
+ }
+
+
+
+}
+
diff --git a/frontend/src/app/pages/events-docs/events-docs.scss b/frontend/src/app/pages/events-docs/events-docs.scss
index 1c8d4bd..859d677 100644
--- a/frontend/src/app/pages/events-docs/events-docs.scss
+++ b/frontend/src/app/pages/events-docs/events-docs.scss
@@ -21,4 +21,103 @@
min-height: 60vh;
}
+.type-details-panel {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: #fff;
+ border-top: 2px solid #1976d2;
+ box-shadow: 0 -4px 12px rgba(0,0,0,0.15);
+ z-index: 1000;
+ max-height: 50vh;
+ overflow: hidden;
+}
+
+.panel-content {
+ padding: 16px;
+ max-height: 50vh;
+ overflow-y: auto;
+}
+
+.panel-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #e0e0e0;
+}
+
+.panel-header h3 {
+ margin: 0;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.emoji {
+ font-size: 1.2em;
+}
+
+.type-image {
+ width: 24px;
+ height: 24px;
+ object-fit: contain;
+}
+
+.close-btn {
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ font-size: 18px;
+ line-height: 1;
+}
+
+.close-btn:hover {
+ background: #e0e0e0;
+}
+
+.panel-body {
+ .description {
+ margin: 0 0 12px 0;
+ color: #555;
+ line-height: 1.4;
+ }
+}
+
+.detail-item {
+ margin-bottom: 8px;
+
+ strong {
+ color: #1976d2;
+ }
+}
+
+.properties-list {
+ margin: 8px 0 0 16px;
+ padding: 0;
+
+ li {
+ margin-bottom: 4px;
+ list-style: none;
+
+ .prop-desc {
+ color: #666;
+ font-style: italic;
+ }
+ }
+}
+
+button.selected {
+ background: #e3f2fd;
+ border-color: #1976d2;
+}
+
diff --git a/frontend/src/app/pages/events-docs/events-docs.ts b/frontend/src/app/pages/events-docs/events-docs.ts
index 4f91407..dc21319 100644
--- a/frontend/src/app/pages/events-docs/events-docs.ts
+++ b/frontend/src/app/pages/events-docs/events-docs.ts
@@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OedbApi } from '../../services/oedb-api';
import { AllEvents } from '../../maps/all-events/all-events';
+import oedb from '../../../oedb-types';
@Component({
selector: 'app-events-docs',
@@ -16,6 +17,8 @@ export class EventsDocs {
counts: Array<{ what: string, count: number }> = [];
filtered: Array
= [];
selected: any | null = null;
+ selectedWhatType: string | null = null;
+ selectedTypeDetails: any = null;
ngOnInit() {
// Charger 1000 events récents
@@ -38,6 +41,36 @@ export class EventsDocs {
filterByWhat(what: string) {
this.filtered = this.features.filter(f => String(f?.properties?.what || '').startsWith(what));
+ this.selectedWhatType = what;
+ this.loadTypeDetails(what);
+ }
+
+ loadTypeDetails(what: string) {
+ const presets = oedb.presets.what as any;
+ this.selectedTypeDetails = presets[what] || null;
+ }
+
+ getEmojiForWhat(what: string): string | null {
+ const details = this.selectedTypeDetails;
+ return details?.emoji || null;
+ }
+
+ getImageForWhat(what: string): string | null {
+ const details = this.selectedTypeDetails;
+ if (details?.image) {
+ const img: string = details.image;
+ return img.startsWith('/') ? img : `/${img}`;
+ }
+ return null;
+ }
+
+ getPropertiesForWhat(what: string): any {
+ const details = this.selectedTypeDetails;
+ return details?.properties || null;
+ }
+
+ getObjectKeys(obj: any): string[] {
+ return Object.keys(obj || {});
}
}
diff --git a/frontend/src/app/pages/home/home.html b/frontend/src/app/pages/home/home.html
index 23ddfb0..c25a50a 100644
--- a/frontend/src/app/pages/home/home.html
+++ b/frontend/src/app/pages/home/home.html
@@ -1,42 +1,46 @@
+ @if(showOptions){
-
-
- @if (isLoading) {
- ⏳
- }
-
-
-
-
-
+
-