View on GitHub

映画カードへの評価値コンポーネントの追加

Home

映画カードへの評価値コンポーネントの追加

定数の定義

src/frontend/src/constants/styles.ts

/**
 * スタイル関連の定数
 */
export const STYLES = {
  ......
  // 映画カード関連
  ......
  MOVIE_LABEL_TITLE: `line-clamp-2 text-sm font-bold break-words`,
  MOVIE_STAR_WIDTH: 24, // <- 追加
  ......
} as const;

コンポーネント

映画カードコンポーネント

src/frontend/src/app/components/ui/card/CardMovie.tsx

......
import { Movie, User } from "@/types/data"; // <- Userを追加
import { STYLES, MESSAGES } from "@/constants";

import StarRating from '../rating/StarRating'; // <- 追加

interface Props {
  movie: Movie;
  user?: User | null; // <- 追加
}

/**
 * 映画カードコンポーネント
 */
const CardMovie = (props: Props) => {
  ......
  return (
    <article className={`${STYLES.MOVIE_CARD}`} key={props.movie.movie_id}>
      ...(略)...
      <div className={`${STYLES.MOVIE_INFO}`}>
        <div className={`${STYLES.MOVIE_LABEL_TITLE}`}>{props.movie.title}</div>
      </div>
      {/* ↓追加 */}
      {props.user ? (
        <StarRating starWidth={STYLES.MOVIE_STAR_WIDTH} rating={props.movie.rating?.rating!} />
      ) : (
        <></>
      )}
      {/* ↑追加 */}
    </article>
  );
};

export default CardMovie;

映画リストコンポーネント

src/frontend/src/app/components/ui/list/ListMovie.tsx

......
import { Movie, User } from "@/types/data"; // <- Userを追加
import { STYLES } from "@/constants";
......
interface Props {
  phrase: string;
  user?: User | null; // <- 追加
  movies: Movie[];
}

/**
 * 映画リストコンポーネント
 */
const ListMovie = (props: Props) => {
  ......
  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} key={movie.movie_id} /> // <- userを追加
          ))}
        </div>
        ...(略)...
      </div>
    </>
  );
};

export default ListMovie;

本日のおすすめ映画リストコンポーネント

src/frontend/src/app/components/ui/list/ListMovieDaily.tsx

......
import { Movie, User } from "@/types/data"; // <- Userを追加
import { STYLES, ERROR_MESSAGES } from "@/constants";
import getMovies from "@/api/movies/getMovies";
import getMyAccount from "@/api/auth/getMyAccount"; // <- 追加
......
/**
 * 本日のおすすめ映画リストコンポーネント
 */
const ListMovieDaily = () => {
  const [loading, setLoading] = useState(true);
  const [loadingUser, setLoadingUser] = useState(true); // <- 追加
  const [user, setUser] = useState<User | null>(null); // <- 追加
  const [movies, setMovies] = useState<Movie[]>([]);

  const phrase = STYLES.LIST_MOVIE_DAILY_PHRASE;

  useEffect(() => {
    const load = async () => {
      // ↓追加
      try {
        const user_ = await getMyAccount();
        setUser(user_);
      } catch (e) {
        setUser(null);
      } finally {
        setLoadingUser(false);
      }
      // ↑追加

      try {
        const { movies: movies_ } = await getMovies();
        setMovies(movies_);
      } catch (e) {
        console.error(ERROR_MESSAGES.MOVIE_GET_FAILED, e);
        setMovies([]);
      } finally {
        setLoading(false);
      }
    };
    load();
  }, []);
  ......
  return (
    <>
      <ListMovie
        phrase={phrase}
        user={loadingUser ? null : user}  // <- 追加
        movies={movies}
      />
    </>
  );
};

export default ListMovieDaily;

実行確認

ブラウザで下記 URL にアクセスしてください。

サインインすると、映画リスト内の各映画カードに評価値コンポーネントが表示されます。評価値コンポーネント上で任意の評価値をクリックすると、その評価値までのスターが黄色く表示されます。ただし、現時点では、評価値は記憶されないため、ブラウザを更新したり、ページを切り替えたりすると元に戻ります。また、現時点では、ユーザ情報は評価値コンポーネントの表示/非表示の判定のために参照しているだけですので、ユーザ依存の評価値は取得できません。