Files
frontend/app/mainValounter/page.jsx
2025-12-13 17:58:31 +05:00

203 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useEffect, useState } from "react";
import dynamic from "next/dynamic";
import { FaUser, FaCog } from "react-icons/fa";
import TabBar from "../components/TabBar";
import AcceptPopup from "../components/acceptPopUp";
// динамический импорт карты, чтобы не падало на сервере
const MapContainer = dynamic(
() => import("react-leaflet").then((m) => m.MapContainer),
{ ssr: false }
);
const TileLayer = dynamic(
() => import("react-leaflet").then((m) => m.TileLayer),
{ ssr: false }
);
const Marker = dynamic(
() => import("react-leaflet").then((m) => m.Marker),
{ ssr: false }
);
const Popup = dynamic(
() => import("react-leaflet").then((m) => m.Popup),
{ ssr: false }
);
// центр Перми
const DEFAULT_POSITION = [58.0105, 56.2294];
const requests = [
{
id: 1,
title: "Приобрести продукты пенсионерке",
address: "г. Пермь, ул. Ленина 50, кв. 24, этаж 3",
coords: [58.0109, 56.2478], // район ул. Ленина
distance: "1.2 км",
},
{
id: 2,
title: "Приобрести медикаменты бабушке",
address: "г. Пермь, ул. Пушкина 24, кв. 12, этаж 1",
coords: [58.0135, 56.2320], // район ул. Пушкина
distance: "2.0 км",
},
{
id: 3,
title: "Сопроводить до поликлиники",
address: "г. Пермь, ул. Куйбышева 95, кв. 7, этаж 2",
coords: [58.0068, 56.2265], // район ул. Куйбышева
distance: "3.4 км",
},
{
id: 4,
title: "Сопроводить до поликлиники",
address: "г. Пермь, ул. Куйбышева 95, кв. 7, этаж 2",
coords: [58.0068, 56.2265], // район ул. Куйбышева
distance: "3.4 км",
},
{
id: 5,
title: "Сопроводить до поликлиники",
address: "г. Пермь, ул. Куйбышева 95, кв. 7, этаж 2",
coords: [58.0068, 56.2265], // район ул. Куйбышева
distance: "3.4 км",
},
];
const MainVolunteerPage = () => {
const [position, setPosition] = useState(DEFAULT_POSITION);
const [hasLocation, setHasLocation] = useState(false);
const [selectedRequest, setSelectedRequest] = useState(null);
const [isPopupOpen, setIsPopupOpen] = useState(false);
const openPopup = (req) => {
setSelectedRequest(req);
setIsPopupOpen(true);
};
const closePopup = () => {
setIsPopupOpen(false);
setSelectedRequest(null);
};
useEffect(() => {
if (!navigator.geolocation) return;
navigator.geolocation.getCurrentPosition(
(pos) => {
setPosition([pos.coords.latitude, pos.coords.longitude]);
setHasLocation(true);
},
() => {
setHasLocation(false);
}
);
}, []);
const handleAccept = (req) => {
console.log("Откликнуться на заявку:", req.id);
// TODO: запрос на бэк
};
return (
<div className="min-h-screen w-full bg-[#90D2F9] flex justify-center px-4">
<div className="relative w-full max-w-md flex flex-col pb-20 pt-4">
{/* Header */}
<header className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<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-[11px] leading-[11px] text-white">
Александр
</p>
</div>
<button
type="button"
className="w-8 h-8 rounded-full border border-white flex items-center justify-center"
>
<FaCog className="text-white text-sm" />
</button>
</header>
<h1 className="font-montserrat font-extrabold text-[16px] leading-[20px] text-white mb-2">
Кому нужна помощь
</h1>
{/* Карта */}
<div className="w-full bg-transparent mb-3">
<div className="w-full h-[250px] bg-[#D9D9D9] rounded-2xl overflow-hidden">
<MapContainer
center={position}
zoom={13}
style={{ width: "100%", height: "100%" }}
>
<TileLayer
attribution='&copy; OpenStreetMap contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{/* Маркер волонтёра */}
{hasLocation && (
<Marker position={position}>
<Popup>Вы здесь</Popup>
</Marker>
)}
{/* Маркеры заявок */}
{requests.map((req) => (
<Marker key={req.id} position={req.coords}>
<Popup>{req.title}</Popup>
</Marker>
))}
</MapContainer>
</div>
</div>
{/* Заявки ниже карты */}
<main className="space-y-3">
{requests.map((req) => (
<div
key={req.id}
className="bg-white rounded-xl px-3 py-2 flex flex-col gap-1"
onClick={() => openPopup(req)}
>
<p className="font-montserrat font-semibold text-[12px] leading-[14px] text-black">
{req.title}
</p>
<p className="font-montserrat text-[10px] text-black">
{req.address}
</p>
{req.distance && (
<p className="font-montserrat text-[9px] text-gray-500">
Расстояние: {req.distance}
</p>
)}
<button
type="button"
onClick={() => handleAccept(req)}
className="mt-2 w-full bg-[#94E067] rounded-lg py-2 flex items-center justify-center"
>
<span className="font-montserrat font-bold text-[14px] text-white">
Откликнуться
</span>
</button>
</div>
))}
</main>
<TabBar />
</div>
<AcceptPopup
request={selectedRequest}
isOpen={isPopupOpen}
onClose={closePopup}
onAccept={handleAccept}
/>
</div>
);
};
export default MainVolunteerPage;