Compare commits
2 Commits
af14cfb11d
...
33ee18d7e2
Author | SHA1 | Date | |
---|---|---|---|
33ee18d7e2 | |||
54a7806316 |
@ -33,7 +33,7 @@ export default function TabLayout() {
|
|||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="train"
|
name="train"
|
||||||
options={{
|
options={{
|
||||||
title: 'Ajouter un trajet',
|
title: 'Trains',
|
||||||
headerTitleStyle: {fontSize: 32},
|
headerTitleStyle: {fontSize: 32},
|
||||||
tabBarIcon: ({ color }) => <FontAwesome6 name="train" size={24} color={color} />,
|
tabBarIcon: ({ color }) => <FontAwesome6 name="train" size={24} color={color} />,
|
||||||
}}
|
}}
|
||||||
|
@ -27,7 +27,7 @@ export default function MapScreen() {
|
|||||||
visible={game.gameStarted || game.money > 0}
|
visible={game.gameStarted || game.money > 0}
|
||||||
size='small'
|
size='small'
|
||||||
color='black'
|
color='black'
|
||||||
icon={game.currentRunner ? 'run-fast' : 'police-badge'}
|
icon={game.currentRunner ? 'run-fast' : () => <FontAwesome6 name='cat' size={20} />}
|
||||||
label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} />
|
label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} />
|
||||||
</Surface>
|
</Surface>
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,65 @@
|
|||||||
import { ScrollView } from 'react-native'
|
import { useAddTrainMutation } from '@/hooks/mutations/useTrainMutation'
|
||||||
import { Surface, Text } from 'react-native-paper'
|
import { useAuth } from '@/hooks/useAuth'
|
||||||
|
import { useMemo, useState } from 'react'
|
||||||
|
import { StyleSheet } from 'react-native'
|
||||||
|
import { Button, Dialog, FAB, HelperText, Portal, Surface, Text, TextInput } from 'react-native-paper'
|
||||||
|
|
||||||
export default function TrainScreen() {
|
export default function TrainScreen() {
|
||||||
|
const [addTrainVisible, setAddTrainVisible] = useState(false)
|
||||||
|
const [addTrainUrl, setAddTrainUrl] = useState("")
|
||||||
|
const trainId = useMemo(() => /[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/.exec(addTrainUrl)?.[0], [addTrainUrl])
|
||||||
|
|
||||||
|
const auth = useAuth()
|
||||||
|
const addTrainMutation = useAddTrainMutation({
|
||||||
|
auth,
|
||||||
|
onPostSuccess: () => setAddTrainVisible(false)
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Surface>
|
<Surface style={{ flex: 1 }}>
|
||||||
<Text>Ici on aura la page pour ajouter un trajet en train depuis Rail Planner</Text>
|
<Text variant='bodyMedium'>Ici on aura la page pour ajouter un trajet en train depuis Rail Planner</Text>
|
||||||
|
<FAB
|
||||||
|
icon='plus'
|
||||||
|
style={styles.addTrainButton}
|
||||||
|
onPress={() => setAddTrainVisible(true)} />
|
||||||
|
<Portal>
|
||||||
|
<Dialog visible={addTrainVisible} onDismiss={() => setAddTrainVisible(false)}>
|
||||||
|
<Dialog.Title>Ajout d'un train</Dialog.Title>
|
||||||
|
<Dialog.Content>
|
||||||
|
<TextInput
|
||||||
|
label="URL de partage RailPlanner"
|
||||||
|
autoComplete='url'
|
||||||
|
inputMode='url'
|
||||||
|
defaultValue={addTrainUrl}
|
||||||
|
multiline={true}
|
||||||
|
onChangeText={setAddTrainUrl}
|
||||||
|
error={!trainId}
|
||||||
|
onEndEditing={() => {
|
||||||
|
if (trainId !== undefined)
|
||||||
|
addTrainMutation.mutate(trainId)
|
||||||
|
}}
|
||||||
|
placeholder="https://eurailapp.com/share/journey?id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&type=list&brand=interrail" />
|
||||||
|
<HelperText type='error' visible={!trainId && addTrainVisible}>
|
||||||
|
Le champ doit contenir l'identifiant d'un voyage au format UUID. {trainId}
|
||||||
|
</HelperText>
|
||||||
|
</Dialog.Content>
|
||||||
|
<Dialog.Actions>
|
||||||
|
<Button onPress={() => setAddTrainVisible(false)}>Annuler</Button>
|
||||||
|
<Button onPress={() => {
|
||||||
|
if (trainId !== undefined)
|
||||||
|
addTrainMutation.mutate(trainId)
|
||||||
|
}} disabled={trainId === undefined || addTrainMutation.isPending}>Ajouter</Button>
|
||||||
|
</Dialog.Actions>
|
||||||
|
</Dialog>
|
||||||
|
</Portal>
|
||||||
</Surface>
|
</Surface>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
addTrainButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: 25,
|
||||||
|
bottom: 25,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
49
client/hooks/mutations/useTrainMutation.ts
Normal file
49
client/hooks/mutations/useTrainMutation.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { AuthState } from "@/utils/features/auth/authSlice"
|
||||||
|
import { useMutation } from "@tanstack/react-query"
|
||||||
|
|
||||||
|
type ErrorResponse = {
|
||||||
|
error: string
|
||||||
|
message: string
|
||||||
|
statusCode: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type onPostSuccessFunc = () => void
|
||||||
|
type ErrorFuncProps = { response?: ErrorResponse, error?: Error }
|
||||||
|
type onErrorFunc = (props: ErrorFuncProps) => void
|
||||||
|
|
||||||
|
type TrainProps = {
|
||||||
|
// addTrain: (payload: TrainPayload) => { payload: GamePayload, type: "train/addTrain" }
|
||||||
|
auth: AuthState
|
||||||
|
onPostSuccess?: onPostSuccessFunc
|
||||||
|
onError?: onErrorFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAddTrainMutation = ({ auth, onPostSuccess, onError }: TrainProps) => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async (trainId: string) => {
|
||||||
|
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/trains/import/`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${auth.token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: trainId,
|
||||||
|
}),
|
||||||
|
}).then(resp => resp.json())
|
||||||
|
},
|
||||||
|
onSuccess: async (data) => {
|
||||||
|
if (data.error) {
|
||||||
|
if (onError)
|
||||||
|
onError({ response: data })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (onPostSuccess)
|
||||||
|
onPostSuccess()
|
||||||
|
},
|
||||||
|
onError: async (error: Error) => {
|
||||||
|
if (onError)
|
||||||
|
onError({ error: error })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -37,7 +37,7 @@ export class ChallengeActionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(id: number, updateChallengeActionDto: UpdateChallengeActionDto): Promise<ChallengeAction> {
|
async update(id: number, updateChallengeActionDto: UpdateChallengeActionDto): Promise<ChallengeAction> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucune action de défi trouvée avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucune action de défi trouvée avec l'identifiant ${id}`)
|
||||||
return await this.prisma.challengeAction.update({
|
return await this.prisma.challengeAction.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -46,7 +46,7 @@ export class ChallengeActionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: number): Promise<ChallengeAction> {
|
async remove(id: number): Promise<ChallengeAction> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucune action de défi trouvée avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucune action de défi trouvée avec l'identifiant ${id}`)
|
||||||
return await this.prisma.challengeAction.delete({
|
return await this.prisma.challengeAction.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
@ -38,7 +38,7 @@ export class ChallengesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(id: number, updateChallengeDto: UpdateChallengeDto): Promise<Challenge> {
|
async update(id: number, updateChallengeDto: UpdateChallengeDto): Promise<Challenge> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucun défi n'existe avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucun défi n'existe avec l'identifiant ${id}`)
|
||||||
return await this.prisma.challenge.update({
|
return await this.prisma.challenge.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -50,7 +50,7 @@ export class ChallengesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: number): Promise<Challenge> {
|
async remove(id: number): Promise<Challenge> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucun défi n'existe avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucun défi n'existe avec l'identifiant ${id}`)
|
||||||
return await this.prisma.challenge.delete({
|
return await this.prisma.challenge.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
@ -49,7 +49,7 @@ export class GeolocationsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: number): Promise<Geolocation> {
|
async remove(id: number): Promise<Geolocation> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucune géolocalisation n'existe avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucune géolocalisation n'existe avec l'identifiant ${id}`)
|
||||||
return await this.prisma.geolocation.delete({ where: { id } })
|
return await this.prisma.geolocation.delete({ where: { id } })
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ export class MoneyUpdatesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(id: number, updateMoneyUpdateDto: UpdateMoneyUpdateDto): Promise<MoneyUpdate> {
|
async update(id: number, updateMoneyUpdateDto: UpdateMoneyUpdateDto): Promise<MoneyUpdate> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucune modification de solde n'existe avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucune modification de solde n'existe avec l'identifiant ${id}`)
|
||||||
return await this.prisma.moneyUpdate.update({
|
return await this.prisma.moneyUpdate.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -48,7 +48,7 @@ export class MoneyUpdatesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: number): Promise<MoneyUpdate> {
|
async remove(id: number): Promise<MoneyUpdate> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Aucune modification de solde n'existe avec l'identifiant ${id}`)
|
throw new NotFoundException(`Aucune modification de solde n'existe avec l'identifiant ${id}`)
|
||||||
return await this.prisma.moneyUpdate.delete({
|
return await this.prisma.moneyUpdate.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
@ -40,7 +40,7 @@ export class TrainsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(id: string, updateTrainDto: UpdateTrainDto): Promise<TrainTrip> {
|
async update(id: string, updateTrainDto: UpdateTrainDto): Promise<TrainTrip> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Le train à modifier n'existe pas avec l'identifiant ${id}`)
|
throw new NotFoundException(`Le train à modifier n'existe pas avec l'identifiant ${id}`)
|
||||||
return await this.prisma.trainTrip.update({
|
return await this.prisma.trainTrip.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -49,7 +49,7 @@ export class TrainsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: string): Promise<TrainTrip> {
|
async remove(id: string): Promise<TrainTrip> {
|
||||||
if (!this.findOne(id))
|
if (!await this.findOne(id))
|
||||||
throw new NotFoundException(`Le train à supprimer n'existe pas avec l'identifiant ${id}`)
|
throw new NotFoundException(`Le train à supprimer n'existe pas avec l'identifiant ${id}`)
|
||||||
return await this.prisma.trainTrip.delete({
|
return await this.prisma.trainTrip.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -58,8 +58,7 @@ export class TrainsService {
|
|||||||
|
|
||||||
async import(player: Player, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
|
async import(player: Player, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
|
||||||
const game = await this.prisma.game.findUnique({ where: { id: 1 } })
|
const game = await this.prisma.game.findUnique({ where: { id: 1 } })
|
||||||
|
if (await this.findOne(trainId))
|
||||||
if (this.findOne(trainId))
|
|
||||||
throw new ConflictException(`Le train avec l'identifiant ${trainId} est déjà importé`)
|
throw new ConflictException(`Le train avec l'identifiant ${trainId} est déjà importé`)
|
||||||
|
|
||||||
const interrailResult: InterrailJourney = await fetch(`https://3uiwjsimnh.execute-api.eu-central-1.amazonaws.com/Prod/journey-import?id=${trainId}`)
|
const interrailResult: InterrailJourney = await fetch(`https://3uiwjsimnh.execute-api.eu-central-1.amazonaws.com/Prod/journey-import?id=${trainId}`)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user