WIPVOLONT
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { FaTimesCircle } from "react-icons/fa";
|
||||
|
||||
const AcceptPopup = ({ request, isOpen, onClose, onAccept, loading, error }) => {
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL;
|
||||
|
||||
const AcceptPopup = ({ request, isOpen, onClose }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
if (!isOpen || !request) return null;
|
||||
|
||||
const title = request.title;
|
||||
@@ -15,14 +20,21 @@ const AcceptPopup = ({ request, isOpen, onClose, onAccept, loading, error }) =>
|
||||
const city = request.city ? `, ${request.city}` : "";
|
||||
const place = `${baseAddress}${city}`;
|
||||
|
||||
const deadline = request.desired_completion_date
|
||||
? new Date(request.desired_completion_date).toLocaleString("ru-RU", {
|
||||
let deadline = "Не указано";
|
||||
if (request.desired_completion_date) {
|
||||
const d = new Date(request.desired_completion_date);
|
||||
if (!Number.isNaN(d.getTime())) {
|
||||
const datePart = d.toLocaleDateString("ru-RU", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
});
|
||||
const timePart = d.toLocaleTimeString("ru-RU", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})
|
||||
: "Не указано";
|
||||
});
|
||||
deadline = `${datePart}, ${timePart}`;
|
||||
}
|
||||
}
|
||||
|
||||
const phone = request.contact_phone || request.phone;
|
||||
const contactNotes = request.contact_notes || request.contactNotes;
|
||||
@@ -42,26 +54,79 @@ const AcceptPopup = ({ request, isOpen, onClose, onAccept, loading, error }) =>
|
||||
}
|
||||
})();
|
||||
|
||||
const handleClick = () => {
|
||||
// здесь видно, с каким id ты стучишься в /requests/{id}/responses
|
||||
console.log("Отклик на заявку из попапа:", {
|
||||
id: request.id,
|
||||
title: request.title,
|
||||
raw: request,
|
||||
});
|
||||
onAccept(request);
|
||||
const getAccessToken = () => {
|
||||
if (typeof window === "undefined") return null;
|
||||
const saved = localStorage.getItem("authUser");
|
||||
const authUser = saved ? JSON.parse(saved) : null;
|
||||
return authUser?.accessToken || null;
|
||||
};
|
||||
|
||||
// тут полностью логика отклика
|
||||
const handleClick = async () => {
|
||||
if (!API_BASE || !request.id) {
|
||||
setError("Некорректная заявка (нет id)");
|
||||
return;
|
||||
}
|
||||
const accessToken = getAccessToken();
|
||||
if (!accessToken) {
|
||||
setError("Вы не авторизованы");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
|
||||
console.log("POST отклик", {
|
||||
url: `${API_BASE}/requests/${request.id}/responses`,
|
||||
requestId: request.id,
|
||||
});
|
||||
|
||||
const res = await fetch(`${API_BASE}/requests/${request.id}/responses`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
// по схеме тело обязательно, просто пустой объект допустим [file:598]
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
console.error("Ответ API /responses:", msg);
|
||||
setError(msg);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await res.json(); // VolunteerResponse [file:598]
|
||||
setLoading(false);
|
||||
onClose();
|
||||
} catch (e) {
|
||||
setError(e.message || "Ошибка сети");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
{/* затемнение */}
|
||||
<div
|
||||
className="absolute inset-0 bg-black/40"
|
||||
onClick={onClose}
|
||||
/>
|
||||
|
||||
{/* карточка на всю страницу */}
|
||||
<div className="relative z-10 w-full h-250px bg-white rounded-2xl px-4 pt-4 pb-6 flex flex-col">
|
||||
{/* карточка поверх всего */}
|
||||
<div className="relative z-50 w-full max-w-[400px] bg-white rounded-2xl px-4 pt-4 pb-6 flex flex-col mt-50">
|
||||
{/* крестик */}
|
||||
<button
|
||||
type="button"
|
||||
@@ -80,9 +145,9 @@ const AcceptPopup = ({ request, isOpen, onClose, onAccept, loading, error }) =>
|
||||
</p>
|
||||
|
||||
{/* Только время выполнить до */}
|
||||
<div className="flex.items-center gap-3 mb-3">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="w-full h-[40px] bg-[#90D2F9] rounded-full flex flex-col items-center justify-center">
|
||||
<span className="text-[12px] leading-[11px] text-white font-semibold.mb-2">
|
||||
<span className="text-[12px] leading-[11px] text-white font-semibold mb-1">
|
||||
Выполнить до
|
||||
</span>
|
||||
<span className="text-[15px] leading-[13px] text-white font-semibold">
|
||||
|
||||
Reference in New Issue
Block a user