mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
Compare commits
4 Commits
v2.5.3
...
18893bfe02
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18893bfe02 | ||
|
|
7fdf9e2876 | ||
|
|
7d0781b035 | ||
|
|
b9b843b9db |
23
CHANGELOG.md
23
CHANGELOG.md
@@ -5,6 +5,29 @@ 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/).
|
||||
|
||||
## [2.5.4] - 2026-05-06
|
||||
|
||||
Esta versão é uma faxina arquitetural de larga escala sem nenhuma mudança visível ao usuário. Removido código morto, padronizamos identificadores em inglês conforme a convenção do projeto, simplificamos o barrel de Server Actions e consolidamos os arquivos de helpers/queries soltos nas raízes das features dentro de pastas `lib/`. O resultado é uma estrutura previsível e consistente entre features (`actions.ts`, `queries.ts`, `actions/`, `components/`, `hooks/`, `lib/`) e um saldo líquido de −428 linhas de código com zero impacto em comportamento, performance ou banco de dados.
|
||||
|
||||
### Alterado
|
||||
- Padronização da estrutura de `transactions/`: 14 helpers soltos na raiz movidos para `lib/`; barrel `actions.ts` reduzido de 76 linhas de wrappers redundantes para 14 linhas de re-exports puros; `anticipation-actions.ts` movido para `actions/anticipation.ts`.
|
||||
- Reorganização de `dashboard/`: 8 helpers soltos consolidados em `dashboard/lib/`; orquestradores (`fetch-dashboard-data.ts`, `page-data-queries.ts`) permanecem na raiz como entry points.
|
||||
- Reorganização de `reports/`: 5 query files na raiz consolidados em `reports/lib/`.
|
||||
- Reorganização de `payers/`: god file `detail-actions.ts` (21KB) e `detail-queries.ts` movidos para `payers/lib/`.
|
||||
- `shared/components/`: 9 dos 16 componentes soltos agrupados em 3 novas subpastas temáticas (`brand/`, `widgets/`, `feedback/`).
|
||||
- `shared/lib/fetch-json.ts` movido para `shared/utils/fetch-json.ts` (categorização correta — utilitário genérico de transporte HTTP).
|
||||
- Padronização EN dos identificadores remanescentes: 4 constantes globais (`LANCAMENTOS_*` → `TRANSACTIONS_*`), 12 tipos/interfaces (`Lancamento*`/`Pagador*`/`Estabelecimento*` → equivalentes em EN), 13 funções/components exportados (`fetchPagador*`, `EstabelecimentoInput`, `PagadorInfoCard`, etc.), 5 props cross-file (`preLancamentosCount` → `inboxPendingCount`, etc.).
|
||||
- Server Actions de `insights/` simplificadas: barrel reduzido para re-exports puros.
|
||||
- Mantidas intencionalmente em PT-BR conforme exceção do `CLAUDE.md`: variáveis locais (`pagador`, `categoria`, `lancamento`), accessor key `pagadorName` (persistida em preferências do usuário), strings de UI.
|
||||
|
||||
### Removido
|
||||
- 14 funções/constantes mortas verificadas via `grep` em todo o repo: `validateCategoriaOwnership`, `getInstallmentAnticipationsAction`, `getAnticipationDetailsAction`, `formatDecimalForDb`, `currencyFormatterNoCents`, `optionalDecimalSchema`, `formatMonthLabel`, `getGoalProgressStatusColorClass`, `MONTH_PERIOD_PARAM`, `calculateRemainingInstallments`, e 5 funções `fetch*` não usadas em `inbox/queries.ts`.
|
||||
- 1 tipo morto: `ImportRow` em `transactions/actions/import-action.ts`.
|
||||
- 2 tipos órfãos consequentes: `InstallmentAnticipationWithRelations`, `GoalProgressStatus` (este último convertido em interno).
|
||||
- ~30 `export` keywords desnecessários (símbolos usados apenas no próprio arquivo) — visibilidade reduzida sem mudar comportamento.
|
||||
- Re-exports mortos em barrels: `EstablishmentLogoPicker` em `entity-avatar/index.ts`, `CategoryReportSkeleton` e `WidgetSkeleton` em `skeletons/index.ts`, `toNameKey` em `establishment-logo-queries.ts`.
|
||||
- Arquivo `features/reports/types.ts` (barrel inteiro era órfão — todos os 5 tipos eram importados direto de `@/shared/lib/types/reports`).
|
||||
|
||||
## [2.5.3] - 2026-05-05
|
||||
|
||||
Esta versão foca em polimento do diálogo de detalhes do lançamento, refresh visual da linha do tempo de parcelas e limpeza terminológica em torno de contas/cartões inativos. O diálogo de detalhes ganhou logo da conta/cartão, ícone colorido por categoria e avatar do responsável; a barra de progresso de parcelas foi redesenhada num layout horizontal compacto; e o widget "Minhas Contas" do dashboard passou a ocultar automaticamente contas marcadas como inativas. Internamente, o termo "arquivadas" foi padronizado como "inativas" nas tabs de contas e cartões, surgiram constantes compartilhadas para formas de pagamento liquidáveis e um helper `isAccountInactive`, e o seed de mock data ganhou cobertura mais realista (novas pessoas, contas, cartões e assinaturas recorrentes).
|
||||
|
||||
57
CLAUDE.md
57
CLAUDE.md
@@ -97,7 +97,7 @@ src/
|
||||
│ ├── api/
|
||||
│ ├── globals.css
|
||||
│ └── layout.tsx
|
||||
├── features/
|
||||
├── features/ # cada feature segue: actions.ts, queries.ts, actions/, components/, hooks/, lib/
|
||||
│ ├── auth/
|
||||
│ ├── landing/
|
||||
│ ├── dashboard/
|
||||
@@ -117,9 +117,12 @@ src/
|
||||
│ └── settings/
|
||||
├── shared/
|
||||
│ ├── components/
|
||||
│ │ ├── ui/
|
||||
│ │ ├── navigation/
|
||||
│ │ ├── providers/
|
||||
│ │ ├── ui/ # shadcn/ui primitives
|
||||
│ │ ├── navigation/ # navbar, sidebar, breadcrumbs
|
||||
│ │ ├── providers/ # React context providers
|
||||
│ │ ├── brand/ # logos do app (logo, logo-icon, logo-text)
|
||||
│ │ ├── widgets/ # widget-card, widget-empty-state, expandable-widget-card
|
||||
│ │ ├── feedback/ # empty-state, status-dot, payment-success
|
||||
│ │ ├── month-picker/
|
||||
│ │ ├── logo-picker/
|
||||
│ │ ├── calculator/
|
||||
@@ -134,34 +137,56 @@ src/
|
||||
│ │ ├── calculator/
|
||||
│ │ ├── categories/
|
||||
│ │ ├── email/
|
||||
│ │ ├── import/
|
||||
│ │ ├── installments/
|
||||
│ │ ├── invoices/
|
||||
│ │ ├── logo/
|
||||
│ │ ├── notifications/
|
||||
│ │ ├── payers/
|
||||
│ │ ├── schemas/
|
||||
│ │ ├── storage/
|
||||
│ │ ├── transfers/
|
||||
│ │ ├── types/
|
||||
│ │ ├── version/
|
||||
│ │ └── db.ts
|
||||
│ └── utils/
|
||||
│ ├── period/
|
||||
│ ├── calculator.ts
|
||||
│ ├── calendar.ts
|
||||
│ ├── category-colors.ts
|
||||
│ ├── currency.ts
|
||||
│ ├── date.ts
|
||||
│ ├── export-branding.ts
|
||||
│ ├── fetch-json.ts
|
||||
│ ├── financial-dates.ts
|
||||
│ ├── percentage.ts
|
||||
│ ├── category-colors.ts
|
||||
│ ├── calendar.ts
|
||||
│ ├── icons.tsx
|
||||
│ ├── id.ts
|
||||
│ ├── initials.ts
|
||||
│ ├── math.ts
|
||||
│ ├── number.ts
|
||||
│ ├── percentage.ts
|
||||
│ ├── string.ts
|
||||
│ ├── initials.ts
|
||||
│ ├── icons.tsx
|
||||
│ ├── export-branding.ts
|
||||
│ ├── ui.ts
|
||||
│ └── calculator.ts
|
||||
│ └── ui.ts
|
||||
└── db/
|
||||
└── schema.ts
|
||||
```
|
||||
|
||||
### Estrutura interna padrão de uma feature
|
||||
|
||||
Toda feature em `src/features/<nome>/` segue:
|
||||
|
||||
```text
|
||||
<feature>/
|
||||
├── actions.ts # entry point de Server Actions (barrel quando há actions/)
|
||||
├── queries.ts # entry point de leitura do banco
|
||||
├── actions/ # (opcional) Server Actions divididas por domínio quando o volume cresce
|
||||
├── components/ # componentes de UI da feature
|
||||
├── hooks/ # React hooks específicos da feature
|
||||
└── lib/ # helpers, types, sub-queries e constantes internas
|
||||
```
|
||||
|
||||
`actions.ts` e `queries.ts` são as portas de entrada da feature. Tudo que é helper interno fica em `lib/`. Componentes e hooks ficam nas pastas com nome óbvio.
|
||||
|
||||
---
|
||||
|
||||
## Import Patterns
|
||||
@@ -299,9 +324,11 @@ export async function fetchData(userId: string, period: string) {
|
||||
2. Criar a feature em `src/features/<feature>/`
|
||||
3. Separar:
|
||||
- `components/`
|
||||
- `queries.ts`
|
||||
- `actions.ts`
|
||||
- `types.ts` ou `schemas.ts` quando fizer sentido
|
||||
- `queries.ts` (entry point de leitura)
|
||||
- `actions.ts` (entry point de Server Actions; vira barrel quando crescer e migrar para `actions/`)
|
||||
- `lib/` para helpers internos, sub-queries por tópico, types e constantes da feature
|
||||
- `types.ts` ou `schemas.ts` quando fizer sentido (alternativa a `lib/`)
|
||||
- `hooks/` quando houver hooks específicos da feature
|
||||
4. Extrair para `src/shared/` tudo que for reutilizavel
|
||||
5. Atualizar navegacao e `revalidateForEntity()` se a feature tiver CRUD
|
||||
6. Rodar:
|
||||
|
||||
54
README.md
54
README.md
@@ -8,7 +8,7 @@
|
||||
|
||||
> **⚠️ Não há versão online hospedada.** Você precisa clonar o repositório e rodar localmente ou no seu próprio servidor.
|
||||
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
[](https://nextjs.org/)
|
||||
[](https://www.typescriptlang.org/)
|
||||
[](https://www.postgresql.org/)
|
||||
@@ -127,21 +127,20 @@ Só quer rodar o OpenMonetis. **Não precisa clonar o repositório nem instalar
|
||||
# 1. Baixe o compose
|
||||
curl -fsSL https://raw.githubusercontent.com/felipegcoutinho/openmonetis/main/docker-compose.yml -o docker-compose.yml
|
||||
|
||||
# 2. Suba tudo
|
||||
# 2. Crie um .en na mesma pasta.
|
||||
# .env mínimo recomendado para produção
|
||||
BETTER_AUTH_SECRET=gere-um-valor-com-openssl-rand-base64-32
|
||||
BETTER_AUTH_URL=http://seu-dominio.com
|
||||
|
||||
# 3. Suba tudo
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Acesse em: `http://localhost:3000`
|
||||
|
||||
O banco sobe com credenciais padrão. Para personalizar (senha, Google OAuth, e-mail, IA...), crie um `.env` na mesma pasta **antes** de subir:
|
||||
O banco sobe com credenciais padrão. Para personalizar (senha, Google OAuth, e-mail, IA...), crie um `.env` na mesma pasta **antes** de subir.
|
||||
|
||||
```bash
|
||||
# .env mínimo recomendado para produção
|
||||
BETTER_AUTH_SECRET=gere-um-valor-com-openssl-rand-base64-32
|
||||
BETTER_AUTH_URL=https://seu-dominio.com
|
||||
```
|
||||
|
||||
Veja todas as variáveis disponíveis em [Variáveis de Ambiente](#-variáveis-de-ambiente).
|
||||
Mais sobre .env em [Variáveis de Ambiente](#-variáveis-de-ambiente).
|
||||
|
||||
**Banco remoto (Supabase, Neon, Railway...):** defina `DATABASE_URL` no `.env` e suba só o app:
|
||||
|
||||
@@ -508,7 +507,18 @@ openmonetis/
|
||||
│ │ └── auth/ # Formulários de autenticação
|
||||
│ │
|
||||
│ ├── shared/ # Código reutilizado entre features
|
||||
│ │ ├── components/ # UI compartilhada (shadcn/ui, navigation, skeletons...)
|
||||
│ │ ├── components/ # UI compartilhada
|
||||
│ │ │ ├── ui/ # shadcn/ui primitives
|
||||
│ │ │ ├── navigation/ # navbar, sidebar, breadcrumbs
|
||||
│ │ │ ├── brand/ # logos do app
|
||||
│ │ │ ├── widgets/ # widget-card e variantes
|
||||
│ │ │ ├── feedback/ # empty-state, status-dot, payment-success
|
||||
│ │ │ ├── entity-avatar/ # avatares de categoria/estabelecimento
|
||||
│ │ │ ├── month-picker/ # seletor de período
|
||||
│ │ │ ├── logo-picker/ # seletor de logos
|
||||
│ │ │ ├── calculator/ # calculadora de cálculos rápidos
|
||||
│ │ │ ├── skeletons/ # loading skeletons
|
||||
│ │ │ └── providers/ # React context providers
|
||||
│ │ ├── hooks/ # React hooks globais
|
||||
│ │ ├── lib/ # Helpers de domínio (auth, db, payers, schemas, email...)
|
||||
│ │ └── utils/ # Utilitários (currency, date, period, math, string...)
|
||||
@@ -524,6 +534,22 @@ openmonetis/
|
||||
└── proxy.ts # Middleware (auth + multi-domínio)
|
||||
```
|
||||
|
||||
### Estrutura interna de uma feature
|
||||
|
||||
Toda feature em `src/features/<nome>/` segue o mesmo padrão:
|
||||
|
||||
```
|
||||
<feature>/
|
||||
├── actions.ts # Server Actions (entry point — barrel re-export quando há actions/)
|
||||
├── queries.ts # Funções de leitura do banco (entry point)
|
||||
├── actions/ # (opcional) Server Actions divididas por domínio quando o volume cresce
|
||||
├── components/ # Componentes de UI da feature
|
||||
├── hooks/ # React hooks específicos da feature
|
||||
└── lib/ # Helpers, types, sub-queries e constantes
|
||||
```
|
||||
|
||||
A regra é: `actions.ts` e `queries.ts` são as portas de entrada da feature. Tudo que é helper interno fica em `lib/`. Componentes e hooks ficam nas pastas com nome óbvio.
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contribuindo
|
||||
@@ -563,12 +589,6 @@ Para o texto legal completo, consulte o arquivo [LICENSE](LICENSE) ou visite [cr
|
||||
|
||||
---
|
||||
|
||||
## 🙏 Agradecimentos
|
||||
|
||||
[Next.js](https://nextjs.org/) · [Better Auth](https://better-auth.com/) · [Drizzle ORM](https://orm.drizzle.team/) · [shadcn/ui](https://ui.shadcn.com/) · [Biome](https://biomejs.dev/) · [Vercel](https://vercel.com/)
|
||||
|
||||
---
|
||||
|
||||
**Desenvolvido por:** Felipe Coutinho — [@felipegcoutinho](https://github.com/felipegcoutinho)
|
||||
|
||||
<div align="center">
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
],
|
||||
// PostCSS is inferred from the config file, but the project only depends on
|
||||
// the Tailwind PostCSS plugin directly.
|
||||
// `server-only` is provided implicitly by Next.js — no install needed.
|
||||
"ignoreDependencies": [
|
||||
"postcss"
|
||||
"postcss",
|
||||
"server-only"
|
||||
],
|
||||
"next": true,
|
||||
"postcss": true,
|
||||
|
||||
@@ -21,6 +21,7 @@ const nextConfig: NextConfig = {
|
||||
experimental: {
|
||||
prefetchInlining: true,
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
optimizePackageImports: ["@remixicon/react"],
|
||||
},
|
||||
|
||||
// Headers for Safari compatibility
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openmonetis",
|
||||
"version": "2.5.3",
|
||||
"version": "2.5.4",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.33.0",
|
||||
"scripts": {
|
||||
|
||||
@@ -21,7 +21,7 @@ import type {
|
||||
PAYMENT_METHODS,
|
||||
TRANSACTION_CONDITIONS,
|
||||
TRANSACTION_TYPES,
|
||||
} from "@/features/transactions/constants";
|
||||
} from "@/features/transactions/lib/constants";
|
||||
import {
|
||||
buildInvoicePaymentNote,
|
||||
INITIAL_BALANCE_CATEGORY_NAME,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
import { Logo } from "@/shared/components/brand/logo";
|
||||
|
||||
export default function AuthLayout({
|
||||
children,
|
||||
|
||||
@@ -7,8 +7,8 @@ import { AdjustBalanceDialog } from "@/features/accounts/components/adjust-balan
|
||||
import type { Account } from "@/features/accounts/components/types";
|
||||
import {
|
||||
fetchAccountData,
|
||||
fetchAccountLancamentosPage,
|
||||
fetchAccountSummary,
|
||||
fetchAccountTransactionsPage,
|
||||
} from "@/features/accounts/statement-queries";
|
||||
import { fetchUserPreferences } from "@/features/settings/queries";
|
||||
import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page";
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
mapTransactionsData,
|
||||
type ResolvedSearchParams,
|
||||
resolveTransactionPagination,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
@@ -89,7 +89,7 @@ export default async function Page({ params, searchParams }: PageProps) {
|
||||
accountId: account.id,
|
||||
});
|
||||
|
||||
const transactionsPage = await fetchAccountLancamentosPage(
|
||||
const transactionsPage = await fetchAccountTransactionsPage(
|
||||
filters,
|
||||
pagination,
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { fetchCalendarData } from "@/features/calendar/queries";
|
||||
import {
|
||||
getSingleParam,
|
||||
type ResolvedSearchParams,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import MonthNavigation from "@/shared/components/month-picker/month-navigation";
|
||||
import { getUserId } from "@/shared/lib/auth/server";
|
||||
import type { CalendarPeriod } from "@/shared/lib/types/calendar";
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
getSingleParam,
|
||||
mapTransactionsData,
|
||||
type ResolvedSearchParams,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TransactionsPage } from "@/features/transactions/components/page/transa
|
||||
import {
|
||||
buildOptionSets,
|
||||
buildSluggedFilters,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
|
||||
@@ -2,9 +2,9 @@ import { connection } from "next/server";
|
||||
import { DashboardGridEditable } from "@/features/dashboard/components/dashboard-grid-editable";
|
||||
import { DashboardMetricsCards } from "@/features/dashboard/components/dashboard-metrics-cards";
|
||||
import { DashboardWelcome } from "@/features/dashboard/components/dashboard-welcome";
|
||||
import { extractDashboardLogoNames } from "@/features/dashboard/extract-logo-names";
|
||||
import { extractDashboardLogoNames } from "@/features/dashboard/lib/extract-logo-names";
|
||||
import { fetchDashboardPageData } from "@/features/dashboard/page-data-queries";
|
||||
import { getSingleParam } from "@/features/transactions/page-helpers";
|
||||
import { getSingleParam } from "@/features/transactions/lib/page-helpers";
|
||||
import { LogoPrefetchProvider } from "@/shared/components/entity-avatar";
|
||||
import MonthNavigation from "@/shared/components/month-picker/month-navigation";
|
||||
import { getUser } from "@/shared/lib/auth/server";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { connection } from "next/server";
|
||||
import { fetchDashboardNavbarData } from "@/features/dashboard/navbar-queries";
|
||||
import { fetchDashboardNavbarData } from "@/features/dashboard/lib/navbar-queries";
|
||||
import { AppNavbar } from "@/shared/components/navigation/navbar/app-navbar";
|
||||
import { LogoDevProvider } from "@/shared/components/providers/logo-dev-provider";
|
||||
import { PrivacyProvider } from "@/shared/components/providers/privacy-provider";
|
||||
@@ -21,8 +21,8 @@ export default async function DashboardLayout({
|
||||
<PrivacyProvider>
|
||||
<AppNavbar
|
||||
user={{ ...session.user, image: session.user.image ?? null }}
|
||||
pagadorAvatarUrl={navbarData.pagadorAvatarUrl}
|
||||
preLancamentosCount={navbarData.preLancamentosCount}
|
||||
payerAvatarUrl={navbarData.payerAvatarUrl}
|
||||
inboxPendingCount={navbarData.inboxPendingCount}
|
||||
notificationsSnapshot={navbarData.notificationsSnapshot}
|
||||
/>
|
||||
<div className="relative flex flex-1 flex-col pt-16">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
|
||||
* Loading state para a página de detalhes do pagador.
|
||||
* Layout: navegação mensal + tabs com card compartilhado do pagador.
|
||||
*/
|
||||
export default function PagadorDetailsLoading() {
|
||||
export default function PayerDetailsLoading() {
|
||||
return (
|
||||
<main className="flex flex-col gap-6">
|
||||
<div className="h-[60px] animate-pulse rounded-md bg-foreground/10" />
|
||||
|
||||
@@ -8,7 +8,7 @@ import { connection } from "next/server";
|
||||
import { PayerCardUsageCard } from "@/features/payers/components/details/payer-card-usage-card";
|
||||
import { PayerHeaderCard } from "@/features/payers/components/details/payer-header-card";
|
||||
import { PayerHistoryCard } from "@/features/payers/components/details/payer-history-card";
|
||||
import { PagadorInfoCard } from "@/features/payers/components/details/payer-info-card";
|
||||
import { PayerInfoCard } from "@/features/payers/components/details/payer-info-card";
|
||||
import { PayerLeaveShareCard } from "@/features/payers/components/details/payer-leave-share-card";
|
||||
import { PayerMonthlySummaryCard } from "@/features/payers/components/details/payer-monthly-summary-card";
|
||||
import {
|
||||
@@ -16,12 +16,12 @@ import {
|
||||
PayerPaymentStatusCard,
|
||||
} from "@/features/payers/components/details/payer-payment-method-cards";
|
||||
import { PayerSharingCard } from "@/features/payers/components/details/payer-sharing-card";
|
||||
import { buildReadOnlyOptionSets } from "@/features/payers/lib/build-readonly-option-sets";
|
||||
import {
|
||||
fetchCurrentUserShare,
|
||||
fetchPagadorLancamentos,
|
||||
fetchPayerShares,
|
||||
} from "@/features/payers/detail-queries";
|
||||
import { buildReadOnlyOptionSets } from "@/features/payers/lib/build-readonly-option-sets";
|
||||
fetchPayerTransactions,
|
||||
} from "@/features/payers/lib/detail-queries";
|
||||
import { fetchUserPreferences } from "@/features/settings/queries";
|
||||
import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page";
|
||||
import {
|
||||
@@ -36,13 +36,12 @@ import {
|
||||
type SluggedFilters,
|
||||
type SlugMaps,
|
||||
type TransactionSearchFilters,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
} from "@/features/transactions/queries";
|
||||
import { LogoPrefetchProvider } from "@/shared/components/entity-avatar";
|
||||
import { ExpandableWidgetCard } from "@/shared/components/expandable-widget-card";
|
||||
import MonthNavigation from "@/shared/components/month-picker/month-navigation";
|
||||
import {
|
||||
Tabs,
|
||||
@@ -50,16 +49,17 @@ import {
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/shared/components/ui/tabs";
|
||||
import { ExpandableWidgetCard } from "@/shared/components/widgets/expandable-widget-card";
|
||||
import { getUserId } from "@/shared/lib/auth/server";
|
||||
import { prefetchLogoMappings } from "@/shared/lib/logo/prefetch-server";
|
||||
import { getPayerAccess } from "@/shared/lib/payers/access";
|
||||
import {
|
||||
fetchPagadorBoletoItems,
|
||||
fetchPagadorBoletoStats,
|
||||
fetchPagadorCardUsage,
|
||||
fetchPagadorPaymentStatus,
|
||||
fetchPayerBoletoItems,
|
||||
fetchPayerBoletoStats,
|
||||
fetchPayerCardUsage,
|
||||
fetchPayerHistory,
|
||||
fetchPayerMonthlyBreakdown,
|
||||
fetchPayerPaymentStatus,
|
||||
type PayerCardUsageItem,
|
||||
} from "@/shared/lib/payers/details";
|
||||
import { parsePeriodParam } from "@/shared/utils/period";
|
||||
@@ -182,7 +182,7 @@ export default async function Page({ params, searchParams }: PageProps) {
|
||||
estabelecimentos,
|
||||
userPreferences,
|
||||
] = await Promise.all([
|
||||
fetchPagadorLancamentos(filters),
|
||||
fetchPayerTransactions(filters),
|
||||
fetchPayerMonthlyBreakdown({
|
||||
userId: dataOwnerId,
|
||||
payerId: pagador.id,
|
||||
@@ -193,22 +193,22 @@ export default async function Page({ params, searchParams }: PageProps) {
|
||||
payerId: pagador.id,
|
||||
period: selectedPeriod,
|
||||
}),
|
||||
fetchPagadorCardUsage({
|
||||
fetchPayerCardUsage({
|
||||
userId: dataOwnerId,
|
||||
payerId: pagador.id,
|
||||
period: selectedPeriod,
|
||||
}),
|
||||
fetchPagadorBoletoStats({
|
||||
fetchPayerBoletoStats({
|
||||
userId: dataOwnerId,
|
||||
payerId: pagador.id,
|
||||
period: selectedPeriod,
|
||||
}),
|
||||
fetchPagadorBoletoItems({
|
||||
fetchPayerBoletoItems({
|
||||
userId: dataOwnerId,
|
||||
payerId: pagador.id,
|
||||
period: selectedPeriod,
|
||||
}),
|
||||
fetchPagadorPaymentStatus({
|
||||
fetchPayerPaymentStatus({
|
||||
userId: dataOwnerId,
|
||||
payerId: pagador.id,
|
||||
period: selectedPeriod,
|
||||
@@ -333,7 +333,7 @@ export default async function Page({ params, searchParams }: PageProps) {
|
||||
/>
|
||||
|
||||
<TabsContent value="profile" className="space-y-4">
|
||||
<PagadorInfoCard payer={payerData} />
|
||||
<PayerInfoCard payer={payerData} />
|
||||
{canEdit && payerData.shareCode ? (
|
||||
<PayerSharingCard
|
||||
payerId={pagador.id}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
|
||||
* Loading state para a página de pessoas
|
||||
* Layout: Header + Input de compartilhamento + Grid de cards
|
||||
*/
|
||||
export default function PagadoresLoading() {
|
||||
export default function PayersLoading() {
|
||||
return (
|
||||
<main className="flex flex-col items-start gap-6">
|
||||
<div className="w-full space-y-6">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { RiBankCard2Line } from "@remixicon/react";
|
||||
import { connection } from "next/server";
|
||||
import { fetchCartoesReportData } from "@/features/reports/cards-report-queries";
|
||||
import { CardCategoryBreakdown } from "@/features/reports/components/cards/card-category-breakdown";
|
||||
import { CardInvoiceStatus } from "@/features/reports/components/cards/card-invoice-status";
|
||||
import { CardTopExpenses } from "@/features/reports/components/cards/card-top-expenses";
|
||||
import { CardUsageChart } from "@/features/reports/components/cards/card-usage-chart";
|
||||
import { CardsOverview } from "@/features/reports/components/cards/cards-overview";
|
||||
import { fetchCartoesReportData } from "@/features/reports/lib/cards-report-queries";
|
||||
import MonthNavigation from "@/shared/components/month-picker/month-navigation";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
import { getUser } from "@/shared/lib/auth/server";
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { connection } from "next/server";
|
||||
import type { Category } from "@/db/schema";
|
||||
import { fetchCategoryChartData } from "@/features/reports/category-chart-queries";
|
||||
import { fetchCategoryReport } from "@/features/reports/category-report-queries";
|
||||
import { fetchUserCategories } from "@/features/reports/category-trends-queries";
|
||||
import { CategoryReportPage } from "@/features/reports/components/category-report-page";
|
||||
import type {
|
||||
CategoryOption,
|
||||
FilterState,
|
||||
} from "@/features/reports/components/types";
|
||||
import { validateDateRange } from "@/features/reports/utils";
|
||||
import { fetchCategoryChartData } from "@/features/reports/lib/category-chart-queries";
|
||||
import { fetchCategoryReport } from "@/features/reports/lib/category-report-queries";
|
||||
import { fetchUserCategories } from "@/features/reports/lib/category-trends-queries";
|
||||
import { validateDateRange } from "@/features/reports/lib/utils";
|
||||
import { getUserId } from "@/shared/lib/auth/server";
|
||||
import type { CategoryReportFilters } from "@/shared/lib/types/reports";
|
||||
import { addMonthsToPeriod, getCurrentPeriod } from "@/shared/utils/period";
|
||||
|
||||
@@ -34,7 +34,7 @@ const validatePeriodFilter = (value: string | null): PeriodFilter => {
|
||||
return "6";
|
||||
};
|
||||
|
||||
export default async function TopEstabelecimentosPage({
|
||||
export default async function TopEstablishmentsPage({
|
||||
searchParams,
|
||||
}: PageProps) {
|
||||
await connection();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ImportPage } from "@/features/transactions/components/import/import-pag
|
||||
import {
|
||||
buildOptionSets,
|
||||
buildSluggedFilters,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import { fetchTransactionFilterSources } from "@/features/transactions/queries";
|
||||
import { getUserId } from "@/shared/lib/auth/server";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
|
||||
* Loading state para a página de lançamentos
|
||||
* Mantém o mesmo layout da página final
|
||||
*/
|
||||
export default function LancamentosLoading() {
|
||||
export default function TransactionsLoading() {
|
||||
return (
|
||||
<main className="flex flex-col gap-6">
|
||||
{/* Month Picker placeholder */}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
mapTransactionsData,
|
||||
type ResolvedSearchParams,
|
||||
resolveTransactionPagination,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
import { landingImages } from "@/features/landing/images";
|
||||
import { fetchGitHubStats } from "@/features/landing/queries";
|
||||
import { AnimatedThemeToggler } from "@/shared/components/animated-theme-toggler";
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
import { Logo } from "@/shared/components/brand/logo";
|
||||
import { NavbarShell } from "@/shared/components/navigation/navbar/navbar-shell";
|
||||
import { Badge } from "@/shared/components/ui/badge";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { fetchTransactionAttachments } from "@/features/transactions/attachment-queries";
|
||||
import { fetchTransactionAttachments } from "@/features/transactions/lib/attachment-queries";
|
||||
import { getOptionalUserSession } from "@/shared/lib/auth/server";
|
||||
|
||||
const PRIVATE_RESPONSE_HEADERS = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { fetchInstallmentAnticipations } from "@/features/transactions/anticipation-queries";
|
||||
import { fetchInstallmentAnticipations } from "@/features/transactions/lib/anticipation-queries";
|
||||
import { getOptionalUserSession } from "@/shared/lib/auth/server";
|
||||
|
||||
const PRIVATE_RESPONSE_HEADERS = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import StatusDot from "@/shared/components/status-dot";
|
||||
import StatusDot from "@/shared/components/feedback/status-dot";
|
||||
import { getAccountTypeIcon } from "@/shared/utils/icons";
|
||||
|
||||
export function AccountTypeSelectContent({ label }: { label: string }) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { toast } from "sonner";
|
||||
import { deleteAccountAction } from "@/features/accounts/actions";
|
||||
import { AccountCard } from "@/features/accounts/components/account-card";
|
||||
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { EmptyState } from "@/shared/components/feedback/empty-state";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
import {
|
||||
|
||||
@@ -99,13 +99,13 @@ async function fetchAccountsByStatus(
|
||||
return { accounts, logoOptions };
|
||||
}
|
||||
|
||||
export async function fetchAccountsForUser(
|
||||
async function fetchAccountsForUser(
|
||||
userId: string,
|
||||
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
|
||||
return fetchAccountsByStatus(userId, false);
|
||||
}
|
||||
|
||||
export async function fetchInactiveForUser(
|
||||
async function fetchInactiveForUser(
|
||||
userId: string,
|
||||
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
|
||||
return fetchAccountsByStatus(userId, true);
|
||||
|
||||
@@ -154,7 +154,7 @@ export async function fetchAccountSummary(
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchAccountLancamentos(
|
||||
export async function fetchAccountTransactions(
|
||||
filters: SQL[],
|
||||
settledOnly = true,
|
||||
) {
|
||||
@@ -167,7 +167,7 @@ export async function fetchAccountLancamentos(
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchAccountLancamentosPage(
|
||||
export async function fetchAccountTransactionsPage(
|
||||
filters: SQL[],
|
||||
{
|
||||
page,
|
||||
|
||||
@@ -18,7 +18,7 @@ import { fetchTransactionDialogOptionsAction } from "@/features/transactions/act
|
||||
import { TransactionDetailsDialog } from "@/features/transactions/components/dialogs/transaction-details-dialog";
|
||||
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
|
||||
import type { TransactionItem } from "@/features/transactions/components/types";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { EmptyState } from "@/shared/components/feedback/empty-state";
|
||||
import { Card, CardContent } from "@/shared/components/ui/card";
|
||||
import { cn } from "@/shared/utils/ui";
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { fetchJson } from "@/shared/lib/fetch-json";
|
||||
import { fetchJson } from "@/shared/utils/fetch-json";
|
||||
|
||||
const ATTACHMENT_URL_STALE_TIME = 4 * 60 * 1000;
|
||||
|
||||
export const attachmentUrlQueryKey = (attachmentId: string) =>
|
||||
const attachmentUrlQueryKey = (attachmentId: string) =>
|
||||
["attachments", "url", attachmentId] as const;
|
||||
|
||||
export function useAttachmentUrlQuery(attachmentId: string, enabled: boolean) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
RiBarChart2Line,
|
||||
RiShieldCheckLine,
|
||||
} from "@remixicon/react";
|
||||
import { Logo } from "@/shared/components/logo";
|
||||
import { Logo } from "@/shared/components/brand/logo";
|
||||
import { DotPattern } from "@/shared/components/ui/dot-pattern";
|
||||
import { AuthSidebarInvoicesMock } from "./auth-sidebar-invoices-mock";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
duplicatePreviousMonthBudgetsAction,
|
||||
} from "@/features/budgets/actions";
|
||||
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { EmptyState } from "@/shared/components/feedback/empty-state";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
import { BudgetCard } from "./budget-card";
|
||||
|
||||
@@ -26,7 +26,7 @@ type BudgetData = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type CategoryOption = {
|
||||
type CategoryOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
buildOptionSets,
|
||||
buildSluggedFilters,
|
||||
mapTransactionsData,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { RiBankLine } from "@remixicon/react";
|
||||
import Image from "next/image";
|
||||
import StatusDot from "@/shared/components/status-dot";
|
||||
import StatusDot from "@/shared/components/feedback/status-dot";
|
||||
import { resolveCardBrandLogoSrc } from "@/shared/lib/cards/brand-assets";
|
||||
import { resolveLogoSrc } from "@/shared/lib/logo";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { deleteCardAction } from "@/features/cards/actions";
|
||||
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { EmptyState } from "@/shared/components/feedback/empty-state";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { Card as UiCard } from "@/shared/components/ui/card";
|
||||
import {
|
||||
|
||||
@@ -19,7 +19,7 @@ type CardData = {
|
||||
accountName: string;
|
||||
};
|
||||
|
||||
export type AccountSimple = {
|
||||
type AccountSimple = {
|
||||
id: string;
|
||||
name: string;
|
||||
logo: string | null;
|
||||
@@ -121,7 +121,7 @@ async function fetchCardsByStatus(
|
||||
return { cards: cardList, accounts, logoOptions };
|
||||
}
|
||||
|
||||
export async function fetchCardsForUser(userId: string): Promise<{
|
||||
async function fetchCardsForUser(userId: string): Promise<{
|
||||
cards: CardData[];
|
||||
accounts: AccountSimple[];
|
||||
logoOptions: string[];
|
||||
@@ -129,7 +129,7 @@ export async function fetchCardsForUser(userId: string): Promise<{
|
||||
return fetchCardsByStatus(userId, false);
|
||||
}
|
||||
|
||||
export async function fetchInactiveForUser(userId: string): Promise<{
|
||||
async function fetchInactiveForUser(userId: string): Promise<{
|
||||
cards: CardData[];
|
||||
accounts: AccountSimple[];
|
||||
logoOptions: string[];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import StatusDot from "@/shared/components/status-dot";
|
||||
import StatusDot from "@/shared/components/feedback/status-dot";
|
||||
|
||||
export function TypeSelectContent({ label }: { label: string }) {
|
||||
const isReceita = label === "Receita";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { type Category, categories } from "@/db/schema";
|
||||
import type { CategoryType } from "@/shared/lib/categories/constants";
|
||||
import { db } from "@/shared/lib/db";
|
||||
|
||||
export type CategoryData = {
|
||||
type CategoryData = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: CategoryType;
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "@/shared/utils/financial-dates";
|
||||
|
||||
export type BillDialogState = PaymentDialogState;
|
||||
export type BillStatusDateItem = Pick<
|
||||
type BillStatusDateItem = Pick<
|
||||
DashboardBill,
|
||||
"dueDate" | "boletoPaymentDate" | "isSettled"
|
||||
>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { and, desc, eq, isNull, ne, or, sql } from "drizzle-orm";
|
||||
import { categories, financialAccounts, transactions } from "@/db/schema";
|
||||
import { mapTransactionsData } from "@/features/transactions/page-helpers";
|
||||
import { mapTransactionsData } from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
ACCOUNT_AUTO_INVOICE_NOTE_PREFIX,
|
||||
INITIAL_BALANCE_NOTE,
|
||||
@@ -17,7 +17,7 @@ import { getPreviousPeriod } from "@/shared/utils/period";
|
||||
|
||||
type MappedLancamentos = ReturnType<typeof mapTransactionsData>;
|
||||
|
||||
export type CategoryDetailData = {
|
||||
type CategoryDetailData = {
|
||||
category: {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
@@ -11,14 +11,14 @@ import {
|
||||
formatPeriodMonthShort,
|
||||
} from "@/shared/utils/period";
|
||||
|
||||
export type CategoryOption = {
|
||||
type CategoryOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
type: "receita" | "despesa";
|
||||
};
|
||||
|
||||
export type CategoryHistoryItem = {
|
||||
type CategoryHistoryItem = {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
excludeInitialBalanceWhenConfigured,
|
||||
excludeRefundEntries,
|
||||
excludeTransactionsFromExcludedAccounts,
|
||||
} from "@/features/dashboard/transaction-filters";
|
||||
} from "@/features/dashboard/lib/transaction-filters";
|
||||
import { db } from "@/shared/lib/db";
|
||||
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
|
||||
import { safeToNumber as toNumber } from "@/shared/utils/number";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
export type CategoryOption = {
|
||||
type CategoryOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type CategoryTransaction = {
|
||||
type CategoryTransaction = {
|
||||
id: string;
|
||||
name: string;
|
||||
amount: number;
|
||||
|
||||
@@ -14,8 +14,8 @@ import type {
|
||||
} from "@/features/dashboard/bills/bills-queries";
|
||||
import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
|
||||
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
|
||||
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { PaymentSuccess } from "@/shared/components/payment-success";
|
||||
import { Badge } from "@/shared/components/ui/badge";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RiBarcodeFill } from "@remixicon/react";
|
||||
import type { DashboardBill } from "@/features/dashboard/bills/bills-queries";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { BillListItem } from "./bill-list-item";
|
||||
|
||||
type BillsListProps = {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/shared/components/ui/tabs";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { formatPeriodForUrl } from "@/shared/utils/period";
|
||||
import { CategoryBreakdownChart } from "./category-breakdown-chart";
|
||||
import { CategoryBreakdownList } from "./category-breakdown-list";
|
||||
|
||||
@@ -40,8 +40,8 @@ import {
|
||||
} from "@/features/dashboard/widget-registry/widget-config";
|
||||
import { NoteDialog } from "@/features/notes/components/note-dialog";
|
||||
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
|
||||
import { ExpandableWidgetCard } from "@/shared/components/expandable-widget-card";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { ExpandableWidgetCard } from "@/shared/components/widgets/expandable-widget-card";
|
||||
|
||||
type DashboardGridEditableProps = {
|
||||
data: DashboardData;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RiFundsLine } from "@remixicon/react";
|
||||
import type { GoalProgressItem } from "@/features/dashboard/goals-progress/goals-progress-queries";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { GoalProgressItem as GoalProgressListItem } from "./goals-progress-item";
|
||||
|
||||
type GoalsProgressListProps = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RiNumbersLine } from "@remixicon/react";
|
||||
import type { InstallmentExpense } from "@/features/dashboard/expenses/installment-expenses-queries";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { InstallmentExpenseListItem } from "./installment-expense-list-item";
|
||||
|
||||
type InstallmentExpensesListProps = {
|
||||
|
||||
@@ -14,8 +14,8 @@ import type {
|
||||
InvoicePaymentAccountOption,
|
||||
} from "@/features/dashboard/invoices/invoices-queries";
|
||||
import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
|
||||
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { PaymentSuccess } from "@/shared/components/payment-success";
|
||||
import { Badge } from "@/shared/components/ui/badge";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RiBillLine } from "@remixicon/react";
|
||||
import type { DashboardInvoice } from "@/features/dashboard/invoices/invoices-queries";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { InvoiceListItem } from "./invoice-list-item";
|
||||
|
||||
type InvoicesListProps = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RiTodoLine } from "@remixicon/react";
|
||||
import type { Note } from "@/features/notes/components/types";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { NoteListItem } from "./note-list-item";
|
||||
|
||||
type NotesListProps = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import {
|
||||
PaymentBreakdownListItem,
|
||||
type PaymentBreakdownListItemData,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import StatusDot from "@/shared/components/feedback/status-dot";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import StatusDot from "@/shared/components/status-dot";
|
||||
import { Progress } from "@/shared/components/ui/progress";
|
||||
|
||||
type PaymentStatusCategorySectionProps = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { RiWallet3Line } from "@remixicon/react";
|
||||
import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries";
|
||||
import { CardContent } from "@/shared/components/ui/card";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { PaymentStatusCategorySection } from "./payment-status-category-section";
|
||||
|
||||
type PaymentStatusWidgetViewProps = {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import { formatPercentage } from "@/shared/utils/percentage";
|
||||
import { cn } from "@/shared/utils/ui";
|
||||
|
||||
export type PercentageChangeTrend = "up" | "down" | "flat";
|
||||
type PercentageChangeTrend = "up" | "down" | "flat";
|
||||
|
||||
type PercentageChangeIndicatorProps = {
|
||||
value?: number | null;
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/shared/components/ui/tooltip";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { formatDateOnly } from "@/shared/utils/date";
|
||||
import { formatBytes } from "@/shared/utils/number";
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/shared/components/ui/popover";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { CATEGORY_COLORS } from "@/shared/utils/category-colors";
|
||||
import { formatCurrency, formatCurrencyCompact } from "@/shared/utils/currency";
|
||||
import { getIconComponent } from "@/shared/utils/icons";
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { DashboardCategoryBreakdownItem } from "@/features/dashboard/catego
|
||||
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
|
||||
import { CategoryIconBadge } from "@/shared/components/entity-avatar";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { formatPercentage } from "@/shared/utils/percentage";
|
||||
|
||||
type CategoryTrendsWidgetProps = {
|
||||
|
||||
@@ -9,7 +9,7 @@ import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import type { DashboardInboxSnapshot } from "@/features/dashboard/inbox-snapshot-queries";
|
||||
import type { DashboardInboxSnapshot } from "@/features/dashboard/lib/inbox-snapshot-queries";
|
||||
import type { DashboardWidgetQuickActionOptions } from "@/features/dashboard/widget-registry/widget-config";
|
||||
import {
|
||||
discardInboxItemAction,
|
||||
@@ -19,7 +19,7 @@ import { TransactionDialog } from "@/features/transactions/components/dialogs/tr
|
||||
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { resolveLogoSrc } from "@/shared/lib/logo";
|
||||
|
||||
const DEFAULT_INBOX_APP_LOGO = "/avatars/default_icon.png";
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
} from "@/shared/components/ui/chart";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { formatCurrency } from "@/shared/utils/currency";
|
||||
|
||||
type IncomeExpenseBalanceWidgetProps = {
|
||||
|
||||
@@ -10,7 +10,7 @@ import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
import type { DashboardAccount } from "@/features/dashboard/accounts-queries";
|
||||
import type { DashboardAccount } from "@/features/dashboard/lib/accounts-queries";
|
||||
import { updateMyAccountsWidgetPreference } from "@/features/dashboard/widget-registry/widget-actions";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { Badge } from "@/shared/components/ui/badge";
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/shared/components/ui/tooltip";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { isAccountInactive } from "@/shared/lib/accounts/constants";
|
||||
import { resolveLogoSrc } from "@/shared/lib/logo";
|
||||
import { formatPeriodForUrl } from "@/shared/utils/period";
|
||||
|
||||
@@ -7,14 +7,14 @@ import {
|
||||
} from "@remixicon/react";
|
||||
import Link from "next/link";
|
||||
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
|
||||
import type { DashboardPagador } from "@/features/dashboard/payers-queries";
|
||||
import type { DashboardPagador } from "@/features/dashboard/lib/payers-queries";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/shared/components/ui/avatar";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { getAvatarSrc } from "@/shared/lib/payers/utils";
|
||||
import { buildInitials } from "@/shared/utils/initials";
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/shared/components/ui/select";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { CATEGORY_TYPE_LABEL } from "@/shared/lib/categories/constants";
|
||||
import { formatTransactionDate } from "@/shared/utils/date";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { RiRefreshLine } from "@remixicon/react";
|
||||
import type { RecurringExpensesData } from "@/features/dashboard/expenses/recurring-expenses-queries";
|
||||
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
|
||||
type RecurringExpensesWidgetProps = {
|
||||
data: RecurringExpensesData;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { RiArrowUpDoubleLine, RiStore2Line } from "@remixicon/react";
|
||||
import { useState } from "react";
|
||||
import type { TopExpensesData } from "@/features/dashboard/expenses/top-expenses-queries";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { RiStore2Line } from "@remixicon/react";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
|
||||
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
|
||||
type TopEstablishmentsWidgetProps = {
|
||||
data: TopEstablishmentsData;
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
import { EstablishmentLogo } from "@/shared/components/entity-avatar";
|
||||
import MoneyValues from "@/shared/components/money-values";
|
||||
import { Switch } from "@/shared/components/ui/switch";
|
||||
import { WidgetEmptyState } from "@/shared/components/widget-empty-state";
|
||||
import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
|
||||
import { formatTransactionDate } from "@/shared/utils/date";
|
||||
|
||||
type TopExpensesWidgetProps = {
|
||||
|
||||
@@ -31,7 +31,7 @@ function calculateDueDate(period: string, dueDay: string | null): Date | null {
|
||||
}
|
||||
}
|
||||
|
||||
export type InstallmentDetail = {
|
||||
type InstallmentDetail = {
|
||||
id: string;
|
||||
currentInstallment: number;
|
||||
amount: number;
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
formatLastInstallmentDate,
|
||||
} from "@/shared/lib/installments/utils";
|
||||
|
||||
export type InstallmentExpenseDisplay = {
|
||||
type InstallmentExpenseDisplay = {
|
||||
compactLabel: string | null;
|
||||
isLast: boolean;
|
||||
remainingInstallments: number;
|
||||
@@ -13,7 +13,7 @@ export type InstallmentExpenseDisplay = {
|
||||
progress: number;
|
||||
};
|
||||
|
||||
export const buildInstallmentCompactLabel = (
|
||||
const buildInstallmentCompactLabel = (
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
) => {
|
||||
@@ -24,7 +24,7 @@ export const buildInstallmentCompactLabel = (
|
||||
return null;
|
||||
};
|
||||
|
||||
export const isInstallmentLast = (
|
||||
const isInstallmentLast = (
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
) => {
|
||||
@@ -35,7 +35,7 @@ export const isInstallmentLast = (
|
||||
return currentInstallment === installmentCount && installmentCount > 1;
|
||||
};
|
||||
|
||||
export const calculateInstallmentRemainingCount = (
|
||||
const calculateInstallmentRemainingCount = (
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
) => {
|
||||
@@ -46,7 +46,7 @@ export const calculateInstallmentRemainingCount = (
|
||||
return Math.max(0, installmentCount - currentInstallment);
|
||||
};
|
||||
|
||||
export const calculateInstallmentRemainingAmount = (
|
||||
const calculateInstallmentRemainingAmount = (
|
||||
amount: number,
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
@@ -54,7 +54,7 @@ export const calculateInstallmentRemainingAmount = (
|
||||
amount *
|
||||
calculateInstallmentRemainingCount(currentInstallment, installmentCount);
|
||||
|
||||
export const formatInstallmentEndDate = (
|
||||
const formatInstallmentEndDate = (
|
||||
period: string,
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
@@ -72,7 +72,7 @@ export const formatInstallmentEndDate = (
|
||||
return formatLastInstallmentDate(lastDate);
|
||||
};
|
||||
|
||||
export const buildInstallmentProgress = (
|
||||
const buildInstallmentProgress = (
|
||||
currentInstallment: number | null,
|
||||
installmentCount: number | null,
|
||||
) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type RecurringExpense = {
|
||||
type RecurringExpense = {
|
||||
id: string;
|
||||
name: string;
|
||||
amount: number;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { cacheLife, cacheTag } from "next/cache";
|
||||
import { fetchAttachmentsForPeriod } from "@/features/attachments/queries";
|
||||
import { fetchDashboardAccounts } from "./accounts-queries";
|
||||
import { fetchDashboardCategoryOverview } from "./categories/category-overview-queries";
|
||||
import { fetchDashboardInboxSnapshot } from "./inbox-snapshot-queries";
|
||||
import { fetchDashboardInvoices } from "./invoices/invoices-queries";
|
||||
import { fetchDashboardAccounts } from "./lib/accounts-queries";
|
||||
import { fetchDashboardInboxSnapshot } from "./lib/inbox-snapshot-queries";
|
||||
import { fetchDashboardPayers } from "./lib/payers-queries";
|
||||
import { fetchDashboardNotes } from "./notes/notes-queries";
|
||||
import { fetchDashboardCurrentPeriodOverview } from "./overview/current-period-overview-queries";
|
||||
import { fetchDashboardPeriodOverview } from "./overview/period-overview-queries";
|
||||
import { fetchDashboardPayers } from "./payers-queries";
|
||||
|
||||
async function fetchDashboardDataInternal(userId: string, period: string) {
|
||||
const [
|
||||
|
||||
@@ -5,7 +5,6 @@ import type {
|
||||
import type {
|
||||
GoalProgressCategory,
|
||||
GoalProgressItem,
|
||||
GoalProgressStatus,
|
||||
} from "@/features/dashboard/goals-progress/goals-progress-queries";
|
||||
import { formatPercentage } from "@/shared/utils/percentage";
|
||||
|
||||
@@ -18,9 +17,6 @@ export const formatGoalProgressPercentage = (value: number, withSign = false) =>
|
||||
signDisplay: withSign ? "always" : "auto",
|
||||
});
|
||||
|
||||
export const getGoalProgressStatusColorClass = (status: GoalProgressStatus) =>
|
||||
status === "exceeded" ? "text-destructive" : "";
|
||||
|
||||
export const mapGoalProgressCategoriesToBudgetCategories = (
|
||||
categories: GoalProgressCategory[],
|
||||
): BudgetCategory[] =>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type GoalProgressStatus = "on-track" | "critical" | "exceeded";
|
||||
type GoalProgressStatus = "on-track" | "critical" | "exceeded";
|
||||
|
||||
export type GoalProgressItem = {
|
||||
id: string;
|
||||
|
||||
@@ -55,7 +55,7 @@ type RawInvoiceBreakdownRow = {
|
||||
amount: number | string | null;
|
||||
};
|
||||
|
||||
export type InvoicePagadorBreakdown = {
|
||||
type InvoicePagadorBreakdown = {
|
||||
payerId: string | null;
|
||||
pagadorName: string;
|
||||
pagadorAvatar: string | null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { DashboardData } from "./fetch-dashboard-data";
|
||||
import type { DashboardData } from "../fetch-dashboard-data";
|
||||
|
||||
/**
|
||||
* Coleta todos os nomes de estabelecimentos exibidos nos widgets do
|
||||
@@ -3,7 +3,7 @@ import { cacheLife, cacheTag } from "next/cache";
|
||||
import { cards, financialAccounts, inboxItems } from "@/db/schema";
|
||||
import { db } from "@/shared/lib/db";
|
||||
|
||||
export type DashboardInboxItem = {
|
||||
type DashboardInboxItem = {
|
||||
id: string;
|
||||
sourceAppName: string | null;
|
||||
parsedName: string | null;
|
||||
@@ -8,11 +8,11 @@ import { getBusinessDateString } from "@/shared/utils/date";
|
||||
import {
|
||||
type DashboardNotificationsSnapshot,
|
||||
fetchDashboardNotifications,
|
||||
} from "./notifications/notifications-queries";
|
||||
} from "../notifications/notifications-queries";
|
||||
|
||||
type DashboardNavbarData = {
|
||||
pagadorAvatarUrl: string | null;
|
||||
preLancamentosCount: number;
|
||||
payerAvatarUrl: string | null;
|
||||
inboxPendingCount: number;
|
||||
notificationsSnapshot: DashboardNotificationsSnapshot;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ async function fetchDashboardNavbarDataInternal(
|
||||
userId: string,
|
||||
): Promise<DashboardNavbarData> {
|
||||
const currentPeriod = getBusinessDateString().slice(0, 7);
|
||||
const [pagadorAvatarUrl, notificationsSnapshot, preLancamentosCount] =
|
||||
const [payerAvatarUrl, notificationsSnapshot, inboxPendingCount] =
|
||||
await Promise.all([
|
||||
fetchAdminPayerAvatarUrl(userId),
|
||||
fetchDashboardNotifications(userId, currentPeriod),
|
||||
@@ -47,8 +47,8 @@ async function fetchDashboardNavbarDataInternal(
|
||||
]);
|
||||
|
||||
return {
|
||||
pagadorAvatarUrl,
|
||||
preLancamentosCount,
|
||||
payerAvatarUrl,
|
||||
inboxPendingCount,
|
||||
notificationsSnapshot,
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { and, desc, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||
import { financialAccounts, payers, transactions } from "@/db/schema";
|
||||
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/transaction-filters";
|
||||
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/lib/transaction-filters";
|
||||
import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/shared/lib/accounts/constants";
|
||||
import { db } from "@/shared/lib/db";
|
||||
import { PAYER_ROLE_ADMIN } from "@/shared/lib/payers/constants";
|
||||
@@ -1,4 +1,4 @@
|
||||
export type TopEstablishment = {
|
||||
type TopEstablishment = {
|
||||
id: string;
|
||||
name: string;
|
||||
amount: number;
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DashboardNote } from "@/features/dashboard/notes/notes-queries";
|
||||
import type { Note } from "@/features/notes/components/types";
|
||||
|
||||
export const mapDashboardNoteToNote = (note: DashboardNote): Note => ({
|
||||
const mapDashboardNoteToNote = (note: DashboardNote): Note => ({
|
||||
id: note.id,
|
||||
title: note.title,
|
||||
description: note.description,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { and, eq } from "drizzle-orm";
|
||||
import { notes } from "@/db/schema";
|
||||
import { db } from "@/shared/lib/db";
|
||||
|
||||
export type DashboardTask = {
|
||||
type DashboardTask = {
|
||||
id: string;
|
||||
text: string;
|
||||
completed: boolean;
|
||||
|
||||
@@ -31,13 +31,7 @@ import {
|
||||
getNextPeriod,
|
||||
} from "@/shared/utils/period";
|
||||
|
||||
export type {
|
||||
BudgetNotification,
|
||||
BudgetStatus,
|
||||
DashboardNotification,
|
||||
DashboardNotificationsSnapshot,
|
||||
NotificationType,
|
||||
} from "@/shared/lib/types/notifications";
|
||||
export type { DashboardNotificationsSnapshot } from "@/shared/lib/types/notifications";
|
||||
|
||||
const PAYMENT_METHOD_BOLETO = "Boleto";
|
||||
const BUDGET_CRITICAL_THRESHOLD = 80;
|
||||
|
||||
@@ -13,11 +13,11 @@ import type {
|
||||
TopExpense,
|
||||
TopExpensesData,
|
||||
} from "@/features/dashboard/expenses/top-expenses-queries";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
|
||||
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/lib/transaction-filters";
|
||||
import type { PaymentConditionsData } from "@/features/dashboard/payments/payment-conditions-queries";
|
||||
import type { PaymentMethodsData } from "@/features/dashboard/payments/payment-methods-queries";
|
||||
import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries";
|
||||
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries";
|
||||
import { excludeTransactionsFromExcludedAccounts } from "@/features/dashboard/transaction-filters";
|
||||
import {
|
||||
ACCOUNT_AUTO_INVOICE_NOTE_PREFIX,
|
||||
INITIAL_BALANCE_NOTE,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { and, asc, eq, gte, inArray, lte, sql } from "drizzle-orm";
|
||||
import { financialAccounts, transactions } from "@/db/schema";
|
||||
import type { DashboardCardMetrics } from "@/features/dashboard/overview/dashboard-metrics-queries";
|
||||
import type {
|
||||
IncomeExpenseBalanceData,
|
||||
MonthData,
|
||||
} from "@/features/dashboard/overview/income-expense-balance-queries";
|
||||
import {
|
||||
buildDashboardAdminFilters,
|
||||
excludeAutoInvoiceEntries,
|
||||
excludeInitialBalanceWhenConfigured,
|
||||
excludeTransactionsFromExcludedAccounts,
|
||||
} from "@/features/dashboard/transaction-filters";
|
||||
} from "@/features/dashboard/lib/transaction-filters";
|
||||
import type { DashboardCardMetrics } from "@/features/dashboard/overview/dashboard-metrics-queries";
|
||||
import type {
|
||||
IncomeExpenseBalanceData,
|
||||
MonthData,
|
||||
} from "@/features/dashboard/overview/income-expense-balance-queries";
|
||||
import { REFUND_NOTE_PREFIX } from "@/shared/lib/accounts/constants";
|
||||
import { db } from "@/shared/lib/db";
|
||||
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { cacheLife, cacheTag } from "next/cache";
|
||||
import { fetchDashboardData } from "@/features/dashboard/fetch-dashboard-data";
|
||||
import { fetchUserDashboardPreferences } from "@/features/dashboard/preferences-queries";
|
||||
import { fetchUserDashboardPreferences } from "@/features/dashboard/lib/preferences-queries";
|
||||
import {
|
||||
buildOptionSets,
|
||||
buildSluggedFilters,
|
||||
} from "@/features/transactions/page-helpers";
|
||||
} from "@/features/transactions/lib/page-helpers";
|
||||
import {
|
||||
fetchRecentEstablishments,
|
||||
fetchTransactionFilterSources,
|
||||
@@ -52,7 +52,7 @@ async function fetchDashboardQuickActionOptionsInternal(
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchDashboardQuickActionOptions(userId: string) {
|
||||
async function fetchDashboardQuickActionOptions(userId: string) {
|
||||
"use cache";
|
||||
cacheTag(`dashboard-${userId}`);
|
||||
cacheLife({ revalidate: 3 });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type PaymentConditionSummary = {
|
||||
type PaymentConditionSummary = {
|
||||
condition: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type PaymentMethodSummary = {
|
||||
type PaymentMethodSummary = {
|
||||
paymentMethod: string;
|
||||
amount: number;
|
||||
percentage: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type PaymentStatusCategory = {
|
||||
type PaymentStatusCategory = {
|
||||
total: number;
|
||||
confirmed: number;
|
||||
pending: number;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { RiAtLine, RiCalendarEventLine } from "@remixicon/react";
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
import { EmptyState } from "@/shared/components/empty-state";
|
||||
import { EmptyState } from "@/shared/components/feedback/empty-state";
|
||||
import { Card } from "@/shared/components/ui/card";
|
||||
import { InboxCard } from "./inbox-card";
|
||||
import type { InboxItem } from "./types";
|
||||
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
RiArrowRightDoubleLine,
|
||||
RiArrowRightSLine,
|
||||
} from "@remixicon/react";
|
||||
import {
|
||||
INBOX_DEFAULT_PAGE_SIZE,
|
||||
INBOX_PAGE_SIZE_OPTIONS,
|
||||
} from "@/features/inbox/page-helpers";
|
||||
import { INBOX_PAGE_SIZE_OPTIONS } from "@/features/inbox/page-helpers";
|
||||
import { Button } from "@/shared/components/ui/button";
|
||||
import {
|
||||
Select,
|
||||
@@ -117,6 +114,3 @@ export function InboxPagination({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Re-export para facilitar uso externo
|
||||
export { INBOX_DEFAULT_PAGE_SIZE };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TabsList, TabsTrigger } from "@/shared/components/ui/tabs";
|
||||
import type { InboxStatus, InboxStatusCounts } from "./types";
|
||||
import type { InboxStatusCounts } from "./types";
|
||||
|
||||
type InboxTabsProps = {
|
||||
counts: InboxStatusCounts;
|
||||
@@ -36,5 +36,3 @@ export function InboxTabs({ counts, isPending }: InboxTabsProps) {
|
||||
</TabsList>
|
||||
);
|
||||
}
|
||||
|
||||
export type { InboxStatus, InboxStatusCounts };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SelectOption as LancamentoSelectOption } from "@/features/transactions/components/types";
|
||||
import type { SelectOption as TransactionSelectOption } from "@/features/transactions/components/types";
|
||||
|
||||
export type InboxStatus = "pending" | "processed" | "discarded";
|
||||
|
||||
@@ -29,4 +29,4 @@ export type InboxPaginationState = {
|
||||
};
|
||||
|
||||
// Re-export the lancamentos SelectOption for use in inbox components
|
||||
export type SelectOption = LancamentoSelectOption;
|
||||
export type SelectOption = TransactionSelectOption;
|
||||
|
||||
@@ -7,9 +7,9 @@ export type ResolvedInboxSearchParams =
|
||||
export const INBOX_DEFAULT_PAGE_SIZE = 12;
|
||||
export const INBOX_PAGE_SIZE_OPTIONS = [12, 24, 48];
|
||||
|
||||
export const INBOX_STATUSES = ["pending", "processed", "discarded"] as const;
|
||||
const INBOX_STATUSES = ["pending", "processed", "discarded"] as const;
|
||||
|
||||
export const getSingleParam = (
|
||||
const getSingleParam = (
|
||||
params: ResolvedInboxSearchParams,
|
||||
key: string,
|
||||
): string | null => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user