web / frontend /src /pages /SearchPage.tsx
Chandima Prabhath
Track bun.lockb with Git LFS
cc2caf9
raw
history blame
6.45 kB
import React, { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useToast } from '@/hooks/use-toast';
import { searchAPI } from '../lib/search-api';
import PageHeader from '../components/PageHeader';
import ContentGrid from '../components/ContentGrid';
import ContentCard from '../components/ContentCard';
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Loader2 } from 'lucide-react';
const SearchPage = () => {
const [searchParams] = useSearchParams();
const query = searchParams.get('q') || '';
const [searchResults, setSearchResults] = useState<{
movies: string[];
shows: string[];
episodes: {
series: string;
title: string;
path: string;
season: string;
}[];
}>({
movies: [],
shows: [],
episodes: []
});
const [loading, setLoading] = useState(false);
const [activeTab, setActiveTab] = useState('all');
const { toast } = useToast();
useEffect(() => {
const fetchSearchResults = async () => {
if (!query) return;
try {
setLoading(true);
const results = await searchAPI.search(query);
setSearchResults({
movies: results.films || [],
shows: results.series || [],
episodes: results.episodes || []
});
} catch (error) {
console.error('Search error:', error);
toast({
title: "Search Failed",
description: "Unable to perform search. Please try again.",
variant: "destructive"
});
} finally {
setLoading(false);
}
};
fetchSearchResults();
}, [query, toast]);
const getTotalResultsCount = () => {
return searchResults.movies.length + searchResults.shows.length + searchResults.episodes.length;
};
const renderMovieResults = () => {
if (searchResults.movies.length === 0) {
return <p className="text-center text-gray-400 my-8">No movies found matching "{query}"</p>;
}
return (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{searchResults.movies.map((title, index) => (
<ContentCard
key={`movie-${title}-${index}`}
type="movie"
title={title.split('/')[1]}
prefetchData={true}
/>
))}
</div>
);
};
const renderShowResults = () => {
if (searchResults.shows.length === 0) {
return <p className="text-center text-gray-400 my-8">No TV shows found matching "{query}"</p>;
}
return (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{searchResults.shows.map((title, index) => (
<ContentCard
key={`show-${title}-${index}`}
type="tvshow"
title={title}
prefetchData={true}
/>
))}
</div>
);
};
const renderEpisodeResults = () => {
if (searchResults.episodes.length === 0) {
return <p className="text-center text-gray-400 my-8">No episodes found matching "{query}"</p>;
}
return (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
{searchResults.episodes.map((episode, index) => (
<div key={`episode-${index}`} className="bg-theme-card p-4 rounded-md hover:bg-theme-card-hover transition-colors">
<h3 className="font-semibold">{episode.title}</h3>
<p className="text-sm text-gray-400">
{episode.series} • Season {episode.season}
</p>
</div>
))}
</div>
);
};
return (
<div className="container mx-auto px-4 py-8">
<PageHeader
title={query ? `Search Results for "${query}"` : "Search"}
subtitle={query ? `${getTotalResultsCount()} results found` : "Enter a search term in the search box"}
/>
{loading ? (
<div className="flex justify-center items-center py-12">
<Loader2 className="w-12 h-12 animate-spin text-theme-primary/70" />
</div>
) : query ? (
<Tabs defaultValue={activeTab} onValueChange={setActiveTab} className="w-full mt-6">
<TabsList className="mb-6">
<TabsTrigger value="all">
All Results ({getTotalResultsCount()})
</TabsTrigger>
<TabsTrigger value="movies">
Movies ({searchResults.movies.length})
</TabsTrigger>
<TabsTrigger value="shows">
TV Shows ({searchResults.shows.length})
</TabsTrigger>
<TabsTrigger value="episodes">
Episodes ({searchResults.episodes.length})
</TabsTrigger>
</TabsList>
<TabsContent value="all">
{getTotalResultsCount() === 0 ? (
<p className="text-center text-gray-400 my-8">No results found matching "{query}"</p>
) : (
<>
{searchResults.movies.length > 0 && (
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">Movies</h2>
{renderMovieResults()}
</div>
)}
{searchResults.shows.length > 0 && (
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">TV Shows</h2>
{renderShowResults()}
</div>
)}
{searchResults.episodes.length > 0 && (
<div>
<h2 className="text-xl font-semibold mb-4">Episodes</h2>
{renderEpisodeResults()}
</div>
)}
</>
)}
</TabsContent>
<TabsContent value="movies">
{renderMovieResults()}
</TabsContent>
<TabsContent value="shows">
{renderShowResults()}
</TabsContent>
<TabsContent value="episodes">
{renderEpisodeResults()}
</TabsContent>
</Tabs>
) : (
<div className="text-center py-12">
<p className="text-gray-400">Enter a search term to find movies, TV shows, and episodes.</p>
</div>
)}
</div>
);
};
export default SearchPage;