From 0611ef715c04df907495214e5f9aacc55046ff7b Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Wed, 14 Jan 2026 22:18:50 +0100 Subject: [PATCH] feat(ui): add `ViewCounter` component and enhance accessibility annotations Introduce a new `ViewCounter` component to manage view tracking for content. Add biome-ignore comments for accessibility standards in several UI components, enhance semantic element usage, and improve tag handling in `SearchSidebar`. --- frontend/src/components/search-sidebar.tsx | 37 +++++++++++++-------- frontend/src/components/ui/breadcrumb.tsx | 2 -- frontend/src/components/ui/button-group.tsx | 1 + frontend/src/components/ui/carousel.tsx | 2 ++ frontend/src/components/ui/field.tsx | 1 + frontend/src/components/ui/input-group.tsx | 2 ++ frontend/src/components/ui/input-otp.tsx | 2 +- frontend/src/components/ui/item.tsx | 1 + frontend/src/components/ui/sidebar.tsx | 1 + frontend/src/components/view-counter.tsx | 23 +++++++++++++ 10 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 frontend/src/components/view-counter.tsx diff --git a/frontend/src/components/search-sidebar.tsx b/frontend/src/components/search-sidebar.tsx index 5acfc49..71da096 100644 --- a/frontend/src/components/search-sidebar.tsx +++ b/frontend/src/components/search-sidebar.tsx @@ -8,7 +8,8 @@ import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import { CategoryService } from "@/services/category.service"; -import type { Category } from "@/types/content"; +import { TagService } from "@/services/tag.service"; +import type { Category, Tag } from "@/types/content"; export function SearchSidebar() { const router = useRouter(); @@ -16,10 +17,14 @@ export function SearchSidebar() { const pathname = usePathname(); const [categories, setCategories] = React.useState([]); + const [popularTags, setPopularTags] = React.useState([]); const [query, setQuery] = React.useState(searchParams.get("query") || ""); React.useEffect(() => { CategoryService.getAll().then(setCategories).catch(console.error); + TagService.getAll({ limit: 10, sort: "popular" }) + .then(setPopularTags) + .catch(console.error); }, []); const updateSearch = React.useCallback( @@ -116,19 +121,23 @@ export function SearchSidebar() {

Tags populaires

- {["funny", "coding", "cat", "dog", "work", "relatable", "gaming"].map( - (tag) => ( - - updateSearch("tag", searchParams.get("tag") === tag ? null : tag) - } - > - #{tag} - - ), + {popularTags.map((tag) => ( + + updateSearch( + "tag", + searchParams.get("tag") === tag.name ? null : tag.name, + ) + } + > + #{tag.name} + + ))} + {popularTags.length === 0 && ( +

Aucun tag trouvé.

)}
diff --git a/frontend/src/components/ui/breadcrumb.tsx b/frontend/src/components/ui/breadcrumb.tsx index acf0a22..e390bd1 100644 --- a/frontend/src/components/ui/breadcrumb.tsx +++ b/frontend/src/components/ui/breadcrumb.tsx @@ -53,8 +53,6 @@ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) { return ( & VariantProps) { return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for button groups
+ {/* biome-ignore lint/a11y/useSemanticElements: standard pattern for carousels */}
) { const { orientation } = useCarousel(); return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for carousel items
& VariantProps) { return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for field components
) { return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for input groups
& VariantProps) { return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for input groups
) { return ( -
+ ); diff --git a/frontend/src/components/ui/item.tsx b/frontend/src/components/ui/item.tsx index d974f90..f9451f9 100644 --- a/frontend/src/components/ui/item.tsx +++ b/frontend/src/components/ui/item.tsx @@ -6,6 +6,7 @@ import { cn } from "@/lib/utils"; function ItemGroup({ className, ...props }: React.ComponentProps<"div">) { return ( + // biome-ignore lint/a11y/useSemanticElements: standard pattern for item groups
{ + if (!hasIncremented.current) { + ContentService.incrementViews(contentId).catch((err) => { + console.error("Failed to increment views:", err); + }); + hasIncremented.current = true; + } + }, [contentId]); + + return null; +}