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 })
+ }
+ })
+}