Files
nahodka-front/src/pages/ReviewsPage.jsx
2026-08-18 01:06:50 +03:00

132 lines
5.0 KiB
JavaScript

import { useState, useEffect, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { getImageUrl } from "../config/authConstants";
import { useAuthContext } from "../context/AuthContext";
import Sidebar from "../components/Sidebar";
import AppTopBar from "../components/layout/AppTopBar";
import { ProfileModal } from "../components/profile";
import AuthModal from "../components/AuthModal";
import RulesModal from "./RulesModal";
import ReviewCard from "../components/reviews/ReviewCard";
import ReviewForm from "../components/reviews/ReviewForm";
import RatingSummary from "../components/reviews/RatingSummary";
import { useReviews } from "../hooks/useReviews";
import "../styles/reviews.css";
import { useTranslation } from 'react-i18next';
export default function ReviewsPage() {
const { t } = useTranslation();
const navigate = useNavigate();
const { user, token, isAuthenticated } = useAuthContext();
const [sidebarOpen, setSidebarOpen] = useState(false);
const [profileModalOpen, setProfileModalOpen] = useState(false);
const [authModalOpen, setAuthModalOpen] = useState(false);
const [rulesModalOpen, setRulesModalOpen] = useState(false);
const profileData = useMemo(() => {
if (!user) return {};
const nameParts = (user.name || "").trim().split(/\s+/);
return {
login: user.login || "",
firstName: user.firstName || nameParts[0] || "",
lastName: user.lastName || nameParts.slice(1).join(" ") || "",
email: user.email || "",
phone: user.phone || "",
avatar: getImageUrl(user.avatar),
id: user.id,
};
}, [user]);
const {
reviews, loading, error, submitting, submitError,
loadReviews, submitReview, avgRating, distribution,
} = useReviews({
token,
isAuthenticated,
onAuthRequired: () => setAuthModalOpen(true),
authorFallbackName: profileData.firstName || t('reviews.you'),
});
useEffect(() => { loadReviews(); }, [loadReviews]);
return (
<div className="f-app">
<Sidebar
open={sidebarOpen}
activeNav="reviews"
onClose={() => setSidebarOpen(false)}
onNavClick={(key) => navigate("/feed")}
isAuthenticated={isAuthenticated}
onLoginClick={() => setAuthModalOpen(true)}
onRulesClick={() => setRulesModalOpen(true)}
onCreatePost={() => navigate("/feed")}
onProfileClick={() => setProfileModalOpen(true)}
profileData={profileData}
/>
<div className="f-main">
<AppTopBar
onMenuClick={() => setSidebarOpen((v) => !v)}
isAuthenticated={isAuthenticated}
profileData={profileData}
onProfileClick={() => setProfileModalOpen(true)}
onLoginClick={() => setAuthModalOpen(true)}
loginLabel={t('reviews.login')}
centerContent={<h1 className="rv-page-title">{t('reviews.title')}</h1>}
/>
<div className="rv-layout">
<div className="rv-sidebar">
<RatingSummary
avgRating={avgRating}
totalCount={reviews.length}
distribution={distribution}
/>
{isAuthenticated ? (
<>
<ReviewForm onSubmit={submitReview} submitting={submitting} />
{submitError && (
<div className="rv-form-error">{t('reviews.submitError')}</div>
)}
</>
) : (
<div className="rv-login-prompt">
<p>{t('reviews.loginPrompt')}</p>
<button className="rv-login-btn" onClick={() => setAuthModalOpen(true)}>
{t('reviews.login')}
</button>
</div>
)}
</div>
<div className="rv-list">
{loading ? (
<div className="f-center">
<div className="f-spinner-wrap">
<div className="f-spinner" />
{t('reviews.loading')}
</div>
</div>
) : error && reviews.length === 0 ? (
<div className="f-center">
<div className="f-center-icon">💬</div>
<div className="f-center-title">{t('reviews.emptyTitle')}</div>
<div className="f-center-sub">{t('reviews.emptySub')}</div>
</div>
) : (
reviews.map((review) => <ReviewCard key={review.id} review={review} />)
)}
</div>
</div>
</div>
{profileModalOpen && isAuthenticated && (
<ProfileModal onClose={() => setProfileModalOpen(false)} initialData={profileData} />
)}
{authModalOpen && <AuthModal onClose={() => setAuthModalOpen(false)} />}
{rulesModalOpen && <RulesModal onClose={() => setRulesModalOpen(false)} />}
</div>
);
}