import { View, Text, StyleSheet, FlatList, RefreshControl, TouchableOpacity, ActivityIndicator, Platform, useWindowDimensions } from "react-native"; import { useMatchStore, useAuthStore } from "../../src/store"; import { useEffect, useCallback, useState } from "react"; import { useFocusEffect } from "expo-router"; import { Ionicons } from "@expo/vector-icons"; import { useRouter } from "expo-router"; import { LinearGradient } from "expo-linear-gradient"; import Animated, { FadeIn, FadeInDown, FadeInRight, FadeInUp, } from "react-native-reanimated"; import { GradientBackground, GlassCard, GlassButton, DecorativeSeparator } from "../../src/components/ui"; import { useAmbientOrbAnimation } from "../../src/hooks"; import { colors, gradients, spacing, typography, radius, shadows } from "../../src/theme"; import { MatchesTutorial } from "../../src/components/tutorials"; import { hasSeenMatchesTutorial, markMatchesTutorialSeen } from "../../src/lib/matchesTutorialSeen"; // Premium color palette const ACCENT = colors.premium.gold; const ACCENT_RGBA = 'rgba(212, 175, 55, '; const ROSE = colors.premium.rose; const ROSE_RGBA = 'rgba(232, 164, 174, '; const MAX_CONTENT_WIDTH = 500; export default function MatchesScreen() { const { matches, fetchMatches, markAllAsSeen } = useMatchStore(); const { user } = useAuthStore(); const router = useRouter(); const { width } = useWindowDimensions(); const isWideScreen = width > MAX_CONTENT_WIDTH; const [showTutorial, setShowTutorial] = useState(false); // Ambient orb breathing animations const { orbStyle1, orbStyle2 } = useAmbientOrbAnimation(); // Check if tutorial should be shown when screen is focused or matches change useFocusEffect( useCallback(() => { const checkTutorial = async () => { if (matches.length > 0) { const seen = await hasSeenMatchesTutorial(); if (!seen) { setShowTutorial(true); } } }; checkTutorial(); }, [matches.length]) ); const handleTutorialComplete = async () => { await markMatchesTutorialSeen(); setShowTutorial(false); }; useFocusEffect( useCallback(() => { fetchMatches(); }, []) ); useEffect(() => { if (matches.length > 0) { markAllAsSeen(); } }, [matches.length]); const renderItem = ({ item, index }: { item: any; index: number }) => { const userResponse = item.responses?.find((r: any) => r.user_id === user?.id); const partnerResponse = item.responses?.find((r: any) => r.user_id !== user?.id); let userText = item.question.text; let partnerText = item.question.partner_text; if (item.question.partner_text && userResponse && partnerResponse) { const userTime = new Date(userResponse.created_at).getTime(); const partnerTime = new Date(partnerResponse.created_at).getTime(); if (userTime > partnerTime) { userText = item.question.partner_text; partnerText = item.question.text; } } const isYesYes = item.match_type === "yes_yes"; return ( router.push(`/chat/${item.id}`)} activeOpacity={0.8} > {/* Subtle gradient background */} {/* Top silk highlight */} {/* Premium icon container */} {userText} {item.question.partner_text && ( Partner: {partnerText} )} {isYesYes ? "YES + YES" : "YES + MAYBE"} {new Date(item.created_at).toLocaleDateString()} {item.unreadCount > 0 && ( )} {/* Premium border */} ); }; if (!user) { return ( ); } return ( {/* Ambient Orbs - Premium gold/rose */} {/* Premium Header */} {/* Premium label */} DISCOVER Matches {/* Decorative separator */} {/* Count badge */} {matches.length} {matches.length === 1 ? 'MATCH' : 'MATCHES'} item.id} contentContainerStyle={[styles.list, isWideScreen && styles.listWide]} showsVerticalScrollIndicator={false} refreshControl={ } ListEmptyComponent={ {/* Premium icon */} {/* Title section */} BEGIN No Matches Yet {/* Decorative separator */} {/* Status badge */} START EXPLORING {/* Description */} Answer questions together to discover what you both enjoy. Matches appear when you agree! {/* Feature hints */} Swipe right for yes Match when you both agree Chat about your matches {/* Bottom teaser */} Your first match is just a swipe away router.push("/(app)/swipe")} style={{ marginTop: spacing.lg }} > Start Swiping } /> {/* Matches Tutorial Overlay */} {showTutorial && ( )} ); } const styles = StyleSheet.create({ container: { flex: 1, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", }, // Ambient orbs ambientOrb: { position: 'absolute', width: 300, height: 300, borderRadius: 150, }, orbTopRight: { top: 60, right: -40, }, orbBottomLeft: { bottom: 180, left: -40, }, orbGradient: { width: '100%', height: '100%', borderRadius: 150, }, // Premium Header header: { paddingTop: 60, paddingHorizontal: spacing.lg, paddingBottom: spacing.md, }, headerWide: { alignSelf: 'center', width: '100%', maxWidth: MAX_CONTENT_WIDTH, }, headerContent: { alignItems: 'center', }, headerLabel: { ...typography.caption2, fontWeight: '600', letterSpacing: 3, color: ACCENT, marginBottom: spacing.xs, }, headerTitle: { ...typography.largeTitle, color: colors.text, textAlign: 'center', }, countBadgePremium: { flexDirection: 'row', alignItems: 'center', backgroundColor: `${ACCENT_RGBA}0.1)`, paddingHorizontal: spacing.md, paddingVertical: spacing.sm, borderRadius: radius.full, borderWidth: 1, borderColor: `${ACCENT_RGBA}0.2)`, gap: spacing.xs, }, countTextPremium: { ...typography.caption2, fontWeight: '600', letterSpacing: 2, color: ACCENT, }, // List list: { padding: spacing.lg, paddingTop: spacing.sm, paddingBottom: Platform.OS === 'ios' ? 120 : 100, }, listWide: { alignSelf: 'center', width: '100%', maxWidth: MAX_CONTENT_WIDTH, }, // Premium Match Card matchCardPremium: { marginBottom: spacing.sm, borderRadius: radius.lg, overflow: 'hidden', padding: spacing.md, }, cardSilkHighlight: { position: 'absolute', top: 0, left: 0, right: 0, height: 60, }, cardPremiumBorder: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, borderRadius: radius.lg, borderWidth: 1, borderColor: `${ACCENT_RGBA}0.15)`, }, matchRow: { flexDirection: "row", alignItems: "center", }, iconContainerPremium: { width: 44, height: 44, borderRadius: 22, backgroundColor: `${ROSE_RGBA}0.1)`, borderWidth: 1, borderColor: `${ROSE_RGBA}0.2)`, justifyContent: "center", alignItems: "center", marginRight: spacing.md, }, iconContainerYesYes: { backgroundColor: `${ACCENT_RGBA}0.1)`, borderColor: `${ACCENT_RGBA}0.2)`, }, content: { flex: 1, }, questionTextPremium: { ...typography.subhead, color: colors.text, fontWeight: "600", marginBottom: spacing.xs, lineHeight: 20, }, partnerTextPremium: { ...typography.caption1, color: colors.textSecondary, fontStyle: "italic", marginBottom: spacing.sm, }, metaRow: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", }, tagPremium: { backgroundColor: `${ROSE_RGBA}0.1)`, paddingHorizontal: spacing.sm, paddingVertical: 3, borderRadius: radius.sm, borderWidth: 1, borderColor: `${ROSE_RGBA}0.15)`, }, tagPremiumHighlight: { backgroundColor: `${ACCENT_RGBA}0.1)`, borderColor: `${ACCENT_RGBA}0.2)`, }, tagTextPremium: { ...typography.caption2, color: ROSE, fontWeight: "600", letterSpacing: 1, }, tagTextPremiumHighlight: { color: ACCENT, }, datePremium: { ...typography.caption2, color: colors.textTertiary, fontStyle: 'italic', }, rightSection: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm, marginLeft: spacing.sm, }, unreadBadgePremium: { width: 22, height: 22, borderRadius: 11, backgroundColor: ACCENT, justifyContent: 'center', alignItems: 'center', }, chevronContainerPremium: { width: 28, height: 28, borderRadius: 14, backgroundColor: `${ACCENT_RGBA}0.08)`, borderWidth: 1, borderColor: `${ACCENT_RGBA}0.15)`, justifyContent: 'center', alignItems: 'center', }, // Premium Empty State emptyContent: { width: '100%', alignItems: 'center', paddingHorizontal: spacing.md, paddingVertical: spacing.xl, }, emptyIconContainerPremium: { width: 72, height: 72, borderRadius: 36, backgroundColor: `${ROSE_RGBA}0.1)`, borderWidth: 1, borderColor: `${ROSE_RGBA}0.2)`, justifyContent: 'center', alignItems: 'center', marginBottom: spacing.xl, }, emptyLabel: { ...typography.caption1, fontWeight: '600', letterSpacing: 3, color: ROSE, textAlign: 'center', marginBottom: spacing.xs, }, emptyTitlePremium: { ...typography.largeTitle, color: colors.text, textAlign: 'center', }, emptyBadge: { backgroundColor: `${ROSE_RGBA}0.1)`, paddingHorizontal: spacing.lg, paddingVertical: spacing.sm, borderRadius: radius.full, borderWidth: 1, borderColor: `${ROSE_RGBA}0.2)`, marginBottom: spacing.xl, }, emptyBadgeText: { ...typography.caption2, fontWeight: '600', letterSpacing: 2, color: ROSE, }, emptyDescription: { ...typography.body, color: colors.textSecondary, textAlign: 'center', marginBottom: spacing.xl, paddingHorizontal: spacing.md, }, emptyFeatures: { marginBottom: spacing.xl, }, emptyFeatureItem: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: spacing.sm, }, emptyFeatureText: { ...typography.subhead, color: colors.text, marginLeft: spacing.sm, }, emptyTeaser: { ...typography.footnote, fontStyle: 'italic', color: colors.textTertiary, textAlign: 'center', }, });