From d3476a1d8a618702e4623d90f8848dea695f73e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Tue, 20 Oct 2026 21:26:09 +0200
Subject: [PATCH 01/28] refactor: use shadcn Button for FavoriteButton
---
.../FavoriteButton/FavoriteButton.tsx | 17 +++++++++++------
frontend/app/index.css | 8 ++++++++
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/frontend/app/components/FavoriteButton/FavoriteButton.tsx b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
index 26c74e3..5b5014a 100644
--- a/frontend/app/components/FavoriteButton/FavoriteButton.tsx
+++ b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
@@ -1,4 +1,5 @@
import { useState } from "react";
+import { Button } from "~/components/ui/Button";
import { CheckIcon } from "~/components/icons/CheckIcon";
import type { Book } from "~/api/types";
@@ -27,21 +28,25 @@ function FavoriteButton({ book }: FavoriteButtonProps) {
setFavorites(savedFavorites);
};
+ const isFavorite = favorites.includes(book.id);
+
return (
-
+ {isFavorite ? : "+"}
+
);
}
diff --git a/frontend/app/index.css b/frontend/app/index.css
index d17f6d2..665339d 100644
--- a/frontend/app/index.css
+++ b/frontend/app/index.css
@@ -32,11 +32,17 @@
footer {
@apply mt-auto;
}
+
+ button:not(:disabled),
+ [role="button"]:not(:disabled) {
+ cursor: pointer;
+ }
}
@theme inline {
--font-heading: var(--font-sans);
--font-sans: "Inter Variable", sans-serif;
+ --color-favorite-button: var(--favorite-button);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -110,6 +116,7 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
+ --favorite-button: oklch(0.985 0 0);
}
.dark {
@@ -144,4 +151,5 @@
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
+ --favorite-button: oklch(0.220 0 0);
}
From 6b4ee4f47d75e3650d2e6d91d633b9e0d8b66c20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Tue, 20 Oct 2026 22:54:49 +0200
Subject: [PATCH 02/28] refactor: use shadcn Card in BookCard
---
frontend/app/components/BookCard/BookCard.tsx | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/frontend/app/components/BookCard/BookCard.tsx b/frontend/app/components/BookCard/BookCard.tsx
index b8533a6..4ef9db4 100644
--- a/frontend/app/components/BookCard/BookCard.tsx
+++ b/frontend/app/components/BookCard/BookCard.tsx
@@ -1,5 +1,6 @@
import { BookCover } from "~/components/BookCover/BookCover";
import { FavoriteButton } from "~/components/FavoriteButton/FavoriteButton";
+import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/Card";
import type { Book } from "~/api/types";
import { Link, useSearchParams } from "react-router";
@@ -11,7 +12,7 @@ function BookCard({ book }: BookCardProps) {
const [searchParams] = useSearchParams();
return (
-
+
-
+
+
+
+
+
+ {book.title}
+
-
- {book.title}
+
{book.author.join(", ")}
{book.publishedYear ?? "Unknown"}
-
+
-
+
);
}
From aae070b13ef6dfd8c75b5d29413cdb6fcf0277e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Tue, 20 Oct 2026 22:55:38 +0200
Subject: [PATCH 03/28] feat: add hover animations to BookCard
---
frontend/app/components/BookCard/BookCard.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/app/components/BookCard/BookCard.tsx b/frontend/app/components/BookCard/BookCard.tsx
index 4ef9db4..d75b1bf 100644
--- a/frontend/app/components/BookCard/BookCard.tsx
+++ b/frontend/app/components/BookCard/BookCard.tsx
@@ -12,7 +12,7 @@ function BookCard({ book }: BookCardProps) {
const [searchParams] = useSearchParams();
return (
-
+
-
+
-
+
{book.title}
From f5fd7a4ce04e98b3933c69128c56644ed4ada3c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Wed, 21 Oct 2026 20:16:19 +0200
Subject: [PATCH 04/28] feat: add shadcn pagination with page links
---
.../app/components/Pagination/Pagination.tsx | 124 ++++++++++++++----
frontend/app/components/ui/Pagination.tsx | 27 ++--
2 files changed, 108 insertions(+), 43 deletions(-)
diff --git a/frontend/app/components/Pagination/Pagination.tsx b/frontend/app/components/Pagination/Pagination.tsx
index 814376c..1d65527 100644
--- a/frontend/app/components/Pagination/Pagination.tsx
+++ b/frontend/app/components/Pagination/Pagination.tsx
@@ -1,40 +1,108 @@
import { useSearchParams } from "react-router";
+import {
+ Pagination as PaginationRoot,
+ PaginationContent,
+ PaginationEllipsis,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+} from "~/components/ui/Pagination";
+
+const DISABLED_STYLE = "pointer-events-none opacity-50";
function Pagination({ totalPages }: { totalPages: number }) {
- const [searchParams, setSearchParams] = useSearchParams();
+ const [searchParams] = useSearchParams();
const currentPage = parseInt(searchParams.get("page") ?? "1");
- const handlePageChange = (newPage: number) => {
- window.scrollTo({ top: 0, behavior: "smooth" });
+ const isFirstPage = currentPage === 1;
+ const isLastPage = currentPage === totalPages;
+
+ // Pages around the current page (one before, current, one after)
+ // For each page in the list, keep only page numbers larger than 1 and less than the last page
+ const middlePages = [currentPage - 1, currentPage, currentPage + 1].filter(
+ (page) => page > 1 && page < totalPages,
+ );
+
+ // Show ellipsis when there is a gap between the first/last page and the middle pages
+ const showStartEllipsis = currentPage > 3;
+ const showEndEllipsis = currentPage < totalPages - 2;
+
+ // Only show the last page separately if there is more than 1 page, so page 1 is not rendered twice
+ const showLastPage = totalPages > 1;
- setSearchParams((prev) => {
- prev.set("page", newPage.toString());
- return prev;
- });
+ const getValidPage = (page: number) => {
+ if (page < 1) return 1;
+ if (page > totalPages) return totalPages;
+ return page;
};
- return (
-
-
-
- {currentPage} of {totalPages}
-
-
-
+ {page}
+
+
+ );
+
+ return (
+
+
+
+
+
+
+ {renderPageLink(1)}
+
+ {showStartEllipsis && (
+
+
+
+ )}
+
+ {middlePages.map((page) => renderPageLink(page))}
+
+ {showEndEllipsis && (
+
+
+
+ )}
+
+ {showLastPage && renderPageLink(totalPages)}
+
+
+
+
+
+
);
}
diff --git a/frontend/app/components/ui/Pagination.tsx b/frontend/app/components/ui/Pagination.tsx
index b2c7ab1..54a2fd8 100644
--- a/frontend/app/components/ui/Pagination.tsx
+++ b/frontend/app/components/ui/Pagination.tsx
@@ -1,7 +1,8 @@
import * as React from "react";
import { cn } from "cn";
+import { Link } from "react-router";
-import { Button } from "~/components/ui/Button";
+import { Button, buttonVariants } from "~/components/ui/Button";
import {
ChevronLeftIcon,
ChevronRightIcon,
@@ -40,7 +41,7 @@ function PaginationItem({ ...props }: React.ComponentProps<"li">) {
type PaginationLinkProps = {
isActive?: boolean;
} & Pick, "size"> &
- React.ComponentProps<"a">;
+ React.ComponentProps;
function PaginationLink({
className,
@@ -49,19 +50,15 @@ function PaginationLink({
...props
}: PaginationLinkProps) {
return (
-
- }
+
);
}
From 12a8b09c779e42f7875bb3c9c05e36dabf898253 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Wed, 21 Oct 2026 20:39:27 +0200
Subject: [PATCH 05/28] fix: Keep favorite button above book cover
---
frontend/app/components/FavoriteButton/FavoriteButton.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/app/components/FavoriteButton/FavoriteButton.tsx b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
index 5b5014a..a939e5c 100644
--- a/frontend/app/components/FavoriteButton/FavoriteButton.tsx
+++ b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
@@ -35,7 +35,7 @@ function FavoriteButton({ book }: FavoriteButtonProps) {
type="button"
variant="outline"
size="icon"
- className={`absolute right-2 top-2 bg-favorite-button text-xl ${isFavorite ? "border-primary text-primary" : ""}`}
+ className={`absolute right-2 top-2 z-10 bg-favorite-button text-xl ${isFavorite ? "border-primary text-primary" : ""}`}
onClick={saveFavorite}
aria-label={
// Toggle the accessibility label based on the current state for screen readers
From 90a77eb97c58386b225e27d68a5f82ee98443ca3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Wed, 21 Oct 2026 21:34:30 +0200
Subject: [PATCH 06/28] feat: add hover style to pagination links
---
frontend/app/components/Pagination/Pagination.tsx | 7 ++++---
frontend/app/index.css | 3 +++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/frontend/app/components/Pagination/Pagination.tsx b/frontend/app/components/Pagination/Pagination.tsx
index 1d65527..6ab0db5 100644
--- a/frontend/app/components/Pagination/Pagination.tsx
+++ b/frontend/app/components/Pagination/Pagination.tsx
@@ -10,6 +10,7 @@ import {
} from "~/components/ui/Pagination";
const DISABLED_STYLE = "pointer-events-none opacity-50";
+const HOVER_STYLE = "transition-colors duration-200 hover:bg-hover-surface hover:text-foreground/90";
function Pagination({ totalPages }: { totalPages: number }) {
const [searchParams] = useSearchParams();
@@ -54,7 +55,7 @@ function Pagination({ totalPages }: { totalPages: number }) {
to={getPageLink(page)}
onClick={handlePageChange}
isActive={page === currentPage}
- className="min-w-8 w-auto px-3"
+ className={`min-w-8 w-auto px-3 ${HOVER_STYLE}`}
>
{page}
@@ -70,7 +71,7 @@ function Pagination({ totalPages }: { totalPages: number }) {
onClick={handlePageChange}
aria-disabled={isFirstPage}
tabIndex={isFirstPage ? -1 : undefined} // -1 means the link is skipped when tabbing
- className={isFirstPage ? DISABLED_STYLE : undefined}
+ className={isFirstPage ? DISABLED_STYLE : HOVER_STYLE}
/>
@@ -98,7 +99,7 @@ function Pagination({ totalPages }: { totalPages: number }) {
onClick={handlePageChange}
aria-disabled={isLastPage}
tabIndex={isLastPage ? -1 : undefined} // -1 means the link is skipped when tabbing
- className={isLastPage ? DISABLED_STYLE : undefined}
+ className={isLastPage ? DISABLED_STYLE : HOVER_STYLE}
/>
diff --git a/frontend/app/index.css b/frontend/app/index.css
index 665339d..6433c61 100644
--- a/frontend/app/index.css
+++ b/frontend/app/index.css
@@ -42,6 +42,7 @@
@theme inline {
--font-heading: var(--font-sans);
--font-sans: "Inter Variable", sans-serif;
+ --color-hover-surface: var(--hover-surface);
--color-favorite-button: var(--favorite-button);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
@@ -117,6 +118,7 @@
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--favorite-button: oklch(0.985 0 0);
+ --hover-surface: oklch(0.985 0 0);
}
.dark {
@@ -152,4 +154,5 @@
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--favorite-button: oklch(0.220 0 0);
+ --hover-surface: oklch(0.220 0 0);
}
From 46f72f5d2511bba83ad9ac6b34f36ea65ced5316 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Wed, 21 Oct 2026 22:18:01 +0200
Subject: [PATCH 07/28] feat: add keyboard focus ring to BookCard
---
frontend/app/components/BookCard/BookCard.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/app/components/BookCard/BookCard.tsx b/frontend/app/components/BookCard/BookCard.tsx
index d75b1bf..bb3a22a 100644
--- a/frontend/app/components/BookCard/BookCard.tsx
+++ b/frontend/app/components/BookCard/BookCard.tsx
@@ -12,9 +12,7 @@ function BookCard({ book }: BookCardProps) {
const [searchParams] = useSearchParams();
return (
-
-
-
+
{book.publishedYear ?? "Unknown"}
+
+
);
}
From 88d26968e123a05b21bc8792fc398cae35f42642 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Wed, 21 Oct 2026 22:23:58 +0200
Subject: [PATCH 08/28] feat: use shadcn input group in SearchBar
---
.../app/components/SearchBar/SearchBar.tsx | 69 +++++++++++++------
frontend/app/components/icons/SearchIcon.tsx | 23 +++++++
frontend/app/components/ui/Button.tsx | 1 +
frontend/app/routes/home.tsx | 4 +-
4 files changed, 75 insertions(+), 22 deletions(-)
create mode 100644 frontend/app/components/icons/SearchIcon.tsx
diff --git a/frontend/app/components/SearchBar/SearchBar.tsx b/frontend/app/components/SearchBar/SearchBar.tsx
index a4345d9..466abbf 100644
--- a/frontend/app/components/SearchBar/SearchBar.tsx
+++ b/frontend/app/components/SearchBar/SearchBar.tsx
@@ -1,13 +1,26 @@
import { useEffect, useRef, useState } from "react";
import { FilterIcon } from "~/components/icons/FilterIcon";
+import { SearchIcon } from "~/components/icons/SearchIcon";
import { FilterBooksSection } from "~/components/FilterBooksSection/FilterBooksSection";
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+ InputGroupText,
+} from "~/components/ui/InputGroup";
+import { Button } from "~/components/ui/Button";
+import { Badge } from "~/components/ui/Badge";
import { useSearchParams } from "react-router";
import { useDebounce } from "~/api/useDebounce";
import { useBookSearchParams } from "~/api/useBookSearchParams";
const SEARCH_DEBOUNCE_MS = 500;
-function SearchBar() {
+interface SearchBarProps {
+ resultCount?: number;
+}
+
+function SearchBar({ resultCount }: SearchBarProps) {
const { rawQuery: query, filters } = useBookSearchParams();
const [, setSearchParams] = useSearchParams();
@@ -47,35 +60,51 @@ function SearchBar() {
return (
<>
-
{filtersOpen && }
>
diff --git a/frontend/app/components/icons/SearchIcon.tsx b/frontend/app/components/icons/SearchIcon.tsx
new file mode 100644
index 0000000..d8cf75a
--- /dev/null
+++ b/frontend/app/components/icons/SearchIcon.tsx
@@ -0,0 +1,23 @@
+// Found as a part of Lucide:
+// https://lucide.dev/icons/search
+
+function SearchIcon() {
+ return (
+
+ );
+}
+
+export { SearchIcon };
diff --git a/frontend/app/components/ui/Button.tsx b/frontend/app/components/ui/Button.tsx
index 4212cbb..f70fd70 100644
--- a/frontend/app/components/ui/Button.tsx
+++ b/frontend/app/components/ui/Button.tsx
@@ -30,6 +30,7 @@ const buttonVariants = cva(
"icon-sm":
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
"icon-lg": "size-9",
+ "icon-xl": "size-10",
},
},
defaultVariants: {
diff --git a/frontend/app/routes/home.tsx b/frontend/app/routes/home.tsx
index 76983a4..9d0871e 100644
--- a/frontend/app/routes/home.tsx
+++ b/frontend/app/routes/home.tsx
@@ -53,7 +53,7 @@ export default function HomePage() {
if (books.length === 0) {
return (
-
+
-
+
{books.map((book) => (
-
From 371da7005d979c5efe05c1ecd9a92d2293e0d685 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Thu, 22 Oct 2026 00:29:39 +0200
Subject: [PATCH 09/28] feat: add shadcn Popover component
---
frontend/app/components/ui/Popover.tsx | 87 ++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
create mode 100644 frontend/app/components/ui/Popover.tsx
diff --git a/frontend/app/components/ui/Popover.tsx b/frontend/app/components/ui/Popover.tsx
new file mode 100644
index 0000000..904781c
--- /dev/null
+++ b/frontend/app/components/ui/Popover.tsx
@@ -0,0 +1,87 @@
+import * as React from "react"
+import { Popover as PopoverPrimitive } from "@base-ui/react/popover"
+import { cn } from "cn"
+
+function Popover({ ...props }: PopoverPrimitive.Root.Props) {
+ return
+}
+
+function PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {
+ return
+}
+
+function PopoverContent({
+ className,
+ align = "center",
+ alignOffset = 0,
+ side = "bottom",
+ sideOffset = 4,
+ ...props
+}: PopoverPrimitive.Popup.Props &
+ Pick<
+ PopoverPrimitive.Positioner.Props,
+ "align" | "alignOffset" | "side" | "sideOffset"
+ >) {
+ return (
+
+
+
+
+
+ )
+}
+
+function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {
+ return (
+
+ )
+}
+
+function PopoverDescription({
+ className,
+ ...props
+}: PopoverPrimitive.Description.Props) {
+ return (
+
+ )
+}
+
+export {
+ Popover,
+ PopoverContent,
+ PopoverDescription,
+ PopoverHeader,
+ PopoverTitle,
+ PopoverTrigger,
+}
From f7d34898bf0a126fad773177aade9d0460d2d998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Thu, 22 Oct 2026 00:31:19 +0200
Subject: [PATCH 10/28] feat: add shadcn components for filters
---
.../FilterBooksSection/FilterBooksSection.tsx | 105 ++++++++++++------
.../app/components/SearchBar/SearchBar.tsx | 83 ++++++++------
2 files changed, 120 insertions(+), 68 deletions(-)
diff --git a/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx b/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
index e3651fe..9dd9e0c 100644
--- a/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
+++ b/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
@@ -1,6 +1,20 @@
import type { BookFilters } from "~/api/types";
import { languageCodes } from "~/api/languageCodes";
import { CircleQuestionMark } from "~/components/icons/CircleQuestionMark";
+import { Input } from "~/components/ui/Input";
+import { Label } from "~/components/ui/Label";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "~/components/ui/Select";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "~/components/ui/Tooltip";
import { useSearchParams } from "react-router";
import { useBookSearchParams } from "~/api/useBookSearchParams";
import { useDebounce } from "~/api/useDebounce";
@@ -38,6 +52,17 @@ const FILTER_INPUTS: {
},
];
+const LANGUAGE_ITEMS = [
+ {
+ value: "none",
+ label: "Select a language",
+ },
+ ...languageCodes.map((lang) => ({
+ value: lang.code,
+ label: lang.name,
+ })),
+];
+
function FilterBooksSection() {
const [, setSearchParams] = useSearchParams();
const { filters: rawFilters } = useBookSearchParams();
@@ -70,17 +95,17 @@ function FilterBooksSection() {
}, [debouncedFilters, rawFilters, setSearchParams]);
return (
-
-
Filter Books
-
+
diff --git a/frontend/app/components/SearchBar/SearchBar.tsx b/frontend/app/components/SearchBar/SearchBar.tsx
index 466abbf..5f7c639 100644
--- a/frontend/app/components/SearchBar/SearchBar.tsx
+++ b/frontend/app/components/SearchBar/SearchBar.tsx
@@ -10,6 +10,11 @@ import {
} from "~/components/ui/InputGroup";
import { Button } from "~/components/ui/Button";
import { Badge } from "~/components/ui/Badge";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "~/components/ui/Popover";
import { useSearchParams } from "react-router";
import { useDebounce } from "~/api/useDebounce";
import { useBookSearchParams } from "~/api/useBookSearchParams";
@@ -51,7 +56,6 @@ function SearchBar({ resultCount }: SearchBarProps) {
newQueryFromInputRef.current = false;
}, [debouncedQuery, inputField, query, setSearchParams]);
- const [filtersOpen, setFiltersOpen] = useState(false);
const filtersCount = Object.values(filters).filter(
(value) => value !== undefined,
).length;
@@ -59,41 +63,44 @@ function SearchBar({ resultCount }: SearchBarProps) {
const filtersDescription = `${filtersCount} ${filtersCount === 1 ? "filter" : "filters"} active`;
return (
- <>
-
-
-
-
-
+
+
+
+
+
- {
- newQueryFromInputRef.current = true;
- setInputField(e.target.value);
- }}
- />
+ {
+ newQueryFromInputRef.current = true;
+ setInputField(e.target.value);
+ }}
+ />
- {resultCount !== undefined && (
-
-
- {resultCount} {resultCount === 1 ? "result" : "results"}
-
-
- )}
-
+ {resultCount !== undefined && (
+
+
+ {resultCount} {resultCount === 1 ? "result" : "results"}
+
+
+ )}
+
-
-
- {filtersOpen && }
- >
+
+
+
+
+
+
);
}
From ce48cb2ec84e670eae55983f986d40a053638a21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Thu, 22 Oct 2026 01:08:13 +0200
Subject: [PATCH 11/28] fix: improve accessibility of language filter tooltip
---
.../FilterBooksSection/FilterBooksSection.tsx | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx b/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
index 9dd9e0c..e8b5078 100644
--- a/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
+++ b/frontend/app/components/FilterBooksSection/FilterBooksSection.tsx
@@ -119,21 +119,19 @@ function FilterBooksSection() {
))}
-
-
+
);
}
From 65d2590e3fa902a11390f96c38ffa802cd72c6bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Str=C3=B8m-Andersen?=
Date: Sat, 24 Oct 2026 13:14:41 +0200
Subject: [PATCH 27/28] refactor: rename breadcrumb component to PageBreadcrumb
---
.../PageBreadcrumb.tsx} | 10 +++++-----
frontend/app/routes/book/selectedBook.tsx | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
rename frontend/app/components/{Breadcrumb/Breadcrumb.tsx => PageBreadcrumb/PageBreadcrumb.tsx} (83%)
diff --git a/frontend/app/components/Breadcrumb/Breadcrumb.tsx b/frontend/app/components/PageBreadcrumb/PageBreadcrumb.tsx
similarity index 83%
rename from frontend/app/components/Breadcrumb/Breadcrumb.tsx
rename to frontend/app/components/PageBreadcrumb/PageBreadcrumb.tsx
index 7a71c21..82ebe92 100644
--- a/frontend/app/components/Breadcrumb/Breadcrumb.tsx
+++ b/frontend/app/components/PageBreadcrumb/PageBreadcrumb.tsx
@@ -1,7 +1,7 @@
import { Fragment } from "react";
import { Link, type To } from "react-router";
import {
- Breadcrumb as BreadcrumbRoot,
+ Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
@@ -16,9 +16,9 @@ interface BreadcrumbProps {
}[];
}
-function Breadcrumb({ items }: BreadcrumbProps) {
+function PageBreadcrumb({ items }: BreadcrumbProps) {
return (
-
+
{items.map((item, index) => (
@@ -37,8 +37,8 @@ function Breadcrumb({ items }: BreadcrumbProps) {
))}
-
+
);
}
-export { Breadcrumb };
+export { PageBreadcrumb };
diff --git a/frontend/app/routes/book/selectedBook.tsx b/frontend/app/routes/book/selectedBook.tsx
index e0b188d..cf9c0a5 100644
--- a/frontend/app/routes/book/selectedBook.tsx
+++ b/frontend/app/routes/book/selectedBook.tsx
@@ -1,5 +1,5 @@
import type { Route } from "./+types/selectedBook";
-import { Breadcrumb } from "~/components/Breadcrumb/Breadcrumb";
+import { PageBreadcrumb } from "~/components/PageBreadcrumb/PageBreadcrumb";
import { BookCover } from "~/components/BookCover/BookCover";
import { FavoriteButton } from "~/components/FavoriteButton/FavoriteButton";
import { BookDescription } from "~/components/BookDescription/BookDescription";
@@ -59,7 +59,7 @@ export default function SelectedBookPage({ params }: Route.ComponentProps) {
return (
-
Date: Sun, 25 Oct 2026 00:32:18 +0200
Subject: [PATCH 28/28] fix: adjust FavoriteButton size and variant after merge
with main
---
frontend/app/components/FavoriteButton/FavoriteButton.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend/app/components/FavoriteButton/FavoriteButton.tsx b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
index d2e53ef..20bc2f8 100644
--- a/frontend/app/components/FavoriteButton/FavoriteButton.tsx
+++ b/frontend/app/components/FavoriteButton/FavoriteButton.tsx
@@ -55,6 +55,8 @@ function FavoriteButton({ book }: FavoriteButtonProps) {
<>