api: reconfigered api handling

This commit is contained in:
Yordan Simeonov
2025-10-20 18:45:01 +02:00
parent d0194f0dc2
commit 98a2067b8d
9 changed files with 112 additions and 295 deletions

View File

@@ -1,7 +1,7 @@
import { ShowProvider } from "@/contexts/ShowContext";
import { SeasonProvider } from "@/contexts/SeasonContext";
import { ShowProvider } from "@/contexts/ShowContext";
import { StreamingServiceProvider } from "@/contexts/StreamingServiceContext";
import { PersonProvider } from "@/contexts/PersonContext";
import { DiscoveryProvider } from "@/contexts/DiscoveryContext";
import { Stack } from "expo-router";
import "react-native-reanimated";
@@ -11,7 +11,7 @@ export default function RootLayout() {
<ShowProvider>
<SeasonProvider>
<StreamingServiceProvider>
<PersonProvider>
<DiscoveryProvider>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
@@ -30,7 +30,7 @@ export default function RootLayout() {
/>
</Stack>
</DiscoveryProvider>
</PersonProvider>
</StreamingServiceProvider>
</SeasonProvider>
</ShowProvider>

View File

@@ -1,47 +1,28 @@
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 * as WebBrowser from "expo-web-browser";
import {
ScrollView,
GestureHandlerRootView,
} from "react-native-gesture-handler";
import React, { useMemo, useState } from "react";
import { Image, Text, TouchableOpacity, View } from "react-native";
import { useShowContext } from "@/contexts/ShowContext";
import {
GestureHandlerRootView,
ScrollView,
} from "react-native-gesture-handler";
export default function ParticipantScreen() {
const { getPersonAppearances, isLoading, getError } = usePersonContext();
const [appearances, setAppearances] = useState<
const [appearances,] = 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);
const { shows} = useShowContext();
const { name } = useLocalSearchParams();
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],
partners: data.partnersByShow[id] || [],
}));
setAppearances(grouped as any);
})();
return () => {
active = false;
};
}, [numericId, getPersonAppearances]);
const resolved = useMemo(
() =>
@@ -88,21 +69,9 @@ export default function ParticipantScreen() {
<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}

View File

@@ -23,14 +23,13 @@ export default function ShowDetails() {
genres,
streamingService,
id,
endDate,
} = useLocalSearchParams();
const [selectedParticipants, setSelectedParticipants] =
React.useState<boolean>(true);
const [selectedSeason, setSelectedSeason] = React.useState<number>(1);
const showId = Number(id);
const { fetchSeasonParticipants, fetchSeasonCount } = useSeasonContext();
const { fetchSeasonParticipants, fetchSeasonCount, fetchSeasonDates } = useSeasonContext();
const [seasonCount, setSeasonCount] = React.useState<number>(0);
const [participants, setParticipants] = React.useState<
{ id: number; name: string; imageUri: string }[]
@@ -62,15 +61,21 @@ export default function ShowDetails() {
};
}, [showId, fetchSeasonCount, selectedSeason]);
React.useEffect(() => {
React.useEffect(() => {
if (!showId || !selectedSeason) return;
let active = true;
(async () => {
setPError(null);
setPLoading(true);
try {
const data = await fetchSeasonParticipants(showId, selectedSeason);
if (active) setParticipants(data);
const [data, dates] = await Promise.all([
fetchSeasonParticipants(showId, selectedSeason),
fetchSeasonDates(showId, selectedSeason),
]);
if (active) {
setParticipants(data);
setStartDate(dates?.startDate);
}
} catch {
if (active) setPError("Fehler beim Laden");
} finally {
@@ -80,14 +85,18 @@ export default function ShowDetails() {
return () => {
active = false;
};
}, [showId, selectedSeason, fetchSeasonParticipants]);
}, [showId, selectedSeason, fetchSeasonParticipants, fetchSeasonDates]);
const startDateObj = new Date(startDate as string);
const formattedStartDate = startDateObj.toLocaleDateString("de-DE", {
day: "2-digit",
month: "long",
year: "numeric",
});
const formattedStartDate = React.useMemo(() => {
if (!startDate) return "";
const d = new Date(startDate);
if (isNaN(d.getTime())) return "";
return d.toLocaleDateString("de-DE", {
day: "2-digit",
month: "long",
year: "numeric",
});
}, [startDate]);
return (
<View style={styles.mainContainer}>
@@ -98,7 +107,10 @@ export default function ShowDetails() {
paddingBottom: Dimensions.get("window").height * 0.1,
}}
>
<Text style={styles.startDate}>{formattedStartDate}</Text>
{formattedStartDate ? (
<Text style={styles.startDate}>{formattedStartDate}</Text>
) : null}
<ShowInfo
seasons={seasonCount}
participants={participants.length}