Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion 85f7f045f99c649f87f9d0baa67c7663.txt

This file was deleted.

24 changes: 0 additions & 24 deletions Asset 1.svg

This file was deleted.

Binary file removed Asset 1chrome.png
Binary file not shown.
Binary file removed image.png
Binary file not shown.
87 changes: 57 additions & 30 deletions src/components/ContentTabs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
//import { motion } from 'framer-motion';
import { Tab } from '@headlessui/react';
//import { User, Star } from 'react-feather';
import { useDarkMode } from './DarkModeContext';

const ContentTabs = ({
item,
Expand All @@ -14,38 +13,49 @@ const ContentTabs = ({
similar,
handleListItemClick
}) => {
const { isDarkMode } = useDarkMode();

return (
<Tab.Group>
<Tab.List className="flex space-x-1 rounded-xl bg-black/20 p-1">
<Tab.List className={`flex space-x-1 rounded-xl ${isDarkMode ? 'bg-black/20' : 'bg-gray-100'} p-1`}>
<Tab className={({ selected }) =>
`w-full rounded-lg py-2.5 text-sm font-medium leading-5
`w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all
${selected
? 'bg-[#02c39a] text-white dark:text-black shadow'
: 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}`
? 'bg-[#02c39a] text-white shadow'
: isDarkMode
? 'text-gray-400 hover:bg-white/[0.12] hover:text-white'
: 'text-gray-600 hover:bg-gray-200 hover:text-gray-900'
}`
}>
Overview
</Tab>
<Tab className={({ selected }) =>
`w-full rounded-lg py-2.5 text-sm font-medium leading-5
`w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all
${selected
? 'bg-[#02c39a] text-white dark:text-black shadow'
: 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}`
? 'bg-[#02c39a] text-white shadow'
: isDarkMode
? 'text-gray-400 hover:bg-white/[0.12] hover:text-white'
: 'text-gray-600 hover:bg-gray-200 hover:text-gray-900'
}`
}>
Cast & Crew
</Tab>
<Tab className={({ selected }) =>
`w-full rounded-lg py-2.5 text-sm font-medium leading-5
`w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all
${selected
? 'bg-[#02c39a] text-white dark:text-black shadow'
: 'text-gray-600 dark:text-gray-400 hover:bg-white/[0.12] hover:text-gray-900 dark:hover:text-white'}`
? 'bg-[#02c39a] text-white shadow'
: isDarkMode
? 'text-gray-400 hover:bg-white/[0.12] hover:text-white'
: 'text-gray-600 hover:bg-gray-200 hover:text-gray-900'
}`
}>
Reviews
</Tab>
</Tab.List>
<Tab.Panels className="mt-4">
<Tab.Panel className="space-y-4">
<div className="prose prose-invert max-w-none">
<p className={`text-gray-800 dark:text-gray-200 ${!showFullOverview && 'line-clamp-3'}`}>
<div className={`prose max-w-none ${isDarkMode ? 'prose-invert' : ''}`}>
<p className={`${isDarkMode ? 'text-gray-200' : 'text-gray-700'} ${!showFullOverview && 'line-clamp-3'}`}>
{detailedOverview}
</p>
{detailedOverview?.length > 200 && (
Expand All @@ -61,31 +71,42 @@ const ContentTabs = ({
<Tab.Panel className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
{cast.map((person) => (
<div key={person.id} className="text-center">
<img
src={`https://image.tmdb.org/t/p/w185${person.profile_path}`}
alt={person.name}
className="w-full rounded-lg"
/>
<p className="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">{person.name}</p>
<p className="text-xs text-gray-600 dark:text-gray-400">{person.character}</p>
<div className="relative aspect-[2/3] rounded-lg overflow-hidden shadow-md">
<img
src={`https://image.tmdb.org/t/p/w185${person.profile_path}`}
alt={person.name}
className="w-full h-full object-cover"
onError={(e) => {
e.target.src = '/fallback-poster.jpg';
}}
/>
</div>
<p className={`mt-2 text-sm font-medium ${isDarkMode ? 'text-gray-100' : 'text-gray-900'}`}>
{person.name}
</p>
<p className={`text-xs ${isDarkMode ? 'text-gray-400' : 'text-gray-600'}`}>
{person.character}
</p>
</div>
))}
</Tab.Panel>
<Tab.Panel>
<ReviewsTab reviews={reviews} />
<ReviewsTab reviews={reviews} isDarkMode={isDarkMode} />
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
};

const ReviewsTab = ({ reviews }) => (
const ReviewsTab = ({ reviews, isDarkMode }) => (
<div className="space-y-6">
{reviews.length > 0 ? (
reviews.map((review) => (
<div
key={review.id}
className="bg-white/5 rounded-lg p-4 space-y-3"
className={`rounded-lg p-4 space-y-3 ${
isDarkMode ? 'bg-white/5' : 'bg-gray-50'
}`}
>
<div className="flex items-start justify-between gap-4">
<div className="flex items-center gap-3">
Expand All @@ -95,30 +116,36 @@ const ReviewsTab = ({ reviews }) => (
</span>
</div>
<div>
<h4 className="font-medium text-white/90">{review.author}</h4>
<p className="text-sm text-white/60">
<h4 className={`font-medium ${isDarkMode ? 'text-white/90' : 'text-gray-900'}`}>
{review.author}
</h4>
<p className={`text-sm ${isDarkMode ? 'text-white/60' : 'text-gray-600'}`}>
{new Date(review.created_at).toLocaleDateString()}
</p>
</div>
</div>
{review.author_details?.rating && (
<div className="flex items-center gap-1 bg-white/10 px-2 py-1 rounded">
<div className={`flex items-center gap-1 px-2 py-1 rounded ${
isDarkMode ? 'bg-white/10' : 'bg-gray-100'
}`}>
<svg className="w-4 h-4 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<path d="M9.049 2.927c.396-.902 1.506-.902 1.902 0l1.286 2.93a1 1 0 00.832.604l3.018.33c.98.107 1.373 1.361.625 2.04l-2.3 2.112a1 1 0 00-.318.981l.669 2.983c.219.97-.857 1.73-1.726 1.218L10 14.147l-2.736 1.98c-.87.512-1.945-.248-1.726-1.218l.669-2.983a1 1 0 00-.318-.981l-2.3-2.112c-.748-.679-.355-1.933.625-2.04l3.018-.33a1 1 0 00.832-.604l1.286-2.93z" />
</svg>
<span className="text-sm font-medium text-white/90">
<span className={`text-sm font-medium ${isDarkMode ? 'text-white/90' : 'text-gray-900'}`}>
{review.author_details.rating}
</span>
</div>
)}
</div>
<p className="text-white/80 line-clamp-4 hover:line-clamp-none transition-all duration-200">
<p className={`line-clamp-4 hover:line-clamp-none transition-all duration-200 ${
isDarkMode ? 'text-white/80' : 'text-gray-700'
}`}>
{review.content}
</p>
</div>
))
) : (
<div className="text-center text-white/60 py-8">
<div className={`text-center py-8 ${isDarkMode ? 'text-white/60' : 'text-gray-500'}`}>
No reviews available yet
</div>
)}
Expand Down
30 changes: 23 additions & 7 deletions src/components/EpisodeGrid.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import React from 'react';
import { motion } from 'framer-motion';
import { useDarkMode } from './DarkModeContext';

const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handleInputChange }) => {
const { isDarkMode } = useDarkMode();

if (type !== 'tv') return null;

return (
Expand Down Expand Up @@ -29,14 +33,18 @@ const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handl

<div className="grid grid-cols-2 xs:grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-3">
{episodes.map((episode) => (
<button
<motion.button
key={episode.id}
className={`relative group ${
currentEpisode?.id === episode.id ? 'ring-2 ring-[#02c39a]' : ''
} rounded-lg overflow-hidden bg-white/5 hover:bg-white/10 transition-colors`}
} rounded-lg overflow-hidden ${
isDarkMode ? 'hover:bg-white/10' : 'hover:bg-gray-100'
} transition-colors`}
onClick={() => handleInputChange({
target: { name: 'episodeNo', value: episode.episode_number.toString() }
})}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
>
<div className="relative aspect-video rounded-lg overflow-hidden bg-gray-900/40 backdrop-blur-sm">
{episode.still_path ? (
Expand All @@ -47,8 +55,12 @@ const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handl
loading="lazy"
/>
) : (
<div className="w-full h-full flex items-center justify-center">
<span className="text-gray-400">No Preview</span>
<div className={`w-full h-full flex items-center justify-center ${
isDarkMode ? 'bg-gray-800' : 'bg-gray-200'
}`}>
<span className={`text-gray-400 ${isDarkMode ? 'text-white/40' : 'text-gray-400'}`}>
No Preview
</span>
</div>
)}

Expand All @@ -63,7 +75,9 @@ const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handl

<div className="p-2 space-y-1">
<div className="flex items-center justify-between">
<span className="text-xs text-white/60 font-medium">
<span className={`text-xs font-medium ${
isDarkMode ? 'text-white/90' : 'text-white'
}`}>
Episode {episode.episode_number}
</span>
{episode.vote_average > 0 && (
Expand All @@ -72,11 +86,13 @@ const EpisodeGrid = ({ type, mediaData, episodes, seasons, currentEpisode, handl
</span>
)}
</div>
<h3 className="text-sm font-medium text-white/90 line-clamp-2 group-hover:text-[#02c39a] transition-colors">
<h3 className={`text-sm font-medium ${
isDarkMode ? 'text-white/90' : 'text-white'
} line-clamp-2 group-hover:text-[#02c39a] transition-colors`}>
{episode.name}
</h3>
</div>
</button>
</motion.button>
))}
</div>
</div>
Expand Down
11 changes: 7 additions & 4 deletions src/components/EpisodeNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import React from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/solid';
import { Tooltip } from 'react-tooltip';
import { useDarkMode } from './DarkModeContext';

const EpisodeNavigation = ({
episodes,
currentEpisodeNo,
season,
onEpisodeChange,
isDarkMode,
isDarkMode: parentIsDarkMode,
isLoading
}) => {
const { isDarkMode } = useDarkMode();
const actualIsDarkMode = parentIsDarkMode ?? isDarkMode;
const currentEpisodeIndex = episodes.findIndex(ep => ep.episode_number === parseInt(currentEpisodeNo));
const hasPrevious = currentEpisodeIndex > 0;
const hasNext = currentEpisodeIndex < episodes.length - 1;
Expand All @@ -28,13 +31,13 @@ const EpisodeNavigation = ({

return (
<div className={`flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-2 sm:gap-4 p-2 sm:p-3 rounded-lg ${
isDarkMode ? 'bg-gray-800' : 'bg-gray-100'
actualIsDarkMode ? 'bg-gray-800' : 'bg-gray-100'
}`}>
<motion.button
onClick={handlePrevious}
disabled={!hasPrevious || isLoading}
className={`flex-1 sm:flex-initial flex items-center justify-center gap-1 px-3 py-2 rounded-lg transition-all duration-200 ${
isDarkMode
actualIsDarkMode
? 'text-white hover:bg-gray-700 disabled:opacity-40 disabled:hover:bg-transparent'
: 'text-gray-800 hover:bg-gray-200 disabled:opacity-40 disabled:hover:bg-transparent'
}`}
Expand Down Expand Up @@ -74,7 +77,7 @@ const EpisodeNavigation = ({
onClick={handleNext}
disabled={!hasNext || isLoading}
className={`flex-1 sm:flex-initial flex items-center justify-center gap-1 px-3 py-2 rounded-lg transition-all duration-200 ${
isDarkMode
actualIsDarkMode
? 'text-white hover:bg-gray-700 disabled:opacity-40 disabled:hover:bg-transparent'
: 'text-gray-800 hover:bg-gray-200 disabled:opacity-40 disabled:hover:bg-transparent'
}`}
Expand Down
18 changes: 11 additions & 7 deletions src/components/Recommendations.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react';
import { motion } from 'framer-motion';
import { useDarkMode } from './DarkModeContext';

const Recommendations = ({ recommendations, handleListItemClick }) => {
const { isDarkMode } = useDarkMode();

const handleImageError = (e) => {
e.target.src = '/fallback-poster.jpg';
};
Expand All @@ -14,10 +17,10 @@ const Recommendations = ({ recommendations, handleListItemClick }) => {
transition={{ staggerChildren: 0.1 }}
>
<div className="relative">
<div className="max-h-[calc(100vh-200px)] overflow-y-auto overflow-x-hidden
<div className={`max-h-[calc(100vh-200px)] overflow-y-auto overflow-x-hidden
scrollbar-thin scrollbar-thumb-[#02c39a]/20 scrollbar-track-transparent
hover:scrollbar-thumb-[#02c39a]/40 sm:pr-2 pb-4
snap-y snap-mandatory scroll-smooth touch-pan-y"
snap-y snap-mandatory scroll-smooth touch-pan-y`}
>
<div className="grid grid-cols-2 gap-3 min-w-0">
{recommendations.map((item, index) => (
Expand All @@ -42,7 +45,7 @@ const Recommendations = ({ recommendations, handleListItemClick }) => {
opacity-0 group-hover:opacity-100 transition-opacity duration-200">
<div className="absolute bottom-0 left-0 right-0 p-2">
<motion.p
className="text-xs text-white/90 text-center line-clamp-2"
className="text-xs text-white text-center line-clamp-2"
initial={{ opacity: 0, y: 10 }}
whileHover={{ opacity: 1, y: 0 }}
>
Expand All @@ -52,18 +55,19 @@ const Recommendations = ({ recommendations, handleListItemClick }) => {
</div>
</div>
<div className="space-y-0.5">
<h3 className="text-xs font-medium text-white/80 line-clamp-1 group-hover:text-[#02c39a]
transition-colors"
<h3 className={`text-xs font-medium ${
isDarkMode ? 'text-white/80' : 'text-gray-800'
} line-clamp-1 group-hover:text-[#02c39a] transition-colors`}
>
{item.title || item.name}
</h3>
{(item.release_date || item.first_air_date) && (
<div className="flex items-center gap-1.5">
<p className="text-[10px] text-white/60">
<p className={`text-[10px] ${isDarkMode ? 'text-white/60' : 'text-gray-600'}`}>
{new Date(item.release_date || item.first_air_date).getFullYear()}
</p>
{item.vote_average > 0 && (
<div className="flex items-center gap-0.5 text-[10px] text-white/60">
<div className={`flex items-center gap-0.5 text-[10px] ${isDarkMode ? 'text-white/60' : 'text-gray-600'}`}>
<span>•</span>
<span className="text-[#02c39a]">{item.vote_average.toFixed(1)}</span>
<svg className="w-2.5 h-2.5 text-[#02c39a]" fill="currentColor" viewBox="0 0 20 20">
Expand Down
Loading