118 lines
4.6 KiB
TypeScript
118 lines
4.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
||
// import { DefaultService } from "../../api";
|
||
import { addUserTitle, deleteUserTitle, getUserTitle, updateUserTitle } from "../../api";
|
||
import type { UserTitleStatus } from "../../api";
|
||
import { useCookies } from 'react-cookie';
|
||
|
||
import {
|
||
ClockIcon,
|
||
CheckCircleIcon,
|
||
PlayCircleIcon,
|
||
XCircleIcon,
|
||
} from "@heroicons/react/24/solid";
|
||
// import { stat } from "fs";
|
||
|
||
// Статусы с иконками и подписью
|
||
const STATUS_BUTTONS: { status: UserTitleStatus; icon: React.ReactNode; label: string }[] = [
|
||
{ status: "planned", icon: <ClockIcon className="w-5 h-5" />, label: "Planned" },
|
||
{ status: "finished", icon: <CheckCircleIcon className="w-5 h-5" />, label: "Finished" },
|
||
{ status: "in-progress", icon: <PlayCircleIcon className="w-5 h-5" />, label: "In Progress" },
|
||
{ status: "dropped", icon: <XCircleIcon className="w-5 h-5" />, label: "Dropped" },
|
||
];
|
||
|
||
export function TitleStatusControls({ titleId }: { titleId: number }) {
|
||
const [cookies] = useCookies(['xsrf_token']);
|
||
const xsrfToken = cookies['xsrf_token'] || null;
|
||
|
||
const [currentStatus, setCurrentStatus] = useState<UserTitleStatus | null>(null);
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
const userIdStr = localStorage.getItem("userId");
|
||
const userId = userIdStr ? Number(userIdStr) : null;
|
||
|
||
// --- Load initial status ---
|
||
useEffect(() => {
|
||
if (!userId) return;
|
||
getUserTitle({ path: { user_id: userId, title_id: titleId } })
|
||
.then(res => setCurrentStatus(res.data?.status ?? null))
|
||
.catch(() => setCurrentStatus(null)); // 404 = not assigned
|
||
|
||
// DefaultService.getUserTitle(userId, titleId)
|
||
// .then((res) => setCurrentStatus(res.status))
|
||
// .catch(() => setCurrentStatus(null)); // 404 = user title does not exist
|
||
}, [titleId, userId]);
|
||
|
||
// --- Handle click ---
|
||
const handleStatusClick = async (status: UserTitleStatus) => {
|
||
if (!userId || loading) return;
|
||
|
||
setLoading(true);
|
||
|
||
try {
|
||
// 1) Если кликнули на текущий статус — DELETE
|
||
if (currentStatus === status) {
|
||
// await DefaultService.deleteUserTitle(userId, titleId);
|
||
await deleteUserTitle({path: {
|
||
user_id: userId,
|
||
title_id: titleId,
|
||
},
|
||
headers: { "X-XSRF-TOKEN": xsrfToken },
|
||
})
|
||
setCurrentStatus(null);
|
||
return;
|
||
}
|
||
|
||
// 2) Если другой статус — POST или PATCH
|
||
if (!currentStatus) {
|
||
// ещё нет записи — POST
|
||
// const added = await DefaultService.addUserTitle(userId, {
|
||
// title_id: titleId,
|
||
// status,
|
||
// });
|
||
const added = await addUserTitle({
|
||
body: {
|
||
title_id: titleId,
|
||
status: status,
|
||
},
|
||
path: {user_id: userId},
|
||
headers: { "X-XSRF-TOKEN": xsrfToken },
|
||
});
|
||
|
||
setCurrentStatus(added.data?.status ?? null);
|
||
} else {
|
||
// уже есть запись — PATCH
|
||
//const updated = await DefaultService.updateUserTitle(userId, titleId, { status });
|
||
const updated = await updateUserTitle({
|
||
path: { user_id: userId, title_id: titleId },
|
||
body: { status },
|
||
headers: { "X-XSRF-TOKEN": xsrfToken },
|
||
});
|
||
setCurrentStatus(updated.data?.status ?? null);
|
||
}
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="flex gap-2 flex-wrap justify-center mt-2">
|
||
{STATUS_BUTTONS.map(btn => (
|
||
<button
|
||
key={btn.status}
|
||
onClick={() => handleStatusClick(btn.status)}
|
||
disabled={loading}
|
||
className={`
|
||
px-3 py-1 rounded-md border flex items-center gap-1 transition
|
||
${currentStatus === btn.status
|
||
? "bg-blue-600 text-white border-blue-700"
|
||
: "bg-gray-200 text-black border-gray-300 hover:bg-gray-300"}
|
||
`}
|
||
title={btn.label}
|
||
>
|
||
{btn.icon}
|
||
<span>{btn.label}</span>
|
||
</button>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|