From 3895ef320a713ef9598eae58b9f8cfe659bdc943 Mon Sep 17 00:00:00 2001 From: albdert Date: Mon, 14 Sep 2026 22:52:17 +0200 Subject: [PATCH 1/3] =?UTF-8?q?opprettet=20layouts=20for=20hovedside=20og?= =?UTF-8?q?=20s=C3=B8k?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 31 ++++++++++++++++--------- src/components/MovieDetails.tsx | 2 +- src/components/TrendingPreview.tsx | 2 +- src/layout/MainLayout.tsx | 37 ++++++++++++++++++++++++++++++ src/layout/SearchLayout.tsx | 22 ++++++++++++++++++ 5 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 src/layout/SearchLayout.tsx diff --git a/src/App.tsx b/src/App.tsx index 12bc5ef..1d35e5e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,6 +17,8 @@ import { MovieDetails } from './components/MovieDetails'; import type { Movie } from './types/tmdb'; import './App.css'; +import { SearchLayout } from './layout/SearchLayout'; +import { MainLayout } from './layout/MainLayout'; function App() { @@ -45,6 +47,23 @@ function App() { minRating={minRating} onMinRatingChange={setMinRating} /> + {isSearching ? ( + + ) : ( + + )} + + + {selectedMovie && ( + setSelectedMovie(null)} /> + )} + + + ); +} + +export default App; + /* {isSearching ? (
{search.data && } @@ -68,14 +87,4 @@ function App() {
)} - - - {selectedMovie && ( - setSelectedMovie(null)} /> - )} - - - ); -} - -export default App; + */ 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/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..96512cd 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 From 69cc58b9810f1c9573b49142819329d7f3a3fd1a Mon Sep 17 00:00:00 2001 From: albdert Date: Mon, 14 Sep 2026 23:18:02 +0200 Subject: [PATCH 2/3] section skeleton for cleaner loading --- src/App.tsx | 58 ++++++++++++-------------------------- src/components/Section.css | 10 +++++++ src/components/Section.tsx | 5 ++-- src/layout/MainLayout.tsx | 2 +- 4 files changed, 32 insertions(+), 43 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1d35e5e..6227d1f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,39 +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'; -import { SearchLayout } from './layout/SearchLayout'; -import { MainLayout } from './layout/MainLayout'; 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 ( @@ -57,34 +59,10 @@ function App() { {selectedMovie && ( setSelectedMovie(null)} /> )} +
); } export default App; - /* - {isSearching ? ( -
- {search.data && } -
- ) : ( - <> -
- {current.data && } -
- -
- {popular.data && } -
- -
- {current.data && } -
- -
- {people.data && } -
- - )} - */ 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/layout/MainLayout.tsx b/src/layout/MainLayout.tsx index 96512cd..dba57e7 100644 --- a/src/layout/MainLayout.tsx +++ b/src/layout/MainLayout.tsx @@ -20,7 +20,7 @@ export function MainLayout({ isFavorite, toggleFavorite, onSelectMovie }: MainLa return ( <> -
+
{current.data && }
From 67425973e1081688ff99da113dcffef5d8030d20 Mon Sep 17 00:00:00 2001 From: albdert Date: Tue, 15 Sep 2026 08:03:24 +0200 Subject: [PATCH 3/3] =?UTF-8?q?cursor:=20pointer=20p=C3=A5=20moviecard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MovieCard.css | 2 ++ 1 file changed, 2 insertions(+) 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 {