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
41 changes: 28 additions & 13 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,48 @@
import { usePopMovies, useCurMovies } from './hooks/useMovies';
import { useState } from 'react';
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 { PersonList } from './components/PersonList';
import './App.css';
import { useDebouncedValue } from './hooks/useDebouncedValue';

function App() {

const [query, setQuery] = useState('');

const popular = usePopMovies()
const current = useCurMovies()
const people = usePopularPeople()
const debouncedQuery = useDebouncedValue(query, 400);
const search = useSearchMovies(debouncedQuery)
const isSearching = query.trim().length > 0;

return (
<div className="page">
<Sidebar />
<Sidebar onSearch={setQuery} searchValue={query} />

<main>
<Section id="populaere" title="Populære filmer" isLoading={popular.isLoading} error={popular.error}>
{popular.data && <MovieList movies={popular.data.results} />}
</Section>

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

<Section id="skuespillere" title="Skuespillere" isLoading={people.isLoading} error={people.error}>
{people.data && <PersonList people={people.data.results} />}
</Section>
{isSearching ? (
<Section id="sok" title={`Søkeresultater for "${query}"`} isLoading={search.isLoading} error={search.error}>
{search.data && <MovieList movies={search.data.results} />}
</Section>
) : (
<>
<Section id="populaere" title="Populære filmer" isLoading={popular.isLoading} error={popular.error}>
{popular.data && <MovieList movies={popular.data.results} />}
</Section>

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

<Section id="skuespillere" title="Skuespillere" isLoading={people.isLoading} error={people.error}>
{people.data && <PersonList people={people.data.results} />}
</Section>
</>
)}
</main>

<div className="page-spacer" aria-hidden="true"></div>
Expand Down
6 changes: 5 additions & 1 deletion src/api/tmdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ export function fetchPopularPeople(): Promise<TmdbResponse<Person>> {
return tmdbFetch('/person/popular?language=en-US&page=1', 'Klarte ikke hente skuespillere...');
}

export function fetchSearchMovies(query: string): Promise<TmdbResponse<Movie>> {
return tmdbFetch(`/search/movie?query=${encodeURIComponent(query)}&language=en-US&page=1`, 'Søket feilet...');
}

export function fetchMovieCredits(movieId: number): Promise<CreditsResponse> {
return tmdbFetch<CreditsResponse>(
`/movie/${movieId}/credits?language=en-US`,
'Klarte ikke hente skuespillere...',
);
}
}
20 changes: 16 additions & 4 deletions src/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './sidebar.css';

type SidebarProps = {
onSearch?: (query: string) => void;
searchValue?: string;
};

//under kommer seksjonene i midtkolonnen som sidebaren skal kunne hoppe mellom
Expand All @@ -12,7 +13,7 @@ const sections = [
{ id: "skuespillere", label: "Skuespillere"},
];

export function Sidebar({onSearch}: SidebarProps) {
export function Sidebar({onSearch, searchValue}: SidebarProps) {
return (

<aside className="sidebar">
Expand All @@ -25,16 +26,27 @@ export function Sidebar({onSearch}: SidebarProps) {
id="movie-search"
type="search"
placeholder="Søk..."
value={searchValue ?? ''}
onChange={(e) => onSearch?.(e.target.value)}
/>
</div>
<nav aria-label="Innhold på siden">
<ul className="sidebar-nav">
{sections.map((section) =>(
<li key={section.id}>

<a href={`#${section.id}`} >{section.label}</a>
</li>
<a
href={`#${section.id}`}
onClick={(e) => {
e.preventDefault();
onSearch?.('');
setTimeout(() => {
document.getElementById(section.id)?.scrollIntoView({ behavior: 'smooth' });
}, 0);
}}
>
{section.label}
</a>
</li>
))}
</ul>
</nav>
Expand Down
15 changes: 15 additions & 0 deletions src/hooks/useDebouncedValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useState, useEffect } from 'react';

export function useDebouncedValue<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);

useEffect(() => {
const timeoutId = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => clearTimeout(timeoutId);
}, [value, delay]);

return debouncedValue;
}
10 changes: 9 additions & 1 deletion src/hooks/useMovies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// hooks/useMovies.ts
import { useQuery } from '@tanstack/react-query'
import { fetchCurrentMovies, fetchPopularMovies } from '../api/tmdb'
import { fetchCurrentMovies, fetchPopularMovies, fetchSearchMovies } from '../api/tmdb'

export function usePopMovies() {
return useQuery({
Expand All @@ -15,4 +15,12 @@ export function useCurMovies() {
queryFn: fetchCurrentMovies,

})
}

export function useSearchMovies(query: string) {
return useQuery({
queryKey: ['movies', 'search', query],
queryFn: () => fetchSearchMovies(query),
enabled: query.trim().length > 0,
})
}