Skip to content

Commit 939c286

Browse files
committed
wip: book display in app
1 parent 17722f9 commit 939c286

File tree

4 files changed

+90
-14
lines changed

4 files changed

+90
-14
lines changed

app/features/book/app/page-book.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import { getUiState } from '@/lib/ui-state';
77

88
import { BackButton } from '@/components/back-button';
99
import { PageError } from '@/components/page-error';
10+
import { Card, CardContent } from '@/components/ui/card';
1011
import { Separator } from '@/components/ui/separator';
1112
import { Skeleton } from '@/components/ui/skeleton';
1213
import { Spinner } from '@/components/ui/spinner';
1314

15+
import { BookCover } from '@/features/book/book-cover';
1416
import {
1517
PageLayout,
1618
PageLayoutContent,
@@ -62,7 +64,45 @@ export const PageBook = (props: { params: { id: string } }) => {
6264
.match('pending', () => <Spinner full />)
6365
.match('not-found', () => <PageError error="404" />)
6466
.match('error', () => <PageError />)
65-
.match('default', ({ book }) => <>{book.title}</>)
67+
.match('default', ({ book }) => (
68+
<div className="flex flex-col gap-8 xs:flex-row-reverse">
69+
<div className="flex-2">
70+
<Card className="py-1">
71+
<CardContent>
72+
<dl className="flex flex-col divide-y text-sm">
73+
<div className="flex gap-4 py-3">
74+
<dt className="w-24 flex-none font-medium text-muted-foreground">
75+
Title
76+
</dt>
77+
<dd className="flex-1">{book.title}</dd>
78+
</div>
79+
<div className="flex gap-4 py-3">
80+
<dt className="w-24 flex-none font-medium text-muted-foreground">
81+
Author
82+
</dt>
83+
<dd className="flex-1">{book.author}</dd>
84+
</div>
85+
<div className="flex gap-4 py-3">
86+
<dt className="w-24 flex-none font-medium text-muted-foreground">
87+
Genre
88+
</dt>
89+
<dd className="flex-1">{book.genre}</dd>
90+
</div>
91+
<div className="flex gap-4 py-3">
92+
<dt className="w-24 flex-none font-medium text-muted-foreground">
93+
Publisher
94+
</dt>
95+
<dd className="flex-1">{book.publisher}</dd>
96+
</div>
97+
</dl>
98+
</CardContent>
99+
</Card>
100+
</div>
101+
<div className="mx-auto w-full max-w-64 min-w-48 flex-1">
102+
<BookCover book={book} />
103+
</div>
104+
</div>
105+
))
66106
.exhaustive()}
67107
</PageLayoutContent>
68108
</PageLayout>

app/features/book/app/page-books.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getUiState } from '@/lib/ui-state';
77
import { PageError } from '@/components/page-error';
88
import { Button } from '@/components/ui/button';
99

10+
import { BookCover } from '@/features/book/book-cover';
1011
import {
1112
PageLayout,
1213
PageLayoutContent,
@@ -46,27 +47,28 @@ export const PageBooks = () => {
4647
.match('error', () => <PageError />)
4748
.match('empty', () => <>No books</>)
4849
.match('default', ({ items }) => (
49-
<>
50-
{items.map((item) => (
51-
<Link
52-
key={item.id}
53-
to="/app/books/$id"
54-
params={{ id: item.id }}
55-
>
56-
Repo: {item.title}
57-
</Link>
58-
))}
50+
<div className="flex flex-col gap-4 pb-20">
51+
<div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
52+
{items.map((item) => (
53+
<Link
54+
key={item.id}
55+
to="/app/books/$id"
56+
params={{ id: item.id }}
57+
>
58+
<BookCover book={item} />
59+
</Link>
60+
))}
61+
</div>
5962
{booksQuery.hasNextPage && (
6063
<Button
61-
size="sm"
62-
variant="link"
64+
variant="ghost"
6365
onClick={() => booksQuery.fetchNextPage()}
6466
loading={booksQuery.isFetchingNextPage}
6567
>
6668
Load more
6769
</Button>
6870
)}
69-
</>
71+
</div>
7072
))
7173
.exhaustive()}
7274
</PageLayoutContent>

app/features/book/book-cover.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Book } from '@/features/book/schema';
2+
3+
export const BookCover = (props: {
4+
book: Pick<Book, 'id' | 'title' | 'author' | 'genre'>;
5+
}) => {
6+
return (
7+
<div
8+
className="relative flex aspect-[2/3] flex-col justify-between overflow-hidden rounded-sm bg-neutral-800 p-4 pl-6 text-white shadow-2xl [view-transition-name:book-cover]"
9+
style={{
10+
background: '#333', // TODO get color from genre
11+
}}
12+
>
13+
<div className="absolute inset-y-0 left-0 w-1.5 bg-gradient-to-r from-black/0 to-black/10 bg-blend-screen" />
14+
<div className="absolute inset-y-0 left-1.5 w-0.5 bg-gradient-to-r from-white/0 to-white/20 bg-blend-screen" />
15+
<div className="absolute inset-y-0 left-2 w-0.5 bg-gradient-to-r from-white/0 to-white/20 bg-blend-screen" />
16+
<div className="absolute -top-1/8 -right-1/8 aspect-square w-3/4 rounded-full bg-white/40 bg-blend-screen blur-3xl" />
17+
<div className="absolute -bottom-1/8 -left-1/8 aspect-square w-3/4 rounded-full bg-black/40 bg-blend-screen blur-3xl" />
18+
<div className="relative flex flex-1 flex-col justify-between">
19+
<h3 className="text-base leading-tight font-bold xs:text-lg">
20+
{props.book.title}
21+
</h3>
22+
<div className="flex flex-col">
23+
<p className="text-xs opacity-60">By {props.book.author}</p>
24+
{!!props.book.genre && (
25+
<p className="text-2xs capitalize opacity-60">{props.book.genre}</p>
26+
)}
27+
</div>
28+
</div>
29+
</div>
30+
);
31+
};

app/styles/app.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
--spacing-safe-right: env(safe-area-inset-right);
6363

6464
--text-2xs: 0.625rem;
65+
66+
--breakpoint-2xs: 24rem;
67+
--breakpoint-xs: 32rem;
6568
}
6669

6770
:root {

0 commit comments

Comments
 (0)