Skip to content

Commit a21020d

Browse files
committed
feat: book edit form
1 parent a3caae3 commit a21020d

File tree

12 files changed

+172
-51
lines changed

12 files changed

+172
-51
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import {
2+
Breadcrumb,
3+
BreadcrumbItem,
4+
BreadcrumbLink,
5+
BreadcrumbList,
6+
BreadcrumbPage,
7+
BreadcrumbSeparator,
8+
} from '@/components/ui/breadcrumb'
9+
import Link from 'next/link'
10+
import { Verify } from '@/lib/firebase/firebase'
11+
import { getBook } from '@/lib/api/book'
12+
import { cookies } from 'next/headers'
13+
import { BookEditForm } from '@/components/books/book-edit-form'
14+
15+
export default async function EditBookPage({
16+
params,
17+
}: {
18+
params: Promise<{ id: string }>
19+
}) {
20+
const { id } = await params
21+
22+
await Verify({ from: `/libraries/${id}/edit` })
23+
24+
const [bookRes] = await Promise.all([getBook({ id })])
25+
26+
if ('error' in bookRes) {
27+
console.log({ libRes: bookRes })
28+
return <div>{JSON.stringify(bookRes.message)}</div>
29+
}
30+
31+
const cookieStore = await cookies()
32+
const sessionName = process.env.SESSION_COOKIE_NAME as string
33+
const session = cookieStore.get(sessionName)
34+
35+
return (
36+
<div className="space-y-4">
37+
<h1 className="text-2xl font-semibold">{bookRes.data.title}</h1>
38+
<Breadcrumb>
39+
<BreadcrumbList>
40+
<BreadcrumbItem>
41+
<Link href="/" passHref legacyBehavior>
42+
<BreadcrumbLink>Home</BreadcrumbLink>
43+
</Link>
44+
</BreadcrumbItem>
45+
<BreadcrumbSeparator />
46+
<BreadcrumbItem>
47+
<Link href="/books" passHref legacyBehavior>
48+
<BreadcrumbLink>Books</BreadcrumbLink>
49+
</Link>
50+
</BreadcrumbItem>
51+
<BreadcrumbSeparator />
52+
<BreadcrumbItem>
53+
<BreadcrumbPage>Edit Book</BreadcrumbPage>
54+
</BreadcrumbItem>
55+
</BreadcrumbList>
56+
</Breadcrumb>
57+
<BookEditForm book={bookRes.data} token={session?.value as string} />
58+
</div>
59+
)
60+
}

app/(protected)/books/new/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
BreadcrumbSeparator,
88
} from '@/components/ui/breadcrumb'
99
import Link from 'next/link'
10-
import { CreateBookForm } from '@/components/books/CreateBookForm'
10+
import { BookCreateForm } from '@/components/books/book-create-form'
1111

1212
export default function NewBook() {
1313
return (
@@ -32,7 +32,7 @@ export default function NewBook() {
3232
</BreadcrumbItem>
3333
</BreadcrumbList>
3434
</Breadcrumb>
35-
<CreateBookForm />
35+
<BookCreateForm token="" />
3636
</div>
3737
)
3838
}

app/(protected)/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export default async function ProtectedLayout({
1+
export default function ProtectedLayout({
22
children,
3-
}: Readonly<{ children: React.ReactNode; heading: React.ReactNode }>) {
3+
}: Readonly<{ children: React.ReactNode }>) {
44
return <div className="container mx-auto px-4">{children}</div>
55
}
Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,21 @@ import {
2828
PopoverContent,
2929
PopoverTrigger,
3030
} from '@/components/ui/popover'
31-
import { useRouter } from 'next/navigation'
3231
import { getListLibraries } from '@/lib/api/library'
3332
import { Library } from '@/lib/types/library'
3433
import { useState, useEffect, useCallback } from 'react'
35-
import { Input } from '../ui/input'
36-
import { createBook } from '@/lib/api/book'
34+
import { Input } from '@/components/ui/input'
35+
import { Book } from '@/lib/types/book'
36+
37+
export type BookFormValues = Pick<
38+
Book,
39+
'title' | 'author' | 'year' | 'code' | 'library_id'
40+
>
41+
42+
type BookFormProps = {
43+
initialData: BookFormValues
44+
onSubmit(data: BookFormValues): void
45+
}
3746

3847
const FormSchema = z.object({
3948
title: z
@@ -63,18 +72,13 @@ const FormSchema = z.object({
6372
.uuid(),
6473
})
6574

66-
export const CreateBookForm: React.FC = () => {
67-
const router = useRouter()
68-
75+
export const BookForm: React.FC<BookFormProps> = ({
76+
initialData,
77+
onSubmit,
78+
}) => {
6979
const form = useForm<z.infer<typeof FormSchema>>({
7080
resolver: zodResolver(FormSchema),
71-
defaultValues: {
72-
title: '',
73-
author: '',
74-
code: '',
75-
year: 0,
76-
library_id: '',
77-
},
81+
defaultValues: initialData,
7882
})
7983

8084
const [libQ, setLibQ] = useState('')
@@ -96,24 +100,6 @@ export const CreateBookForm: React.FC = () => {
96100
})
97101
}, [libQ])
98102

99-
function onSubmit(data: z.infer<typeof FormSchema>) {
100-
createBook(data)
101-
.then(console.log)
102-
.then(() => {
103-
toast({
104-
title: 'Book Registered',
105-
})
106-
router.push('/books')
107-
})
108-
.catch((e) => {
109-
toast({
110-
title: 'Error',
111-
description: e?.error,
112-
variant: 'destructive',
113-
})
114-
})
115-
}
116-
117103
const onReset = useCallback(() => {
118104
form.reset()
119105
}, [form])
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use client'
2+
3+
import { useRouter } from 'next/navigation'
4+
import React from 'react'
5+
import { BookForm, BookFormValues } from './BookForm'
6+
import { createBook } from '@/lib/api/book'
7+
import { toast } from '../hooks/use-toast'
8+
9+
const initialData: BookFormValues = {
10+
title: '',
11+
author: '',
12+
year: 0,
13+
code: '',
14+
library_id: '',
15+
}
16+
17+
export const BookCreateForm: React.FC<{ token: string }> = () => {
18+
const router = useRouter()
19+
20+
function onSubmit(data: BookFormValues) {
21+
createBook(data)
22+
.then(console.log)
23+
.then(() => {
24+
toast({
25+
title: 'Book Registered',
26+
})
27+
router.push('/books')
28+
})
29+
.catch((e) => {
30+
toast({
31+
title: 'Error',
32+
description: e?.error,
33+
variant: 'destructive',
34+
})
35+
})
36+
}
37+
38+
return <BookForm initialData={initialData} onSubmit={onSubmit} />
39+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use client'
2+
3+
import { BookDetail } from '@/lib/types/book'
4+
// import { useRouter } from 'next/router'
5+
import { BookForm, BookFormValues } from './BookForm'
6+
7+
export const BookEditForm: React.FC<{ book: BookDetail; token: string }> = ({
8+
book,
9+
}) => {
10+
const initialData = {
11+
title: book.title,
12+
author: book.author,
13+
year: book.year,
14+
code: book.code,
15+
library_id: book.library_id,
16+
}
17+
// const router = useRouter()
18+
19+
function onSubmit(data: BookFormValues) {
20+
console.log(data)
21+
// updateBook(book.id, data, {
22+
// headers: {
23+
// Authorization: `Bearer ${token}`,
24+
// },
25+
// })
26+
// .then(console.log)
27+
// .then(() => {
28+
// toast({
29+
// title: 'Book Updated',
30+
// })
31+
// router.push(`/books/${book.id}`)
32+
// })
33+
// .catch((e) => {
34+
// toast({
35+
// title: 'Error',
36+
// description: e?.error,
37+
// variant: 'destructive',
38+
// })
39+
// })
40+
}
41+
42+
return <BookForm initialData={initialData} onSubmit={onSubmit} />
43+
}

components/landing.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import Link from 'next/link'
22
import {
33
ArrowRight,
4-
BookUser,
54
Users,
65
BookCheck,
76
TicketPlus,
@@ -56,7 +55,6 @@ export default function LandingPage() {
5655
<div className="flex flex-col min-h-screen">
5756
<header className="px-4 lg:px-6 h-14 flex items-center border-b justify-between">
5857
<Link className="flex items-center justify-center" href="/">
59-
<BookUser className="h-6 w-6" />
6058
<span className="ml-2 text-lg font-bold">Librarease</span>
6159
</Link>
6260
<nav className="flex gap-4 sm:gap-6">
@@ -84,7 +82,7 @@ export default function LandingPage() {
8482
</div>
8583
<div className="space-y-2 md:space-x-4">
8684
<Button size="lg" asChild>
87-
<Link href="/signup">
85+
<Link href="/login">
8886
Start Borrowing Today
8987
<ArrowRight className="ml-2 h-4 w-4" />
9088
</Link>

components/login-form.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export function LoginForm({
6565
type="email"
6666
name="email"
6767
placeholder="e.g. mgmg@example.com"
68+
autoFocus
6869
defaultValue={state.email}
6970
required
7071
/>

lib/api/book.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Book } from '../types/book'
1+
import { Book, BookDetail } from '../types/book'
22
import { QueryParams, ResList, ResSingle } from '../types/common'
33
import { BASE_URL } from './common'
44

@@ -22,7 +22,7 @@ export const getListBooks = async (
2222
}
2323

2424
type GetBookQuery = Pick<Book, 'id'>
25-
type GetBookResponse = Promise<ResSingle<Book>>
25+
type GetBookResponse = Promise<ResSingle<BookDetail>>
2626
export const getBook = async (query: GetBookQuery): GetBookResponse => {
2727
const url = new URL(`${BOOKS_URL}/${query.id}`)
2828
const response = await fetch(url.toString())

lib/api/borrow.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ export const getListBorrows = async (
3333
return response.json()
3434
}
3535

36-
type GetBookQuery = Pick<Borrow, 'id'>
37-
type GetBookResponse = Promise<ResSingle<Borrow>>
38-
export const getBook = async (query: GetBookQuery): GetBookResponse => {
36+
type GetBorrowQuery = Pick<Borrow, 'id'>
37+
type GetBorrowResponse = Promise<ResSingle<Borrow>>
38+
export const getBorrow = async (query: GetBorrowQuery): GetBorrowResponse => {
3939
const url = new URL(`${BORROW_URL}/${query.id}`)
4040
const response = await fetch(url.toString())
4141
return response.json()
4242
}
4343

4444
export const createBorrow = async (
4545
data: Pick<Borrow, 'book_id' | 'subscription_id' | 'staff_id'>
46-
): GetBookResponse => {
46+
): GetBorrowResponse => {
4747
const response = await fetch(BORROW_URL, {
4848
method: 'POST',
4949
headers: {
@@ -63,7 +63,7 @@ export const createBorrow = async (
6363
export const returnBorrow = async (
6464
data: Pick<Borrow, 'id' | 'returned_at'>,
6565
init?: RequestInit
66-
): GetBookResponse => {
66+
): GetBorrowResponse => {
6767
const response = await fetch(`${BORROW_URL}/${data.id}`, {
6868
...init,
6969
method: 'PUT',

0 commit comments

Comments
 (0)