added calendar on press create date

This commit is contained in:
SlimusMinus
2026-07-06 01:17:40 +03:00
parent f94a80fa59
commit aa82b054a5
5 changed files with 140 additions and 15 deletions

View File

@@ -0,0 +1,50 @@
import { useState, useEffect, useRef } from "react";
const MONTHS = ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"];
const DAYS = ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"];
export default function DateCalendarPopup({ date, onClose }) {
const ref = useRef(null);
const d = new Date(date);
const [year, setYear] = useState(d.getFullYear());
const [month, setMonth] = useState(d.getMonth());
useEffect(() => {
const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
document.addEventListener("mousedown", handler);
return () => document.removeEventListener("mousedown", handler);
}, [onClose]);
const firstDay = new Date(year, month, 1).getDay();
const offset = firstDay === 0 ? 6 : firstDay - 1;
const daysInMonth = new Date(year, month + 1, 0).getDate();
const cells = [];
for (let i = 0; i < offset; i++) cells.push(null);
for (let i = 1; i <= daysInMonth; i++) cells.push(i);
const isSameDay = (day) =>
d.getFullYear() === year && d.getMonth() === month && d.getDate() === day;
return (
<div className="f-date-calendar" ref={ref}>
<div className="f-cal-header">
<button onClick={() => setMonth(m => m === 0 ? (setYear(y => y - 1), 11) : m - 1)}>‹</button>
<span>{MONTHS[month]} {year}</span>
<button onClick={() => setMonth(m => m === 11 ? (setYear(y => y + 1), 0) : m + 1)}>›</button>
</div>
<div className="f-cal-grid">
{DAYS.map(d => <div key={d} className="f-cal-day-name">{d}</div>)}
{cells.map((day, i) =>
day ? (
<div key={i}
className={`f-cal-day${isSameDay(day) ? " f-cal-selected" : ""}`}
>
{day}
</div>
) : <div key={i} />
)}
</div>
</div>
);
}

View File

@@ -441,13 +441,6 @@ export default function MainFeed() {
{/* Фильтр по типу объявления */}
<div className="f-filter-bar">
<button
className={`f-filter-btn${typeFilter === null ? " active"
: ""}`}
onClick={() => setTypeFilter(null)}
>
Все объявления
</button>
<button
className={`f-filter-btn${typeFilter === "loss" ? " active"
: ""}`}
@@ -455,6 +448,13 @@ export default function MainFeed() {
>
🔴 Потери
</button>
<button
className={`f-filter-btn${typeFilter === null ? " active"
: ""}`}
onClick={() => setTypeFilter(null)}
>
Все объявления
</button>
<button
className={`f-filter-btn${typeFilter === "found" ? " active"
: ""}`}

View File

@@ -4,12 +4,15 @@ import PhoneIcon from "./icons/PhoneIcon";
import MapIcon from "./icons/MapIcon";
import HeartIcon from "./icons/HeartIcon";
import TrashIcon from "./icons/TrashIcon";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useChats } from "../hooks/useChats";
import { useAuthContext } from "../context/AuthContext";
import { API_URL } from "../config/authConstants";
import DateCalendarPopup from "./DateCalendarPopup";
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMarkFound, isOwner, onImageClick, onAuthRequired }) {
const [showCalendar, setShowCalendar] = useState(false);
const navigate = useNavigate();
const { createOrGetChat } = useChats();
const { isAuthenticated } = useAuthContext();
@@ -76,15 +79,21 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMark
{ad.type === "loss" ? "Потеря" : "Находка"}
</div>
{roleBadge}
{isClosed && <div className="f-status-badge f-status-closed">✓ Найдено</div>}
</div>
<div className="f-card-title">{ad.title}</div>
<div className="f-card-title">
{ad.title}
{isClosed && <span className="f-status-badge f-status-closed">✓ Найдено</span>}
</div>
<div className="f-card-desc">{ad.description}</div>
<div className="f-card-meta">
{/* ✅ address вместо ad.location */}
{address && <div className="f-meta-pill"><PinIcon /> {address}</div>}
{/* ✅ createdAt вместо ad.date */}
{createdAt && <div className="f-meta-pill"><CalendarIcon /> {createdAt}</div>}
{createdAt && (
<div className="f-meta-pill f-date-pill" onClick={e => { e.stopPropagation(); setShowCalendar(s => !s); }}>
<CalendarIcon /> {createdAt}
{showCalendar && <DateCalendarPopup date={ad.createdAt} onClose={() => setShowCalendar(false)} />}
</div>
)}
</div>
{address && (
<button className="f-card-map" onClick={e => e.stopPropagation()}>

View File

@@ -1,10 +1,10 @@
// ─── CONSTANTS ────────────────────────────────────────────────────────────────
export const NAV_ITEMS = [
{ icon: "grid", label: "Главная" },
{ icon: "file", label: "Мои объявления" },
{ icon: "box", label: "Вещи" },
{ icon: "paw", label: "Питомцы" },
{ icon: "chat", label: "Чат" },
{ icon: "file", label: "Мои объявления" },
];
export const NAV_BOTTOM = [

View File

@@ -43,9 +43,10 @@
/* Status badge for closed/found posts */
.f-status-badge {
border-radius: 20px; padding: 3px 10px;
font-size: .72rem; font-weight: 900;
position: absolute; left: 50%; transform: translateX(-50%);
border-radius: 20px; padding: 2px 8px;
font-size: .7rem; font-weight: 900;
display: inline-block; vertical-align: middle;
margin-left: 8px;
}
.f-status-closed {
background: rgba(72,187,120,.2); color: #48bb78; border: 1px solid rgba(72,187,120,.3);
@@ -109,6 +110,13 @@
background: var(--hover-bg); border: 1px solid var(--border);
border-radius: 20px; padding: 3px 9px; font-size: .73rem; color: var(--muted);
}
.f-date-pill {
cursor: pointer;
position: relative;
}
.f-date-pill:hover {
background: rgba(128,128,128,.12);
}
/* Map stub */
.f-card-map {
@@ -221,3 +229,61 @@
font-size: 0.72rem;
}
}
/* ── Calendar Popup ── */
.f-date-calendar {
position: absolute;
bottom: calc(100% + 6px);
left: 0;
z-index: 100;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 10px;
width: 220px;
box-shadow: 0 8px 32px rgba(0,0,0,.25);
}
.f-cal-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
font-size: .82rem;
font-weight: 700;
}
.f-cal-header button {
background: none;
border: none;
color: var(--text-primary);
font-size: 1.1rem;
cursor: pointer;
padding: 2px 6px;
border-radius: 6px;
line-height: 1;
}
.f-cal-header button:hover {
background: rgba(128,128,128,.15);
}
.f-cal-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 2px;
text-align: center;
font-size: .75rem;
}
.f-cal-day-name {
font-weight: 700;
color: var(--muted);
padding: 4px 0;
font-size: .68rem;
}
.f-cal-day {
padding: 4px 0;
border-radius: 6px;
cursor: default;
}
.f-cal-selected {
background: rgba(var(--teal-rgb), .25);
color: var(--teal);
font-weight: 800;
}