Files
nahodka-front/src/pages/PostOnFeed.jsx
SlimusMinus 7f59ee1f38 fixed code
2026-08-11 00:24:07 +03:00

146 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

// src/components/PostOnFeed.jsx
import PinIcon from "../components/icons/PinIcon";
import CalendarIcon from "../components/icons/CalendarIcon";
import PhoneIcon from "../components/icons/PhoneIcon";
import MapIcon from "../components/icons/MapIcon";
import HeartIcon from "../components/icons/HeartIcon";
import TrashIcon from "../components/icons/TrashIcon";
import { useState } from "react";
import { useContactSeller } from "../hooks/useContactSeller";
import { useAuthContext } from "../context/AuthContext";
import { getImageUrl } from "../config/authConstants";
import DateCalendarPopup from "../components/DateCalendarPopup";
import Toast from "../components/Toast";
import { useTranslation } from 'react-i18next';
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, onMarkFound, isOwner, onImageClick, onAuthRequired }) {
const { t } = useTranslation();
const [showCalendar, setShowCalendar] = useState(false);
const { isAuthenticated } = useAuthContext();
const { contactSeller, error: contactError, clearError } = useContactSeller(ad);
const handleContact = (e) => {
e.stopPropagation();
if (!isAuthenticated) {
if (onAuthRequired) onAuthRequired();
return;
}
contactSeller();
};
const imageUrl = getImageUrl(ad.images?.[0]);
const address = ad.city;
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={t('postCard.lostFoundBureau')}>
<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>
{t('postCard.lostFoundBureau')}
</div>
) : ad.userRole === 'METRO' ? (
<div className="f-role-badge f-role-metro" title={t('postCard.metro')}>
<span className="f-role-metro-letter">М</span>
{t('postCard.metro')}
</div>
) : null;
return (
<div className={`f-card${isClosed ? ' f-card-closed' : ''}${roleClass ? ' ' + roleClass : ''}`}>
<div className="f-card-inner">
<div className="f-card-img" onClick={e => { e.stopPropagation(); if (onImageClick) onImageClick(ad.images, 0, ad); }}>
{ad.reward && (
<div className="f-card-reward">
💰 {t("postCard.reward")}
</div>
)}
{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" ? t('postCard.loss') : t('postCard.found')}
</div>
{roleBadge}
</div>
<div className="f-card-title">
{ad.title}
{isClosed && <span className="f-status-badge f-status-closed">{t('postCard.foundStatus')}</span>}
</div>
<div className="f-card-desc">{ad.description}</div>
<div className="f-card-meta">
{address && <div className="f-meta-pill"><PinIcon /> {address}</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>
<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">
{!isOwner && !isClosed && (
<button type="button" className="f-card-contact" onClick={handleContact}>
{t('postCard.write')}
</button>
)}
{onEdit && isOwner && !isClosed && (
<button type="button" className="f-card-edit-btn"
onClick={e => { e.stopPropagation(); onEdit(ad); }}>
✏️
</button>
)}
{onDelete && isOwner && (
<button type="button" className="f-card-delete-btn"
onClick={e => { e.stopPropagation(); onDelete(ad.id); }}>
<TrashIcon />
</button>
)}
{onMarkFound && isOwner && !isClosed && (
<button type="button" className="f-card-found-btn"
onClick={e => { e.stopPropagation(); onMarkFound(ad.id); }}>
{t('postCard.itemFound')}
</button>
)}
<button type="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>
{contactError && (
<Toast
message={contactError}
type="error"
onDismiss={clearError}
/>
)}
</div>
);
}