Compare commits
	
		
			2 Commits
		
	
	
		
			af14cfb11d
			...
			33ee18d7e2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 33ee18d7e2 | |||
| 54a7806316 | 
| @@ -33,7 +33,7 @@ export default function TabLayout() { | ||||
|       <Tabs.Screen | ||||
|         name="train" | ||||
|         options={{ | ||||
|           title: 'Ajouter un trajet', | ||||
|           title: 'Trains', | ||||
|           headerTitleStyle: {fontSize: 32}, | ||||
|           tabBarIcon: ({ color }) => <FontAwesome6 name="train" size={24} color={color} />, | ||||
|         }} | ||||
|   | ||||
| @@ -27,7 +27,7 @@ export default function MapScreen() { | ||||
|           visible={game.gameStarted || game.money > 0} | ||||
|           size='small' | ||||
|           color='black' | ||||
|           icon={game.currentRunner ? 'run-fast' : 'police-badge'} | ||||
|           icon={game.currentRunner ? 'run-fast' : () => <FontAwesome6 name='cat' size={20} />} | ||||
|           label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} /> | ||||
|     </Surface> | ||||
|   ) | ||||
|   | ||||
| @@ -1,10 +1,65 @@ | ||||
| import { ScrollView } from 'react-native' | ||||
| import { Surface, Text } from 'react-native-paper' | ||||
| import { useAddTrainMutation } from '@/hooks/mutations/useTrainMutation' | ||||
| 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() { | ||||
|   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 ( | ||||
|     <Surface> | ||||
|       <Text>Ici on aura la page pour ajouter un trajet en train depuis Rail Planner</Text> | ||||
|     <Surface style={{ flex: 1 }}> | ||||
|       <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> | ||||
|   ) | ||||
| } | ||||
|  | ||||
| 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> { | ||||
|     if (!this.findOne(id)) | ||||
|     if (!await this.findOne(id)) | ||||
|       throw new NotFoundException(`Aucune action de défi trouvée avec l'identifiant ${id}`) | ||||
|     return await this.prisma.challengeAction.update({ | ||||
|       where: { id }, | ||||
| @@ -46,7 +46,7 @@ export class ChallengeActionsService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.challengeAction.delete({ | ||||
|       where: { id }, | ||||
|   | ||||
| @@ -38,7 +38,7 @@ export class ChallengesService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.challenge.update({ | ||||
|       where: { id }, | ||||
| @@ -50,7 +50,7 @@ export class ChallengesService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.challenge.delete({ | ||||
|       where: { id }, | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export class GeolocationsService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.geolocation.delete({ where: { id } }) | ||||
|   } | ||||
|   | ||||
| @@ -39,7 +39,7 @@ export class MoneyUpdatesService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.moneyUpdate.update({ | ||||
|       where: { id }, | ||||
| @@ -48,7 +48,7 @@ export class MoneyUpdatesService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.moneyUpdate.delete({ | ||||
|       where: { id }, | ||||
|   | ||||
| @@ -40,7 +40,7 @@ export class TrainsService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.trainTrip.update({ | ||||
|       where: { id }, | ||||
| @@ -49,7 +49,7 @@ export class TrainsService { | ||||
|   } | ||||
|  | ||||
|   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}`) | ||||
|     return await this.prisma.trainTrip.delete({ | ||||
|       where: { id }, | ||||
| @@ -58,8 +58,7 @@ export class TrainsService { | ||||
|  | ||||
|   async import(player: Player, { id: trainId }: ImportTrainDto): Promise<TrainTrip> { | ||||
|     const game = await this.prisma.game.findUnique({ where: { id: 1 } }) | ||||
|  | ||||
|     if (this.findOne(trainId)) | ||||
|     if (await this.findOne(trainId)) | ||||
|       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}`) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user