View on GitHub

評価値の取得

Home

評価値の取得

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 にアクセスしてください。

映画リスト上で評価値を更新してください。ページを切り替えても更新結果が維持されています。ただし、現時点では、ユーザ依存の処理を実装していないため、映画詳細ページを表示しても、ユーザの与えた評価値は表示されません。