Админ: управление медиа партии (добавление/удаление в любой момент)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { ApiError, api, unwrap } from "../api/client";
|
||||
import { qk } from "../api/queryKeys";
|
||||
import type { AdminMe, MatchUpdate } from "../domain/types";
|
||||
import { resizeImage } from "../lib/image";
|
||||
|
||||
function readCsrfToken(): string | null {
|
||||
const m = document.cookie.match(/(?:^|; )csrf_token=([^;]*)/);
|
||||
@@ -87,6 +88,64 @@ export function useAdminMatch(matchId: number | null) {
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Медиа партии (админ правит в любой момент) ──────────────────────────────
|
||||
|
||||
export function useAdminMatchAttachments(matchId: number | null) {
|
||||
return useQuery({
|
||||
queryKey: ["adminMatchAttachments", matchId],
|
||||
enabled: matchId != null,
|
||||
queryFn: async () =>
|
||||
unwrap(
|
||||
await api.GET("/api/admin/matches/{match_id}/attachments", {
|
||||
params: { path: { match_id: matchId as number } },
|
||||
}),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
export function useAdminUploadAttachment(matchId: number) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (file: File) => {
|
||||
const blob = await resizeImage(file);
|
||||
const form = new FormData();
|
||||
form.append("file", blob, "photo.jpg");
|
||||
const csrf = readCsrfToken();
|
||||
const base = import.meta.env.VITE_API_BASE_URL || "";
|
||||
const r = await fetch(`${base}/api/admin/matches/${matchId}/attachments`, {
|
||||
method: "POST",
|
||||
body: form,
|
||||
credentials: "include",
|
||||
headers: csrf ? { "X-CSRF-Token": csrf } : {},
|
||||
});
|
||||
if (!r.ok) {
|
||||
let env: { code?: string; message?: string } | undefined;
|
||||
try {
|
||||
env = ((await r.json()) as { error?: typeof env }).error;
|
||||
} catch {
|
||||
/* тело без JSON */
|
||||
}
|
||||
throw new ApiError(env?.message || "Не удалось загрузить", env?.code || "ERROR", r.status);
|
||||
}
|
||||
return await r.json();
|
||||
},
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ["adminMatchAttachments", matchId] }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useAdminDeleteAttachment(matchId: number) {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (attachmentId: number) =>
|
||||
unwrap(
|
||||
await api.DELETE("/api/admin/matches/{match_id}/attachments/{attachment_id}", {
|
||||
params: { path: { match_id: matchId, attachment_id: attachmentId } },
|
||||
}),
|
||||
),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ["adminMatchAttachments", matchId] }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useAdminUpdateMatch() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
|
||||
Reference in New Issue
Block a user