評価値の取得
API
評価値取得 API
src/frontend/src/api/ratings/getRating.ts
import { ApiContext, Rating } from "@/types/data";
import { ERROR_MESSAGES } from "@/constants";
import { fetcher } from "@/utils";
const context: ApiContext = {
apiRootUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
};
/**
* 評価値取得API
* @param movieId - 映画ID
* @returns rating - 評価値
*/
const getRating = async (movieId: number): Promise<{ rating: Rating }> => {
const access =
typeof window !== "undefined" ? localStorage.getItem("access") : null;
if (!access) throw new Error(ERROR_MESSAGES.USER_NOT_AUTHENTICATED);
const url = `${context.apiRootUrl?.replace(/\/$/g, "")}/online/ratings/?movie_id=${movieId}`;
const headers: Record<string, string> = {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Bearer ${access}`,
};
return await fetcher(url, {
method: "GET",
headers: headers,
cache: "no-store",
});
};
export default getRating;
コンポーネント
映画カードコンポーネント
src/frontend/src/app/components/ui/card/CardMovie.tsx
...(略)...
import { Movie, User } from '@/types/data';
import { STYLES, MESSAGES } from '@/constants';
import postRating from '@/api/ratings/postRating';
import getRating from '@/api/ratings/getRating'; // <- 追加
import StarRating from '../rating/StarRating';
interface Props {
movie: Movie;
user?: User | null;
handleRatingClick: (movie: Movie) => void; // <- 追加
}
/**
* 映画カードコンポーネント
*/
const CardMovie = (props: Props) => {
...(略)...
const handleRatingClick = async (rating: number) => {
try {
await postRating(props.movie.movie_id, rating);
// ↓追加
const { rating: rating_ } = await getRating(props.movie.movie_id);
const movie_: Movie = {
...props.movie,
rating: rating_,
};
props.handleRatingClick(movie_);
// ↑追加
} catch (e) {
console.error('Failed to post rating:', e);
}
};
...(略)...
};
export default CardMovie;
映画リストコンポーネント
src/frontend/src/app/components/ui/list/ListMovie.tsx
...(略)...
/**
* 映画リストコンポーネント
*/
const ListMovie = (props: Props) => {
...(略)...
/**
* ページ変更ハンドラ
* @param page - 移動先のページ番号
*/
const handlePageChange = useCallback(
...(略)...
);
// ↓追加
const handleRatingClick = useCallback((movie: Movie) => {
setMovies((prev) => prev.map((m) => (m.movie_id === movie.movie_id ? movie : m)));
}, []);
// ↑追加
...(略)...
return (
<>
<div className={`${STYLES.LIST_MOVIE_LABEL_PHRASE}`}>{props.phrase}</div>
<div className={`${STYLES.LIST_MOVIE}`}>
...(略)...
<div ref={containerRef} className={`${STYLES.LIST_MOVIE_INSIDE}`}>
{currentMovies.map((movie, index) => (
<CardMovie
movie={movie}
user={props.user}
handleRatingClick={handleRatingClick} // <- 追加
key={movie.movie_id}
/>
))}
</div>
...(略)...
</div>
</>
);
};
export default ListMovie;
ブラウザで下記 URL にアクセスしてください。
映画リスト上で評価値を更新してください。ページを切り替えても更新結果が維持されています。ただし、現時点では、ユーザ依存の処理を実装していないため、映画詳細ページを表示しても、ユーザの与えた評価値は表示されません。