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 + 404 | 10 |
| Головна: популярні фільми + пошук | 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 |