diff --git a/src/components/MainFeed.jsx b/src/components/MainFeed.jsx
index 5ed0374..23f28c9 100644
--- a/src/components/MainFeed.jsx
+++ b/src/components/MainFeed.jsx
@@ -8,6 +8,7 @@ import CreateUpdatePost from "./CreateUpdatePost";
import MenuIcon from "./icons/MenuIcon";
import { ProfileModal } from "./profile";
import AuthModal from "./AuthModal";
+import RulesModal from "./RulesModal";
import { useAuthContext } from "../context/AuthContext";
/**
@@ -32,6 +33,8 @@ export default function MainFeed() {
const [profileModalOpen, setProfileModalOpen] = useState(false);
// Открыто ли модальное окно аутентификации (login / register)
const [authModalOpen, setAuthModalOpen] = useState(false);
+ // Открыто ли модальное окно правил площадки
+ const [rulesModalOpen, setRulesModalOpen] = useState(false);
// Массив объявлений из API (основная лента)
const [ads, setAds] = useState([]);
// Объявления текущего пользователя (загружаются отдельно по userId)
@@ -45,13 +48,26 @@ export default function MainFeed() {
// Данные профиля — из контекста авторизации (или пустой объект для гостя)
const profileData = useMemo(() => {
if (!user) return {};
+
+ // Если бэк присылает имя одним полем "name" — разбиваем на firstName/lastName
+ // Если бэк присылает отдельные поля firstName/lastName — используем их напрямую
+ const nameParts = (user.name || "").trim().split(/\s+/);
+ const firstName = user.firstName || nameParts[0] || "";
+ const lastName = user.lastName || nameParts.slice(1).join(" ") || "";
+
+ // Аватар может быть относительным путём (/uploads/avatars/...) — добавляем API_URL
+ const rawAvatar = user.avatar || null;
+ const avatar = rawAvatar && rawAvatar.startsWith("/")
+ ? `${API_URL}${rawAvatar}`
+ : rawAvatar;
+
return {
login: user.login || "",
- firstName: user.name || user.firstName || "",
- lastName: user.lastName || "",
+ firstName,
+ lastName,
email: user.email || "",
phone: user.phone || "",
- avatar: user.avatar || null,
+ avatar,
id: user.id,
};
}, [user]);
@@ -230,9 +246,8 @@ export default function MainFeed() {
ad={ad}
liked={liked.has(ad.id)}
onLike={toggleLike}
- onEdit={handleEdit}
- // На вкладке «Мои объявления» все посты принадлежат пользователю
- isOwner={activeNav === "Мои объявления" || (isAuthenticated && ad.userId === user?.id)}
+ onEdit={activeNav === "Мои объявления" ? handleEdit : undefined}
+ isOwner={activeNav === "Мои объявления"}
/>
));
};
@@ -253,6 +268,7 @@ export default function MainFeed() {
isAuthenticated={isAuthenticated}
onLogout={logout}
onLoginClick={() => setAuthModalOpen(true)}
+ onRulesClick={() => setRulesModalOpen(true)}
/>
@@ -334,6 +350,11 @@ export default function MainFeed() {
onClose={() => setAuthModalOpen(false)}
/>
)}
+
+ {/* Модальное окно правил площадки */}
+ {rulesModalOpen && (
+ setRulesModalOpen(false)} />
+ )}
);
}
diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx
index 17184b7..3a313c2 100644
--- a/src/components/Sidebar.jsx
+++ b/src/components/Sidebar.jsx
@@ -13,6 +13,7 @@ export default function Sidebar({
isAuthenticated,
onLogout,
onLoginClick,
+ onRulesClick,
}) {
return (
<>
@@ -48,11 +49,20 @@ export default function Sidebar({
{NAV_BOTTOM.map(({ icon, label }) => {
const Ic = NavIcons[icon];
+ const handleBottomClick = () => {
+ if (label === "Правила площадки") {
+ onRulesClick?.();
+ onClose();
+ return;
+ }
+ onNavClick(label);
+ onClose();
+ };
return (
{ onNavClick(label); onClose(); }}
+ onClick={handleBottomClick}
>
{label}
diff --git a/src/components/icons/NavIcons.jsx b/src/components/icons/NavIcons.jsx
index e16b378..69af650 100644
--- a/src/components/icons/NavIcons.jsx
+++ b/src/components/icons/NavIcons.jsx
@@ -36,4 +36,13 @@ export const NavIcons = {
),
+ rules: () => (
+
+ ),
};
\ No newline at end of file
diff --git a/src/components/profile/ProfileModal.jsx b/src/components/profile/ProfileModal.jsx
index 1dd230f..1c1ed2c 100644
--- a/src/components/profile/ProfileModal.jsx
+++ b/src/components/profile/ProfileModal.jsx
@@ -52,11 +52,12 @@ export default function ProfileModal({ onClose, initialData = {} }) {
}
const profileData = {
- name: form.firstName.trim(),
- login: form.login.trim(),
- phone: form.phone.trim(),
- email: form.email.trim(),
- avatar: imageFile || existingImageUrl,
+ firstName: form.firstName.trim(),
+ lastName: form.lastName.trim(),
+ login: form.login.trim(),
+ phone: form.phone.trim(),
+ email: form.email.trim(),
+ avatar: imageFile || existingImageUrl,
};
const updatedUser = await updateProfile(user?.id, profileData);
diff --git a/src/config/feedConstants.js b/src/config/feedConstants.js
index e5a1f92..71371e0 100644
--- a/src/config/feedConstants.js
+++ b/src/config/feedConstants.js
@@ -9,7 +9,7 @@ export const NAV_ITEMS = [
export const NAV_BOTTOM = [
{ icon: "user", label: "Профиль" },
- { icon: "settings", label: "Настройки" },
+ { icon: "rules", label: "Правила площадки" },
];
export const CATEGORIES = [
diff --git a/src/styles/card.css b/src/styles/card.css
index d239848..1b1aa8b 100644
--- a/src/styles/card.css
+++ b/src/styles/card.css
@@ -8,17 +8,18 @@
.f-card:hover { border-color: rgba(45,224,200,.3); transform: translateY(-2px); }
.f-card-inner {
- display: flex; flex-direction: row; min-height: 160px;
+ display: flex; flex-direction: row; min-height: 180px;
}
/* Image Panel */
.f-card-img {
width: 180px; min-width: 180px;
+ align-self: stretch; /* растягивается на всю высоту карточки */
background: linear-gradient(135deg, #1a3a4a 0%, #0f2235 100%);
display: flex; align-items: center; justify-content: center;
position: relative; overflow: hidden; flex-shrink: 0;
}
-.f-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
+.f-card-img img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; position: absolute; inset: 0; }
.f-card-emoji { font-size: 3rem; opacity: .22; }
/* Badges */
@@ -103,7 +104,7 @@
.f-card-img {
width: 100%;
min-width: unset;
- height: 160px;
+ height: 180px;
}
/* Убираем кнопку карты на мобилке — занимает много места */
diff --git a/src/styles/modal.css b/src/styles/modal.css
index 989771f..ed3614b 100644
--- a/src/styles/modal.css
+++ b/src/styles/modal.css
@@ -77,8 +77,8 @@
.f-img-input { display: none; }
/* Image Preview */
-.f-img-preview-wrap { position: relative; display: inline-block; width: 100%; }
-.f-img-preview { width: 100%; max-height: 220px; object-fit: cover; border-radius: 12px; display: block; }
+.f-img-preview-wrap { position: relative; display: block; width: 100%; }
+.f-img-preview { width: 100%; height: 200px; object-fit: cover; object-position: center; border-radius: 12px; display: block; }
.f-img-remove {
position: absolute; top: 8px; right: 8px;
background: rgba(0,0,0,0.55); border: none; border-radius: 50%;