feat: changelog como página própria, versão 1.7.1

- Remove aba Changelog de Ajustes; cria página em /changelog
- Adiciona link para /changelog no menu do usuário com versão ao lado
- Data do changelog formatada como dd/mm/aaaa
- Limpa formatação ** do CHANGELOG.md
- Bump de versão para 1.7.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-02-24 16:07:34 +00:00
parent 1b90be6b54
commit 9cb6593186
7 changed files with 63 additions and 30 deletions

View File

@@ -5,26 +5,28 @@ 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/), 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/). e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/).
## [1.7.0] - 2026-02-24 ## [1.7.1] - 2026-02-24
### Adicionado ### 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) - Topbar de navegação substituindo o header fixo: backdrop blur, links agrupados em 5 seções (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`) - Dropdown Ferramentas na topbar consolidando calculadora e modo privacidade
- **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 - Sino de notificações expandido: exibe orçamentos estourados e pré-lançamentos pendentes com seções separadas e contagem agregada
- Página dedicada de changelog em `/changelog`
- Link para o changelog no menu do usuário com versão exibida ao lado
### Alterado ### Alterado
- **Logo** refatorado com variante `compact` usada na topbar - Logo refatorado com variante compacta para uso na topbar
- **TopbarUser**: incorpora o botão de logout (antes em `logout-button.tsx` separado) - Menu do usuário incorpora o botão de logout e link para ajustes
- **Topbar**: links em lowercase; layout centralizado em `max-w-8xl`; `radix-ui ^1.4.3` adicionado como dependência - Links da topbar em lowercase; layout centralizado em max-w-8xl
- **Gráfico de relatório de categorias** (`category-report-chart`): refatoração interna - Data no changelog exibida no formato dd/mm/aaaa
### Removido ### Removido
- `components/header-dashboard.tsx` substituído pela topbar - Header lateral substituído pela topbar
- `components/auth/logout-button.tsx` — lógica incorporada ao `TopbarUser` - Aba Changelog removida de Ajustes (agora é página própria)
- `components/privacy-mode-toggle.tsx` movido para o `FerramentasDropdown` - Componentes separados de logout e modo privacidade (incorporados à topbar)
## [1.6.3] - 2026-02-19 ## [1.6.3] - 2026-02-19

View File

@@ -2,7 +2,6 @@ import { RiArrowRightSLine } from "@remixicon/react";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { ChangelogTab } from "@/components/ajustes/changelog-tab";
import { CompanionTab } from "@/components/ajustes/companion-tab"; import { CompanionTab } from "@/components/ajustes/companion-tab";
import { DeleteAccountForm } from "@/components/ajustes/delete-account-form"; import { DeleteAccountForm } from "@/components/ajustes/delete-account-form";
import { PreferencesForm } from "@/components/ajustes/preferences-form"; import { PreferencesForm } from "@/components/ajustes/preferences-form";
@@ -12,8 +11,6 @@ import { UpdatePasswordForm } from "@/components/ajustes/update-password-form";
import { Card } from "@/components/ui/card"; import { Card } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { auth } from "@/lib/auth/config"; import { auth } from "@/lib/auth/config";
import { parseChangelog } from "@/lib/changelog/parse-changelog";
import { fetchAjustesPageData } from "./data"; import { fetchAjustesPageData } from "./data";
export default async function Page() { export default async function Page() {
@@ -31,8 +28,6 @@ export default async function Page() {
const { authProvider, userPreferences, userApiTokens } = const { authProvider, userPreferences, userApiTokens } =
await fetchAjustesPageData(session.user.id); await fetchAjustesPageData(session.user.id);
const changelogVersions = parseChangelog();
return ( return (
<div className="w-full"> <div className="w-full">
<Tabs defaultValue="preferencias" className="w-full"> <Tabs defaultValue="preferencias" className="w-full">
@@ -45,14 +40,13 @@ export default async function Page() {
<TabsTrigger value="nome">Alterar nome</TabsTrigger> <TabsTrigger value="nome">Alterar nome</TabsTrigger>
<TabsTrigger value="senha">Alterar senha</TabsTrigger> <TabsTrigger value="senha">Alterar senha</TabsTrigger>
<TabsTrigger value="email">Alterar e-mail</TabsTrigger> <TabsTrigger value="email">Alterar e-mail</TabsTrigger>
<TabsTrigger value="changelog">Changelog</TabsTrigger>
<TabsTrigger value="deletar" className="text-destructive"> <TabsTrigger value="deletar" className="text-destructive">
Deletar conta Deletar conta
</TabsTrigger> </TabsTrigger>
</TabsList> </TabsList>
</div> </div>
<div <div
className="pointer-events-none absolute right-0 top-0 hidden h-9 w-10 items-center justify-end bg-gradient-to-l from-background to-transparent md:hidden" className="pointer-events-none absolute right-0 top-0 hidden h-9 w-10 items-center justify-end bg-linear-to-l from-background to-transparent md:hidden"
aria-hidden aria-hidden
> >
<RiArrowRightSLine className="size-5 shrink-0 text-muted-foreground" /> <RiArrowRightSLine className="size-5 shrink-0 text-muted-foreground" />
@@ -139,10 +133,6 @@ export default async function Page() {
</Card> </Card>
</TabsContent> </TabsContent>
<TabsContent value="changelog" className="mt-4">
<ChangelogTab versions={changelogVersions} />
</TabsContent>
<TabsContent value="deletar" className="mt-4"> <TabsContent value="deletar" className="mt-4">
<Card className="p-6"> <Card className="p-6">
<div className="space-y-4"> <div className="space-y-4">

View File

@@ -0,0 +1,23 @@
import { RiHistoryLine } from "@remixicon/react";
import PageDescription from "@/components/page-description";
export const metadata = {
title: "Cartões | OpenMonetis",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<section className="space-y-6 pt-4">
<PageDescription
icon={<RiHistoryLine />}
title="Changelog"
subtitle="Acompanhe todas as alterações feitas na plataforma."
/>
{children}
</section>
);
}

View File

@@ -0,0 +1,12 @@
import { ChangelogTab } from "@/components/ajustes/changelog-tab";
import { parseChangelog } from "@/lib/changelog/parse-changelog";
export default function ChangelogPage() {
const versions = parseChangelog();
return (
<div className="w-full">
<ChangelogTab versions={versions} />
</div>
);
}

View File

@@ -1,6 +1,7 @@
"use client"; "use client";
import { import {
RiHistoryLine,
RiLogoutCircleLine, RiLogoutCircleLine,
RiMessageLine, RiMessageLine,
RiSettings2Line, RiSettings2Line,
@@ -23,6 +24,7 @@ import { authClient } from "@/lib/auth/client";
import { getAvatarSrc } from "@/lib/pagadores/utils"; import { getAvatarSrc } from "@/lib/pagadores/utils";
import { cn } from "@/lib/utils/ui"; import { cn } from "@/lib/utils/ui";
import { version } from "@/package.json"; import { version } from "@/package.json";
import { Badge } from "../ui/badge";
const itemClass = const itemClass =
"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors hover:bg-accent"; "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors hover:bg-accent";
@@ -100,6 +102,15 @@ export function TopbarUser({ user, pagadorAvatarUrl }: TopbarUserProps) {
Ajustes Ajustes
</Link> </Link>
<Link
href="/changelog"
className={cn(itemClass, "text-foreground")}
>
<RiHistoryLine className="size-4 text-muted-foreground shrink-0" />
<span className="flex-1">Changelog</span>
<Badge variant="secondary">v{version}</Badge>
</Link>
<DialogTrigger asChild> <DialogTrigger asChild>
<button <button
type="button" type="button"
@@ -132,12 +143,6 @@ export function TopbarUser({ user, pagadorAvatarUrl }: TopbarUserProps) {
{logoutLoading ? "Saindo..." : "Sair"} {logoutLoading ? "Saindo..." : "Sair"}
</button> </button>
</div> </div>
<DropdownMenuSeparator />
<div className="px-3 py-1.5">
<span className="text-[10px] font-mono text-muted-foreground/40 select-none">
Versão {version}
</span>
</div>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<FeedbackDialogBody onClose={() => setFeedbackOpen(false)} /> <FeedbackDialogBody onClose={() => setFeedbackOpen(false)} />

View File

@@ -29,9 +29,10 @@ export function parseChangelog(): ChangelogVersion[] {
if (currentSection && currentVersion) { if (currentSection && currentVersion) {
currentVersion.sections.push(currentSection); currentVersion.sections.push(currentSection);
} }
const [y, m, d] = versionMatch[2].split("-");
currentVersion = { currentVersion = {
version: versionMatch[1], version: versionMatch[1],
date: versionMatch[2], date: d && m && y ? `${d}/${m}/${y}` : versionMatch[2],
sections: [], sections: [],
}; };
versions.push(currentVersion); versions.push(currentVersion);

View File

@@ -1,6 +1,6 @@
{ {
"name": "openmonetis", "name": "openmonetis",
"version": "1.6.3", "version": "1.7.1",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev --turbopack",