Skip to content

Commit d167e89

Browse files
committed
feat: book colors
1 parent 233a9dc commit d167e89

File tree

28 files changed

+1925
-1200
lines changed

28 files changed

+1925
-1200
lines changed

app/(protected)/admin/books/[id]/edit/page.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import {
33
BreadcrumbItem,
44
BreadcrumbLink,
55
BreadcrumbList,
6-
BreadcrumbPage,
76
BreadcrumbSeparator,
87
} from '@/components/ui/breadcrumb'
98
import { Verify } from '@/lib/firebase/firebase'
109
import { getBook } from '@/lib/api/book'
11-
import { BookEditForm } from '@/components/books/book-edit-form'
10+
import { BookForm } from '@/components/books/BookForm'
11+
import { updateBookAction } from '@/lib/actions/update-book'
12+
import { Route } from 'next'
1213

1314
export default async function EditBookPage({
1415
params,
@@ -40,11 +41,13 @@ export default async function EditBookPage({
4041
</BreadcrumbItem>
4142
<BreadcrumbSeparator />
4243
<BreadcrumbItem>
43-
<BreadcrumbPage>Edit Book</BreadcrumbPage>
44+
<BreadcrumbLink href={`/admin/books/${id}` as Route}>
45+
{bookRes.data.title}
46+
</BreadcrumbLink>
4447
</BreadcrumbItem>
4548
</BreadcrumbList>
4649
</Breadcrumb>
47-
<BookEditForm book={bookRes.data} />
50+
<BookForm initialData={bookRes.data} onSubmitAction={updateBookAction} />
4851
</div>
4952
)
5053
}

app/(protected)/admin/books/[id]/page.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Button } from '@/components/ui/button'
1111
import { Pen } from 'lucide-react'
1212
import Link from 'next/link'
1313
import { DetailBook } from '@/components/books/DetailBook'
14+
import { colorsToCssVars } from '@/lib/utils/color-utils'
1415

1516
export default async function BookDetailsPage({
1617
params,
@@ -26,6 +27,8 @@ export default async function BookDetailsPage({
2627
return <div>{JSON.stringify(bookRes.message)}</div>
2728
}
2829

30+
const cssVars = colorsToCssVars(bookRes.data.colors)
31+
2932
return (
3033
<div className="space-y-4">
3134
<h1 className="text-2xl font-semibold">{bookRes.data.title}</h1>
@@ -45,7 +48,7 @@ export default async function BookDetailsPage({
4548
</BreadcrumbList>
4649
</Breadcrumb>
4750

48-
<DetailBook book={bookRes.data}>
51+
<DetailBook book={bookRes.data} style={cssVars}>
4952
<Button className="w-full" asChild>
5053
<Link href={`/admin/books/${bookRes.data.id}/edit`}>
5154
<Pen />

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
BreadcrumbPage,
77
BreadcrumbSeparator,
88
} from '@/components/ui/breadcrumb'
9-
import { BookCreateForm } from '@/components/books/book-create-form'
9+
import { BookForm } from '@/components/books/BookForm'
10+
import { createBookAction } from '@/lib/actions/create-book'
1011

1112
export default function NewBook() {
1213
return (
@@ -27,7 +28,16 @@ export default function NewBook() {
2728
</BreadcrumbItem>
2829
</BreadcrumbList>
2930
</Breadcrumb>
30-
<BookCreateForm />
31+
<BookForm
32+
initialData={{
33+
title: '',
34+
author: '',
35+
year: 0,
36+
code: '',
37+
library_id: '',
38+
}}
39+
onSubmitAction={createBookAction}
40+
/>
3141
</div>
3242
)
3343
}

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import { getListBooks } from '@/lib/api/book'
1818
import Link from 'next/link'
1919
import type { Metadata } from 'next'
2020
import { SITE_NAME } from '@/lib/consts'
21-
import { Plus, Search, Settings, Upload } from 'lucide-react'
22-
import { DebouncedInput } from '@/components/common/DebouncedInput'
21+
import { Plus, Settings, Upload } from 'lucide-react'
2322
import { Badge } from '@/components/ui/badge'
2423
import { ListBook } from '@/components/books/ListBook'
2524
import { cookies } from 'next/headers'
2625
import { Verify } from '@/lib/firebase/firebase'
26+
import { colorsToCssVars } from '@/lib/utils/color-utils'
27+
import { SearchInput } from '@/components/common/SearchInput'
2728

2829
export const metadata: Metadata = {
2930
title: `Books · ${SITE_NAME}`,
@@ -113,20 +114,18 @@ export default async function Books({
113114
</div>
114115
</nav>
115116

116-
<div className="relative flex-1">
117-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
118-
119-
<DebouncedInput
120-
name="title"
117+
<div className="flex justify-between gap-4">
118+
<SearchInput
119+
className="max-w-md"
121120
placeholder="Search by title"
122-
className="pl-8 max-w-md"
121+
name="title"
123122
/>
124123
</div>
125124

126125
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
127126
{res.data.map((book) => (
128127
<Link key={book.id} href={`/admin/books/${book.id}`} passHref>
129-
<ListBook book={book} />
128+
<ListBook book={book} style={colorsToCssVars(book.colors)} />
130129
</Link>
131130
))}
132131
</div>

app/(protected)/admin/collections/page.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ import {
1616
import Link from 'next/link'
1717
import type { Metadata } from 'next'
1818
import { SITE_NAME } from '@/lib/consts'
19-
import { Plus, Search } from 'lucide-react'
20-
import { DebouncedInput } from '@/components/common/DebouncedInput'
19+
import { Plus } from 'lucide-react'
2120
import { Badge } from '@/components/ui/badge'
2221
import { Verify } from '@/lib/firebase/firebase'
2322
import { Button } from '@/components/ui/button'
2423
import { getListCollections } from '@/lib/api/collection'
2524
import { ListCollection } from '@/components/collections/ListCollection'
25+
import { SearchInput } from '@/components/common/SearchInput'
2626

2727
export const metadata: Metadata = {
2828
title: `Collections · ${SITE_NAME}`,
@@ -101,13 +101,11 @@ export default async function UserCollections({
101101
</div>
102102
</nav>
103103

104-
<div className="relative flex-1">
105-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
106-
107-
<DebouncedInput
108-
name="title"
104+
<div className="flex justify-between gap-4">
105+
<SearchInput
106+
className="max-w-md"
109107
placeholder="Search by title"
110-
className="pl-8 max-w-md"
108+
name="title"
111109
/>
112110
</div>
113111

app/(protected)/admin/memberships/page.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ import Link from 'next/link'
1919
import type { Metadata } from 'next'
2020
import { SITE_NAME } from '@/lib/consts'
2121
import { ListCardMembership } from '@/components/memberships/ListCardMembership'
22-
import { Search } from 'lucide-react'
23-
import { DebouncedInput } from '@/components/common/DebouncedInput'
2422
import { Badge } from '@/components/ui/badge'
2523
import { cookies } from 'next/headers'
24+
import { SearchInput } from '@/components/common/SearchInput'
2625

2726
export const metadata: Metadata = {
2827
title: `Memberships · ${SITE_NAME}`,
@@ -93,13 +92,11 @@ export default async function Memberships({
9392
</div>
9493
</nav>
9594

96-
<div className="relative flex-1">
97-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
98-
99-
<DebouncedInput
100-
name="name"
95+
<div className="flex justify-between gap-4">
96+
<SearchInput
97+
className="max-w-md"
10198
placeholder="Search by name"
102-
className="pl-8 max-w-md"
99+
name="name"
103100
/>
104101
</div>
105102

app/(protected)/books/[id]/page.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { getBook } from '@/lib/api/book'
1111
import BtnWatchlist from '@/components/books/BtnWatchlist'
1212
import { DetailBook } from '@/components/books/DetailBook'
1313
import { IsLoggedIn } from '@/lib/firebase/firebase'
14+
import { colorsToCssVars } from '@/lib/utils/color-utils'
1415

1516
export default async function BookDetailsPage({
1617
params,
@@ -30,6 +31,13 @@ export default async function BookDetailsPage({
3031
return <div>{JSON.stringify(bookRes.message)}</div>
3132
}
3233

34+
const cssVars = colorsToCssVars(bookRes.data.colors)
35+
36+
// Map vibrant color to --color-primary for theme integration
37+
if (cssVars['--color-light-vibrant']) {
38+
cssVars['--color-primary'] = cssVars['--color-light-vibrant']
39+
}
40+
3341
return (
3442
<div className="space-y-4">
3543
<h1 className="text-2xl font-semibold">{bookRes.data.title}</h1>
@@ -49,7 +57,7 @@ export default async function BookDetailsPage({
4957
</BreadcrumbList>
5058
</Breadcrumb>
5159

52-
<DetailBook book={bookRes.data}>
60+
<DetailBook book={bookRes.data} style={cssVars}>
5361
<BtnWatchlist
5462
bookId={bookRes.data.id}
5563
isWatched={!!bookRes.data.watchlists?.[0]}

app/(protected)/books/page.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ import { getListBooks } from '@/lib/api/book'
1717
import Link from 'next/link'
1818
import type { Metadata } from 'next'
1919
import { SITE_NAME } from '@/lib/consts'
20-
import { BellRing, Search } from 'lucide-react'
21-
import { DebouncedInput } from '@/components/common/DebouncedInput'
20+
import { BellRing } from 'lucide-react'
2221
import { Badge } from '@/components/ui/badge'
2322
import { ListBook } from '@/components/books/ListBook'
2423
import { Verify } from '@/lib/firebase/firebase'
2524
import { Button } from '@/components/ui/button'
25+
import { colorsToCssVars } from '@/lib/utils/color-utils'
26+
import { SearchInput } from '@/components/common/SearchInput'
2627

2728
export const metadata: Metadata = {
2829
title: `Books · ${SITE_NAME}`,
@@ -100,20 +101,18 @@ export default async function UserBooks({
100101
</div>
101102
</nav>
102103

103-
<div className="relative flex-1">
104-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
105-
106-
<DebouncedInput
107-
name="title"
104+
<div className="flex justify-between gap-4">
105+
<SearchInput
106+
className="max-w-md"
108107
placeholder="Search by title"
109-
className="pl-8 max-w-md"
108+
name="title"
110109
/>
111110
</div>
112111

113112
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
114113
{res.data.map((book) => (
115114
<Link key={book.id} href={`/books/${book.id}`} passHref>
116-
<ListBook book={book} />
115+
<ListBook book={book} style={colorsToCssVars(book.colors)} />
117116
</Link>
118117
))}
119118
</div>

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ import {
1616
import Link from 'next/link'
1717
import type { Metadata } from 'next'
1818
import { SITE_NAME } from '@/lib/consts'
19-
import { Search } from 'lucide-react'
20-
import { DebouncedInput } from '@/components/common/DebouncedInput'
2119
import { Badge } from '@/components/ui/badge'
2220
import { ListBook } from '@/components/books/ListBook'
2321
import { Verify } from '@/lib/firebase/firebase'
2422
import { getListWatchlist } from '@/lib/api/watchlist'
23+
import { SearchInput } from '@/components/common/SearchInput'
2524

2625
export const metadata: Metadata = {
2726
title: `Watchlist Books · ${SITE_NAME}`,
@@ -91,13 +90,11 @@ export default async function UserBooks({
9190
</div>
9291
</nav>
9392

94-
<div className="relative flex-1">
95-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
96-
97-
<DebouncedInput
98-
name="title"
93+
<div className="flex justify-between gap-4">
94+
<SearchInput
95+
className="max-w-md"
9996
placeholder="Search by title"
100-
className="pl-8 max-w-md"
97+
name="title"
10198
/>
10299
</div>
103100

app/(protected)/collections/page.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ import {
1616
import Link from 'next/link'
1717
import type { Metadata } from 'next'
1818
import { SITE_NAME } from '@/lib/consts'
19-
import { BellRing, Heart, Search } from 'lucide-react'
20-
import { DebouncedInput } from '@/components/common/DebouncedInput'
19+
import { BellRing, Heart } from 'lucide-react'
2120
import { Badge } from '@/components/ui/badge'
2221
import { Verify } from '@/lib/firebase/firebase'
2322
import { Button } from '@/components/ui/button'
2423
import { getListCollections } from '@/lib/api/collection'
2524
import { ListCollection } from '@/components/collections/ListCollection'
25+
import { SearchInput } from '@/components/common/SearchInput'
2626

2727
export const metadata: Metadata = {
2828
title: `Collections · ${SITE_NAME}`,
@@ -100,13 +100,11 @@ export default async function UserCollections({
100100
</div>
101101
</nav>
102102

103-
<div className="relative flex-1">
104-
<Search className="absolute left-3 top-3 size-4 text-muted-foreground" />
105-
106-
<DebouncedInput
107-
name="title"
103+
<div className="flex justify-between gap-4">
104+
<SearchInput
105+
className="max-w-md"
108106
placeholder="Search by title"
109-
className="pl-8 max-w-md"
107+
name="title"
110108
/>
111109
</div>
112110

0 commit comments

Comments
 (0)