131 lines
5.4 KiB
JavaScript
131 lines
5.4 KiB
JavaScript
import PinIcon from "./icons/PinIcon";
|
||
import CalendarIcon from "./icons/CalendarIcon";
|
||
import PhoneIcon from "./icons/PhoneIcon";
|
||
import MapIcon from "./icons/MapIcon";
|
||
import HeartIcon from "./icons/HeartIcon";
|
||
import TrashIcon from "./icons/TrashIcon";
|
||
import { useNavigate } from "react-router-dom";
|
||
import { useChats } from "../hooks/useChats";
|
||
import { useAuthContext } from "../context/AuthContext";
|
||
import { API_URL } from "../config/authConstants";
|
||
|
||
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMarkFound, isOwner }) {
|
||
const navigate = useNavigate();
|
||
const { createOrGetChat } = useChats();
|
||
const { isAuthenticated } = useAuthContext();
|
||
|
||
const handleContact = async (e) => {
|
||
e.stopPropagation();
|
||
try {
|
||
const chat = await createOrGetChat(ad.userId, ad.id);
|
||
navigate(`/chats/${chat.id}`);
|
||
} catch (err) {
|
||
console.error(err);
|
||
}
|
||
};
|
||
const imageUrl = ad.images?.[0] ? `${API_URL}${ad.images[0]}` : null;
|
||
|
||
// ✅ Формируем строку адреса из city + district
|
||
const address = [ad.city, ad.district].filter(Boolean).join(", ");
|
||
const createdAt = ad.createdAt
|
||
? new Date(ad.createdAt).toLocaleDateString("ru-RU")
|
||
: null;
|
||
|
||
// Проверяем, закрыт ли пост (вещь найдена)
|
||
const isClosed = ad.status === 'CLOSED';
|
||
|
||
const roleClass = ad.userRole === 'LOST_AND_FOUND' ? 'f-card-role-lost-found'
|
||
: ad.userRole === 'METRO' ? 'f-card-role-metro' : '';
|
||
|
||
const roleBadge = ad.userRole === 'LOST_AND_FOUND' ? (
|
||
<div className="f-role-badge f-role-lost-found" title="Бюро находок">
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||
<circle cx="12" cy="12" r="10"/>
|
||
<path d="M12 6v6l4 2"/>
|
||
</svg>
|
||
Бюро находок
|
||
</div>
|
||
) : ad.userRole === 'METRO' ? (
|
||
<div className="f-role-badge f-role-metro" title="Метрополитен">
|
||
<span className="f-role-metro-letter">М</span>
|
||
Метрополитен
|
||
</div>
|
||
) : null;
|
||
|
||
return (
|
||
<div className={`f-card${isClosed ? ' f-card-closed' : ''}${roleClass ? ' ' + roleClass : ''}`}>
|
||
<div className="f-card-inner">
|
||
<div className="f-card-img">
|
||
{imageUrl
|
||
? <img src={imageUrl} alt={ad.title} />
|
||
: <span className="f-card-emoji">{ad.emoji || "📋"}</span>
|
||
}
|
||
</div>
|
||
<div className="f-card-body">
|
||
<div className="f-card-badges">
|
||
{ad.category && <div className="f-cat-badge">{ad.category}</div>}
|
||
<div className={`f-type-badge ${ad.type === "loss" ? "f-type-loss" : "f-type-found"}`}>
|
||
{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-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>}
|
||
</div>
|
||
{address && (
|
||
<button className="f-card-map" onClick={e => e.stopPropagation()}>
|
||
<MapIcon /> Показать на карте — {address}
|
||
</button>
|
||
)}
|
||
<div className="f-card-foot">
|
||
<div className="f-card-foot-left">
|
||
{ad.phone && (
|
||
<a className="f-card-phone" href={`tel:${ad.phone}`}
|
||
onClick={e => e.stopPropagation()}>
|
||
<PhoneIcon /> {ad.phone}
|
||
</a>
|
||
)}
|
||
</div>
|
||
<div className="f-card-foot-right">
|
||
{isAuthenticated && !isOwner && !isClosed && (
|
||
<button className="f-card-contact" onClick={handleContact}>
|
||
Написать
|
||
</button>
|
||
)}
|
||
{onEdit && isOwner && !isClosed && (
|
||
<button className="f-card-edit-btn"
|
||
onClick={e => { e.stopPropagation(); onEdit(ad); }}>
|
||
✏️
|
||
</button>
|
||
)}
|
||
{onDelete && isOwner && (
|
||
<button className="f-card-delete-btn"
|
||
onClick={e => { e.stopPropagation(); onDelete(ad.id); }}>
|
||
<TrashIcon />
|
||
</button>
|
||
)}
|
||
{onMarkFound && isOwner && !isClosed && (
|
||
<button className="f-card-found-btn"
|
||
onClick={e => { e.stopPropagation(); onMarkFound(ad.id); }}>
|
||
✓ Вещь найдена
|
||
</button>
|
||
)}
|
||
<button className={`f-like-btn${liked ? " liked" : ""}`}
|
||
onClick={e => { e.stopPropagation(); onLike(ad.id); }}>
|
||
<HeartIcon filled={liked} />
|
||
{ad.likeCount || 0}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|