Afifchage de l'historique des mouvements de point
This commit is contained in:
parent
02304527d3
commit
3d50cee9a9
@ -30,12 +30,12 @@ function ChallengeScreenBody() {
|
|||||||
const currentChallengeAction = useMemo(() => {
|
const currentChallengeAction = useMemo(() => {
|
||||||
if (!game.activeChallengeId)
|
if (!game.activeChallengeId)
|
||||||
return null
|
return null
|
||||||
return challengeActions.challengeActions.find((action) => action.id === game.activeChallengeId)
|
return challengeActions.find((action) => action.id === game.activeChallengeId)
|
||||||
}, [game, challengeActions])
|
}, [game, challengeActions])
|
||||||
const currentChallenge = useMemo(() => {
|
const currentChallenge = useMemo(() => {
|
||||||
if (!currentChallengeAction)
|
if (!currentChallengeAction)
|
||||||
return null
|
return null
|
||||||
return challenges.challenges.find((challenge) => challenge.id === currentChallengeAction.challengeId)
|
return 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 [successSnackbarVisible, setSuccessSnackbarVisible] = useState(false)
|
||||||
|
@ -1,12 +1,78 @@
|
|||||||
|
import { useChallengeActions } from '@/hooks/useChallengeActions'
|
||||||
|
import { useChallenges } from '@/hooks/useChallenges'
|
||||||
import { useMoneyUpdates } from '@/hooks/useMoneyUpdates'
|
import { useMoneyUpdates } from '@/hooks/useMoneyUpdates'
|
||||||
import { Surface, Text } from 'react-native-paper'
|
import { useTrain } from '@/hooks/useTrain'
|
||||||
|
import { MoneyUpdate } from '@/utils/features/moneyUpdates/moneyUpdatesSlice'
|
||||||
|
import { FontAwesome6 } from '@expo/vector-icons'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
import { FlatList } from 'react-native'
|
||||||
|
import { Divider, FAB, List, Surface, Text } from 'react-native-paper'
|
||||||
|
|
||||||
export default function HistoryScreen() {
|
export default function HistoryScreen() {
|
||||||
const moneyUpdates = useMoneyUpdates()
|
const moneyUpdates = useMoneyUpdates()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Surface>
|
<Surface style={{ flex :1 }}>
|
||||||
<Text>Ici on aura la gestion de l'historique des trains empruntés et des challenges effectués</Text>
|
<FlatList
|
||||||
|
data={moneyUpdates}
|
||||||
|
keyExtractor={(moneyUpdate) => `money-update-list-item-${moneyUpdate.id}`}
|
||||||
|
ItemSeparatorComponent={() => <Divider />}
|
||||||
|
renderItem={(item) => <MoneyUpdateListItem moneyUpdate={item.item} />} />
|
||||||
</Surface>
|
</Surface>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function MoneyUpdateListItem({ moneyUpdate }: { moneyUpdate: MoneyUpdate }) {
|
||||||
|
const trains = useTrain()
|
||||||
|
const challengeActions = useChallengeActions()
|
||||||
|
const challenges = useChallenges()
|
||||||
|
|
||||||
|
const icon = useMemo(() => {
|
||||||
|
switch (moneyUpdate.reason) {
|
||||||
|
case 'START': return 'star'
|
||||||
|
case 'NEW_RUN': return 'run'
|
||||||
|
case 'BUY_TRAIN': return 'train'
|
||||||
|
case 'WIN_CHALLENGE': return 'cards'
|
||||||
|
}
|
||||||
|
}, [moneyUpdate.reason])
|
||||||
|
|
||||||
|
const title = useMemo(() => {
|
||||||
|
switch (moneyUpdate.reason) {
|
||||||
|
case 'START':
|
||||||
|
return "Début de la partie"
|
||||||
|
case 'NEW_RUN':
|
||||||
|
return "Nouvelle tentative"
|
||||||
|
case 'BUY_TRAIN':
|
||||||
|
const train = trains.find((train) => train.id === moneyUpdate.tripId)
|
||||||
|
if (!train) return "Train"
|
||||||
|
const depDateTime = new Date(train.departureTime)
|
||||||
|
const depTime = depDateTime.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
|
||||||
|
const arrDateTime = new Date(train.arrivalTime)
|
||||||
|
const arrTime = arrDateTime.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
|
||||||
|
return `${train.from} ${depTime} => ${train.to} ${arrTime}`
|
||||||
|
case 'WIN_CHALLENGE':
|
||||||
|
const challengeAction = challengeActions.find((challengeAction) => challengeAction.id === moneyUpdate.actionId)
|
||||||
|
if (!challengeAction) return "Défi"
|
||||||
|
const challenge = challenges.find((challenge) => challenge.id === challengeAction.challengeId)
|
||||||
|
if (!challenge) return "Défi"
|
||||||
|
return challenge.title
|
||||||
|
}
|
||||||
|
}, [moneyUpdate.reason, moneyUpdate.tripId, moneyUpdate.actionId])
|
||||||
|
|
||||||
|
const description = useMemo(() => {
|
||||||
|
const earnDate = new Date(moneyUpdate.timestamp).toLocaleDateString(undefined, { day: '2-digit', month: '2-digit' })
|
||||||
|
const earnTime = new Date(moneyUpdate.timestamp).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
|
||||||
|
const verb = moneyUpdate.amount > 0 ? "Gagné" : "Dépensé"
|
||||||
|
return <Text>
|
||||||
|
{verb} {moneyUpdate.amount} <FontAwesome6 name='coins' /> le {earnDate} à {earnTime}
|
||||||
|
</Text>
|
||||||
|
}, [moneyUpdate.amount])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<List.Item
|
||||||
|
left={(props) => <List.Icon {...props} icon={icon} />}
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
right={(props) => <FAB mode='elevated' icon='delete' size='small' {...props} onPress={() => {}} />} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ export default function TrainScreen() {
|
|||||||
<Surface style={{ flex: 1 }}>
|
<Surface style={{ flex: 1 }}>
|
||||||
<PenaltyBanner />
|
<PenaltyBanner />
|
||||||
<FlatList
|
<FlatList
|
||||||
data={trains.trains}
|
data={trains}
|
||||||
keyExtractor={(train) => train.id}
|
keyExtractor={(train) => train.id}
|
||||||
ItemSeparatorComponent={() => <Divider />}
|
ItemSeparatorComponent={() => <Divider />}
|
||||||
renderItem={(item) => <TrainListItem train={item.item} />} />
|
renderItem={(item) => <TrainListItem train={item.item} />} />
|
||||||
|
@ -15,7 +15,6 @@ import { useStartBackgroundFetchServiceEffect } from '@/utils/background'
|
|||||||
import LoginProvider from '@/components/LoginProvider'
|
import LoginProvider from '@/components/LoginProvider'
|
||||||
import GeolocationProvider from '@/components/GeolocationProvider'
|
import GeolocationProvider from '@/components/GeolocationProvider'
|
||||||
import GameProvider from '@/components/GameProvider'
|
import GameProvider from '@/components/GameProvider'
|
||||||
import { FontAwesome6 } from '@expo/vector-icons'
|
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
@ -49,10 +48,7 @@ export default function RootLayout() {
|
|||||||
<GeolocationProvider>
|
<GeolocationProvider>
|
||||||
<GameProvider>
|
<GameProvider>
|
||||||
<PaperProvider
|
<PaperProvider
|
||||||
theme={colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme}
|
theme={colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme} >
|
||||||
settings={{
|
|
||||||
// icon: (props) => <FontAwesome6 {...props} />
|
|
||||||
}}>
|
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
|
@ -96,7 +96,7 @@ export default function GameProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const now = new Date().getTime()
|
const now = new Date().getTime()
|
||||||
const activeChallenge: ChallengeAction | undefined = challengeActions.challengeActions
|
const activeChallenge: ChallengeAction | undefined = challengeActions
|
||||||
.find(challengeAction => challengeAction.penaltyStart && challengeAction.penaltyEnd
|
.find(challengeAction => challengeAction.penaltyStart && challengeAction.penaltyEnd
|
||||||
&& challengeAction.penaltyStart <= now && now <= challengeAction.penaltyEnd)
|
&& challengeAction.penaltyStart <= now && now <= challengeAction.penaltyEnd)
|
||||||
if (!activeChallenge || !game.currentRunner)
|
if (!activeChallenge || !game.currentRunner)
|
||||||
|
@ -45,7 +45,7 @@ export default function GeolocationProvider({ children }: { children: ReactNode
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (lastLocationsQuery.isSuccess && lastLocationsQuery.data)
|
if (lastLocationsQuery.isSuccess && lastLocationsQuery.data)
|
||||||
setLastPlayerLocations(lastLocationsQuery.data)
|
setLastPlayerLocations(lastLocationsQuery.data)
|
||||||
}, [lastLocationsQuery.status, lastLocationsQuery.dataUpdatedAt])
|
}, [lastLocationsQuery.status, lastLocationsQuery.dataUpdatedAt, auth])
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{children}
|
{children}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ChallengeActionsPayload, downloadChallengeActions } from "@/utils/features/challengeActions/challengeActionsSlice"
|
import { ChallengeActionsPayload, downloadChallengeActions } from "@/utils/features/challengeActions/challengeActionsSlice"
|
||||||
import { useAppDispatch, useAppSelector } from "./useStore"
|
import { useAppDispatch, useAppSelector } from "./useStore"
|
||||||
|
|
||||||
export const useChallengeActions = () => useAppSelector((state) => state.challengeActions)
|
export const useChallengeActions = () => useAppSelector((state) => state.challengeActions.challengeActions)
|
||||||
export const useDownloadChallengeActions = () => {
|
export const useDownloadChallengeActions = () => {
|
||||||
const dispath = useAppDispatch()
|
const dispath = useAppDispatch()
|
||||||
return (challengesData: ChallengeActionsPayload) => dispath(downloadChallengeActions(challengesData))
|
return (challengesData: ChallengeActionsPayload) => dispath(downloadChallengeActions(challengesData))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ChallengesPayload, downloadChallenges } from "@/utils/features/challenges/challengesSlice"
|
import { ChallengesPayload, downloadChallenges } from "@/utils/features/challenges/challengesSlice"
|
||||||
import { useAppDispatch, useAppSelector } from "./useStore"
|
import { useAppDispatch, useAppSelector } from "./useStore"
|
||||||
|
|
||||||
export const useChallenges = () => useAppSelector((state) => state.challenges)
|
export const useChallenges = () => useAppSelector((state) => state.challenges.challenges)
|
||||||
export const useDownloadChallenges = () => {
|
export const useDownloadChallenges = () => {
|
||||||
const dispath = useAppDispatch()
|
const dispath = useAppDispatch()
|
||||||
return (challengesData: ChallengesPayload) => dispath(downloadChallenges(challengesData))
|
return (challengesData: ChallengesPayload) => dispath(downloadChallenges(challengesData))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { downloadTrains, TrainsPayload } from "@/utils/features/train/trainSlice"
|
import { downloadTrains, TrainsPayload } from "@/utils/features/train/trainSlice"
|
||||||
import { useAppDispatch, useAppSelector } from "./useStore"
|
import { useAppDispatch, useAppSelector } from "./useStore"
|
||||||
|
|
||||||
export const useTrain = () => useAppSelector((state) => state.train)
|
export const useTrain = () => useAppSelector((state) => state.train.trains)
|
||||||
export const useDownloadTrains = () => {
|
export const useDownloadTrains = () => {
|
||||||
const dispath = useAppDispatch()
|
const dispath = useAppDispatch()
|
||||||
return (trainsData: TrainsPayload) => dispath(downloadTrains(trainsData))
|
return (trainsData: TrainsPayload) => dispath(downloadTrains(trainsData))
|
||||||
|
@ -4,11 +4,12 @@ import { PaginationMeta } from '../common'
|
|||||||
export interface MoneyUpdate {
|
export interface MoneyUpdate {
|
||||||
id: number
|
id: number
|
||||||
playerId: number
|
playerId: number
|
||||||
|
amount: number
|
||||||
reason: 'START' | 'NEW_RUN' | 'BUY_TRAIN' | 'WIN_CHALLENGE'
|
reason: 'START' | 'NEW_RUN' | 'BUY_TRAIN' | 'WIN_CHALLENGE'
|
||||||
timestamp: number
|
timestamp: number
|
||||||
runId: number | null
|
runId: number | null
|
||||||
actionId: number | null
|
actionId: number | null
|
||||||
tripId: number | null
|
tripId: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MoneyUpdatesState {
|
export interface MoneyUpdatesState {
|
||||||
@ -19,8 +20,19 @@ const initialState: MoneyUpdatesState = {
|
|||||||
moneyUpdates: []
|
moneyUpdates: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MoneyUpdatePayload {
|
||||||
|
id: number
|
||||||
|
playerId: number
|
||||||
|
amount: number
|
||||||
|
reason: 'START' | 'NEW_RUN' | 'BUY_TRAIN' | 'WIN_CHALLENGE'
|
||||||
|
timestamp: string
|
||||||
|
runId: number | null
|
||||||
|
actionId: number | null
|
||||||
|
tripId: string | null
|
||||||
|
}
|
||||||
|
|
||||||
export interface MoneyUpdatesPayload {
|
export interface MoneyUpdatesPayload {
|
||||||
data: MoneyUpdate[]
|
data: MoneyUpdatePayload[]
|
||||||
meta: PaginationMeta
|
meta: PaginationMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +43,16 @@ export const moneyUpdatesSlice = createSlice({
|
|||||||
downloadMoneyUpdates(state, action: PayloadAction<MoneyUpdatesPayload>) {
|
downloadMoneyUpdates(state, action: PayloadAction<MoneyUpdatesPayload>) {
|
||||||
state.moneyUpdates = state.moneyUpdates.filter(moneyUpdate => action.payload.data.filter(dlMU => dlMU.id === moneyUpdate.id) === null)
|
state.moneyUpdates = state.moneyUpdates.filter(moneyUpdate => action.payload.data.filter(dlMU => dlMU.id === moneyUpdate.id) === null)
|
||||||
for (const dlMU of action.payload.data) {
|
for (const dlMU of action.payload.data) {
|
||||||
state.moneyUpdates.push(dlMU)
|
state.moneyUpdates.push({
|
||||||
|
id: dlMU.id,
|
||||||
|
playerId: dlMU.playerId,
|
||||||
|
amount: dlMU.amount,
|
||||||
|
reason: dlMU.reason,
|
||||||
|
timestamp: new Date(dlMU.timestamp).getTime(),
|
||||||
|
runId: dlMU.runId,
|
||||||
|
actionId: dlMU.actionId,
|
||||||
|
tripId: dlMU.tripId,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
state.moneyUpdates.sort((mu1, mu2) => mu2.id - mu1.id)
|
state.moneyUpdates.sort((mu1, mu2) => mu2.id - mu1.id)
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user