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:
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user