add embed, research pages

This commit is contained in:
Tykayn 2025-10-12 17:19:50 +02:00 committed by tykayn
parent 2238380e80
commit 2c95bea01b
24 changed files with 2925 additions and 251 deletions

View file

@ -0,0 +1,142 @@
<div class="embed-page">
<div class="layout">
<div class="aside">
<app-menu></app-menu>
</div>
<div class="main">
<div class="container">
<header class="page-header">
<h1>Intégration OEDB</h1>
<p>Générez un code d'intégration pour afficher les événements OEDB sur votre site web</p>
</header>
<div class="embed-config">
<div class="config-form">
<h2>Configuration</h2>
<div class="form-group">
<label for="apiUrl">URL de l'API :</label>
<input
id="apiUrl"
type="url"
[(ngModel)]="config().apiUrl"
(ngModelChange)="updateConfig()"
placeholder="https://api.oedb.fr">
</div>
<div class="form-group">
<label for="what">Type d'événements :</label>
<select
id="what"
[(ngModel)]="config().what"
(ngModelChange)="updateConfig()">
<option value="culture">Culture</option>
<option value="traffic">Trafic</option>
<option value="sport">Sport</option>
<option value="education">Éducation</option>
<option value="">Tous</option>
</select>
</div>
<div class="form-row">
<div class="form-group">
<label for="start">Date de début :</label>
<input
id="start"
type="date"
[(ngModel)]="config().start"
(ngModelChange)="updateConfig()">
</div>
<div class="form-group">
<label for="end">Date de fin :</label>
<input
id="end"
type="date"
[(ngModel)]="config().end"
(ngModelChange)="updateConfig()">
</div>
</div>
<div class="form-group">
<label for="limit">Nombre d'événements :</label>
<input
id="limit"
type="number"
[(ngModel)]="config().limit"
(ngModelChange)="updateConfig()"
min="1"
max="1000">
</div>
<div class="form-row">
<div class="form-group">
<label for="width">Largeur :</label>
<input
id="width"
type="text"
[(ngModel)]="config().width"
(ngModelChange)="updateConfig()"
placeholder="100%">
</div>
<div class="form-group">
<label for="height">Hauteur :</label>
<input
id="height"
type="text"
[(ngModel)]="config().height"
(ngModelChange)="updateConfig()"
placeholder="400px">
</div>
</div>
<div class="form-group">
<label for="theme">Thème :</label>
<select
id="theme"
[(ngModel)]="config().theme"
(ngModelChange)="updateConfig()">
<option value="light">Clair</option>
<option value="dark">Sombre</option>
</select>
</div>
</div>
<div class="code-output">
<div class="code-header">
<h2>Code d'intégration</h2>
<div class="code-actions">
<button class="btn btn-secondary" (click)="preview()">Aperçu</button>
<button class="btn btn-primary" (click)="copyToClipboard()">Copier</button>
</div>
</div>
<div class="code-container">
<pre><code>{{generatedCode()}}</code></pre>
</div>
</div>
</div>
<div class="usage-info">
<h2>Comment utiliser</h2>
<ol>
<li>Configurez les paramètres ci-dessus selon vos besoins</li>
<li>Copiez le code généré</li>
<li>Collez-le dans votre page HTML</li>
<li>Le script chargera automatiquement les événements depuis l'API OEDB</li>
</ol>
<div class="features">
<h3>Fonctionnalités</h3>
<ul>
<li>✅ Affichage responsive des événements</li>
<li>✅ Filtrage par type et dates</li>
<li>✅ Thèmes clair et sombre</li>
<li>✅ Mise à jour automatique</li>
<li>✅ Compatible avec tous les navigateurs</li>
</ul>
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,220 @@
.embed-page {
min-height: 100vh;
background: #f8f9fa;
padding: 2rem 0;
}
.layout {
display: grid;
grid-template-columns: 400px 1fr;
grid-template-rows: minmax(100vh, auto);
gap: 0;
min-height: 100vh;
&.is-small {
grid-template-columns: 100px 1fr;
}
}
.aside {
background: #f8f9fa;
border-right: 1px solid #e9ecef;
overflow-y: auto;
}
.main {
background: white;
overflow-y: auto;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.page-header {
text-align: center;
margin-bottom: 3rem;
h1 {
color: #2c3e50;
margin-bottom: 0.5rem;
}
p {
color: #6c757d;
font-size: 1.1rem;
}
}
.embed-config {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin-bottom: 3rem;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
}
.config-form {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
h2 {
color: #2c3e50;
margin-bottom: 1.5rem;
border-bottom: 2px solid #3498db;
padding-bottom: 0.5rem;
}
.form-group {
margin-bottom: 1.5rem;
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #2c3e50;
}
input, select {
width: 100%;
padding: 0.75rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
transition: border-color 0.3s;
&:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
}
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
}
.code-output {
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
.code-header {
background: #2c3e50;
color: white;
padding: 1rem 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
h2 {
margin: 0;
font-size: 1.2rem;
}
.code-actions {
display: flex;
gap: 0.5rem;
}
}
.code-container {
padding: 1.5rem;
background: #f8f9fa;
pre {
margin: 0;
background: #2c3e50;
color: #ecf0f1;
padding: 1rem;
border-radius: 4px;
overflow-x: auto;
font-size: 0.9rem;
line-height: 1.4;
code {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
}
}
}
.usage-info {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
h2 {
color: #2c3e50;
margin-bottom: 1rem;
}
h3 {
color: #34495e;
margin: 1.5rem 0 1rem 0;
}
ol {
padding-left: 1.5rem;
margin-bottom: 2rem;
li {
margin-bottom: 0.5rem;
line-height: 1.6;
}
}
.features {
ul {
list-style: none;
padding: 0;
li {
padding: 0.5rem 0;
border-bottom: 1px solid #ecf0f1;
color: #2c3e50;
}
}
}
}
.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 600;
transition: all 0.3s;
&.btn-primary {
background: #3498db;
color: white;
&:hover {
background: #2980b9;
}
}
&.btn-secondary {
background: #95a5a6;
color: white;
&:hover {
background: #7f8c8d;
}
}
}

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Embed } from './embed';
describe('Embed', () => {
let component: Embed;
let fixture: ComponentFixture<Embed>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [Embed]
})
.compileComponents();
fixture = TestBed.createComponent(Embed);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,103 @@
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Menu } from '../home/menu/menu';
interface EmbedConfig {
apiUrl: string;
what: string;
start: string;
end: string;
limit: number;
width: string;
height: string;
theme: string;
}
@Component({
selector: 'app-embed',
standalone: true,
imports: [CommonModule, FormsModule, Menu],
templateUrl: './embed.html',
styleUrl: './embed.scss'
})
export class Embed {
config = signal<EmbedConfig>({
apiUrl: 'https://api.oedb.fr',
what: 'culture',
start: '',
end: '',
limit: 50,
width: '100%',
height: '400px',
theme: 'light'
});
generatedCode = signal<string>('');
updateConfig() {
const config = this.config();
const code = this.generateEmbedCode(config);
this.generatedCode.set(code);
}
private generateEmbedCode(config: EmbedConfig): string {
const params = new URLSearchParams();
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());
const queryString = params.toString();
const scriptUrl = `${window.location.origin}/embed.js`;
return `<!-- Intégration OEDB Embed -->
<div id="oedb-events" style="width: ${config.width}; height: ${config.height}; border: 1px solid #ddd; border-radius: 8px; overflow: hidden;"></div>
<script src="${scriptUrl}"></script>
<script>
OEDBEmbed.init({
container: '#oedb-events',
apiUrl: '${config.apiUrl}',
params: {
${queryString ? queryString.split('&').map(param => `'${param.split('=')[0]}': '${param.split('=')[1]}'`).join(',\n ') : ''}
},
theme: '${config.theme}'
});
</script>`;
}
copyToClipboard() {
const code = this.generatedCode();
navigator.clipboard.writeText(code).then(() => {
// Optionnel : afficher une notification de succès
console.log('Code copié dans le presse-papiers');
});
}
preview() {
// Ouvrir une nouvelle fenêtre avec un aperçu
const previewWindow = window.open('', '_blank', 'width=800,height=600');
if (previewWindow) {
const config = this.config();
const code = this.generateEmbedCode(config);
previewWindow.document.write(`
<!DOCTYPE html>
<html>
<head>
<title>Aperçu OEDB Embed</title>
<style>
body { margin: 0; padding: 20px; font-family: Arial, sans-serif; }
.preview-container { max-width: 100%; }
</style>
</head>
<body>
<h2>Aperçu de l'intégration</h2>
<div class="preview-container">
${code}
</div>
</body>
</html>
`);
}
}
}