From 7a7bc2575bd8af5e0abc11b5c149e22298dd84f8 Mon Sep 17 00:00:00 2001 From: Norbert Maciaszek Date: Mon, 18 Aug 2025 00:24:08 +0200 Subject: [PATCH] feat: integrate database operations for movie management in global store and UI components; enhance MovieCast with dynamic cast display and button for full cast visibility --- src/app/store/globalStore.tsx | 4 +++ src/components/atoms/MovieCard/index.tsx | 13 +++------ src/components/molecules/MovieCast/index.tsx | 30 +++++++++++++++++--- src/components/organisms/Hero/index.tsx | 4 --- src/lib/db/index.ts | 9 ++++-- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/app/store/globalStore.tsx b/src/app/store/globalStore.tsx index da1e785..1dd44db 100644 --- a/src/app/store/globalStore.tsx +++ b/src/app/store/globalStore.tsx @@ -1,4 +1,5 @@ "use client"; +import { addMovieToDB, deleteMovieFromDB, updateMovieInDB } from "@/lib/db"; import { movies } from "@/lib/db/schema"; import { createContext, FC, use, useEffect, useState } from "react"; @@ -37,14 +38,17 @@ export const GlobalStoreProvider: FC = ({ children }) => { const addMovie = async (movie: Movie) => { if (movies.find((m) => m.id === movie.id)) return; + addMovieToDB(movie); setMovies((prev) => [...prev, movie]); }; const deleteMovie = async (id: number) => { + deleteMovieFromDB(id); setMovies((prev) => prev.filter((m) => m.id !== id)); }; const updateMovie = async (id: number, movie: Partial) => { + updateMovieInDB(id, movie); setMovies((prev) => prev.map((m) => (m.id === id ? { ...m, ...movie } : m)) ); diff --git a/src/components/atoms/MovieCard/index.tsx b/src/components/atoms/MovieCard/index.tsx index 3a8b429..74f73d0 100644 --- a/src/components/atoms/MovieCard/index.tsx +++ b/src/components/atoms/MovieCard/index.tsx @@ -1,6 +1,5 @@ "use client"; import { FC } from "react"; -import { addMovie, deleteMovie, updateMovie } from "@/lib/db"; import { useGlobalStore } from "@/app/store/globalStore"; import { Movie } from "@/types/global"; import { @@ -37,23 +36,19 @@ export const MovieCard: FC = ({ const buttonClass = "p-4 text-sm transition-colors cursor-pointer text-center group/toggle"; - const handleAdd = async () => { - await addMovie(movie); + const handleAdd = () => { addMovieToStore(movie); }; - const handleRemove = async () => { - await deleteMovie(id); + const handleRemove = () => { deleteMovieFromStore(id); }; - const handleSeen = async () => { - await updateMovie(id, { seen: !movie.seen }); + const handleSeen = () => { updateMovieInStore(id, { seen: !movie.seen }); }; - const handleFavorite = async () => { - await updateMovie(id, { favorite: !movie.favorite }); + const handleFavorite = () => { updateMovieInStore(id, { favorite: !movie.favorite }); }; diff --git a/src/components/molecules/MovieCast/index.tsx b/src/components/molecules/MovieCast/index.tsx index 4a48889..034139e 100644 --- a/src/components/molecules/MovieCast/index.tsx +++ b/src/components/molecules/MovieCast/index.tsx @@ -1,5 +1,7 @@ +"use client"; +import { Button } from "@/components/atoms/Button"; import { MovieDetailsRich } from "@/lib/tmdb/types"; -import { FC } from "react"; +import { FC, useState } from "react"; import { FaDollarSign } from "react-icons/fa"; type Props = { @@ -7,10 +9,11 @@ type Props = { }; export const MovieCast: FC = ({ movieDetails }) => { + const [limitCast, setLimitCast] = useState(8); const director = movieDetails?.credits.crew.find( (member) => member.job === "Director" ); - const mainCast = movieDetails?.credits.cast.slice(0, 6) || []; + const mainCast = movieDetails?.credits.cast.slice(0, limitCast) || []; const formatCurrency = (amount: number) => new Intl.NumberFormat("pl-PL", { @@ -26,18 +29,21 @@ export const MovieCast: FC = ({ movieDetails }) => { {mainCast.length > 0 && (

Obsada

-
+
{mainCast.map((actor) => (
{actor.name}
@@ -46,6 +52,22 @@ export const MovieCast: FC = ({ movieDetails }) => {
))}
+ + {limitCast < movieDetails.credits.cast.length && ( +
+ +
+ )}
)} diff --git a/src/components/organisms/Hero/index.tsx b/src/components/organisms/Hero/index.tsx index 2a383d6..711704c 100644 --- a/src/components/organisms/Hero/index.tsx +++ b/src/components/organisms/Hero/index.tsx @@ -10,8 +10,6 @@ import { } from "react-icons/fa"; import { RiCalendarCheckLine, RiCalendarScheduleLine } from "react-icons/ri"; import { useGlobalStore } from "@/app/store/globalStore"; -import { addMovie, deleteMovie } from "@/lib/db"; -import { ReadMore } from "@/components/atoms/ReadMore"; import Link from "next/link"; import { Button } from "@/components/atoms/Button"; @@ -95,12 +93,10 @@ export const Hero: FC = ({ }, [autoRotate, rotateInterval, nextSlide, movies.length]); const handleAdd = async () => { - await addMovie(currentMovie); addMovieToStore(currentMovie); }; const handleRemove = async () => { - await deleteMovie(id); deleteMovieInStore(id); }; diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts index b019759..ec25d1e 100644 --- a/src/lib/db/index.ts +++ b/src/lib/db/index.ts @@ -10,7 +10,7 @@ export const getMovies = async () => { return await db.select().from(movies).$withCache(); }; -export const addMovie = async (movie: Movie) => { +export const addMovieToDB = async (movie: Movie) => { await db .insert(movies) .values({ @@ -20,10 +20,13 @@ export const addMovie = async (movie: Movie) => { .onConflictDoNothing(); }; -export const deleteMovie = async (id: number) => { +export const deleteMovieFromDB = async (id: number) => { await db.delete(movies).where(eq(movies.id, id)); }; -export const updateMovie = async (movieId: number, movie: Partial) => { +export const updateMovieInDB = async ( + movieId: number, + movie: Partial +) => { await db.update(movies).set(movie).where(eq(movies.id, movieId)); };