Compare commits

..

No commits in common. '19f4a2ebde3c8bd8f98bbddba70a5faca7cb07b6' and '4def1b5fc5ed091d769936382b101635e587fdbc' have entirely different histories.

@ -9,7 +9,6 @@ import clsx from 'clsx'
import { userSchema } from '@/types' import { userSchema } from '@/types'
import { cookies } from 'next/headers' import { cookies } from 'next/headers'
import { getUser } from '@/lib/auth' import { getUser } from '@/lib/auth'
import { getBookmarkCategories } from '@/lib/utils'
export const metadata: Metadata = { export const metadata: Metadata = {
title: { title: {
@ -41,10 +40,6 @@ export default async function RootLayout({
user = userSchema.parse(userData) user = userSchema.parse(userData)
} }
const bookmarkCategories = await getBookmarkCategories(
userData ? userData.id : null
)
return ( return (
<html <html
lang='en' lang='en'
@ -58,10 +53,7 @@ export default async function RootLayout({
<Providers <Providers
themeProps={{ attribute: 'class', defaultTheme: 'dark' }}> themeProps={{ attribute: 'class', defaultTheme: 'dark' }}>
<div className='relative flex h-screen flex-col'> <div className='relative flex h-screen flex-col'>
<Navbar <Navbar user={user} />
user={user}
categories={bookmarkCategories}
/>
<main className='container mx-auto max-w-7xl flex-grow px-6 pt-16'> <main className='container mx-auto max-w-7xl flex-grow px-6 pt-16'>
{children} {children}
</main> </main>

@ -30,15 +30,9 @@ import { GithubIcon } from '@/components/icons'
import { Icon } from '@iconify/react' import { Icon } from '@iconify/react'
import NewBookmarkForm from '@/components/newBookmarkForm' import NewBookmarkForm from '@/components/newBookmarkForm'
import { usePathname, useRouter } from 'next/navigation' import { usePathname, useRouter } from 'next/navigation'
import { BookmarkCategory, User } from '@/types' import { User } from '@/types'
export const Navbar = ({ export const Navbar = ({ user }: { user: User | null }) => {
user,
categories,
}: {
user: User | null
categories: BookmarkCategory[]
}) => {
const pathname = usePathname() const pathname = usePathname()
const router = useRouter() const router = useRouter()
@ -101,7 +95,7 @@ export const Navbar = ({
<NavbarItem className='hidden gap-2 sm:flex'> <NavbarItem className='hidden gap-2 sm:flex'>
{pathname.startsWith('/dashboard') && ( {pathname.startsWith('/dashboard') && (
<div className='mr-4'> <div className='mr-4'>
<NewBookmarkForm categories={categories} /> <NewBookmarkForm />
</div> </div>
)} )}
<Link <Link

@ -8,37 +8,30 @@ import {
ModalFooter, ModalFooter,
useDisclosure, useDisclosure,
} from '@nextui-org/modal' } from '@nextui-org/modal'
import { Select, SelectSection, SelectItem } from '@nextui-org/select' import {
import { Selection } from '@nextui-org/react' Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
} from '@nextui-org/dropdown'
import { Button } from '@nextui-org/button' import { Button } from '@nextui-org/button'
import { Input } from '@nextui-org/input' import { Input } from '@nextui-org/input'
import { Icon } from '@iconify/react' import { Icon } from '@iconify/react'
import { ChevronDownIcon } from './ChevronDownIcon'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { useState } from 'react' import { useState } from 'react'
import { Tab, Tabs } from '@nextui-org/tabs'
import { BookmarkCategory } from '@/types'
export default function NewBookmarkForm({ export default function NewBookmarkForm() {
categories,
}: {
categories: BookmarkCategory[]
}) {
const { isOpen, onOpen, onOpenChange } = useDisclosure() const { isOpen, onOpen, onOpenChange } = useDisclosure()
const router = useRouter() const router = useRouter()
const onSubmit = () => { const onSubmit = async () => {
if (selected === 'bookmark') submitBookmark()
else if (selected === 'bookmark_category') submitCategory()
else return
}
const submitBookmark = async () => {
const body = { const body = {
name, name,
link, link,
description, description,
url, url,
category_id: parseInt(value.currentKey), category_id: selectedKey === 'Other' ? 2 : 1,
} }
await fetch('/api/bookmark', { await fetch('/api/bookmark', {
method: 'POST', method: 'POST',
@ -48,28 +41,12 @@ export default function NewBookmarkForm({
router.refresh() router.refresh()
} }
const submitCategory = async () => {
const body = {
name: categoryName,
}
await fetch('/api/bookmark_category', {
method: 'POST',
body: JSON.stringify(body),
})
onOpenChange()
router.refresh()
}
const [selected, setSelected] = useState('bookmark')
const [name, setName] = useState('') const [name, setName] = useState('')
const [link, setLink] = useState('') const [link, setLink] = useState('')
const [description, setDescription] = useState('') const [description, setDescription] = useState('')
const [url, setUrl] = useState('') const [url, setUrl] = useState('')
const [categoryName, setCategoryName] = useState('') const [selectedKey, setSelectedKey] = useState('Other')
const [value, setValue] = useState<Selection>(new Set([]))
return ( return (
<> <>
@ -90,95 +67,84 @@ export default function NewBookmarkForm({
onOpenChange={onOpenChange} onOpenChange={onOpenChange}
placement='center' placement='center'
hideCloseButton> hideCloseButton>
<ModalContent> <ModalContent
onKeyUp={(e) => {
if (e.key === 'Enter') onSubmit()
}}>
{(onClose) => ( {(onClose) => (
<> <>
<ModalHeader className='flex gap-2'> <ModalHeader className='flex gap-2'>
New Bookmark/Category New Bookmark
<Icon <Icon
icon='mdi:bookmark-box' icon='mdi:bookmark-box'
fontSize={30} fontSize={30}
/> />
</ModalHeader> </ModalHeader>
<ModalBody className='gap-4'> <ModalBody className='gap-4'>
<Tabs <Dropdown>
selectedKey={selected} <DropdownTrigger className='flex justify-start'>
onSelectionChange={(key) => <Button
setSelected(key.toString()) startContent={
} <span className='text-default-400'>
fullWidth Category:
color='primary'> </span>
<Tab }
key='bookmark' endContent={
title={'Bookmark'}> <ChevronDownIcon className='text-small' />
<form className='flex flex-col gap-4'> }
<Select variant='flat'>
label='Select category' <div className='w-full text-start'>
placeholder='Select a category' {selectedKey}
selectedKeys={value} </div>
onSelectionChange={setValue}> </Button>
{categories.length > 0 ? ( </DropdownTrigger>
categories.map( <DropdownMenu
(category) => ( disallowEmptySelection
<SelectItem selectionMode='single'
key={ selectedKeys={selectedKey}
category.id disabledKeys={['disabled']}>
} <DropdownItem
value={ key='disabled'
category.id className='capitalize'>
}> Select Category
{category.name} </DropdownItem>
</SelectItem> <DropdownItem
) key='Coding'
) onClick={() => {
) : ( setSelectedKey('Coding')
<SelectItem }}
key={'test'} className='capitalize'>
value={'test'}> Coding
{'test'} </DropdownItem>
</SelectItem> <DropdownItem
)} key='Other'
</Select> onClick={() => {
<Input setSelectedKey('Other')
autoFocus }}
label='Name' className='capitalize'>
placeholder='Enter Name' Other
variant='bordered' </DropdownItem>
value={name} </DropdownMenu>
onChange={(event) => { </Dropdown>
setName(event.target.value) <Input
}} autoFocus
/> label='Name'
<Input placeholder='Enter Name'
label='Url' variant='bordered'
placeholder='Enter Url' value={name}
variant='bordered' onChange={(event) => {
value={url} setName(event.target.value)
onChange={(event) => { }}
setUrl(event.target.value) />
}} <Input
/> label='Url'
</form> placeholder='Enter Url'
</Tab> variant='bordered'
<Tab value={url}
key='bookmark_category' onChange={(event) => {
title={'Bookmark Category'}> setUrl(event.target.value)
<form className='flex flex-col gap-4'> }}
<Input />
autoFocus
label='Category Name'
placeholder='Enter Category Name'
variant='bordered'
value={categoryName}
onChange={(event) => {
setCategoryName(
event.target.value
)
}}
/>
</form>
</Tab>
</Tabs>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button <Button

@ -1,6 +0,0 @@
ALTER TABLE "bookmark_categories" ALTER COLUMN "user_id" SET DEFAULT 0;--> statement-breakpoint
ALTER TABLE "bookmark_categories" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "bookmark_categories" ALTER COLUMN "name" SET DEFAULT 'Other';--> statement-breakpoint
ALTER TABLE "bookmark_categories" ALTER COLUMN "name" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "users" ALTER COLUMN "password" SET DEFAULT '';--> statement-breakpoint
ALTER TABLE "users" ALTER COLUMN "password" SET NOT NULL;

@ -1,214 +0,0 @@
{
"version": "5",
"dialect": "pg",
"id": "8ee9d2e6-45d6-45ac-8552-b3e40c39b90e",
"prevId": "bd1fa6fc-b40d-4d9a-b024-69acb0a34270",
"tables": {
"bookmarks": {
"name": "bookmarks",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"category_id": {
"name": "category_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": false
},
"link": {
"name": "link",
"type": "text",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"bookmarks_user_id_users_id_fk": {
"name": "bookmarks_user_id_users_id_fk",
"tableFrom": "bookmarks",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"bookmark_categories": {
"name": "bookmark_categories",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'Other'"
}
},
"indexes": {},
"foreignKeys": {
"bookmark_categories_user_id_users_id_fk": {
"name": "bookmark_categories_user_id_users_id_fk",
"tableFrom": "bookmark_categories",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"session": {
"name": "session",
"schema": "",
"columns": {
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"expires": {
"name": "expires",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"session_user_id_users_id_fk": {
"name": "session_user_id_users_id_fk",
"tableFrom": "session",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"schemas": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

@ -22,13 +22,6 @@
"when": 1692438117496, "when": 1692438117496,
"tag": "0002_unusual_nico_minoru", "tag": "0002_unusual_nico_minoru",
"breakpoints": true "breakpoints": true
},
{
"idx": 3,
"version": "5",
"when": 1693043001584,
"tag": "0003_same_texas_twister",
"breakpoints": true
} }
] ]
} }

@ -5,7 +5,7 @@ export const user = pgTable('users', {
id: serial('id').primaryKey(), id: serial('id').primaryKey(),
name: text('name'), name: text('name'),
email: text('email'), email: text('email'),
hashedPassword: text('password').notNull().default(''), hashedPassword: text('password').notNull(),
createdAt: timestamp('created_at'), createdAt: timestamp('created_at'),
updatedAt: timestamp('updated_at'), updatedAt: timestamp('updated_at'),
}) })
@ -38,11 +38,8 @@ export const bookmarkRelations = relations(bookmark, ({ one }) => ({
export const bookmarkCategory = pgTable('bookmark_categories', { export const bookmarkCategory = pgTable('bookmark_categories', {
id: serial('id').primaryKey(), id: serial('id').primaryKey(),
userId: integer('user_id') userId: integer('user_id').references(() => user.id),
.references(() => user.id) name: text('name'),
.notNull()
.default(0),
name: text('name').notNull().default('Other'),
}) })
export const bookmarkCategoryRelations = relations( export const bookmarkCategoryRelations = relations(

@ -1,10 +0,0 @@
import { db } from './db'
export const getBookmarkCategories = async (user: number | null) => {
const bookmarkCategories = await db.query.bookmarkCategory.findMany({
where: (bookmarkCategory, { eq }) =>
eq(bookmarkCategory.userId, user ?? 0),
})
return bookmarkCategories
}

@ -22,8 +22,6 @@
"@nextui-org/link": "2.0.0", "@nextui-org/link": "2.0.0",
"@nextui-org/modal": "^2.0.13", "@nextui-org/modal": "^2.0.13",
"@nextui-org/navbar": "2.0.0", "@nextui-org/navbar": "2.0.0",
"@nextui-org/react": "^2.1.5",
"@nextui-org/select": "^2.1.4",
"@nextui-org/snippet": "2.0.0", "@nextui-org/snippet": "2.0.0",
"@nextui-org/switch": "2.0.0", "@nextui-org/switch": "2.0.0",
"@nextui-org/system": "2.0.0", "@nextui-org/system": "2.0.0",

File diff suppressed because it is too large Load Diff

@ -34,12 +34,9 @@ export const newBookmarkCategorySchema = z.object({
export const bookmarkCategorySchema = z.object({ export const bookmarkCategorySchema = z.object({
id: z.number(), id: z.number(),
userId: z.number(),
...bookmarkCategory, ...bookmarkCategory,
}) })
export type BookmarkCategory = z.infer<typeof bookmarkCategorySchema>
export const bookmarkCategoryWithBookmarksSchema = z.object({ export const bookmarkCategoryWithBookmarksSchema = z.object({
id: z.number(), id: z.number(),
...bookmarkCategory, ...bookmarkCategory,

Loading…
Cancel
Save