From b8701332c385ed087c745473a45d346615a06334 Mon Sep 17 00:00:00 2001 From: TZGyn Date: Sun, 13 Aug 2023 02:07:37 +0800 Subject: [PATCH] New feature: edit bookmark --- app/api/bookmark/route.ts | 19 ++++- app/dashboard/page.tsx | 2 + app/providers.tsx | 72 ++++++++++++++++--- components/bookmarkCard.tsx | 15 ++++ components/editBookmarkForm.tsx | 122 ++++++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 components/editBookmarkForm.tsx diff --git a/app/api/bookmark/route.ts b/app/api/bookmark/route.ts index abf0913..5ac414c 100644 --- a/app/api/bookmark/route.ts +++ b/app/api/bookmark/route.ts @@ -1,4 +1,4 @@ -import { newBookmarkSchema } from '@/types' +import { bookmarkSchema, newBookmarkSchema } from '@/types' import { NextRequest, NextResponse } from 'next/server' import { db, bookmark } from '@/lib/schema' import { eq } from 'drizzle-orm' @@ -23,6 +23,23 @@ export const POST = async (request: NextRequest) => { return NextResponse.json(newBookmark.error) } +export const PATCH = async (request: NextRequest) => { + const body = await request.json() + + const updateBookmark = bookmarkSchema.safeParse(body) + + if (updateBookmark.success) { + await db + .update(bookmark) + .set({ ...updateBookmark.data }) + .where(eq(bookmark.id, updateBookmark.data.id)) + + return NextResponse.json({ message: 'Bookmark Updated' }) + } + + return NextResponse.json({ message: 'Invalid Bookmark' }) +} + export const DELETE = async (request: NextRequest) => { const body = await request.json() diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index e4cc869..e1cb0f5 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,6 +1,7 @@ import { BookmarkCard } from '@/components/bookmarkCard' import { bookmarkSchema } from '@/types' import { db, bookmark } from '@/lib/schema' +import EditBookmarkForm from '@/components/editBookmarkForm' export const dynamic = 'force-dynamic' export const fetchCache = 'force-no-store' @@ -17,6 +18,7 @@ export default async function DashboardPage() { data={data} /> ))} + ) } diff --git a/app/providers.tsx b/app/providers.tsx index b94f2a7..e3da583 100644 --- a/app/providers.tsx +++ b/app/providers.tsx @@ -1,19 +1,69 @@ -"use client"; +'use client' -import * as React from "react"; -import { NextUIProvider } from "@nextui-org/system"; -import { ThemeProvider as NextThemesProvider } from "next-themes"; -import { ThemeProviderProps } from "next-themes/dist/types"; +import * as React from 'react' +import { NextUIProvider } from '@nextui-org/system' +import { ThemeProvider as NextThemesProvider } from 'next-themes' +import { ThemeProviderProps } from 'next-themes/dist/types' +import { Bookmark } from '@/types' export interface ProvidersProps { - children: React.ReactNode; - themeProps?: ThemeProviderProps; + children: React.ReactNode + themeProps?: ThemeProviderProps } +export type EditBookmarkContextContent = { + isEditBookmark: boolean + setIsEditBookmark: (c: boolean) => void +} + +export const EditBookmarkContext = + React.createContext({ + isEditBookmark: false, + setIsEditBookmark: () => {}, + }) + +export type BookmarkContextContent = { + bookmark: Bookmark + setBookmark: (c: Bookmark) => void +} + +export const BookmarkContext = React.createContext({ + bookmark: { + id: 0, + name: '', + link: '', + description: '', + url: '', + }, + setBookmark: () => {}, +}) + export function Providers({ children, themeProps }: ProvidersProps) { + const [isEditBookmark, setIsEditBookmark] = React.useState(false) + const [bookmark, setBookmark] = React.useState({ + id: 0, + name: '', + link: '', + description: '', + url: '', + }) return ( - - {children} - - ); + + + + + {children} + + + + + ) } diff --git a/components/bookmarkCard.tsx b/components/bookmarkCard.tsx index a9b3f9b..13593e3 100644 --- a/components/bookmarkCard.tsx +++ b/components/bookmarkCard.tsx @@ -14,9 +14,15 @@ import { } from '@nextui-org/dropdown' import { useRouter } from 'next/navigation' +import EditBookmarkForm from './editBookmarkForm' import { type Bookmark } from '@/types' +import { useContext } from 'react' +import { BookmarkContext, EditBookmarkContext } from '@/app/providers' export const BookmarkCard = ({ data }: { data: Bookmark }) => { + const { setIsEditBookmark } = useContext(EditBookmarkContext) + const { bookmark, setBookmark } = useContext(BookmarkContext) + const router = useRouter() const deleteBookmark = async (event: React.MouseEvent, id: Number) => { event.stopPropagation() @@ -26,6 +32,10 @@ export const BookmarkCard = ({ data }: { data: Bookmark }) => { }) router.refresh() } + const editBookmark = (selectedBookmark: Bookmark) => { + setBookmark({ ...bookmark, ...selectedBookmark }) + setIsEditBookmark(true) + } return ( <> @@ -55,6 +65,11 @@ export const BookmarkCard = ({ data }: { data: Bookmark }) => { + editBookmark(data)}> + Edit Bookmark + { + const body = bookmark + + await fetch('/api/bookmark', { + method: 'PATCH', + body: JSON.stringify(body), + }) + setIsEditBookmark(false) + router.refresh() + } + + return ( + <> + setIsEditBookmark(false)} + placement='top-center' + hideCloseButton> + + {(onClose) => ( + <> + + Edit Bookmark + + + + { + setBookmark({ + ...bookmark, + name: event.target.value, + }) + }} + /> + { + setBookmark({ + ...bookmark, + link: event.target.value, + }) + }} + /> + { + setBookmark({ + ...bookmark, + description: event.target.value, + }) + }} + /> + { + setBookmark({ + ...bookmark, + url: event.target.value, + }) + }} + /> + + + + + + + )} + + + + ) +}