157 lines
4.4 KiB
TypeScript
157 lines
4.4 KiB
TypeScript
import { EventsTimeline } from "@/components/live-detail/events-timeline";
|
|
import { LiveLeagueInfo } from "@/components/live-detail/live-league-info";
|
|
import { LiveMatchTabs } from "@/components/live-detail/live-match-tabs";
|
|
import { LiveScoreHeader } from "@/components/live-detail/live-score-header";
|
|
import { OddsCard } from "@/components/live-detail/odds-card";
|
|
import { OtherInfoCard } from "@/components/live-detail/other-info-card";
|
|
import { StatsCard } from "@/components/live-detail/stats-card";
|
|
import { ThemedText } from "@/components/themed-text";
|
|
import { ThemedView } from "@/components/themed-view";
|
|
import { Colors } from "@/constants/theme";
|
|
import { useTheme } from "@/context/ThemeContext";
|
|
import { fetchLiveScore } from "@/lib/api";
|
|
import { LiveScoreMatch } from "@/types/api";
|
|
import { useLocalSearchParams } from "expo-router";
|
|
import React, { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import {
|
|
ActivityIndicator,
|
|
ScrollView,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
View,
|
|
} from "react-native";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
|
|
export default function LiveDetailScreen() {
|
|
const { id, league_id, sport_id } = useLocalSearchParams<{
|
|
id: string;
|
|
league_id: string;
|
|
sport_id: string;
|
|
}>();
|
|
const { theme } = useTheme();
|
|
const { t } = useTranslation();
|
|
const insets = useSafeAreaInsets();
|
|
const isDark = theme === "dark";
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
const [match, setMatch] = useState<LiveScoreMatch | null>(null);
|
|
const [activeTab, setActiveTab] = useState("detail"); // Default to detail to show all data
|
|
|
|
useEffect(() => {
|
|
loadLiveDetail();
|
|
}, [id, league_id]);
|
|
|
|
const loadLiveDetail = async () => {
|
|
try {
|
|
setLoading(true);
|
|
// Fetch live scores for the league
|
|
const sportId = parseInt(sport_id || "1");
|
|
const leagueId = parseInt(league_id || "0");
|
|
|
|
const liveData = await fetchLiveScore(sportId, leagueId);
|
|
|
|
if (liveData && Array.isArray(liveData)) {
|
|
// Find the specific match
|
|
const found = liveData.find((m) => m.event_key.toString() === id);
|
|
if (found) {
|
|
setMatch(found);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<ThemedView style={styles.center}>
|
|
<ActivityIndicator size="large" color={Colors[theme].tint} />
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
if (!match) {
|
|
return (
|
|
<ThemedView style={styles.center}>
|
|
<ThemedText>{t("detail.not_found")}</ThemedText>
|
|
<TouchableOpacity style={styles.retryButton} onPress={loadLiveDetail}>
|
|
<ThemedText style={styles.retryText}>{t("detail.retry")}</ThemedText>
|
|
</TouchableOpacity>
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const renderTabContent = () => {
|
|
switch (activeTab) {
|
|
case "stats":
|
|
return <StatsCard match={match} isDark={isDark} />;
|
|
case "odds":
|
|
return <OddsCard match={match} isDark={isDark} />;
|
|
case "detail":
|
|
return (
|
|
<>
|
|
<OddsCard match={match} isDark={isDark} />
|
|
<StatsCard match={match} isDark={isDark} />
|
|
<EventsTimeline match={match} isDark={isDark} />
|
|
<OtherInfoCard match={match} isDark={isDark} />
|
|
</>
|
|
);
|
|
default:
|
|
return (
|
|
<View style={styles.center}>
|
|
<ThemedText style={{ opacity: 0.5 }}>
|
|
{t("detail.empty_stats")}
|
|
</ThemedText>
|
|
</View>
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<ThemedView style={styles.container}>
|
|
<ScrollView
|
|
bounces={false}
|
|
showsVerticalScrollIndicator={false}
|
|
contentContainerStyle={{ paddingBottom: insets.bottom + 20 }}
|
|
>
|
|
<LiveScoreHeader match={match} topInset={insets.top} />
|
|
<LiveLeagueInfo match={match} />
|
|
<LiveMatchTabs
|
|
activeTab={activeTab}
|
|
onTabChange={setActiveTab}
|
|
isDark={isDark}
|
|
/>
|
|
|
|
{renderTabContent()}
|
|
</ScrollView>
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
center: {
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
padding: 20,
|
|
minHeight: 200,
|
|
},
|
|
retryButton: {
|
|
marginTop: 20,
|
|
paddingHorizontal: 20,
|
|
paddingVertical: 10,
|
|
backgroundColor: "#007AFF",
|
|
borderRadius: 8,
|
|
},
|
|
retryText: {
|
|
color: "#FFF",
|
|
fontWeight: "600",
|
|
},
|
|
});
|