Вивчай
Домашнє завдання #23 ·
балівintermediate

FilmBox — додаток для перегляду фільмів

Фінальний проект блоку React. Побудуй повноцінний багатосторінковий додаток для пошуку фільмів, що використовує всі вивчені концепції: компоненти, state, effects, context та routing.


Підготовка

npm create vite@latest filmbox -- --template react-ts
cd filmbox
npm install react-router-dom
npm run dev

API

Використовуй TMDB API — безкоштовна реєстрація, отримаєш API key.

Основні ендпоінти:

ЕндпоінтURL
Популярніhttps://api.themoviedb.org/3/movie/popular?api_key=KEY
Пошукhttps://api.themoviedb.org/3/search/movie?api_key=KEY&query=TERM
Деталіhttps://api.themoviedb.org/3/movie/{id}?api_key=KEY
Зображенняhttps://image.tmdb.org/t/p/w500{poster_path}
Порада

API key зберігай у файлі .env: VITE_TMDB_KEY=твій_ключ. Доступ через import.meta.env.VITE_TMDB_KEY. Не забудь додати .env в .gitignore.


Завдання

1. Сторінки та routing

/              → HomePage     (популярні фільми + пошук)
/movie/:id     → MoviePage    (деталі фільму)
/favorites     → FavoritesPage (збережені фільми)
*              → NotFound      (404)

Layout зі спільним Header (логотип, навігація, кількість улюблених) та Footer.

2. Головна сторінка

  • При завантаженні — показати популярні фільми (сітка карток)
  • Поле пошуку: при введенні тексту завантажуються результати пошуку (debounce або пошук по Enter)
  • Індикатор завантаження під час fetch
  • Обробка помилок: якщо API не відповідає — показати повідомлення

3. Картка фільму (MovieCard)

Props: movie (title, poster, rating, year, id).

  • Постер фільму (або заглушка, якщо немає)
  • Назва, рік випуску
  • Рейтинг (зірочки або число з кольором: зелений > 7, жовтий > 5, червоний < 5)
  • Кнопка "В улюблені" (серце) — toggle
  • Клік на картку → перехід на /movie/:id

4. Сторінка фільму

  • Завантажити деталі через useParams + useEffect
  • Великий постер, назва, рік, рейтинг
  • Опис (overview)
  • Жанри (бейджики)
  • Кнопка "В улюблені"
  • Кнопка "Назад" (useNavigate)

5. FavoritesContext

Контекст для управління списком улюблених фільмів:

  • favorites: Movie[]
  • addFavorite(movie), removeFavorite(id), isFavorite(id)
  • Збереження в localStorage — улюблені зберігаються між сесіями
  • В Header показується кількість: "Улюблені (3)"

6. Сторінка Favorites

  • Список збережених фільмів (ті ж MovieCard)
  • Якщо список порожній — повідомлення "У вас ще немає улюблених фільмів" з посиланням на головну
  • Кнопка "Очистити все"

Структура проекту

src/
├── components/
│   ├── MovieCard.tsx
│   ├── SearchBar.tsx
│   ├── Loader.tsx
│   ├── Layout.tsx
│   └── Rating.tsx
├── pages/
│   ├── HomePage.tsx
│   ├── MoviePage.tsx
│   ├── FavoritesPage.tsx
│   └── NotFound.tsx
├── context/
│   └── FavoritesContext.tsx
├── types/
│   └── movie.ts
├── App.tsx
└── main.tsx

Бонус

  • Пагінація: кнопки "Попередня / Наступна" для результатів пошуку (TMDB API підтримує &page=2)
  • Жанри-фільтри: завантажити список жанрів з API, фільтрувати фільми за жанром
  • Темна/світла тема через ThemeContext (використай з ДЗ #22)
  • Анімації переходів між сторінками
  • "Схожі фільми" на сторінці фільму (endpoint: /movie/{id}/similar)

Критерії оцінки

КритерійБали
Routing: 4 сторінки + Layout + 40410
Головна: популярні фільми + пошук15
MovieCard компонент з props (poster, title, rating, heart)10
Сторінка фільму (useParams + useEffect + деталі)15
FavoritesContext (add/remove/isFavorite + localStorage)15
Сторінка Favorites (список + порожній стан)10
Loading/Error стани10
Стилізація (responsive grid, рейтинг, бейджики жанрів)10
TypeScript типи (Movie, API responses)5
Бонус: Пагінація / Жанри / Тема / Анімації / Схожі фільми+20