Skip to content

Commit c8b31ef

Browse files
committed
feat: collection management api
1 parent b2b6d7e commit c8b31ef

File tree

6 files changed

+53
-18
lines changed

6 files changed

+53
-18
lines changed

.prettierrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"singleQuote": true,
77
"trailingComma": "es5",
88
"bracketSpacing": true,
9-
"jsxBracketSameLine": false,
109
"arrowParens": "always",
1110
"endOfLine": "lf"
1211
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
BreadcrumbSeparator,
99
} from '@/components/ui/breadcrumb'
1010
import { Card } from '@/components/ui/card'
11+
import { updateCollectionBooksAction } from '@/lib/actions/collection'
1112
import { getCollection, getListCollectionBooks } from '@/lib/api/collection'
1213
import { Book } from 'lucide-react'
1314

@@ -53,7 +54,10 @@ export default async function CollectionManageBooksPage({
5354
</BreadcrumbItem>
5455
<BreadcrumbSeparator />
5556
<BreadcrumbItem>
56-
<BreadcrumbPage>{collectionRes.data.title}</BreadcrumbPage>
57+
{/* @ts-expect-error: typegen does not work */}
58+
<BreadcrumbLink href={`/admin/collections/${id}`}>
59+
{collectionRes.data.title}
60+
</BreadcrumbLink>
5761
</BreadcrumbItem>
5862
</BreadcrumbList>
5963
</Breadcrumb>
@@ -64,6 +68,7 @@ export default async function CollectionManageBooksPage({
6468
initialBooks={bookRes.data.map((b) => b.book!)}
6569
libraryID={collectionRes.data.library_id}
6670
initialBookIDs={collectionRes.data.book_ids}
71+
onSubmitAction={updateCollectionBooksAction.bind(null, id)}
6772
/>
6873
</div>
6974

components/collections/FormCollection.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,18 @@ export const FormCollection: React.FC<FormCollectionProps> = ({
158158
className={`border-2 border-dashed rounded-lg aspect-[2/1] flex flex-col items-center justify-center transition-colors ${
159159
dragActive
160160
? 'border-primary bg-primary/5'
161-
: 'border-slate-300'
161+
: 'border-muted-foreground/20'
162162
}`}
163163
onDragEnter={handleDrag}
164164
onDragLeave={handleDrag}
165165
onDragOver={handleDrag}
166166
onDrop={handleDrop}
167167
>
168-
<Upload className="h-12 w-12 text-slate-400 mb-4" />
169-
<p className="text-sm text-slate-600 mb-2">
168+
<Upload className="h-12 w-12 text-muted-foreground mb-4" />
169+
<p className="text-sm text-muted-foreground mb-2">
170170
Drag and drop a banner image here, or click to select
171171
</p>
172-
<p className="text-xs text-slate-500 mb-4">
172+
<p className="text-xs text-muted-foreground mb-4">
173173
Recommended: 800x400px (2:1 aspect ratio)
174174
</p>
175175
<input
@@ -307,7 +307,7 @@ export const FormCollection: React.FC<FormCollectionProps> = ({
307307
<Button type="submit" disabled={form.formState.isSubmitting}>
308308
{form.formState.isSubmitting
309309
? 'Submitting...'
310-
: 'Submit Collection'}
310+
: 'Save Collection'}
311311
</Button>
312312
</div>
313313
</form>

components/collections/FormManageCollectionBooks.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ export const FormManageCollectionBooks: React.FC<{
2020
initialBooks: Book[]
2121
libraryID: string
2222
initialBookIDs: string[]
23-
}> = ({ initialBooks, libraryID, initialBookIDs }) => {
23+
onSubmitAction: (v: string[]) => Promise<string>
24+
}> = ({ initialBooks, libraryID, initialBookIDs, onSubmitAction }) => {
2425
const [books, setBooks] = useState<Book[]>([])
2526
const [selectedBooks, setSelectedBooks] = useState<Book[]>(initialBooks)
2627
const selectedBookIDs = selectedBooks.map((b) => b.id)
@@ -67,6 +68,11 @@ export const FormManageCollectionBooks: React.FC<{
6768
)
6869
const isNoChange = hasSameNumber && hasEveryBook
6970

71+
const onSubmit = async () => {
72+
const result = await onSubmitAction(selectedBookIDs)
73+
toast(result)
74+
}
75+
7076
return (
7177
<div className="mx-auto space-y-4">
7278
<div className="flex flex-col md:flex-row top-4 sticky z-10 gap-4">
@@ -89,11 +95,7 @@ export const FormManageCollectionBooks: React.FC<{
8995
<X className="mr-2 h-4 w-4" />
9096
Deselect All ({selectedBooks.length})
9197
</Button>
92-
<Button
93-
onClick={console.log}
94-
className="h-full"
95-
disabled={isNoChange}
96-
>
98+
<Button onClick={onSubmit} className="h-full" disabled={isNoChange}>
9799
<Plus className="mr-2 h-4 w-4" />
98100
Save Selection ({selectedBooks.length})
99101
</Button>

lib/actions/collection.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
createCollection,
66
deleteCollection,
77
updateCollection,
8+
updateCollectionBooks,
89
} from '../api/collection'
910
import { IsLoggedIn, Verify } from '../firebase/firebase'
1011

@@ -60,7 +61,7 @@ export async function deleteCollectionAction(
6061

6162
export async function updateCollectionAction(
6263
id: string,
63-
data: Parameters<typeof createCollection>[0]
64+
data: Parameters<typeof updateCollection>[1]
6465
) {
6566
const headers = await Verify({
6667
from: `/admin/collections/${id}/edit`,
@@ -79,3 +80,29 @@ export async function updateCollectionAction(
7980
return { error: 'An unknown error occurred.' }
8081
}
8182
}
83+
84+
export async function updateCollectionBooksAction(
85+
id: string,
86+
bookIDs: string[]
87+
): Promise<string> {
88+
const headers = await Verify({
89+
from: `admin/collections/${id}/manage-books`,
90+
})
91+
try {
92+
const res = await updateCollectionBooks(
93+
id,
94+
{ book_ids: bookIDs },
95+
{ headers }
96+
)
97+
if ('error' in res) {
98+
return res.error
99+
}
100+
revalidatePath(`/admin/collections/${id}`, 'page')
101+
return 'Collection books updated successfully'
102+
} catch (e: unknown) {
103+
if (e instanceof Error) {
104+
return e.message
105+
}
106+
return 'An unknown error occurred.'
107+
}
108+
}

lib/api/collection.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,15 @@ type UpdateCollectionBooksResponse = Promise<
136136
>
137137
export const updateCollectionBooks = async (
138138
collection_id: string,
139-
query: UpdateCollectionBooksQuery
139+
query: UpdateCollectionBooksQuery,
140+
init?: RequestInit
140141
): UpdateCollectionBooksResponse => {
142+
const headers = new Headers(init?.headers)
143+
headers.set('Content-Type', 'application/json')
141144
const res = await fetch(`${COLLECTION_URL}/${collection_id}/books`, {
145+
...init,
142146
method: 'PUT',
143-
headers: {
144-
'Content-Type': 'application/json',
145-
},
147+
headers,
146148
body: JSON.stringify(query),
147149
})
148150
if (!res.ok) {

0 commit comments

Comments
 (0)