From 761c0392449132cb0f3a74582f177be403ebe68c Mon Sep 17 00:00:00 2001 From: Felipe Coutinho Date: Sat, 28 Feb 2026 13:38:41 +0000 Subject: [PATCH] refactor: melhorias de UI e responsividade mobile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Corrigir layout truncado no card de parcelas (analise-parcelas) - Empilhar cards de top estabelecimentos e categorias no mobile - Ajustes gerais de responsividade em múltiplos componentes Co-Authored-By: Claude Opus 4.6 --- app/(dashboard)/dashboard/loading.tsx | 14 +- app/(dashboard)/layout.tsx | 3 +- app/(dashboard)/top-estabelecimentos/page.tsx | 2 +- app/(landing-page)/page.tsx | 4 +- app/globals.css | 2 +- components/anotacoes/notes-page.tsx | 4 +- components/cartoes/cards-page.tsx | 4 +- components/categorias/categories-page.tsx | 4 +- components/contas/accounts-page.tsx | 4 +- .../installment-group-card.tsx | 36 +- .../dashboard/payment-status-widget.tsx | 19 +- .../basic-fields-section.tsx | 4 +- .../lancamentos/table/lancamentos-filters.tsx | 507 +++++++++--------- .../lancamentos/table/lancamentos-table.tsx | 91 ++-- components/month-picker/month-navigation.tsx | 2 +- components/month-picker/return-button.tsx | 4 +- components/navbar/app-navbar.tsx | 2 +- components/navbar/nav-items.tsx | 2 + components/navbar/nav-menu.tsx | 48 +- components/orcamentos/budgets-page.tsx | 56 +- components/pagadores/pagadores-page.tsx | 6 +- .../relatorios/category-report-filters.tsx | 13 +- .../skeletons/dashboard-grid-skeleton.tsx | 6 +- components/skeletons/widget-skeleton.tsx | 2 +- components/ui/dialog.tsx | 2 +- components/widget-card.tsx | 6 +- 26 files changed, 422 insertions(+), 425 deletions(-) diff --git a/app/(dashboard)/dashboard/loading.tsx b/app/(dashboard)/dashboard/loading.tsx index 5e6c313..40e5877 100644 --- a/app/(dashboard)/dashboard/loading.tsx +++ b/app/(dashboard)/dashboard/loading.tsx @@ -1,16 +1,20 @@ import { DashboardGridSkeleton } from "@/components/skeletons"; +import { Skeleton } from "@/components/ui/skeleton"; /** * Loading state para a página do dashboard - * Usa skeleton fiel ao layout final para evitar layout shift + * Estrutura: Welcome Banner → Month Picker → Section Cards → Widget Grid */ export default function DashboardLoading() { return ( -
- {/* Month Picker placeholder */} -
+
+ {/* Welcome Banner skeleton */} + - {/* Dashboard content skeleton */} + {/* Month Picker skeleton */} + + + {/* Dashboard content skeleton (Section Cards + Widget Grid) */}
); diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index 62d747a..624c48a 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -59,7 +59,8 @@ export default async function DashboardLayout({ preLancamentosCount={preLancamentosCount} notificationsSnapshot={notificationsSnapshot} /> -
+
+
{children} diff --git a/app/(dashboard)/top-estabelecimentos/page.tsx b/app/(dashboard)/top-estabelecimentos/page.tsx index f90efbc..deb9c5c 100644 --- a/app/(dashboard)/top-estabelecimentos/page.tsx +++ b/app/(dashboard)/top-estabelecimentos/page.tsx @@ -63,7 +63,7 @@ export default async function TopEstabelecimentosPage({ -
+
diff --git a/app/(landing-page)/page.tsx b/app/(landing-page)/page.tsx index 9ee76f4..59439c2 100644 --- a/app/(landing-page)/page.tsx +++ b/app/(landing-page)/page.tsx @@ -154,8 +154,8 @@ export default async function Page() { return (
{/* Navigation */} -
-
+
+
{/* Center Navigation Links */} diff --git a/app/globals.css b/app/globals.css index 3cea177..33211e4 100644 --- a/app/globals.css +++ b/app/globals.css @@ -105,7 +105,7 @@ /* Base surfaces - warm dark with consistent hue family */ --background: oklch(18.5% 0.002 70); --foreground: oklch(92% 0.015 80); - --card: oklch(24% 0.003 70); + --card: oklch(22.717% 0.00244 67.467); --card-foreground: oklch(92% 0.015 80); --popover: oklch(24% 0.003 70); --popover-foreground: oklch(92% 0.015 80); diff --git a/components/anotacoes/notes-page.tsx b/components/anotacoes/notes-page.tsx index d7410ab..16a3f33 100644 --- a/components/anotacoes/notes-page.tsx +++ b/components/anotacoes/notes-page.tsx @@ -197,13 +197,13 @@ export function NotesPage({ notes, archivedNotes }: NotesPageProps) { return ( <>
-
+
+ diff --git a/components/cartoes/cards-page.tsx b/components/cartoes/cards-page.tsx index fe0e1dd..bb71fb9 100644 --- a/components/cartoes/cards-page.tsx +++ b/components/cartoes/cards-page.tsx @@ -152,13 +152,13 @@ export function CardsPage({ return ( <>
-
+
+ diff --git a/components/categorias/categories-page.tsx b/components/categorias/categories-page.tsx index 74b304f..d88f8ca 100644 --- a/components/categorias/categories-page.tsx +++ b/components/categorias/categories-page.tsx @@ -95,12 +95,12 @@ export function CategoriesPage({ categories }: CategoriesPageProps) { return ( <>
-
+
+ diff --git a/components/contas/accounts-page.tsx b/components/contas/accounts-page.tsx index e41130f..09c5485 100644 --- a/components/contas/accounts-page.tsx +++ b/components/contas/accounts-page.tsx @@ -175,12 +175,12 @@ export function AccountsPage({ return ( <>
-
+
+ diff --git a/components/dashboard/installment-analysis/installment-group-card.tsx b/components/dashboard/installment-analysis/installment-group-card.tsx index ed31284..177e0ae 100644 --- a/components/dashboard/installment-analysis/installment-group-card.tsx +++ b/components/dashboard/installment-analysis/installment-group-card.tsx @@ -75,24 +75,22 @@ export function InstallmentGroupCard({ />
-
-
-
- {group.cartaoLogo && ( - {group.cartaoName} - )} - {group.name}| - - {group.cartaoName} - -
+
+
+ {group.cartaoLogo && ( + {group.cartaoName} + )} + {group.name} + + | {group.cartaoName} +
-
+
Total: -
+
{group.paidInstallments} de {group.totalInstallments} pagas -
+
{unpaidCount} {unpaidCount === 1 ? "pendente" : "pendentes"} @@ -159,7 +157,7 @@ export function InstallmentGroupCard({ {/* Lista de parcelas expandida */} {isExpanded && ( -
+
{group.pendingInstallments.map((installment) => { const isSelected = selectedInstallments.has(installment.id); const isPaid = installment.isSettled; diff --git a/components/dashboard/payment-status-widget.tsx b/components/dashboard/payment-status-widget.tsx index 70b6222..6a9fba5 100644 --- a/components/dashboard/payment-status-widget.tsx +++ b/components/dashboard/payment-status-widget.tsx @@ -38,23 +38,26 @@ function CategorySection({
{title} - +
{/* Barra de progresso */} {/* Status de confirmados e pendentes */} -
-
- - +
+
+ + confirmados
-
- - +
+ + pendentes
diff --git a/components/lancamentos/dialogs/lancamento-dialog/basic-fields-section.tsx b/components/lancamentos/dialogs/lancamento-dialog/basic-fields-section.tsx index aae7127..765ffe0 100644 --- a/components/lancamentos/dialogs/lancamento-dialog/basic-fields-section.tsx +++ b/components/lancamentos/dialogs/lancamento-dialog/basic-fields-section.tsx @@ -29,7 +29,7 @@ export function BasicFieldsSection({
-
+
-
+
+
setSearchValue(event.target.value)} placeholder="Buscar" aria-label="Buscar lançamentos" - className="w-[250px] text-sm border-dashed" + className="w-full md:w-[250px] text-sm border-dashed" /> - {exportButton} +
+ {exportButton && ( +
+ {exportButton} +
+ )} - {!hideAdvancedFilters && ( - - - - - - - Filtros - - Selecione os filtros desejados para refinar os lançamentos - - + {!hideAdvancedFilters && ( + + + + + + + Filtros + + Selecione os filtros desejados para refinar os lançamentos + + -
-
- - ( - - )} - /> -
+
+
+ + ( + + )} + /> +
-
- - ( - - )} - /> -
+
+ + ( + + )} + /> +
-
- - ( - - )} - /> -
+
+ + ( + + )} + /> +
-
- - + handleFilterChange( + "pagador", + value === FILTER_EMPTY_VALUE ? null : value, + ) + } disabled={isPending} > - - {selectedPagador ? ( - - ) : ( - "Todos" - )} - - - - Todos - {pagadorSelectOptions.map((option) => ( - - - - ))} - - -
- -
- - - - - - - - - - Nada encontrado. - - { - handleFilterChange("categoria", null); - setCategoriaOpen(false); - }} - > - Todas - {categoriaValue === FILTER_EMPTY_VALUE ? ( - - ) : null} - - {categoriaOptions.map((option) => ( + + + Todos + {pagadorSelectOptions.map((option) => ( + + + + ))} + + +
+ +
+ + + + + + + + + + Nada encontrado. + { - handleFilterChange("categoria", option.slug); + handleFilterChange("categoria", null); setCategoriaOpen(false); }} > - - {categoriaValue === option.slug ? ( + Todas + {categoriaValue === FILTER_EMPTY_VALUE ? ( ) : null} - ))} - - - - - -
+ {categoriaOptions.map((option) => ( + { + handleFilterChange("categoria", option.slug); + setCategoriaOpen(false); + }} + > + + {categoriaValue === option.slug ? ( + + ) : null} + + ))} + + + + + +
-
- - + handleFilterChange( + "contaCartao", + value === FILTER_EMPTY_VALUE ? null : value, + ) + } disabled={isPending} > - - {selectedContaCartao ? ( - - ) : ( - "Todos" - )} - - - - Todos - {contaOptions.length > 0 ? ( - - Contas - {contaOptions.map((option) => ( - - - - ))} - - ) : null} - {cartaoOptions.length > 0 ? ( - - Cartões - {cartaoOptions.map((option) => ( - - - - ))} - - ) : null} - - + + + {selectedContaCartao ? ( + + ) : ( + "Todos" + )} + + + + Todos + {contaOptions.length > 0 ? ( + + Contas + {contaOptions.map((option) => ( + + + + ))} + + ) : null} + {cartaoOptions.length > 0 ? ( + + Cartões + {cartaoOptions.map((option) => ( + + + + ))} + + ) : null} + + +
-
- - - - - - )} + + + + + + )} +
); } diff --git a/components/lancamentos/table/lancamentos-table.tsx b/components/lancamentos/table/lancamentos-table.tsx index 50cf572..21cffb6 100644 --- a/components/lancamentos/table/lancamentos-table.tsx +++ b/components/lancamentos/table/lancamentos-table.tsx @@ -3,7 +3,6 @@ import { RiAddCircleFill, RiAddCircleLine, RiArrowLeftRightLine, - RiArrowRightSLine, RiChat1Line, RiCheckLine, RiDeleteBin5Line, @@ -864,57 +863,45 @@ export function LancamentosTable({ {showTopControls ? (
{onCreate || onMassAdd ? ( -
-
-
- {onCreate ? ( - <> - - - - ) : null} - {onMassAdd ? ( - - - - - -

Adicionar múltiplos lançamentos

-
-
- ) : null} -
-
-
- -
+
+ {onCreate ? ( + <> + + + + ) : null} + {onMassAdd ? ( + + + + + +

Adicionar múltiplos lançamentos

+
+
+ ) : null}
) : ( diff --git a/components/month-picker/month-navigation.tsx b/components/month-picker/month-navigation.tsx index 1daca24..23ae542 100644 --- a/components/month-picker/month-navigation.tsx +++ b/components/month-picker/month-navigation.tsx @@ -79,7 +79,7 @@ export default function MonthNavigation() { }; return ( - +
- Ir para Mês Atual + Mês Atual ); } diff --git a/components/navbar/app-navbar.tsx b/components/navbar/app-navbar.tsx index 24b73df..a68d485 100644 --- a/components/navbar/app-navbar.tsx +++ b/components/navbar/app-navbar.tsx @@ -26,7 +26,7 @@ export function AppNavbar({ notificationsSnapshot, }: AppNavbarProps) { return ( -
+
{/* Logo */} diff --git a/components/navbar/nav-items.tsx b/components/navbar/nav-items.tsx index 846ba09..c2bfe6a 100644 --- a/components/navbar/nav-items.tsx +++ b/components/navbar/nav-items.tsx @@ -18,6 +18,7 @@ export type NavItem = { icon: React.ReactNode; badge?: number; preservePeriod?: boolean; + hideOnMobile?: boolean; }; export type NavSection = { @@ -44,6 +45,7 @@ export const NAV_SECTIONS: NavSection[] = [ href: "/calendario", label: "calendário", icon: , + hideOnMobile: true, }, ], }, diff --git a/components/navbar/nav-menu.tsx b/components/navbar/nav-menu.tsx index 212fff9..8a2b1d8 100644 --- a/components/navbar/nav-menu.tsx +++ b/components/navbar/nav-menu.tsx @@ -31,7 +31,7 @@ export function NavMenu() { return ( <> {/* Desktop */} -
-
+
+ + Copiar orçamentos do último mês +
{hasBudgets ? ( diff --git a/components/pagadores/pagadores-page.tsx b/components/pagadores/pagadores-page.tsx index c116339..67bad5d 100644 --- a/components/pagadores/pagadores-page.tsx +++ b/components/pagadores/pagadores-page.tsx @@ -131,7 +131,7 @@ export function PagadoresPage({ mode="create" avatarOptions={avatarOptions} trigger={ - @@ -139,14 +139,14 @@ export function PagadoresPage({ />
setShareCodeInput(event.target.value)} disabled={joinPending} - className="w-56 border-dashed" + className="w-full sm:w-56 border-dashed" />
{/* Export Button */} - {exportButton} +
{exportButton}
{/* Validation Message */} diff --git a/components/skeletons/dashboard-grid-skeleton.tsx b/components/skeletons/dashboard-grid-skeleton.tsx index 2d32da7..291122e 100644 --- a/components/skeletons/dashboard-grid-skeleton.tsx +++ b/components/skeletons/dashboard-grid-skeleton.tsx @@ -11,9 +11,9 @@ export function DashboardGridSkeleton() { {/* Section Cards no topo */} - {/* Grid de widgets */} -
- {Array.from({ length: 12 }).map((_, i) => ( + {/* Grid de widgets - mesmos breakpoints do dashboard real */} +
+ {Array.from({ length: 9 }).map((_, i) => ( ))}
diff --git a/components/skeletons/widget-skeleton.tsx b/components/skeletons/widget-skeleton.tsx index f60759c..2e35cce 100644 --- a/components/skeletons/widget-skeleton.tsx +++ b/components/skeletons/widget-skeleton.tsx @@ -7,7 +7,7 @@ import { Skeleton } from "@/components/ui/skeleton"; */ export function WidgetSkeleton() { return ( - +
diff --git a/components/ui/dialog.tsx b/components/ui/dialog.tsx index c65f80c..3293414 100644 --- a/components/ui/dialog.tsx +++ b/components/ui/dialog.tsx @@ -56,7 +56,7 @@ function DialogContent({ - - + + {icon} {title} @@ -121,7 +121,7 @@ export default function WidgetCard({

{subtitle}

) : null}
-
+
{children}