Initial commit

Created from https://vercel.com/new
This commit is contained in:
MrPatator230 committed 2026-03-19 15:46:03 +00:00
commit 3fcdf7e5ef
172 files changed
+52525

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
import React, { useEffect, useState } from 'react';
import supabase from '../lib/supabase';
import sessionMemory from '../lib/sessionMemory';
export default function Departs({ onBack, navigate }) {
const [gares, setGares] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [selected, setSelected] = useState('');
const [search, setSearch] = useState('');
useEffect(() => {
let mounted = true;
async function loadGares() {
setLoading(true);
setError(null);
if (!supabase) {
// Le client Supabase n'a pas pu être initialisé (variables d'env manquantes)
if (mounted) {
setError(
"Supabase non initialisé : vérifiez REACT_APP_SUPABASE_URL et REACT_APP_SUPABASE_ANON_KEY dans votre .env et redémarrez le serveur de développement (npm start)."
);
setLoading(false);
}
return;
}
try {
const { data, error } = await supabase.from('gares').select('nom');
if (error) throw error;
if (mounted) setGares(Array.isArray(data) ? data.map((r) => r.nom) : []);
} catch (err) {
console.error('Supabase error:', err);
if (mounted) setError(err.message || String(err));
} finally {
if (mounted) setLoading(false);
}
}
loadGares();
return () => {
mounted = false;
};
}, []);
return (
<div style={{ padding: 20 }}>
<h1>Départs</h1>
{loading && <p>Chargement des gares...</p>}
{error && <p style={{ color: 'red' }}>Erreur : {error}</p>}
{!loading && !error && (
<div>
{/* Barre de recherche centrée */}
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>
<input
type="search"
placeholder="Rechercher une gare..."
value={search}
onChange={(e) => setSearch(e.target.value)}
style={{ width: '60%', padding: '10px 12px', borderRadius: 6, border: '1px solid #ccc' }}
aria-label="Rechercher une gare"
/>
</div>
{/* Résultats sous forme de lignes */}
<div role="list" aria-label="Résultats des gares">
{gares
.filter((nom) => nom.toLowerCase().includes(search.trim().toLowerCase()))
.map((nom) => (
<div key={nom} role="listitem">
<div
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', cursor: 'pointer' }}
onClick={() => {
setSelected(nom);
try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {}
if (navigate) navigate(`/afficheurs/${encodeURIComponent(nom)}?mode=departs`);
}}
onKeyDown={(e) => (e.key === 'Enter' ? (navigate ? navigate(`/afficheurs/${encodeURIComponent(nom)}?mode=departs`) : setSelected(nom)) : null)}
tabIndex={0}
>
<div>{nom}</div>
{selected === nom && <div style={{ color: '#0070f3' }}>Sélectionnée</div>}
</div>
<div style={{ height: 1, background: '#e0e0e0', margin: '6px 0' }} />
</div>
))}
</div>
{selected && (
<div style={{ marginTop: 12 }}>
<p>Gare sélectionnée : <strong>{selected}</strong></p>
<button onClick={() => {
try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {}
if (navigate) {
navigate(`/afficheurs/${encodeURIComponent(selected)}?mode=departs`);
} else {
alert(`Afficher les départs pour ${selected}`);
}
}}>Voir les départs</button>
</div>
)}
</div>
)}
<div style={{ marginTop: 20 }}>
<button onClick={onBack}>Retour</button>
</div>
</div>
);
}