Главная страница
Создание главной страницы
This commit is contained in:
parent
068794b4a6
commit
8bda3252cd
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user