Главная страница

Создание главной страницы
This commit is contained in:
degradin 2025-05-07 13:35:53 +03:00
parent 068794b4a6
commit 8bda3252cd

View File

@ -1,188 +1,138 @@
import { useEffect } from "react"; import React, { useState, useEffect } from 'react';
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom';
import { useMedia } from "../contexts/MediaContext"; import { useMedia } from '../contexts/MediaContext';
import { useAuth } from "../contexts/AuthContext"; import { useAuth } from '../contexts/AuthContext';
import MediaCarousel from "../components/media/MediaCarousel"; import { listMedia } from '../services/supabase';
import { mediaTypes } from '../services/mediaService';
import { FiTrendingUp, FiCalendar, FiAward } from "react-icons/fi"; import { FiTrendingUp, FiCalendar, FiAward } from "react-icons/fi";
import MediaCarousel from "../components/media/MediaCarousel";
import { getImageUrl } from "../services/tmdbApi"; import { getImageUrl } from "../services/tmdbApi";
function HomePage() { const HomePage = () => {
const { fetchTrendingMedia, trendingMovies, trendingTvShows, loading } = const [media, setMedia] = useState([]);
useMedia(); const [loading, setLoading] = useState(true);
const { currentUser } = useAuth(); const [error, setError] = useState(null);
const { user } = useAuth();
useEffect(() => { useEffect(() => {
fetchTrendingMedia(); const loadMedia = async () => {
}, [fetchTrendingMedia]); try {
setLoading(true);
setError(null);
const { data, error } = await listMedia();
if (error) {
throw new Error(error);
}
setMedia(data || []);
} catch (err) {
console.error('Error loading media:', err);
setError('Не удалось загрузить контент');
} finally {
setLoading(false);
}
};
// Get featured media (first trending movie with backdrop) loadMedia();
const featuredMedia = }, []);
trendingMovies.find((movie) => movie.backdrop_path) || trendingMovies[0];
return ( if (loading) {
<div className="pt-20"> return (
{/* Hero Section */} <div className="min-h-screen bg-campfire-dark pt-20">
{featuredMedia && ( <div className="container-custom py-12">
<div className="relative w-full h-[500px] md:h-[600px] overflow-hidden">
<div className="absolute inset-0">
<img
src={getImageUrl(featuredMedia.backdrop_path, "original")}
alt={featuredMedia.title}
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-campfire-dark via-campfire-dark/60 to-transparent"></div>
</div>
<div className="container-custom relative h-full flex flex-col justify-end pb-16">
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-campfire-amber text-campfire-dark mb-4">
<FiTrendingUp className="mr-1" /> Trending
</span>
<h1 className="text-4xl md:text-5xl font-bold mb-4 max-w-2xl">
{featuredMedia.title}
</h1>
<p className="text-campfire-ash mb-6 max-w-2xl">
{featuredMedia.overview.substring(0, 200)}...
</p>
<Link
to={`/media/${featuredMedia.id}?type=movie`}
className="btn-primary inline-flex items-center"
>
View Details
</Link>
</div>
</div>
)}
{/* Welcome Message for Logged In Users */}
{currentUser && (
<div className="container-custom my-8">
<div className="bg-campfire-charcoal rounded-lg p-6">
<h2 className="text-2xl font-bold mb-2">
С возвращением, {currentUser.username}!
</h2>
<p className="text-campfire-ash mb-4">
Продолжайте открывать отличный контент и делиться своими мыслями с
сообществом.
</p>
<Link
to={`/profile/${currentUser.uid}`}
className="text-campfire-amber hover:text-campfire-ember"
>
Перейти в профиль
</Link>
</div>
</div>
)}
{/* Main Content */}
<div className="container-custom py-8">
{loading ? (
<div className="flex justify-center items-center h-64"> <div className="flex justify-center items-center h-64">
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-campfire-amber"></div> <div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-campfire-amber"></div>
</div> </div>
) : ( </div>
<> </div>
{/* Trending Movies */} );
<div className="mb-12"> }
<div className="flex items-center mb-2">
<FiTrendingUp className="text-campfire-amber mr-2" size={20} />
<h2 className="text-2xl font-bold">Фильмы</h2>
</div>
<MediaCarousel
media={trendingMovies}
mediaType="movie"
seeAllLink="/discover/movies"
/>
</div>
{/* Trending TV Shows */} if (error) {
<div className="mb-12"> return (
<div className="flex items-center mb-2"> <div className="min-h-screen bg-campfire-dark pt-20">
<FiTrendingUp className="text-campfire-amber mr-2" size={20} /> <div className="container-custom py-12">
<h2 className="text-2xl font-bold">Сериалы</h2> <div className="bg-status-error/20 text-status-error p-4 rounded-lg text-center">
</div> {error}
<MediaCarousel </div>
media={trendingTvShows} </div>
mediaType="tv" </div>
seeAllLink="/discover/tv" );
/> }
</div>
{/* Latest Reviews */} return (
<div className="mb-12"> <div className="min-h-screen bg-campfire-dark pt-20">
<div className="flex items-center mb-6"> <div className="container-custom py-12">
<FiCalendar className="text-campfire-amber mr-2" size={20} /> <div className="flex justify-between items-center mb-8">
<h2 className="text-2xl font-bold">Последние рецензии</h2> <h1 className="text-3xl font-bold text-campfire-light">
</div> Добро пожаловать в CampFire
<div className="grid grid-cols-1 md:grid-cols-2 gap-6"> </h1>
{/* Placeholder for latest reviews */} {user?.role === 'admin' && (
<div className="bg-campfire-charcoal rounded-lg p-6 flex flex-col items-center justify-center text-center h-48"> <Link
<p className="text-campfire-ash mb-4">Рецензий пока нет</p> to="/admin/media"
{!currentUser && ( className="btn-secondary"
<Link >
to="/login" Управление контентом
className="text-campfire-amber hover:text-campfire-ember" </Link>
> )}
Войдите, чтобы написать рецензию </div>
</Link>
)}
</div>
<div className="bg-campfire-charcoal rounded-lg p-6 flex flex-col items-center justify-center text-center h-48">
<p className="text-campfire-ash mb-4">Рецензий пока нет</p>
{!currentUser && (
<Link
to="/login"
className="text-campfire-amber hover:text-campfire-ember"
>
Войдите, чтобы написать рецензию
</Link>
)}
</div>
</div>
</div>
{/* Critic's Choice */} {media.length > 0 ? (
<div className="mb-12"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<div className="flex items-center mb-6"> {media.map((item) => (
<FiAward className="text-campfire-amber mr-2" size={20} /> <Link
<h2 className="text-2xl font-bold">Выбор Резидентов</h2> key={`${item.id}-${item.type}`}
</div> to={`/media/${item.id}`}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> className="group"
{trendingMovies.slice(0, 3).map((movie) => ( >
<Link <div className="bg-campfire-charcoal rounded-lg overflow-hidden shadow-lg border border-campfire-ash/20 transition-all duration-300 hover:shadow-xl hover:border-campfire-amber/30">
key={movie.id} <div className="aspect-[2/3] relative">
to={`/media/${movie.id}?type=movie`} <img
className="block" src={item.poster_url}
> alt={item.title}
<div className="card h-full"> className="w-full h-full object-cover"
<div className="relative aspect-video"> />
<img <div className="absolute inset-0 bg-gradient-to-t from-campfire-charcoal/80 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
src={ </div>
getImageUrl(movie.backdrop_path, "w780") || <div className="p-4">
getImageUrl(movie.poster_path, "w342") <div className="flex items-center justify-between mb-2">
} <span className="text-xs font-medium px-2 py-1 rounded-full bg-campfire-amber/20 text-campfire-amber">
alt={movie.title} {item.type === 'movie' ? 'Фильм' : 'Сериал'}
className="w-full h-full object-cover" </span>
/> <span className="text-sm text-campfire-ash">
</div> {new Date(item.release_date).getFullYear()}
<div className="p-4"> </span>
<h3 className="font-bold text-lg mb-2">
{movie.title}
</h3>
<p className="text-campfire-ash text-sm line-clamp-2">
{movie.overview}
</p>
</div>
</div> </div>
</Link> <h3 className="text-lg font-semibold text-campfire-light mb-1 group-hover:text-campfire-amber transition-colors">
))} {item.title}
</div> </h3>
</div> <p className="text-sm text-campfire-ash line-clamp-2">
</> {item.description}
</p>
</div>
</div>
</Link>
))}
</div>
) : (
<div className="text-center py-12">
<p className="text-campfire-ash text-lg">
Пока нет доступного контента
</p>
{user?.role === 'admin' && (
<Link
to="/admin/media"
className="inline-block mt-4 btn-primary"
>
Добавить контент
</Link>
)}
</div>
)} )}
</div> </div>
</div> </div>
); );
} };
export default HomePage; export default HomePage;