mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(frontend/api): movie recommendations/similar request and frontend detail page update
This commit is contained in:
@@ -7,11 +7,22 @@ import Button from '../Common/Button';
|
||||
import MovieRequestModal from '../RequestModal/MovieRequestModal';
|
||||
import type { MediaRequest } from '../../../server/entity/MediaRequest';
|
||||
import axios from 'axios';
|
||||
import type { MovieResult } from '../../../server/models/Search';
|
||||
import Link from 'next/link';
|
||||
import Slider from '../Slider';
|
||||
import TitleCard from '../TitleCard';
|
||||
|
||||
interface MovieDetailsProps {
|
||||
movie?: MovieDetailsType;
|
||||
}
|
||||
|
||||
interface SearchResult {
|
||||
page: number;
|
||||
totalResults: number;
|
||||
totalPages: number;
|
||||
results: MovieResult[];
|
||||
}
|
||||
|
||||
enum MediaRequestStatus {
|
||||
PENDING = 1,
|
||||
APPROVED,
|
||||
@@ -30,6 +41,12 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
initialData: movie,
|
||||
}
|
||||
);
|
||||
const { data: recommended, error: recommendedError } = useSWR<SearchResult>(
|
||||
`/api/v1/movie/${router.query.movieId}/recommendations`
|
||||
);
|
||||
const { data: similar, error: similarError } = useSWR<SearchResult>(
|
||||
`/api/v1/movie/${router.query.movieId}/similar`
|
||||
);
|
||||
|
||||
const request = async () => {
|
||||
const response = await axios.post<MediaRequest>('/api/v1/request', {
|
||||
@@ -263,6 +280,97 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:flex md:items-center md:justify-between mb-4 mt-6">
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link
|
||||
href="/movie/[movieId]/recommendations"
|
||||
as={`/movie/${data.id}/recommendations`}
|
||||
>
|
||||
<a className="inline-flex text-xl leading-7 text-cool-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate items-center">
|
||||
<span>Recommendations</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="recommendations"
|
||||
isLoading={!recommended && !recommendedError}
|
||||
isEmpty={false}
|
||||
items={recommended?.results.map((title) => (
|
||||
<TitleCard
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
<div className="md:flex md:items-center md:justify-between mb-4 mt-6">
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link
|
||||
href="/movie/[movieId]/similar"
|
||||
as={`/movie/${data.id}/similar`}
|
||||
>
|
||||
<a className="inline-flex text-xl leading-7 text-cool-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate items-center">
|
||||
<span>Similar Titles</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="recommendations"
|
||||
isLoading={!similar && !similarError}
|
||||
isEmpty={false}
|
||||
items={similar?.results.map((title) => (
|
||||
<TitleCard
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
<div className="pb-8" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user