Commit a98ca0cd authored by Daniel Puchala's avatar Daniel Puchala
Browse files

Merge branch 'milestone-3-fix'

parents 9dca574f 0fce097c
......@@ -17,11 +17,13 @@ export const Header = () => {
<p className="text-2xl">PA165 Movie Recommender Catalogue</p>
</Link>
{user === null ?
<Link to="/pa165/login" className="ml-auto h-[50%] px-4">
<Link to="/pa165/login" className="ml-auto flex h-[50%] px-4 gap-2">
<span className="self-center">Login</span>
<img className="h-full" src={Login} alt="Login"/>
</Link>
:
<button className="ml-auto h-[50%] px-4" onClick={onClick}>
<button className="flex ml-auto h-[50%] px-4 gap-2" onClick={onClick}>
<span className="self-center">Logout</span>
<img className="h-full" src={Logout} alt="Login"/>
</button>
}
......
......@@ -17,7 +17,6 @@ export const Login = () => {
navigate('/pa165/', { replace: true });
} else {
setIsError(true);
alert('Invalid credentials');
}
}
......@@ -25,7 +24,7 @@ export const Login = () => {
<div className="h-[100vh]">
<Header/>
<div className="grid place-items-center h-[90%]">
{isError && <div className="text-2xl text-center font-bold mt-auto text-red-900">Invalid credentials</div>}
{isError && <div className="text-3xl text-center font-bold mt-auto mb-4 text-red-600">Invalid credentials</div>}
<form onSubmit={handleSubmit}
className={`flex flex-col w-1/4 gap-3 border-2 border-black rounded-lg bg-slate-300 p-4 mb-auto ${isError || 'mt-auto'}`}>
<p className="text-2xl text-center font-bold">Login</p>
......
......@@ -11,15 +11,11 @@ import formatDuration from '../services/formatDuration';
import Review from './Review';
function getAverageRating(review: any) {
return (review.actingRating + review.ideaRating + review.scriptRating + review.musicRating + review.visualsEditRating) / 5
return (review.actingRating + review.ideaRating + review.scriptRating + review.musicRating + review.visualsEditRating) / 5;
}
export const Movie = () => {
const [ showReviews, setShowReviews ] = useState<boolean>(false);
const changeShowStatus = () => {
setShowReviews((prevState => !prevState));
};
const { register, handleSubmit, getValues, watch } = useForm();
watch();
......@@ -31,7 +27,7 @@ export const Movie = () => {
const reviewData = {
...data,
movieId: id,
userId: getUser()!.sub,
userId: getUser()!.sub
};
await instance.post('reviews', reviewData, { headers });
await mutateReviews();
......@@ -39,20 +35,14 @@ export const Movie = () => {
};
const { id } = useParams();
const { data: movie, error: movieError } = useSWR(`movies/${id}`)
const { data: reviews, error: reviewError, mutate: mutateReviews } = useSWR(`reviews/search/${id}`)
const { data: recommended, error: recommendedError } = useSWR(`movies/${id}/recommended`)
if (movieError) return <div>failed to load</div>;
if (!movie) return <div>loading...</div>;
const { data: movie, error: movieError } = useSWR(`movies/${id}`);
const { data: reviews, error: reviewError, mutate: mutateReviews } = useSWR(`reviews/search/${id}`);
const { data: recommended, error: recommendedError } = useSWR(`movies/${id}/recommended`);
if (reviewError) return <div>failed to load</div>;
if (!reviews) return <div>loading...</div>;
if (movieError || reviewError || recommendedError) return <div>failed to load</div>;
if (!movie || !reviews || !recommended) return <div>loading...</div>;
if (recommendedError) return <div>failed to load</div>;
if (!recommended) return <div>loading...</div>;
const recommendedMovies = recommended.slice(0, 5)
const recommendedMovies = recommended.slice(0, 5);
return (
<div>
......@@ -63,21 +53,25 @@ export const Movie = () => {
<div className="p-4 flex-shrink-0 h-full w-2/5">
<img className="h-full w-full" src={movie.poster} alt="Poster"/>
</div>
<div className="flex flex-col p-4">
<div className="flex flex-col p-4 w-full">
<p className="text-2xl font-bold">{movie.name}</p>
<p ><b>Genres: </b>
{movie.genres.slice(0, -1).map((genre: any) => `${genre}, `)}
{movie.genres.slice(-1).map(((genre: any) => `${genre}`))}
</p>
{movie.genres &&
<p><b>Genres: </b>
{movie.genres.slice(0, -1).map((genre: any) => `${genre}, `)}
{`${movie.genres.at(-1)}`}
</p>
}
<p><b>Duration: </b>{formatDuration(movie.duration)}</p>
<p>{movie.description}</p>
<p className="text-xl mt-auto"><b>Director: </b>{movie.director.name}</p>
<p className="text-xl"><b>Actors: </b>
{movie.actors.slice(0, -1).map((actor: any) => `${actor.name}, `)}
{movie.actors.slice(-1).map((actor: any) => `${actor.name}`)}
</p>
{movie.actors &&
<p className="text-xl"><b>Actors: </b>
{movie.actors.slice(0, -1).map((actor: any) => `${actor.name}, `)}
{`${movie.actors.at(-1).name}`}
</p>
}
<button className="w-max p-4 self-center bg-blue-600 border-2 rounded-3xl border-slate-900"
onClick={changeShowStatus}>
onClick={() => setShowReviews((prevState => !prevState))}>
{showReviews ? 'Show recommended movies' : 'Show reviews'}
</button>
</div>
......@@ -87,7 +81,8 @@ export const Movie = () => {
<div className={`h-full ${showReviews && 'hidden'}`}>
<p className="text-2xl text-center font-bold">Recommended movies</p>
<div className="flex flex-row flex-wrap p-4">
{recommendedMovies.map((movie: any) => <MovieCard key={movie.id} {...movie} mode={MovieCardMode.Recommend}/>)}
{recommendedMovies.map((movie: any) => <MovieCard key={movie.id} {...movie}
mode={MovieCardMode.Recommend}/>)}
</div>
</div>
<div className={`h-full flex flex-col overflow-hidden ${showReviews || 'hidden'}`}>
......@@ -106,42 +101,43 @@ export const Movie = () => {
)}
</div>
{getUser() &&
<form
onSubmit={handleSubmit(sendReview)}
className="flex flex-col p-2 m-2 mt-auto bg-slate-300 border-4 rounded-3xl border-slate-900"
>
<span className="text-2xl text-center font-bold">Write your review</span>
<label className="flex justify-between">
<span className="font-bold">Script: {getValues('scriptRating')}</span>
<input type="range" min={1} max={10} {...register('scriptRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Idea: {getValues('ideaRating')}</span>
<input type="range" min={1} max={10} {...register('ideaRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Visual edits: {getValues('visualsEditRating')}</span>
<input type="range" min={1} max={10} {...register('visualsEditRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Music: {getValues('musicRating')}</span>
<input type="range" min={1} max={10} {...register('musicRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Acting: {getValues('actingRating')}</span>
<input type="range" min={1} max={10} {...register('actingRating', { required: true })}/>
</label>
<label>
<form
onSubmit={handleSubmit(sendReview)}
className="flex flex-col p-2 m-2 mt-auto bg-slate-300 border-4 rounded-3xl border-slate-900"
>
<span className="text-2xl text-center font-bold">Write your review</span>
<label className="flex justify-between">
<span className="font-bold">Script: {getValues('scriptRating')}</span>
<input type="range" min={1} max={10} {...register('scriptRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Idea: {getValues('ideaRating')}</span>
<input type="range" min={1} max={10} {...register('ideaRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Visual edits: {getValues('visualsEditRating')}</span>
<input type="range" min={1} max={10} {...register('visualsEditRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Music: {getValues('musicRating')}</span>
<input type="range" min={1} max={10} {...register('musicRating', { required: true })}/>
</label>
<label className="flex justify-between">
<span className="font-bold">Acting: {getValues('actingRating')}</span>
<input type="range" min={1} max={10} {...register('actingRating', { required: true })}/>
</label>
<label>
<textarea
className="w-full border-2 border-slate-900"
{...register('text', { required: true, minLength: 1 })}
placeholder={"Write your review here."}
className="w-full border-2 border-slate-900"
{...register('text', { required: true, minLength: 1 })}
placeholder={'Write your review here.'}
/>
</label>
<button type="submit" className="w-max p-2 self-center bg-blue-600 border-2 rounded-3xl border-slate-900">
Send review
</button>
</form>
</label>
<button type="submit"
className="w-max p-2 self-center bg-blue-600 border-2 rounded-3xl border-slate-900">
Send review
</button>
</form>
}
</div>
......
......@@ -3,12 +3,14 @@ import Header from './Header';
export const PageNotFound = () => {
return (
<>
<Header />
<div>
Page not found
<Header/>
<div className="flex h-[90vh] justify-center">
<span className="mt-10 text-3xl">
<b>Page not found</b>
</span>
</div>
</>
)
}
);
};
export default PageNotFound;
......@@ -29,13 +29,13 @@ export const Review = ({id, userId, text, averageRating, userName, mutate}: Revi
<div className="border-solid border-4 border-slate-900 bg-slate-300 w-full h-full p-2 ">
<div className="flex justify-between font-bold">
<p>Username: {userName}</p>
<p>Average Rating: {averageRating}</p>
{(user?.role === 'ADMIN' || user?.sub == userId) &&
(<button onClick={deleteReview} className="border-solid border-2 rounded-lg border-slate-900 p-1 bg-red-600">
Delete
</button>
)
}
<p>Average Rating: {averageRating}</p>
</div>
<p>{text}</p>
</div>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment