tangled
alpha
login
or
join now
baileykane.co
/
personal-website-next
0
fork
atom
this repo has no description
www.baileykane.co/
0
fork
atom
overview
issues
pulls
pipelines
Create BookCard to display content for one Book.
baileykane.co
7 months ago
0d4f9a10
25678199
+52
1 changed file
expand all
collapse all
unified
split
components
pageContent
books
BookCard.tsx
+52
components/pageContent/books/BookCard.tsx
···
1
1
+
"use client";
2
2
+
3
3
+
import type Book from "@/types/Book";
4
4
+
import { useState } from "react";
5
5
+
6
6
+
export default function BookCard({ book }: { book: Book }): React.ReactElement {
7
7
+
const [imageError, setImageError] = useState(false);
8
8
+
9
9
+
const formattedReadDate = new Date(book.dateRead).toLocaleDateString(
10
10
+
"en-US",
11
11
+
{
12
12
+
year: "numeric",
13
13
+
month: "long",
14
14
+
}
15
15
+
);
16
16
+
17
17
+
return (
18
18
+
<a
19
19
+
target="_blank"
20
20
+
href={`https://openlibrary.org/isbn/${book.isbn}`}
21
21
+
className="rounded-md w-72 mx-auto sm:w-auto sm:mx-0"
22
22
+
>
23
23
+
<div className="p-2 rounded-md border-2 bg-stone-50 dark:bg-stone-800 border-stone-400 hover:border-stone-500 dark:border-stone-600 shadow-md hover:shadow-xl transition-all">
24
24
+
<div className="shadow-md rounded-sm w-full aspect-book outline outline-1 dark:outline-stone-400">
25
25
+
<img
26
26
+
// OpenLibrary Covers API:https://openlibrary.org/dev/docs/api/covers
27
27
+
src={`https://covers.openlibrary.org/b/isbn/${book.isbn}-M.jpg?default=false`}
28
28
+
alt={`The cover of ${book.title}, by ${book.author}.`}
29
29
+
loading="lazy"
30
30
+
onError={() => setImageError(true)}
31
31
+
className={`w-full rounded-sm aspect-book ${
32
32
+
imageError && "hidden"
33
33
+
}`}
34
34
+
/>
35
35
+
{imageError && (
36
36
+
<div className="rounded-sm h-full bg-stone-200 dark:bg-stone-700 flex items-center justify-center">
37
37
+
<p className="text-sm">Book image not found.</p>
38
38
+
</div>
39
39
+
)}
40
40
+
</div>
41
41
+
<div className="prose prose-stone dark:prose-invert">
42
42
+
<h3 className="text-base line-clamp-1 -mb-1 mt-3">{book.title}</h3>
43
43
+
<p className="text-sm line-clamp-1">by {book.author}</p>
44
44
+
<hr className="-mt-2 mb-1 border-stone-200 dark:border-stone-700" />
45
45
+
<p className="text-xs line-clamp-1 text-stone-600 dark:text-stone-400">
46
46
+
Read {formattedReadDate}
47
47
+
</p>
48
48
+
</div>
49
49
+
</div>
50
50
+
</a>
51
51
+
);
52
52
+
}