feat: enhance Sidebar and TransactionTable components with improved accessibility and layout adjustments; add SheetTitle for navigation context and refine padding and width for better responsiveness

This commit is contained in:
Julien Froidefond
2025-12-21 13:25:27 +01:00
parent 82e27524b5
commit 2887a6a750
3 changed files with 22 additions and 20 deletions

View File

@@ -18,7 +18,7 @@ import {
LogOut, LogOut,
} from "lucide-react"; } from "lucide-react";
import { toast } from "sonner"; import { toast } from "sonner";
import { Sheet, SheetContent } from "@/components/ui/sheet"; import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet";
import { useIsMobile } from "@/hooks/use-mobile"; import { useIsMobile } from "@/hooks/use-mobile";
import { useLocalStorage } from "@/hooks/use-local-storage"; import { useLocalStorage } from "@/hooks/use-local-storage";
@@ -165,6 +165,7 @@ export function Sidebar({ open, onOpenChange }: SidebarProps) {
return ( return (
<Sheet open={open} onOpenChange={onOpenChange}> <Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent side="left" className="w-64 p-0"> <SheetContent side="left" className="w-64 p-0">
<SheetTitle className="sr-only">Navigation</SheetTitle>
<div className="flex flex-col h-full"> <div className="flex flex-col h-full">
<SidebarContent <SidebarContent
showHeader showHeader

View File

@@ -18,7 +18,7 @@ export function PageLayout({ children }: PageLayoutProps) {
<div className="flex h-screen bg-background overflow-hidden page-background"> <div className="flex h-screen bg-background overflow-hidden page-background">
<Sidebar open={sidebarOpen} onOpenChange={setSidebarOpen} /> <Sidebar open={sidebarOpen} onOpenChange={setSidebarOpen} />
<main className="flex-1 overflow-auto overflow-x-hidden page-content"> <main className="flex-1 overflow-auto overflow-x-hidden page-content">
<div className="p-6 md:p-8 lg:p-10 space-y-6 md:space-y-8 max-w-full"> <div className="p-3 md:p-8 lg:p-10 space-y-4 md:space-y-8 max-w-full">
{children} {children}
</div> </div>
</main> </main>

View File

@@ -155,7 +155,7 @@ export function TransactionTable({
const parentRef = useRef<HTMLDivElement>(null); const parentRef = useRef<HTMLDivElement>(null);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const MOBILE_ROW_HEIGHT = 120; const MOBILE_ROW_HEIGHT = 140;
const virtualizer = useVirtualizer({ const virtualizer = useVirtualizer({
count: transactions.length, count: transactions.length,
@@ -227,17 +227,17 @@ export function TransactionTable({
); );
return ( return (
<Card className="overflow-hidden"> <Card className="overflow-hidden w-full">
<CardContent className="p-0"> <CardContent className="p-0 w-full">
{transactions.length === 0 ? ( {transactions.length === 0 ? (
<div className="flex flex-col items-center justify-center py-12"> <div className="flex flex-col items-center justify-center py-12">
<p className="text-muted-foreground">Aucune transaction trouvée</p> <p className="text-muted-foreground">Aucune transaction trouvée</p>
</div> </div>
) : isMobile ? ( ) : isMobile ? (
<div className="divide-y divide-border"> <div className="divide-y divide-border w-full">
<div <div
ref={parentRef} ref={parentRef}
className="overflow-auto" className="overflow-auto w-full"
style={{ height: "calc(100vh - 200px)", minHeight: "600px" }} style={{ height: "calc(100vh - 200px)", minHeight: "600px" }}
> >
<div <div
@@ -278,30 +278,31 @@ export function TransactionTable({
} }
}} }}
className={cn( className={cn(
"p-4 space-y-3 hover:bg-muted/50 cursor-pointer border-b border-border", "p-4 md:p-4 space-y-3 hover:bg-muted/50 cursor-pointer border-b border-border",
transaction.isReconciled && "bg-emerald-500/5", transaction.isReconciled && "bg-emerald-500/5",
isFocused && "bg-primary/10 ring-1 ring-primary/30", isFocused && "bg-primary/10 ring-1 ring-primary/30",
isDuplicate && "shadow-sm" isDuplicate && "shadow-sm"
)} )}
> >
<div className="flex items-start justify-between gap-2"> <div className="flex items-start justify-between gap-3">
<div className="flex items-start gap-3 flex-1 min-w-0"> <div className="flex items-start gap-0 md:gap-3 flex-1 min-w-0">
<Checkbox <Checkbox
checked={selectedTransactions.has(transaction.id)} checked={selectedTransactions.has(transaction.id)}
onCheckedChange={() => { onCheckedChange={() => {
onToggleSelectTransaction(transaction.id); onToggleSelectTransaction(transaction.id);
}} }}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="mt-0.5 hidden md:flex"
/> />
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<p className="font-medium text-xs md:text-sm truncate"> <p className="font-medium text-sm md:text-sm truncate leading-tight">
{transaction.description} {transaction.description}
</p> </p>
{isDuplicate && ( {isDuplicate && (
<Tooltip delayDuration={200}> <Tooltip delayDuration={200}>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<AlertTriangle className="h-3 w-3 md:h-4 md:w-4 text-[var(--warning)] shrink-0" /> <AlertTriangle className="h-4 w-4 md:h-4 md:w-4 text-[var(--warning)] shrink-0" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
<p> <p>
@@ -312,7 +313,7 @@ export function TransactionTable({
)} )}
</div> </div>
{transaction.memo && ( {transaction.memo && (
<p className="text-[10px] md:text-xs text-muted-foreground truncate mt-1"> <p className="text-xs md:text-xs text-muted-foreground truncate mt-1.5">
{transaction.memo} {transaction.memo}
</p> </p>
)} )}
@@ -320,7 +321,7 @@ export function TransactionTable({
</div> </div>
<div <div
className={cn( className={cn(
"font-semibold tabular-nums text-sm md:text-base shrink-0", "font-semibold tabular-nums text-base md:text-base shrink-0",
transaction.amount >= 0 transaction.amount >= 0
? "text-emerald-600" ? "text-emerald-600"
: "text-red-600" : "text-red-600"
@@ -331,18 +332,18 @@ export function TransactionTable({
</div> </div>
</div> </div>
<div className="flex items-center gap-2 md:gap-3 flex-wrap"> <div className="flex items-center gap-2.5 md:gap-3 flex-wrap">
<span className="text-[10px] md:text-xs text-muted-foreground"> <span className="text-xs md:text-xs text-muted-foreground">
{formatDate(transaction.date)} {formatDate(transaction.date)}
</span> </span>
{account && ( {account && (
<span className="text-[10px] md:text-xs text-muted-foreground"> <span className="text-xs md:text-xs text-muted-foreground">
{account.name} {account.name}
</span> </span>
)} )}
<div <div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="flex-1 relative" className="flex-1 relative min-w-[120px]"
> >
{updatingTransactionIds.has(transaction.id) && ( {updatingTransactionIds.has(transaction.id) && (
<div className="absolute inset-0 flex items-center justify-center bg-background/50 z-10 rounded"> <div className="absolute inset-0 flex items-center justify-center bg-background/50 z-10 rounded">
@@ -370,9 +371,9 @@ export function TransactionTable({
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
className="h-8 w-8 shrink-0" className="h-9 w-9 shrink-0"
> >
<MoreVertical className="w-4 h-4" /> <MoreVertical className="w-5 h-5" />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end"> <DropdownMenuContent align="end">