diff --git a/src/App.tsx b/src/App.tsx index 12bc5ef..6227d1f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,37 +1,41 @@ +// hooks 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 { useSearchMovies } from './hooks/useMovies'; import { useDebouncedValue } from './hooks/useDebouncedValue'; -import { useSessionStorage } from './hooks/useSessionStorage'; +/* Brukes denne til noe Leona? */ import { sortAndFilterMovies, type SortOption } from './utils/sortAndFilterMovies'; + +import { useSessionStorage } from './hooks/useSessionStorage'; import { SortFilterBar } from './components/SortFilterBar'; import { useFavorites } from './hooks/useFavorites'; -import { TrendingPreview } from './components/TrendingPreview'; import { MovieDetails } from './components/MovieDetails'; +// layout templates og components +import { SearchLayout } from './layout/SearchLayout'; +import { MainLayout } from './layout/MainLayout'; +import { Sidebar } from './components/Sidebar'; + +// Movie type, holder all informajson om en film import type { Movie } from './types/tmdb'; import './App.css'; function App() { - - const [query, setQuery] = useState(''); + // brukes for å kunne velge film å vise detaljer om const [selectedMovie, setSelectedMovie] = useState(null); + // sorterings-funksjonalitet ? const [sortBy, setSortBy] = useSessionStorage('sortBy', 'popularity'); const [minRating, setMinRating] = useSessionStorage('minRating', 0); - const popular = usePopMovies() - const current = useCurMovies() - const people = usePopularPeople() + // search query var setter + const [query, setQuery] = useState(''); const debouncedQuery = useDebouncedValue(query, 400); const search = useSearchMovies(debouncedQuery) const isSearching = query.trim().length > 0; + + // favorite-funksjonalitet const { isFavorite, toggleFavorite} = useFavorites(); return ( @@ -46,33 +50,16 @@ function App() { onMinRatingChange={setMinRating} /> {isSearching ? ( -
- {search.data && } -
- ) : ( - <> -
- {current.data && } -
- -
- {popular.data && } -
- -
- {current.data && } -
- -
- {people.data && } -
- + + ) : ( + )} {selectedMovie && ( setSelectedMovie(null)} /> )} + ); diff --git a/src/components/MovieCard.css b/src/components/MovieCard.css index 0cfb3af..a99168f 100644 --- a/src/components/MovieCard.css +++ b/src/components/MovieCard.css @@ -8,6 +8,8 @@ overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); transition: transform 0.15s ease, box-shadow 0.15s ease; + + cursor: pointer; } .movie-card:hover { diff --git a/src/components/MovieDetails.tsx b/src/components/MovieDetails.tsx index 5da3174..60abbda 100644 --- a/src/components/MovieDetails.tsx +++ b/src/components/MovieDetails.tsx @@ -18,7 +18,7 @@ export function MovieDetails({ movie, isFavorite, onToggleFavorite, onClose }:
e.stopPropagation()}> {movie.title} diff --git a/src/components/Section.css b/src/components/Section.css index e69de29..e5f7649 100644 --- a/src/components/Section.css +++ b/src/components/Section.css @@ -0,0 +1,10 @@ +.section-skeleton { + border-radius: 0.5rem; + background: linear-gradient(90deg, #1a1a1a 25%, #2a2a2a 50%, #1a1a1a 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; +} +@keyframes shimmer { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} \ No newline at end of file diff --git a/src/components/Section.tsx b/src/components/Section.tsx index f2f77ce..5e347b4 100644 --- a/src/components/Section.tsx +++ b/src/components/Section.tsx @@ -8,13 +8,14 @@ type SectionProps = { isLoading: boolean; error: Error | null; children: ReactNode; + skeletonHeight?: string; }; -export function Section({ id, title, isLoading, error, children }: SectionProps) { +export function Section({ id, title, isLoading, error, children, skeletonHeight="300px"}: SectionProps) { return (

{title}

- {isLoading &&

Laster...

} + {isLoading &&
} {error &&

Noe gikk galt: {error.message}

} {!isLoading && !error && children}
diff --git a/src/components/TrendingPreview.tsx b/src/components/TrendingPreview.tsx index ef53660..636c52a 100644 --- a/src/components/TrendingPreview.tsx +++ b/src/components/TrendingPreview.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import type { Movie } from "../types/tmdb"; import "./TrendingPreview.css" -const tmdbURL = `https://image.tmdb.org/t/p/original`; +const tmdbURL = `https://image.tmdb.org/t/p/w1280`; type TrendingPreviewProps = { movies : Movie[]; diff --git a/src/layout/MainLayout.tsx b/src/layout/MainLayout.tsx index e69de29..dba57e7 100644 --- a/src/layout/MainLayout.tsx +++ b/src/layout/MainLayout.tsx @@ -0,0 +1,37 @@ +import { MovieList } from "../components/MovieList"; +import { PersonList } from "../components/PersonList"; +import { Section } from "../components/Section"; +import { TrendingPreview } from "../components/TrendingPreview"; +import { useCurMovies, usePopMovies } from "../hooks/useMovies"; +import { usePopularPeople } from "../hooks/usePeople"; +import type { Movie } from "../types/tmdb"; + +type MainLayoutProps = { + isFavorite: (id: number) => boolean; + toggleFavorite: (id: number) => void; + onSelectMovie: (movie: Movie) => void; +} + +// HomeSections.tsx +export function MainLayout({ isFavorite, toggleFavorite, onSelectMovie }: MainLayoutProps) { + const popular = usePopMovies(); + const current = useCurMovies(); + const people = usePopularPeople(); + + return ( + <> +
+ {current.data && } +
+
+ {popular.data && } +
+
+ {current.data && } +
+
+ {people.data && } +
+ + ); +} \ No newline at end of file diff --git a/src/layout/SearchLayout.tsx b/src/layout/SearchLayout.tsx new file mode 100644 index 0000000..0bd187d --- /dev/null +++ b/src/layout/SearchLayout.tsx @@ -0,0 +1,22 @@ +import type { UseQueryResult } from "@tanstack/react-query"; +import type { Movie } from "../types/tmdb"; +import { Section } from "../components/Section"; +import { MovieList } from "../components/MovieList"; + +type SearchSectionProps = { + query: string; + search: UseQueryResult; // or whatever your hook returns + isFavorite: (id: number) => boolean; + toggleFavorite: (id: number) => void; + onSelectMovie: (movie: Movie) => void; +}; + +export function SearchLayout({ query, search, isFavorite, toggleFavorite, onSelectMovie }: SearchSectionProps) { + return ( +
+ {search.data && ( + + )} +
+ ); +} \ No newline at end of file