moved icon profile on up
This commit is contained in:
11
.idea/aws.xml
generated
Normal file
11
.idea/aws.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="accountSettings">
|
||||||
|
<option name="activeRegion" value="us-east-1" />
|
||||||
|
<option name="recentlyUsedRegions">
|
||||||
|
<list>
|
||||||
|
<option value="us-east-1" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -7,6 +7,7 @@ import RightSidebar from "./RightSidebar";
|
|||||||
import PostOnFeed from "./PostOnFeed";
|
import PostOnFeed from "./PostOnFeed";
|
||||||
import CreateUpdatePost from "./CreateUpdatePost";
|
import CreateUpdatePost from "./CreateUpdatePost";
|
||||||
import MenuIcon from "./icons/MenuIcon";
|
import MenuIcon from "./icons/MenuIcon";
|
||||||
|
import ProfileAvatar from "./profile/ProfileAvatar";
|
||||||
import { ProfileModal } from "./profile";
|
import { ProfileModal } from "./profile";
|
||||||
import AuthModal from "./AuthModal";
|
import AuthModal from "./AuthModal";
|
||||||
import RulesModal from "./RulesModal";
|
import RulesModal from "./RulesModal";
|
||||||
@@ -22,7 +23,7 @@ import { usePostStatus } from "../hooks/usePostStatus";
|
|||||||
*/
|
*/
|
||||||
export default function MainFeed() {
|
export default function MainFeed() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { user, token, isAuthenticated, logout } = useAuthContext();
|
const { user, token, isAuthenticated } = useAuthContext();
|
||||||
const { deletePost } = useDeletePost();
|
const { deletePost } = useDeletePost();
|
||||||
const { toggleFavorite, loadFavorites } = useFavorites();
|
const { toggleFavorite, loadFavorites } = useFavorites();
|
||||||
const { markAsFound } = usePostStatus();
|
const { markAsFound } = usePostStatus();
|
||||||
@@ -312,13 +313,7 @@ export default function MainFeed() {
|
|||||||
activeNav={activeNav}
|
activeNav={activeNav}
|
||||||
onClose={() => setSidebarOpen(false)}
|
onClose={() => setSidebarOpen(false)}
|
||||||
onNavClick={setActiveNav}
|
onNavClick={setActiveNav}
|
||||||
onEditProfile={() => {
|
|
||||||
if (!isAuthenticated) { setAuthModalOpen(true); return; }
|
|
||||||
setProfileModalOpen(true);
|
|
||||||
}}
|
|
||||||
profileData={profileData}
|
|
||||||
isAuthenticated={isAuthenticated}
|
isAuthenticated={isAuthenticated}
|
||||||
onLogout={logout}
|
|
||||||
onLoginClick={() => setAuthModalOpen(true)}
|
onLoginClick={() => setAuthModalOpen(true)}
|
||||||
onRulesClick={() => setRulesModalOpen(true)}
|
onRulesClick={() => setRulesModalOpen(true)}
|
||||||
onReviewsClick={() => navigate("/reviews")}
|
onReviewsClick={() => navigate("/reviews")}
|
||||||
@@ -336,8 +331,14 @@ export default function MainFeed() {
|
|||||||
Разместить объявление
|
Разместить объявление
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/* Пустой спейсер симметрично уравновешивает бургер слева */}
|
{/* Иконка профиля в правом углу */}
|
||||||
<div className="f-topbar-spacer" />
|
<div className="f-topbar-profile" onClick={() => isAuthenticated ? setProfileModalOpen(true) : setAuthModalOpen(true)}>
|
||||||
|
{isAuthenticated ? (
|
||||||
|
<ProfileAvatar avatar={profileData.avatar} name={`${profileData.firstName || ""} ${profileData.lastName || ""}`} />
|
||||||
|
) : (
|
||||||
|
<span className="f-topbar-login-icon">🔑</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Фильтр по типу объявления */}
|
{/* Фильтр по типу объявления */}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import LogoIcon from "./icons/LogoIcon";
|
import LogoIcon from "./icons/LogoIcon";
|
||||||
import {NAV_BOTTOM, NAV_ITEMS} from "../config/feedConstants";
|
import {NAV_BOTTOM, NAV_ITEMS} from "../config/feedConstants";
|
||||||
import {NavIcons} from "./icons/NavIcons";
|
import {NavIcons} from "./icons/NavIcons";
|
||||||
import Profile from "./profile/Profile";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
@@ -9,10 +8,7 @@ export default function Sidebar({
|
|||||||
activeNav,
|
activeNav,
|
||||||
onClose,
|
onClose,
|
||||||
onNavClick,
|
onNavClick,
|
||||||
onEditProfile,
|
|
||||||
profileData = {},
|
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
onLogout,
|
|
||||||
onLoginClick,
|
onLoginClick,
|
||||||
onRulesClick,
|
onRulesClick,
|
||||||
onReviewsClick,
|
onReviewsClick,
|
||||||
@@ -82,28 +78,6 @@ export default function Sidebar({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<div className="f-sb-divider" />
|
|
||||||
|
|
||||||
{isAuthenticated ? (
|
|
||||||
<>
|
|
||||||
<Profile data={profileData} onEdit={onEditProfile} />
|
|
||||||
<div
|
|
||||||
className="f-sb-item"
|
|
||||||
onClick={() => { onLogout(); onClose(); }}
|
|
||||||
style={{ color: "rgba(255,107,107,.7)", marginTop: 8 }}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: "1.1rem" }}>🚪</span> Выйти
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className="f-sb-item"
|
|
||||||
onClick={() => { onLoginClick(); onClose(); }}
|
|
||||||
style={{ color: "#2de0c8" }}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: "1.1rem" }}>🔑</span> Войти
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
} from "./ProfileFormFields";
|
} from "./ProfileFormFields";
|
||||||
|
|
||||||
export default function ProfileModal({ onClose, initialData = {} }) {
|
export default function ProfileModal({ onClose, initialData = {} }) {
|
||||||
const { user, updateUser } = useAuthContext();
|
const { user, updateUser, logout } = useAuthContext();
|
||||||
const { updateProfile, loading: saving, error: saveError } = useUpdateProfile();
|
const { updateProfile, loading: saving, error: saveError } = useUpdateProfile();
|
||||||
const [form, setForm] = useState(initializeFormState(initialData));
|
const [form, setForm] = useState(initializeFormState(initialData));
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
@@ -105,6 +105,14 @@ export default function ProfileModal({ onClose, initialData = {} }) {
|
|||||||
{saveError && <p className="f-err-msg" style={{ marginBottom: 10 }}>{saveError}</p>}
|
{saveError && <p className="f-err-msg" style={{ marginBottom: 10 }}>{saveError}</p>}
|
||||||
|
|
||||||
<SubmitButton loading={compressing || saving} onSubmit={handleSubmit} />
|
<SubmitButton loading={compressing || saving} onSubmit={handleSubmit} />
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="f-modal-logout"
|
||||||
|
onClick={() => { logout(); onClose(); }}
|
||||||
|
>
|
||||||
|
Выйти
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -35,6 +35,22 @@
|
|||||||
.f-topbar-center { flex: 1; display: flex; justify-content: center; }
|
.f-topbar-center { flex: 1; display: flex; justify-content: center; }
|
||||||
.f-topbar-spacer { width: 32px; flex-shrink: 0; }
|
.f-topbar-spacer { width: 32px; flex-shrink: 0; }
|
||||||
|
|
||||||
|
/* ── Topbar Profile ── */
|
||||||
|
.f-topbar-profile {
|
||||||
|
width: 32px; height: 32px; flex-shrink: 0;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
cursor: pointer; border-radius: 50%;
|
||||||
|
transition: background .15s;
|
||||||
|
}
|
||||||
|
.f-topbar-profile:hover { background: rgba(255,255,255,.08); }
|
||||||
|
.f-topbar-profile .f-profile-avatar {
|
||||||
|
width: 28px; height: 28px; border-width: 1.5px;
|
||||||
|
}
|
||||||
|
.f-topbar-profile .f-profile-avatar-placeholder {
|
||||||
|
width: 28px; height: 28px; font-size: 1rem;
|
||||||
|
}
|
||||||
|
.f-topbar-login-icon { font-size: 1.1rem; line-height: 1; }
|
||||||
|
|
||||||
/* ── Filter Bar ── */
|
/* ── Filter Bar ── */
|
||||||
.f-filter-bar {
|
.f-filter-bar {
|
||||||
display: flex; gap: 10px;
|
display: flex; gap: 10px;
|
||||||
|
|||||||
@@ -105,6 +105,19 @@
|
|||||||
.f-m-submit:active:not(:disabled) { transform: translateY(0); }
|
.f-m-submit:active:not(:disabled) { transform: translateY(0); }
|
||||||
.f-m-submit:disabled { opacity: .5; cursor: not-allowed; animation: none; background: #444; color: #aaa; }
|
.f-m-submit:disabled { opacity: .5; cursor: not-allowed; animation: none; background: #444; color: #aaa; }
|
||||||
.f-m-submit-row { display: flex; align-items: center; justify-content: center; gap: 8px; }
|
.f-m-submit-row { display: flex; align-items: center; justify-content: center; gap: 8px; }
|
||||||
|
|
||||||
|
/* ── Modal Logout Button ── */
|
||||||
|
.f-modal-logout {
|
||||||
|
display: block; width: 100%; margin-top: 16px; padding: 10px;
|
||||||
|
border-radius: 10px; border: 1px solid rgba(255,107,107,.3);
|
||||||
|
background: rgba(255,107,107,.08); color: rgba(255,107,107,.8);
|
||||||
|
font-family: var(--font); font-size: .9rem; font-weight: 700; cursor: pointer;
|
||||||
|
transition: background .15s, border-color .15s;
|
||||||
|
}
|
||||||
|
.f-modal-logout:hover {
|
||||||
|
background: rgba(255,107,107,.18);
|
||||||
|
border-color: rgba(255,107,107,.5);
|
||||||
|
}
|
||||||
.f-m-spinner {
|
.f-m-spinner {
|
||||||
width: 16px; height: 16px;
|
width: 16px; height: 16px;
|
||||||
border: 2px solid rgba(8,35,32,.3); border-top-color: #082320;
|
border: 2px solid rgba(8,35,32,.3); border-top-color: #082320;
|
||||||
|
|||||||
Reference in New Issue
Block a user