diff --git a/CHANGELOG.md b/CHANGELOG.md index be1368c..dfd5fb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ Todas as mudanças notáveis deste projeto serão documentadas neste arquivo. O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/), e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/). +## [1.7.0] - 2026-02-24 + +### Adicionado + +- **Topbar de navegação** como experimento: substitui o header fixo por uma topbar com backdrop blur (`bg-card/80`), agrupando os links de navegação em 5 grupos lógicos (Dashboard, Lançamentos, Cartões, Relatórios, Ferramentas) +- **Dropdown "Ferramentas"** na topbar: consolida calculadora e modo privacidade em um único menu (`components/topbar/ferramentas-dropdown.tsx`) +- **NotificationBell expandida**: passa a exibir notificações de orçamentos estourados e pré-lançamentos pendentes além das notificações gerais, com seções separadas por tipo e contagem agregada + +### Alterado + +- **Logo** refatorado com variante `compact` usada na topbar +- **TopbarUser**: incorpora o botão de logout (antes em `logout-button.tsx` separado) +- **Topbar**: links em lowercase; layout centralizado em `max-w-8xl`; `radix-ui ^1.4.3` adicionado como dependência +- **Gráfico de relatório de categorias** (`category-report-chart`): refatoração interna + +### Removido + +- `components/header-dashboard.tsx` — substituído pela topbar +- `components/auth/logout-button.tsx` — lógica incorporada ao `TopbarUser` +- `components/privacy-mode-toggle.tsx` — movido para o `FerramentasDropdown` + ## [1.6.3] - 2026-02-19 ### Corrigido diff --git a/app/(dashboard)/ajustes/layout.tsx b/app/(dashboard)/ajustes/layout.tsx index 874e3a5..4c4099e 100644 --- a/app/(dashboard)/ajustes/layout.tsx +++ b/app/(dashboard)/ajustes/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Ajustes" diff --git a/app/(dashboard)/anotacoes/layout.tsx b/app/(dashboard)/anotacoes/layout.tsx index d0fda75..a459077 100644 --- a/app/(dashboard)/anotacoes/layout.tsx +++ b/app/(dashboard)/anotacoes/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Notas" diff --git a/app/(dashboard)/calendario/layout.tsx b/app/(dashboard)/calendario/layout.tsx index ae2d427..4686a63 100644 --- a/app/(dashboard)/calendario/layout.tsx +++ b/app/(dashboard)/calendario/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Calendário" diff --git a/app/(dashboard)/cartoes/[cartaoId]/fatura/loading.tsx b/app/(dashboard)/cartoes/[cartaoId]/fatura/loading.tsx index 82394e7..5e09e9a 100644 --- a/app/(dashboard)/cartoes/[cartaoId]/fatura/loading.tsx +++ b/app/(dashboard)/cartoes/[cartaoId]/fatura/loading.tsx @@ -22,7 +22,7 @@ export default function FaturaLoading() { {/* Seção de lançamentos */}
-
+
{/* Header */}
diff --git a/app/(dashboard)/cartoes/layout.tsx b/app/(dashboard)/cartoes/layout.tsx index 071a76a..20cd696 100644 --- a/app/(dashboard)/cartoes/layout.tsx +++ b/app/(dashboard)/cartoes/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Cartões" diff --git a/app/(dashboard)/cartoes/loading.tsx b/app/(dashboard)/cartoes/loading.tsx index 1145fb1..4908802 100644 --- a/app/(dashboard)/cartoes/loading.tsx +++ b/app/(dashboard)/cartoes/loading.tsx @@ -3,7 +3,7 @@ import { Skeleton } from "@/components/ui/skeleton"; export default function CartoesLoading() { return (
-
+
{/* Header */}
diff --git a/app/(dashboard)/categorias/layout.tsx b/app/(dashboard)/categorias/layout.tsx index 57932f2..bb2e67f 100644 --- a/app/(dashboard)/categorias/layout.tsx +++ b/app/(dashboard)/categorias/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Categorias" diff --git a/app/(dashboard)/contas/[contaId]/extrato/loading.tsx b/app/(dashboard)/contas/[contaId]/extrato/loading.tsx index efd7e3e..02fa036 100644 --- a/app/(dashboard)/contas/[contaId]/extrato/loading.tsx +++ b/app/(dashboard)/contas/[contaId]/extrato/loading.tsx @@ -20,7 +20,7 @@ export default function ExtratoLoading() { {/* Seção de lançamentos */}
-
+
{/* Header */}
diff --git a/app/(dashboard)/contas/layout.tsx b/app/(dashboard)/contas/layout.tsx index ff084a4..21dfb70 100644 --- a/app/(dashboard)/contas/layout.tsx +++ b/app/(dashboard)/contas/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Contas" diff --git a/app/(dashboard)/contas/loading.tsx b/app/(dashboard)/contas/loading.tsx index 6e5c952..334b496 100644 --- a/app/(dashboard)/contas/loading.tsx +++ b/app/(dashboard)/contas/loading.tsx @@ -3,7 +3,7 @@ import { Skeleton } from "@/components/ui/skeleton"; export default function ContasLoading() { return (
-
+
{/* Header */}
diff --git a/app/(dashboard)/dashboard/analise-parcelas/layout.tsx b/app/(dashboard)/dashboard/analise-parcelas/layout.tsx index 582bf60..a17f31f 100644 --- a/app/(dashboard)/dashboard/analise-parcelas/layout.tsx +++ b/app/(dashboard)/dashboard/analise-parcelas/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Análise de Parcelas" diff --git a/app/(dashboard)/dashboard/page.tsx b/app/(dashboard)/dashboard/page.tsx index 65da0cd..0b049e2 100644 --- a/app/(dashboard)/dashboard/page.tsx +++ b/app/(dashboard)/dashboard/page.tsx @@ -36,7 +36,7 @@ export default async function Page({ searchParams }: PageProps) { const { disableMagnetlines, dashboardWidgets } = preferences; return ( -
+
+
} title="Insights" diff --git a/app/(dashboard)/insights/loading.tsx b/app/(dashboard)/insights/loading.tsx index ce19e20..bc92c05 100644 --- a/app/(dashboard)/insights/loading.tsx +++ b/app/(dashboard)/insights/loading.tsx @@ -6,7 +6,7 @@ import { Skeleton } from "@/components/ui/skeleton"; export default function InsightsLoading() { return (
-
+
{/* Header */}
diff --git a/app/(dashboard)/lancamentos/layout.tsx b/app/(dashboard)/lancamentos/layout.tsx index bc2a7cf..9087375 100644 --- a/app/(dashboard)/lancamentos/layout.tsx +++ b/app/(dashboard)/lancamentos/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Lançamentos" diff --git a/app/(dashboard)/lancamentos/loading.tsx b/app/(dashboard)/lancamentos/loading.tsx index 13f1b0e..697ec09 100644 --- a/app/(dashboard)/lancamentos/loading.tsx +++ b/app/(dashboard)/lancamentos/loading.tsx @@ -14,7 +14,7 @@ export default function LancamentosLoading() { {/* Month Picker placeholder */}
-
+
{/* Header com título e botão */}
diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx index f305926..9558863 100644 --- a/app/(dashboard)/layout.tsx +++ b/app/(dashboard)/layout.tsx @@ -61,7 +61,7 @@ export default async function DashboardLayout({ />
-
+
{children}
diff --git a/app/(dashboard)/orcamentos/layout.tsx b/app/(dashboard)/orcamentos/layout.tsx index 44436e8..b71baf1 100644 --- a/app/(dashboard)/orcamentos/layout.tsx +++ b/app/(dashboard)/orcamentos/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Orçamentos" diff --git a/app/(dashboard)/orcamentos/loading.tsx b/app/(dashboard)/orcamentos/loading.tsx index 042b8ea..9789786 100644 --- a/app/(dashboard)/orcamentos/loading.tsx +++ b/app/(dashboard)/orcamentos/loading.tsx @@ -10,7 +10,7 @@ export default function OrcamentosLoading() { {/* Month Picker placeholder */}
-
+
{/* Header */}
diff --git a/app/(dashboard)/pagadores/[pagadorId]/loading.tsx b/app/(dashboard)/pagadores/[pagadorId]/loading.tsx index 3623965..b20b108 100644 --- a/app/(dashboard)/pagadores/[pagadorId]/loading.tsx +++ b/app/(dashboard)/pagadores/[pagadorId]/loading.tsx @@ -42,7 +42,7 @@ export default function PagadorDetailsLoading() {
{/* Tabs */} -
+
diff --git a/app/(dashboard)/pagadores/layout.tsx b/app/(dashboard)/pagadores/layout.tsx index 03dab28..3398d7f 100644 --- a/app/(dashboard)/pagadores/layout.tsx +++ b/app/(dashboard)/pagadores/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Pagadores" diff --git a/app/(dashboard)/pre-lancamentos/layout.tsx b/app/(dashboard)/pre-lancamentos/layout.tsx index 097068c..312beff 100644 --- a/app/(dashboard)/pre-lancamentos/layout.tsx +++ b/app/(dashboard)/pre-lancamentos/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Pré-Lançamentos" diff --git a/app/(dashboard)/relatorios/tendencias/layout.tsx b/app/(dashboard)/relatorios/tendencias/layout.tsx index 8da888d..19bc5ed 100644 --- a/app/(dashboard)/relatorios/tendencias/layout.tsx +++ b/app/(dashboard)/relatorios/tendencias/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Tendências" diff --git a/app/(dashboard)/relatorios/uso-cartoes/layout.tsx b/app/(dashboard)/relatorios/uso-cartoes/layout.tsx index 3ac8ca5..2c8efb6 100644 --- a/app/(dashboard)/relatorios/uso-cartoes/layout.tsx +++ b/app/(dashboard)/relatorios/uso-cartoes/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Uso de Cartões" diff --git a/app/(dashboard)/top-estabelecimentos/layout.tsx b/app/(dashboard)/top-estabelecimentos/layout.tsx index 92c7eb6..c20ca10 100644 --- a/app/(dashboard)/top-estabelecimentos/layout.tsx +++ b/app/(dashboard)/top-estabelecimentos/layout.tsx @@ -11,7 +11,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( -
+
} title="Top Estabelecimentos" diff --git a/app/(landing-page)/page.tsx b/app/(landing-page)/page.tsx index ec0badb..9ee76f4 100644 --- a/app/(landing-page)/page.tsx +++ b/app/(landing-page)/page.tsx @@ -155,40 +155,38 @@ export default async function Page() {
{/* Navigation */}
-
-
- -
+
+ {/* Center Navigation Links */} @@ -198,22 +206,21 @@ export function TopNavMenu({ preLancamentosCount = 0 }: TopNavMenuProps) { icon={} onClick={close} > - Lançamentos + lançamentos } onClick={close} - badge={preLancamentosCount} > - Pré-Lançamentos + pré-lançamentos } onClick={close} > - Calendário + calendário @@ -222,21 +229,21 @@ export function TopNavMenu({ preLancamentosCount = 0 }: TopNavMenuProps) { icon={} onClick={close} > - Cartões + cartões } onClick={close} > - Contas + contas } onClick={close} > - Orçamentos + orçamentos @@ -245,21 +252,21 @@ export function TopNavMenu({ preLancamentosCount = 0 }: TopNavMenuProps) { icon={} onClick={close} > - Pagadores + pagadores } onClick={close} > - Categorias + categorias } onClick={close} > - Anotações + anotações @@ -268,22 +275,25 @@ export function TopNavMenu({ preLancamentosCount = 0 }: TopNavMenuProps) { icon={} onClick={close} > - Insights + insights } onClick={close} > - Tendências + tendências } onClick={close} > - Uso de Cartões + uso de cartões + + + diff --git a/components/topbar/topbar-user.tsx b/components/topbar/topbar-user.tsx index 0c39b46..7d4fa89 100644 --- a/components/topbar/topbar-user.tsx +++ b/components/topbar/topbar-user.tsx @@ -1,10 +1,16 @@ "use client"; -import { RiSettings2Line } from "@remixicon/react"; +import { + RiLogoutCircleLine, + RiMessageLine, + RiSettings2Line, +} from "@remixicon/react"; import Image from "next/image"; import Link from "next/link"; -import { useMemo } from "react"; -import LogoutButton from "@/components/auth/logout-button"; +import { useRouter } from "next/navigation"; +import { useMemo, useState } from "react"; +import { FeedbackDialogBody } from "@/components/feedback/feedback-dialog"; +import { Dialog, DialogTrigger } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, @@ -12,7 +18,14 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Spinner } from "@/components/ui/spinner"; +import { authClient } from "@/lib/auth/client"; import { getAvatarSrc } from "@/lib/pagadores/utils"; +import { cn } from "@/lib/utils/ui"; +import { version } from "@/package.json"; + +const itemClass = + "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors hover:bg-accent"; type TopbarUserProps = { user: { @@ -25,58 +38,109 @@ type TopbarUserProps = { }; export function TopbarUser({ user, pagadorAvatarUrl }: TopbarUserProps) { + const router = useRouter(); + const [logoutLoading, setLogoutLoading] = useState(false); + const [feedbackOpen, setFeedbackOpen] = useState(false); + const avatarSrc = useMemo(() => { if (pagadorAvatarUrl) return getAvatarSrc(pagadorAvatarUrl); if (user.image) return user.image; return getAvatarSrc(null); }, [user.image, pagadorAvatarUrl]); + async function handleLogout() { + await authClient.signOut({ + fetchOptions: { + onSuccess: () => router.push("/login"), + onRequest: () => setLogoutLoading(true), + onResponse: () => setLogoutLoading(false), + }, + }); + } + return ( - - - - - - - {user.name} -
- {user.name} - - {user.email} + + + + + + + + {user.name} +
+ {user.name} + + {user.email} + +
+
+ + + +
+ + + Ajustes + + + + + +
+ + + +
+ +
+ +
+ + Versão {version}
- - -
- - - Ajustes - -
- -
-
-
-
+ + + setFeedbackOpen(false)} /> +
); } diff --git a/components/ui/navigation-menu.tsx b/components/ui/navigation-menu.tsx index 36cb1c9..7dcf668 100644 --- a/components/ui/navigation-menu.tsx +++ b/components/ui/navigation-menu.tsx @@ -1,4 +1,4 @@ -import { RiArrowDownBoxFill } from "@remixicon/react"; +import { RiArrowDropDownLine } from "@remixicon/react"; import { cva } from "class-variance-authority"; import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui"; import type * as React from "react"; @@ -73,8 +73,8 @@ function NavigationMenuTrigger({ {...props} > {children}{" "} -