import { ThemedText } from "@/components/themed-text"; import { IconSymbol } from "@/components/ui/icon-symbol"; import { Colors } from "@/constants/theme"; import { useTheme } from "@/context/ThemeContext"; import { addFavorite, removeFavorite } from "@/lib/api"; import { UpcomingMatch } from "@/types/api"; import { Image } from "expo-image"; import { useRouter } from "expo-router"; import React, { useEffect, useState } from "react"; import { Pressable, StyleSheet, TouchableOpacity, View } from "react-native"; interface UpcomingMatchCardProps { match: UpcomingMatch; onFavoriteToggle?: (matchId: string, isFav: boolean) => void; } export function UpcomingMatchCard({ match, onFavoriteToggle, }: UpcomingMatchCardProps) { const router = useRouter(); const { theme } = useTheme(); const [isFav, setIsFav] = useState(match.fav || false); const [loading, setLoading] = useState(false); // 当外部传入的 match.fav 改变时,更新内部状态 useEffect(() => { setIsFav(match.fav || false); }, [match.fav]); const isDark = theme === "dark"; const iconColor = isDark ? Colors.dark.icon : Colors.light.icon; const cardBg = isDark ? "#1C1C1E" : "#FFFFFF"; const borderColor = isDark ? "#38383A" : "#E5E5EA"; const toggleFavorite = async () => { if (loading) return; setLoading(true); const newFavState = !isFav; try { if (newFavState) { await addFavorite({ matchId: match.id, type: "match", typeId: match.id.toString(), notify: true, }); } else { await removeFavorite({ type: "match", typeId: match.id.toString(), }); } setIsFav(newFavState); if (onFavoriteToggle) { onFavoriteToggle(match.id.toString(), newFavState); } } catch (error) { console.error("Toggle favorite error:", error); } finally { setLoading(false); } }; const handlePress = () => { router.push(`/match-detail/${match.id}`); }; // 格式化日期时间 const formatDateTime = () => { if (match.eventDate && match.eventTime) { return `${match.eventDate} ${match.eventTime}`; } return match.eventDate || match.eventTime || ""; }; return ( [ styles.card, { backgroundColor: cardBg, borderColor, opacity: pressed ? 0.7 : 1 }, ]} > {match.leagueLogo && ( )} {match.leagueName} {formatDateTime()} { e.stopPropagation(); toggleFavorite(); }} disabled={loading} style={{ marginLeft: 8 }} hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }} > {match.homeTeamLogo && ( )} {match.homeTeamName} VS {match.awayTeamLogo && ( )} {match.awayTeamName} {(match.venue || match.round) && ( {match.venue && ( {match.venue} )} {match.round && ( {match.round} )} )} ); } const styles = StyleSheet.create({ card: { padding: 12, marginBottom: 12, borderRadius: 12, borderWidth: 1, }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 12, }, leagueBadge: { flexDirection: "row", alignItems: "center", paddingHorizontal: 8, paddingVertical: 4, borderRadius: 4, flex: 1, marginRight: 8, }, leagueLogo: { width: 16, height: 16, marginRight: 4, }, leagueText: { fontSize: 12, opacity: 0.7, flex: 1, }, timeText: { fontSize: 12, opacity: 0.5, }, teamsContainer: { flexDirection: "row", alignItems: "center", marginBottom: 8, }, team: { flex: 1, flexDirection: "row", alignItems: "center", }, teamLogo: { width: 24, height: 24, marginRight: 8, }, teamName: { fontSize: 14, flex: 1, }, vsContainer: { paddingHorizontal: 12, }, vsText: { fontSize: 12, opacity: 0.5, fontWeight: "600", }, metaContainer: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: 8, marginTop: 4, }, metaItem: { flexDirection: "row", alignItems: "center", gap: 4, }, metaText: { fontSize: 11, opacity: 0.5, }, });