From fd4b0e8cd1e580d2f4cf2b090181435c16f200d0 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Sat, 14 Dec 2024 12:36:50 +0100 Subject: [PATCH] =?UTF-8?q?Ajout,=20modification=20et=20suppression=20de?= =?UTF-8?q?=20d=C3=A9fi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/app/(tabs)/index.tsx | 6 +- client/app/challenges-list.tsx | 84 +++++++++++++++- .../hooks/mutations/useChallengeMutation.ts | 98 +++++++++++++++++++ 3 files changed, 182 insertions(+), 6 deletions(-) diff --git a/client/app/(tabs)/index.tsx b/client/app/(tabs)/index.tsx index 5d5bb65..4610c50 100644 --- a/client/app/(tabs)/index.tsx +++ b/client/app/(tabs)/index.tsx @@ -24,14 +24,16 @@ export default function MapScreen() { visible={game.gameStarted || game.money > 0} icon={(props) => } color='black' - label={`${game.money}`} /> + label={`${game.money}`} + onPress={() => {}} /> 0} size='small' color='black' icon={game.currentRunner ? 'run-fast' : () => } - label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} /> + label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} + onPress={() => {}} /> diff --git a/client/app/challenges-list.tsx b/client/app/challenges-list.tsx index 1ba2afa..633d35f 100644 --- a/client/app/challenges-list.tsx +++ b/client/app/challenges-list.tsx @@ -1,7 +1,10 @@ import ChallengeCard from "@/components/ChallengeCard" +import { useAddChallengeMutation, useDeleteChallengeMutation, useEditChallengeMutation } from "@/hooks/mutations/useChallengeMutation" +import { useAuth } from "@/hooks/useAuth" import { useChallenges } from "@/hooks/useChallenges" import { Challenge } from "@/utils/features/challenges/challengesSlice" import { FontAwesome6 } from "@expo/vector-icons" +import { useQueryClient } from "@tanstack/react-query" import { useRouter } from "expo-router" import { useState } from "react" import { FlatList, StyleSheet } from "react-native" @@ -9,6 +12,8 @@ import { Appbar, Button, Dialog, Divider, FAB, List, MD3Colors, Modal, Portal, S export default function ChallengesList() { const router = useRouter() + const queryClient = useQueryClient() + const auth = useAuth() const challenges = useChallenges() const [editChallengeVisible, setEditChallengeVisible] = useState(false) @@ -23,6 +28,77 @@ export default function ChallengesList() { const [errorVisible, setErrorVisible] = useState(false) const [error, setError] = useState([200, ""]) + const addChallengeMutation = useAddChallengeMutation({ + auth, + onPostSuccess: () => { + setSuccessMessage("Le défi a bien été ajouté !") + setSuccessSnackbarVisible(true) + queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' }) + }, + onError: ({ response, error }) => { + setErrorVisible(true) + if (response) + setError([response.statusCode, response.message]) + else if (error) + setError([400, error.message]) + }, + }) + const editChallengeMutation = useEditChallengeMutation({ + auth, + onPostSuccess: () => { + setSuccessMessage("Le défi a bien été modifié !") + setSuccessSnackbarVisible(true) + setEditChallengeVisible(false) + setDisplayedChallenge(null) + queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' }) + }, + onError: ({ response, error }) => { + setErrorVisible(true) + if (response) + setError([response.statusCode, response.message]) + else if (error) + setError([400, error.message]) + }, + }) + const deleteChallengeMutation = useDeleteChallengeMutation({ + auth, + onPostSuccess: () => { + setSuccessMessage("Le défi a bien été supprimé !") + setSuccessSnackbarVisible(true) + setEditChallengeVisible(false) + queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-challenges' }) + }, + onError: ({ response, error }) => { + setErrorVisible(true) + if (response) + setError([response.statusCode, response.message]) + else if (error) + setError([400, error.message]) + }, + }) + + function sendEditChallenge() { + if (editChallengeId) { + editChallengeMutation.mutate({ + id: editChallengeId, + title: editChallengeTitle, + description: editChallengeDescription, + reward: editChallengeReward, + }) + } + else { + addChallengeMutation.mutate({ + title: editChallengeTitle, + description: editChallengeDescription, + reward: editChallengeReward, + }) + } + } + + function sendDeleteChallenge() { + displayedChallenge && deleteChallengeMutation.mutate(displayedChallenge) + } + return ( @@ -103,14 +179,14 @@ export default function ChallengesList() { inputMode='numeric' onChangeText={(text) => setEditChallengeReward(+text)} error={!editChallengeReward} - onEndEditing={() => { }} /> + onEndEditing={sendEditChallenge} /> @@ -123,7 +199,7 @@ export default function ChallengesList() { - + diff --git a/client/hooks/mutations/useChallengeMutation.ts b/client/hooks/mutations/useChallengeMutation.ts index 9e3c1bb..7a89618 100644 --- a/client/hooks/mutations/useChallengeMutation.ts +++ b/client/hooks/mutations/useChallengeMutation.ts @@ -1,4 +1,5 @@ import { AuthState } from "@/utils/features/auth/authSlice" +import { Challenge } from "@/utils/features/challenges/challengesSlice" import { useMutation } from "@tanstack/react-query" type ErrorResponse = { @@ -17,6 +18,12 @@ type ChallengeActionProps = { onError?: onErrorFunc } +type ChallengeProps = { + auth: AuthState + onPostSuccess?: onPostSuccessFunc + onError?: onErrorFunc +} + export const useDrawRandomChallengeMutation = ({ auth, onPostSuccess, onError }: ChallengeActionProps) => { return useMutation({ mutationFn: async () => { @@ -73,3 +80,94 @@ export const useEndChallenge = ({ auth, onPostSuccess, onError }: ChallengeActio } }) } + +export const useAddChallengeMutation = ({ auth, onPostSuccess, onError }: ChallengeProps) => { + return useMutation({ + mutationFn: async (challenge: Omit) => { + return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/challenges/`, { + method: "POST", + headers: { + "Authorization": `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: challenge.title, + description: challenge.description, + reward: challenge.reward, + }) + }).then(resp => resp.json()) + }, + onSuccess: async (data) => { + if (data.statusCode) { + if (onError) + onError({ response: data }) + return + } + if (onPostSuccess) + onPostSuccess() + }, + onError: async (error: Error) => { + if (onError) + onError({ error: error }) + } + }) +} + +export const useEditChallengeMutation = ({ auth, onPostSuccess, onError }: ChallengeProps) => { + return useMutation({ + mutationFn: async (challenge: Challenge) => { + return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/challenges/${challenge.id}/`, { + method: "PATCH", + headers: { + "Authorization": `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: challenge.title, + description: challenge.description, + reward: challenge.reward, + }) + }).then(resp => resp.json()) + }, + onSuccess: async (data) => { + if (data.statusCode) { + if (onError) + onError({ response: data }) + return + } + if (onPostSuccess) + onPostSuccess() + }, + onError: async (error: Error) => { + if (onError) + onError({ error: error }) + } + }) +} + +export const useDeleteChallengeMutation = ({ auth, onPostSuccess, onError }: ChallengeProps) => { + return useMutation({ + mutationFn: async (challenge: Challenge) => { + return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/challenges/${challenge.id}/`, { + method: "DELETE", + headers: { + "Authorization": `Bearer ${auth.token}`, + "Content-Type": "application/json", + }, + }).then(resp => resp.json()) + }, + onSuccess: async (data) => { + if (data.statusCode) { + if (onError) + onError({ response: data }) + return + } + if (onPostSuccess) + onPostSuccess() + }, + onError: async (error: Error) => { + if (onError) + onError({ error: error }) + } + }) +}