Compare commits
3 Commits
e623dad81f
...
291e7ff8a7
Author | SHA1 | Date | |
---|---|---|---|
291e7ff8a7 | |||
9543177db6 | |||
9c7a447e4e |
@ -25,8 +25,8 @@ export default function TabLayout() {
|
|||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="challenges"
|
name="challenges"
|
||||||
options={{
|
options={{
|
||||||
title: 'Challenges',
|
title: 'Défis',
|
||||||
headerTitleStyle: {fontSize: 32},
|
headerShown: false,
|
||||||
tabBarIcon: ({ color }) => <FontAwesome6 name="coins" size={24} color={color} />,
|
tabBarIcon: ({ color }) => <FontAwesome6 name="coins" size={24} color={color} />,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -1,9 +1,37 @@
|
|||||||
import { Surface, Text } from 'react-native-paper'
|
import PenaltyBanner from '@/components/PenalyBanner'
|
||||||
|
import { FontAwesome6 } from '@expo/vector-icons'
|
||||||
|
import { View } from 'react-native'
|
||||||
|
import { Appbar, Button, Surface, Text } from 'react-native-paper'
|
||||||
|
|
||||||
export default function ChallengesScreen() {
|
export default function ChallengesScreen() {
|
||||||
return (
|
return (
|
||||||
<Surface>
|
<Surface style={{ flex: 1 }}>
|
||||||
<Text>Ici on aura la gestion des challenges</Text>
|
<Appbar.Header>
|
||||||
|
<Appbar.Content title={"Défis"} />
|
||||||
|
<Appbar.Action icon='format-list-bulleted' />
|
||||||
|
</Appbar.Header>
|
||||||
|
<PenaltyBanner />
|
||||||
|
<Surface elevation={2} style={{ flex: 1, margin: 20, borderRadius: 20 }}>
|
||||||
|
<View style={{ padding: 10 }}>
|
||||||
|
<Text variant='headlineMedium' style={{ textAlign: 'center' }}>Titre</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flexGrow: 1 }}>
|
||||||
|
<Surface elevation={5} mode='flat' style={{ flexGrow: 1, padding: 15 }}>
|
||||||
|
<Text variant='bodyLarge' style={{ flexGrow: 1 }}>Description</Text>
|
||||||
|
<Text variant='titleMedium'>
|
||||||
|
Récompense : 500 <FontAwesome6 name='coins' />
|
||||||
|
</Text>
|
||||||
|
</Surface>
|
||||||
|
</View>
|
||||||
|
<View style={{ flexWrap: 'wrap', flexDirection: 'row', justifyContent: 'space-around', padding: 15 }}>
|
||||||
|
<Button mode='outlined' icon='cancel'>
|
||||||
|
Passer
|
||||||
|
</Button>
|
||||||
|
<Button mode='contained' icon='check'>
|
||||||
|
Terminer
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</Surface>
|
||||||
</Surface>
|
</Surface>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import PenaltyBanner from '@/components/PenalyBanner'
|
||||||
import { useAddTrainMutation } from '@/hooks/mutations/useTrainMutation'
|
import { useAddTrainMutation } from '@/hooks/mutations/useTrainMutation'
|
||||||
import { useAuth } from '@/hooks/useAuth'
|
import { useAuth } from '@/hooks/useAuth'
|
||||||
import { useTrain } from '@/hooks/useTrain'
|
import { useTrain } from '@/hooks/useTrain'
|
||||||
@ -22,6 +23,7 @@ export default function TrainScreen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Surface style={{ flex: 1 }}>
|
<Surface style={{ flex: 1 }}>
|
||||||
|
<PenaltyBanner />
|
||||||
<FlatList
|
<FlatList
|
||||||
data={trains.trains}
|
data={trains.trains}
|
||||||
keyExtractor={(train) => train.id}
|
keyExtractor={(train) => train.id}
|
||||||
|
@ -43,7 +43,7 @@ export default function GameProvider({ children }: { children: ReactNode }) {
|
|||||||
queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/trains/?playerId=${game.playerId}&size=10000`, {
|
queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/trains/?playerId=${game.playerId}&size=10000`, {
|
||||||
headers: { "Authorization": `Bearer ${auth.token}` }}
|
headers: { "Authorization": `Bearer ${auth.token}` }}
|
||||||
).then(resp => resp.json()),
|
).then(resp => resp.json()),
|
||||||
enabled: isAuthValid(auth) && !game.playerId,
|
enabled: isAuthValid(auth) && !!game.playerId,
|
||||||
refetchInterval: 5000,
|
refetchInterval: 5000,
|
||||||
})
|
})
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
49
client/components/PenalyBanner.tsx
Normal file
49
client/components/PenalyBanner.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { useGame } from "@/hooks/useGame"
|
||||||
|
import { FontAwesome6 } from "@expo/vector-icons"
|
||||||
|
import { useEffect, useMemo, useState } from "react"
|
||||||
|
import { View } from "react-native"
|
||||||
|
import { Banner, MD3Colors, ProgressBar, Text } from "react-native-paper"
|
||||||
|
|
||||||
|
export default function PenaltyBanner() {
|
||||||
|
const game = useGame()
|
||||||
|
const penaltyEnd = game.penaltyEnd
|
||||||
|
const hasPenalty = penaltyEnd !== null
|
||||||
|
const penaltyEndDate = useMemo(() => new Date(penaltyEnd || 0), [penaltyEnd])
|
||||||
|
const penaltyEndPretty = penaltyEndDate.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
|
||||||
|
const [remainingTime, setRemainingTime] = useState(0)
|
||||||
|
const prettyRemainingTime = useMemo(() => `${Math.floor(remainingTime / 60).toString().padStart(2, '0')}:${Math.floor(remainingTime % 60).toString().padStart(2, '0')}`, [remainingTime])
|
||||||
|
const iconName = useMemo(() => {
|
||||||
|
switch (Math.abs(remainingTime % 4)) {
|
||||||
|
case 0: return 'hourglass-empty'
|
||||||
|
case 1: return 'hourglass-end'
|
||||||
|
case 2: return 'hourglass-half'
|
||||||
|
case 3: return 'hourglass-start'
|
||||||
|
}
|
||||||
|
}, [remainingTime])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasPenalty)
|
||||||
|
return
|
||||||
|
const interval = setInterval(() => setRemainingTime(Math.floor((penaltyEndDate.getTime() - new Date().getTime()) / 1000)), 1000)
|
||||||
|
return () => clearInterval(interval)
|
||||||
|
}, [hasPenalty, penaltyEndDate])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Banner
|
||||||
|
visible={hasPenalty}
|
||||||
|
icon={({ size }) => <FontAwesome6 name={iconName} size={size} color={MD3Colors.tertiary80} />}
|
||||||
|
style={{ backgroundColor: MD3Colors.primary30 }}>
|
||||||
|
<View>
|
||||||
|
<Text variant='titleMedium'>Vous avez actuellement une pénalité jusqu'à {penaltyEndPretty}.</Text>
|
||||||
|
<Text variant='titleSmall'>Temps restant : {prettyRemainingTime}</Text>
|
||||||
|
</View>
|
||||||
|
</Banner>
|
||||||
|
<ProgressBar
|
||||||
|
visible={hasPenalty}
|
||||||
|
animatedValue={1 - remainingTime / (3 * 60)}
|
||||||
|
color={MD3Colors.error40}
|
||||||
|
style={{ height: 6 }} />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user