added delete posts
This commit is contained in:
@@ -11,6 +11,7 @@ import { ProfileModal } from "./profile";
|
|||||||
import AuthModal from "./AuthModal";
|
import AuthModal from "./AuthModal";
|
||||||
import RulesModal from "./RulesModal";
|
import RulesModal from "./RulesModal";
|
||||||
import { useAuthContext } from "../context/AuthContext";
|
import { useAuthContext } from "../context/AuthContext";
|
||||||
|
import { useDeletePost } from "../hooks/useDeletePost";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MainFeed — корневой компонент приложения.
|
* MainFeed — корневой компонент приложения.
|
||||||
@@ -20,6 +21,7 @@ import { useAuthContext } from "../context/AuthContext";
|
|||||||
export default function MainFeed() {
|
export default function MainFeed() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { user, token, isAuthenticated, logout } = useAuthContext();
|
const { user, token, isAuthenticated, logout } = useAuthContext();
|
||||||
|
const { deletePost } = useDeletePost();
|
||||||
|
|
||||||
// Открыт ли левый сайдбар (мобильный слайд-аут)
|
// Открыт ли левый сайдбар (мобильный слайд-аут)
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
@@ -139,6 +141,18 @@ export default function MainFeed() {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
/** Удаляет объявление и перезагружает ленту */
|
||||||
|
const handleDelete = useCallback(async (postId) => {
|
||||||
|
if (!window.confirm("Вы уверены, что хотите удалить это объявление?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const success = await deletePost(postId);
|
||||||
|
if (success) {
|
||||||
|
loadFeed();
|
||||||
|
loadMyPosts();
|
||||||
|
}
|
||||||
|
}, [deletePost, loadFeed, loadMyPosts]);
|
||||||
|
|
||||||
// После создания или редактирования объявления перезагружаем ленту,
|
// После создания или редактирования объявления перезагружаем ленту,
|
||||||
// чтобы получить актуальные данные (включая изображения) из БД
|
// чтобы получить актуальные данные (включая изображения) из БД
|
||||||
const handleNewAd = useCallback(() => { loadFeed(); loadMyPosts(); }, [loadFeed, loadMyPosts]);
|
const handleNewAd = useCallback(() => { loadFeed(); loadMyPosts(); }, [loadFeed, loadMyPosts]);
|
||||||
@@ -249,6 +263,7 @@ export default function MainFeed() {
|
|||||||
liked={liked.has(ad.id)}
|
liked={liked.has(ad.id)}
|
||||||
onLike={toggleLike}
|
onLike={toggleLike}
|
||||||
onEdit={activeNav === "Мои объявления" ? handleEdit : undefined}
|
onEdit={activeNav === "Мои объявления" ? handleEdit : undefined}
|
||||||
|
onDelete={activeNav === "Мои объявления" ? handleDelete : undefined}
|
||||||
isOwner={activeNav === "Мои объявления"}
|
isOwner={activeNav === "Мои объявления"}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import CalendarIcon from "./icons/CalendarIcon";
|
|||||||
import PhoneIcon from "./icons/PhoneIcon";
|
import PhoneIcon from "./icons/PhoneIcon";
|
||||||
import MapIcon from "./icons/MapIcon";
|
import MapIcon from "./icons/MapIcon";
|
||||||
import HeartIcon from "./icons/HeartIcon";
|
import HeartIcon from "./icons/HeartIcon";
|
||||||
|
import TrashIcon from "./icons/TrashIcon";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useChats } from "../hooks/useChats";
|
import { useChats } from "../hooks/useChats";
|
||||||
import { useAuthContext } from "../context/AuthContext";
|
import { useAuthContext } from "../context/AuthContext";
|
||||||
import { API_URL } from "../config/authConstants";
|
import { API_URL } from "../config/authConstants";
|
||||||
|
|
||||||
export default function PostOnFeed({ ad, liked, onLike, onEdit, isOwner }) {
|
export default function PostOnFeed({ ad, liked, onLike, onEdit, onDelete, isOwner }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { createOrGetChat } = useChats();
|
const { createOrGetChat } = useChats();
|
||||||
const { isAuthenticated } = useAuthContext();
|
const { isAuthenticated } = useAuthContext();
|
||||||
@@ -75,11 +76,17 @@ export default function PostOnFeed({ ad, liked, onLike, onEdit, isOwner }) {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{onEdit && isOwner && (
|
{onEdit && isOwner && (
|
||||||
<button className="f-like-btn"
|
<button className="f-card-edit-btn"
|
||||||
onClick={e => { e.stopPropagation(); onEdit(ad); }}>
|
onClick={e => { e.stopPropagation(); onEdit(ad); }}>
|
||||||
✏️
|
✏️
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
{onDelete && isOwner && (
|
||||||
|
<button className="f-card-delete-btn"
|
||||||
|
onClick={e => { e.stopPropagation(); onDelete(ad.id); }}>
|
||||||
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
<button className={`f-like-btn${liked ? " liked" : ""}`}
|
<button className={`f-like-btn${liked ? " liked" : ""}`}
|
||||||
onClick={e => { e.stopPropagation(); onLike(ad.id); }}>
|
onClick={e => { e.stopPropagation(); onLike(ad.id); }}>
|
||||||
<HeartIcon filled={liked} />
|
<HeartIcon filled={liked} />
|
||||||
|
|||||||
@@ -93,6 +93,22 @@
|
|||||||
border-color: rgba(255,107,107,.5); color: #ff6b6b; background: rgba(255,107,107,.08);
|
border-color: rgba(255,107,107,.5); color: #ff6b6b; background: rgba(255,107,107,.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Edit & Delete buttons */
|
||||||
|
.f-card-edit-btn,
|
||||||
|
.f-card-delete-btn {
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
background: none; border: 1px solid var(--border);
|
||||||
|
border-radius: 8px; width: 32px; height: 32px;
|
||||||
|
cursor: pointer; transition: all .2s;
|
||||||
|
color: var(--muted); padding: 0;
|
||||||
|
}
|
||||||
|
.f-card-edit-btn:hover {
|
||||||
|
border-color: rgba(45,224,200,.5); color: #2de0c8; background: rgba(45,224,200,.08);
|
||||||
|
}
|
||||||
|
.f-card-delete-btn:hover {
|
||||||
|
border-color: rgba(255,107,107,.5); color: #ff6b6b; background: rgba(255,107,107,.08);
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
/* Карточка становится вертикальной */
|
/* Карточка становится вертикальной */
|
||||||
.f-card-inner {
|
.f-card-inner {
|
||||||
|
|||||||
Reference in New Issue
Block a user