feat: update layout to fetch and provide initial movie data; enhance GlobalStoreProvider to accept initialMovies prop for improved state management
This commit is contained in:
parent
d767684c2c
commit
9051d4887c
|
|
@ -1,37 +1,29 @@
|
|||
import "./globals.css";
|
||||
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import { Navbar } from "@/components/organisms/Navbar";
|
||||
import { GlobalStoreProvider } from "./store/globalStore";
|
||||
import { AuroraBackground } from "@/components/effects";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Movie List",
|
||||
description: "Personal watch list and progress tracker",
|
||||
};
|
||||
import { GlobalStoreProvider } from "./store/globalStore";
|
||||
import { getMovies } from "@/lib/db";
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const movies = await getMovies();
|
||||
|
||||
return (
|
||||
<html lang="pl">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
<GlobalStoreProvider>
|
||||
<head>
|
||||
<title>Homepage | Movie List</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Personal watch list and progress tracker"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body className={`antialiased`}>
|
||||
<GlobalStoreProvider initialMovies={movies}>
|
||||
<AuroraBackground />
|
||||
<Navbar />
|
||||
<main className="relative">{children}</main>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
import { addMovieToDB, deleteMovieFromDB, updateMovieInDB } from "@/lib/db";
|
||||
import { movies } from "@/lib/db/schema";
|
||||
import { createContext, FC, use, useEffect, useState } from "react";
|
||||
import { createContext, FC, use, useState } from "react";
|
||||
|
||||
type Movie = typeof movies.$inferSelect;
|
||||
|
||||
|
|
@ -21,19 +21,15 @@ const globalStore = createContext<GlobalStore>({
|
|||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
initialMovies?: Movie[];
|
||||
};
|
||||
|
||||
export const GlobalStoreProvider: FC<Props> = ({ children }) => {
|
||||
export const GlobalStoreProvider: FC<Props> = ({
|
||||
children,
|
||||
initialMovies = [],
|
||||
}) => {
|
||||
// Optimistic update
|
||||
const [movies, setMovies] = useState<GlobalStore["movies"]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/movies")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setMovies(data);
|
||||
});
|
||||
}, []);
|
||||
const [movies, setMovies] = useState<GlobalStore["movies"]>(initialMovies);
|
||||
|
||||
const addMovie = async (movie: Movie) => {
|
||||
if (movies.find((m) => m.id === movie.id)) return;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { drizzle } from "drizzle-orm/libsql";
|
|||
import { movies } from "./schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { Movie } from "@/types/global";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
const db = drizzle(process.env.DB_FILE_NAME!);
|
||||
|
||||
|
|
@ -18,10 +19,13 @@ export const addMovieToDB = async (movie: Movie) => {
|
|||
genre_ids: JSON.stringify(movie.genre_ids),
|
||||
})
|
||||
.onConflictDoNothing();
|
||||
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
||||
export const deleteMovieFromDB = async (id: number) => {
|
||||
await db.delete(movies).where(eq(movies.id, id));
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
||||
export const updateMovieInDB = async (
|
||||
|
|
@ -29,4 +33,5 @@ export const updateMovieInDB = async (
|
|||
movie: Partial<Movie>
|
||||
) => {
|
||||
await db.update(movies).set(movie).where(eq(movies.id, movieId));
|
||||
revalidatePath("/", "layout");
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue