Adiciona sistema completo de preferências de usuário: - Cria tabela userPreferences no schema com campos disableMagnetlines, periodMonthsBefore e periodMonthsAfter - Implementa página de Ajustes com abas (Preferências, Alterar nome, Senha, E-mail, Deletar conta) - Adiciona componente PreferencesForm para configuração de magnetlines e períodos de exibição - Propaga periodPreferences para todos os componentes de lançamentos e calendário Refatora sistema de changelog: - Remove implementação anterior baseada em JSON estático - Adiciona nova página de changelog dinâmica em app/(dashboard)/changelog - Adiciona componente changelog-list.tsx - Remove arquivos obsoletos (changelog-notification, actions, data, utils, scripts) Adiciona controle de saldo inicial em contas: - Novo campo excludeInitialBalanceFromIncome em contas - Permite excluir saldo inicial do cálculo de receitas - Atualiza queries de lançamentos para respeitar esta configuração Melhorias adicionais: - Adiciona componente ui/accordion.tsx do shadcn/ui - Refatora formatPeriodLabel para displayPeriod centralizado - Propaga estabelecimentos para componentes de lançamentos - Remove variável DB_PROVIDER obsoleta do .env.example e documentação - Adiciona 6 migrações de banco de dados (0003-0008)
103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
import { ChangelogList } from "@/components/changelog/changelog-list";
|
|
import { execSync } from "child_process";
|
|
|
|
type GitCommit = {
|
|
hash: string;
|
|
shortHash: string;
|
|
author: string;
|
|
date: string;
|
|
message: string;
|
|
body: string;
|
|
filesChanged: string[];
|
|
};
|
|
|
|
function getGitRemoteUrl(): string | null {
|
|
try {
|
|
const remoteUrl = execSync("git config --get remote.origin.url", {
|
|
encoding: "utf-8",
|
|
cwd: process.cwd(),
|
|
}).trim();
|
|
|
|
// Converter SSH para HTTPS se necessário
|
|
if (remoteUrl.startsWith("git@")) {
|
|
return remoteUrl
|
|
.replace("git@github.com:", "https://github.com/")
|
|
.replace("git@gitlab.com:", "https://gitlab.com/")
|
|
.replace(".git", "");
|
|
}
|
|
|
|
return remoteUrl.replace(".git", "");
|
|
} catch (error) {
|
|
console.error("Error fetching git remote URL:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function getGitCommits(): GitCommit[] {
|
|
try {
|
|
// Buscar os últimos 50 commits
|
|
const commits = execSync(
|
|
'git log -50 --pretty=format:"%H|%h|%an|%ad|%s|%b" --date=iso --name-only',
|
|
{
|
|
encoding: "utf-8",
|
|
cwd: process.cwd(),
|
|
}
|
|
)
|
|
.trim()
|
|
.split("\n\n");
|
|
|
|
return commits
|
|
.map((commitBlock) => {
|
|
const lines = commitBlock.split("\n");
|
|
const [hash, shortHash, author, date, message, ...rest] =
|
|
lines[0].split("|");
|
|
|
|
// Separar body e arquivos
|
|
const bodyLines: string[] = [];
|
|
const filesChanged: string[] = [];
|
|
let isBody = true;
|
|
|
|
rest.forEach((line) => {
|
|
if (line && !line.includes("/") && !line.includes(".")) {
|
|
bodyLines.push(line);
|
|
} else {
|
|
isBody = false;
|
|
}
|
|
});
|
|
|
|
lines.slice(1).forEach((line) => {
|
|
if (line.trim()) {
|
|
filesChanged.push(line.trim());
|
|
}
|
|
});
|
|
|
|
return {
|
|
hash,
|
|
shortHash,
|
|
author,
|
|
date,
|
|
message,
|
|
body: bodyLines.join("\n").trim(),
|
|
filesChanged: filesChanged.filter(
|
|
(f) => f && !f.startsWith("git log")
|
|
),
|
|
};
|
|
})
|
|
.filter((commit) => commit.hash && commit.message);
|
|
} catch (error) {
|
|
console.error("Error fetching git commits:", error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export default async function ChangelogPage() {
|
|
const commits = getGitCommits();
|
|
const repoUrl = getGitRemoteUrl();
|
|
|
|
return (
|
|
<main>
|
|
<ChangelogList commits={commits} repoUrl={repoUrl} />
|
|
</main>
|
|
);
|
|
}
|