@layerfi/components 0.1.35 → 0.1.37

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.js CHANGED
@@ -33,10 +33,12 @@ __export(src_exports, {
33
33
  AccountingOverview: () => AccountingOverview,
34
34
  BalanceSheet: () => BalanceSheet,
35
35
  BankTransactions: () => BankTransactions,
36
+ BankTransactionsProvider: () => BankTransactionsProvider,
36
37
  BankTransactionsWithLinkedAccounts: () => BankTransactionsWithLinkedAccounts,
37
38
  BookkeepingOverview: () => BookkeepingOverview,
38
39
  BookkeepingUpsellBar: () => BookkeepingUpsellBar,
39
40
  ChartOfAccounts: () => ChartOfAccounts,
41
+ DisplayState: () => DisplayState,
40
42
  GeneralLedgerView: () => GeneralLedgerView,
41
43
  Journal: () => Journal,
42
44
  LayerProvider: () => LayerProvider,
@@ -201,9 +203,11 @@ var getBalanceSheet = get(
201
203
  var getBankTransactions = get(
202
204
  ({
203
205
  businessId,
206
+ cursor,
207
+ categorized,
204
208
  sortBy = "date",
205
209
  sortOrder = "DESC"
206
- }) => `/v1/businesses/${businessId}/bank-transactions?sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
210
+ }) => `/v1/businesses/${businessId}/bank-transactions?${cursor ? `cursor=${cursor}&` : ""}${categorized !== void 0 && categorized !== "" ? `categorized=${categorized}&` : ""}sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
207
211
  );
208
212
  var categorizeBankTransaction = put(
209
213
  ({ businessId, bankTransactionId }) => `/v1/businesses/${businessId}/bank-transactions/${bankTransactionId}/categorize`
@@ -667,6 +671,25 @@ var import_react11 = __toESM(require("react"));
667
671
 
668
672
  // src/contexts/BankTransactionsContext/BankTransactionsContext.tsx
669
673
  var import_react9 = require("react");
674
+
675
+ // src/types/bank_transactions.ts
676
+ var Direction = /* @__PURE__ */ ((Direction3) => {
677
+ Direction3["CREDIT"] = "CREDIT";
678
+ Direction3["DEBIT"] = "DEBIT";
679
+ return Direction3;
680
+ })(Direction || {});
681
+ var DisplayState = /* @__PURE__ */ ((DisplayState2) => {
682
+ DisplayState2["review"] = "review";
683
+ DisplayState2["categorized"] = "categorized";
684
+ return DisplayState2;
685
+ })(DisplayState || {});
686
+
687
+ // src/types/categories.ts
688
+ function hasSuggestions(categorization) {
689
+ return categorization.suggestions !== void 0 && categorization.suggestions.length > 0;
690
+ }
691
+
692
+ // src/contexts/BankTransactionsContext/BankTransactionsContext.tsx
670
693
  var BankTransactionsContext = (0, import_react9.createContext)({
671
694
  data: void 0,
672
695
  isLoading: false,
@@ -684,26 +707,18 @@ var BankTransactionsContext = (0, import_react9.createContext)({
684
707
  pagination: void 0
685
708
  },
686
709
  updateOneLocal: () => void 0,
710
+ removeAfterCategorize: () => void 0,
687
711
  activate: () => void 0,
688
- display: "review" /* review */
712
+ display: "review" /* review */,
713
+ fetchMore: () => {
714
+ },
715
+ hasMore: false
689
716
  });
690
717
  var useBankTransactionsContext = () => (0, import_react9.useContext)(BankTransactionsContext);
691
718
 
692
719
  // src/hooks/useBankTransactions/useBankTransactions.tsx
693
720
  var import_react10 = require("react");
694
721
 
695
- // src/types/bank_transactions.ts
696
- var Direction = /* @__PURE__ */ ((Direction3) => {
697
- Direction3["CREDIT"] = "CREDIT";
698
- Direction3["DEBIT"] = "DEBIT";
699
- return Direction3;
700
- })(Direction || {});
701
-
702
- // src/types/categories.ts
703
- function hasSuggestions(categorization) {
704
- return categorization.suggestions !== void 0 && categorization.suggestions.length > 0;
705
- }
706
-
707
722
  // src/components/BankTransactions/constants.ts
708
723
  var CategorizedCategories = [
709
724
  "CATEGORIZED" /* CATEGORIZED */,
@@ -724,7 +739,7 @@ var filterVisibility = (scope, bankTransaction) => {
724
739
  const inReview = ReviewCategories.includes(
725
740
  bankTransaction.categorization_status
726
741
  );
727
- return scope === "TO_REVIEW" /* TO_REVIEW */ && inReview || scope === "CATEGORIZED" /* CATEGORIZED */ && categorized;
742
+ return scope === "review" /* review */ && inReview || scope === "categorized" /* categorized */ && categorized;
728
743
  };
729
744
  var isCategorized = (bankTransaction) => CategorizedCategories.includes(bankTransaction.categorization_status);
730
745
 
@@ -773,7 +788,7 @@ var applyCategorizationStatusFilter = (data, filter) => {
773
788
  return data;
774
789
  }
775
790
  return data?.filter(
776
- (tx) => filterVisibility(filter, tx) || filter === "TO_REVIEW" /* TO_REVIEW */ && tx.recently_categorized || filter === "CATEGORIZED" /* CATEGORIZED */ && tx.recently_categorized
791
+ (tx) => filterVisibility(filter, tx) || filter === "review" /* review */ && tx.recently_categorized || filter === "categorized" /* categorized */ && tx.recently_categorized
777
792
  );
778
793
  };
779
794
  var appplyDateRangeFilter = (data, filter) => {
@@ -792,8 +807,8 @@ var appplyDateRangeFilter = (data, filter) => {
792
807
  };
793
808
 
794
809
  // src/hooks/useBankTransactions/useBankTransactions.tsx
795
- var import_swr = __toESM(require("swr"));
796
- var useBankTransactions = () => {
810
+ var import_infinite = __toESM(require("swr/infinite"));
811
+ var useBankTransactions = (params) => {
797
812
  const {
798
813
  auth,
799
814
  businessId,
@@ -804,36 +819,82 @@ var useBankTransactions = () => {
804
819
  syncTimestamps,
805
820
  hasBeenTouched
806
821
  } = useLayerContext();
807
- const [loadingStatus, setLoadingStatus] = (0, import_react10.useState)("initial");
808
- const [filters, setTheFilters] = (0, import_react10.useState)();
809
- const [active, setActive] = (0, import_react10.useState)(false);
822
+ const { scope = void 0 } = params ?? {};
823
+ const [filters, setTheFilters] = (0, import_react10.useState)(
824
+ scope ? { categorizationStatus: scope } : void 0
825
+ );
810
826
  const display = (0, import_react10.useMemo)(() => {
811
- if (filters?.categorizationStatus === "TO_REVIEW" /* TO_REVIEW */) {
827
+ if (filters?.categorizationStatus === "review" /* review */) {
812
828
  return "review" /* review */;
813
829
  }
814
830
  return "categorized" /* categorized */;
815
831
  }, [filters?.categorizationStatus]);
816
- const queryKey = (0, import_react10.useMemo)(() => {
817
- if (!active) {
818
- return false;
819
- }
820
- return businessId && auth?.access_token && `bank-transactions-${businessId}`;
821
- }, [businessId, auth?.access_token, active]);
832
+ const [active, setActive] = (0, import_react10.useState)(false);
833
+ const [loadingStatus, setLoadingStatus] = (0, import_react10.useState)("initial");
834
+ const getKey = (_index, prevData) => {
835
+ if (!auth?.access_token || !active) {
836
+ return [false, void 0];
837
+ }
838
+ if (!prevData?.meta?.pagination?.cursor) {
839
+ return [
840
+ businessId && auth?.access_token && `bank-transactions${filters?.categorizationStatus ? `-scope-${filters?.categorizationStatus}` : ""}-${businessId}`,
841
+ void 0
842
+ ];
843
+ }
844
+ return [
845
+ businessId && auth?.access_token && `bank-transactions${filters?.categorizationStatus ? `-scope-${filters?.categorizationStatus}` : ""}-${businessId}-${prevData.meta.pagination.cursor}`,
846
+ prevData.meta.pagination.cursor
847
+ ];
848
+ };
822
849
  const {
823
- data: responseData,
850
+ data: rawResponseData,
824
851
  isLoading,
825
852
  isValidating,
826
853
  error: responseError,
827
- mutate
828
- } = (0, import_swr.default)(
829
- queryKey,
830
- Layer.getBankTransactions(apiUrl, auth?.access_token, {
831
- params: { businessId }
832
- })
854
+ mutate,
855
+ size,
856
+ setSize
857
+ } = (0, import_infinite.default)(
858
+ getKey,
859
+ async ([query, nextCursor]) => {
860
+ if (auth?.access_token) {
861
+ return Layer.getBankTransactions(apiUrl, auth?.access_token, {
862
+ params: {
863
+ businessId,
864
+ cursor: nextCursor,
865
+ categorized: filters?.categorizationStatus ? filters?.categorizationStatus === "categorized" /* categorized */ ? "true" : "false" : ""
866
+ }
867
+ }).call(false);
868
+ }
869
+ return {};
870
+ },
871
+ {
872
+ initialSize: 1,
873
+ revalidateFirstPage: false
874
+ }
833
875
  );
876
+ const data = (0, import_react10.useMemo)(() => {
877
+ if (rawResponseData && rawResponseData.length > 0) {
878
+ return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
879
+ }
880
+ return void 0;
881
+ }, [rawResponseData]);
882
+ const lastMetadata = (0, import_react10.useMemo)(() => {
883
+ if (rawResponseData && rawResponseData.length > 0) {
884
+ return rawResponseData[rawResponseData.length - 1].meta;
885
+ }
886
+ return void 0;
887
+ }, [rawResponseData]);
888
+ const hasMore = (0, import_react10.useMemo)(() => {
889
+ if (rawResponseData && rawResponseData.length > 0) {
890
+ const lastElement = rawResponseData[rawResponseData.length - 1];
891
+ return Boolean(lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more);
892
+ }
893
+ return false;
894
+ }, [rawResponseData]);
834
895
  const accountsList = (0, import_react10.useMemo)(
835
- () => collectAccounts(responseData?.data),
836
- [responseData]
896
+ () => data ? collectAccounts(data) : [],
897
+ [data]
837
898
  );
838
899
  (0, import_react10.useEffect)(() => {
839
900
  if (isLoading && loadingStatus === "initial") {
@@ -854,13 +915,11 @@ var useBankTransactions = () => {
854
915
  ...value ?? {}
855
916
  });
856
917
  };
857
- const {
858
- data = void 0,
859
- meta: metadata = {},
860
- error = void 0
861
- } = responseData || {};
862
918
  const filteredData = (0, import_react10.useMemo)(() => {
863
919
  let filtered = data;
920
+ if (!filtered) {
921
+ return;
922
+ }
864
923
  if (filters?.amount?.min || filters?.amount?.max) {
865
924
  filtered = applyAmountFilter(filtered, filters.amount);
866
925
  }
@@ -880,7 +939,7 @@ var useBankTransactions = () => {
880
939
  filtered = appplyDateRangeFilter(filtered, filters?.dateRange);
881
940
  }
882
941
  return filtered;
883
- }, [filters, responseData]);
942
+ }, [filters, data]);
884
943
  const categorize = (id, newCategory, notify) => {
885
944
  const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
886
945
  if (foundBT) {
@@ -953,14 +1012,31 @@ var useBankTransactions = () => {
953
1012
  }).finally(() => touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */));
954
1013
  };
955
1014
  const updateOneLocal = (newBankTransaction) => {
956
- const updatedData = data?.map(
957
- (bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
958
- );
959
- mutate({ data: updatedData }, { revalidate: false });
1015
+ const updatedData = rawResponseData?.map((page) => {
1016
+ return {
1017
+ ...page,
1018
+ data: page.data?.map((bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt)
1019
+ };
1020
+ });
1021
+ mutate(updatedData, { revalidate: false });
1022
+ };
1023
+ const removeAfterCategorize = (bankTransaction) => {
1024
+ const updatedData = rawResponseData?.map((page) => {
1025
+ return {
1026
+ ...page,
1027
+ data: page.data?.filter((bt) => bt.id !== bankTransaction.id)
1028
+ };
1029
+ });
1030
+ mutate(updatedData, { revalidate: false });
960
1031
  };
961
1032
  const refetch = () => {
962
1033
  mutate();
963
1034
  };
1035
+ const fetchMore = () => {
1036
+ if (hasMore) {
1037
+ setSize(size + 1);
1038
+ }
1039
+ };
964
1040
  (0, import_react10.useEffect)(() => {
965
1041
  if (isLoading || isValidating) {
966
1042
  read("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
@@ -973,20 +1049,23 @@ var useBankTransactions = () => {
973
1049
  }, [syncTimestamps]);
974
1050
  return {
975
1051
  data: filteredData,
976
- metadata,
1052
+ metadata: lastMetadata,
977
1053
  loadingStatus,
978
1054
  isLoading,
979
1055
  isValidating,
980
1056
  refetch,
981
- error: responseError || error,
1057
+ error: responseError,
982
1058
  categorize,
983
1059
  match,
984
1060
  updateOneLocal,
1061
+ removeAfterCategorize,
985
1062
  filters,
986
1063
  setFilters,
987
1064
  accountsList,
988
1065
  activate,
989
- display
1066
+ display,
1067
+ fetchMore,
1068
+ hasMore
990
1069
  };
991
1070
  };
992
1071
 
@@ -1239,7 +1318,7 @@ var hslToHex = (hsl) => {
1239
1318
 
1240
1319
  // src/providers/LayerProvider/LayerProvider.tsx
1241
1320
  var import_date_fns2 = require("date-fns");
1242
- var import_swr2 = __toESM(require("swr"));
1321
+ var import_swr = __toESM(require("swr"));
1243
1322
  var reducer = (state, action) => {
1244
1323
  switch (action.type) {
1245
1324
  case "LayerContext.setAuth" /* setAuth */:
@@ -1279,10 +1358,20 @@ var LayerEnvironment = {
1279
1358
  scope: "https://api.layerfi.com/production",
1280
1359
  apiUrl: "https://api.layerfi.com"
1281
1360
  },
1361
+ sandbox: {
1362
+ url: "https://auth.layerfi.com/oauth2/token",
1363
+ scope: "https://sandbox.layerfi.com/sandbox",
1364
+ apiUrl: "https://sandbox.layerfi.com"
1365
+ },
1282
1366
  staging: {
1283
1367
  url: "https://auth.layerfi.com/oauth2/token",
1284
1368
  scope: "https://sandbox.layerfi.com/sandbox",
1285
1369
  apiUrl: "https://sandbox.layerfi.com"
1370
+ },
1371
+ internalStaging: {
1372
+ url: "https://auth.layerfi.com/oauth2/token",
1373
+ scope: "https://sandbox.layerfi.com/sandbox",
1374
+ apiUrl: "https://staging.layerfi.com"
1286
1375
  }
1287
1376
  };
1288
1377
  var LayerProvider = ({
@@ -1324,7 +1413,7 @@ var LayerProvider = ({
1324
1413
  toasts: []
1325
1414
  });
1326
1415
  const { touch, syncTimestamps, read, readTimestamps, hasBeenTouched } = useDataSync();
1327
- const { data: auth } = appId !== void 0 && appSecret !== void 0 ? (0, import_swr2.default)(
1416
+ const { data: auth } = appId !== void 0 && appSecret !== void 0 ? (0, import_swr.default)(
1328
1417
  businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && (0, import_date_fns2.isBefore)(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
1329
1418
  Layer.authenticate({
1330
1419
  appId,
@@ -1359,7 +1448,7 @@ var LayerProvider = ({
1359
1448
  });
1360
1449
  }
1361
1450
  }, [businessAccessToken, auth?.access_token]);
1362
- (0, import_swr2.default)(
1451
+ (0, import_swr.default)(
1363
1452
  businessId && state.auth?.access_token && `categories-${businessId}`,
1364
1453
  Layer.getCategories(apiUrl, state.auth?.access_token, {
1365
1454
  params: { businessId }
@@ -1376,7 +1465,7 @@ var LayerProvider = ({
1376
1465
  }
1377
1466
  }
1378
1467
  );
1379
- (0, import_swr2.default)(
1468
+ (0, import_swr.default)(
1380
1469
  businessId && state?.auth?.access_token && `business-${businessId}`,
1381
1470
  Layer.getBusiness(apiUrl, state?.auth?.access_token, {
1382
1471
  params: { businessId }
@@ -1465,7 +1554,7 @@ var LayerProvider = ({
1465
1554
  payload: { onboardingStep: value }
1466
1555
  });
1467
1556
  const drawerContextData = useDrawer();
1468
- return /* @__PURE__ */ import_react12.default.createElement(import_swr2.SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ import_react12.default.createElement(
1557
+ return /* @__PURE__ */ import_react12.default.createElement(import_swr.SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ import_react12.default.createElement(
1469
1558
  LayerContext.Provider,
1470
1559
  {
1471
1560
  value: {
@@ -1544,7 +1633,7 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1544
1633
  external_account_source: "PLAID",
1545
1634
  balance: 435121,
1546
1635
  at: "2024-04-03T13:00:00Z",
1547
- created_at: "2024-04-06T16:44:35.715458Z"
1636
+ created_at: "2024-04-06T22:47:59.715458Z"
1548
1637
  },
1549
1638
  current_ledger_balance: 373717,
1550
1639
  institution: {
@@ -1554,7 +1643,8 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1554
1643
  connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
1555
1644
  connection_external_id: "11111",
1556
1645
  connection_needs_repair_as_of: null,
1557
- requires_user_confirmation_as_of: null
1646
+ requires_user_confirmation_as_of: null,
1647
+ is_syncing: true
1558
1648
  },
1559
1649
  {
1560
1650
  id: "f98ec50a-c370-484d-a35b-d00207436075",
@@ -1577,7 +1667,8 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1577
1667
  connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
1578
1668
  connection_external_id: "11111",
1579
1669
  connection_needs_repair_as_of: null,
1580
- requires_user_confirmation_as_of: null
1670
+ requires_user_confirmation_as_of: null,
1671
+ is_syncing: false
1581
1672
  },
1582
1673
  {
1583
1674
  id: "843f1748-fdaa-422d-a73d-2489a40c8dc7",
@@ -1600,7 +1691,8 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1600
1691
  connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
1601
1692
  connection_external_id: "11111",
1602
1693
  connection_needs_repair_as_of: "2024-03-06T16:44:35.715458Z",
1603
- requires_user_confirmation_as_of: null
1694
+ requires_user_confirmation_as_of: null,
1695
+ is_syncing: false
1604
1696
  },
1605
1697
  {
1606
1698
  id: "8f430e29-e339-4d71-a08a-fce469c7a7c1",
@@ -1623,12 +1715,13 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1623
1715
  connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
1624
1716
  connection_external_id: "11111",
1625
1717
  connection_needs_repair_as_of: null,
1626
- requires_user_confirmation_as_of: "2024-03-06T16:44:35.715458Z"
1718
+ requires_user_confirmation_as_of: "2024-03-06T16:44:35.715458Z",
1719
+ is_syncing: false
1627
1720
  }
1628
1721
  ];
1629
1722
 
1630
1723
  // src/hooks/useLinkedAccounts/useLinkedAccounts.ts
1631
- var import_swr3 = __toESM(require("swr"));
1724
+ var import_swr2 = __toESM(require("swr"));
1632
1725
  var DEBUG = true;
1633
1726
  var USE_MOCK_RESPONSE_DATA = false;
1634
1727
  var useLinkedAccounts = () => {
@@ -1652,7 +1745,7 @@ var useLinkedAccounts = () => {
1652
1745
  isValidating,
1653
1746
  error: responseError,
1654
1747
  mutate
1655
- } = (0, import_swr3.default)(
1748
+ } = (0, import_swr2.default)(
1656
1749
  businessId && auth?.access_token && `linked-accounts-${businessId}`,
1657
1750
  Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
1658
1751
  params: { businessId }
@@ -2173,15 +2266,13 @@ var countTransactionsToReview = ({
2173
2266
  };
2174
2267
  return transactions.filter((tx) => {
2175
2268
  try {
2176
- return filterVisibility("TO_REVIEW" /* TO_REVIEW */, tx) && (0, import_date_fns3.isWithinInterval)((0, import_date_fns3.parseISO)(tx.date), dateRangeInterval);
2269
+ return filterVisibility("review" /* review */, tx) && (0, import_date_fns3.isWithinInterval)((0, import_date_fns3.parseISO)(tx.date), dateRangeInterval);
2177
2270
  } catch (_err) {
2178
2271
  return false;
2179
2272
  }
2180
2273
  }).length;
2181
2274
  }
2182
- return transactions.filter(
2183
- (tx) => filterVisibility("TO_REVIEW" /* TO_REVIEW */, tx)
2184
- ).length;
2275
+ return transactions.filter((tx) => filterVisibility("review" /* review */, tx)).length;
2185
2276
  }
2186
2277
  return 0;
2187
2278
  };
@@ -3241,7 +3332,9 @@ var ConnectAccount = ({
3241
3332
  onTransactionsToReviewClick
3242
3333
  }) => {
3243
3334
  const { addConnection } = (0, import_react38.useContext)(LinkedAccountsContext);
3244
- const { data, isLoading } = useBankTransactions();
3335
+ const { data, isLoading } = useBankTransactions({
3336
+ scope: "review" /* review */
3337
+ });
3245
3338
  const transactionsToReview = (0, import_react38.useMemo)(
3246
3339
  () => countTransactionsToReview({ transactions: data }),
3247
3340
  [data, isLoading]
@@ -3857,15 +3950,21 @@ var LinkedAccountThumb = ({
3857
3950
  }) => {
3858
3951
  const linkedAccountThumbClassName = (0, import_classnames19.default)(
3859
3952
  "Layer__linked-account-thumb",
3860
- asWidget && "--as-widget"
3953
+ asWidget && "--as-widget",
3954
+ account.is_syncing && "--is-syncing",
3955
+ account.is_syncing && "skeleton-loader"
3956
+ );
3957
+ const linkedAccountInfoClassName = (0, import_classnames19.default)(
3958
+ "topbar",
3959
+ account.is_syncing && "--is-syncing"
3861
3960
  );
3862
- let balance;
3961
+ let bankBalance;
3863
3962
  if (pillConfig) {
3864
- balance = /* @__PURE__ */ import_react46.default.createElement(LinkedAccountPill, { text: pillConfig.text, config: pillConfig.config });
3963
+ bankBalance = /* @__PURE__ */ import_react46.default.createElement(LinkedAccountPill, { text: pillConfig.text, config: pillConfig.config });
3865
3964
  } else {
3866
- balance = /* @__PURE__ */ import_react46.default.createElement(Text, { as: "span", className: "account-balance" }, "$", centsToDollars(account.latest_balance_timestamp?.balance));
3965
+ bankBalance = /* @__PURE__ */ import_react46.default.createElement(Text, { as: "span", className: "account-balance" }, `${centsToDollars(account.latest_balance_timestamp?.balance)}`);
3867
3966
  }
3868
- return /* @__PURE__ */ import_react46.default.createElement("div", { className: linkedAccountThumbClassName }, /* @__PURE__ */ import_react46.default.createElement("div", { className: "topbar" }, /* @__PURE__ */ import_react46.default.createElement("div", { className: "topbar-details" }, /* @__PURE__ */ import_react46.default.createElement(Text, { as: "span", className: "account-name" }, account.external_account_name), !asWidget && account.mask && /* @__PURE__ */ import_react46.default.createElement(AccountNumber, { accountNumber: account.mask }), /* @__PURE__ */ import_react46.default.createElement(
3967
+ return /* @__PURE__ */ import_react46.default.createElement("div", { className: linkedAccountThumbClassName }, /* @__PURE__ */ import_react46.default.createElement("div", { className: linkedAccountInfoClassName }, /* @__PURE__ */ import_react46.default.createElement("div", { className: "topbar-details" }, /* @__PURE__ */ import_react46.default.createElement(Text, { as: "div", className: "account-name" }, account.external_account_name), !asWidget && account.mask && /* @__PURE__ */ import_react46.default.createElement(AccountNumber, { accountNumber: account.mask }), /* @__PURE__ */ import_react46.default.createElement(
3869
3968
  Text,
3870
3969
  {
3871
3970
  as: "span",
@@ -3881,7 +3980,7 @@ var LinkedAccountThumb = ({
3881
3980
  src: `data:image/png;base64,${account.institution.logo}`,
3882
3981
  alt: account.institution?.name
3883
3982
  }
3884
- ) : /* @__PURE__ */ import_react46.default.createElement(InstitutionIcon_default, null))), !asWidget && /* @__PURE__ */ import_react46.default.createElement("div", { className: "middlebar" }, /* @__PURE__ */ import_react46.default.createElement(
3983
+ ) : /* @__PURE__ */ import_react46.default.createElement(InstitutionIcon_default, null))), account.is_syncing ? /* @__PURE__ */ import_react46.default.createElement("div", { className: "loadingbar" }, /* @__PURE__ */ import_react46.default.createElement("div", { className: "loading-text Layer__text--sm" }, /* @__PURE__ */ import_react46.default.createElement("div", null, "Syncing account data"), /* @__PURE__ */ import_react46.default.createElement("div", { className: "syncing-data-description" }, "This may take up to 5 minutes")), /* @__PURE__ */ import_react46.default.createElement("div", { className: "loading-wrapper" }, /* @__PURE__ */ import_react46.default.createElement(Loader_default, { size: 11, className: "Layer__anim--rotating" }))) : /* @__PURE__ */ import_react46.default.createElement(import_react46.default.Fragment, null, !asWidget && /* @__PURE__ */ import_react46.default.createElement("div", { className: "middlebar" }, /* @__PURE__ */ import_react46.default.createElement(
3885
3984
  Text,
3886
3985
  {
3887
3986
  as: "span",
@@ -3889,7 +3988,7 @@ var LinkedAccountThumb = ({
3889
3988
  size: "sm"
3890
3989
  },
3891
3990
  "Bank balance"
3892
- ), balance), showLedgerBalance && /* @__PURE__ */ import_react46.default.createElement("div", { className: "bottombar" }, asWidget && account.mask ? /* @__PURE__ */ import_react46.default.createElement(AccountNumber, { accountNumber: account.mask }) : /* @__PURE__ */ import_react46.default.createElement(
3991
+ ), bankBalance), showLedgerBalance && /* @__PURE__ */ import_react46.default.createElement("div", { className: "bottombar" }, asWidget && account.mask ? /* @__PURE__ */ import_react46.default.createElement(AccountNumber, { accountNumber: account.mask }) : /* @__PURE__ */ import_react46.default.createElement(
3893
3992
  Text,
3894
3993
  {
3895
3994
  as: "span",
@@ -3897,7 +3996,7 @@ var LinkedAccountThumb = ({
3897
3996
  size: "sm"
3898
3997
  },
3899
3998
  "Ledger balance"
3900
- ), /* @__PURE__ */ import_react46.default.createElement(Text, { as: "span", className: "account-balance" }, "$", centsToDollars(account.current_ledger_balance))));
3999
+ ), /* @__PURE__ */ import_react46.default.createElement(Text, { as: "span", className: "account-balance" }, `${centsToDollars(account.current_ledger_balance)}`))));
3901
4000
  };
3902
4001
 
3903
4002
  // src/components/LinkedAccounts/LinkedAccountsContent.tsx
@@ -5591,9 +5690,20 @@ var ExpandedBankTransactionRow = (0, import_react65.forwardRef)(
5591
5690
  });
5592
5691
  setSplitFormError(void 0);
5593
5692
  };
5693
+ const sanitizeNumberInput = (input) => {
5694
+ let sanitized = input.replace(/[^0-9.]/g, "");
5695
+ let parts = sanitized.split(".");
5696
+ if (parts.length > 2) {
5697
+ sanitized = parts[0] + "." + parts.slice(1).join("");
5698
+ }
5699
+ if (parts.length === 2) {
5700
+ sanitized = parts[0] + "." + parts[1].slice(0, 2);
5701
+ }
5702
+ return sanitized;
5703
+ };
5594
5704
  const updateAmounts = (rowNumber) => (event) => {
5595
- const newAmount = dollarsToCents(event.target.value) || 0;
5596
- const newDisplaying = event.target.value;
5705
+ const newDisplaying = sanitizeNumberInput(event.target.value);
5706
+ const newAmount = Number(newDisplaying);
5597
5707
  const splitTotal = rowState.splits.reduce((sum, split, index) => {
5598
5708
  const amount = index === 0 ? 0 : index === rowNumber ? newAmount : split.amount;
5599
5709
  return sum + amount;
@@ -6030,7 +6140,6 @@ var BankTransactionRow = ({
6030
6140
  }) => {
6031
6141
  const expandedRowRef = (0, import_react67.useRef)(null);
6032
6142
  const [showRetry, setShowRetry] = (0, import_react67.useState)(false);
6033
- const [removed, setRemoved] = (0, import_react67.useState)(false);
6034
6143
  const {
6035
6144
  filters,
6036
6145
  categorize: categorizeBankTransaction2,
@@ -6071,6 +6180,13 @@ var BankTransactionRow = ({
6071
6180
  setShowRetry(true);
6072
6181
  }
6073
6182
  }, [bankTransaction.error]);
6183
+ (0, import_react67.useEffect)(() => {
6184
+ if (editable && bankTransaction.recently_categorized) {
6185
+ setTimeout(() => {
6186
+ removeTransaction(bankTransaction);
6187
+ }, 300);
6188
+ }
6189
+ }, [bankTransaction.recently_categorized]);
6074
6190
  const save = async () => {
6075
6191
  if (open && expandedRowRef?.current) {
6076
6192
  expandedRowRef?.current?.save();
@@ -6093,9 +6209,6 @@ var BankTransactionRow = ({
6093
6209
  });
6094
6210
  setOpen(false);
6095
6211
  };
6096
- if (removed) {
6097
- return null;
6098
- }
6099
6212
  const categorized = isCategorized(bankTransaction);
6100
6213
  const className = "Layer__bank-transaction-row";
6101
6214
  const openClassName = open ? `${className}--expanded` : "";
@@ -6106,178 +6219,160 @@ var BankTransactionRow = ({
6106
6219
  initialLoad ? "initial-load" : "",
6107
6220
  showComponent ? "show" : ""
6108
6221
  );
6109
- return /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement(
6110
- "tr",
6222
+ return /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement("tr", { className: rowClassName }, /* @__PURE__ */ import_react67.default.createElement(
6223
+ "td",
6111
6224
  {
6112
- className: rowClassName,
6113
- onTransitionEnd: ({ propertyName }) => {
6114
- if (propertyName === "top") {
6115
- if (editable) {
6116
- setRemoved(true);
6117
- removeTransaction(bankTransaction.id);
6118
- }
6225
+ className: "Layer__table-cell Layer__bank-transaction-table__date-col",
6226
+ ...openRow
6227
+ },
6228
+ /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, (0, import_date_fns8.format)((0, import_date_fns8.parseISO)(bankTransaction.date), dateFormat))
6229
+ ), /* @__PURE__ */ import_react67.default.createElement(
6230
+ "td",
6231
+ {
6232
+ className: "Layer__table-cell Layer__bank-transactions__tx-col",
6233
+ ...openRow
6234
+ },
6235
+ /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react67.default.createElement(
6236
+ Text,
6237
+ {
6238
+ as: "span",
6239
+ className: "Layer__bank-transactions__tx-text",
6240
+ withTooltip: "whenTruncated" /* whenTruncated */,
6241
+ tooltipOptions: {
6242
+ contentClassName: "Layer__bank-transactions__tx-tooltip"
6119
6243
  }
6120
- }
6244
+ },
6245
+ bankTransaction.counterparty_name ?? bankTransaction.description
6246
+ ))
6247
+ ), /* @__PURE__ */ import_react67.default.createElement(
6248
+ "td",
6249
+ {
6250
+ className: "Layer__table-cell Layer__bank-transactions__account-col",
6251
+ ...openRow
6121
6252
  },
6122
- /* @__PURE__ */ import_react67.default.createElement(
6123
- "td",
6253
+ /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react67.default.createElement(
6254
+ Text,
6124
6255
  {
6125
- className: "Layer__table-cell Layer__bank-transaction-table__date-col",
6126
- ...openRow
6256
+ as: "span",
6257
+ className: "Layer__bank-transactions__account-text",
6258
+ withTooltip: "whenTruncated" /* whenTruncated */
6127
6259
  },
6128
- /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, (0, import_date_fns8.format)((0, import_date_fns8.parseISO)(bankTransaction.date), dateFormat))
6129
- ),
6260
+ bankTransaction.account_name ?? ""
6261
+ ))
6262
+ ), /* @__PURE__ */ import_react67.default.createElement(
6263
+ "td",
6264
+ {
6265
+ className: `Layer__table-cell Layer__table-cell__amount-col Layer__bank-transactions__amount-col Layer__table-cell--amount ${className}__table-cell--amount-${isCredit(bankTransaction) ? "credit" : "debit"}`,
6266
+ ...openRow
6267
+ },
6268
+ /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, isCredit(bankTransaction) ? "+$" : " $", centsToDollars(bankTransaction.amount))
6269
+ ), /* @__PURE__ */ import_react67.default.createElement(
6270
+ "td",
6271
+ {
6272
+ className: (0, import_classnames33.default)(
6273
+ "Layer__table-cell",
6274
+ "Layer__table-cell__category-col",
6275
+ `${className}__actions-cell`,
6276
+ `${className}__actions-cell--${open ? "open" : "close"}`
6277
+ )
6278
+ },
6130
6279
  /* @__PURE__ */ import_react67.default.createElement(
6131
- "td",
6280
+ "span",
6132
6281
  {
6133
- className: "Layer__table-cell Layer__bank-transactions__tx-col",
6134
- ...openRow
6282
+ className: `${className}__actions-container Layer__table-cell-content`
6135
6283
  },
6136
- /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react67.default.createElement(
6137
- Text,
6284
+ !categorized && !open ? /* @__PURE__ */ import_react67.default.createElement(
6285
+ CategorySelect,
6138
6286
  {
6139
- as: "span",
6140
- className: "Layer__bank-transactions__tx-text",
6141
- withTooltip: "whenTruncated" /* whenTruncated */,
6142
- tooltipOptions: {
6143
- contentClassName: "Layer__bank-transactions__tx-tooltip"
6144
- }
6287
+ bankTransaction,
6288
+ name: `category-${bankTransaction.id}`,
6289
+ value: selectedCategory,
6290
+ onChange: (category) => {
6291
+ setSelectedCategory(category);
6292
+ setShowRetry(false);
6293
+ },
6294
+ disabled: bankTransaction.processing
6295
+ }
6296
+ ) : null,
6297
+ categorized && !open ? /* @__PURE__ */ import_react67.default.createElement(Text, { as: "span", className: `${className}__category-text` }, bankTransaction.categorization_status === "SPLIT" /* SPLIT */ && /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement(
6298
+ Badge,
6299
+ {
6300
+ icon: /* @__PURE__ */ import_react67.default.createElement(Scissors_default, { size: 11 }),
6301
+ tooltip: /* @__PURE__ */ import_react67.default.createElement(
6302
+ SplitTooltipDetails,
6303
+ {
6304
+ classNamePrefix: className,
6305
+ category: bankTransaction.category
6306
+ }
6307
+ )
6145
6308
  },
6146
- bankTransaction.counterparty_name ?? bankTransaction.description
6147
- ))
6148
- ),
6149
- /* @__PURE__ */ import_react67.default.createElement(
6150
- "td",
6151
- {
6152
- className: "Layer__table-cell Layer__bank-transactions__account-col",
6153
- ...openRow
6154
- },
6155
- /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ import_react67.default.createElement(
6309
+ "Split"
6310
+ ), /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, extractDescriptionForSplit(bankTransaction.category))), bankTransaction?.categorization_status === "MATCHED" /* MATCHED */ && bankTransaction?.match && /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement(
6311
+ MatchBadge,
6312
+ {
6313
+ classNamePrefix: className,
6314
+ bankTransaction,
6315
+ dateFormat
6316
+ }
6317
+ ), /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, `${(0, import_date_fns8.format)(
6318
+ (0, import_date_fns8.parseISO)(bankTransaction.match.bank_transaction.date),
6319
+ dateFormat
6320
+ )}, ${bankTransaction.match?.details?.description}`)), bankTransaction?.categorization_status !== "MATCHED" /* MATCHED */ && bankTransaction?.categorization_status !== "SPLIT" /* SPLIT */ && /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, bankTransaction?.category?.display_name)) : null,
6321
+ !categorized && !open && showRetry ? /* @__PURE__ */ import_react67.default.createElement(
6322
+ RetryButton,
6323
+ {
6324
+ onClick: () => {
6325
+ if (!bankTransaction.processing) {
6326
+ save();
6327
+ }
6328
+ },
6329
+ className: "Layer__bank-transaction__retry-btn",
6330
+ processing: bankTransaction.processing,
6331
+ error: "Approval failed. Check connection and retry in few seconds."
6332
+ },
6333
+ "Retry"
6334
+ ) : null,
6335
+ open && bankTransaction.error ? /* @__PURE__ */ import_react67.default.createElement(
6156
6336
  Text,
6157
6337
  {
6158
6338
  as: "span",
6159
- className: "Layer__bank-transactions__account-text",
6160
- withTooltip: "whenTruncated" /* whenTruncated */
6339
+ size: "md" /* md */,
6340
+ className: "Layer__unsaved-info"
6161
6341
  },
6162
- bankTransaction.account_name ?? ""
6163
- ))
6164
- ),
6165
- /* @__PURE__ */ import_react67.default.createElement(
6166
- "td",
6167
- {
6168
- className: `Layer__table-cell Layer__table-cell__amount-col Layer__bank-transactions__amount-col Layer__table-cell--amount ${className}__table-cell--amount-${isCredit(bankTransaction) ? "credit" : "debit"}`,
6169
- ...openRow
6170
- },
6171
- /* @__PURE__ */ import_react67.default.createElement("span", { className: "Layer__table-cell-content" }, isCredit(bankTransaction) ? "+$" : " $", centsToDollars(bankTransaction.amount))
6172
- ),
6173
- /* @__PURE__ */ import_react67.default.createElement(
6174
- "td",
6175
- {
6176
- className: (0, import_classnames33.default)(
6177
- "Layer__table-cell",
6178
- "Layer__table-cell__category-col",
6179
- `${className}__actions-cell`,
6180
- `${className}__actions-cell--${open ? "open" : "close"}`
6181
- )
6182
- },
6183
- /* @__PURE__ */ import_react67.default.createElement(
6184
- "span",
6342
+ /* @__PURE__ */ import_react67.default.createElement("span", null, "Unsaved"),
6343
+ /* @__PURE__ */ import_react67.default.createElement(AlertCircle_default, { size: 12 })
6344
+ ) : null,
6345
+ !categorized && (open || !open && !showRetry) || categorized && open ? /* @__PURE__ */ import_react67.default.createElement(
6346
+ SubmitButton,
6185
6347
  {
6186
- className: `${className}__actions-container Layer__table-cell-content`
6187
- },
6188
- !categorized && !open ? /* @__PURE__ */ import_react67.default.createElement(
6189
- CategorySelect,
6190
- {
6191
- bankTransaction,
6192
- name: `category-${bankTransaction.id}`,
6193
- value: selectedCategory,
6194
- onChange: (category) => {
6195
- setSelectedCategory(category);
6196
- setShowRetry(false);
6197
- },
6198
- disabled: bankTransaction.processing
6199
- }
6200
- ) : null,
6201
- categorized && !open ? /* @__PURE__ */ import_react67.default.createElement(Text, { as: "span", className: `${className}__category-text` }, bankTransaction.categorization_status === "SPLIT" /* SPLIT */ && /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement(
6202
- Badge,
6203
- {
6204
- icon: /* @__PURE__ */ import_react67.default.createElement(Scissors_default, { size: 11 }),
6205
- tooltip: /* @__PURE__ */ import_react67.default.createElement(
6206
- SplitTooltipDetails,
6207
- {
6208
- classNamePrefix: className,
6209
- category: bankTransaction.category
6210
- }
6211
- )
6212
- },
6213
- "Split"
6214
- ), /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, extractDescriptionForSplit(bankTransaction.category))), bankTransaction?.categorization_status === "MATCHED" /* MATCHED */ && bankTransaction?.match && /* @__PURE__ */ import_react67.default.createElement(import_react67.default.Fragment, null, /* @__PURE__ */ import_react67.default.createElement(
6215
- MatchBadge,
6216
- {
6217
- classNamePrefix: className,
6218
- bankTransaction,
6219
- dateFormat
6220
- }
6221
- ), /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, `${(0, import_date_fns8.format)(
6222
- (0, import_date_fns8.parseISO)(bankTransaction.match.bank_transaction.date),
6223
- dateFormat
6224
- )}, ${bankTransaction.match?.details?.description}`)), bankTransaction?.categorization_status !== "MATCHED" /* MATCHED */ && bankTransaction?.categorization_status !== "SPLIT" /* SPLIT */ && /* @__PURE__ */ import_react67.default.createElement("span", { className: `${className}__category-text__text` }, bankTransaction?.category?.display_name)) : null,
6225
- !categorized && !open && showRetry ? /* @__PURE__ */ import_react67.default.createElement(
6226
- RetryButton,
6227
- {
6228
- onClick: () => {
6229
- if (!bankTransaction.processing) {
6230
- save();
6231
- }
6232
- },
6233
- className: "Layer__bank-transaction__retry-btn",
6234
- processing: bankTransaction.processing,
6235
- error: "Approval failed. Check connection and retry in few seconds."
6236
- },
6237
- "Retry"
6238
- ) : null,
6239
- open && bankTransaction.error ? /* @__PURE__ */ import_react67.default.createElement(
6240
- Text,
6241
- {
6242
- as: "span",
6243
- size: "md" /* md */,
6244
- className: "Layer__unsaved-info"
6245
- },
6246
- /* @__PURE__ */ import_react67.default.createElement("span", null, "Unsaved"),
6247
- /* @__PURE__ */ import_react67.default.createElement(AlertCircle_default, { size: 12 })
6248
- ) : null,
6249
- !categorized && (open || !open && !showRetry) || categorized && open ? /* @__PURE__ */ import_react67.default.createElement(
6250
- SubmitButton,
6251
- {
6252
- onClick: () => {
6253
- if (!bankTransaction.processing) {
6254
- save();
6255
- }
6256
- },
6257
- className: "Layer__bank-transaction__submit-btn",
6258
- processing: bankTransaction.processing,
6259
- active: open,
6260
- action: categorized ? "save" /* SAVE */ : "update" /* UPDATE */
6348
+ onClick: () => {
6349
+ if (!bankTransaction.processing) {
6350
+ save();
6351
+ }
6261
6352
  },
6262
- categorized ? "Update" : "Approve"
6263
- ) : null,
6264
- /* @__PURE__ */ import_react67.default.createElement(
6265
- IconButton,
6266
- {
6267
- onClick: toggleOpen,
6268
- className: "Layer__bank-transaction-row__expand-button",
6269
- active: open,
6270
- icon: /* @__PURE__ */ import_react67.default.createElement(
6271
- ChevronDownFill_default,
6272
- {
6273
- className: `Layer__chevron ${open ? "Layer__chevron__up" : "Layer__chevron__down"}`
6274
- }
6275
- )
6276
- }
6277
- )
6353
+ className: "Layer__bank-transaction__submit-btn",
6354
+ processing: bankTransaction.processing,
6355
+ active: open,
6356
+ action: categorized ? "save" /* SAVE */ : "update" /* UPDATE */
6357
+ },
6358
+ categorized ? "Update" : "Approve"
6359
+ ) : null,
6360
+ /* @__PURE__ */ import_react67.default.createElement(
6361
+ IconButton,
6362
+ {
6363
+ onClick: toggleOpen,
6364
+ className: "Layer__bank-transaction-row__expand-button",
6365
+ active: open,
6366
+ icon: /* @__PURE__ */ import_react67.default.createElement(
6367
+ ChevronDownFill_default,
6368
+ {
6369
+ className: `Layer__chevron ${open ? "Layer__chevron__up" : "Layer__chevron__down"}`
6370
+ }
6371
+ )
6372
+ }
6278
6373
  )
6279
6374
  )
6280
- ), /* @__PURE__ */ import_react67.default.createElement("tr", null, /* @__PURE__ */ import_react67.default.createElement("td", { colSpan: 5, className: "Layer__bank-transaction-row__expanded-td" }, /* @__PURE__ */ import_react67.default.createElement(
6375
+ )), /* @__PURE__ */ import_react67.default.createElement("tr", null, /* @__PURE__ */ import_react67.default.createElement("td", { colSpan: 5, className: "Layer__bank-transaction-row__expanded-td" }, /* @__PURE__ */ import_react67.default.createElement(
6281
6376
  ExpandedBankTransactionRow,
6282
6377
  {
6283
6378
  ref: expandedRowRef,
@@ -6339,11 +6434,11 @@ var BankTransactionListItem = ({
6339
6434
  editable,
6340
6435
  showDescriptions,
6341
6436
  showReceiptUploads,
6342
- containerWidth
6437
+ containerWidth,
6438
+ removeTransaction
6343
6439
  }) => {
6344
6440
  const expandedRowRef = (0, import_react69.useRef)(null);
6345
6441
  const [showRetry, setShowRetry] = (0, import_react69.useState)(false);
6346
- const [removed, setRemoved] = (0, import_react69.useState)(false);
6347
6442
  const { categorize: categorizeBankTransaction2, match: matchBankTransaction2 } = useBankTransactionsContext();
6348
6443
  const [selectedCategory, setSelectedCategory] = (0, import_react69.useState)(
6349
6444
  getDefaultSelectedCategory(bankTransaction)
@@ -6365,6 +6460,13 @@ var BankTransactionListItem = ({
6365
6460
  setShowRetry(true);
6366
6461
  }
6367
6462
  }, [bankTransaction.error]);
6463
+ (0, import_react69.useEffect)(() => {
6464
+ if (editable && bankTransaction.recently_categorized) {
6465
+ setTimeout(() => {
6466
+ removeTransaction(bankTransaction);
6467
+ }, 300);
6468
+ }
6469
+ }, [bankTransaction.recently_categorized]);
6368
6470
  const save = () => {
6369
6471
  if (open && expandedRowRef?.current) {
6370
6472
  expandedRowRef?.current?.save();
@@ -6382,9 +6484,6 @@ var BankTransactionListItem = ({
6382
6484
  category: getCategorizePayload(selectedCategory)
6383
6485
  });
6384
6486
  };
6385
- if (removed) {
6386
- return null;
6387
- }
6388
6487
  const categorized = isCategorized(bankTransaction);
6389
6488
  const className = "Layer__bank-transaction-list-item";
6390
6489
  const openClassName = open ? `${className}--expanded` : "";
@@ -6583,7 +6682,15 @@ var BusinessForm = ({ bankTransaction }) => {
6583
6682
  onClick: onCategorySelect,
6584
6683
  selected: selectedCategory
6585
6684
  }
6586
- ), options.length === 0 ? /* @__PURE__ */ import_react71.default.createElement(Button, { onClick: openDrawer, fullWidth: true }, "Select category") : null, options.length > 0 ? /* @__PURE__ */ import_react71.default.createElement(
6685
+ ), options.length === 0 ? /* @__PURE__ */ import_react71.default.createElement(
6686
+ Button,
6687
+ {
6688
+ onClick: openDrawer,
6689
+ fullWidth: true,
6690
+ variant: "secondary" /* secondary */
6691
+ },
6692
+ "Select category"
6693
+ ) : null, options.length > 0 ? /* @__PURE__ */ import_react71.default.createElement(
6587
6694
  Button,
6588
6695
  {
6589
6696
  onClick: save,
@@ -7004,8 +7111,12 @@ var BankTransactionMobileListItem = ({
7004
7111
  }, [transactionIdToOpen]);
7005
7112
  (0, import_react78.useEffect)(() => {
7006
7113
  if (!removeAnim && bankTransaction.recently_categorized) {
7007
- setRemoveAnim(true);
7008
- openNext();
7114
+ if (editable) {
7115
+ setRemoveAnim(true);
7116
+ openNext();
7117
+ } else {
7118
+ close();
7119
+ }
7009
7120
  }
7010
7121
  }, [
7011
7122
  bankTransaction.recently_categorized,
@@ -7032,6 +7143,13 @@ var BankTransactionMobileListItem = ({
7032
7143
  setShowComponent(true);
7033
7144
  }
7034
7145
  }, []);
7146
+ (0, import_react78.useEffect)(() => {
7147
+ if (editable && bankTransaction.recently_categorized) {
7148
+ setTimeout(() => {
7149
+ removeTransaction(bankTransaction);
7150
+ }, 300);
7151
+ }
7152
+ }, [bankTransaction.recently_categorized]);
7035
7153
  const onChangePurpose = (event) => setPurpose(event.target.value);
7036
7154
  const categorized = isCategorized(bankTransaction);
7037
7155
  const className = "Layer__bank-transaction-mobile-list-item";
@@ -7047,18 +7165,7 @@ var BankTransactionMobileListItem = ({
7047
7165
  {
7048
7166
  ref: itemRef,
7049
7167
  className: rowClassName,
7050
- "data-item": bankTransaction.id,
7051
- onTransitionEnd: ({ propertyName }) => {
7052
- if (propertyName === "opacity") {
7053
- close();
7054
- if (editable) {
7055
- setRemoveAnim(false);
7056
- setTimeout(() => {
7057
- removeTransaction(bankTransaction.id);
7058
- }, 500);
7059
- }
7060
- }
7061
- }
7168
+ "data-item": bankTransaction.id
7062
7169
  },
7063
7170
  /* @__PURE__ */ import_react78.default.createElement(
7064
7171
  "span",
@@ -7077,7 +7184,7 @@ var BankTransactionMobileListItem = ({
7077
7184
  centsToDollars(bankTransaction.amount)
7078
7185
  ), /* @__PURE__ */ import_react78.default.createElement("span", { className: `${className}__heading__date` }, (0, import_date_fns11.format)((0, import_date_fns11.parseISO)(bankTransaction.date), DATE_FORMAT2))))
7079
7186
  ),
7080
- /* @__PURE__ */ import_react78.default.createElement("div", { className: `${className}__expanded-row`, style: { height } }, open && /* @__PURE__ */ import_react78.default.createElement(
7187
+ /* @__PURE__ */ import_react78.default.createElement("div", { className: `${className}__expanded-row`, style: { height: !open || removeAnim ? 0 : height } }, open && /* @__PURE__ */ import_react78.default.createElement(
7081
7188
  "div",
7082
7189
  {
7083
7190
  className: `${className}__expanded-row__content`,
@@ -7303,7 +7410,9 @@ var Pagination = ({
7303
7410
  totalCount,
7304
7411
  siblingCount = 1,
7305
7412
  currentPage,
7306
- pageSize
7413
+ pageSize,
7414
+ hasMore,
7415
+ fetchMore
7307
7416
  }) => {
7308
7417
  const paginationRange = usePagination({
7309
7418
  currentPage,
@@ -7352,12 +7461,23 @@ var Pagination = ({
7352
7461
  onClick: () => {
7353
7462
  if (typeof pageNumber === "number") {
7354
7463
  onPageChange(pageNumber);
7464
+ if (pageNumber === lastPage && hasMore && fetchMore) {
7465
+ fetchMore();
7466
+ }
7355
7467
  }
7356
7468
  }
7357
7469
  },
7358
7470
  pageNumber
7359
7471
  );
7360
- }), /* @__PURE__ */ import_react84.default.createElement(
7472
+ }), hasMore && fetchMore ? /* @__PURE__ */ import_react84.default.createElement(
7473
+ "li",
7474
+ {
7475
+ key: `page-has-more`,
7476
+ className: "Layer__pagination-item Layer__pagination-arrow Layer__pagination-arrow--next",
7477
+ onClick: fetchMore
7478
+ },
7479
+ "..."
7480
+ ) : null, /* @__PURE__ */ import_react84.default.createElement(
7361
7481
  "li",
7362
7482
  {
7363
7483
  key: `page-last`,
@@ -7505,6 +7625,21 @@ var DatePickerOptions = ({
7505
7625
  },
7506
7626
  "This quarter"
7507
7627
  );
7628
+ case "last-quarter":
7629
+ return /* @__PURE__ */ import_react85.default.createElement(
7630
+ TextButton,
7631
+ {
7632
+ key: option,
7633
+ onClick: () => {
7634
+ const lastQuarter = (0, import_date_fns13.subQuarters)(/* @__PURE__ */ new Date(), 1);
7635
+ setSelectedDate([
7636
+ (0, import_date_fns13.startOfQuarter)(lastQuarter),
7637
+ (0, import_date_fns13.endOfQuarter)(lastQuarter)
7638
+ ]);
7639
+ }
7640
+ },
7641
+ "Last quarter"
7642
+ );
7508
7643
  case "this-year":
7509
7644
  return /* @__PURE__ */ import_react85.default.createElement(
7510
7645
  TextButton,
@@ -7516,11 +7651,30 @@ var DatePickerOptions = ({
7516
7651
  },
7517
7652
  "This year"
7518
7653
  );
7654
+ case "last-year":
7655
+ return /* @__PURE__ */ import_react85.default.createElement(
7656
+ TextButton,
7657
+ {
7658
+ key: option,
7659
+ onClick: () => {
7660
+ const lastYear = (0, import_date_fns13.subYears)(/* @__PURE__ */ new Date(), 1);
7661
+ setSelectedDate([(0, import_date_fns13.startOfYear)(lastYear), (0, import_date_fns13.endOfYear)(lastYear)]);
7662
+ }
7663
+ },
7664
+ "Last year"
7665
+ );
7519
7666
  }
7520
7667
  return /* @__PURE__ */ import_react85.default.createElement(import_react85.default.Fragment, null);
7521
7668
  };
7522
7669
  if (options.length === 0) {
7523
- const allOptions = ["this-month", "last-month", "this-quarter", "this-year"];
7670
+ const allOptions = [
7671
+ "this-month",
7672
+ "last-month",
7673
+ "this-quarter",
7674
+ "last-quarter",
7675
+ "this-year",
7676
+ "last-year"
7677
+ ];
7524
7678
  allOptions.forEach((option) => {
7525
7679
  optionsComponents.push(getOptionComponent(option));
7526
7680
  });
@@ -7537,6 +7691,20 @@ var DatePickerOptions = ({
7537
7691
 
7538
7692
  // src/components/DatePicker/DatePicker.tsx
7539
7693
  var import_classnames38 = __toESM(require("classnames"));
7694
+ var getDefaultRangeDate = (date, mode, selected) => {
7695
+ try {
7696
+ if (isRangeMode(mode) && selected) {
7697
+ if (date === "end") {
7698
+ return selected[1];
7699
+ }
7700
+ return selected[0];
7701
+ }
7702
+ return null;
7703
+ } catch (_err) {
7704
+ return null;
7705
+ }
7706
+ };
7707
+ var isRangeMode = (mode) => mode === "dayRangePicker" || mode === "monthRangePicker";
7540
7708
  var DatePicker = ({
7541
7709
  selected,
7542
7710
  onChange,
@@ -7555,10 +7723,29 @@ var DatePicker = ({
7555
7723
  }) => {
7556
7724
  const [updatePickerDate, setPickerDate] = (0, import_react86.useState)(false);
7557
7725
  const [selectedDates, setSelectedDates] = (0, import_react86.useState)(selected);
7726
+ const [startDate, setStartDate] = (0, import_react86.useState)(
7727
+ getDefaultRangeDate("start", mode, selected) ?? /* @__PURE__ */ new Date()
7728
+ );
7729
+ const [endDate, setEndDate] = (0, import_react86.useState)(
7730
+ getDefaultRangeDate("end", mode, selected)
7731
+ );
7558
7732
  (0, import_react86.useEffect)(() => {
7559
- setPickerDate(true);
7560
- if (selected !== selectedDates) {
7561
- setSelectedDates(selected);
7733
+ try {
7734
+ setPickerDate(true);
7735
+ if (!isRangeMode(mode) && selected !== selectedDates) {
7736
+ setSelectedDates(selected);
7737
+ return;
7738
+ }
7739
+ if (isRangeMode(mode) && Array.isArray(selected)) {
7740
+ if (startDate !== selected[0]) {
7741
+ setStartDate(selected[0]);
7742
+ }
7743
+ if (endDate !== selected[1]) {
7744
+ setEndDate(selected[1]);
7745
+ }
7746
+ }
7747
+ } catch (_err) {
7748
+ return;
7562
7749
  }
7563
7750
  }, [selected]);
7564
7751
  (0, import_react86.useEffect)(() => {
@@ -7568,6 +7755,11 @@ var DatePicker = ({
7568
7755
  setPickerDate(false);
7569
7756
  }
7570
7757
  }, [selectedDates]);
7758
+ (0, import_react86.useEffect)(() => {
7759
+ if (isRangeMode(mode)) {
7760
+ setSelectedDates([startDate, endDate]);
7761
+ }
7762
+ }, [startDate, endDate]);
7571
7763
  const wrapperClassNames = (0, import_classnames38.default)(
7572
7764
  "Layer__datepicker__wrapper",
7573
7765
  mode === "timePicker" && "Layer__datepicker__time__wrapper"
@@ -7586,6 +7778,12 @@ var DatePicker = ({
7586
7778
  popperClassName
7587
7779
  );
7588
7780
  const handleDateChange = (date) => {
7781
+ if (isRangeMode(mode)) {
7782
+ const [start, end] = date;
7783
+ setStartDate(start);
7784
+ setEndDate(end);
7785
+ return;
7786
+ }
7589
7787
  setSelectedDates(date);
7590
7788
  };
7591
7789
  const isCurrentDate = () => {
@@ -7611,15 +7809,15 @@ var DatePicker = ({
7611
7809
  import_react_datepicker.default,
7612
7810
  {
7613
7811
  wrapperClassName: datePickerWrapperClassNames,
7614
- startDate: mode === "dayRangePicker" || mode === "monthRangePicker" ? selectedDates[0] : void 0,
7615
- endDate: mode === "dayRangePicker" || mode === "monthRangePicker" ? selectedDates[1] : void 0,
7812
+ startDate: isRangeMode(mode) ? startDate : void 0,
7813
+ endDate: isRangeMode(mode) ? endDate : void 0,
7616
7814
  selected: mode !== "dayRangePicker" && mode !== "monthRangePicker" ? selectedDates : void 0,
7617
7815
  onChange: handleDateChange,
7618
7816
  calendarClassName: calendarClassNames,
7619
7817
  popperClassName: popperClassNames,
7620
7818
  enableTabLoop: false,
7621
7819
  popperPlacement: "bottom-start",
7622
- selectsRange: mode === "dayRangePicker" || mode === "monthRangePicker",
7820
+ selectsRange: isRangeMode(mode),
7623
7821
  showMonthYearPicker: mode === "monthPicker" || mode === "monthRangePicker",
7624
7822
  dateFormat,
7625
7823
  renderDayContents: (day) => /* @__PURE__ */ import_react86.default.createElement("span", { className: "Layer__datepicker__day-contents" }, day),
@@ -7628,6 +7826,7 @@ var DatePicker = ({
7628
7826
  showTimeSelect: mode === "timePicker",
7629
7827
  showTimeSelectOnly: mode === "timePicker",
7630
7828
  minDate,
7829
+ maxDate: /* @__PURE__ */ new Date(),
7631
7830
  ...props
7632
7831
  },
7633
7832
  mode === "dayRangePicker" && /* @__PURE__ */ import_react86.default.createElement(
@@ -7924,19 +8123,30 @@ var Inbox_default = Inbox;
7924
8123
  // src/components/BankTransactions/DataStates.tsx
7925
8124
  var DataStates = ({
7926
8125
  bankTransactions,
8126
+ transactionsLoading,
7927
8127
  isLoading,
7928
8128
  isValidating,
7929
8129
  error,
7930
8130
  refetch,
7931
8131
  editable
7932
8132
  }) => {
8133
+ let title;
8134
+ let description;
8135
+ if (transactionsLoading) {
8136
+ title = "Data sync in progress";
8137
+ description = "Check back later to review your transactions";
8138
+ } else {
8139
+ title = editable ? "You are up to date with transactions!" : "You have no categorized transactions";
8140
+ description = editable ? "All uncategorized transaction will be displayed here" : "All transaction will be displayed here once reviewed";
8141
+ }
8142
+ const showRefreshButton = transactionsLoading || bankTransactions?.length;
7933
8143
  return /* @__PURE__ */ import_react90.default.createElement(import_react90.default.Fragment, null, !isLoading && !error && (bankTransactions === void 0 || bankTransactions !== void 0 && bankTransactions.length === 0) ? /* @__PURE__ */ import_react90.default.createElement("div", { className: "Layer__table-state-container" }, /* @__PURE__ */ import_react90.default.createElement(
7934
8144
  DataState,
7935
8145
  {
7936
- status: "allDone" /* allDone */,
7937
- title: editable ? "You are up to date with transactions!" : "You have no categorized transactions",
7938
- description: editable ? "All uncategorized transaction will be displayed here" : "All transaction will be displayed here once reviewed",
7939
- onRefresh: () => refetch(),
8146
+ status: transactionsLoading ? "info" /* info */ : "allDone" /* allDone */,
8147
+ title,
8148
+ description,
8149
+ onRefresh: showRefreshButton ? refetch : void 0,
7940
8150
  isLoading: isValidating,
7941
8151
  icon: !editable ? /* @__PURE__ */ import_react90.default.createElement(Inbox_default, null) : void 0
7942
8152
  }
@@ -7946,7 +8156,7 @@ var DataStates = ({
7946
8156
  status: "failed" /* failed */,
7947
8157
  title: "Something went wrong",
7948
8158
  description: "We couldn\u2019t load your data.",
7949
- onRefresh: () => refetch(),
8159
+ onRefresh: refetch,
7950
8160
  isLoading: isValidating
7951
8161
  }
7952
8162
  )) : null);
@@ -7955,6 +8165,7 @@ var DataStates = ({
7955
8165
  // src/components/BankTransactions/BankTransactions.tsx
7956
8166
  var import_date_fns15 = require("date-fns");
7957
8167
  var COMPONENT_NAME2 = "bank-transactions";
8168
+ var TEST_EMPTY_STATE = false;
7958
8169
  var BankTransactions = ({
7959
8170
  onError,
7960
8171
  ...props
@@ -7963,7 +8174,7 @@ var BankTransactions = ({
7963
8174
  };
7964
8175
  var BankTransactionsContent = ({
7965
8176
  asWidget = false,
7966
- pageSize = 15,
8177
+ pageSize = 20,
7967
8178
  categorizedOnly = false,
7968
8179
  categorizeView = true,
7969
8180
  showDescriptions = false,
@@ -7974,7 +8185,6 @@ var BankTransactionsContent = ({
7974
8185
  hideHeader = false
7975
8186
  }) => {
7976
8187
  const [currentPage, setCurrentPage] = (0, import_react91.useState)(1);
7977
- const [removedTxs, setRemovedTxs] = (0, import_react91.useState)([]);
7978
8188
  const [initialLoad, setInitialLoad] = (0, import_react91.useState)(true);
7979
8189
  const [dateRange, setDateRange] = (0, import_react91.useState)({
7980
8190
  startDate: (0, import_date_fns15.startOfMonth)(/* @__PURE__ */ new Date()),
@@ -7990,9 +8200,12 @@ var BankTransactionsContent = ({
7990
8200
  refetch,
7991
8201
  setFilters,
7992
8202
  filters,
7993
- accountsList,
7994
- display
8203
+ display,
8204
+ hasMore,
8205
+ fetchMore,
8206
+ removeAfterCategorize
7995
8207
  } = useBankTransactionsContext();
8208
+ const { data: linkedAccounts } = useLinkedAccounts();
7996
8209
  (0, import_react91.useEffect)(() => {
7997
8210
  activate();
7998
8211
  }, []);
@@ -8002,24 +8215,24 @@ var BankTransactionsContent = ({
8002
8215
  setFilters({
8003
8216
  ...filters,
8004
8217
  ...inputFilters,
8005
- categorizationStatus: "TO_REVIEW" /* TO_REVIEW */
8218
+ categorizationStatus: "review" /* review */
8006
8219
  });
8007
8220
  } else if (!filters?.categorizationStatus && categorizedOnly) {
8008
8221
  setFilters({
8009
8222
  ...filters,
8010
8223
  ...inputFilters,
8011
- categorizationStatus: "CATEGORIZED" /* CATEGORIZED */
8224
+ categorizationStatus: "categorized" /* categorized */
8012
8225
  });
8013
8226
  } else {
8014
8227
  setFilters({ ...filters, ...inputFilters });
8015
8228
  }
8016
8229
  } else if (!filters?.categorizationStatus && categorizeView) {
8017
8230
  setFilters({
8018
- categorizationStatus: "TO_REVIEW" /* TO_REVIEW */
8231
+ categorizationStatus: "review" /* review */
8019
8232
  });
8020
8233
  } else if (!filters?.categorizationStatus && categorizedOnly) {
8021
8234
  setFilters({
8022
- categorizationStatus: "CATEGORIZED" /* CATEGORIZED */
8235
+ categorizationStatus: "categorized" /* categorized */
8023
8236
  });
8024
8237
  }
8025
8238
  }, [inputFilters, categorizeView, categorizedOnly]);
@@ -8031,7 +8244,7 @@ var BankTransactionsContent = ({
8031
8244
  return () => clearTimeout(timeoutLoad);
8032
8245
  }
8033
8246
  }, [loadingStatus]);
8034
- const bankTransactions = (0, import_react91.useMemo)(() => {
8247
+ const bankTransactions = TEST_EMPTY_STATE ? [] : (0, import_react91.useMemo)(() => {
8035
8248
  if (monthlyView) {
8036
8249
  return data?.filter(
8037
8250
  (x) => (0, import_date_fns15.parseISO)(x.date) >= dateRange.startDate && (0, import_date_fns15.parseISO)(x.date) <= dateRange.endDate
@@ -8040,10 +8253,10 @@ var BankTransactionsContent = ({
8040
8253
  const firstPageIndex = (currentPage - 1) * pageSize;
8041
8254
  const lastPageIndex = firstPageIndex + pageSize;
8042
8255
  return data?.slice(firstPageIndex, lastPageIndex);
8043
- }, [currentPage, data, removedTxs, dateRange]);
8256
+ }, [currentPage, data, dateRange]);
8044
8257
  const onCategorizationDisplayChange = (event) => {
8045
8258
  setFilters({
8046
- categorizationStatus: event.target.value === "categorized" /* categorized */ ? "CATEGORIZED" /* CATEGORIZED */ : "TO_REVIEW" /* TO_REVIEW */
8259
+ categorizationStatus: event.target.value === "categorized" /* categorized */ ? "categorized" /* categorized */ : "review" /* review */
8047
8260
  });
8048
8261
  setCurrentPage(1);
8049
8262
  };
@@ -8052,11 +8265,7 @@ var BankTransactionsContent = ({
8052
8265
  const [listView, setListView] = (0, import_react91.useState)(false);
8053
8266
  const [containerWidth, setContainerWidth] = (0, import_react91.useState)(0);
8054
8267
  const debounceContainerWidth = debounce(setContainerWidth, 500);
8055
- const removeTransaction = (id) => {
8056
- const newTxs = removedTxs.slice();
8057
- newTxs.push(id);
8058
- setRemovedTxs(newTxs);
8059
- };
8268
+ const removeTransaction = (bankTransaction) => removeAfterCategorize(bankTransaction);
8060
8269
  const containerRef = useElementSize((_el, _en, size) => {
8061
8270
  if (size?.height && size?.height >= 90) {
8062
8271
  const newShift = -Math.floor(size.height / 2) + 6;
@@ -8137,6 +8346,9 @@ var BankTransactionsContent = ({
8137
8346
  {
8138
8347
  bankTransactions,
8139
8348
  isLoading,
8349
+ transactionsLoading: Boolean(
8350
+ linkedAccounts?.some((item) => item.is_syncing)
8351
+ ),
8140
8352
  isValidating,
8141
8353
  error,
8142
8354
  refetch,
@@ -8149,7 +8361,9 @@ var BankTransactionsContent = ({
8149
8361
  currentPage,
8150
8362
  totalCount: data?.length || 0,
8151
8363
  pageSize,
8152
- onPageChange: (page) => setCurrentPage(page)
8364
+ onPageChange: (page) => setCurrentPage(page),
8365
+ fetchMore,
8366
+ hasMore
8153
8367
  }
8154
8368
  ))
8155
8369
  );
@@ -8309,7 +8523,7 @@ var applyShare = (items, total) => {
8309
8523
  // src/hooks/useProfitAndLoss/useProfitAndLossQuery.tsx
8310
8524
  var import_react94 = require("react");
8311
8525
  var import_date_fns16 = require("date-fns");
8312
- var import_swr4 = __toESM(require("swr"));
8526
+ var import_swr3 = __toESM(require("swr"));
8313
8527
  var useProfitAndLossQuery = ({
8314
8528
  startDate,
8315
8529
  endDate,
@@ -8326,7 +8540,7 @@ var useProfitAndLossQuery = ({
8326
8540
  isValidating,
8327
8541
  error: rawError,
8328
8542
  mutate
8329
- } = (0, import_swr4.default)(
8543
+ } = (0, import_swr3.default)(
8330
8544
  businessId && startDate && endDate && auth?.access_token && `profit-and-loss-${businessId}-${startDate.valueOf()}-${endDate.valueOf()}-${tagFilter?.key}-${tagFilter?.values?.join(
8331
8545
  ","
8332
8546
  )}-${reportingBasis}`,
@@ -8519,7 +8733,7 @@ var import_react98 = __toESM(require("react"));
8519
8733
  // src/hooks/useProfitAndLoss/useProfitAndLossLTM.tsx
8520
8734
  var import_react96 = require("react");
8521
8735
  var import_date_fns18 = require("date-fns");
8522
- var import_swr5 = __toESM(require("swr"));
8736
+ var import_swr4 = __toESM(require("swr"));
8523
8737
  var buildDates = ({ currentDate }) => {
8524
8738
  return {
8525
8739
  startYear: (0, import_date_fns18.startOfMonth)(currentDate).getFullYear() - 1,
@@ -8554,7 +8768,7 @@ var useProfitAndLossLTM = ({ currentDate, tagFilter, reportingBasis } = {
8554
8768
  isValidating,
8555
8769
  error,
8556
8770
  mutate
8557
- } = (0, import_swr5.default)(
8771
+ } = (0, import_swr4.default)(
8558
8772
  businessId && Boolean(startYear) && Boolean(startMonth) && Boolean(endYear) && Boolean(endMonth) && auth?.access_token && `profit-and-loss-summaries-${businessId}-${startYear.toString()}-${startMonth.toString()}-${tagFilter?.key}-${tagFilter?.values?.join(
8559
8773
  ","
8560
8774
  )}-${reportingBasis}`,
@@ -8859,8 +9073,10 @@ var ProfitAndLossChart = () => {
8859
9073
  name: getMonthName(pnl),
8860
9074
  revenue: pnl?.income || 0,
8861
9075
  revenueUncategorized: pnl?.uncategorizedInflows || 0,
8862
- expenses: -Math.abs((pnl?.income || 0) - (pnl?.netProfit || 0)),
8863
- expensesUncategorized: -Math.abs(pnl?.uncategorizedOutflows || 0),
9076
+ expenses: -(pnl?.operatingExpenses || 0),
9077
+ expensesUncategorized: -(pnl?.uncategorizedOutflows || 0),
9078
+ operatingExpensesInverse: pnl?.operatingExpensesInverse || 0,
9079
+ uncategorizedOutflowsInverse: pnl?.uncategorizedOutflowsInverse || 0,
8864
9080
  netProfit: pnl?.netProfit || 0,
8865
9081
  selected: !!pnl && pnl.month === selectionMonth.month + 1 && pnl.year === selectionMonth.year,
8866
9082
  year: pnl?.year,
@@ -8879,6 +9095,8 @@ var ProfitAndLossChart = () => {
8879
9095
  name: (0, import_date_fns19.format)(currentDate, compactView ? "LLLLL" : "LLL"),
8880
9096
  revenue: 0,
8881
9097
  revenueUncategorized: 0,
9098
+ operatingExpensesInverse: 0,
9099
+ uncategorizedOutflowsInverse: 0,
8882
9100
  expenses: 0,
8883
9101
  expensesUncategorized: 0,
8884
9102
  netProfit: 0,
@@ -8892,7 +9110,18 @@ var ProfitAndLossChart = () => {
8892
9110
  }
8893
9111
  return loadingData;
8894
9112
  }
8895
- return data?.filter(
9113
+ return data?.map((x) => {
9114
+ if (x.operatingExpenses < 0 || x.uncategorizedOutflows < 0) {
9115
+ return {
9116
+ ...x,
9117
+ operatingExpenses: x.operatingExpenses < 0 ? 0 : x.operatingExpenses,
9118
+ uncategorizedOutflows: x.uncategorizedOutflows < 0 ? 0 : x.uncategorizedOutflows,
9119
+ operatingExpensesInverse: x.operatingExpenses < 0 ? -x.operatingExpenses : 0,
9120
+ uncategorizedOutflowsInverse: x.uncategorizedOutflows < 0 ? -x.uncategorizedOutflows : 0
9121
+ };
9122
+ }
9123
+ return x;
9124
+ })?.filter(
8896
9125
  (x) => (0, import_date_fns19.differenceInMonths)(
8897
9126
  (0, import_date_fns19.startOfMonth)(new Date(x.year, x.month - 1, 1)),
8898
9127
  chartWindow.start
@@ -9179,6 +9408,22 @@ var ProfitAndLossChart = () => {
9179
9408
  stackId: "expenses"
9180
9409
  }
9181
9410
  ),
9411
+ /* @__PURE__ */ import_react98.default.createElement(
9412
+ import_recharts.Bar,
9413
+ {
9414
+ dataKey: "operatingExpensesInverse",
9415
+ barSize,
9416
+ isAnimationActive: barAnimActive,
9417
+ animationDuration: 100,
9418
+ radius: [2, 2, 0, 0],
9419
+ className: "Layer__profit-and-loss-chart__bar--expenses",
9420
+ xAxisId: "revenue",
9421
+ stackId: "revenue"
9422
+ },
9423
+ theData?.map((entry) => {
9424
+ return /* @__PURE__ */ import_react98.default.createElement(import_recharts.Cell, { key: entry.name, fill: "url(#layer-bar-stripe-pattern-dark)" });
9425
+ })
9426
+ ),
9182
9427
  /* @__PURE__ */ import_react98.default.createElement(
9183
9428
  import_recharts.Bar,
9184
9429
  {
@@ -9214,6 +9459,22 @@ var ProfitAndLossChart = () => {
9214
9459
  );
9215
9460
  })
9216
9461
  ),
9462
+ /* @__PURE__ */ import_react98.default.createElement(
9463
+ import_recharts.Bar,
9464
+ {
9465
+ dataKey: "uncategorizedOutflowsInverse",
9466
+ barSize,
9467
+ isAnimationActive: barAnimActive,
9468
+ animationDuration: 100,
9469
+ radius: [2, 2, 0, 0],
9470
+ className: "Layer__profit-and-loss-chart__bar--expenses-uncategorized",
9471
+ xAxisId: "revenue",
9472
+ stackId: "revenue"
9473
+ },
9474
+ theData?.map((entry) => {
9475
+ return /* @__PURE__ */ import_react98.default.createElement(import_recharts.Cell, { key: entry.name, fill: "url(#layer-bar-stripe-pattern-dark)" });
9476
+ })
9477
+ ),
9217
9478
  /* @__PURE__ */ import_react98.default.createElement(
9218
9479
  import_recharts.Bar,
9219
9480
  {
@@ -10600,11 +10861,11 @@ var TableProvider = ({ children }) => {
10600
10861
  // src/hooks/useBalanceSheet/useBalanceSheet.tsx
10601
10862
  var import_react112 = require("react");
10602
10863
  var import_date_fns23 = require("date-fns");
10603
- var import_swr6 = __toESM(require("swr"));
10864
+ var import_swr5 = __toESM(require("swr"));
10604
10865
  var useBalanceSheet = (date = /* @__PURE__ */ new Date()) => {
10605
10866
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
10606
10867
  const dateString = (0, import_date_fns23.format)((0, import_date_fns23.startOfDay)(date), "yyyy-MM-dd'T'HH:mm:ssXXX");
10607
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr6.default)(
10868
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr5.default)(
10608
10869
  businessId && dateString && auth?.access_token && `balance-sheet-${businessId}-${dateString}`,
10609
10870
  Layer.getBalanceSheet(apiUrl, auth?.access_token, {
10610
10871
  params: {
@@ -11049,7 +11310,7 @@ var StatementOfCashFlowContext = (0, import_react126.createContext)({
11049
11310
  // src/hooks/useStatementOfCashFlow/useStatementOfCashFlow.tsx
11050
11311
  var import_react127 = require("react");
11051
11312
  var import_date_fns25 = require("date-fns");
11052
- var import_swr7 = __toESM(require("swr"));
11313
+ var import_swr6 = __toESM(require("swr"));
11053
11314
  var useStatementOfCashFlow = (startDate = /* @__PURE__ */ new Date(), endDate = /* @__PURE__ */ new Date()) => {
11054
11315
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
11055
11316
  const startDateString = (0, import_date_fns25.format)(
@@ -11057,7 +11318,7 @@ var useStatementOfCashFlow = (startDate = /* @__PURE__ */ new Date(), endDate =
11057
11318
  "yyyy-MM-dd'T'HH:mm:ssXXX"
11058
11319
  );
11059
11320
  const endDateString = (0, import_date_fns25.format)((0, import_date_fns25.startOfDay)(endDate), "yyyy-MM-dd'T'HH:mm:ssXXX");
11060
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr7.default)(
11321
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr6.default)(
11061
11322
  businessId && startDateString && endDateString && auth?.access_token && `statement-of-cash-${businessId}-${startDateString}-${endDateString}`,
11062
11323
  Layer.getStatementOfCashFlow(apiUrl, auth?.access_token, {
11063
11324
  params: {
@@ -11498,7 +11759,7 @@ var LEDGER_ACCOUNT_SUBTYPES_FOR_TYPE = {
11498
11759
 
11499
11760
  // src/hooks/useChartOfAccounts/useChartOfAccounts.tsx
11500
11761
  var import_date_fns28 = require("date-fns");
11501
- var import_swr8 = __toESM(require("swr"));
11762
+ var import_swr7 = __toESM(require("swr"));
11502
11763
  var validate = (formData) => {
11503
11764
  const errors = [];
11504
11765
  const nameError = validateName(formData);
@@ -11599,7 +11860,7 @@ var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: ini
11599
11860
  const [endDate, setEndDate] = (0, import_react132.useState)(
11600
11861
  initialEndDate ?? (0, import_date_fns28.endOfMonth)(Date.now())
11601
11862
  );
11602
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr8.default)(
11863
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr7.default)(
11603
11864
  businessId && auth?.access_token && `chart-of-accounts-${businessId}-${startDate?.valueOf()}-${endDate?.valueOf()}`,
11604
11865
  Layer.getLedgerAccountBalances(apiUrl, auth?.access_token, {
11605
11866
  params: {
@@ -11808,12 +12069,12 @@ var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: ini
11808
12069
 
11809
12070
  // src/hooks/useLedgerAccounts/useLedgerAccounts.tsx
11810
12071
  var import_react133 = require("react");
11811
- var import_swr9 = __toESM(require("swr"));
12072
+ var import_swr8 = __toESM(require("swr"));
11812
12073
  var useLedgerAccounts = () => {
11813
12074
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
11814
12075
  const [accountId, setAccountId] = (0, import_react133.useState)();
11815
12076
  const [selectedEntryId, setSelectedEntryId] = (0, import_react133.useState)();
11816
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr9.default)(
12077
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr8.default)(
11817
12078
  businessId && accountId && auth?.access_token && `ledger-accounts-lines-${businessId}-${accountId}`,
11818
12079
  Layer.getLedgerAccountsLines(apiUrl, auth?.access_token, {
11819
12080
  params: { businessId, accountId }
@@ -11825,7 +12086,7 @@ var useLedgerAccounts = () => {
11825
12086
  isLoading: isLoadingEntry,
11826
12087
  isValidating: isValdiatingEntry,
11827
12088
  error: errorEntry
11828
- } = (0, import_swr9.default)(
12089
+ } = (0, import_swr8.default)(
11829
12090
  businessId && selectedEntryId && auth?.access_token && `ledger-accounts-entry-${businessId}-${selectedEntryId}}`,
11830
12091
  Layer.getLedgerAccountsEntry(apiUrl, auth?.access_token, {
11831
12092
  params: { businessId, entryId: selectedEntryId }
@@ -12915,7 +13176,7 @@ var getAccountIdentifierPayload = (journalLineItem) => {
12915
13176
  };
12916
13177
 
12917
13178
  // src/hooks/useJournal/useJournal.tsx
12918
- var import_swr10 = __toESM(require("swr"));
13179
+ var import_swr9 = __toESM(require("swr"));
12919
13180
  var useJournal = () => {
12920
13181
  const {
12921
13182
  auth,
@@ -12931,7 +13192,7 @@ var useJournal = () => {
12931
13192
  const [addingEntry, setAddingEntry] = (0, import_react149.useState)(false);
12932
13193
  const [sendingForm, setSendingForm] = (0, import_react149.useState)(false);
12933
13194
  const [apiError, setApiError] = (0, import_react149.useState)(void 0);
12934
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr10.default)(
13195
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr9.default)(
12935
13196
  businessId && auth?.access_token && `journal-lines-${businessId}`,
12936
13197
  Layer.getJournal(apiUrl, auth?.access_token, {
12937
13198
  params: { businessId }
@@ -13830,11 +14091,11 @@ var TasksContext = (0, import_react157.createContext)({
13830
14091
 
13831
14092
  // src/hooks/useTasks/useTasks.tsx
13832
14093
  var import_react158 = require("react");
13833
- var import_swr11 = __toESM(require("swr"));
14094
+ var import_swr10 = __toESM(require("swr"));
13834
14095
  var useTasks = () => {
13835
14096
  const [loadedStatus, setLoadedStatus] = (0, import_react158.useState)("initial");
13836
14097
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
13837
- const { data, isLoading, isValidating, error, mutate } = (0, import_swr11.default)(
14098
+ const { data, isLoading, isValidating, error, mutate } = (0, import_swr10.default)(
13838
14099
  businessId && auth?.access_token && `tasks-${businessId}`,
13839
14100
  Layer.getTasks(apiUrl, auth?.access_token, {
13840
14101
  params: { businessId }
@@ -14816,10 +15077,12 @@ var Components = ({
14816
15077
  AccountingOverview,
14817
15078
  BalanceSheet,
14818
15079
  BankTransactions,
15080
+ BankTransactionsProvider,
14819
15081
  BankTransactionsWithLinkedAccounts,
14820
15082
  BookkeepingOverview,
14821
15083
  BookkeepingUpsellBar,
14822
15084
  ChartOfAccounts,
15085
+ DisplayState,
14823
15086
  GeneralLedgerView,
14824
15087
  Journal,
14825
15088
  LayerProvider,