// ============================================================================== // Author: Simon-Pierre Boucher // File: frontend/src/pages/Ville.tsx // Desc: Pages programmatiques SEO — /villes (répertoire) et /ville/:ville. // Le serveur rend le même contenu en HTML (restoka/seo.py) ; ici, la // version interactive avec les cartes de restos de l'app. // ============================================================================== import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; import { fetchRestaurants, Restaurant } from "../api"; import RestoCard from "../components/RestoCard"; interface VilleRow { city: string; slug: string; n: number; with_menu: number; } interface VilleData { city: string; slug: string; n: number; with_menu: number; neighbors: VilleRow[]; } async function getJson(path: string): Promise { const res = await fetch(path); if (!res.ok) throw new Error(`${res.status}`); return res.json(); } export function VillesPage() { const [villes, setVilles] = useState(null); const [error, setError] = useState(null); useEffect(() => { getJson<{ villes: VilleRow[] }>("/api/seo/villes") .then((r) => setVilles(r.villes)) .catch((e) => setError(String(e))); window.scrollTo(0, 0); }, []); return (

Restaurants par ville

Toutes les villes du Québec où Resto-Ka recense des restaurants, avec le nombre d'établissements et de menus complets à prix réels.

{error &&
⚠️ {error}
} {!villes && !error &&
Chargement…
} {villes && (
    {villes.map((v) => (
  • {v.city} {" — "} {v.n} établissement{v.n > 1 ? "s" : ""} {v.with_menu > 0 && <> · {v.with_menu} menus}
  • ))}
)}
); } export default function VillePage() { const { ville = "" } = useParams(); const [data, setData] = useState(null); const [restos, setRestos] = useState(null); const [error, setError] = useState(null); useEffect(() => { setData(null); setRestos(null); setError(null); getJson(`/api/seo/ville/${encodeURIComponent(ville)}`) .then((d) => { setData(d); return fetchRestaurants({ city: d.city, limit: 60 }).then((r) => setRestos(r.restaurants)); }) .catch((e) => setError(e.message === "404" ? "Ville inconnue." : String(e))); window.scrollTo(0, 0); }, [ville]); if (error) return (

Page introuvable

⚠️ {error} Voir toutes les villes
); if (!data) return (
Chargement…
); return (

Villes — {data.city}

Restaurants à {data.city}

{data.n} établissement{data.n > 1 ? "s" : ""} {data.with_menu > 0 && ( <> · {data.with_menu} avec menu complet et prix réels )}

{!restos &&
Chargement des restos…
} {restos && restos.map((r) => )}
{data.neighbors.length > 0 && ( <>

Autres villes

{data.neighbors.map((v) => ( {v.city} ({v.n}) ))}

)}

← Tous les restaurants du Québec

); }