This commit is contained in:
fullofempt
2025-12-15 13:18:18 +05:00
parent b5575b8e47
commit e4bfbd30cc
9 changed files with 738 additions and 747 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -17,19 +17,19 @@ const TabBar = () => {
requester: [
{ key: "home", icon: FaHome, href: "/createRequest" },
{ key: "history", icon: FaClock, href: "/historyRequest" },
{ key: "news", icon: FaNewspaper, href: "/news" },
{ key: "news", icon: FaNewspaper, href: "/notification" },
{ key: "profile", icon: FaCog, href: "/ProfilePage" },
],
volunteer: [
{ key: "home", icon: FaHome, href: "/mainValounter" },
{ key: "history", icon: FaClock, href: "/valounterHistoryRequest" },
{ key: "news", icon: FaNewspaper, href: "/volunteer/news" },
{ key: "news", icon: FaNewspaper, href: "/notification" },
{ key: "profile", icon: FaCog, href: "/valounterProfilePage" },
],
moderator: [
{ key: "queue", icon: FaHome, href: "/moderatorMain" },
{ key: "history", icon: FaClock, href: "/moderatorHistoryRequest" },
{ key: "news", icon: FaNewspaper, href: "/moderator/news" },
{ key: "news", icon: FaNewspaper, href: "/notification" },
{ key: "profile", icon: FaCog, href: "/moderatorProfilePage" },
],
};

View File

@@ -4,16 +4,30 @@ import React, { useEffect, useState } from "react";
const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL;
// Статус ИМЕННО ОТКЛИКА волонтёра (ResponseStatus)
const responseStatusMap = {
pending: { label: "Ожидает ответа", color: "#E9D171" },
accepted: { label: "Принят", color: "#94E067" },
rejected: { label: "Отклонён", color: "#FF8282" },
cancelled: { label: "Отменён", color: "#FF8282" },
};
const VolunteerRequestDetailsModal = ({ request, onClose }) => {
const [details, setDetails] = useState(null);
const [loading, setLoading] = useState(true);
const [loadError, setLoadError] = useState("");
const normalizedStatus = String(request.rawStatus || request.status || "").toLowerCase();
const isAccepted = normalizedStatus === "accepted";
const isInProgress =
normalizedStatus === "in_progress" || normalizedStatus === "inprogress" || isAccepted;
const isDone = normalizedStatus === "completed";
// статус отклика (из списка /responses/my)
const responseRawStatus = String(
request.rawStatus || request.status || ""
).toLowerCase();
const responseStatus =
responseStatusMap[responseRawStatus] ||
{ label: "Неизвестен", color: "#E2E2E2" };
const isAccepted = responseRawStatus === "accepted";
const isDone = false; // для волонтёра нет completed в ResponseStatus
const isInProgress = isAccepted; // принятый отклик ~ «в процессе»
const getAccessToken = () => {
if (typeof window === "undefined") return null;
@@ -38,7 +52,7 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
try {
const res = await fetch(
`${API_BASE}/requests/${request.request_id || request.id}`,
`${API_BASE}/requests/${request.requestId || request.request_id || request.id}`,
{
headers: {
Accept: "application/json",
@@ -78,7 +92,7 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
};
fetchDetails();
}, [request.request_id, request.id]);
}, [request.requestId, request.request_id, request.id]);
if (loading) {
return (
@@ -105,7 +119,9 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
);
}
// Тип заявки из RequestDetail
const requestTypeName = details.request_type?.name || "Не указан";
const urgencyText = (() => {
switch (details.urgency) {
case "low":
@@ -122,6 +138,7 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
})();
const place = [details.address, details.city].filter(Boolean).join(", ");
const requesterName =
(details.requester &&
[details.requester.first_name, details.requester.last_name]
@@ -152,26 +169,6 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
}
}
const statusColorMap = {
pending_moderation: "#E9D171",
approved: "#94E067",
in_progress: "#E971E1",
completed: "#71A5E9",
cancelled: "#FF8282",
rejected: "#FF8282",
};
const statusLabelMap = {
pending_moderation: "На модерации",
approved: "Принята",
in_progress: "В процессе",
completed: "Выполнена",
cancelled: "Отменена",
rejected: "Отклонена",
};
const rawReqStatus = String(details.status || "").toLowerCase();
const badgeColor = statusColorMap[rawReqStatus] || "#E2E2E2";
const statusLabel = statusLabelMap[rawReqStatus] || "Неизвестен";
return (
<div className="fixed inset-0 z-40 flex flex-col bg-[#90D2F9] px-4 pt-4 pb-20">
{/* Хедер */}
@@ -192,13 +189,13 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
{/* Карточка */}
<div className="flex-1 flex items-start justify-center">
<div className="w-full max-w-[360px] bg-white rounded-2xl p-4 flex flex-col gap-4 shadow-lg">
{/* Статус + дата/время */}
{/* Статус ОТКЛИКА + дата/время */}
<div className="flex items-start justify-between">
<span
className="inline-flex items-center justify-center px-3 py-1 rounded-full font-montserrat text-[10px] font-semibold text-white"
style={{ backgroundColor: badgeColor }}
style={{ backgroundColor: responseStatus.color }}
>
{statusLabel}
{responseStatus.label}
</span>
<div className="text-right leading-tight">
<p className="font-montserrat text-[10px] text-black">
@@ -237,10 +234,7 @@ const VolunteerRequestDetailsModal = ({ request, onClose }) => {
</div>
)}
{/* Доп. блоки для волонтёра по желанию:
- данные назначенного волонтёра details.assigned_volunteer
- статус отклика request.rawStatus / request.status
*/}
{/* Блок для принятых откликов */}
{(isAccepted || isInProgress || isDone) && details.assigned_volunteer && (
<div className="bg-[#F3F8FF] rounded-2xl px-3 py-2">
<p className="font-montserrat text-[11px] font-semibold text-black mb-1">