Skip to content

Commit 93187ba

Browse files
committed
feat: view transition for book
1 parent 52a33d7 commit 93187ba

File tree

6 files changed

+39
-95
lines changed

6 files changed

+39
-95
lines changed

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

Lines changed: 9 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ThreeDBook } from '@/components/books/three-d-book'
1313
import { Button } from '@/components/ui/button'
1414
import { Badge } from '@/components/ui/badge'
1515
import Link from 'next/link'
16+
import { DetailBook } from '@/components/books/DetailBook'
1617

1718
export default async function BookDetailsPage({
1819
params,
@@ -47,79 +48,14 @@ export default async function BookDetailsPage({
4748
</BreadcrumbList>
4849
</Breadcrumb>
4950

50-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
51-
{/* Book Cover */}
52-
<div className="lg:col-span-1 grid place-items-center gap-4">
53-
<ThreeDBook book={bookRes.data} />
54-
<Button className="w-full" asChild>
55-
<Link href={`/admin/books/${bookRes.data.id}/edit`}>
56-
<Pen />
57-
Edit
58-
</Link>
59-
</Button>
60-
</div>
61-
62-
{/* Book Information */}
63-
<div className="lg:col-span-2 space-y-4">
64-
<div>
65-
<h1 className="text-3xl font-bold mb-2">{bookRes.data.title}</h1>
66-
<p className="text-xl text-muted-foreground mb-4">
67-
{bookRes.data.author}
68-
</p>
69-
<div className="flex flex-wrap gap-2 mb-4">
70-
<Badge
71-
variant={
72-
bookRes.data.stats?.is_available ? 'default' : 'secondary'
73-
}
74-
>
75-
{bookRes.data.stats?.is_available ? 'Available' : 'Borrowed'}
76-
</Badge>
77-
<Badge variant="outline">bookRes.data.genre</Badge>
78-
</div>
79-
</div>
80-
81-
<Card>
82-
<CardHeader>
83-
<CardTitle>Book Information</CardTitle>
84-
</CardHeader>
85-
<CardContent className="grid gap-2 grid-cols-[max-content_1fr] md:grid-cols-[max-content_1fr_max-content_1fr] items-center">
86-
<Hash className="size-4" />
87-
<p>
88-
<span className="font-medium">Code:&nbsp;</span>
89-
{bookRes.data.code}
90-
</p>
91-
<Calendar className="size-4" />
92-
<p>
93-
<span className="font-medium">Year:&nbsp;</span>
94-
{bookRes.data.year}
95-
</p>
96-
<Library className="size-4" />
97-
<p>
98-
<span className="font-medium">Library:&nbsp;</span>
99-
<Link href={`/libraries/${bookRes.data.library.id}`}>
100-
{bookRes.data.library.name}
101-
</Link>
102-
</p>
103-
</CardContent>
104-
</Card>
105-
106-
<Card>
107-
<CardHeader>
108-
<CardTitle>Description</CardTitle>
109-
</CardHeader>
110-
<CardContent>
111-
<p className="text-sm leading-relaxed">
112-
bookRes.data.description
113-
</p>
114-
</CardContent>
115-
</Card>
116-
</div>
117-
</div>
118-
119-
{/* <div className="place-self-center text-center pt-4 border-t">
120-
<p className="text-gray-600">{bookRes.data.author}</p>
121-
<p className="text-sm text-gray-500">{bookRes.data.code}</p>
122-
</div> */}
51+
<DetailBook book={bookRes.data}>
52+
<Button className="w-full" asChild>
53+
<Link href={`/admin/books/${bookRes.data.id}/edit`}>
54+
<Pen />
55+
Edit
56+
</Link>
57+
</Button>
58+
</DetailBook>
12359
</div>
12460
)
12561
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ import {
77
BreadcrumbSeparator,
88
} from '@/components/ui/breadcrumb'
99
import { getBook } from '@/lib/api/book'
10-
import { BookDown } from 'lucide-react'
1110

1211
import BtnWatchlist from '@/components/books/BtnWatchlist'
13-
import { Button } from '@/components/ui/button'
1412
import { DetailBook } from '@/components/books/DetailBook'
1513
import { IsLoggedIn } from '@/lib/firebase/firebase'
1614

components/books/DetailBook.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ThreeDBook } from '@/components/books/three-d-book'
44
import { Badge } from '@/components/ui/badge'
55
import Link from 'next/link'
66
import { BookDetail } from '@/lib/types/book'
7+
import { unstable_ViewTransition as ViewTransition } from 'react'
78

89
export const DetailBook: React.FC<
910
React.PropsWithChildren<{ book: BookDetail }>
@@ -12,7 +13,9 @@ export const DetailBook: React.FC<
1213
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
1314
{/* Book Cover */}
1415
<div className="lg:col-span-1 grid place-items-center gap-4">
15-
<ThreeDBook book={book} />
16+
<ViewTransition name={book.id}>
17+
<ThreeDBook book={book} />
18+
</ViewTransition>
1619
{children}
1720
</div>
1821

components/books/ListBook.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
CardTitle,
1010
} from '@/components/ui/card'
1111
import clsx from 'clsx'
12+
import { unstable_ViewTransition as ViewTransition } from 'react'
1213

1314
export const ListBook: React.FC<{ book: Book }> = ({ book }) => {
1415
return (
@@ -19,26 +20,28 @@ export const ListBook: React.FC<{ book: Book }> = ({ book }) => {
1920
)}
2021
>
2122
<CardHeader className="pb-3">
22-
<div className="grid place-items-center">
23-
{/* 3D Book Effect */}
24-
<div className="flex my-12">
25-
<div className="bg-accent [transform:perspective(400px)_rotateY(314deg)] -mr-1 w-4">
26-
<span className="inline-block text-nowrap text-[0.5rem] font-bold text-accent-foreground/50 [transform:rotate(90deg)_translateY(-16px)] origin-top-left"></span>
23+
<ViewTransition name={book.id}>
24+
<div className="grid place-items-center">
25+
{/* 3D Book Effect */}
26+
<div className="flex my-12">
27+
<div className="bg-accent [transform:perspective(400px)_rotateY(314deg)] -mr-1 w-4">
28+
<span className="inline-block text-nowrap text-[0.5rem] font-bold text-accent-foreground/50 [transform:rotate(90deg)_translateY(-16px)] origin-top-left"></span>
29+
</div>
30+
<Image
31+
src={book?.cover ?? '/book-placeholder.svg'}
32+
alt={book.title + "'s cover"}
33+
width={128}
34+
height={192}
35+
className={clsx(
36+
'shadow-xl rounded-r-md w-32 h-48 object-cover',
37+
'[transform:perspective(800px)_rotateY(14deg)]',
38+
!book.stats?.is_available && 'grayscale'
39+
)}
40+
priority
41+
/>
2742
</div>
28-
<Image
29-
src={book?.cover ?? '/book-placeholder.svg'}
30-
alt={book.title + "'s cover"}
31-
width={128}
32-
height={192}
33-
className={clsx(
34-
'shadow-xl rounded-r-md w-32 h-48 object-cover',
35-
'[transform:perspective(800px)_rotateY(14deg)]',
36-
!book.stats?.is_available && 'grayscale'
37-
)}
38-
priority
39-
/>
4043
</div>
41-
</div>
44+
</ViewTransition>
4245
<CardTitle className="text-lg line-clamp-1">{book.title}</CardTitle>
4346
<CardDescription className="line-clamp-1">
4447
{book.author}

components/borrows/DetailBorrow.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { Borrow } from '@/lib/types/borrow'
2828
import { DateTime } from '@/components/common/DateTime'
2929
import { ThreeDBook } from '@/components/books/three-d-book'
3030
import { Route } from 'next'
31+
import { unstable_ViewTransition as ViewTransition } from 'react'
3132

3233
export const DetailBorrow: React.FC<
3334
React.PropsWithChildren<{
@@ -46,7 +47,9 @@ export const DetailBorrow: React.FC<
4647
<CardContent className="grid place-self-center md:place-self-auto md:grid-cols-2 gap-4">
4748
{/* FIXME */}
4849
<Link href={`../books/${borrow.book.id}` as Route}>
49-
<ThreeDBook book={borrow.book} />
50+
<ViewTransition name={borrow.book.id}>
51+
<ThreeDBook book={borrow.book} />
52+
</ViewTransition>
5053
</Link>
5154
<div>
5255
{/* FIXME */}

next.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const nextConfig: NextConfig = {
88
experimental: {
99
// for event source stream
1010
proxyTimeout: 0,
11+
viewTransition: true,
1112
},
1213

1314
logging: {

0 commit comments

Comments
 (0)