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
14 changes: 9 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { usePopMovies, useCurMovies, useSearchMovies } from './hooks/useMovies';
import { usePopularPeople } from './hooks/usePeople';
import { Sidebar } from './components/sidebar';
import { Section } from './components/Section';
import MovieList from './components/MovieList';
import { MovieList } from './components/MovieList';
import { PersonList } from './components/PersonList';
import './App.css';
import { useDebouncedValue } from './hooks/useDebouncedValue';
import './App.css';
import { TrendingPreview } from './components/TrendingPreview';

function App() {

Expand All @@ -26,16 +27,19 @@ function App() {
<main>
{isSearching ? (
<Section id="sok" title={`Søkeresultater for "${query}"`} isLoading={search.isLoading} error={search.error}>
{search.data && <MovieList movies={search.data.results} />}
{search.data && <MovieList movies={search.data} />}
</Section>
) : (
<>
<Section id="trendingPreview" title="" isLoading={current.isLoading} error={current.error}>
{current.data && <TrendingPreview movies={current.data}/>}
</Section>
<Section id="populaere" title="Populære filmer" isLoading={popular.isLoading} error={popular.error}>
{popular.data && <MovieList movies={popular.data.results} />}
{popular.data && <MovieList movies={popular.data} />}
</Section>

<Section id="nye-filmer" title="Nye filmer" isLoading={current.isLoading} error={current.error}>
{current.data && <MovieList movies={current.data.results} />}
{current.data && <MovieList movies={current.data} />}
</Section>

<Section id="skuespillere" title="Skuespillere" isLoading={people.isLoading} error={people.error}>
Expand Down
8 changes: 4 additions & 4 deletions src/api/tmdb.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Movie, Person, TmdbResponse, CreditsResponse } from '../types/tmdb';

// TOKEN er lagret i root/.env.local, denne må alle legge til manuelt selv
// og så må vi finne en løsning for å ha den tilgjengelig på serveren når vi
// får satt den opp senere.

// BASE_URL er lenken vi bruker i en API request, her til TMDB

// TOKEN er lagret i .env.local, denne må alle legge til manuelt selv
import type { Movie, Person, TmdbResponse, CreditsResponse } from '../types/tmdb';

const TOKEN = import.meta.env.VITE_TMDB_TOKEN; // v4 read access token

// BASE_URL er lenken vi bruker i en API request, her til TMDB
const BASE_URL = 'https://api.themoviedb.org/3';

async function tmdbFetch<T>(path: string, errorMessage: string): Promise<T> {
Expand Down
8 changes: 0 additions & 8 deletions src/components/Button.tsx

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMovieCredits } from "../hooks/useMovieCredits";
import "./Movie_card.css";
import "./MovieCard.css";

// Definerer hvilke props (data utenfra) komponenten forventer å motta,
// og hvilken type hver av dem skal ha.
Expand Down
9 changes: 3 additions & 6 deletions src/components/MovieList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Henter inn MovieCard-komponenten vår, slik at vi kan bruke den til å vise hver film.
import MovieCard from "./Movie_card";
import MovieCard from "./MovieCard";
import type { Movie } from "../types/tmdb";
import "./MovieList.css";

Expand All @@ -11,7 +11,7 @@ type MovieListProps = {
movies: Movie[];
};

function MovieList({ movies }: MovieListProps) {
export function MovieList({ movies }: MovieListProps) {
return (
// Ytre container for hele filmlisten, kan style'es med CSS senere
<div className="movie-list">
Expand Down Expand Up @@ -39,7 +39,4 @@ function MovieList({ movies }: MovieListProps) {
))}
</div>
);
}

// Eksporterer komponenten slik at App.tsx (eller en layout-komponent) kan bruke <MovieList />
export default MovieList;
}
Empty file added src/components/Section.css
Empty file.
71 changes: 71 additions & 0 deletions src/components/TrendingPreview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.hero {
position: relative;
width: 100%;
height: 30vh; /* adjust to taste, or set a fixed px value */
overflow: hidden;
border-radius: 1rem;
}

.backdrop {
width: 33.333%;
height: 100%;
object-fit: cover;
flex-shrink: 0;
}

.hero-title {
position: absolute;
left: 1.5rem;
bottom: 1.5rem;
color: white;
margin: 0;
z-index: 2;
cursor: pointer;
}

.hero-track {
display: flex;
width: 300%;
height: 100%;
}

.hero-zone {
position: absolute;
top: 0;
height: 100%;
width: 10%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 3;
user-select: none;
}

.hero-zone-left {
left: 0;
}

.hero-zone-middle {
left: 10%;
width: 80%;
cursor: pointer;
}

.hero-zone-right {
right: 0;
}

.hero-arrow {
display: inline-block;
/*transform: skewX(-15deg);*/
font-size: 2rem;
color: white;
opacity: 0.7;
transition: opacity 0.2s;
user-select: none;
}

.hero-zone:hover .hero-arrow {
opacity: 1;
}
70 changes: 70 additions & 0 deletions src/components/TrendingPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useState } from "react";
import type { Movie } from "../types/tmdb";
import "./TrendingPreview.css"

type TrendingPreviewProps = {
movies : Movie[];
};

export function TrendingPreview({ movies }: TrendingPreviewProps) {
const [index, setIndex] = useState(0);
const [offset, setOffset] = useState(0);
const [transitioning, setTransitioning] = useState(false);

const prevIndex = ( (index-1+movies.length) % movies.length );
const nextIndex = ( (index+1) % movies.length );
const movie = movies[index];

function handleClick( n: number ) {
if (transitioning) { return; }
setTransitioning(true);
setOffset(-n);

setTimeout(() => {
setIndex( (i) => ((i+n+movies.length) % movies.length) );
setOffset(0);
setTransitioning(false);
}, 400);
}

function openDetails() {
return;
}

return (
<div className="hero">
<div
className="hero-track"
style={{
transform: `translateX(${(offset - 1) * 33.3333}%)`,
transition: transitioning ? "transform 0.4s ease" : "none",
}}
>
<img
src={`https://image.tmdb.org/t/p/original${movies[prevIndex].backdrop_path}`}
className="backdrop"
/>
<img
src={`https://image.tmdb.org/t/p/original${movie.backdrop_path}`}
className="backdrop"
/>
<img
src={`https://image.tmdb.org/t/p/original${movies[nextIndex].backdrop_path}`}
className="backdrop"
/>
</div>

<h1 className="hero-title" onClick={openDetails}>{movie.title}</h1>

<div className="hero-zone hero-zone-left" onClick={() => handleClick(-1)}>
<span className="hero-arrow hero-arrow-left">{"❮"}</span>
</div>

<div className="hero-zone hero-zone-middle" onClick={openDetails} />

<div className="hero-zone hero-zone-right" onClick={() => handleClick(1)}>
<span className="hero-arrow hero-arrow-right">{"❯"}</span>
</div>
</div>
);
}
File renamed without changes.
4 changes: 3 additions & 1 deletion src/hooks/useMovies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ export function usePopMovies() {
return useQuery({
queryKey: ['movies', 'popular'],
queryFn: fetchPopularMovies,
select: (data) => data.results,
})
}

export function useCurMovies() {
return useQuery({
queryKey: ['movies', 'current'],
queryFn: fetchCurrentMovies,

select: (data) => data.results,
})
}

Expand All @@ -22,5 +23,6 @@ export function useSearchMovies(query: string) {
queryKey: ['movies', 'search', query],
queryFn: () => fetchSearchMovies(query),
enabled: query.trim().length > 0,
select: (data) => data.results,
})
}
25 changes: 25 additions & 0 deletions src/types/tmdb.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
export type Movie = {
id: number;
title: string;
overview: string;
backdrop_path: string | null;
poster_path: string | null;
vote_average: number;
release_date: string;
};

/*
{
"adult": false,
"backdrop_path": "/gMJngTNfaqCSCqGD4y8lVMZXKDn.jpg",
"genre_ids": [
28,
12,
878
],
"id": 640146,
"original_language": "en",
"original_title": "Ant-Man and the Wasp: Quantumania",
"overview": "Super-Hero partners Scott Lang and Hope van Dyne, along with with Hope's parents Janet van Dyne and Hank Pym, and Scott's daughter Cassie Lang, find themselves exploring the Quantum Realm, interacting with strange new creatures and embarking on an adventure that will push them beyond the limits of what they thought possible.",
"popularity": 8567.865,
"poster_path": "/ngl2FKBlU4fhbdsrtdom9LVLBXw.jpg",
"release_date": "2023-02-15",
"title": "Ant-Man and the Wasp: Quantumania",
"video": false,
"vote_average": 6.5,
"vote_count": 1886
},
*/
export type Person = {
id: number;
name: string;
Expand Down