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

Создание главной страницы
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 { Link } from "react-router-dom";
import { useMedia } from "../contexts/MediaContext";
import { useAuth } from "../contexts/AuthContext";
import MediaCarousel from "../components/media/MediaCarousel";
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useMedia } from '../contexts/MediaContext';
import { useAuth } from '../contexts/AuthContext';
import { listMedia } from '../services/supabase';
import { mediaTypes } from '../services/mediaService';
import { FiTrendingUp, FiCalendar, FiAward } from "react-icons/fi";
import MediaCarousel from "../components/media/MediaCarousel";
import { getImageUrl } from "../services/tmdbApi";
function HomePage() {
const { fetchTrendingMedia, trendingMovies, trendingTvShows, loading } =
useMedia();
const { currentUser } = useAuth();
const HomePage = () => {
const [media, setMedia] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const { user } = useAuth();
useEffect(() => {
fetchTrendingMedia();
}, [fetchTrendingMedia]);
const loadMedia = async () => {
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)
const featuredMedia =
trendingMovies.find((movie) => movie.backdrop_path) || trendingMovies[0];
loadMedia();
}, []);
return (
<div className="pt-20">
{/* Hero Section */}
{featuredMedia && (
<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 ? (
if (loading) {
return (
<div className="min-h-screen bg-campfire-dark pt-20">
<div className="container-custom py-12">
<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>
) : (
<>
{/* 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>
</div>
</div>
);
}
{/* Trending TV Shows */}
<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={trendingTvShows}
mediaType="tv"
seeAllLink="/discover/tv"
/>
</div>
if (error) {
return (
<div className="min-h-screen bg-campfire-dark pt-20">
<div className="container-custom py-12">
<div className="bg-status-error/20 text-status-error p-4 rounded-lg text-center">
{error}
</div>
</div>
</div>
);
}
{/* Latest Reviews */}
<div className="mb-12">
<div className="flex items-center mb-6">
<FiCalendar className="text-campfire-amber mr-2" size={20} />
<h2 className="text-2xl font-bold">Последние рецензии</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Placeholder for latest reviews */}
<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 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>
return (
<div className="min-h-screen bg-campfire-dark pt-20">
<div className="container-custom py-12">
<div className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold text-campfire-light">
Добро пожаловать в CampFire
</h1>
{user?.role === 'admin' && (
<Link
to="/admin/media"
className="btn-secondary"
>
Управление контентом
</Link>
)}
</div>
{/* Critic's Choice */}
<div className="mb-12">
<div className="flex items-center mb-6">
<FiAward className="text-campfire-amber mr-2" size={20} />
<h2 className="text-2xl font-bold">Выбор Резидентов</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{trendingMovies.slice(0, 3).map((movie) => (
<Link
key={movie.id}
to={`/media/${movie.id}?type=movie`}
className="block"
>
<div className="card h-full">
<div className="relative aspect-video">
<img
src={
getImageUrl(movie.backdrop_path, "w780") ||
getImageUrl(movie.poster_path, "w342")
}
alt={movie.title}
className="w-full h-full object-cover"
/>
</div>
<div className="p-4">
<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>
{media.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{media.map((item) => (
<Link
key={`${item.id}-${item.type}`}
to={`/media/${item.id}`}
className="group"
>
<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">
<div className="aspect-[2/3] relative">
<img
src={item.poster_url}
alt={item.title}
className="w-full h-full object-cover"
/>
<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" />
</div>
<div className="p-4">
<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">
{item.type === 'movie' ? 'Фильм' : 'Сериал'}
</span>
<span className="text-sm text-campfire-ash">
{new Date(item.release_date).getFullYear()}
</span>
</div>
</Link>
))}
</div>
</div>
</>
<h3 className="text-lg font-semibold text-campfire-light mb-1 group-hover:text-campfire-amber transition-colors">
{item.title}
</h3>
<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>
);
}
};
export default HomePage;