Add genlocke admin panel with CRUD endpoints and UI

Backend: PATCH/DELETE genlocke, POST/DELETE legs with order
re-numbering. Frontend: admin list page with status filter,
detail page with inline editing, legs table, and stats display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Julian Tabel
2026-02-09 10:51:47 +01:00
parent 08f6857451
commit a81a17c485
11 changed files with 685 additions and 12 deletions

View File

@@ -17,6 +17,8 @@ import type {
UpdateBossBattleInput,
BossPokemonInput,
BossReorderItem,
UpdateGenlockeInput,
AddGenlockeLegInput,
} from '../types'
// --- Queries ---
@@ -360,3 +362,56 @@ export function useSetBossTeam(gameId: number, bossId: number) {
onError: (err) => toast.error(`Failed to update boss team: ${err.message}`),
})
}
// --- Genlocke Mutations ---
export function useUpdateGenlocke() {
const qc = useQueryClient()
return useMutation({
mutationFn: ({ id, data }: { id: number; data: UpdateGenlockeInput }) =>
adminApi.updateGenlocke(id, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['genlockes'] })
toast.success('Genlocke updated')
},
onError: (err) => toast.error(`Failed to update genlocke: ${err.message}`),
})
}
export function useDeleteGenlocke() {
const qc = useQueryClient()
return useMutation({
mutationFn: (id: number) => adminApi.deleteGenlocke(id),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['genlockes'] })
toast.success('Genlocke deleted')
},
onError: (err) => toast.error(`Failed to delete genlocke: ${err.message}`),
})
}
export function useAddGenlockeLeg(genlockeId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (data: AddGenlockeLegInput) => adminApi.addGenlockeLeg(genlockeId, data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['genlockes'] })
qc.invalidateQueries({ queryKey: ['genlockes', genlockeId] })
toast.success('Leg added')
},
onError: (err) => toast.error(`Failed to add leg: ${err.message}`),
})
}
export function useDeleteGenlockeLeg(genlockeId: number) {
const qc = useQueryClient()
return useMutation({
mutationFn: (legId: number) => adminApi.deleteGenlockeLeg(genlockeId, legId),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['genlockes'] })
qc.invalidateQueries({ queryKey: ['genlockes', genlockeId] })
toast.success('Leg removed')
},
onError: (err) => toast.error(`Failed to remove leg: ${err.message}`),
})
}