Tela de Detalhe
O EventDetail precisa buscar os dados de um único evento. O backend ainda não
tem um endpoint GET /api/events/:id — ele retorna a lista completa. Então
vamos buscar a lista e filtrar pelo id no frontend1.
Crie src/EventDetail.tsx:
import { useState, useEffect } from "react";
import { useParams, Link } from "react-router-dom";
import { Event } from "./types";
function EventDetail() {
const { id } = useParams<{ id: string }>();
const [event, setEvent] = useState<Event | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
fetch("/api/events")
.then((res) => {
if (!res.ok) throw new Error(`Erro ${res.status}`);
return res.json();
})
.then((data: Event[]) => {
const found = data.find((ev) => ev.id === Number(id));
if (!found) throw new Error("Evento não encontrado");
setEvent(found);
})
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, [id]);
if (loading) return <p>Carregando...</p>;
if (error) return <p>{error}</p>;
if (!event) return null;
return (
<div>
<Link to="/">← Voltar</Link>
<h1>{event.title}</h1>
<time dateTime={event.date}>
{new Date(event.date).toLocaleString("pt-BR", {
dateStyle: "full",
timeStyle: "short",
})}
</time>
<p>{event.description}</p>
<p>📍 {event.location}</p>
<p>Capacidade: {event.capacity} pessoas</p>
<p>Organizado por {event.organizer_name}</p>
</div>
);
}
export default EventDetail;
Código 7-9: Tela de detalhe que exibe um único evento.
O useParams extrai o id da URL. O useEffect tem [id] na lista de
dependências — se o usuário navegar de /events/3 para /events/7 sem voltar
à lista, o efeito roda novamente com o novo id.
A data aqui usa dateStyle: "full" para mostrar o formato extenso: “segunda-
feira, 15 de setembro de 2026, 08:00”. A lista usava o formato curto. Cada tela
mostra o nível de detalhe adequado.
-
Buscar a lista inteira para exibir um evento é desperdício de banda e processamento. O exercício 6 do capítulo Armazenando e Servindo Dados propõe criar o endpoint
GET /api/events/:id. Se você o implementou, use-o aqui em vez de buscar a lista completa. ↩