Files
nuzlocke-tracker/frontend/src/hooks/useAdmin.ts

165 lines
4.9 KiB
TypeScript
Raw Normal View History

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import * as adminApi from '../api/admin'
import type {
CreateGameInput,
UpdateGameInput,
CreateRouteInput,
UpdateRouteInput,
RouteReorderItem,
CreatePokemonInput,
UpdatePokemonInput,
CreateRouteEncounterInput,
UpdateRouteEncounterInput,
} from '../types'
// --- Queries ---
export function usePokemonList(search?: string, limit = 50, offset = 0) {
return useQuery({
queryKey: ['pokemon', { search, limit, offset }],
queryFn: () => adminApi.listPokemon(search, limit, offset),
})
}
// --- Game Mutations ---
export function useCreateGame() {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: CreateGameInput) => adminApi.createGame(data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['games'] }),
})
}
export function useUpdateGame() {
const qc = useQueryClient()
return useMutation({
mutationFn: ({ id, data }: { id: number; data: UpdateGameInput }) =>
adminApi.updateGame(id, data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['games'] }),
})
}
export function useDeleteGame() {
const qc = useQueryClient()
return useMutation({
mutationFn: (id: number) => adminApi.deleteGame(id),
onSuccess: () => qc.invalidateQueries({ queryKey: ['games'] }),
})
}
// --- Route Mutations ---
export function useCreateRoute(gameId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: CreateRouteInput) => adminApi.createRoute(gameId, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['games', gameId] })
qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
},
})
}
export function useUpdateRoute(gameId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: ({ routeId, data }: { routeId: number; data: UpdateRouteInput }) =>
adminApi.updateRoute(gameId, routeId, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['games', gameId] })
qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
},
})
}
export function useDeleteRoute(gameId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (routeId: number) => adminApi.deleteRoute(gameId, routeId),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['games', gameId] })
qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
},
})
}
export function useReorderRoutes(gameId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (routes: RouteReorderItem[]) => adminApi.reorderRoutes(gameId, routes),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['games', gameId] })
qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
},
})
}
// --- Pokemon Mutations ---
export function useCreatePokemon() {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: CreatePokemonInput) => adminApi.createPokemon(data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['pokemon'] }),
})
}
export function useUpdatePokemon() {
const qc = useQueryClient()
return useMutation({
mutationFn: ({ id, data }: { id: number; data: UpdatePokemonInput }) =>
adminApi.updatePokemon(id, data),
onSuccess: () => qc.invalidateQueries({ queryKey: ['pokemon'] }),
})
}
export function useDeletePokemon() {
const qc = useQueryClient()
return useMutation({
mutationFn: (id: number) => adminApi.deletePokemon(id),
onSuccess: () => qc.invalidateQueries({ queryKey: ['pokemon'] }),
})
}
export function useBulkImportPokemon() {
const qc = useQueryClient()
return useMutation({
mutationFn: (items: Array<{ nationalDex: number; name: string; types: string[]; spriteUrl?: string | null }>) =>
adminApi.bulkImportPokemon(items),
onSuccess: () => qc.invalidateQueries({ queryKey: ['pokemon'] }),
})
}
// --- Route Encounter Mutations ---
export function useAddRouteEncounter(routeId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: CreateRouteEncounterInput) =>
adminApi.addRouteEncounter(routeId, data),
onSuccess: () =>
qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] }),
})
}
export function useUpdateRouteEncounter(routeId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: ({ encounterId, data }: { encounterId: number; data: UpdateRouteEncounterInput }) =>
adminApi.updateRouteEncounter(routeId, encounterId, data),
onSuccess: () =>
qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] }),
})
}
export function useRemoveRouteEncounter(routeId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (encounterId: number) =>
adminApi.removeRouteEncounter(routeId, encounterId),
onSuccess: () =>
qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] }),
})
}