refactor: enhance layout and styling consistency in dashboard components, including adjustments to card headers, content, and typography for improved readability and responsiveness

This commit is contained in:
Julien Froidefond
2025-12-08 06:44:59 +01:00
parent 0321eab5b5
commit 1263ac9c52
3 changed files with 31 additions and 53 deletions

View File

@@ -48,7 +48,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<div className="grid gap-4 sm:gap-6 grid-cols-2 lg:grid-cols-4"> <div className="grid gap-4 sm:gap-6 grid-cols-2 lg:grid-cols-4">
<Card className="stat-card-gradient-1 card-hover group relative overflow-hidden"> <Card className="stat-card-gradient-1 card-hover group relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-primary/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 bg-gradient-to-br from-primary/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 relative z-10"> <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 lg:px-5 lg:pt-5 relative z-10">
<CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest"> <CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest">
Solde Total Solde Total
</CardTitle> </CardTitle>
@@ -56,10 +56,10 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<Wallet className="h-5 w-5 text-primary" /> <Wallet className="h-5 w-5 text-primary" />
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 pt-0 relative z-10"> <CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 lg:px-5 lg:pb-5 pt-0 relative z-10">
<div <div
className={cn( className={cn(
"text-2xl sm:text-3xl md:text-3xl lg:text-4xl xl:text-5xl font-black tracking-tight mb-4 leading-none", "text-2xl sm:text-3xl md:text-3xl lg:text-xl xl:text-xl font-black tracking-tight mb-4 leading-none break-words",
totalBalance >= 0 totalBalance >= 0
? "text-emerald-600 dark:text-emerald-400" ? "text-emerald-600 dark:text-emerald-400"
: "text-red-600 dark:text-red-400", : "text-red-600 dark:text-red-400",
@@ -75,7 +75,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<Card className="stat-card-gradient-2 card-hover group relative overflow-hidden"> <Card className="stat-card-gradient-2 card-hover group relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-success/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 bg-gradient-to-br from-success/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 relative z-10"> <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 lg:px-5 lg:pt-5 relative z-10">
<CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest"> <CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest">
Revenus du mois Revenus du mois
</CardTitle> </CardTitle>
@@ -83,8 +83,8 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<TrendingUp className="h-5 w-5 text-success" /> <TrendingUp className="h-5 w-5 text-success" />
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 pt-0 relative z-10"> <CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 lg:px-5 lg:pb-5 pt-0 relative z-10">
<div className="text-2xl sm:text-3xl md:text-3xl lg:text-4xl xl:text-5xl font-black tracking-tight text-success mb-4 leading-none"> <div className="text-2xl sm:text-3xl md:text-3xl lg:text-xl xl:text-xl font-black tracking-tight text-success mb-4 leading-none break-words">
{formatCurrency(income)} {formatCurrency(income)}
</div> </div>
<p className="text-xs sm:text-sm font-semibold text-muted-foreground/60"> <p className="text-xs sm:text-sm font-semibold text-muted-foreground/60">
@@ -98,7 +98,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<Card className="stat-card-gradient-3 card-hover group relative overflow-hidden"> <Card className="stat-card-gradient-3 card-hover group relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-destructive/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 bg-gradient-to-br from-destructive/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 relative z-10"> <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 lg:px-5 lg:pt-5 relative z-10">
<CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest"> <CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest">
Dépenses du mois Dépenses du mois
</CardTitle> </CardTitle>
@@ -106,8 +106,8 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<TrendingDown className="h-5 w-5 text-destructive" /> <TrendingDown className="h-5 w-5 text-destructive" />
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 pt-0 relative z-10"> <CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 lg:px-5 lg:pb-5 pt-0 relative z-10">
<div className="text-2xl sm:text-3xl md:text-3xl lg:text-4xl xl:text-5xl font-black tracking-tight text-destructive mb-4 leading-none"> <div className="text-2xl sm:text-3xl md:text-3xl lg:text-xl xl:text-xl font-black tracking-tight text-destructive mb-4 leading-none break-words">
{formatCurrency(expenses)} {formatCurrency(expenses)}
</div> </div>
<p className="text-xs sm:text-sm font-semibold text-muted-foreground/60"> <p className="text-xs sm:text-sm font-semibold text-muted-foreground/60">
@@ -121,7 +121,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<Card className="stat-card-gradient-4 card-hover group relative overflow-hidden"> <Card className="stat-card-gradient-4 card-hover group relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-chart-4/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> <div className="absolute inset-0 bg-gradient-to-br from-chart-4/8 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 relative z-10"> <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-4 px-6 pt-6 sm:px-7 sm:pt-7 lg:px-5 lg:pt-5 relative z-10">
<CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest"> <CardTitle className="text-xs font-bold text-muted-foreground/70 leading-tight uppercase tracking-widest">
Pointage Pointage
</CardTitle> </CardTitle>
@@ -129,8 +129,8 @@ export function OverviewCards({ data }: OverviewCardsProps) {
<CreditCard className="h-5 w-5 text-chart-4" /> <CreditCard className="h-5 w-5 text-chart-4" />
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 pt-0 relative z-10"> <CardContent className="px-6 pb-6 sm:px-7 sm:pb-7 lg:px-5 lg:pb-5 pt-0 relative z-10">
<div className="text-2xl sm:text-3xl md:text-3xl lg:text-4xl xl:text-5xl font-black tracking-tight mb-4 leading-none"> <div className="text-2xl sm:text-3xl md:text-3xl lg:text-xl xl:text-xl font-black tracking-tight mb-4 leading-none break-words">
{reconciledPercent}% {reconciledPercent}%
</div> </div>
<p className="text-xs sm:text-sm font-semibold text-muted-foreground/60"> <p className="text-xs sm:text-sm font-semibold text-muted-foreground/60">

View File

@@ -2,7 +2,6 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { CheckCircle2, Circle } from "lucide-react";
import { CategoryIcon } from "@/components/ui/category-icon"; import { CategoryIcon } from "@/components/ui/category-icon";
import type { BankingData } from "@/lib/types"; import type { BankingData } from "@/lib/types";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -80,26 +79,14 @@ export function RecentTransactions({ data }: RecentTransactionsProps) {
className="group rounded-2xl bg-gradient-to-r from-muted/50 via-muted/30 to-muted/20 hover:from-muted/70 hover:via-muted/50 hover:to-muted/40 border-2 border-border/40 hover:border-primary/30 transition-all duration-300 overflow-hidden hover:shadow-lg hover:shadow-primary/10 hover:scale-[1.02] backdrop-blur-sm" className="group rounded-2xl bg-gradient-to-r from-muted/50 via-muted/30 to-muted/20 hover:from-muted/70 hover:via-muted/50 hover:to-muted/40 border-2 border-border/40 hover:border-primary/30 transition-all duration-300 overflow-hidden hover:shadow-lg hover:shadow-primary/10 hover:scale-[1.02] backdrop-blur-sm"
> >
<div className="flex items-start gap-4 md:gap-5 p-4 md:p-5"> <div className="flex items-start gap-4 md:gap-5 p-4 md:p-5">
<div className="flex-shrink-0 pt-0.5">
{transaction.isReconciled ? (
<div className="rounded-2xl bg-gradient-to-br from-emerald-500/30 to-emerald-500/20 p-2 group-hover:scale-110 group-hover:rotate-3 transition-all duration-300 shadow-md shadow-emerald-500/20">
<CheckCircle2 className="w-5 h-5 md:w-6 md:h-6 text-emerald-600 dark:text-emerald-400" />
</div>
) : (
<div className="rounded-2xl bg-muted/60 p-2 group-hover:bg-muted/80 transition-all duration-300">
<Circle className="w-5 h-5 md:w-6 md:h-6 text-muted-foreground" />
</div>
)}
</div>
<div className="flex-1 min-w-0 overflow-hidden"> <div className="flex-1 min-w-0 overflow-hidden">
<div className="flex items-start justify-between gap-2"> <div className="flex items-start justify-between gap-2">
<p className="font-bold text-base md:text-lg truncate flex-1 leading-tight"> <p className="font-bold text-sm md:text-base truncate flex-1 leading-tight">
{transaction.description} {transaction.description}
</p> </p>
<div <div
className={cn( className={cn(
"font-black tabular-nums text-base md:text-lg shrink-0 md:hidden", "font-black tabular-nums text-sm md:text-base shrink-0 md:hidden",
transaction.amount >= 0 transaction.amount >= 0
? "text-emerald-600 dark:text-emerald-400" ? "text-emerald-600 dark:text-emerald-400"
: "text-red-600 dark:text-red-400", : "text-red-600 dark:text-red-400",
@@ -141,7 +128,7 @@ export function RecentTransactions({ data }: RecentTransactionsProps) {
<div <div
className={cn( className={cn(
"font-black tabular-nums text-lg md:text-xl shrink-0 hidden md:block leading-tight", "font-black tabular-nums text-base md:text-lg shrink-0 hidden md:block leading-tight",
transaction.amount >= 0 transaction.amount >= 0
? "text-emerald-600 dark:text-emerald-400" ? "text-emerald-600 dark:text-emerald-400"
: "text-red-600 dark:text-red-400", : "text-red-600 dark:text-red-400",

View File

@@ -23,22 +23,27 @@ export function PageHeader({
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return ( return (
<div className="relative flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-2"> <div className="flex flex-col gap-4 mb-2">
<div className="flex items-center gap-4 flex-1 min-w-0"> <div className="flex items-start gap-4 flex-1 min-w-0">
{isMobile && ( {isMobile && (
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
className="shrink-0 rounded-xl hover:bg-muted/60" className="shrink-0 rounded-xl hover:bg-muted/60 mt-1"
> >
<Menu className="w-5 h-5" /> <Menu className="w-5 h-5" />
</Button> </Button>
)} )}
<div className="flex-1 min-w-0 pr-20 md:pr-0"> <div className="flex-1 min-w-0">
<h1 className="text-3xl md:text-4xl lg:text-5xl font-black text-foreground tracking-tight mb-2 leading-tight"> <div className="flex items-start justify-between gap-2 mb-2">
<h1 className="text-2xl md:text-4xl lg:text-5xl font-black text-foreground tracking-tight leading-tight flex-1 min-w-0">
{title} {title}
</h1> </h1>
{rightContent && (
<div className="shrink-0">{rightContent}</div>
)}
</div>
{description && ( {description && (
<div className="text-base md:text-lg text-muted-foreground/70 font-semibold"> <div className="text-base md:text-lg text-muted-foreground/70 font-semibold">
{description} {description}
@@ -46,25 +51,11 @@ export function PageHeader({
)} )}
</div> </div>
</div> </div>
{(rightContent || actions) && (
<>
{isMobile ? (
<div className="absolute top-0 right-0 flex items-center gap-2">
{rightContent}
{actions && ( {actions && (
<div className="[&>button]:h-10 [&>button]:px-3 [&>button]:text-sm"> <div className="flex items-center gap-3 flex-wrap justify-end">
{actions} {actions}
</div> </div>
)} )}
</div> </div>
) : (
<div className="flex items-center gap-3 flex-wrap">
{rightContent}
{actions && <div className="flex gap-3">{actions}</div>}
</div>
)}
</>
)}
</div>
); );
} }