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}`) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user