60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
import { ApiError } from "../../api/client";
|
|
import { Spinner } from "../../components/Spinner";
|
|
import { useToast } from "../../context/ToastContext";
|
|
import { useAdminFactions, useAdminRenameFaction } from "../../hooks/admin";
|
|
|
|
export function AdminFactionsPage() {
|
|
const { data: factions, isLoading } = useAdminFactions();
|
|
const rename = useAdminRenameFaction();
|
|
const toast = useToast();
|
|
const [names, setNames] = useState<Record<number, string>>({});
|
|
|
|
useEffect(() => {
|
|
if (factions) {
|
|
setNames(Object.fromEntries(factions.map((f) => [f.id, f.name_ru])));
|
|
}
|
|
}, [factions]);
|
|
|
|
if (isLoading) return <Spinner />;
|
|
|
|
const save = async (id: number) => {
|
|
try {
|
|
await rename.mutateAsync({ factionId: id, name_ru: names[id] });
|
|
toast.show("Название обновлено во всей системе");
|
|
} catch (e) {
|
|
toast.show(e instanceof ApiError ? e.message : "Ошибка");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<h3>Фракции</h3>
|
|
<p className="muted small">
|
|
Переименование меняет название фракции во всех партиях и статистике.
|
|
</p>
|
|
<div className="stack">
|
|
{(factions ?? []).map((f) => (
|
|
<div key={f.id} className="card" style={{ margin: 0 }}>
|
|
<div className="muted small">{f.code}</div>
|
|
<div className="row">
|
|
<input
|
|
value={names[f.id] ?? ""}
|
|
onChange={(e) => setNames((n) => ({ ...n, [f.id]: e.target.value }))}
|
|
/>
|
|
<button
|
|
className="btn btn-primary"
|
|
disabled={!names[f.id] || names[f.id] === f.name_ru}
|
|
onClick={() => save(f.id)}
|
|
>
|
|
ОК
|
|
</button>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|