Доделать уведомления + историю волонтера + пофиксить визуал
This commit is contained in:
@@ -18,7 +18,6 @@ const statusMap = {
|
||||
|
||||
const HistoryRequestPage = () => {
|
||||
const [userName, setUserName] = useState("Волонтёр");
|
||||
|
||||
const [requests, setRequests] = useState([]);
|
||||
const [selectedRequest, setSelectedRequest] = useState(null);
|
||||
|
||||
@@ -32,7 +31,7 @@ const HistoryRequestPage = () => {
|
||||
return authUser?.accessToken || null;
|
||||
};
|
||||
|
||||
// имя
|
||||
// профиль волонтёра
|
||||
useEffect(() => {
|
||||
const fetchProfile = async () => {
|
||||
if (!API_BASE) return;
|
||||
@@ -60,7 +59,7 @@ const HistoryRequestPage = () => {
|
||||
fetchProfile();
|
||||
}, []);
|
||||
|
||||
// история: /requests/my
|
||||
// история откликов волонтёра: /responses/my
|
||||
useEffect(() => {
|
||||
const fetchVolunteerRequests = async () => {
|
||||
if (!API_BASE) {
|
||||
@@ -76,62 +75,72 @@ const HistoryRequestPage = () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
limit: "50",
|
||||
offset: "0",
|
||||
});
|
||||
|
||||
const res = await fetch(`${API_BASE}/requests/my?${params}`, {
|
||||
const res = await fetch(`${API_BASE}/responses/my`, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
const text = await res.text();
|
||||
let data = null;
|
||||
if (text) {
|
||||
try {
|
||||
data = JSON.parse(text);
|
||||
} catch {
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
let msg = "Не удалось загрузить историю заявок";
|
||||
try {
|
||||
const data = await res.json();
|
||||
if (data.error) msg = data.error;
|
||||
} catch {
|
||||
const text = await res.text();
|
||||
if (text) msg = text;
|
||||
if (data && typeof data === "object" && data.error) {
|
||||
msg = data.error;
|
||||
} else if (text) {
|
||||
msg = text;
|
||||
}
|
||||
setError(msg);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json(); // RequestListItem[][web:598]
|
||||
const list = Array.isArray(data) ? data : [];
|
||||
|
||||
const mapped = data.map((item) => {
|
||||
const key = String(item.status || "").toLowerCase();
|
||||
const m = statusMap[key] || {
|
||||
label: item.status,
|
||||
// status: { response_status: "...", valid: true }
|
||||
const mapped = list.map((item) => {
|
||||
const rawStatus = String(
|
||||
item.status?.response_status || item.status || ""
|
||||
).toLowerCase();
|
||||
|
||||
const m = statusMap[rawStatus] || {
|
||||
label: rawStatus || "Неизвестен",
|
||||
color: "#E2E2E2",
|
||||
};
|
||||
|
||||
const created = new Date(item.created_at);
|
||||
const createdAt = created.toLocaleDateString("ru-RU");
|
||||
const date = created.toLocaleDateString("ru-RU");
|
||||
const time = created.toLocaleTimeString("ru-RU", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
id: item.request_id ?? item.id,
|
||||
title: item.title,
|
||||
description: item.description,
|
||||
status: m.label,
|
||||
statusColor: m.color,
|
||||
createdAt,
|
||||
date: createdAt,
|
||||
date,
|
||||
time,
|
||||
description: item.description,
|
||||
address: item.address,
|
||||
city: item.city,
|
||||
createdAt: date,
|
||||
address: item.city ? `${item.city}, ${item.address}` : item.address,
|
||||
requesterName: item.requester_name,
|
||||
requestTypeName: item.request_type_name,
|
||||
rawStatus: item.status,
|
||||
requestTypeName:
|
||||
item.request_type_name &&
|
||||
typeof item.request_type_name === "object"
|
||||
? item.request_type_name.name
|
||||
: item.request_type_name,
|
||||
rawStatus, // настоящий статус для модалки
|
||||
};
|
||||
});
|
||||
|
||||
@@ -147,7 +156,11 @@ const HistoryRequestPage = () => {
|
||||
}, []);
|
||||
|
||||
const handleOpen = (req) => {
|
||||
setSelectedRequest(req);
|
||||
// если модалке нужен сырой статус — пробрасываем его так же, как в референсе
|
||||
setSelectedRequest({
|
||||
...req,
|
||||
status: req.rawStatus,
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
@@ -160,10 +173,10 @@ const HistoryRequestPage = () => {
|
||||
{/* Header */}
|
||||
<header className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 rounded-full border border-white flex items.center justify-center">
|
||||
<div className="w-8 h-8 rounded-full border border-white flex items-center justify-center">
|
||||
<FaUser className="text-white text-sm" />
|
||||
</div>
|
||||
<p className="font-montserrat font-extrabold text-[20px] leading-[11px] text-white">
|
||||
<p className="font-montserrat font-extrabold text-[20px] leading-[22px] text-white">
|
||||
{userName}
|
||||
</p>
|
||||
</div>
|
||||
@@ -180,9 +193,9 @@ const HistoryRequestPage = () => {
|
||||
</h1>
|
||||
|
||||
{error && (
|
||||
<div className="mb-2 bg-red-500 text-white text-xs font-montserrat px-3 py-2 rounded-lg">
|
||||
<p className="mb-2 text-xs font-montserrat text-red-200">
|
||||
{error}
|
||||
</div>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Список заявок */}
|
||||
@@ -208,12 +221,12 @@ const HistoryRequestPage = () => {
|
||||
>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span
|
||||
className="inline-flex items-center justify-center px-2 py-0.5 rounded-full font-montserrat text-[12px] font-light text-black"
|
||||
className="inline-flex items-center justify-center px-2 py-0.5 rounded-full font-montserrat text-[12px] font-semibold text.white"
|
||||
style={{ backgroundColor: req.statusColor }}
|
||||
>
|
||||
{req.status}
|
||||
</span>
|
||||
<div className="text-right leading-tight">
|
||||
<div className="text-right.leading-tight">
|
||||
<p className="font-montserrat text-[10px] text-black">
|
||||
{req.date}
|
||||
</p>
|
||||
@@ -227,6 +240,17 @@ const HistoryRequestPage = () => {
|
||||
{req.title}
|
||||
</p>
|
||||
|
||||
{req.requesterName && (
|
||||
<p className="font-montserrat text-[11px] text-black/80">
|
||||
{req.requesterName}
|
||||
</p>
|
||||
)}
|
||||
{req.address && (
|
||||
<p className="font-montserrat text-[10px] text-black/70">
|
||||
{req.address}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="mt-2 w-full bg-[#94E067] rounded-lg py-3 flex items-center justify-center">
|
||||
<span className="font-montserrat font-bold text-[15px] leading-[18px] text-white">
|
||||
Развернуть
|
||||
|
||||
Reference in New Issue
Block a user