@fayz-ai/plugin-financial 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +3 -3
  2. package/dist/components/PersonStatementWidget.d.ts +1 -1
  3. package/dist/components/PersonStatementWidget.d.ts.map +1 -1
  4. package/dist/{FinancialContext.d.ts → context.d.ts} +4 -2
  5. package/dist/context.d.ts.map +1 -0
  6. package/dist/data/registries.d.ts.map +1 -0
  7. package/dist/index.d.ts +13 -4
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1426 -1426
  10. package/dist/index.js.map +1 -1
  11. package/dist/integrations/stripe/connectorDef.d.ts +14 -0
  12. package/dist/integrations/stripe/connectorDef.d.ts.map +1 -0
  13. package/dist/integrations/stripe/data.d.ts +43 -0
  14. package/dist/integrations/stripe/data.d.ts.map +1 -0
  15. package/dist/lib/message-events.d.ts +12 -0
  16. package/dist/lib/message-events.d.ts.map +1 -0
  17. package/dist/{quick-add.d.ts → lib/quick-add.d.ts} +1 -1
  18. package/dist/lib/quick-add.d.ts.map +1 -0
  19. package/dist/locales/en.d.ts.map +1 -1
  20. package/dist/locales/pt-BR.d.ts.map +1 -1
  21. package/dist/{FinancialPage.d.ts → views/FinancialPage.d.ts} +3 -3
  22. package/dist/views/FinancialPage.d.ts.map +1 -0
  23. package/dist/views/InvoiceDetailView.d.ts.map +1 -1
  24. package/dist/views/InvoiceFormView.d.ts.map +1 -1
  25. package/dist/views/InvoiceListView.d.ts.map +1 -1
  26. package/dist/views/PayablesView.d.ts +1 -1
  27. package/dist/views/PayablesView.d.ts.map +1 -1
  28. package/dist/views/ReceivablesView.d.ts +1 -1
  29. package/dist/views/ReceivablesView.d.ts.map +1 -1
  30. package/dist/views/StatementsView.d.ts.map +1 -1
  31. package/dist/views/dashboardWidgets.d.ts +1 -1
  32. package/dist/views/dashboardWidgets.d.ts.map +1 -1
  33. package/package.json +12 -14
  34. package/dist/FinancialContext.d.ts.map +0 -1
  35. package/dist/FinancialPage.d.ts.map +0 -1
  36. package/dist/contract.test.d.ts +0 -2
  37. package/dist/contract.test.d.ts.map +0 -1
  38. package/dist/quick-add.d.ts.map +0 -1
  39. package/dist/registries.d.ts.map +0 -1
  40. package/src/FinancialContext.tsx +0 -59
  41. package/src/FinancialPage.tsx +0 -413
  42. package/src/README.md +0 -155
  43. package/src/components/FinancialGeneralSettings.tsx +0 -39
  44. package/src/components/FinancialOnboarding.tsx +0 -87
  45. package/src/components/FinancialSettings.tsx +0 -31
  46. package/src/components/PaymentModal.tsx +0 -369
  47. package/src/components/PersonStatementWidget.tsx +0 -133
  48. package/src/components/TransferModal.tsx +0 -150
  49. package/src/contract.test.ts +0 -58
  50. package/src/data/capability.test.ts +0 -135
  51. package/src/data/index.ts +0 -3
  52. package/src/data/mock.ts +0 -842
  53. package/src/data/supabase.ts +0 -968
  54. package/src/data/tables.ts +0 -13
  55. package/src/data/types.ts +0 -86
  56. package/src/index.ts +0 -487
  57. package/src/lib/tenant.ts +0 -3
  58. package/src/locales/en.ts +0 -493
  59. package/src/locales/index.ts +0 -7
  60. package/src/locales/pt-BR.ts +0 -493
  61. package/src/migrations/000_plg_rename.sql +0 -30
  62. package/src/migrations/001_financial_base.sql +0 -109
  63. package/src/migrations/002_chart_of_accounts.sql +0 -28
  64. package/src/migrations/003_card_brands.sql +0 -12
  65. package/src/migrations/004_order_to_cash.sql +0 -178
  66. package/src/migrations/005_seed_defaults.sql +0 -38
  67. package/src/migrations/006_rls_policies.sql +0 -37
  68. package/src/migrations/006b_extract_fee_amount.sql +0 -20
  69. package/src/migrations/007_reconciliation.sql +0 -32
  70. package/src/migrations/007b_movement_payment_method_type.sql +0 -6
  71. package/src/migrations/008_split_payment_movements.sql +0 -29
  72. package/src/migrations/009_agent_rpcs.sql +0 -165
  73. package/src/migrations/010_invoice_internal.sql +0 -133
  74. package/src/migrations/011_nfe.sql +0 -58
  75. package/src/migrations/index.ts +0 -923
  76. package/src/quick-add.ts +0 -58
  77. package/src/registries.ts +0 -308
  78. package/src/store.ts +0 -329
  79. package/src/types.ts +0 -592
  80. package/src/views/CardsView.tsx +0 -213
  81. package/src/views/CashRegistersView.tsx +0 -597
  82. package/src/views/CommissionsView.tsx +0 -18
  83. package/src/views/InvoiceDetailView.tsx +0 -616
  84. package/src/views/InvoiceFormView.tsx +0 -945
  85. package/src/views/InvoiceListView.tsx +0 -323
  86. package/src/views/NotasFiscaisView.tsx +0 -209
  87. package/src/views/PayablesView.tsx +0 -48
  88. package/src/views/QuickTransactionForm.tsx +0 -548
  89. package/src/views/ReceivablesView.tsx +0 -48
  90. package/src/views/ReconciliationView.tsx +0 -211
  91. package/src/views/StatementsView.tsx +0 -335
  92. package/src/views/SummaryView.tsx +0 -203
  93. package/src/views/dashboardWidgets.tsx +0 -437
  94. package/src/views/navReferrer.ts +0 -24
  95. /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
@@ -1,213 +0,0 @@
1
- import React, { useEffect, useMemo, useState } from 'react'
2
- import { CreditCard, Plus, CalendarClock } from 'lucide-react'
3
- import { useFinancialConfig, useFinancialStore, formatCurrency } from '../FinancialContext'
4
- import { SubpageHeader } from '@fayz-ai/ui'
5
- import { PermissionGate } from '@fayz-ai/saas'
6
- import { useTranslation } from '@fayz-ai/core'
7
- import type { BankAccount } from '../types'
8
- import { QuickTransactionForm } from './QuickTransactionForm'
9
-
10
- // ---------------------------------------------------------------------------
11
- // Per-card money math. Credit-card balances are stored as debt (negative), so
12
- // the current bill (fatura) is the magnitude owed; the available limit is what
13
- // remains of the credit line.
14
- // ---------------------------------------------------------------------------
15
-
16
- function cardMath(acc: BankAccount) {
17
- const limit = acc.creditLimit ?? 0
18
- const used = Math.max(0, -acc.currentBalance)
19
- const available = Math.max(0, limit - used)
20
- const pct = limit > 0 ? Math.min(100, (used / limit) * 100) : 0
21
- return { limit, used, available, pct }
22
- }
23
-
24
- export function CardsView() {
25
- const t = useTranslation()
26
- const { currency } = useFinancialConfig()
27
- const bankAccounts = useFinancialStore((s) => s.bankAccounts)
28
- const bankAccountsLoading = useFinancialStore((s) => s.bankAccountsLoading)
29
- const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts)
30
-
31
- const [tab, setTab] = useState<'open' | 'closed'>('open')
32
- const [addOpen, setAddOpen] = useState(false)
33
- const [addCardId, setAddCardId] = useState<string | undefined>()
34
-
35
- useEffect(() => { fetchBankAccounts() }, [])
36
-
37
- const cards = useMemo(
38
- () => bankAccounts.filter((a) => a.accountType === 'credit_card'),
39
- [bankAccounts],
40
- )
41
- const openCards = useMemo(() => cards.filter((c) => c.isActive), [cards])
42
- const closedCards = useMemo(() => cards.filter((c) => !c.isActive), [cards])
43
- const visibleCards = tab === 'open' ? openCards : closedCards
44
-
45
- // Summary strip is computed over the active (open) cards — the money that is
46
- // actually in play this cycle.
47
- const summary = useMemo(() => {
48
- let totalAvailable = 0
49
- let totalBills = 0
50
- for (const c of openCards) {
51
- const { available, used } = cardMath(c)
52
- totalAvailable += available
53
- totalBills += used
54
- }
55
- return { totalAvailable, totalBills }
56
- }, [openCards])
57
-
58
- function openAddExpense(cardId: string) {
59
- setAddCardId(cardId)
60
- setAddOpen(true)
61
- }
62
-
63
- return (
64
- <div className="space-y-4">
65
- <SubpageHeader title={t('financial.cards.title')} subtitle={t('financial.cards.subtitle')} />
66
-
67
- {bankAccountsLoading && cards.length === 0 ? (
68
- <div className="text-center py-12 text-sm text-muted-foreground">Loading...</div>
69
- ) : cards.length === 0 ? (
70
- <div className="flex flex-col items-center justify-center py-12 text-center rounded-2xl border-2 border-dashed border-muted">
71
- <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-amber-300 to-yellow-600 mb-3 text-white shadow-sm">
72
- <CreditCard className="h-6 w-6" />
73
- </div>
74
- <p className="text-sm font-medium">{t('financial.cards.noCards')}</p>
75
- <p className="text-xs text-muted-foreground mt-0.5 max-w-xs">{t('financial.cards.noCardsHint')}</p>
76
- </div>
77
- ) : (
78
- <>
79
- {/* Summary strip — available limit + total bills across open cards */}
80
- <div className="grid grid-cols-2 gap-px overflow-hidden rounded-2xl border bg-border shadow-sm">
81
- <div className="bg-card px-4 py-3">
82
- <p className="text-xs text-muted-foreground">{t('financial.cards.availableLimit')}</p>
83
- <p className="mt-0.5 text-lg font-bold tabular-nums text-success">
84
- {formatCurrency(summary.totalAvailable, currency)}
85
- </p>
86
- </div>
87
- <div className="bg-card px-4 py-3">
88
- <p className="text-xs text-muted-foreground">{t('financial.cards.allBillsValue')}</p>
89
- <p className="mt-0.5 text-lg font-bold tabular-nums">
90
- {formatCurrency(summary.totalBills, currency)}
91
- </p>
92
- </div>
93
- </div>
94
-
95
- {/* Open / Closed tabs (only when there are closed cards to switch to) */}
96
- {closedCards.length > 0 && (
97
- <div className="flex gap-1 rounded-full bg-muted p-1 w-full max-w-xs">
98
- {(['open', 'closed'] as const).map((k) => (
99
- <button
100
- key={k}
101
- onClick={() => setTab(k)}
102
- className={`flex-1 rounded-full px-3 py-1.5 text-xs font-medium transition-colors ${
103
- tab === k ? 'bg-card text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'
104
- }`}
105
- >
106
- {k === 'open' ? t('financial.cards.tabOpen') : t('financial.cards.tabClosed')}
107
- </button>
108
- ))}
109
- </div>
110
- )}
111
-
112
- {/* Card tiles — stacked on mobile, grid on desktop */}
113
- <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
114
- {visibleCards.map((card) => {
115
- const { limit, used, available, pct } = cardMath(card)
116
- const over = pct >= 90
117
- // Per-brand color so cards match the bank (and the Home card), not a uniform gold.
118
- const brand = `${card.bankName ?? ''} ${card.name ?? ''}`.toLowerCase()
119
- const headerGrad =
120
- brand.includes('nubank') || brand.includes('nu ') ? 'from-purple-500 via-purple-600 to-indigo-700'
121
- : brand.includes('ita') ? 'from-orange-400 via-orange-500 to-amber-600'
122
- : brand.includes('inter') ? 'from-orange-500 via-orange-600 to-orange-700'
123
- : 'from-indigo-500 via-indigo-600 to-violet-700'
124
- const barGrad =
125
- brand.includes('nubank') || brand.includes('nu ') ? 'from-purple-500 to-indigo-600'
126
- : brand.includes('ita') ? 'from-orange-400 to-amber-500'
127
- : brand.includes('inter') ? 'from-orange-500 to-orange-600'
128
- : 'from-indigo-500 to-violet-600'
129
- return (
130
- <div key={card.id} className="overflow-hidden rounded-2xl border bg-card shadow-sm">
131
- {/* Per-brand header */}
132
- <div className={`bg-gradient-to-br ${headerGrad} px-4 py-4 text-white`}>
133
- <div className="flex items-start justify-between">
134
- <div className="flex items-center gap-2">
135
- <CreditCard className="h-5 w-5" />
136
- <span className="text-sm font-semibold">{card.name}</span>
137
- </div>
138
- {card.bankName && (
139
- <span className="text-[11px] font-medium uppercase tracking-wide opacity-80">
140
- {card.bankName}
141
- </span>
142
- )}
143
- </div>
144
- <div className="mt-4">
145
- <p className="text-[11px] uppercase tracking-wide opacity-80">
146
- {t('financial.cards.currentBill')}
147
- </p>
148
- <p className="text-2xl font-bold tabular-nums leading-tight">
149
- {formatCurrency(used, currency)}
150
- </p>
151
- </div>
152
- </div>
153
-
154
- {/* Body */}
155
- <div className="space-y-3 px-4 py-3">
156
- {/* Usage progress bar */}
157
- <div>
158
- <div className="flex items-center justify-between text-[11px] text-muted-foreground">
159
- <span>{t('financial.cards.usedOfLimit', { percent: String(Math.round(pct)) })}</span>
160
- <span className="tabular-nums">{formatCurrency(limit, currency)}</span>
161
- </div>
162
- <div className="mt-1 h-2 overflow-hidden rounded-full bg-muted">
163
- <div
164
- className={`h-full rounded-full ${
165
- over ? 'bg-destructive' : `bg-gradient-to-r ${barGrad}`
166
- }`}
167
- style={{ width: `${pct}%` }}
168
- />
169
- </div>
170
- </div>
171
-
172
- {/* Available limit + due date */}
173
- <div className="flex items-center justify-between">
174
- <div>
175
- <p className="text-[11px] text-muted-foreground">{t('financial.cards.availableLimit')}</p>
176
- <p className="text-sm font-semibold tabular-nums">{formatCurrency(available, currency)}</p>
177
- </div>
178
- {card.dueDay != null && (
179
- <div className="flex items-center gap-1.5 text-right text-xs text-muted-foreground">
180
- <CalendarClock className="h-3.5 w-3.5" />
181
- <span>{t('financial.cards.dueOn', { day: String(card.dueDay) })}</span>
182
- </div>
183
- )}
184
- </div>
185
-
186
- {/* Add expense against this card — gated on the role's create action */}
187
- <PermissionGate feature="financial" action="create">
188
- <button
189
- type="button"
190
- onClick={() => openAddExpense(card.id)}
191
- className="flex w-full items-center justify-center gap-1.5 rounded-input border border-input bg-card px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-muted/40"
192
- >
193
- <Plus className="h-3.5 w-3.5" />
194
- {t('financial.cards.addExpense')}
195
- </button>
196
- </PermissionGate>
197
- </div>
198
- </div>
199
- )
200
- })}
201
- </div>
202
- </>
203
- )}
204
-
205
- <QuickTransactionForm
206
- open={addOpen}
207
- onOpenChange={setAddOpen}
208
- defaultType="expense"
209
- defaultAccountId={addCardId}
210
- />
211
- </div>
212
- )
213
- }