Files
fltr-app/app/participant.tsx
2025-10-07 20:09:34 +02:00

133 lines
4.4 KiB
TypeScript

import { View, Image, Text, TouchableOpacity } from "react-native";
import styles from "@/app/stackStyles/participantStyles";
import Ionicons from "@expo/vector-icons/Ionicons";
import React, { useEffect, useMemo, useState } from "react";
import { router, useLocalSearchParams } from "expo-router";
import { usePersonContext } from "@/contexts/PersonContext";
import {
ScrollView,
GestureHandlerRootView,
} from "react-native-gesture-handler";
import { useShowContext } from "@/contexts/ShowContext";
import { getPersonHistory } from "@/apis/personApi";
export default function ParticipantScreen() {
const { getPersonAppearances, isLoading, getError } = usePersonContext();
const [appearances, setAppearances] = useState<
{
showId: number;
seasons: number[];
}[]
>([]);
const { shows, error, loading } = useShowContext();
const { participantId, name, season } = useLocalSearchParams();
const numericId = Array.isArray(participantId)
? Number(participantId[0])
: Number(participantId);
useEffect(() => {
let active = true;
(async () => {
if (!numericId || Number.isNaN(numericId)) return;
const data = await getPersonAppearances(numericId);
if (!active) return;
const grouped = data.showIds.map((id) => ({
showId: id,
seasons: data.byShow[id],
}));
setAppearances(grouped);
})();
return () => {
active = false;
};
}, [numericId, getPersonAppearances]);
const resolved = useMemo(
() =>
appearances
.map((a) => {
const show = shows.find((s) => s.id === a.showId);
if (!show) return null;
return { show, seasons: a.seasons };
})
.filter(
(v): v is { show: (typeof shows)[number]; seasons: number[] } => !!v
),
[appearances, shows]
);
return (
<GestureHandlerRootView style={styles.mainContainer}>
<ScrollView showsVerticalScrollIndicator={false}>
<Text style={styles.participantName}>
{name ? (Array.isArray(name) ? name[0] : name) : "Teilnehmer"}
</Text>
<TouchableOpacity
style={styles.closeIcon}
onPress={() => router.back()}
>
<Ionicons name="close-circle-outline" size={38} color="white" />
</TouchableOpacity>
<View style={styles.participantInfoSection}>
<Text style={styles.participantInfo}>Single</Text>
<View style={styles.dot} />
<Text style={styles.participantInfo}>24 Jahre</Text>
<View style={styles.dot} />
<Text style={styles.participantInfo}>Köln</Text>
</View>
<Image
source={{
uri: "https://www.fernseh-puls.com/wp-content/uploads/are-you-the-one-calvin-o-im-steckbrief-wir-stellen-euch-den-kandidaten-vor.jpg",
}}
style={styles.participantImage}
/>
<View style={styles.performedShowsSection}>
<Text style={styles.performedShowsTitle}>Auftritte:</Text>
{isLoading(numericId) && (
<Text style={{ color: "white", marginTop: 8 }}>Lädt...</Text>
)}
{getError(numericId) && (
<Text style={{ color: "red", marginTop: 8 }}>
{getError(numericId)}
</Text>
)}
{!isLoading(numericId) &&
resolved.length === 0 &&
!getError(numericId) && (
<Text style={{ color: "gray", marginTop: 8 }}>
Keine Einträge.
</Text>
)}
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={{
width: "100%",
marginTop: 15,
}}
>
{resolved.map(({ show, seasons }) => (
<TouchableOpacity key={show.id} style={styles.showContainer}>
<Image
source={{ uri: show.thumbnailUri }}
style={styles.showImage}
/>
<Text style={styles.showTitle} numberOfLines={2}>
{show.title}
</Text>
<Text style={styles.showSeason} numberOfLines={1}>
Staffel
{seasons.length === 1
? ` ${seasons[0]}`
: `n ${seasons.join(", ")}`}
</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
</ScrollView>
</GestureHandlerRootView>
);
}