Interaction avec les boutons de fin de défi
This commit is contained in:
parent
47ec3da6df
commit
63ad84eb8c
@ -1,6 +1,6 @@
|
|||||||
import ChallengeCard from '@/components/ChallengeCard'
|
import ChallengeCard from '@/components/ChallengeCard'
|
||||||
import PenaltyBanner from '@/components/PenalyBanner'
|
import PenaltyBanner from '@/components/PenalyBanner'
|
||||||
import { useDrawRandomChallengeMutation } from '@/hooks/mutations/useChallengeMutation'
|
import { useDrawRandomChallengeMutation, useEndChallenge } from '@/hooks/mutations/useChallengeMutation'
|
||||||
import { useAuth } from '@/hooks/useAuth'
|
import { useAuth } from '@/hooks/useAuth'
|
||||||
import { useChallengeActions } from '@/hooks/useChallengeActions'
|
import { useChallengeActions } from '@/hooks/useChallengeActions'
|
||||||
import { useChallenges } from '@/hooks/useChallenges'
|
import { useChallenges } from '@/hooks/useChallenges'
|
||||||
@ -9,7 +9,7 @@ import { FontAwesome6 } from '@expo/vector-icons'
|
|||||||
import { useQueryClient } from '@tanstack/react-query'
|
import { useQueryClient } from '@tanstack/react-query'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
import { ActivityIndicator, Appbar, Banner, FAB, MD3Colors, Surface, Text, TouchableRipple } from 'react-native-paper'
|
import { ActivityIndicator, Appbar, Banner, FAB, MD3Colors, Snackbar, Surface, Text, TouchableRipple } from 'react-native-paper'
|
||||||
|
|
||||||
function ChallengeScreenHeader() {
|
function ChallengeScreenHeader() {
|
||||||
return <>
|
return <>
|
||||||
@ -38,26 +38,44 @@ function ChallengeScreenBody() {
|
|||||||
return challenges.challenges.find((challenge) => challenge.id === currentChallengeAction.challengeId)
|
return challenges.challenges.find((challenge) => challenge.id === currentChallengeAction.challengeId)
|
||||||
}, [currentChallengeAction, challenges])
|
}, [currentChallengeAction, challenges])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [successSnackbarVisible, setSuccessSnackbarVisible] = useState(false)
|
||||||
const drawRandomChallengeMutation = useDrawRandomChallengeMutation({
|
const drawRandomChallengeMutation = useDrawRandomChallengeMutation({
|
||||||
auth,
|
auth,
|
||||||
onPostSuccess: () => {
|
onPostSuccess: () => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
setSuccessSnackbarVisible(true)
|
||||||
queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' || query.queryKey[0] === 'get-player' })
|
queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' || query.queryKey[0] === 'get-player' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const endChallenge = useEndChallenge({
|
||||||
|
auth,
|
||||||
|
onPostSuccess: () => {
|
||||||
|
setLoading(true)
|
||||||
|
setSuccessSnackbarVisible(true)
|
||||||
|
queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' || query.queryKey[0] === 'get-player' })
|
||||||
|
},
|
||||||
|
})
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (challengeActions)
|
if (challengeActions)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}, [challengeActions])
|
}, [challengeActions])
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{currentChallenge && <ChallengeCard challenge={currentChallenge} />}
|
{loading &&
|
||||||
{!currentChallenge && game.currentRunner && <>
|
<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 })} />}
|
||||||
|
{!loading && !currentChallenge && game.currentRunner && <>
|
||||||
<Banner
|
<Banner
|
||||||
visible={!currentChallenge && game.currentRunner && !loading}
|
visible={!currentChallenge && game.currentRunner && !loading}
|
||||||
icon='cancel'
|
icon='cancel'
|
||||||
style={{ backgroundColor: MD3Colors.error40 }}>
|
style={{ backgroundColor: MD3Colors.error40 }}>
|
||||||
<Text variant='titleMedium' style={{ textAlign: 'center' }}>Aucun défi en cours.</Text>
|
Aucun défi n'est en cours.
|
||||||
</Banner>
|
</Banner>
|
||||||
<View style={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center' }}>
|
<View style={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||||
<FAB
|
<FAB
|
||||||
@ -68,15 +86,20 @@ function ChallengeScreenBody() {
|
|||||||
onPress={() => drawRandomChallengeMutation.mutate()}
|
onPress={() => drawRandomChallengeMutation.mutate()}
|
||||||
variant='tertiary'
|
variant='tertiary'
|
||||||
customSize={64} />
|
customSize={64} />
|
||||||
{loading && <ActivityIndicator size={'large'} />}
|
|
||||||
</View>
|
</View>
|
||||||
</>}
|
</>}
|
||||||
<Banner
|
<Banner
|
||||||
visible={game.gameStarted && !game.currentRunner}
|
visible={!loading && game.gameStarted && !game.currentRunner}
|
||||||
icon={({ size }) => <FontAwesome6 name='cat' size={size} color={'pink'} />}
|
icon={({ size }) => <FontAwesome6 name='cat' size={size} color={'pink'} />}
|
||||||
style={{ backgroundColor: MD3Colors.secondary30 }}>
|
style={{ backgroundColor: MD3Colors.secondary30 }}>
|
||||||
Vous êtes poursuiveuse, et n'avez donc pas de défi à accomplir.
|
Vous êtes poursuiveuse, et n'avez donc pas de défi à accomplir.
|
||||||
</Banner>
|
</Banner>
|
||||||
|
<Snackbar
|
||||||
|
visible={successSnackbarVisible}
|
||||||
|
onDismiss={() => setSuccessSnackbarVisible(false)}
|
||||||
|
action={{ label: "Fermer", onPress: () => setSuccessSnackbarVisible(false) }}>
|
||||||
|
Jeu actualisé
|
||||||
|
</Snackbar>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
import { Challenge } from "@/utils/features/challenges/challengesSlice"
|
import { Challenge } from "@/utils/features/challenges/challengesSlice"
|
||||||
import { FontAwesome6 } from "@expo/vector-icons"
|
import { FontAwesome6 } from "@expo/vector-icons"
|
||||||
import { View } from "react-native"
|
import { View } from "react-native"
|
||||||
import { Button, Surface, Text } from "react-native-paper"
|
import { Button, Card, IconButton, MD3Colors, Surface, Text } from "react-native-paper"
|
||||||
|
|
||||||
export default function ChallengeCard({ challenge }: { challenge: Challenge }) {
|
export type ChallengeCardProps = {
|
||||||
|
challenge: Challenge,
|
||||||
|
onSuccess?: () => void,
|
||||||
|
onFail?: () => void,
|
||||||
|
onDelete?: () => void,
|
||||||
|
onEdit?: () => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ChallengeCard({ challenge, onSuccess, onFail, onDelete, onEdit }: ChallengeCardProps) {
|
||||||
return (
|
return (
|
||||||
<Surface elevation={2} style={{ flex: 1, margin: 20, borderRadius: 20 }}>
|
<Surface elevation={2} style={{ flex: 1, margin: 20, borderRadius: 20 }}>
|
||||||
<View style={{ padding: 10 }}>
|
<Card.Title
|
||||||
<Text variant='headlineMedium' style={{ textAlign: 'center' }}>{challenge.title}</Text>
|
title={challenge.title}
|
||||||
</View>
|
titleStyle={{ textAlign: 'center' }}
|
||||||
|
titleVariant='headlineMedium'
|
||||||
|
right={(props) => onEdit ? <IconButton {...props} icon='file-document-edit-outline' onPress={() => onEdit()} /> : <></>} />
|
||||||
<View style={{ flexGrow: 1 }}>
|
<View style={{ flexGrow: 1 }}>
|
||||||
<Surface elevation={5} mode='flat' style={{ flexGrow: 1, padding: 15 }}>
|
<Surface elevation={5} mode='flat' style={{ flexGrow: 1, paddingHorizontal: 15, paddingVertical: 20 }}>
|
||||||
<Text variant='bodyLarge' style={{ flexGrow: 1 }}>{challenge.description}</Text>
|
<Text variant='bodyLarge' style={{ flexGrow: 1 }}>{challenge.description}</Text>
|
||||||
<Text variant='titleMedium'>
|
<Text variant='titleMedium'>
|
||||||
Récompense : {challenge.reward} <FontAwesome6 name='coins' />
|
Récompense : {challenge.reward} <FontAwesome6 name='coins' />
|
||||||
@ -18,12 +28,15 @@ export default function ChallengeCard({ challenge }: { challenge: Challenge }) {
|
|||||||
</Surface>
|
</Surface>
|
||||||
</View>
|
</View>
|
||||||
<View style={{ flexWrap: 'wrap', flexDirection: 'row', justifyContent: 'space-around', padding: 15 }}>
|
<View style={{ flexWrap: 'wrap', flexDirection: 'row', justifyContent: 'space-around', padding: 15 }}>
|
||||||
<Button mode='outlined' icon='cancel'>
|
{onFail && <Button key='failBtn' mode='outlined' icon='cancel' onPress={() => onFail()}>
|
||||||
Passer
|
Passer
|
||||||
</Button>
|
</Button>}
|
||||||
<Button mode='contained' icon='check'>
|
{onSuccess && <Button key='successBtn' mode='contained' icon='check' onPress={() => onSuccess()}>
|
||||||
Terminer
|
Terminer
|
||||||
</Button>
|
</Button>}
|
||||||
|
{onDelete && <Button key='deleteBtn' mode='contained' icon='delete' onPress={() => onDelete()} buttonColor={MD3Colors.error60}>
|
||||||
|
Supprimer
|
||||||
|
</Button>}
|
||||||
</View>
|
</View>
|
||||||
</Surface>
|
</Surface>
|
||||||
)
|
)
|
||||||
|
@ -43,3 +43,33 @@ export const useDrawRandomChallengeMutation = ({ auth, onPostSuccess, onError }:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useEndChallenge = ({ auth, onPostSuccess, onError }: ChallengeActionProps) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ success }: { success: boolean }) => {
|
||||||
|
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/challenge-actions/end-current/`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${auth.token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: success,
|
||||||
|
})
|
||||||
|
}).then(resp => resp.json())
|
||||||
|
},
|
||||||
|
onSuccess: async (data) => {
|
||||||
|
if (data.statusCode) {
|
||||||
|
if (onError)
|
||||||
|
onError({ response: data })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (onPostSuccess)
|
||||||
|
onPostSuccess()
|
||||||
|
},
|
||||||
|
onError: async (error: Error) => {
|
||||||
|
if (onError)
|
||||||
|
onError({ error: error })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user