New feature: edit bookmark

master
TZGyn 2 years ago
parent fd3ba9e08d
commit b8701332c3
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -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()

@ -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}
/>
))}
<EditBookmarkForm />
</div>
)
}

@ -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<EditBookmarkContextContent>({
isEditBookmark: false,
setIsEditBookmark: () => {},
})
export type BookmarkContextContent = {
bookmark: Bookmark
setBookmark: (c: Bookmark) => void
}
export const BookmarkContext = React.createContext<BookmarkContextContent>({
bookmark: {
id: 0,
name: '',
link: '',
description: '',
url: '',
},
setBookmark: () => {},
})
export function Providers({ children, themeProps }: ProvidersProps) {
const [isEditBookmark, setIsEditBookmark] = React.useState<boolean>(false)
const [bookmark, setBookmark] = React.useState<Bookmark>({
id: 0,
name: '',
link: '',
description: '',
url: '',
})
return (
<BookmarkContext.Provider
value={{
bookmark,
setBookmark,
}}>
<EditBookmarkContext.Provider
value={{
isEditBookmark,
setIsEditBookmark,
}}>
<NextUIProvider>
<NextThemesProvider {...themeProps}>{children}</NextThemesProvider>
<NextThemesProvider {...themeProps}>
{children}
</NextThemesProvider>
</NextUIProvider>
);
</EditBookmarkContext.Provider>
</BookmarkContext.Provider>
)
}

@ -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 (
<>
<Card className='w-96 select-none'>
@ -55,6 +65,11 @@ export const BookmarkCard = ({ data }: { data: Bookmark }) => {
</Button>
</DropdownTrigger>
<DropdownMenu aria-label='Static Actions'>
<DropdownItem
key='edit'
onClick={() => editBookmark(data)}>
Edit Bookmark
</DropdownItem>
<DropdownItem
key='delete'
className='text-danger'

@ -0,0 +1,122 @@
'use client'
import {
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
} from '@nextui-org/modal'
import { Button } from '@nextui-org/button'
import { Input } from '@nextui-org/input'
import { Icon } from '@iconify/react'
import { useRouter } from 'next/navigation'
import { useContext, useState } from 'react'
import { Bookmark } from '@/types'
import { BookmarkContext, EditBookmarkContext } from '@/app/providers'
export default function EditBookmarkForm() {
const { isEditBookmark, setIsEditBookmark } =
useContext(EditBookmarkContext)
const { bookmark, setBookmark } = useContext(BookmarkContext)
const router = useRouter()
const onSubmit = async () => {
const body = bookmark
await fetch('/api/bookmark', {
method: 'PATCH',
body: JSON.stringify(body),
})
setIsEditBookmark(false)
router.refresh()
}
return (
<>
<Modal
isOpen={isEditBookmark}
onOpenChange={() => setIsEditBookmark(false)}
placement='top-center'
hideCloseButton>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className='flex gap-2'>
Edit Bookmark
<Icon
icon='mdi:bookmark-box'
fontSize={30}
/>
</ModalHeader>
<ModalBody className='gap-4'>
<Input
autoFocus
label='Name'
placeholder='Enter Name'
variant='bordered'
value={bookmark.name}
onChange={(event) => {
setBookmark({
...bookmark,
name: event.target.value,
})
}}
/>
<Input
label='Link'
placeholder='Enter Link'
variant='bordered'
value={bookmark.link}
onChange={(event) => {
setBookmark({
...bookmark,
link: event.target.value,
})
}}
/>
<Input
label='Description'
placeholder='Enter Desription'
variant='bordered'
value={bookmark.description}
onChange={(event) => {
setBookmark({
...bookmark,
description: event.target.value,
})
}}
/>
<Input
label='Url'
placeholder='Enter Url'
variant='bordered'
value={bookmark.url}
onChange={(event) => {
setBookmark({
...bookmark,
url: event.target.value,
})
}}
/>
</ModalBody>
<ModalFooter>
<Button
color='danger'
variant='flat'
onClick={onClose}>
Close
</Button>
<Button
color='primary'
onPress={onSubmit}>
Add
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</>
)
}
Loading…
Cancel
Save