@fayz-ai/plugin-financial 0.8.3 → 0.8.4

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.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React17 = require('react');
3
+ var React18 = require('react');
4
4
  var core = require('@fayz-ai/core');
5
5
  var ui = require('@fayz-ai/ui');
6
6
  var saas = require('@fayz-ai/saas');
@@ -27,7 +27,7 @@ function _interopNamespace(e) {
27
27
  return Object.freeze(n);
28
28
  }
29
29
 
30
- var React17__namespace = /*#__PURE__*/_interopNamespace(React17);
30
+ var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
31
31
 
32
32
  // src/index.ts
33
33
  var ctx = saas.createPluginContext("FinancialPage");
@@ -68,7 +68,7 @@ function categoryIcon(label) {
68
68
  function useDateLabel() {
69
69
  const t2 = core.useTranslation();
70
70
  const { currency } = useFinancialConfig();
71
- return React17.useMemo(() => {
71
+ return React18.useMemo(() => {
72
72
  const todayStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
73
73
  const y = /* @__PURE__ */ new Date();
74
74
  y.setDate(y.getDate() - 1);
@@ -98,7 +98,7 @@ function MobileSummary() {
98
98
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
99
99
  const fetchStatement = useFinancialStore((s) => s.fetchStatement);
100
100
  const dateLabel = useDateLabel();
101
- React17.useEffect(() => {
101
+ React18.useEffect(() => {
102
102
  void fetchSummary();
103
103
  void fetchBankAccounts();
104
104
  const to = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -109,11 +109,11 @@ function MobileSummary() {
109
109
  const fmt = (n) => saas.formatCurrency(n, currency);
110
110
  const inflow = summary?.monthlyInflow ?? 0;
111
111
  const outflow = summary?.monthlyOutflow ?? 0;
112
- const accountName = React17.useMemo(() => {
112
+ const accountName = React18.useMemo(() => {
113
113
  const map = new Map(bankAccounts.map((a) => [a.id, a.name]));
114
114
  return (id) => id ? map.get(id) ?? "" : "";
115
115
  }, [bankAccounts]);
116
- const groups = React17.useMemo(() => {
116
+ const groups = React18.useMemo(() => {
117
117
  const entries = (statement?.entries ?? []).filter((e) => e.entryKind === "movement");
118
118
  const byDate = /* @__PURE__ */ new Map();
119
119
  for (const e of entries) {
@@ -193,9 +193,9 @@ function typeTheme(type) {
193
193
  }
194
194
  }
195
195
  function ChipSelect({ icon: Icon, label, value, options, onChange, emptyLabel }) {
196
- const [open, setOpen] = React17.useState(false);
197
- const ref = React17.useRef(null);
198
- React17.useEffect(() => {
196
+ const [open, setOpen] = React18.useState(false);
197
+ const ref = React18.useRef(null);
198
+ React18.useEffect(() => {
199
199
  if (!open) return;
200
200
  function onDoc(e) {
201
201
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -275,22 +275,22 @@ function QuickTransactionForm({ open, onOpenChange, defaultType = "expense", def
275
275
  const createQuickTransaction = useFinancialStore((s) => s.createQuickTransaction);
276
276
  const guardMovements = saas.useLimitGuard("movements_month");
277
277
  const can = saas.usePermissionOptional();
278
- const [type, setType] = React17.useState(defaultType);
279
- const [amount, setAmount] = React17.useState(0);
280
- const [amountStr, setAmountStr] = React17.useState("");
281
- const [paid, setPaid] = React17.useState(true);
282
- const [date, setDate] = React17.useState(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
283
- const [description, setDescription] = React17.useState("");
284
- const [categoryId, setCategoryId] = React17.useState();
285
- const [accountId, setAccountId] = React17.useState();
286
- const [toAccountId, setToAccountId] = React17.useState();
287
- const [recurring, setRecurring] = React17.useState(false);
288
- const [saving, setSaving] = React17.useState(false);
289
- const [receiptUrl, setReceiptUrl] = React17.useState();
290
- const fileInputRef = React17.useRef(null);
291
- const [accounts, setAccounts] = React17.useState([]);
292
- const [categories, setCategories] = React17.useState([]);
293
- React17.useEffect(() => {
278
+ const [type, setType] = React18.useState(defaultType);
279
+ const [amount, setAmount] = React18.useState(0);
280
+ const [amountStr, setAmountStr] = React18.useState("");
281
+ const [paid, setPaid] = React18.useState(true);
282
+ const [date, setDate] = React18.useState(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
283
+ const [description, setDescription] = React18.useState("");
284
+ const [categoryId, setCategoryId] = React18.useState();
285
+ const [accountId, setAccountId] = React18.useState();
286
+ const [toAccountId, setToAccountId] = React18.useState();
287
+ const [recurring, setRecurring] = React18.useState(false);
288
+ const [saving, setSaving] = React18.useState(false);
289
+ const [receiptUrl, setReceiptUrl] = React18.useState();
290
+ const fileInputRef = React18.useRef(null);
291
+ const [accounts, setAccounts] = React18.useState([]);
292
+ const [categories, setCategories] = React18.useState([]);
293
+ React18.useEffect(() => {
294
294
  if (!open) return;
295
295
  setType(defaultType);
296
296
  setAmount(0);
@@ -304,7 +304,7 @@ function QuickTransactionForm({ open, onOpenChange, defaultType = "expense", def
304
304
  setRecurring(false);
305
305
  setReceiptUrl(void 0);
306
306
  }, [open, defaultType, defaultAccountId]);
307
- React17.useEffect(() => {
307
+ React18.useEffect(() => {
308
308
  if (open && focusReceipt) {
309
309
  const id = window.setTimeout(() => fileInputRef.current?.click(), 250);
310
310
  return () => window.clearTimeout(id);
@@ -325,7 +325,7 @@ function QuickTransactionForm({ open, onOpenChange, defaultType = "expense", def
325
325
  reader.onerror = () => ui.toast.error(t2("financial.quickTx.receiptInvalid"));
326
326
  reader.readAsDataURL(file);
327
327
  }
328
- React17.useEffect(() => {
328
+ React18.useEffect(() => {
329
329
  if (!open) return;
330
330
  let cancelled = false;
331
331
  void (async () => {
@@ -344,11 +344,11 @@ function QuickTransactionForm({ open, onOpenChange, defaultType = "expense", def
344
344
  }, [open, provider]);
345
345
  const theme = typeTheme(type);
346
346
  const HeaderIcon = theme.icon;
347
- const accountOptions = React17.useMemo(
347
+ const accountOptions = React18.useMemo(
348
348
  () => accounts.map((a) => ({ id: a.id, name: a.name, hint: a.accountType === "credit_card" ? t2("financial.quickTx.card") : void 0 })),
349
349
  [accounts, t2]
350
350
  );
351
- const categoryOptions = React17.useMemo(
351
+ const categoryOptions = React18.useMemo(
352
352
  () => categories.filter((c) => c.isActive).map((c) => ({ id: c.id, name: c.name, hint: c.code })),
353
353
  [categories]
354
354
  );
@@ -662,7 +662,7 @@ function getSnapshot() {
662
662
  return pending;
663
663
  }
664
664
  function usePendingQuickAdd() {
665
- return React17__namespace.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
665
+ return React18__namespace.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
666
666
  }
667
667
  var STATUS_OPTIONS = [
668
668
  { value: "open", labelKey: "financial.invoice.statusOpen", color: "bg-info-soft text-info-soft-foreground", icon: lucideReact.CircleDashed },
@@ -700,7 +700,7 @@ function StatusBadge({ status }) {
700
700
  }
701
701
  function useInvoiceColumns(currency) {
702
702
  const t2 = core.useTranslation();
703
- return React17.useMemo(() => [
703
+ return React18.useMemo(() => [
704
704
  {
705
705
  accessorKey: "fiscalNumber",
706
706
  header: "#",
@@ -759,16 +759,16 @@ function InvoiceListView({ direction, onNew, onEdit }) {
759
759
  useFinancialStore((s) => s.invoicesTotal);
760
760
  const invoicesLoading = useFinancialStore((s) => s.invoicesLoading);
761
761
  const fetchInvoices = useFinancialStore((s) => s.fetchInvoices);
762
- const [search, setSearch] = React17.useState("");
763
- const [statusFilter, setStatusFilter] = React17.useState([]);
764
- const [accountId, setAccountId] = React17.useState("");
765
- const [costCenterId, setCostCenterId] = React17.useState("");
766
- const [accounts, setAccounts] = React17.useState([]);
767
- const [costCenters, setCostCenters] = React17.useState([]);
768
- const [datePreset, setDatePreset] = React17.useState("all");
769
- const [dateFrom, setDateFrom] = React17.useState("");
770
- const [dateTo, setDateTo] = React17.useState("");
771
- const dateRange = React17.useMemo(() => {
762
+ const [search, setSearch] = React18.useState("");
763
+ const [statusFilter, setStatusFilter] = React18.useState([]);
764
+ const [accountId, setAccountId] = React18.useState("");
765
+ const [costCenterId, setCostCenterId] = React18.useState("");
766
+ const [accounts, setAccounts] = React18.useState([]);
767
+ const [costCenters, setCostCenters] = React18.useState([]);
768
+ const [datePreset, setDatePreset] = React18.useState("all");
769
+ const [dateFrom, setDateFrom] = React18.useState("");
770
+ const [dateTo, setDateTo] = React18.useState("");
771
+ const dateRange = React18.useMemo(() => {
772
772
  if (!dateFrom && !dateTo) return void 0;
773
773
  return { from: dateFrom || "0001-01-01", to: dateTo || "9999-12-31" };
774
774
  }, [dateFrom, dateTo]);
@@ -784,7 +784,7 @@ function InvoiceListView({ direction, onNew, onEdit }) {
784
784
  setDateFrom(range.from);
785
785
  setDateTo(range.to);
786
786
  };
787
- React17.useEffect(() => {
787
+ React18.useEffect(() => {
788
788
  let active = true;
789
789
  Promise.all([provider.getChartOfAccounts(), provider.getCostCenters()]).then(([accountRows, costCenterRows]) => {
790
790
  if (!active) return;
@@ -799,7 +799,7 @@ function InvoiceListView({ direction, onNew, onEdit }) {
799
799
  active = false;
800
800
  };
801
801
  }, [provider]);
802
- React17.useEffect(() => {
802
+ React18.useEffect(() => {
803
803
  fetchInvoices({
804
804
  direction,
805
805
  status: statusFilter.length > 0 ? statusFilter : void 0,
@@ -812,11 +812,11 @@ function InvoiceListView({ direction, onNew, onEdit }) {
812
812
  const filtered = invoices.filter((inv) => inv.direction === direction);
813
813
  const listTitle = direction === "debit" ? t2("financial.invoice.accountsPayable") : t2("financial.invoice.accountsReceivable");
814
814
  const columns = useInvoiceColumns(currency);
815
- const tags = React17.useMemo(
815
+ const tags = React18.useMemo(
816
816
  () => STATUS_OPTIONS.filter((o) => o.value !== "cancelled").map((o) => ({ value: o.value, label: t2(o.labelKey) })),
817
817
  [t2]
818
818
  );
819
- const summary = React17.useMemo(() => {
819
+ const summary = React18.useMemo(() => {
820
820
  let totalAmount = 0;
821
821
  let paidAmount = 0;
822
822
  let openAmount = 0;
@@ -980,10 +980,10 @@ function InvoiceListView({ direction, onNew, onEdit }) {
980
980
  }
981
981
  function LocationSelector({ locations, value, onChange }) {
982
982
  const t2 = core.useTranslation();
983
- const [open, setOpen] = React17.useState(false);
984
- const [search, setSearch] = React17.useState("");
985
- const ref = React17.useRef(null);
986
- React17.useEffect(() => {
983
+ const [open, setOpen] = React18.useState(false);
984
+ const [search, setSearch] = React18.useState("");
985
+ const ref = React18.useRef(null);
986
+ React18.useEffect(() => {
987
987
  function handler(e) {
988
988
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
989
989
  }
@@ -1063,7 +1063,7 @@ function ItemRow({ item, index, itemTypes, currency, expanded, onToggle, onUpdat
1063
1063
  const total = item.quantity * item.unitPrice - (item.discount ?? 0) + (item.surcharge ?? 0);
1064
1064
  const kindLabel = itemTypes.find((tp) => tp.value === item.itemKind)?.label ?? item.itemKind;
1065
1065
  const hasAdjustments = (item.discount ?? 0) > 0 || (item.surcharge ?? 0) > 0;
1066
- const [showAdjustments, setShowAdjustments] = React17.useState(hasAdjustments);
1066
+ const [showAdjustments, setShowAdjustments] = React18.useState(hasAdjustments);
1067
1067
  function handleFieldKeyDown(e) {
1068
1068
  if (e.key === "Enter" && !e.shiftKey) {
1069
1069
  e.preventDefault();
@@ -1301,25 +1301,25 @@ function InvoiceFormView({ direction, editId, onSaved }) {
1301
1301
  const can = saas.usePermissionOptional();
1302
1302
  const hasLocations = locations.length > 0;
1303
1303
  const isEdit = !!editId;
1304
- const [loaded, setLoaded] = React17.useState(!editId);
1305
- const [loading, setLoading] = React17.useState(!!editId);
1306
- const [contactName, setContactName] = React17.useState("");
1307
- const [contactId, setContactId] = React17.useState();
1308
- const [unitId, setUnitId] = React17.useState(locations[0]?.id ?? "");
1309
- const [invoiceDate, setInvoiceDate] = React17.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
1310
- const [fiscalNumber, setFiscalNumber] = React17.useState("");
1311
- const [observations, setObservations] = React17.useState("");
1312
- const [items, setItems] = React17.useState([]);
1313
- const [expandedItemId, setExpandedItemId] = React17.useState(null);
1314
- const [addingItem, setAddingItem] = React17.useState(false);
1315
- const [installments, setInstallments] = React17.useState([]);
1316
- const [saving, setSaving] = React17.useState(false);
1317
- const [menuOpen, setMenuOpen] = React17.useState(false);
1318
- const [confirmCancel, setConfirmCancel] = React17.useState(false);
1319
- const [cancelling, setCancelling] = React17.useState(false);
1320
- const menuRef = React17.useRef(null);
1304
+ const [loaded, setLoaded] = React18.useState(!editId);
1305
+ const [loading, setLoading] = React18.useState(!!editId);
1306
+ const [contactName, setContactName] = React18.useState("");
1307
+ const [contactId, setContactId] = React18.useState();
1308
+ const [unitId, setUnitId] = React18.useState(locations[0]?.id ?? "");
1309
+ const [invoiceDate, setInvoiceDate] = React18.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
1310
+ const [fiscalNumber, setFiscalNumber] = React18.useState("");
1311
+ const [observations, setObservations] = React18.useState("");
1312
+ const [items, setItems] = React18.useState([]);
1313
+ const [expandedItemId, setExpandedItemId] = React18.useState(null);
1314
+ const [addingItem, setAddingItem] = React18.useState(false);
1315
+ const [installments, setInstallments] = React18.useState([]);
1316
+ const [saving, setSaving] = React18.useState(false);
1317
+ const [menuOpen, setMenuOpen] = React18.useState(false);
1318
+ const [confirmCancel, setConfirmCancel] = React18.useState(false);
1319
+ const [cancelling, setCancelling] = React18.useState(false);
1320
+ const menuRef = React18.useRef(null);
1321
1321
  const cancelInvoice = useFinancialStore((s) => s.cancelInvoice);
1322
- React17.useEffect(() => {
1322
+ React18.useEffect(() => {
1323
1323
  if (!menuOpen) return;
1324
1324
  function handleClick(e) {
1325
1325
  if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
@@ -1338,7 +1338,7 @@ function InvoiceFormView({ direction, editId, onSaved }) {
1338
1338
  setCancelling(false);
1339
1339
  }
1340
1340
  }
1341
- React17.useEffect(() => {
1341
+ React18.useEffect(() => {
1342
1342
  if (!editId || loaded) return;
1343
1343
  setLoading(true);
1344
1344
  (async () => {
@@ -1375,8 +1375,8 @@ function InvoiceFormView({ direction, editId, onSaved }) {
1375
1375
  const totalAmount = items.reduce((sum, it) => {
1376
1376
  return sum + it.quantity * it.unitPrice - (it.discount ?? 0) + (it.surcharge ?? 0);
1377
1377
  }, 0);
1378
- const prevItemCount = React17.useRef(items.length);
1379
- React17.useEffect(() => {
1378
+ const prevItemCount = React18.useRef(items.length);
1379
+ React18.useEffect(() => {
1380
1380
  if (items.length > 0 && prevItemCount.current === 0 && installments.length === 0 && !isEdit) {
1381
1381
  const total = items.reduce((sum, it) => sum + it.quantity * it.unitPrice - (it.discount ?? 0) + (it.surcharge ?? 0), 0);
1382
1382
  if (total > 0) {
@@ -1385,7 +1385,7 @@ function InvoiceFormView({ direction, editId, onSaved }) {
1385
1385
  }
1386
1386
  prevItemCount.current = items.length;
1387
1387
  }, [items.length]);
1388
- React17.useEffect(() => {
1388
+ React18.useEffect(() => {
1389
1389
  if (installments.length > 0 && totalAmount > 0 && !isEdit) {
1390
1390
  const count = installments.length;
1391
1391
  const perInstallment = Math.floor(totalAmount * 100 / count) / 100;
@@ -1500,8 +1500,8 @@ function InvoiceFormView({ direction, editId, onSaved }) {
1500
1500
  items: items.map(({ _id, ...rest }) => rest),
1501
1501
  installments: installments.map(({ _id, ...rest }) => rest)
1502
1502
  };
1503
- const snapshot = React17.useRef(null);
1504
- React17.useEffect(() => {
1503
+ const snapshot = React18.useRef(null);
1504
+ React18.useEffect(() => {
1505
1505
  if (loaded && snapshot.current === null) snapshot.current = JSON.stringify(fields);
1506
1506
  }, [loaded]);
1507
1507
  const dirty = snapshot.current !== null && JSON.stringify(fields) !== snapshot.current;
@@ -1811,40 +1811,40 @@ function PaymentModal({ movement, onClose, onPaid }) {
1811
1811
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
1812
1812
  const fetchPaymentMethods = useFinancialStore((s) => s.fetchPaymentMethods);
1813
1813
  const remaining = movement.amount - movement.paidAmount;
1814
- const [amount, setAmount] = React17.useState(remaining);
1815
- const [paymentDate, setPaymentDate] = React17.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
1816
- const [selectedTypeId, setSelectedTypeId] = React17.useState("");
1817
- const [paymentMethodId, setPaymentMethodId] = React17.useState("");
1818
- const [bankAccountId, setBankAccountId] = React17.useState("");
1819
- const [cardBrand, setCardBrand] = React17.useState("");
1820
- const [cardInstallments, setCardInstallments] = React17.useState(1);
1821
- const [notes, setNotes] = React17.useState("");
1822
- const [saving, setSaving] = React17.useState(false);
1823
- const [visible, setVisible] = React17.useState(false);
1824
- const [expandMethodPicker, setExpandMethodPicker] = React17.useState(true);
1825
- React17.useEffect(() => {
1814
+ const [amount, setAmount] = React18.useState(remaining);
1815
+ const [paymentDate, setPaymentDate] = React18.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
1816
+ const [selectedTypeId, setSelectedTypeId] = React18.useState("");
1817
+ const [paymentMethodId, setPaymentMethodId] = React18.useState("");
1818
+ const [bankAccountId, setBankAccountId] = React18.useState("");
1819
+ const [cardBrand, setCardBrand] = React18.useState("");
1820
+ const [cardInstallments, setCardInstallments] = React18.useState(1);
1821
+ const [notes, setNotes] = React18.useState("");
1822
+ const [saving, setSaving] = React18.useState(false);
1823
+ const [visible, setVisible] = React18.useState(false);
1824
+ const [expandMethodPicker, setExpandMethodPicker] = React18.useState(true);
1825
+ React18.useEffect(() => {
1826
1826
  fetchBankAccounts();
1827
1827
  fetchPaymentMethods();
1828
1828
  requestAnimationFrame(() => setVisible(true));
1829
1829
  }, []);
1830
- const selectedType = React17.useMemo(
1830
+ const selectedType = React18.useMemo(
1831
1831
  () => paymentMethodTypes.find((tp) => tp.id === selectedTypeId),
1832
1832
  [paymentMethodTypes, selectedTypeId]
1833
1833
  );
1834
1834
  const txType = selectedType?.transactionType ?? "";
1835
- const filteredMethods = React17.useMemo(
1835
+ const filteredMethods = React18.useMemo(
1836
1836
  () => paymentMethods.filter((m) => m.paymentMethodTypeId === selectedTypeId),
1837
1837
  [paymentMethods, selectedTypeId]
1838
1838
  );
1839
1839
  const needsCard = txType === "credit_card" || txType === "debit_card";
1840
1840
  const needsCardInstallments = txType === "credit_card";
1841
- const eligibleAccounts = React17.useMemo(() => {
1841
+ const eligibleAccounts = React18.useMemo(() => {
1842
1842
  const allowed = selectedType?.allowedAccountTypes && selectedType.allowedAccountTypes.length ? selectedType.allowedAccountTypes : ACCOUNT_TYPES_FOR_TX[txType];
1843
1843
  if (!allowed || !allowed.length) return bankAccounts;
1844
1844
  const filtered = bankAccounts.filter((a) => allowed.includes(a.accountType));
1845
1845
  return filtered.length ? filtered : bankAccounts;
1846
1846
  }, [bankAccounts, selectedType, txType]);
1847
- React17.useEffect(() => {
1847
+ React18.useEffect(() => {
1848
1848
  if (selectedTypeId && !bankAccountId && eligibleAccounts.length) {
1849
1849
  setBankAccountId(eligibleAccounts[0].id);
1850
1850
  }
@@ -2088,26 +2088,28 @@ function InvoiceDetailView({ invoiceId, direction, onBack, onEdit, backLabel })
2088
2088
  const bankAccounts = useFinancialStore((s) => s.bankAccounts);
2089
2089
  const fetchPaymentMethods = useFinancialStore((s) => s.fetchPaymentMethods);
2090
2090
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
2091
- const [detailsLoaded, setDetailsLoaded] = React17.useState(false);
2092
- const [detailsLoading, setDetailsLoading] = React17.useState(false);
2093
- const [invoice, setInvoice] = React17.useState(null);
2094
- const [items, setItems] = React17.useState([]);
2095
- const [movements, setMovements] = React17.useState([]);
2096
- const [payments, setPayments] = React17.useState([]);
2097
- const [loading, setLoading] = React17.useState(true);
2098
- const [payingMovement, setPayingMovement] = React17.useState(null);
2099
- const [expandedMovId, setExpandedMovId] = React17.useState(null);
2100
- const [menuOpen, setMenuOpen] = React17.useState(false);
2101
- const [confirmCancel, setConfirmCancel] = React17.useState(false);
2102
- const [cancelling, setCancelling] = React17.useState(false);
2103
- const menuRef = React17.useRef(null);
2091
+ const [detailsLoaded, setDetailsLoaded] = React18.useState(false);
2092
+ const [detailsLoading, setDetailsLoading] = React18.useState(false);
2093
+ const [invoice, setInvoice] = React18.useState(null);
2094
+ const [items, setItems] = React18.useState([]);
2095
+ const [movements, setMovements] = React18.useState([]);
2096
+ const [payments, setPayments] = React18.useState([]);
2097
+ const [loading, setLoading] = React18.useState(true);
2098
+ const [payingMovement, setPayingMovement] = React18.useState(null);
2099
+ const [expandedMovId, setExpandedMovId] = React18.useState(null);
2100
+ const [menuOpen, setMenuOpen] = React18.useState(false);
2101
+ const [confirmCancel, setConfirmCancel] = React18.useState(false);
2102
+ const [cancelling, setCancelling] = React18.useState(false);
2103
+ const menuRef = React18.useRef(null);
2104
2104
  const cancelInvoice = useFinancialStore((s) => s.cancelInvoice);
2105
2105
  async function loadData() {
2106
2106
  setLoading(true);
2107
2107
  const [inv, invItems, movResult] = await Promise.all([
2108
2108
  provider.getInvoiceById(invoiceId),
2109
2109
  provider.getInvoiceItems(invoiceId),
2110
- provider.getMovements({ direction })
2110
+ // Scope to THIS invoice (not the tenant-wide first-50 page) so every
2111
+ // installment/payment loads regardless of how many movements exist.
2112
+ provider.getMovements({ direction, invoiceId, pageSize: 500 })
2111
2113
  ]);
2112
2114
  setInvoice(inv);
2113
2115
  setItems(invItems);
@@ -2119,10 +2121,10 @@ function InvoiceDetailView({ invoiceId, direction, onBack, onEdit, backLabel })
2119
2121
  );
2120
2122
  setLoading(false);
2121
2123
  }
2122
- React17.useEffect(() => {
2124
+ React18.useEffect(() => {
2123
2125
  loadData();
2124
2126
  }, [invoiceId]);
2125
- React17.useEffect(() => {
2127
+ React18.useEffect(() => {
2126
2128
  if (!menuOpen) return;
2127
2129
  function handleClick(e) {
2128
2130
  if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
@@ -2723,16 +2725,16 @@ function CashOpeningPanel({
2723
2725
  currency,
2724
2726
  onOpen
2725
2727
  }) {
2726
- const [selectedAccountId, setSelectedAccountId] = React17.useState(cashAccounts[0]?.id ?? "");
2727
- const [mode, setMode] = React17.useState("quick");
2728
- const [quickBalance, setQuickBalance] = React17.useState(0);
2729
- const [counts, setCounts] = React17.useState({});
2730
- const [notes, setNotes] = React17.useState("");
2731
- const [showNotes, setShowNotes] = React17.useState(false);
2732
- const [confirming, setConfirming] = React17.useState(false);
2733
- const [submitting, setSubmitting] = React17.useState(false);
2728
+ const [selectedAccountId, setSelectedAccountId] = React18.useState(cashAccounts[0]?.id ?? "");
2729
+ const [mode, setMode] = React18.useState("quick");
2730
+ const [quickBalance, setQuickBalance] = React18.useState(0);
2731
+ const [counts, setCounts] = React18.useState({});
2732
+ const [notes, setNotes] = React18.useState("");
2733
+ const [showNotes, setShowNotes] = React18.useState(false);
2734
+ const [confirming, setConfirming] = React18.useState(false);
2735
+ const [submitting, setSubmitting] = React18.useState(false);
2734
2736
  const t2 = core.useTranslation();
2735
- const countedTotal = React17.useMemo(() => {
2737
+ const countedTotal = React18.useMemo(() => {
2736
2738
  return BRL_DENOMINATIONS.reduce((sum, d) => sum + (counts[d.value] ?? 0) * d.value, 0);
2737
2739
  }, [counts]);
2738
2740
  const effectiveBalance = mode === "count" ? countedTotal : quickBalance;
@@ -2908,13 +2910,13 @@ function CashClosingPanel({
2908
2910
  currency,
2909
2911
  onClose
2910
2912
  }) {
2911
- const [mode, setMode] = React17.useState("quick");
2912
- const [quickBalance, setQuickBalance] = React17.useState(0);
2913
- const [counts, setCounts] = React17.useState({});
2914
- const [notes, setNotes] = React17.useState("");
2915
- const [submitting, setSubmitting] = React17.useState(false);
2913
+ const [mode, setMode] = React18.useState("quick");
2914
+ const [quickBalance, setQuickBalance] = React18.useState(0);
2915
+ const [counts, setCounts] = React18.useState({});
2916
+ const [notes, setNotes] = React18.useState("");
2917
+ const [submitting, setSubmitting] = React18.useState(false);
2916
2918
  const t2 = core.useTranslation();
2917
- const countedTotal = React17.useMemo(() => {
2919
+ const countedTotal = React18.useMemo(() => {
2918
2920
  return BRL_DENOMINATIONS.reduce((sum, d) => sum + (counts[d.value] ?? 0) * d.value, 0);
2919
2921
  }, [counts]);
2920
2922
  const effectiveBalance = mode === "count" ? countedTotal : quickBalance;
@@ -3019,8 +3021,8 @@ function CashRegistersView() {
3019
3021
  const fetchCashSessions = useFinancialStore((s) => s.fetchCashSessions);
3020
3022
  const openCashSession = useFinancialStore((s) => s.openCashSession);
3021
3023
  const closeCashSession = useFinancialStore((s) => s.closeCashSession);
3022
- const [expandedClosing, setExpandedClosing] = React17.useState(null);
3023
- React17.useEffect(() => {
3024
+ const [expandedClosing, setExpandedClosing] = React18.useState(null);
3025
+ React18.useEffect(() => {
3024
3026
  fetchBankAccounts();
3025
3027
  fetchCashSessions();
3026
3028
  }, []);
@@ -3124,7 +3126,7 @@ function OpenAnotherCollapsible({
3124
3126
  onOpen
3125
3127
  }) {
3126
3128
  const t2 = core.useTranslation();
3127
- const [expanded, setExpanded] = React17.useState(false);
3129
+ const [expanded, setExpanded] = React18.useState(false);
3128
3130
  const availableAccounts = cashAccounts.filter((a) => !openSessions.some((s) => s.bankAccountId === a.id));
3129
3131
  if (availableAccounts.length === 0) return null;
3130
3132
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border bg-card shadow-sm", children: [
@@ -3151,14 +3153,14 @@ function TransferModal({ onClose, onDone, defaultFromId }) {
3151
3153
  const bankAccounts = useFinancialStore((s) => s.bankAccounts);
3152
3154
  const createTransfer = useFinancialStore((s) => s.createTransfer);
3153
3155
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
3154
- const [fromAccountId, setFromAccountId] = React17.useState(defaultFromId ?? "");
3155
- const [toAccountId, setToAccountId] = React17.useState("");
3156
- const [amount, setAmount] = React17.useState(0);
3157
- const [date, setDate] = React17.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
3158
- const [notes, setNotes] = React17.useState("");
3159
- const [saving, setSaving] = React17.useState(false);
3160
- const [visible, setVisible] = React17.useState(false);
3161
- React17.useEffect(() => {
3156
+ const [fromAccountId, setFromAccountId] = React18.useState(defaultFromId ?? "");
3157
+ const [toAccountId, setToAccountId] = React18.useState("");
3158
+ const [amount, setAmount] = React18.useState(0);
3159
+ const [date, setDate] = React18.useState((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
3160
+ const [notes, setNotes] = React18.useState("");
3161
+ const [saving, setSaving] = React18.useState(false);
3162
+ const [visible, setVisible] = React18.useState(false);
3163
+ React18.useEffect(() => {
3162
3164
  fetchBankAccounts();
3163
3165
  requestAnimationFrame(() => setVisible(true));
3164
3166
  }, []);
@@ -3301,19 +3303,19 @@ function StatementsView({ onNavigate }) {
3301
3303
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
3302
3304
  const fetchPaymentMethods = useFinancialStore((s) => s.fetchPaymentMethods);
3303
3305
  const fetchStatement = useFinancialStore((s) => s.fetchStatement);
3304
- const [accountId, setAccountId] = React17.useState("");
3305
- const [dateFrom, setDateFrom] = React17.useState(() => {
3306
+ const [accountId, setAccountId] = React18.useState("");
3307
+ const [dateFrom, setDateFrom] = React18.useState(() => {
3306
3308
  const d = /* @__PURE__ */ new Date();
3307
3309
  d.setMonth(d.getMonth() - 3);
3308
3310
  return d.toISOString().slice(0, 10);
3309
3311
  });
3310
- const [dateTo, setDateTo] = React17.useState(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
3311
- const [showTransfer, setShowTransfer] = React17.useState(false);
3312
- React17.useEffect(() => {
3312
+ const [dateTo, setDateTo] = React18.useState(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
3313
+ const [showTransfer, setShowTransfer] = React18.useState(false);
3314
+ React18.useEffect(() => {
3313
3315
  fetchBankAccounts();
3314
3316
  fetchPaymentMethods();
3315
3317
  }, []);
3316
- const methodName = React17.useMemo(() => {
3318
+ const methodName = React18.useMemo(() => {
3317
3319
  const byId = new Map(paymentMethods.map((m) => [m.id, m.name]));
3318
3320
  const typeById = new Map(paymentMethodTypes.map((tp) => [tp.id, tp.name]));
3319
3321
  return (mov) => {
@@ -3328,7 +3330,7 @@ function StatementsView({ onNavigate }) {
3328
3330
  const base = e.movement.direction === "credit" ? "receivables" : "payables";
3329
3331
  onNavigate(`${base}-detail:${e.movement.invoiceId}`);
3330
3332
  }
3331
- React17.useEffect(() => {
3333
+ React18.useEffect(() => {
3332
3334
  if (accountId) {
3333
3335
  fetchStatement({
3334
3336
  bankAccountId: accountId === ALL ? void 0 : accountId,
@@ -3336,11 +3338,11 @@ function StatementsView({ onNavigate }) {
3336
3338
  });
3337
3339
  }
3338
3340
  }, [accountId, dateFrom, dateTo]);
3339
- React17.useEffect(() => {
3341
+ React18.useEffect(() => {
3340
3342
  if (!accountId) setAccountId(ALL);
3341
3343
  }, []);
3342
3344
  const fmt = (n) => saas.formatCurrency(n, currency);
3343
- const columns = React17.useMemo(() => [
3345
+ const columns = React18.useMemo(() => [
3344
3346
  {
3345
3347
  id: "date",
3346
3348
  header: t2("financial.statements.columnDate"),
@@ -3528,20 +3530,20 @@ function CardsView() {
3528
3530
  const bankAccounts = useFinancialStore((s) => s.bankAccounts);
3529
3531
  const bankAccountsLoading = useFinancialStore((s) => s.bankAccountsLoading);
3530
3532
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
3531
- const [tab, setTab] = React17.useState("open");
3532
- const [addOpen, setAddOpen] = React17.useState(false);
3533
- const [addCardId, setAddCardId] = React17.useState();
3534
- React17.useEffect(() => {
3533
+ const [tab, setTab] = React18.useState("open");
3534
+ const [addOpen, setAddOpen] = React18.useState(false);
3535
+ const [addCardId, setAddCardId] = React18.useState();
3536
+ React18.useEffect(() => {
3535
3537
  fetchBankAccounts();
3536
3538
  }, []);
3537
- const cards = React17.useMemo(
3539
+ const cards = React18.useMemo(
3538
3540
  () => bankAccounts.filter((a) => a.accountType === "credit_card"),
3539
3541
  [bankAccounts]
3540
3542
  );
3541
- const openCards = React17.useMemo(() => cards.filter((c) => c.isActive), [cards]);
3542
- const closedCards = React17.useMemo(() => cards.filter((c) => !c.isActive), [cards]);
3543
+ const openCards = React18.useMemo(() => cards.filter((c) => c.isActive), [cards]);
3544
+ const closedCards = React18.useMemo(() => cards.filter((c) => !c.isActive), [cards]);
3543
3545
  const visibleCards = tab === "open" ? openCards : closedCards;
3544
- const summary = React17.useMemo(() => {
3546
+ const summary = React18.useMemo(() => {
3545
3547
  let totalAvailable = 0;
3546
3548
  let totalBills = 0;
3547
3549
  for (const c of openCards) {
@@ -3657,14 +3659,14 @@ function ReconciliationView() {
3657
3659
  const { currency } = useFinancialConfig();
3658
3660
  const provider = useFinancialProvider();
3659
3661
  const fmt = (n) => saas.formatCurrency(n, currency);
3660
- const [lines, setLines] = React17.useState([]);
3661
- const [loading, setLoading] = React17.useState(true);
3662
- const [selectedId, setSelectedId] = React17.useState(null);
3663
- const [candidates, setCandidates] = React17.useState([]);
3664
- const [candidatesLoading, setCandidatesLoading] = React17.useState(false);
3665
- const [busy, setBusy] = React17.useState(false);
3662
+ const [lines, setLines] = React18.useState([]);
3663
+ const [loading, setLoading] = React18.useState(true);
3664
+ const [selectedId, setSelectedId] = React18.useState(null);
3665
+ const [candidates, setCandidates] = React18.useState([]);
3666
+ const [candidatesLoading, setCandidatesLoading] = React18.useState(false);
3667
+ const [busy, setBusy] = React18.useState(false);
3666
3668
  const supported = typeof provider.getUnreconciled === "function";
3667
- const load = React17.useCallback(async () => {
3669
+ const load = React18.useCallback(async () => {
3668
3670
  if (!provider.getUnreconciled) return;
3669
3671
  setLoading(true);
3670
3672
  try {
@@ -3675,10 +3677,10 @@ function ReconciliationView() {
3675
3677
  setLoading(false);
3676
3678
  }
3677
3679
  }, [provider]);
3678
- React17.useEffect(() => {
3680
+ React18.useEffect(() => {
3679
3681
  void load();
3680
3682
  }, [load]);
3681
- React17.useEffect(() => {
3683
+ React18.useEffect(() => {
3682
3684
  if (!selectedId || !provider.suggestReconciliation) {
3683
3685
  setCandidates([]);
3684
3686
  return;
@@ -3797,6 +3799,161 @@ function ReconciliationView() {
3797
3799
  ] })
3798
3800
  ] });
3799
3801
  }
3802
+ var MODEL_LABEL = {
3803
+ nfe: "NF-e",
3804
+ nfce: "NFC-e",
3805
+ nfse: "NFS-e"
3806
+ };
3807
+ var STATUS_META = {
3808
+ draft: { label: "Rascunho", className: "bg-muted text-muted-foreground" },
3809
+ processing: { label: "Processando", className: "bg-blue-100 text-blue-800" },
3810
+ issued: { label: "Emitida", className: "bg-emerald-100 text-emerald-800" },
3811
+ cancelled: { label: "Cancelada", className: "bg-red-100 text-red-700" },
3812
+ error: { label: "Erro", className: "bg-orange-100 text-orange-700" }
3813
+ };
3814
+ function NotasFiscaisView() {
3815
+ const provider = useFinancialProvider();
3816
+ const { currency } = useFinancialConfig();
3817
+ const [notas, setNotas] = React18.useState([]);
3818
+ const [loading, setLoading] = React18.useState(true);
3819
+ const [creating, setCreating] = React18.useState(false);
3820
+ const [busy, setBusy] = React18.useState(null);
3821
+ const supported = typeof provider.getNotas === "function";
3822
+ const reload = React18.useCallback(async () => {
3823
+ if (!provider.getNotas) {
3824
+ setLoading(false);
3825
+ return;
3826
+ }
3827
+ setLoading(true);
3828
+ try {
3829
+ const res = await provider.getNotas({ pageSize: 100 });
3830
+ setNotas(res.data);
3831
+ } finally {
3832
+ setLoading(false);
3833
+ }
3834
+ }, [provider]);
3835
+ React18.useEffect(() => {
3836
+ void reload();
3837
+ }, [reload]);
3838
+ const create = async (input) => {
3839
+ if (!provider.createNota) return;
3840
+ await provider.createNota(input);
3841
+ setCreating(false);
3842
+ await reload();
3843
+ };
3844
+ const issue = async (id) => {
3845
+ if (!provider.issueNota) return;
3846
+ setBusy(id);
3847
+ try {
3848
+ await provider.issueNota(id);
3849
+ await reload();
3850
+ } finally {
3851
+ setBusy(null);
3852
+ }
3853
+ };
3854
+ const cancel = async (id) => {
3855
+ if (!provider.cancelNota) return;
3856
+ setBusy(id);
3857
+ try {
3858
+ await provider.cancelNota(id);
3859
+ await reload();
3860
+ } finally {
3861
+ setBusy(null);
3862
+ }
3863
+ };
3864
+ if (!supported) {
3865
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
3866
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SubpageHeader, { title: "Notas Fiscais", subtitle: "Emiss\xE3o e acompanhamento de NF-e / NFC-e / NFS-e", icon: "FileText" }),
3867
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: "Este provedor financeiro ainda n\xE3o exp\xF5e notas fiscais." })
3868
+ ] });
3869
+ }
3870
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
3871
+ /* @__PURE__ */ jsxRuntime.jsx(
3872
+ ui.SubpageHeader,
3873
+ {
3874
+ title: "Notas Fiscais",
3875
+ subtitle: "Emiss\xE3o e acompanhamento de NF-e / NFC-e / NFS-e",
3876
+ icon: "FileText",
3877
+ actions: /* @__PURE__ */ jsxRuntime.jsx(saas.PermissionGate, { feature: "financial", action: "create", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "sm", onClick: () => setCreating(true), children: [
3878
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "mr-1.5 h-4 w-4" }),
3879
+ " Nova nota"
3880
+ ] }) })
3881
+ }
3882
+ ),
3883
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 rounded-md border border-amber-300/50 bg-amber-50 px-3 py-2 text-xs text-amber-800 dark:bg-amber-950/30 dark:text-amber-300", children: 'Emiss\xE3o fiscal (SEFAZ) ainda n\xE3o integrada \u2014 "Emitir" atribui n\xFAmero/s\xE9rie localmente para acompanhamento. A integra\xE7\xE3o com o emissor entra sem mudar esta tela.' }),
3884
+ creating && /* @__PURE__ */ jsxRuntime.jsx(CreateForm, { onCancel: () => setCreating(false), onCreate: create }),
3885
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 rounded-card border border-border bg-card p-3", children: [
3886
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-9 w-9 shrink-0 rounded-full" }),
3887
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
3888
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3.5 w-40 rounded" }),
3889
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-56 rounded" })
3890
+ ] }),
3891
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-20 shrink-0 rounded-md" })
3892
+ ] }, i)) }) : notas.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 rounded-card border border-dashed border-border p-8 text-center", children: [
3893
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "mx-auto h-8 w-8 text-muted-foreground" }),
3894
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm font-medium text-foreground", children: "Nenhuma nota fiscal ainda" }),
3895
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Crie uma nota a partir de um pedido ou manualmente." })
3896
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-2", children: notas.map((n) => {
3897
+ const meta = STATUS_META[n.status];
3898
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 rounded-card border border-border bg-card p-3", children: [
3899
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "h-4 w-4 text-primary" }) }),
3900
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
3901
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3902
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium text-foreground", children: [
3903
+ MODEL_LABEL[n.model],
3904
+ " ",
3905
+ n.number ? `#${n.number}` : "(rascunho)"
3906
+ ] }),
3907
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${meta.className}`, children: meta.label })
3908
+ ] }),
3909
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "truncate text-xs text-muted-foreground", children: [
3910
+ n.contactName || "Sem destinat\xE1rio",
3911
+ " \xB7 ",
3912
+ saas.formatCurrency(n.totalAmount, currency),
3913
+ n.issuedAt ? ` \xB7 ${n.issuedAt.slice(0, 10)}` : ""
3914
+ ] })
3915
+ ] }),
3916
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
3917
+ n.danfeUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "sm", variant: "ghost", onClick: () => window.open(n.danfeUrl, "_blank", "noopener,noreferrer"), title: "DANFE", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileCheck2, { className: "h-4 w-4" }) }),
3918
+ n.xmlUrl && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "sm", variant: "ghost", onClick: () => window.open(n.xmlUrl, "_blank", "noopener,noreferrer"), title: "XML", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" }) }),
3919
+ n.status === "draft" && /* @__PURE__ */ jsxRuntime.jsx(saas.PermissionGate, { feature: "financial", action: "edit", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { size: "sm", disabled: busy === n.id, onClick: () => issue(n.id), children: [
3920
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "mr-1.5 h-3.5 w-3.5" }),
3921
+ " Emitir"
3922
+ ] }) }),
3923
+ n.status === "issued" && /* @__PURE__ */ jsxRuntime.jsx(saas.PermissionGate, { feature: "financial", action: "edit", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "sm", variant: "ghost", disabled: busy === n.id, onClick: () => cancel(n.id), title: "Cancelar", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ban, { className: "h-4 w-4 text-red-500" }) }) })
3924
+ ] })
3925
+ ] }, n.id);
3926
+ }) })
3927
+ ] });
3928
+ }
3929
+ function CreateForm({ onCancel, onCreate }) {
3930
+ const [model, setModel] = React18.useState("nfe");
3931
+ const [contactName, setContactName] = React18.useState("");
3932
+ const [total, setTotal] = React18.useState("");
3933
+ const [observations, setObservations] = React18.useState("");
3934
+ const models = ["nfe", "nfce", "nfse"];
3935
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 rounded-card border border-border bg-card p-4", children: [
3936
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-3 text-sm font-semibold text-foreground", children: "Nova nota fiscal" }),
3937
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 flex flex-wrap gap-2", children: models.map((m) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setModel(m), className: `rounded-full px-3 py-1 text-xs font-medium ${m === model ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:text-foreground"}`, children: MODEL_LABEL[m] }, m)) }),
3938
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [
3939
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: contactName, placeholder: "Destinat\xE1rio", onChange: (e) => setContactName(e.target.value), className: "flex-1" }),
3940
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: total, placeholder: "Valor total", inputMode: "decimal", onChange: (e) => setTotal(e.target.value), className: "sm:w-40" })
3941
+ ] }),
3942
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { value: observations, placeholder: "Observa\xE7\xF5es (opcional)", onChange: (e) => setObservations(e.target.value), className: "mt-2" }),
3943
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex gap-2", children: [
3944
+ /* @__PURE__ */ jsxRuntime.jsx(
3945
+ ui.Button,
3946
+ {
3947
+ size: "sm",
3948
+ disabled: !total || Number.isNaN(Number(total)),
3949
+ onClick: () => onCreate({ model, contactName: contactName || void 0, totalAmount: Number(total) || 0, observations: observations || void 0 }),
3950
+ children: "Criar rascunho"
3951
+ }
3952
+ ),
3953
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "sm", variant: "outline", onClick: onCancel, children: "Cancelar" })
3954
+ ] })
3955
+ ] });
3956
+ }
3800
3957
  var FINANCIAL_DEFAULTS = {
3801
3958
  autoInstallments: true,
3802
3959
  requireDoc: false,
@@ -3833,7 +3990,7 @@ var STEPS = [
3833
3990
  ];
3834
3991
  function FinancialOnboarding({ onComplete }) {
3835
3992
  const t2 = core.useTranslation();
3836
- const [step, setStep] = React17.useState(0);
3993
+ const [step, setStep] = React18.useState(0);
3837
3994
  const current = STEPS[step];
3838
3995
  const isLast = step === STEPS.length - 1;
3839
3996
  const Icon = current.icon;
@@ -3940,6 +4097,15 @@ function buildNav(config, activeView, navigate, t2) {
3940
4097
  onClick: () => navigate("reconciliation")
3941
4098
  });
3942
4099
  }
4100
+ if (config.modules.notasFiscais) {
4101
+ items.push({
4102
+ id: "notas-fiscais",
4103
+ label: t2("financial.nav.notasFiscais"),
4104
+ icon: "FileText",
4105
+ active: activeView === "notas-fiscais",
4106
+ onClick: () => navigate("notas-fiscais")
4107
+ });
4108
+ }
3943
4109
  if (config.modules.commissions) {
3944
4110
  items.push({
3945
4111
  id: "commissions",
@@ -3980,16 +4146,17 @@ function FinancialPage({ config, provider, store, registries }) {
3980
4146
  reconciliation: 0,
3981
4147
  commissions: 0,
3982
4148
  cards: 0,
4149
+ "notas-fiscais": 0,
3983
4150
  settings: 1
3984
4151
  });
3985
- const [onboardingComplete, setOnboardingComplete] = React17.useState(() => {
4152
+ const [onboardingComplete, setOnboardingComplete] = React18.useState(() => {
3986
4153
  try {
3987
4154
  return localStorage.getItem("saas-core:financial-onboarded") === "true";
3988
4155
  } catch {
3989
4156
  return false;
3990
4157
  }
3991
4158
  });
3992
- React17.useEffect(() => {
4159
+ React18.useEffect(() => {
3993
4160
  if (onboardingComplete) return;
3994
4161
  let cancelled = false;
3995
4162
  void provider.getMovements({ pageSize: 1 }).then((res) => {
@@ -4006,16 +4173,16 @@ function FinancialPage({ config, provider, store, registries }) {
4006
4173
  const intent = parseIntent(view);
4007
4174
  const isSettings = view === "settings";
4008
4175
  const nav = saas.useModuleNavAccess(buildNav(config, view, navigate, t2));
4009
- const [quickAddOpen, setQuickAddOpen] = React17.useState(false);
4010
- const [quickAddType, setQuickAddType] = React17.useState("expense");
4011
- const [quickAddReceipt, setQuickAddReceipt] = React17.useState(false);
4012
- const openQuickAdd2 = React17.useCallback((type = "expense") => {
4176
+ const [quickAddOpen, setQuickAddOpen] = React18.useState(false);
4177
+ const [quickAddType, setQuickAddType] = React18.useState("expense");
4178
+ const [quickAddReceipt, setQuickAddReceipt] = React18.useState(false);
4179
+ const openQuickAdd2 = React18.useCallback((type = "expense") => {
4013
4180
  setQuickAddType(type);
4014
4181
  setQuickAddReceipt(false);
4015
4182
  setQuickAddOpen(true);
4016
4183
  }, []);
4017
4184
  const pendingQuickAdd = usePendingQuickAdd();
4018
- React17.useEffect(() => {
4185
+ React18.useEffect(() => {
4019
4186
  if (!pendingQuickAdd) return;
4020
4187
  const req = consumeQuickAdd();
4021
4188
  if (!req) return;
@@ -4024,7 +4191,7 @@ function FinancialPage({ config, provider, store, registries }) {
4024
4191
  setQuickAddReceipt(req.receipt);
4025
4192
  setQuickAddOpen(true);
4026
4193
  }, [pendingQuickAdd]);
4027
- const quickActions = React17.useMemo(() => {
4194
+ const quickActions = React18.useMemo(() => {
4028
4195
  if (config.quickAdd) return [];
4029
4196
  if (!canCreate) return [];
4030
4197
  const actions = [];
@@ -4096,6 +4263,8 @@ function FinancialPage({ config, provider, store, registries }) {
4096
4263
  return /* @__PURE__ */ jsxRuntime.jsx(CommissionsView, {});
4097
4264
  case "cards":
4098
4265
  return /* @__PURE__ */ jsxRuntime.jsx(CardsView, {});
4266
+ case "notas-fiscais":
4267
+ return /* @__PURE__ */ jsxRuntime.jsx(NotasFiscaisView, {});
4099
4268
  default:
4100
4269
  return /* @__PURE__ */ jsxRuntime.jsx(SummaryView, {});
4101
4270
  }
@@ -4158,7 +4327,7 @@ function FinancialPage({ config, provider, store, registries }) {
4158
4327
  }
4159
4328
  function useEnsureSummary() {
4160
4329
  const fetchSummary = useFinancialStore((s) => s.fetchSummary);
4161
- React17.useEffect(() => {
4330
+ React18.useEffect(() => {
4162
4331
  void fetchSummary();
4163
4332
  }, []);
4164
4333
  }
@@ -4282,7 +4451,7 @@ function RecentTransactions() {
4282
4451
  const { currency } = useFinancialConfig();
4283
4452
  const invoices = useFinancialStore((s) => s.invoices);
4284
4453
  const fetchInvoices = useFinancialStore((s) => s.fetchInvoices);
4285
- React17.useEffect(() => {
4454
+ React18.useEffect(() => {
4286
4455
  void fetchInvoices({ pageSize: 5 });
4287
4456
  }, []);
4288
4457
  const columns = [
@@ -4318,7 +4487,7 @@ function BalanceHero() {
4318
4487
  const summary = useFinancialStore((s) => s.summary);
4319
4488
  const navigate = ui.useDashboardNavigate();
4320
4489
  useEnsureSummary();
4321
- const [hidden, setHidden] = React17__namespace.default.useState(false);
4490
+ const [hidden, setHidden] = React18__namespace.default.useState(false);
4322
4491
  const money = (v) => hidden ? "\u2022\u2022\u2022\u2022\u2022\u2022" : saas.formatCurrency(v ?? 0, currency);
4323
4492
  const inflow = summary?.monthlyInflow ?? 0;
4324
4493
  const outflow = summary?.monthlyOutflow ?? 0;
@@ -4391,8 +4560,8 @@ function categorizeSpend(notes) {
4391
4560
  function SpendByCategoryChart() {
4392
4561
  const t2 = core.useTranslation();
4393
4562
  const provider = useFinancialProvider();
4394
- const [rows, setRows] = React17__namespace.default.useState([]);
4395
- React17.useEffect(() => {
4563
+ const [rows, setRows] = React18__namespace.default.useState([]);
4564
+ React18.useEffect(() => {
4396
4565
  let alive = true;
4397
4566
  void (async () => {
4398
4567
  const res = await provider.getMovements({ status: "paid", direction: "debit" });
@@ -4434,8 +4603,8 @@ function UpcomingBills() {
4434
4603
  const { currency } = useFinancialConfig();
4435
4604
  const provider = useFinancialProvider();
4436
4605
  const dueLabel = useDueLabel();
4437
- const [bills, setBills] = React17__namespace.default.useState([]);
4438
- React17.useEffect(() => {
4606
+ const [bills, setBills] = React18__namespace.default.useState([]);
4607
+ React18.useEffect(() => {
4439
4608
  let alive = true;
4440
4609
  void (async () => {
4441
4610
  const pending2 = await provider.getMovements({ status: "pending" });
@@ -4464,7 +4633,7 @@ function CreditCards() {
4464
4633
  const { currency } = useFinancialConfig();
4465
4634
  const bankAccounts = useFinancialStore((s) => s.bankAccounts);
4466
4635
  const fetchBankAccounts = useFinancialStore((s) => s.fetchBankAccounts);
4467
- React17.useEffect(() => {
4636
+ React18.useEffect(() => {
4468
4637
  void fetchBankAccounts();
4469
4638
  }, []);
4470
4639
  const cards = bankAccounts.filter((a) => a.accountType === "credit_card");
@@ -4609,7 +4778,8 @@ function createStore(options) {
4609
4778
  paymentMethodTypes: defaultPMTypes,
4610
4779
  chartOfAccounts: [],
4611
4780
  costCenters: [],
4612
- cardTransactions: []
4781
+ cardTransactions: [],
4782
+ notas: []
4613
4783
  };
4614
4784
  }
4615
4785
  function createMockFinancialProvider(options) {
@@ -5158,6 +5328,66 @@ function createMockFinancialProvider(options) {
5158
5328
  internal.updatedAt = now();
5159
5329
  }
5160
5330
  }
5331
+ },
5332
+ // --- Notas fiscais (NF-e / NFC-e / NFS-e) ---
5333
+ async getNotas(query) {
5334
+ let list = [...store.notas].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
5335
+ if (query.status) list = list.filter((n) => matchesStatus(n.status, query.status));
5336
+ if (query.model) list = list.filter((n) => n.model === query.model);
5337
+ if (query.orderId) list = list.filter((n) => n.orderId === query.orderId);
5338
+ if (query.search) {
5339
+ const q = query.search.toLowerCase();
5340
+ list = list.filter((n) => (n.number ?? "").toLowerCase().includes(q) || (n.contactName ?? "").toLowerCase().includes(q));
5341
+ }
5342
+ return paginate(list, query.page, query.pageSize);
5343
+ },
5344
+ async getNotaById(id) {
5345
+ return store.notas.find((n) => n.id === id) ?? null;
5346
+ },
5347
+ async createNota(input) {
5348
+ const nota = {
5349
+ id: uid(),
5350
+ tenantId: "mock-tenant",
5351
+ model: input.model ?? "nfe",
5352
+ status: "draft",
5353
+ number: null,
5354
+ series: input.series ?? null,
5355
+ orderId: input.orderId,
5356
+ contactId: input.contactId,
5357
+ contactName: input.contactName,
5358
+ totalAmount: input.totalAmount,
5359
+ observations: input.observations,
5360
+ createdAt: now(),
5361
+ updatedAt: now()
5362
+ };
5363
+ store.notas.unshift(nota);
5364
+ return nota;
5365
+ },
5366
+ async updateNota(id, patch) {
5367
+ const nota = store.notas.find((n) => n.id === id);
5368
+ if (!nota) throw new Error("Nota fiscal not found");
5369
+ Object.assign(nota, patch, { updatedAt: now() });
5370
+ return nota;
5371
+ },
5372
+ async issueNota(id) {
5373
+ const nota = store.notas.find((n) => n.id === id);
5374
+ if (!nota) throw new Error("Nota fiscal not found");
5375
+ const issuedCount = store.notas.filter((n) => n.status === "issued").length;
5376
+ nota.status = "issued";
5377
+ nota.number = String(issuedCount + 1).padStart(6, "0");
5378
+ nota.series = nota.series ?? "1";
5379
+ nota.issuedAt = now();
5380
+ nota.emissor = "manual";
5381
+ nota.updatedAt = now();
5382
+ return nota;
5383
+ },
5384
+ async cancelNota(id, reason) {
5385
+ const nota = store.notas.find((n) => n.id === id);
5386
+ if (!nota) throw new Error("Nota fiscal not found");
5387
+ nota.status = "cancelled";
5388
+ nota.errorMessage = reason;
5389
+ nota.updatedAt = now();
5390
+ return nota;
5161
5391
  }
5162
5392
  };
5163
5393
  return provider;
@@ -5172,7 +5402,8 @@ var T = {
5172
5402
  costCenters: "plg_financial_cost_centers",
5173
5403
  cashRegisterSessions: "plg_financial_cash_register_sessions",
5174
5404
  paymentMethods: "plg_financial_payment_methods",
5175
- paymentMethodTypes: "plg_financial_payment_method_types"
5405
+ paymentMethodTypes: "plg_financial_payment_method_types",
5406
+ notas: "plg_financial_nfe"
5176
5407
  };
5177
5408
 
5178
5409
  // src/data/supabase.ts
@@ -5483,6 +5714,7 @@ function createSupabaseFinancialProvider() {
5483
5714
  }
5484
5715
  if (query.bankAccountId) qb = qb.eq("bank_account_id", query.bankAccountId);
5485
5716
  if (query.cashSessionId) qb = qb.eq("cash_session_id", query.cashSessionId);
5717
+ if (query.invoiceId) qb = qb.eq("invoice_id", query.invoiceId);
5486
5718
  if (query.dateRange) qb = qb.gte("due_date", query.dateRange.from).lte("due_date", query.dateRange.to);
5487
5719
  const page = query.page ?? 1;
5488
5720
  const pageSize = query.pageSize ?? 50;
@@ -5906,6 +6138,75 @@ function createSupabaseFinancialProvider() {
5906
6138
  if (line?.matched_movement_id) {
5907
6139
  await pub.from(T.movements).update({ reconciled_at: null }).eq("id", line.matched_movement_id);
5908
6140
  }
6141
+ },
6142
+ // --- Notas fiscais (NF-e / NFC-e / NFS-e) ---
6143
+ async getNotas(query) {
6144
+ const { pub } = getClients();
6145
+ let qb = pub.from(T.notas).select("*", { count: "exact" });
6146
+ if (query.status) {
6147
+ const statuses = Array.isArray(query.status) ? query.status : [query.status];
6148
+ qb = qb.in("status", statuses);
6149
+ }
6150
+ if (query.model) qb = qb.eq("model", query.model);
6151
+ if (query.orderId) qb = qb.eq("order_id", query.orderId);
6152
+ if (query.search) qb = qb.or(`number.ilike.%${query.search}%,contact_name.ilike.%${query.search}%`);
6153
+ const page = query.page ?? 1;
6154
+ const pageSize = query.pageSize ?? 50;
6155
+ qb = qb.range((page - 1) * pageSize, page * pageSize - 1).order("created_at", { ascending: false });
6156
+ const { data, count } = await qb;
6157
+ return { data: (data ?? []).map((r) => snakeToCamel(r)), total: count ?? 0 };
6158
+ },
6159
+ async getNotaById(id) {
6160
+ const { pub } = getClients();
6161
+ const { data } = await pub.from(T.notas).select("*").eq("id", id).maybeSingle();
6162
+ return data ? snakeToCamel(data) : null;
6163
+ },
6164
+ async createNota(input) {
6165
+ const { pub } = getClients();
6166
+ const row = {
6167
+ tenant_id: getTenantId(),
6168
+ model: input.model ?? "nfe",
6169
+ status: "draft",
6170
+ series: input.series ?? null,
6171
+ order_id: input.orderId ?? null,
6172
+ contact_id: input.contactId ?? null,
6173
+ contact_name: input.contactName ?? null,
6174
+ total_amount: input.totalAmount,
6175
+ observations: input.observations ?? null
6176
+ };
6177
+ const { data, error } = await pub.from(T.notas).insert(row).select().single();
6178
+ if (error) throw error;
6179
+ return snakeToCamel(data);
6180
+ },
6181
+ async updateNota(id, patch) {
6182
+ const { pub } = getClients();
6183
+ const { data, error } = await pub.from(T.notas).update(camelToSnake(patch)).eq("id", id).select().single();
6184
+ if (error) throw error;
6185
+ return snakeToCamel(data);
6186
+ },
6187
+ // Emission seam: no SEFAZ integration yet, so assign a número/série locally
6188
+ // and mark it issued. An external emissor replaces this body (or overrides
6189
+ // issueNota on a wrapping provider) without any UI change.
6190
+ async issueNota(id) {
6191
+ const { pub } = getClients();
6192
+ const { data: current } = await pub.from(T.notas).select("series").eq("id", id).single();
6193
+ const { count } = await pub.from(T.notas).select("id", { count: "exact", head: true }).eq("status", "issued");
6194
+ const patch = {
6195
+ status: "issued",
6196
+ number: String((count ?? 0) + 1).padStart(6, "0"),
6197
+ series: current?.series ?? "1",
6198
+ issued_at: (/* @__PURE__ */ new Date()).toISOString(),
6199
+ emissor: "manual"
6200
+ };
6201
+ const { data, error } = await pub.from(T.notas).update(patch).eq("id", id).select().single();
6202
+ if (error) throw error;
6203
+ return snakeToCamel(data);
6204
+ },
6205
+ async cancelNota(id, reason) {
6206
+ const { pub } = getClients();
6207
+ const { data, error } = await pub.from(T.notas).update({ status: "cancelled", error_message: reason ?? null }).eq("id", id).select().single();
6208
+ if (error) throw error;
6209
+ return snakeToCamel(data);
5909
6210
  }
5910
6211
  };
5911
6212
  return provider;
@@ -6533,6 +6834,7 @@ var en = {
6533
6834
  "financial.nav.payables": "Accounts Payable",
6534
6835
  "financial.nav.receivables": "Accounts Receivable",
6535
6836
  "financial.nav.reconciliation": "Reconciliation",
6837
+ "financial.nav.notasFiscais": "Fiscal Invoices",
6536
6838
  "financial.nav.recurringExpenses": "Recurring Expenses",
6537
6839
  "financial.nav.rules": "Rules",
6538
6840
  "financial.nav.statements": "Statements",
@@ -7026,6 +7328,7 @@ var ptBR = {
7026
7328
  "financial.nav.payables": "Contas a Pagar",
7027
7329
  "financial.nav.receivables": "Contas a Receber",
7028
7330
  "financial.nav.reconciliation": "Concilia\xE7\xE3o",
7331
+ "financial.nav.notasFiscais": "Notas Fiscais",
7029
7332
  "financial.nav.recurringExpenses": "Despesas Recorrentes",
7030
7333
  "financial.nav.rules": "Regras",
7031
7334
  "financial.nav.statements": "Extratos",
@@ -7398,9 +7701,9 @@ var STATUS_STYLE = {
7398
7701
  function PersonStatementWidget({ person, provider, config }) {
7399
7702
  const t2 = core.useTranslation();
7400
7703
  const currency = config.currency;
7401
- const [invoices, setInvoices] = React17.useState([]);
7402
- const [loading, setLoading] = React17.useState(true);
7403
- React17.useEffect(() => {
7704
+ const [invoices, setInvoices] = React18.useState([]);
7705
+ const [loading, setLoading] = React18.useState(true);
7706
+ React18.useEffect(() => {
7404
7707
  let alive = true;
7405
7708
  if (!person?.id) {
7406
7709
  setLoading(false);
@@ -7420,7 +7723,7 @@ function PersonStatementWidget({ person, provider, config }) {
7420
7723
  };
7421
7724
  }, [person?.id, provider]);
7422
7725
  const fmt = (n) => saas.formatCurrency(n, currency);
7423
- const totals = React17.useMemo(() => {
7726
+ const totals = React18.useMemo(() => {
7424
7727
  const active = invoices.filter((i) => i.status !== "cancelled");
7425
7728
  const billed = active.reduce((s, i) => s + (i.totalAmount ?? 0), 0);
7426
7729
  const paid = active.reduce((s, i) => s + (i.paidAmount ?? 0), 0);
@@ -7430,7 +7733,7 @@ function PersonStatementWidget({ person, provider, config }) {
7430
7733
  const base = inv.direction === "credit" ? "receivables" : "payables";
7431
7734
  window.location.hash = `/financial/${base}/detail/${inv.id}`;
7432
7735
  };
7433
- const columns = React17.useMemo(() => [
7736
+ const columns = React18.useMemo(() => [
7434
7737
  {
7435
7738
  id: "date",
7436
7739
  header: t2("financial.invoice.columnDate"),
@@ -7510,7 +7813,8 @@ var DEFAULT_LABELS = {
7510
7813
  commissionsRules: "Rules",
7511
7814
  cards: "Cards",
7512
7815
  cardsOverview: "Overview",
7513
- cardsReconciliation: "Reconciliation"
7816
+ cardsReconciliation: "Reconciliation",
7817
+ notasFiscais: "Fiscal Invoices"
7514
7818
  };
7515
7819
  var DEFAULT_CURRENCY = { code: "BRL", locale: "pt-BR", symbol: "R$" };
7516
7820
  var FINANCIAL_NAV_FEATURES = {
@@ -7537,7 +7841,9 @@ function resolveConfig(options) {
7537
7841
  commissions: options?.modules?.commissions !== false,
7538
7842
  cards: options?.modules?.cards !== false,
7539
7843
  // Opt-in: only shown when an app explicitly enables reconciliation (bank connector present).
7540
- reconciliation: options?.modules?.reconciliation === true
7844
+ reconciliation: options?.modules?.reconciliation === true,
7845
+ // Opt-in: only shown when an app explicitly enables fiscal-invoice tracking.
7846
+ notasFiscais: options?.modules?.notasFiscais === true
7541
7847
  },
7542
7848
  // Opt-in: only render the plugin's own quick-add buttons/FAB when the host asks.
7543
7849
  quickAdd: options?.quickAdd === true,
@@ -7563,9 +7869,9 @@ function createFinancialPlugin(options) {
7563
7869
  const store = createFinancialStore(provider);
7564
7870
  const dashboardWidgets = createFinancialDashboardWidgets({ config, provider, store });
7565
7871
  const registries = [...financialRegistries, ...options?.settingsRegistries ?? []];
7566
- const PersonStatementBound = (props) => React17__namespace.default.createElement(PersonStatementWidget, { person: props.item, provider, config });
7872
+ const PersonStatementBound = (props) => React18__namespace.default.createElement(PersonStatementWidget, { person: props.item, provider, config });
7567
7873
  PersonStatementBound.displayName = "FinancialPersonStatement";
7568
- const PageComponent = () => React17__namespace.default.createElement(FinancialPage, { config, provider, store, registries });
7874
+ const PageComponent = () => React18__namespace.default.createElement(FinancialPage, { config, provider, store, registries });
7569
7875
  return {
7570
7876
  id: "financial",
7571
7877
  name: config.labels.pageTitle,
@@ -7769,10 +8075,10 @@ function createFinancialPlugin(options) {
7769
8075
  label: "Financial",
7770
8076
  icon: "DollarSign",
7771
8077
  component: (() => {
7772
- const FinancialSettingsTab = () => React17__namespace.default.createElement(saas.PluginSettingsPanel, {
8078
+ const FinancialSettingsTab = () => React18__namespace.default.createElement(saas.PluginSettingsPanel, {
7773
8079
  title: "Financial Settings",
7774
8080
  subtitle: "Payment methods, accounts, and configurations",
7775
- generalSettings: React17__namespace.default.createElement(FinancialGeneralSettings),
8081
+ generalSettings: React18__namespace.default.createElement(FinancialGeneralSettings),
7776
8082
  registries,
7777
8083
  hostPluginId: "financial",
7778
8084
  routeBase: "/settings/financial"