Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ function App() {
<Button text="Current" onClick={() => setView('current')} />
</div>
)


}

export default App
51 changes: 51 additions & 0 deletions src/components/MovieList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Henter inn MovieCard-komponenten vår, slik at vi kan bruke den til å vise hver film.
import MovieCard from "./Movie_card";
// Henter inn hooken som henter populære filmer fra TMDB via TanStack Query.
import { usePopMovies } from "../hooks/usePopMovies";

// MovieList har ansvaret for å hente filmene og vise dem som en liste av MovieCard.
// MovieCard selv vet ingenting om TMDB eller fetching, den bare mottar props.
function MovieList() {
// useQuery (inni usePopMovies) returnerer et objekt med bl.a. data, isLoading og error.
// Vi destrukturerer ut akkurat de tre vi trenger her.
const { data, isLoading, error } = usePopMovies();

// Mens dataene fortsatt hentes fra API-et, viser vi en enkel lastetekst
// i stedet for en tom/ødelagt liste.
if (isLoading) {
return <p>Laster filmer...</p>;
}

// Hvis noe gikk galt med kallet (f.eks. nettverksfeil eller ugyldig token),
// viser vi en enkel feilmelding i stedet for å krasje siden.
if (error) {
return <p>Klarte ikke hente filmer akkurat nå.</p>;
}

return (
// Ytre container for hele filmlisten, kan style'es med CSS senere
<div className="movie-list">
{/* data er svaret fra TMDB, som har en "results"-liste med filmobjekter.
?. brukes i tilfelle data enda ikke har kommet (undefined). */}
{data?.results.map((movie: any) => (
// .map() går gjennom hver film og returnerer én MovieCard per film.
// key={movie.id} er påkrevd av React for å holde styr på hvert element i lista.
<MovieCard
key={movie.id}
// TMDB sitt feltnavn er "title", som passer direkte med vår prop
title={movie.title}
// TMDB gir bare en delsti (poster_path), så vi setter sammen full bilde-URL selv
posterUrl={`https://image.tmdb.org/t/p/w200${movie.poster_path}`}
// TMDB sin vote_average går fra 0-10, vi ganger med 10 for å få prosent (0-100)
rating={Math.round(movie.vote_average * 10)}
// Skuespillere ligger ikke i dette API-svaret (krever eget kall til /credits),
// så vi sender en tom liste som placeholder inntil videre
actors={[]}
/>
))}
</div>
);
}

// Eksporterer komponenten slik at App.tsx (eller en layout-komponent) kan bruke <MovieList />
export default MovieList;
42 changes: 42 additions & 0 deletions src/components/Movie_card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Definerer hvilke props (data utenfra) komponenten forventer å motta,
// og hvilken type hver av dem skal ha.
interface MovieCardProps {
title: string; // Filmens tittel, skal vises som overskrift
posterUrl: string; // URL til filmplakat-bildet, brukes i <img>
rating: number; // Terningkast/prosent (0-100), f.eks. vote_average * 10 fra TMDB
actors: string[]; // Liste med skuespillernavn, vises samlet som tekst
}

// Selve komponenten: en funksjon som tar imot props (destrukturert direkte i parameterlista)
// og returnerer JSX-en som beskriver hvordan filmkortet skal se ut.
function MovieCard({ title, posterUrl, rating, actors }: MovieCardProps) {
return (
// Ytterste container for hele kortet, styles med CSS-klassen "movie-card"
<div className="movie-card">
{/* Viser filmplakaten. alt={title} sørger for skjermlesere kan beskrive bildet */}
<img className="movie-card__poster" src={posterUrl} alt={title}/>
{/* Wrapper rundt all tekstinfoen under/ved siden av bildet */}
<div className="movie-card__info">
{/* Rad med tittel og rating side om side */}
<div className="movie-card__header">
{/* Tittelen settes inn med {title}, som henter verdien fra props */}
<h3 className="movie-card__title">{title}</h3>
{/* Rating vises som prosent, {rating} settes inn fra props */}
<span className="movie-card__rating">{rating}%</span>
</div>
{/* actors er en array, .join(", ") slår den sammen til én tekststreng med komma mellom */}
<p className="movie-card__actors">{actors.join(", ")}</p>
</div>
</div>
);
}

// Eksporterer komponenten slik at den kan importeres og brukes i andre filer,
// f.eks. i en liste over filmer (App.tsx eller en MovieList-komponent).
export default MovieCard;

// Eksempel på hvordan komponenten brukes med placeholder-data.
// Dette fjernes/erstattes når du henter ekte data fra TMDB.
// <MovieCard
// title="Placeholder-tittel"
//
2 changes: 1 addition & 1 deletion src/hooks/usePopMovies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useQuery } from '@tanstack/react-query'
import { fetchCurrentMovies, fetchPopularMovies } from '../api/tmdb'

export function useMovies() {
export function usePopMovies() {
return useQuery({
queryKey: ['movies', 'popular'],
queryFn: fetchPopularMovies,
Expand Down