Skip to content

Repository files navigation

Simple Cinema

Setup

Requires Node.js 20.19+ and the TMDB API key supplied with the assignment.

  1. Run npm install.
  2. Copy .env.example to .env.
  3. Replace the placeholder value in .env with the supplied TMDB key.
  4. Run npm run dev.

The key is used by the browser client and must never be committed. .env is gitignored; .env.example is the safe template.

What it does

Simple Cinema is a one-page TMDB browser. It fetches the first page of discover results, lets the user filter by genre and sort by rating or release date, and renders the results as a responsive poster grid.

Filtering and sorting happen in the TMDB request, not over the 20 movies already returned. Every request also requires at least 500 ratings so changing the sort order rearranges a meaningful, consistent result set.

Features

  • Genre options fetched from TMDB and sorted alphabetically.
  • Server-side genre filtering and rating or release-date sorting.
  • Responsive movie grid with poster, title, rating, and release year.
  • Overview reveal available through pointer hover and keyboard focus.
  • Previous results remain visible and dimmed while a new query loads.
  • Concise loading, empty, and error messages.
  • Safe fallbacks for missing posters, release dates, overviews, and result arrays.
  • Request cancellation that prevents stale responses from replacing newer results.

Architecture

Path Purpose
src/App.jsx Page shell and heading.
src/lib/http.js Generic JSON request handling with no TMDB knowledge.
src/styles/tokens.css Semantic colors, spacing, radius, motion, and global resets.
src/features/movies/constants.js TMDB endpoints, vote floor, sort options, and default query.
src/features/movies/api/tmdb.js Discover URL construction, authenticated requests, genres, and poster URLs.
src/features/movies/hooks/useMovies.js Movie request lifecycle, cancellation, stale-result retention, and derived pending state.
src/features/movies/hooks/useGenres.js One-time genre reference-data request.
src/features/movies/components/MoviesPage.jsx Query ownership and loading, empty, error, and result rendering.
src/features/movies/components/QueryControls.jsx Accessible genre and sort controls.
src/features/movies/components/MovieGrid.jsx Responsive result list and stale state.
src/features/movies/components/MovieCard.jsx Nullable-field guards and the hover/focus overview interaction.

The movies feature exposes only MoviesPage through src/features/movies/index.js. API, hooks, and components remain private to the feature.

Decisions

Decision Reason
Vite instead of Next.js This is one client-rendered page with no routing or server-rendering need.
Plain JavaScript instead of TypeScript It keeps the take-home focused on product behavior and limits one-night setup overhead. A production version would use TypeScript.
Native fetch hook instead of a data-fetching library One movie endpoint does not justify another dependency. The custom hook makes cancellation and stale-response protection explicit.
CSS Modules and custom properties instead of a CSS framework The responsive grid, interaction states, and design tokens remain visible and locally scoped.
TMDB-side filtering and sorting Reordering one returned page would not produce the true top 20 across TMDB's full catalogue.
A 500-rating floor on every request It prevents barely rated movies from dominating “Top rated” and keeps result membership consistent across sort orders.
Query state stays in React Refreshing resets two controls, an acceptable tradeoff for this assignment. A router, URL synchronization, or storage would add lifecycle and validation code the brief does not require.
Text loading, empty, and error states They prevent blank screens without adding skeleton components, automatic retries, retry controls, or a dedicated API-key screen. Setup remains in this README.
No alternate layout or rating-based card sizing A single consistent grid is easier to scan and keeps optional display preferences out of scope.
No justfile The assignment explicitly requires the standard npm workflow, and the scripts in package.json cover every project command.

Commands

Command Purpose
npm run dev Start the Vite development server.
npm run test Run the Vitest and Testing Library suite once.
npm run lint Run ESLint.
npm run format:check Verify Prettier formatting.
npm run build Create the production build.

What I would add next

  • Put shareable filter state in the URL once preserving and linking views matters.
  • Move the API key behind a server endpoint in a production application.
  • Adopt TypeScript and a data-fetching library as the API surface grows.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages