Tela de Detalhe
Crie src/EventDetailScreen.tsx:
import { useState, useEffect } from "react";
import { View, Text, StyleSheet, ActivityIndicator } from "react-native";
import { RouteProp, useRoute } from "@react-navigation/native";
import { Event } from "./types";
import { API_BASE_URL } from "./config";
import { RootStackParamList } from "./navigation";
type DetailRoute = RouteProp<RootStackParamList, "EventDetail">;
export default function EventDetailScreen() {
const route = useRoute<DetailRoute>();
const { eventId } = route.params;
const [event, setEvent] = useState<Event | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
fetch(`${API_BASE_URL}/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 === eventId);
if (!found) throw new Error("Evento não encontrado");
setEvent(found);
})
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, [eventId]);
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#3182ce" />
</View>
);
}
if (error) {
return (
<View style={styles.center}>
<Text style={styles.error}>{error}</Text>
</View>
);
}
if (!event) return null;
return (
<View style={styles.container}>
<Text style={styles.title}>{event.title}</Text>
<Text style={styles.date}>
{new Date(event.date).toLocaleString("pt-BR", {
dateStyle: "full",
timeStyle: "short",
})}
</Text>
<Text style={styles.description}>{event.description}</Text>
<Text style={styles.location}>📍 {event.location}</Text>
<Text style={styles.info}>
Capacidade: {event.capacity} pessoas
</Text>
<Text style={styles.info}>
Organizado por {event.organizer_name}
</Text>
</View>
);
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
container: {
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "700",
marginBottom: 8,
},
date: {
color: "#718096",
fontSize: 15,
marginBottom: 16,
},
description: {
fontSize: 16,
lineHeight: 24,
marginBottom: 16,
},
location: {
fontSize: 15,
marginBottom: 8,
},
info: {
fontSize: 15,
color: "#4a5568",
marginBottom: 4,
},
error: {
color: "#e53e3e",
fontSize: 16,
},
});
Código 8-7: Tela de detalhe do evento.
O useRoute extrai os parâmetros da rota — nesse caso, o eventId. O resto
do padrão (fetch, loading, error) é o mesmo do EventList. A diferença é
visual: a tela de detalhe usa fontes maiores e mais espaçamento, já que
dispõe da tela inteira em vez de dividir espaço com outros cards.
O botão “voltar” aparece automaticamente. O stack navigator coloca uma seta no canto superior esquerdo de qualquer tela que não seja a primeira da pilha. No Android, o botão de voltar do sistema (gesto de swipe ou botão virtual) também funciona sem nenhum código adicional.