added edit card and get number
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import {useState, useEffect, useCallback} from "react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import "../styles/feed.css";
|
||||
import {API_URL} from "../config/constants";
|
||||
import { API_URL } from "../config/constants";
|
||||
import Sidebar from "../components/Sidebar";
|
||||
import RightSidebar from "../components/RightSidebar";
|
||||
import AdCard from "../components/AdCard";
|
||||
import PostModal from "../components/PostModal";
|
||||
import MenuIcon from "../components/icons/MenuIcon"
|
||||
import MenuIcon from "../components/icons/MenuIcon";
|
||||
|
||||
export default function FeedPage() {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [activeNav, setActiveNav] = useState("Главная");
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [editAd, setEditAd] = useState(null);
|
||||
const [ads, setAds] = useState([]);
|
||||
const [liked, setLiked] = useState(new Set());
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -22,11 +23,8 @@ export default function FeedPage() {
|
||||
setError("");
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/api/v1/posts`);
|
||||
if (!res.ok) {
|
||||
throw new Error(`Ошибка ${res.status}`);
|
||||
}
|
||||
if (!res.ok) throw new Error(`Ошибка ${res.status}`);
|
||||
const data = await res.json();
|
||||
// поддерживаем { items: [] } и просто []
|
||||
setAds(Array.isArray(data) ? data : (data.items ?? []));
|
||||
} catch (err) {
|
||||
setError(err.message || "Не удалось загрузить объявления");
|
||||
@@ -45,17 +43,20 @@ export default function FeedPage() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Новое объявление — добавляем в начало ленты
|
||||
const handleNewAd = useCallback((ad) => {
|
||||
setAds(prev => [ad, ...prev]);
|
||||
}, []);
|
||||
|
||||
const handleEditSave = useCallback((updated) => {
|
||||
setAds(prev => prev.map(a => a.id === updated.id ? updated : a));
|
||||
}, []);
|
||||
|
||||
const renderContent = () => {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="f-center">
|
||||
<div className="f-spinner-wrap">
|
||||
<div className="f-spinner"/>
|
||||
<div className="f-spinner" />
|
||||
Загружаем объявления...
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,64 +77,67 @@ export default function FeedPage() {
|
||||
<div className="f-center-icon">🔍</div>
|
||||
<div className="f-center-title">Объявлений пока нет</div>
|
||||
<div className="f-center-sub">
|
||||
Будьте первым — разместите объявление<br/>о потере или находке
|
||||
Будьте первым — разместите объявление<br />о потере или находке
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return ads.map(ad => (
|
||||
<AdCard key={ad.id} ad={ad} liked={liked.has(ad.id)}
|
||||
onLike={toggleLike}/>
|
||||
<AdCard
|
||||
key={ad.id}
|
||||
ad={ad}
|
||||
liked={liked.has(ad.id)}
|
||||
onLike={toggleLike}
|
||||
onEdit={setEditAd}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="f-app">
|
||||
<div className="f-app">
|
||||
<Sidebar
|
||||
open={sidebarOpen}
|
||||
activeNav={activeNav}
|
||||
onClose={() => setSidebarOpen(false)}
|
||||
onNavClick={setActiveNav}
|
||||
/>
|
||||
|
||||
<Sidebar
|
||||
open={sidebarOpen}
|
||||
activeNav={activeNav}
|
||||
onClose={() => setSidebarOpen(false)}
|
||||
onNavClick={setActiveNav}
|
||||
/>
|
||||
|
||||
<div className="f-main">
|
||||
<div className="f-topbar">
|
||||
<button className="f-menu-btn"
|
||||
onClick={() => setSidebarOpen(v => !v)}>
|
||||
<MenuIcon/>
|
||||
<div className="f-main">
|
||||
<div className="f-topbar">
|
||||
<button className="f-menu-btn" onClick={() => setSidebarOpen(v => !v)}>
|
||||
<MenuIcon />
|
||||
</button>
|
||||
<div className="f-topbar-center">
|
||||
<button className="f-post-btn" onClick={() => setModalOpen(true)}>
|
||||
<span style={{ fontSize: "1.15rem", fontWeight: 900, lineHeight: 1 }}>+</span>
|
||||
Разместить объявление
|
||||
</button>
|
||||
<div className="f-topbar-center">
|
||||
<button className="f-post-btn"
|
||||
onClick={() => setModalOpen(true)}>
|
||||
<span style={{
|
||||
fontSize: "1.15rem",
|
||||
fontWeight: 900,
|
||||
lineHeight: 1
|
||||
}}>+</span>
|
||||
Разместить объявление
|
||||
</button>
|
||||
</div>
|
||||
<div className="f-topbar-spacer"/>
|
||||
</div>
|
||||
|
||||
<div className="f-wrap">
|
||||
<div className="f-feed">
|
||||
{renderContent()}
|
||||
</div>
|
||||
<RightSidebar/>
|
||||
</div>
|
||||
<div className="f-topbar-spacer" />
|
||||
</div>
|
||||
|
||||
{modalOpen && (
|
||||
<PostModal
|
||||
onClose={() => setModalOpen(false)}
|
||||
onSuccess={handleNewAd}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="f-wrap">
|
||||
<div className="f-feed">
|
||||
{renderContent()}
|
||||
</div>
|
||||
<RightSidebar />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
{modalOpen && (
|
||||
<PostModal
|
||||
onClose={() => setModalOpen(false)}
|
||||
onSuccess={handleNewAd}
|
||||
/>
|
||||
)}
|
||||
|
||||
{editAd && (
|
||||
<PostModal
|
||||
initialData={editAd}
|
||||
onClose={() => setEditAd(null)}
|
||||
onSuccess={handleEditSave}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user