diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 97d9036..361c3f0 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -2,6 +2,8 @@ import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { Navbar } from "@/components/organisms/Navbar";
+import { GlobalStoreProvider } from "./store/globalStore";
+import { getMovies } from "@/lib/db";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -18,19 +20,23 @@ export const metadata: Metadata = {
description: "Generated by create next app",
};
-export default function RootLayout({
+export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
+ const movies = await getMovies();
+
return (
-
+
+
- {children}
+ {children}
+
);
diff --git a/src/app/store/globalStore.tsx b/src/app/store/globalStore.tsx
new file mode 100644
index 0000000..476476a
--- /dev/null
+++ b/src/app/store/globalStore.tsx
@@ -0,0 +1,44 @@
+"use client";
+import { movies } from "@/lib/db/schema";
+import { createContext, FC, use, useState } from "react";
+
+type GlobalStore = {
+ movies: (typeof movies.$inferSelect)[];
+ addMovie: (movie: typeof movies.$inferSelect) => void;
+ deleteMovie: (id: number) => void;
+};
+
+const globalStore = createContext({
+ movies: [],
+ addMovie: () => {},
+ deleteMovie: () => {},
+});
+
+type Props = {
+ children: React.ReactNode;
+ initialMovies: GlobalStore["movies"];
+};
+
+export const GlobalStoreProvider: FC = ({ children, initialMovies }) => {
+ const [movies, setMovies] = useState(initialMovies);
+
+ const addMovie = async (movie: GlobalStore["movies"][number]) => {
+ if (movies.find((m) => m.id === movie.id)) return;
+
+ setMovies((prev) => [...prev, movie]);
+ };
+
+ const deleteMovie = async (id: number) => {
+ setMovies((prev) => prev.filter((m) => m.id !== id));
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useGlobalStore = () => {
+ return use(globalStore);
+};
diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts
index 24b14f9..e03433b 100644
--- a/src/lib/db/index.ts
+++ b/src/lib/db/index.ts
@@ -1,3 +1,18 @@
+"use server";
import { drizzle } from "drizzle-orm/libsql";
+import { movies } from "./schema";
+import { eq } from "drizzle-orm";
-export const db = drizzle(process.env.DB_FILE_NAME!);
+const db = drizzle(process.env.DB_FILE_NAME!);
+
+export const getMovies = async () => {
+ return await db.select().from(movies);
+};
+
+export const addMovie = async (movie: typeof movies.$inferInsert) => {
+ await db.insert(movies).values(movie).onConflictDoNothing();
+};
+
+export const deleteMovie = async (id: number) => {
+ await db.delete(movies).where(eq(movies.id, id));
+};
diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts
index 9081e23..756618b 100644
--- a/src/lib/db/schema.ts
+++ b/src/lib/db/schema.ts
@@ -1,10 +1,13 @@
-import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
+import { integer, real, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const movies = sqliteTable("movies", {
id: integer("id").primaryKey(),
title: text("title").notNull(),
- releaseDate: text("release_date"),
- posterPath: text("poster_path"),
- status: text("status"), // to-watch, seen
- notes: text("notes"),
+ overview: text("overview").notNull(),
+ popularity: real("popularity").notNull(),
+ releaseDate: text("release_date").notNull(),
+ posterPath: text("poster_path").notNull(),
+ seen: integer("seen").default(0).notNull(),
+ favorite: integer("favorite").default(0).notNull(),
+ notes: text("notes").default("").notNull(),
});