import ChallengeCard from '@/components/ChallengeCard' import PenaltyBanner from '@/components/PenalyBanner' import { useDrawRandomChallengeMutation, useEndChallenge } from '@/hooks/mutations/useChallengeMutation' import { useAuth } from '@/hooks/useAuth' import { useChallengeActions } from '@/hooks/useChallengeActions' import { useChallenges } from '@/hooks/useChallenges' import { useGame } from '@/hooks/useGame' import { FontAwesome6, MaterialCommunityIcons } from '@expo/vector-icons' import { useQueryClient } from '@tanstack/react-query' import { useRouter } from 'expo-router' import { useEffect, useMemo, useState } from 'react' import { View } from 'react-native' import { ActivityIndicator, Appbar, Banner, FAB, MD3Colors, Snackbar, Surface, Text, TouchableRipple } from 'react-native-paper' function ChallengeScreenHeader() { const router = useRouter() return <> <Appbar.Header> <Appbar.Content title={"Défi en cours"} /> <Appbar.Action icon='format-list-bulleted' onPress={() => router.navigate('/challenges-list')} /> </Appbar.Header> <PenaltyBanner /> </> } function ChallengeScreenBody() { const queryClient = useQueryClient() const auth = useAuth() const game = useGame() const challengeActions = useChallengeActions() const challenges = useChallenges() const currentChallengeAction = useMemo(() => { if (!game.activeChallengeId) return null return challengeActions.find((action) => action.id === game.activeChallengeId) }, [game, challengeActions]) const currentChallenge = useMemo(() => { if (!currentChallengeAction) return null return challenges.find((challenge) => challenge.id === currentChallengeAction.challengeId) }, [currentChallengeAction, challenges]) const [loading, setLoading] = useState(false) const [successSnackbarVisible, setSuccessSnackbarVisible] = useState(false) const [errorVisible, setErrorVisible] = useState(false) const [error, setError] = useState([200, ""]) const drawRandomChallengeMutation = useDrawRandomChallengeMutation({ auth, onPostSuccess: () => { setLoading(true) setSuccessSnackbarVisible(true) queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' || query.queryKey[0] === 'get-player' }) }, onError: ({ response, error }) => { setErrorVisible(true) if (response) setError([response.statusCode, response.message]) else if (error) setError([400, error.message]) }, }) const endChallenge = useEndChallenge({ auth, onPostSuccess: () => { setLoading(true) setSuccessSnackbarVisible(true) queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' || query.queryKey[0] === 'get-player' }) }, onError: ({ response, error }) => { setErrorVisible(true) if (response) setError([response.statusCode, response.message]) else if (error) setError([400, error.message]) }, }) useEffect(() => { if (challengeActions) setLoading(false) }, [challengeActions]) return <> {loading && <View style={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size={'large'} /> </View>} {!loading && currentChallenge && <ChallengeCard challenge={currentChallenge} onSuccess={() => { setLoading(true); endChallenge.mutate({ success: true }) }} onFail={() => endChallenge.mutate({ success: false })} style={{ flex: 1, margin: 20 }} />} {!loading && !game.penaltyEnd && !currentChallenge && game.currentRunner && <> <Banner elevation={4} visible={!currentChallenge && game.currentRunner && !loading} icon='vanish'> Aucun défi n'est en cours. Veuillez tirer un défi en cliquant sur le bouton central. Pour rappel, il faut être hors d'un train pour tirer un défi. </Banner> <View style={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center' }}> <FAB label='Tirer un défi' icon='cards' disabled={drawRandomChallengeMutation.isPending} visible={!currentChallenge && game.currentRunner && !loading} onPress={() => drawRandomChallengeMutation.mutate()} variant='tertiary' customSize={64} /> </View> </>} <Banner visible={!loading && game.gameStarted && !game.currentRunner} icon={({ size }) => <FontAwesome6 name='cat' size={size} color={'pink'} />} style={{ backgroundColor: MD3Colors.secondary30 }}> Vous êtes poursuiveuse, et n'avez donc pas de défi à accomplir. </Banner> <Snackbar key='success-snackbar' visible={successSnackbarVisible} icon={'close'} onDismiss={() => setSuccessSnackbarVisible(false)} onIconPress={() => setSuccessSnackbarVisible(false)}> Jeu actualisé </Snackbar> <Snackbar key='error-snackbar' visible={errorVisible} icon={'close'} onDismiss={() => setErrorVisible(false)} onIconPress={() => setErrorVisible(false)}> <Text variant='bodyMedium' style={{ color: MD3Colors.secondary0 }}> Erreur {error[0]} : {error[1]} </Text> </Snackbar> </> } export default function ChallengesScreen() { return ( <Surface style={{ flex: 1 }}> <ChallengeScreenHeader /> <ChallengeScreenBody /> </Surface> ) }