nav mobile
This commit is contained in:
parent
f8abb4d11a
commit
912b4da08e
8 changed files with 234 additions and 52 deletions
|
|
@ -15,24 +15,33 @@
|
|||
<div class="content">
|
||||
|
||||
<header>
|
||||
|
||||
|
||||
<nav>
|
||||
<a [routerLink]="['/']" routerLinkActive="active"><h1>
|
||||
<img src="/static/oedb.png" alt="OEDB" style="width: 20px; height: 20px;">
|
||||
OEDB
|
||||
</h1>
|
||||
</a>
|
||||
<!-- <button class="login">login OSM</button> -->
|
||||
|
||||
<a routerLink="/agenda" routerLinkActive="active">agenda</a>
|
||||
<a routerLink="/unlocated-events" routerLinkActive="active">événements non localisés</a>
|
||||
<a routerLink="/batch-edit" routerLinkActive="active">batch edit</a>
|
||||
<a routerLink="/events-docs" routerLinkActive="active">events docs</a>
|
||||
<a routerLink="/research" routerLinkActive="active">research</a>
|
||||
<a routerLink="/nouvelles-categories" routerLinkActive="active">nouvelles catégories</a>
|
||||
<a href="/stats" routerLinkActive="active">stats</a>
|
||||
<a href="https://source.cipherbliss.com/tykayn/oedb-backend" routerLinkActive="active">sources</a>
|
||||
<div class="nav-header">
|
||||
<a [routerLink]="['/']" routerLinkActive="active" class="logo-link">
|
||||
<img src="/static/oedb.png" alt="OEDB" style="width: 20px; height: 20px;">
|
||||
<h1>OEDB</h1>
|
||||
</a>
|
||||
<button
|
||||
class="burger-menu-toggle"
|
||||
(click)="toggleNavMenu()"
|
||||
[attr.aria-expanded]="isNavMenuOpen"
|
||||
aria-label="Toggle navigation menu">
|
||||
<span class="burger-line"></span>
|
||||
<span class="burger-line"></span>
|
||||
<span class="burger-line"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="nav-links" [class.nav-open]="isNavMenuOpen">
|
||||
<a routerLink="/agenda" routerLinkActive="active" (click)="closeNavMenu()">📅 agenda</a>
|
||||
<a routerLink="/unlocated-events" routerLinkActive="active" (click)="closeNavMenu()">📍 événements non localisés</a>
|
||||
<a routerLink="/batch-edit" routerLinkActive="active" (click)="closeNavMenu()">⚡ batch edit</a>
|
||||
<a routerLink="/events-docs" routerLinkActive="active" (click)="closeNavMenu()">📚 events docs</a>
|
||||
<a routerLink="/research" routerLinkActive="active" (click)="closeNavMenu()">🔍 research</a>
|
||||
<a routerLink="/nouvelles-categories" routerLinkActive="active" (click)="closeNavMenu()">🏷️ nouvelles catégories</a>
|
||||
<a href="/stats" routerLinkActive="active" (click)="closeNavMenu()">📊 stats</a>
|
||||
<a href="https://source.cipherbliss.com/tykayn/oedb-backend" routerLinkActive="active" target="_blank" (click)="closeNavMenu()">💻 sources</a>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
|
|
|
|||
|
|
@ -22,4 +22,13 @@ export function momentAdapterFactory() {
|
|||
})
|
||||
export class App {
|
||||
protected readonly title = signal('frontend');
|
||||
isNavMenuOpen = false;
|
||||
|
||||
toggleNavMenu() {
|
||||
this.isNavMenuOpen = !this.isNavMenuOpen;
|
||||
}
|
||||
|
||||
closeNavMenu() {
|
||||
this.isNavMenuOpen = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ export class EmbedView implements OnInit {
|
|||
if (params.what) apiParams.what = params.what;
|
||||
if (params.start) apiParams.start = params.start;
|
||||
if (params.end) apiParams.end = params.end;
|
||||
if (params.bbox) apiParams.bbox = params.bbox;
|
||||
|
||||
this.oedbApi.getEvents(apiParams).subscribe({
|
||||
next: (response: any) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, signal } from '@angular/core';
|
||||
import { Component, signal, OnInit, inject } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Menu } from '../home/menu/menu';
|
||||
|
||||
interface EmbedConfig {
|
||||
|
|
@ -13,6 +14,7 @@ interface EmbedConfig {
|
|||
height: string;
|
||||
theme: string;
|
||||
embedType: 'script' | 'iframe';
|
||||
bbox?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
|
@ -22,10 +24,12 @@ interface EmbedConfig {
|
|||
templateUrl: './embed.html',
|
||||
styleUrl: './embed.scss'
|
||||
})
|
||||
export class Embed {
|
||||
export class Embed implements OnInit {
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
config = signal<EmbedConfig>({
|
||||
apiUrl: 'https://api.openeventdatabase.org',
|
||||
what: 'culture',
|
||||
what: '',
|
||||
start: '',
|
||||
end: '',
|
||||
limit: 50,
|
||||
|
|
@ -40,6 +44,38 @@ export class Embed {
|
|||
constructor() {
|
||||
this.updateConfig();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// Lire les query params pour pré-remplir la configuration
|
||||
this.route.queryParams.subscribe(params => {
|
||||
const currentConfig = this.config();
|
||||
const updatedConfig: EmbedConfig = { ...currentConfig };
|
||||
|
||||
if (params['what']) {
|
||||
updatedConfig.what = params['what'];
|
||||
}
|
||||
|
||||
if (params['start']) {
|
||||
updatedConfig.start = params['start'];
|
||||
}
|
||||
|
||||
if (params['end']) {
|
||||
updatedConfig.end = params['end'];
|
||||
}
|
||||
|
||||
if (params['limit']) {
|
||||
updatedConfig.limit = parseInt(params['limit'], 10) || 50;
|
||||
}
|
||||
|
||||
if (params['bbox']) {
|
||||
// Bbox sera passé dans les paramètres de l'API
|
||||
(updatedConfig as any).bbox = params['bbox'];
|
||||
}
|
||||
|
||||
this.config.set(updatedConfig);
|
||||
this.updateConfig();
|
||||
});
|
||||
}
|
||||
updateConfig() {
|
||||
const config = this.config();
|
||||
const code = this.generateEmbedCode(config);
|
||||
|
|
@ -51,7 +87,8 @@ export class Embed {
|
|||
if (config.what) params.set('what', config.what);
|
||||
if (config.start) params.set('start', config.start);
|
||||
if (config.end) params.set('end', config.end);
|
||||
if (config.limit) params.set('limit', config.limit.toString());
|
||||
if (config.limit) params.set('limit', config.limit.toString());
|
||||
if (config.bbox) params.set('bbox', config.bbox);
|
||||
|
||||
const queryString = params.toString();
|
||||
|
||||
|
|
@ -71,13 +108,15 @@ export class Embed {
|
|||
} else {
|
||||
// Code script (ancienne méthode)
|
||||
const scriptUrl = `${window.location.origin}/embed.js`;
|
||||
const paramsObj = queryString ?
|
||||
queryString.split('&').map(param => {
|
||||
const [key, value] = param.split('=');
|
||||
return ` '${key}': '${decodeURIComponent(value || '')}'`;
|
||||
}).join(',\n') : '';
|
||||
// Construire l'objet params pour le script
|
||||
const paramsObj: string[] = [];
|
||||
if (config.what) paramsObj.push(` 'what': '${config.what}'`);
|
||||
if (config.start) paramsObj.push(` 'start': '${config.start}'`);
|
||||
if (config.end) paramsObj.push(` 'end': '${config.end}'`);
|
||||
if (config.limit) paramsObj.push(` 'limit': '${config.limit}'`);
|
||||
if (config.bbox) paramsObj.push(` 'bbox': '${config.bbox}'`);
|
||||
|
||||
const paramsCode = paramsObj ? ` params: {\n${paramsObj}\n },\n` : '';
|
||||
const paramsCode = paramsObj.length > 0 ? ` params: {\n${paramsObj.join(',\n')}\n },\n` : '';
|
||||
|
||||
return `<!-- OpenEventDatabase Embed (script) -->
|
||||
<div id="oedb-events" style="width: ${config.width}; height: ${config.height}; border: 1px solid #ddd; border-radius: 8px; overflow: hidden;"></div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
@if (isLoading) {
|
||||
<span class="loading-indicator">⏳</span>
|
||||
}
|
||||
<a routerLink="/embed" class="btn-share" title="Partager et intégrer les événements">
|
||||
<a [routerLink]="['/embed']" [queryParams]="getShareQueryParams()" class="btn-share" title="Partager et intégrer les événements">
|
||||
🔗 Partager
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -852,4 +852,31 @@ export class Home implements OnInit, OnDestroy {
|
|||
onMapMove(bbox: { minLng: number, minLat: number, maxLng: number, maxLat: number }) {
|
||||
this.setCurrentBbox(bbox);
|
||||
}
|
||||
|
||||
getShareQueryParams(): any {
|
||||
const params: any = {};
|
||||
|
||||
// Récupérer les paramètres de filtrage actuels
|
||||
if (this.selectedWhatFilter) {
|
||||
params.what = this.selectedWhatFilter;
|
||||
}
|
||||
|
||||
if (this.startDateStr) {
|
||||
params.start = this.startDateStr;
|
||||
}
|
||||
|
||||
if (this.endDateStr) {
|
||||
params.end = this.endDateStr;
|
||||
}
|
||||
|
||||
// Ajouter bbox si disponible
|
||||
if (this.useBboxFilter && this.currentBbox) {
|
||||
params.bbox = `${this.currentBbox.minLng},${this.currentBbox.minLat},${this.currentBbox.maxLng},${this.currentBbox.maxLat}`;
|
||||
}
|
||||
|
||||
// Limite par défaut pour l'embed
|
||||
params.limit = 50;
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
<div class="nav-section">
|
||||
<h3>Communauté</h3>
|
||||
<a routerLink="/community-upcoming" class="link" (click)="closeMenu()">👥 Community à venir</a>
|
||||
<a href="https://community.openstreetmap.org/" class="link" target="_blank" (click)="closeMenu()">💬 Forum OpenStreetMap</a>
|
||||
<a href="https://source.cipherbliss.com/tykayn/oedb-backend" class="link" target="_blank" (click)="closeMenu()">💻 Sources</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -190,26 +190,7 @@ pre{
|
|||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
nav{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
a {
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&:hover{
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Styles nav génériques (remplacés par .main nav dans la section suivante)
|
||||
|
||||
.row, .filters, .controls{
|
||||
input{
|
||||
|
|
@ -256,13 +237,128 @@ nav{
|
|||
|
||||
.main{
|
||||
nav{
|
||||
background: $color-text ;
|
||||
background: $color-text;
|
||||
position: relative;
|
||||
|
||||
.nav-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
gap: 1rem;
|
||||
|
||||
.logo-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.burger-menu-toggle {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
z-index: 1001;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid white;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.burger-line {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: white;
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s ease;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.burger-menu-toggle[aria-expanded="true"] {
|
||||
.burger-line:nth-child(1) {
|
||||
transform: rotate(45deg) translate(7px, 7px);
|
||||
}
|
||||
|
||||
.burger-line:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.burger-line:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(7px, -7px);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
padding: 0 10px 10px 10px;
|
||||
flex-wrap: wrap;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
flex-direction: column;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
padding: 0 10px;
|
||||
gap: 0;
|
||||
|
||||
&.nav-open {
|
||||
max-height: 1000px;
|
||||
opacity: 1;
|
||||
padding: 0 10px 10px 10px;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
background: white;
|
||||
color: $color-text;
|
||||
color: $color-text;
|
||||
}
|
||||
|
||||
&.router-link-active, &.active {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue