152 lines
4.4 KiB
TypeScript
152 lines
4.4 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import axios from "axios";
|
|
|
|
export type BandOption = {
|
|
id: number;
|
|
name: string;
|
|
order?: number | null;
|
|
has_power_category?: boolean | null;
|
|
};
|
|
|
|
export type EdiCategoryOption = {
|
|
id: number;
|
|
value: string;
|
|
};
|
|
|
|
export type EdiBandOption = {
|
|
id: number;
|
|
value: string;
|
|
bands?: { id: number; name: string }[];
|
|
};
|
|
|
|
type SelectedRoundLike = {
|
|
id?: number | null;
|
|
bands?: BandOption[];
|
|
} | null;
|
|
|
|
export const useRoundMeta = (roundId: number | null, selectedRound: SelectedRoundLike) => {
|
|
const [bands, setBands] = useState<BandOption[]>([]);
|
|
const [bandsError, setBandsError] = useState<string | null>(null);
|
|
const [bandsLoading, setBandsLoading] = useState(false);
|
|
const [ediCategories, setEdiCategories] = useState<EdiCategoryOption[]>([]);
|
|
const [ediCategoriesError, setEdiCategoriesError] = useState<string | null>(null);
|
|
const [ediCategoriesLoading, setEdiCategoriesLoading] = useState(false);
|
|
const [ediBands, setEdiBands] = useState<EdiBandOption[]>([]);
|
|
|
|
// načti dostupné bandy pro select PBand
|
|
useEffect(() => {
|
|
let active = true;
|
|
(async () => {
|
|
try {
|
|
setBandsLoading(true);
|
|
setBandsError(null);
|
|
|
|
let bandList: BandOption[] = [];
|
|
|
|
if (roundId && selectedRound?.id === roundId && Array.isArray(selectedRound.bands)) {
|
|
bandList = selectedRound.bands as BandOption[];
|
|
}
|
|
|
|
if (roundId) {
|
|
try {
|
|
const roundRes = await axios.get<any>(`/api/rounds/${roundId}`, {
|
|
headers: { Accept: "application/json" },
|
|
withCredentials: true,
|
|
});
|
|
if (Array.isArray(roundRes.data?.bands) && roundRes.data.bands.length > 0) {
|
|
bandList = roundRes.data.bands;
|
|
}
|
|
} catch {
|
|
// fallback handled below
|
|
}
|
|
}
|
|
|
|
if (!bandList.length) {
|
|
const res = await axios.get<BandOption[] | { data: BandOption[] }>("/api/bands", {
|
|
headers: { Accept: "application/json" },
|
|
withCredentials: true,
|
|
});
|
|
bandList = Array.isArray(res.data) ? res.data : (res.data as any)?.data ?? [];
|
|
}
|
|
|
|
if (!active) return;
|
|
const sorted = [...bandList].sort((a, b) => {
|
|
const aOrder = a.order ?? 0;
|
|
const bOrder = b.order ?? 0;
|
|
if (aOrder !== bOrder) return aOrder - bOrder;
|
|
return a.name.localeCompare(b.name);
|
|
});
|
|
setBands(sorted);
|
|
} catch {
|
|
if (!active) return;
|
|
setBandsError("Nepodařilo se načíst seznam pásem.");
|
|
} finally {
|
|
if (active) setBandsLoading(false);
|
|
}
|
|
})();
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, [roundId, selectedRound]);
|
|
|
|
// načti dostupné EDI kategorie pro validaci PSect
|
|
useEffect(() => {
|
|
let active = true;
|
|
(async () => {
|
|
try {
|
|
setEdiCategoriesLoading(true);
|
|
setEdiCategoriesError(null);
|
|
const res = await axios.get<EdiCategoryOption[] | { data: EdiCategoryOption[] }>("/api/edi-categories", {
|
|
headers: { Accept: "application/json" },
|
|
withCredentials: true,
|
|
});
|
|
if (!active) return;
|
|
const raw = Array.isArray(res.data) ? res.data : (res.data as any)?.data ?? [];
|
|
const sorted = [...raw].sort((a, b) => a.value.localeCompare(b.value));
|
|
setEdiCategories(sorted);
|
|
} catch {
|
|
if (!active) return;
|
|
setEdiCategoriesError("Nepodařilo se načíst seznam kategorií.");
|
|
} finally {
|
|
if (active) setEdiCategoriesLoading(false);
|
|
}
|
|
})();
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, []);
|
|
|
|
// načti EDI bandy pro mapování PBand -> Band
|
|
useEffect(() => {
|
|
let active = true;
|
|
(async () => {
|
|
try {
|
|
const res = await axios.get<EdiBandOption[] | { data: EdiBandOption[] }>("/api/edi-bands", {
|
|
headers: { Accept: "application/json" },
|
|
withCredentials: true,
|
|
params: { per_page: 500 },
|
|
});
|
|
if (!active) return;
|
|
const raw = Array.isArray(res.data) ? res.data : (res.data as any)?.data ?? [];
|
|
setEdiBands(raw);
|
|
} catch {
|
|
if (!active) return;
|
|
// nechávám tiché selhání, mapování je nice-to-have
|
|
}
|
|
})();
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, []);
|
|
|
|
return {
|
|
bands,
|
|
bandsError,
|
|
bandsLoading,
|
|
ediCategories,
|
|
ediCategoriesError,
|
|
ediCategoriesLoading,
|
|
ediBands,
|
|
};
|
|
};
|