Merge pull request #55 from SlimusMinus/fix-post_on_feed
added border on post on feed
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// src/App.jsx
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
|
||||
import { AuthProvider } from './context/AuthContext';
|
||||
import { ThemeProvider } from './context/ThemeContext';
|
||||
import { useAuthContext } from './context/AuthContext';
|
||||
@@ -13,6 +13,12 @@ import ChatListPage from './pages/ChatListPage';
|
||||
import ReviewsPage from './pages/ReviewsPage';
|
||||
import './styles/chat.css';
|
||||
|
||||
function ScrollToTop() {
|
||||
const { pathname } = useLocation();
|
||||
useEffect(() => { window.scrollTo(0, 0); }, [pathname]);
|
||||
return null;
|
||||
}
|
||||
|
||||
function UnreadListener() {
|
||||
const { user } = useAuthContext();
|
||||
const { resetUnread } = useUnread();
|
||||
@@ -38,6 +44,7 @@ function App() {
|
||||
<AuthProvider>
|
||||
<UnreadListener />
|
||||
<BrowserRouter>
|
||||
<ScrollToTop />
|
||||
<Routes>
|
||||
<Route path="/" element={<LandingPage />} />
|
||||
<Route path="/feed" element={<MainFeed />} />
|
||||
|
||||
@@ -73,7 +73,6 @@ export async function apiFetch(url, options = {}) {
|
||||
res = await doFetch(newToken);
|
||||
} catch {
|
||||
clearTokens();
|
||||
window.location.href = "/";
|
||||
throw new Error("Session expired");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// src/components/AuthModal.jsx
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { useAuthContext } from "../context/AuthContext";
|
||||
@@ -14,6 +14,12 @@ export default function AuthModal({ onClose }) {
|
||||
const [mode, setMode] = useState("login"); // "login" | "register"
|
||||
const { login: saveAuth } = useAuthContext();
|
||||
|
||||
useEffect(() => {
|
||||
const prev = document.body.style.overflow;
|
||||
document.body.style.overflow = "hidden";
|
||||
return () => { document.body.style.overflow = prev; };
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="f-modal-bg auth-modal-bg" onClick={e => e.target === e.currentTarget && onClose()}>
|
||||
<div className="f-modal auth-modal">
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function PostOnFeed({ ad, liked, likeCountAdj, onLike, onEdit, on
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={`f-card${isClosed ? ' f-card-closed' : ''}`}>
|
||||
<div className={`f-card${isClosed ? ' f-card-closed' : ''}${ad.type === "found" ? ' f-card-found' : ' f-card-loss'}`}>
|
||||
|
||||
<div className={`f-card-head${headAccentClass}`}>
|
||||
<div className="f-card-author">
|
||||
@@ -114,10 +114,24 @@ export default function PostOnFeed({ ad, liked, likeCountAdj, onLike, onEdit, on
|
||||
<TrashIcon/>
|
||||
</button>
|
||||
)}
|
||||
{ad.reward && (
|
||||
<span className="f-card-reward-text">
|
||||
{t("postCard.reward")}
|
||||
</span>
|
||||
{createdAt && (
|
||||
<div
|
||||
className="f-meta-pill f-date-pill"
|
||||
ref={dateAnchorRef}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
setShowCalendar(s => !s);
|
||||
}}
|
||||
>
|
||||
<CalendarIcon/> {createdAt}
|
||||
{showCalendar && (
|
||||
<DateCalendarPopup
|
||||
date={ad.createdAt}
|
||||
onClose={() => setShowCalendar(false)}
|
||||
anchorRef={dateAnchorRef}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -145,24 +159,10 @@ export default function PostOnFeed({ ad, liked, likeCountAdj, onLike, onEdit, on
|
||||
<PinIcon/> {address}
|
||||
</div>
|
||||
)}
|
||||
{createdAt && (
|
||||
<div
|
||||
className="f-meta-pill f-date-pill"
|
||||
ref={dateAnchorRef}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
setShowCalendar(s => !s);
|
||||
}}
|
||||
>
|
||||
<CalendarIcon/> {createdAt}
|
||||
{showCalendar && (
|
||||
<DateCalendarPopup
|
||||
date={ad.createdAt}
|
||||
onClose={() => setShowCalendar(false)}
|
||||
anchorRef={dateAnchorRef}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{ad.reward && (
|
||||
<span className="f-card-reward-text">
|
||||
{t("postCard.reward")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,28 +7,28 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
.f-card:hover { border-color: var(--muted2); }
|
||||
.f-card-loss {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 2px rgba(237,73,86,.7);
|
||||
}
|
||||
.f-card-found {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 2px rgba(48,168,94,.7);
|
||||
}
|
||||
|
||||
/* ── Post header ── */
|
||||
.f-card-head {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
padding: 12px 14px 12px 17px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Тонкая цветовая идентификация шапки: потеря / находка */
|
||||
.f-card-head::before {
|
||||
content: "";
|
||||
position: absolute; left: 0; top: 0; bottom: 0;
|
||||
width: 3px;
|
||||
}
|
||||
.f-head-loss {
|
||||
background: rgba(237,73,86,.05);
|
||||
}
|
||||
.f-head-loss::before { background: rgba(237,73,86,.45); }
|
||||
.f-head-loss,
|
||||
.f-head-found {
|
||||
background: rgba(48,168,94,.07);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.f-head-found::before { background: rgba(48,168,94,.5); }
|
||||
.f-head-loss .f-card-author-name { color: var(--text-primary); }
|
||||
.f-head-loss .f-type-badge { background: rgba(237,73,86,.1); color: #ed4956; border-color: rgba(237,73,86,.4); }
|
||||
.f-head-found .f-card-author-name { color: var(--text-primary); }
|
||||
.f-head-found .f-type-badge { background: rgba(48,168,94,.1); color: #30a85e; border-color: rgba(48,168,94,.4); }
|
||||
|
||||
.f-card-avatar-ring {
|
||||
width: 42px; height: 42px; border-radius: 50%;
|
||||
@@ -63,11 +63,13 @@
|
||||
background: var(--bg-card-img);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
overflow: hidden;
|
||||
border: none; outline: none;
|
||||
}
|
||||
.f-card-img img {
|
||||
width: 100%; height: 100%;
|
||||
object-fit: cover; object-position: center;
|
||||
display: block;
|
||||
border: none; outline: none;
|
||||
}
|
||||
.f-card-emoji { font-size: 4rem; opacity: .85; filter: drop-shadow(0 4px 12px rgba(0,0,0,.3)); }
|
||||
.f-card-reward {
|
||||
@@ -150,7 +152,8 @@
|
||||
display: flex; flex-wrap: wrap; align-items: center;
|
||||
gap: 6px; padding: 8px 16px 4px;
|
||||
}
|
||||
.f-card-meta .f-date-pill {
|
||||
.f-card-meta .f-date-pill,
|
||||
.f-card-meta .f-card-reward-text {
|
||||
margin-left: auto;
|
||||
}
|
||||
.f-meta-pill {
|
||||
|
||||
Reference in New Issue
Block a user