VolonteurMainPage

This commit is contained in:
fullofempt
2025-12-13 17:58:31 +05:00
parent 55c42a115d
commit 48d4db0e77
9 changed files with 609 additions and 7 deletions

202
app/mainValounter/page.jsx Normal file
View File

@@ -0,0 +1,202 @@
"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;