mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-03-10 04:51:47 +00:00
feat: implementar sistema de preferências do usuário e refatorar changelog
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)
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
import {
|
||||
RiArrowLeftRightLine,
|
||||
RiDeleteBin5Line,
|
||||
RiEyeOffLine,
|
||||
RiFileList2Line,
|
||||
RiPencilLine,
|
||||
RiInformationLine,
|
||||
} from "@remixicon/react";
|
||||
import type React from "react";
|
||||
import MoneyValues from "../money-values";
|
||||
import { Card, CardContent, CardFooter } from "../ui/card";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||||
|
||||
interface AccountCardProps {
|
||||
accountName: string;
|
||||
@@ -19,6 +19,7 @@ interface AccountCardProps {
|
||||
status?: string;
|
||||
icon?: React.ReactNode;
|
||||
excludeFromBalance?: boolean;
|
||||
excludeInitialBalanceFromIncome?: boolean;
|
||||
onViewStatement?: () => void;
|
||||
onEdit?: () => void;
|
||||
onRemove?: () => void;
|
||||
@@ -33,6 +34,7 @@ export function AccountCard({
|
||||
status,
|
||||
icon,
|
||||
excludeFromBalance,
|
||||
excludeInitialBalanceFromIncome,
|
||||
onViewStatement,
|
||||
onEdit,
|
||||
onRemove,
|
||||
@@ -85,21 +87,39 @@ export function AccountCard({
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
{accountName}
|
||||
</h2>
|
||||
{excludeFromBalance ? (
|
||||
<div
|
||||
className="flex items-center gap-1 text-muted-foreground"
|
||||
title="Excluída do saldo geral"
|
||||
>
|
||||
<RiEyeOffLine className="size-4" aria-hidden />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{(excludeFromBalance || excludeInitialBalanceFromIncome) && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="flex items-center">
|
||||
<RiInformationLine className="size-5 text-muted-foreground hover:text-foreground transition-colors cursor-help" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right" className="max-w-xs">
|
||||
<div className="space-y-1">
|
||||
{excludeFromBalance && (
|
||||
<p className="text-xs">
|
||||
<strong>Desconsiderado do saldo total:</strong> Esta conta
|
||||
não é incluída no cálculo do saldo total geral.
|
||||
</p>
|
||||
)}
|
||||
{excludeInitialBalanceFromIncome && (
|
||||
<p className="text-xs">
|
||||
<strong>
|
||||
Saldo inicial desconsiderado das receitas:
|
||||
</strong>{" "}
|
||||
O saldo inicial desta conta não é contabilizado como
|
||||
receita nas métricas.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm text-muted-foreground">Saldo</p>
|
||||
<p className="text-3xl text-foreground">
|
||||
<MoneyValues amount={balance} className="text-3xl" />
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
<MoneyValues amount={balance} className="text-3xl" />
|
||||
<p className="text-sm text-muted-foreground">{accountType}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
@@ -38,7 +38,7 @@ const DEFAULT_ACCOUNT_TYPES = [
|
||||
"Conta Poupança",
|
||||
"Carteira Digital",
|
||||
"Conta Investimento",
|
||||
"Cartão Pré-pago",
|
||||
"Pré-Pago | VR/VA",
|
||||
] as const;
|
||||
|
||||
const DEFAULT_ACCOUNT_STATUS = ["Ativa", "Inativa"] as const;
|
||||
@@ -75,6 +75,8 @@ const buildInitialValues = ({
|
||||
logo: selectedLogo,
|
||||
initialBalance: formatInitialBalanceInput(account?.initialBalance ?? 0),
|
||||
excludeFromBalance: account?.excludeFromBalance ?? false,
|
||||
excludeInitialBalanceFromIncome:
|
||||
account?.excludeInitialBalanceFromIncome ?? false,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -106,17 +106,39 @@ export function AccountFormFields({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 sm:col-span-2">
|
||||
<Checkbox
|
||||
id="exclude-from-balance"
|
||||
checked={values.excludeFromBalance}
|
||||
onCheckedChange={(checked) =>
|
||||
onChange("excludeFromBalance", checked ? "true" : "false")
|
||||
}
|
||||
/>
|
||||
<Label htmlFor="exclude-from-balance" className="cursor-pointer text-sm font-normal">
|
||||
Excluir do saldo total (útil para contas de investimento ou reserva)
|
||||
</Label>
|
||||
<div className="flex flex-col gap-3 sm:col-span-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="exclude-from-balance"
|
||||
checked={values.excludeFromBalance === true || values.excludeFromBalance === "true"}
|
||||
onCheckedChange={(checked) =>
|
||||
onChange("excludeFromBalance", !!checked ? "true" : "false")
|
||||
}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="exclude-from-balance"
|
||||
className="cursor-pointer text-sm font-normal leading-tight"
|
||||
>
|
||||
Desconsiderar do saldo total (útil para contas de investimento ou
|
||||
reserva)
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="exclude-initial-balance-from-income"
|
||||
checked={values.excludeInitialBalanceFromIncome === true || values.excludeInitialBalanceFromIncome === "true"}
|
||||
onCheckedChange={(checked) =>
|
||||
onChange("excludeInitialBalanceFromIncome", !!checked ? "true" : "false")
|
||||
}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="exclude-initial-balance-from-income"
|
||||
className="cursor-pointer text-sm font-normal leading-tight"
|
||||
>
|
||||
Desconsiderar o saldo inicial ao calcular o total de receitas
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -137,10 +137,13 @@ export function AccountsPage({ accounts, logoOptions }: AccountsPageProps) {
|
||||
<AccountCard
|
||||
key={account.id}
|
||||
accountName={account.name}
|
||||
accountType={`${account.accountType} - ${account.status}`}
|
||||
accountType={`${account.accountType}`}
|
||||
balance={account.balance ?? account.initialBalance ?? 0}
|
||||
status={account.status}
|
||||
excludeFromBalance={account.excludeFromBalance}
|
||||
excludeInitialBalanceFromIncome={
|
||||
account.excludeInitialBalanceFromIncome
|
||||
}
|
||||
icon={
|
||||
logoSrc ? (
|
||||
<Image
|
||||
|
||||
@@ -8,6 +8,7 @@ export type Account = {
|
||||
initialBalance: number;
|
||||
balance?: number | null;
|
||||
excludeFromBalance?: boolean;
|
||||
excludeInitialBalanceFromIncome?: boolean;
|
||||
};
|
||||
|
||||
export type AccountFormValues = {
|
||||
@@ -18,4 +19,5 @@ export type AccountFormValues = {
|
||||
logo: string;
|
||||
initialBalance: string;
|
||||
excludeFromBalance: boolean;
|
||||
excludeInitialBalanceFromIncome: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user