@layerfi/components 0.1.36 → 0.1.38

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/esm/index.js CHANGED
@@ -146,9 +146,11 @@ var getBalanceSheet = get(
146
146
  var getBankTransactions = get(
147
147
  ({
148
148
  businessId,
149
+ cursor,
150
+ categorized,
149
151
  sortBy = "date",
150
152
  sortOrder = "DESC"
151
- }) => `/v1/businesses/${businessId}/bank-transactions?sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
153
+ }) => `/v1/businesses/${businessId}/bank-transactions?${cursor ? `cursor=${cursor}&` : ""}${categorized !== void 0 && categorized !== "" ? `categorized=${categorized}&` : ""}sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
152
154
  );
153
155
  var categorizeBankTransaction = put(
154
156
  ({ businessId, bankTransactionId }) => `/v1/businesses/${businessId}/bank-transactions/${bankTransactionId}/categorize`
@@ -395,9 +397,9 @@ function useSizeClass() {
395
397
  const [width] = useWindowSize();
396
398
  const sizeClass = useMemo(() => {
397
399
  switch (true) {
398
- case width < BREAKPOINTS.MOBILE:
400
+ case width <= BREAKPOINTS.MOBILE:
399
401
  return "mobile";
400
- case width < BREAKPOINTS.TABLET:
402
+ case width <= BREAKPOINTS.TABLET:
401
403
  return "tablet";
402
404
  default:
403
405
  return "desktop";
@@ -549,8 +551,25 @@ var DEPENDENCIES = {
549
551
  ["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: ALL_TOUCHABLE
550
552
  };
551
553
  var useDataSync = () => {
552
- const [syncTimestamps, setSyncTimestamps] = useState2({});
553
- const [readTimestamps, setReadTimestamps] = useState2({});
554
+ const initialTimestamp = Date.now();
555
+ const [syncTimestamps, setSyncTimestamps] = useState2({
556
+ ["BALANCE_SHEET" /* BALANCE_SHEET */]: initialTimestamp,
557
+ ["CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */]: initialTimestamp,
558
+ ["JOURNAL" /* JOURNAL */]: initialTimestamp,
559
+ ["LEDGER_ACCOUNTS" /* LEDGER_ACCOUNTS */]: initialTimestamp,
560
+ ["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]: initialTimestamp,
561
+ ["PROFIT_AND_LOSS" /* PROFIT_AND_LOSS */]: initialTimestamp,
562
+ ["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: initialTimestamp
563
+ });
564
+ const [readTimestamps, setReadTimestamps] = useState2({
565
+ ["BALANCE_SHEET" /* BALANCE_SHEET */]: initialTimestamp,
566
+ ["CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */]: initialTimestamp,
567
+ ["JOURNAL" /* JOURNAL */]: initialTimestamp,
568
+ ["LEDGER_ACCOUNTS" /* LEDGER_ACCOUNTS */]: initialTimestamp,
569
+ ["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]: initialTimestamp,
570
+ ["PROFIT_AND_LOSS" /* PROFIT_AND_LOSS */]: initialTimestamp,
571
+ ["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: initialTimestamp
572
+ });
554
573
  const touch = (model) => {
555
574
  setSyncTimestamps({
556
575
  ...syncTimestamps,
@@ -612,6 +631,25 @@ import React6 from "react";
612
631
 
613
632
  // src/contexts/BankTransactionsContext/BankTransactionsContext.tsx
614
633
  import { createContext as createContext3, useContext as useContext4 } from "react";
634
+
635
+ // src/types/bank_transactions.ts
636
+ var Direction = /* @__PURE__ */ ((Direction3) => {
637
+ Direction3["CREDIT"] = "CREDIT";
638
+ Direction3["DEBIT"] = "DEBIT";
639
+ return Direction3;
640
+ })(Direction || {});
641
+ var DisplayState = /* @__PURE__ */ ((DisplayState2) => {
642
+ DisplayState2["review"] = "review";
643
+ DisplayState2["categorized"] = "categorized";
644
+ return DisplayState2;
645
+ })(DisplayState || {});
646
+
647
+ // src/types/categories.ts
648
+ function hasSuggestions(categorization) {
649
+ return categorization.suggestions !== void 0 && categorization.suggestions.length > 0;
650
+ }
651
+
652
+ // src/contexts/BankTransactionsContext/BankTransactionsContext.tsx
615
653
  var BankTransactionsContext = createContext3({
616
654
  data: void 0,
617
655
  isLoading: false,
@@ -629,26 +667,18 @@ var BankTransactionsContext = createContext3({
629
667
  pagination: void 0
630
668
  },
631
669
  updateOneLocal: () => void 0,
670
+ removeAfterCategorize: () => void 0,
632
671
  activate: () => void 0,
633
- display: "review" /* review */
672
+ display: "review" /* review */,
673
+ fetchMore: () => {
674
+ },
675
+ hasMore: false
634
676
  });
635
677
  var useBankTransactionsContext = () => useContext4(BankTransactionsContext);
636
678
 
637
679
  // src/hooks/useBankTransactions/useBankTransactions.tsx
638
680
  import { useEffect as useEffect2, useMemo as useMemo2, useState as useState4 } from "react";
639
681
 
640
- // src/types/bank_transactions.ts
641
- var Direction = /* @__PURE__ */ ((Direction3) => {
642
- Direction3["CREDIT"] = "CREDIT";
643
- Direction3["DEBIT"] = "DEBIT";
644
- return Direction3;
645
- })(Direction || {});
646
-
647
- // src/types/categories.ts
648
- function hasSuggestions(categorization) {
649
- return categorization.suggestions !== void 0 && categorization.suggestions.length > 0;
650
- }
651
-
652
682
  // src/components/BankTransactions/constants.ts
653
683
  var CategorizedCategories = [
654
684
  "CATEGORIZED" /* CATEGORIZED */,
@@ -669,7 +699,7 @@ var filterVisibility = (scope, bankTransaction) => {
669
699
  const inReview = ReviewCategories.includes(
670
700
  bankTransaction.categorization_status
671
701
  );
672
- return scope === "TO_REVIEW" /* TO_REVIEW */ && inReview || scope === "CATEGORIZED" /* CATEGORIZED */ && categorized;
702
+ return scope === "review" /* review */ && inReview || scope === "categorized" /* categorized */ && categorized;
673
703
  };
674
704
  var isCategorized = (bankTransaction) => CategorizedCategories.includes(bankTransaction.categorization_status);
675
705
 
@@ -718,7 +748,7 @@ var applyCategorizationStatusFilter = (data, filter) => {
718
748
  return data;
719
749
  }
720
750
  return data?.filter(
721
- (tx) => filterVisibility(filter, tx) || filter === "TO_REVIEW" /* TO_REVIEW */ && tx.recently_categorized || filter === "CATEGORIZED" /* CATEGORIZED */ && tx.recently_categorized
751
+ (tx) => filterVisibility(filter, tx) || filter === "review" /* review */ && tx.recently_categorized || filter === "categorized" /* categorized */ && tx.recently_categorized
722
752
  );
723
753
  };
724
754
  var appplyDateRangeFilter = (data, filter) => {
@@ -737,8 +767,8 @@ var appplyDateRangeFilter = (data, filter) => {
737
767
  };
738
768
 
739
769
  // src/hooks/useBankTransactions/useBankTransactions.tsx
740
- import useSWR from "swr";
741
- var useBankTransactions = () => {
770
+ import useSWRInfinite from "swr/infinite";
771
+ var useBankTransactions = (params) => {
742
772
  const {
743
773
  auth,
744
774
  businessId,
@@ -749,36 +779,82 @@ var useBankTransactions = () => {
749
779
  syncTimestamps,
750
780
  hasBeenTouched
751
781
  } = useLayerContext();
752
- const [loadingStatus, setLoadingStatus] = useState4("initial");
753
- const [filters, setTheFilters] = useState4();
754
- const [active, setActive] = useState4(false);
782
+ const { scope = void 0 } = params ?? {};
783
+ const [filters, setTheFilters] = useState4(
784
+ scope ? { categorizationStatus: scope } : void 0
785
+ );
755
786
  const display = useMemo2(() => {
756
- if (filters?.categorizationStatus === "TO_REVIEW" /* TO_REVIEW */) {
787
+ if (filters?.categorizationStatus === "review" /* review */) {
757
788
  return "review" /* review */;
758
789
  }
759
790
  return "categorized" /* categorized */;
760
791
  }, [filters?.categorizationStatus]);
761
- const queryKey = useMemo2(() => {
762
- if (!active) {
763
- return false;
764
- }
765
- return businessId && auth?.access_token && `bank-transactions-${businessId}`;
766
- }, [businessId, auth?.access_token, active]);
792
+ const [active, setActive] = useState4(false);
793
+ const [loadingStatus, setLoadingStatus] = useState4("initial");
794
+ const getKey = (_index, prevData) => {
795
+ if (!auth?.access_token || !active) {
796
+ return [false, void 0];
797
+ }
798
+ if (!prevData?.meta?.pagination?.cursor) {
799
+ return [
800
+ businessId && auth?.access_token && `bank-transactions${filters?.categorizationStatus ? `-scope-${filters?.categorizationStatus}` : ""}-${businessId}`,
801
+ void 0
802
+ ];
803
+ }
804
+ return [
805
+ businessId && auth?.access_token && `bank-transactions${filters?.categorizationStatus ? `-scope-${filters?.categorizationStatus}` : ""}-${businessId}-${prevData.meta.pagination.cursor}`,
806
+ prevData.meta.pagination.cursor
807
+ ];
808
+ };
767
809
  const {
768
- data: responseData,
810
+ data: rawResponseData,
769
811
  isLoading,
770
812
  isValidating,
771
813
  error: responseError,
772
- mutate
773
- } = useSWR(
774
- queryKey,
775
- Layer.getBankTransactions(apiUrl, auth?.access_token, {
776
- params: { businessId }
777
- })
814
+ mutate,
815
+ size,
816
+ setSize
817
+ } = useSWRInfinite(
818
+ getKey,
819
+ async ([query, nextCursor]) => {
820
+ if (auth?.access_token) {
821
+ return Layer.getBankTransactions(apiUrl, auth?.access_token, {
822
+ params: {
823
+ businessId,
824
+ cursor: nextCursor,
825
+ categorized: filters?.categorizationStatus ? filters?.categorizationStatus === "categorized" /* categorized */ ? "true" : "false" : ""
826
+ }
827
+ }).call(false);
828
+ }
829
+ return {};
830
+ },
831
+ {
832
+ initialSize: 1,
833
+ revalidateFirstPage: false
834
+ }
778
835
  );
836
+ const data = useMemo2(() => {
837
+ if (rawResponseData && rawResponseData.length > 0) {
838
+ return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
839
+ }
840
+ return void 0;
841
+ }, [rawResponseData]);
842
+ const lastMetadata = useMemo2(() => {
843
+ if (rawResponseData && rawResponseData.length > 0) {
844
+ return rawResponseData[rawResponseData.length - 1].meta;
845
+ }
846
+ return void 0;
847
+ }, [rawResponseData]);
848
+ const hasMore = useMemo2(() => {
849
+ if (rawResponseData && rawResponseData.length > 0) {
850
+ const lastElement = rawResponseData[rawResponseData.length - 1];
851
+ return Boolean(lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more);
852
+ }
853
+ return false;
854
+ }, [rawResponseData]);
779
855
  const accountsList = useMemo2(
780
- () => collectAccounts(responseData?.data),
781
- [responseData]
856
+ () => data ? collectAccounts(data) : [],
857
+ [data]
782
858
  );
783
859
  useEffect2(() => {
784
860
  if (isLoading && loadingStatus === "initial") {
@@ -799,13 +875,11 @@ var useBankTransactions = () => {
799
875
  ...value ?? {}
800
876
  });
801
877
  };
802
- const {
803
- data = void 0,
804
- meta: metadata = {},
805
- error = void 0
806
- } = responseData || {};
807
878
  const filteredData = useMemo2(() => {
808
879
  let filtered = data;
880
+ if (!filtered) {
881
+ return;
882
+ }
809
883
  if (filters?.amount?.min || filters?.amount?.max) {
810
884
  filtered = applyAmountFilter(filtered, filters.amount);
811
885
  }
@@ -825,7 +899,7 @@ var useBankTransactions = () => {
825
899
  filtered = appplyDateRangeFilter(filtered, filters?.dateRange);
826
900
  }
827
901
  return filtered;
828
- }, [filters, responseData]);
902
+ }, [filters, data]);
829
903
  const categorize = (id, newCategory, notify) => {
830
904
  const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
831
905
  if (foundBT) {
@@ -898,14 +972,31 @@ var useBankTransactions = () => {
898
972
  }).finally(() => touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */));
899
973
  };
900
974
  const updateOneLocal = (newBankTransaction) => {
901
- const updatedData = data?.map(
902
- (bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
903
- );
904
- mutate({ data: updatedData }, { revalidate: false });
975
+ const updatedData = rawResponseData?.map((page) => {
976
+ return {
977
+ ...page,
978
+ data: page.data?.map((bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt)
979
+ };
980
+ });
981
+ mutate(updatedData, { revalidate: false });
982
+ };
983
+ const removeAfterCategorize = (bankTransaction) => {
984
+ const updatedData = rawResponseData?.map((page) => {
985
+ return {
986
+ ...page,
987
+ data: page.data?.filter((bt) => bt.id !== bankTransaction.id)
988
+ };
989
+ });
990
+ mutate(updatedData, { revalidate: false });
905
991
  };
906
992
  const refetch = () => {
907
993
  mutate();
908
994
  };
995
+ const fetchMore = () => {
996
+ if (hasMore) {
997
+ setSize(size + 1);
998
+ }
999
+ };
909
1000
  useEffect2(() => {
910
1001
  if (isLoading || isValidating) {
911
1002
  read("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
@@ -918,20 +1009,23 @@ var useBankTransactions = () => {
918
1009
  }, [syncTimestamps]);
919
1010
  return {
920
1011
  data: filteredData,
921
- metadata,
1012
+ metadata: lastMetadata,
922
1013
  loadingStatus,
923
1014
  isLoading,
924
1015
  isValidating,
925
1016
  refetch,
926
- error: responseError || error,
1017
+ error: responseError,
927
1018
  categorize,
928
1019
  match,
929
1020
  updateOneLocal,
1021
+ removeAfterCategorize,
930
1022
  filters,
931
1023
  setFilters,
932
1024
  accountsList,
933
1025
  activate,
934
- display
1026
+ display,
1027
+ fetchMore,
1028
+ hasMore
935
1029
  };
936
1030
  };
937
1031
 
@@ -1184,7 +1278,7 @@ var hslToHex = (hsl) => {
1184
1278
 
1185
1279
  // src/providers/LayerProvider/LayerProvider.tsx
1186
1280
  import { add, isBefore } from "date-fns";
1187
- import useSWR2, { SWRConfig } from "swr";
1281
+ import useSWR, { SWRConfig } from "swr";
1188
1282
  var reducer = (state, action) => {
1189
1283
  switch (action.type) {
1190
1284
  case "LayerContext.setAuth" /* setAuth */:
@@ -1224,10 +1318,20 @@ var LayerEnvironment = {
1224
1318
  scope: "https://api.layerfi.com/production",
1225
1319
  apiUrl: "https://api.layerfi.com"
1226
1320
  },
1321
+ sandbox: {
1322
+ url: "https://auth.layerfi.com/oauth2/token",
1323
+ scope: "https://sandbox.layerfi.com/sandbox",
1324
+ apiUrl: "https://sandbox.layerfi.com"
1325
+ },
1227
1326
  staging: {
1228
1327
  url: "https://auth.layerfi.com/oauth2/token",
1229
1328
  scope: "https://sandbox.layerfi.com/sandbox",
1230
1329
  apiUrl: "https://sandbox.layerfi.com"
1330
+ },
1331
+ internalStaging: {
1332
+ url: "https://auth.layerfi.com/oauth2/token",
1333
+ scope: "https://sandbox.layerfi.com/sandbox",
1334
+ apiUrl: "https://staging.layerfi.com"
1231
1335
  }
1232
1336
  };
1233
1337
  var LayerProvider = ({
@@ -1269,7 +1373,7 @@ var LayerProvider = ({
1269
1373
  toasts: []
1270
1374
  });
1271
1375
  const { touch, syncTimestamps, read, readTimestamps, hasBeenTouched } = useDataSync();
1272
- const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR2(
1376
+ const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR(
1273
1377
  businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && isBefore(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
1274
1378
  Layer.authenticate({
1275
1379
  appId,
@@ -1304,7 +1408,7 @@ var LayerProvider = ({
1304
1408
  });
1305
1409
  }
1306
1410
  }, [businessAccessToken, auth?.access_token]);
1307
- useSWR2(
1411
+ useSWR(
1308
1412
  businessId && state.auth?.access_token && `categories-${businessId}`,
1309
1413
  Layer.getCategories(apiUrl, state.auth?.access_token, {
1310
1414
  params: { businessId }
@@ -1321,7 +1425,7 @@ var LayerProvider = ({
1321
1425
  }
1322
1426
  }
1323
1427
  );
1324
- useSWR2(
1428
+ useSWR(
1325
1429
  businessId && state?.auth?.access_token && `business-${businessId}`,
1326
1430
  Layer.getBusiness(apiUrl, state?.auth?.access_token, {
1327
1431
  params: { businessId }
@@ -1577,7 +1681,7 @@ var LINKED_ACCOUNTS_MOCK_DATA = [
1577
1681
  ];
1578
1682
 
1579
1683
  // src/hooks/useLinkedAccounts/useLinkedAccounts.ts
1580
- import useSWR3 from "swr";
1684
+ import useSWR2 from "swr";
1581
1685
  var DEBUG = true;
1582
1686
  var USE_MOCK_RESPONSE_DATA = false;
1583
1687
  var useLinkedAccounts = () => {
@@ -1601,7 +1705,7 @@ var useLinkedAccounts = () => {
1601
1705
  isValidating,
1602
1706
  error: responseError,
1603
1707
  mutate
1604
- } = useSWR3(
1708
+ } = useSWR2(
1605
1709
  businessId && auth?.access_token && `linked-accounts-${businessId}`,
1606
1710
  Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
1607
1711
  params: { businessId }
@@ -2122,15 +2226,13 @@ var countTransactionsToReview = ({
2122
2226
  };
2123
2227
  return transactions.filter((tx) => {
2124
2228
  try {
2125
- return filterVisibility("TO_REVIEW" /* TO_REVIEW */, tx) && isWithinInterval(parseISO2(tx.date), dateRangeInterval);
2229
+ return filterVisibility("review" /* review */, tx) && isWithinInterval(parseISO2(tx.date), dateRangeInterval);
2126
2230
  } catch (_err) {
2127
2231
  return false;
2128
2232
  }
2129
2233
  }).length;
2130
2234
  }
2131
- return transactions.filter(
2132
- (tx) => filterVisibility("TO_REVIEW" /* TO_REVIEW */, tx)
2133
- ).length;
2235
+ return transactions.filter((tx) => filterVisibility("review" /* review */, tx)).length;
2134
2236
  }
2135
2237
  return 0;
2136
2238
  };
@@ -3208,7 +3310,9 @@ var ConnectAccount = ({
3208
3310
  onTransactionsToReviewClick
3209
3311
  }) => {
3210
3312
  const { addConnection } = useContext5(LinkedAccountsContext);
3211
- const { data, isLoading } = useBankTransactions();
3313
+ const { data, isLoading } = useBankTransactions({
3314
+ scope: "review" /* review */
3315
+ });
3212
3316
  const transactionsToReview = useMemo3(
3213
3317
  () => countTransactionsToReview({ transactions: data }),
3214
3318
  [data, isLoading]
@@ -3824,15 +3928,21 @@ var LinkedAccountThumb = ({
3824
3928
  }) => {
3825
3929
  const linkedAccountThumbClassName = classNames19(
3826
3930
  "Layer__linked-account-thumb",
3827
- asWidget && "--as-widget"
3931
+ asWidget && "--as-widget",
3932
+ account.is_syncing && "--is-syncing",
3933
+ account.is_syncing && "skeleton-loader"
3934
+ );
3935
+ const linkedAccountInfoClassName = classNames19(
3936
+ "topbar",
3937
+ account.is_syncing && "--is-syncing"
3828
3938
  );
3829
3939
  let bankBalance;
3830
3940
  if (pillConfig) {
3831
3941
  bankBalance = /* @__PURE__ */ React53.createElement(LinkedAccountPill, { text: pillConfig.text, config: pillConfig.config });
3832
3942
  } else {
3833
- bankBalance = /* @__PURE__ */ React53.createElement(Text, { as: "span", className: "account-balance" }, account.is_syncing ? "Syncing..." : `${centsToDollars(account.latest_balance_timestamp?.balance)}`);
3943
+ bankBalance = /* @__PURE__ */ React53.createElement(Text, { as: "span", className: "account-balance" }, `${centsToDollars(account.latest_balance_timestamp?.balance)}`);
3834
3944
  }
3835
- return /* @__PURE__ */ React53.createElement("div", { className: linkedAccountThumbClassName }, /* @__PURE__ */ React53.createElement("div", { className: "topbar" }, /* @__PURE__ */ React53.createElement("div", { className: "topbar-details" }, /* @__PURE__ */ React53.createElement(Text, { as: "div", className: "account-name" }, account.external_account_name), !asWidget && account.mask && /* @__PURE__ */ React53.createElement(AccountNumber, { accountNumber: account.mask }), /* @__PURE__ */ React53.createElement(
3945
+ return /* @__PURE__ */ React53.createElement("div", { className: linkedAccountThumbClassName }, /* @__PURE__ */ React53.createElement("div", { className: linkedAccountInfoClassName }, /* @__PURE__ */ React53.createElement("div", { className: "topbar-details" }, /* @__PURE__ */ React53.createElement(Text, { as: "div", className: "account-name" }, account.external_account_name), !asWidget && account.mask && /* @__PURE__ */ React53.createElement(AccountNumber, { accountNumber: account.mask }), /* @__PURE__ */ React53.createElement(
3836
3946
  Text,
3837
3947
  {
3838
3948
  as: "span",
@@ -3848,7 +3958,7 @@ var LinkedAccountThumb = ({
3848
3958
  src: `data:image/png;base64,${account.institution.logo}`,
3849
3959
  alt: account.institution?.name
3850
3960
  }
3851
- ) : /* @__PURE__ */ React53.createElement(InstitutionIcon_default, null))), !asWidget && /* @__PURE__ */ React53.createElement("div", { className: "middlebar" }, /* @__PURE__ */ React53.createElement(
3961
+ ) : /* @__PURE__ */ React53.createElement(InstitutionIcon_default, null))), account.is_syncing ? /* @__PURE__ */ React53.createElement("div", { className: "loadingbar" }, /* @__PURE__ */ React53.createElement("div", { className: "loading-text Layer__text--sm" }, /* @__PURE__ */ React53.createElement("div", null, "Syncing account data"), /* @__PURE__ */ React53.createElement("div", { className: "syncing-data-description" }, "This may take up to 5 minutes")), /* @__PURE__ */ React53.createElement("div", { className: "loading-wrapper" }, /* @__PURE__ */ React53.createElement(Loader_default, { size: 11, className: "Layer__anim--rotating" }))) : /* @__PURE__ */ React53.createElement(React53.Fragment, null, !asWidget && /* @__PURE__ */ React53.createElement("div", { className: "middlebar" }, /* @__PURE__ */ React53.createElement(
3852
3962
  Text,
3853
3963
  {
3854
3964
  as: "span",
@@ -3864,7 +3974,7 @@ var LinkedAccountThumb = ({
3864
3974
  size: "sm"
3865
3975
  },
3866
3976
  "Ledger balance"
3867
- ), /* @__PURE__ */ React53.createElement(Text, { as: "span", className: "account-balance" }, account.is_syncing ? "Syncing..." : `${centsToDollars(account.current_ledger_balance)}`)));
3977
+ ), /* @__PURE__ */ React53.createElement(Text, { as: "span", className: "account-balance" }, `${centsToDollars(account.current_ledger_balance)}`))));
3868
3978
  };
3869
3979
 
3870
3980
  // src/components/LinkedAccounts/LinkedAccountsContent.tsx
@@ -5572,9 +5682,20 @@ var ExpandedBankTransactionRow = forwardRef5(
5572
5682
  });
5573
5683
  setSplitFormError(void 0);
5574
5684
  };
5685
+ const sanitizeNumberInput = (input) => {
5686
+ let sanitized = input.replace(/[^0-9.]/g, "");
5687
+ let parts = sanitized.split(".");
5688
+ if (parts.length > 2) {
5689
+ sanitized = parts[0] + "." + parts.slice(1).join("");
5690
+ }
5691
+ if (parts.length === 2) {
5692
+ sanitized = parts[0] + "." + parts[1].slice(0, 2);
5693
+ }
5694
+ return sanitized;
5695
+ };
5575
5696
  const updateAmounts = (rowNumber) => (event) => {
5576
- const newAmount = dollarsToCents(event.target.value) || 0;
5577
- const newDisplaying = event.target.value;
5697
+ const newDisplaying = sanitizeNumberInput(event.target.value);
5698
+ const newAmount = Number(newDisplaying);
5578
5699
  const splitTotal = rowState.splits.reduce((sum, split, index) => {
5579
5700
  const amount = index === 0 ? 0 : index === rowNumber ? newAmount : split.amount;
5580
5701
  return sum + amount;
@@ -6011,7 +6132,6 @@ var BankTransactionRow = ({
6011
6132
  }) => {
6012
6133
  const expandedRowRef = useRef10(null);
6013
6134
  const [showRetry, setShowRetry] = useState14(false);
6014
- const [removed, setRemoved] = useState14(false);
6015
6135
  const {
6016
6136
  filters,
6017
6137
  categorize: categorizeBankTransaction2,
@@ -6052,6 +6172,13 @@ var BankTransactionRow = ({
6052
6172
  setShowRetry(true);
6053
6173
  }
6054
6174
  }, [bankTransaction.error]);
6175
+ useEffect11(() => {
6176
+ if (editable && bankTransaction.recently_categorized) {
6177
+ setTimeout(() => {
6178
+ removeTransaction(bankTransaction);
6179
+ }, 300);
6180
+ }
6181
+ }, [bankTransaction.recently_categorized]);
6055
6182
  const save = async () => {
6056
6183
  if (open && expandedRowRef?.current) {
6057
6184
  expandedRowRef?.current?.save();
@@ -6074,9 +6201,6 @@ var BankTransactionRow = ({
6074
6201
  });
6075
6202
  setOpen(false);
6076
6203
  };
6077
- if (removed) {
6078
- return null;
6079
- }
6080
6204
  const categorized = isCategorized(bankTransaction);
6081
6205
  const className = "Layer__bank-transaction-row";
6082
6206
  const openClassName = open ? `${className}--expanded` : "";
@@ -6087,178 +6211,160 @@ var BankTransactionRow = ({
6087
6211
  initialLoad ? "initial-load" : "",
6088
6212
  showComponent ? "show" : ""
6089
6213
  );
6090
- return /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement(
6091
- "tr",
6214
+ return /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement("tr", { className: rowClassName }, /* @__PURE__ */ React81.createElement(
6215
+ "td",
6092
6216
  {
6093
- className: rowClassName,
6094
- onTransitionEnd: ({ propertyName }) => {
6095
- if (propertyName === "top") {
6096
- if (editable) {
6097
- setRemoved(true);
6098
- removeTransaction(bankTransaction.id);
6099
- }
6217
+ className: "Layer__table-cell Layer__bank-transaction-table__date-col",
6218
+ ...openRow
6219
+ },
6220
+ /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(parseISO7(bankTransaction.date), dateFormat))
6221
+ ), /* @__PURE__ */ React81.createElement(
6222
+ "td",
6223
+ {
6224
+ className: "Layer__table-cell Layer__bank-transactions__tx-col",
6225
+ ...openRow
6226
+ },
6227
+ /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React81.createElement(
6228
+ Text,
6229
+ {
6230
+ as: "span",
6231
+ className: "Layer__bank-transactions__tx-text",
6232
+ withTooltip: "whenTruncated" /* whenTruncated */,
6233
+ tooltipOptions: {
6234
+ contentClassName: "Layer__bank-transactions__tx-tooltip"
6100
6235
  }
6101
- }
6236
+ },
6237
+ bankTransaction.counterparty_name ?? bankTransaction.description
6238
+ ))
6239
+ ), /* @__PURE__ */ React81.createElement(
6240
+ "td",
6241
+ {
6242
+ className: "Layer__table-cell Layer__bank-transactions__account-col",
6243
+ ...openRow
6102
6244
  },
6103
- /* @__PURE__ */ React81.createElement(
6104
- "td",
6245
+ /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React81.createElement(
6246
+ Text,
6105
6247
  {
6106
- className: "Layer__table-cell Layer__bank-transaction-table__date-col",
6107
- ...openRow
6248
+ as: "span",
6249
+ className: "Layer__bank-transactions__account-text",
6250
+ withTooltip: "whenTruncated" /* whenTruncated */
6108
6251
  },
6109
- /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(parseISO7(bankTransaction.date), dateFormat))
6110
- ),
6252
+ bankTransaction.account_name ?? ""
6253
+ ))
6254
+ ), /* @__PURE__ */ React81.createElement(
6255
+ "td",
6256
+ {
6257
+ 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"}`,
6258
+ ...openRow
6259
+ },
6260
+ /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, isCredit(bankTransaction) ? "+$" : " $", centsToDollars(bankTransaction.amount))
6261
+ ), /* @__PURE__ */ React81.createElement(
6262
+ "td",
6263
+ {
6264
+ className: classNames33(
6265
+ "Layer__table-cell",
6266
+ "Layer__table-cell__category-col",
6267
+ `${className}__actions-cell`,
6268
+ `${className}__actions-cell--${open ? "open" : "close"}`
6269
+ )
6270
+ },
6111
6271
  /* @__PURE__ */ React81.createElement(
6112
- "td",
6272
+ "span",
6113
6273
  {
6114
- className: "Layer__table-cell Layer__bank-transactions__tx-col",
6115
- ...openRow
6274
+ className: `${className}__actions-container Layer__table-cell-content`
6116
6275
  },
6117
- /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React81.createElement(
6118
- Text,
6276
+ !categorized && !open ? /* @__PURE__ */ React81.createElement(
6277
+ CategorySelect,
6119
6278
  {
6120
- as: "span",
6121
- className: "Layer__bank-transactions__tx-text",
6122
- withTooltip: "whenTruncated" /* whenTruncated */,
6123
- tooltipOptions: {
6124
- contentClassName: "Layer__bank-transactions__tx-tooltip"
6125
- }
6279
+ bankTransaction,
6280
+ name: `category-${bankTransaction.id}`,
6281
+ value: selectedCategory,
6282
+ onChange: (category) => {
6283
+ setSelectedCategory(category);
6284
+ setShowRetry(false);
6285
+ },
6286
+ disabled: bankTransaction.processing
6287
+ }
6288
+ ) : null,
6289
+ categorized && !open ? /* @__PURE__ */ React81.createElement(Text, { as: "span", className: `${className}__category-text` }, bankTransaction.categorization_status === "SPLIT" /* SPLIT */ && /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement(
6290
+ Badge,
6291
+ {
6292
+ icon: /* @__PURE__ */ React81.createElement(Scissors_default, { size: 11 }),
6293
+ tooltip: /* @__PURE__ */ React81.createElement(
6294
+ SplitTooltipDetails,
6295
+ {
6296
+ classNamePrefix: className,
6297
+ category: bankTransaction.category
6298
+ }
6299
+ )
6126
6300
  },
6127
- bankTransaction.counterparty_name ?? bankTransaction.description
6128
- ))
6129
- ),
6130
- /* @__PURE__ */ React81.createElement(
6131
- "td",
6132
- {
6133
- className: "Layer__table-cell Layer__bank-transactions__account-col",
6134
- ...openRow
6135
- },
6136
- /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React81.createElement(
6301
+ "Split"
6302
+ ), /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, extractDescriptionForSplit(bankTransaction.category))), bankTransaction?.categorization_status === "MATCHED" /* MATCHED */ && bankTransaction?.match && /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement(
6303
+ MatchBadge,
6304
+ {
6305
+ classNamePrefix: className,
6306
+ bankTransaction,
6307
+ dateFormat
6308
+ }
6309
+ ), /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, `${formatTime5(
6310
+ parseISO7(bankTransaction.match.bank_transaction.date),
6311
+ dateFormat
6312
+ )}, ${bankTransaction.match?.details?.description}`)), bankTransaction?.categorization_status !== "MATCHED" /* MATCHED */ && bankTransaction?.categorization_status !== "SPLIT" /* SPLIT */ && /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, bankTransaction?.category?.display_name)) : null,
6313
+ !categorized && !open && showRetry ? /* @__PURE__ */ React81.createElement(
6314
+ RetryButton,
6315
+ {
6316
+ onClick: () => {
6317
+ if (!bankTransaction.processing) {
6318
+ save();
6319
+ }
6320
+ },
6321
+ className: "Layer__bank-transaction__retry-btn",
6322
+ processing: bankTransaction.processing,
6323
+ error: "Approval failed. Check connection and retry in few seconds."
6324
+ },
6325
+ "Retry"
6326
+ ) : null,
6327
+ open && bankTransaction.error ? /* @__PURE__ */ React81.createElement(
6137
6328
  Text,
6138
6329
  {
6139
6330
  as: "span",
6140
- className: "Layer__bank-transactions__account-text",
6141
- withTooltip: "whenTruncated" /* whenTruncated */
6331
+ size: "md" /* md */,
6332
+ className: "Layer__unsaved-info"
6142
6333
  },
6143
- bankTransaction.account_name ?? ""
6144
- ))
6145
- ),
6146
- /* @__PURE__ */ React81.createElement(
6147
- "td",
6148
- {
6149
- 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"}`,
6150
- ...openRow
6151
- },
6152
- /* @__PURE__ */ React81.createElement("span", { className: "Layer__table-cell-content" }, isCredit(bankTransaction) ? "+$" : " $", centsToDollars(bankTransaction.amount))
6153
- ),
6154
- /* @__PURE__ */ React81.createElement(
6155
- "td",
6156
- {
6157
- className: classNames33(
6158
- "Layer__table-cell",
6159
- "Layer__table-cell__category-col",
6160
- `${className}__actions-cell`,
6161
- `${className}__actions-cell--${open ? "open" : "close"}`
6162
- )
6163
- },
6164
- /* @__PURE__ */ React81.createElement(
6165
- "span",
6334
+ /* @__PURE__ */ React81.createElement("span", null, "Unsaved"),
6335
+ /* @__PURE__ */ React81.createElement(AlertCircle_default, { size: 12 })
6336
+ ) : null,
6337
+ !categorized && (open || !open && !showRetry) || categorized && open ? /* @__PURE__ */ React81.createElement(
6338
+ SubmitButton,
6166
6339
  {
6167
- className: `${className}__actions-container Layer__table-cell-content`
6168
- },
6169
- !categorized && !open ? /* @__PURE__ */ React81.createElement(
6170
- CategorySelect,
6171
- {
6172
- bankTransaction,
6173
- name: `category-${bankTransaction.id}`,
6174
- value: selectedCategory,
6175
- onChange: (category) => {
6176
- setSelectedCategory(category);
6177
- setShowRetry(false);
6178
- },
6179
- disabled: bankTransaction.processing
6180
- }
6181
- ) : null,
6182
- categorized && !open ? /* @__PURE__ */ React81.createElement(Text, { as: "span", className: `${className}__category-text` }, bankTransaction.categorization_status === "SPLIT" /* SPLIT */ && /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement(
6183
- Badge,
6184
- {
6185
- icon: /* @__PURE__ */ React81.createElement(Scissors_default, { size: 11 }),
6186
- tooltip: /* @__PURE__ */ React81.createElement(
6187
- SplitTooltipDetails,
6188
- {
6189
- classNamePrefix: className,
6190
- category: bankTransaction.category
6191
- }
6192
- )
6193
- },
6194
- "Split"
6195
- ), /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, extractDescriptionForSplit(bankTransaction.category))), bankTransaction?.categorization_status === "MATCHED" /* MATCHED */ && bankTransaction?.match && /* @__PURE__ */ React81.createElement(React81.Fragment, null, /* @__PURE__ */ React81.createElement(
6196
- MatchBadge,
6197
- {
6198
- classNamePrefix: className,
6199
- bankTransaction,
6200
- dateFormat
6201
- }
6202
- ), /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, `${formatTime5(
6203
- parseISO7(bankTransaction.match.bank_transaction.date),
6204
- dateFormat
6205
- )}, ${bankTransaction.match?.details?.description}`)), bankTransaction?.categorization_status !== "MATCHED" /* MATCHED */ && bankTransaction?.categorization_status !== "SPLIT" /* SPLIT */ && /* @__PURE__ */ React81.createElement("span", { className: `${className}__category-text__text` }, bankTransaction?.category?.display_name)) : null,
6206
- !categorized && !open && showRetry ? /* @__PURE__ */ React81.createElement(
6207
- RetryButton,
6208
- {
6209
- onClick: () => {
6210
- if (!bankTransaction.processing) {
6211
- save();
6212
- }
6213
- },
6214
- className: "Layer__bank-transaction__retry-btn",
6215
- processing: bankTransaction.processing,
6216
- error: "Approval failed. Check connection and retry in few seconds."
6217
- },
6218
- "Retry"
6219
- ) : null,
6220
- open && bankTransaction.error ? /* @__PURE__ */ React81.createElement(
6221
- Text,
6222
- {
6223
- as: "span",
6224
- size: "md" /* md */,
6225
- className: "Layer__unsaved-info"
6226
- },
6227
- /* @__PURE__ */ React81.createElement("span", null, "Unsaved"),
6228
- /* @__PURE__ */ React81.createElement(AlertCircle_default, { size: 12 })
6229
- ) : null,
6230
- !categorized && (open || !open && !showRetry) || categorized && open ? /* @__PURE__ */ React81.createElement(
6231
- SubmitButton,
6232
- {
6233
- onClick: () => {
6234
- if (!bankTransaction.processing) {
6235
- save();
6236
- }
6237
- },
6238
- className: "Layer__bank-transaction__submit-btn",
6239
- processing: bankTransaction.processing,
6240
- active: open,
6241
- action: categorized ? "save" /* SAVE */ : "update" /* UPDATE */
6340
+ onClick: () => {
6341
+ if (!bankTransaction.processing) {
6342
+ save();
6343
+ }
6242
6344
  },
6243
- categorized ? "Update" : "Approve"
6244
- ) : null,
6245
- /* @__PURE__ */ React81.createElement(
6246
- IconButton,
6247
- {
6248
- onClick: toggleOpen,
6249
- className: "Layer__bank-transaction-row__expand-button",
6250
- active: open,
6251
- icon: /* @__PURE__ */ React81.createElement(
6252
- ChevronDownFill_default,
6253
- {
6254
- className: `Layer__chevron ${open ? "Layer__chevron__up" : "Layer__chevron__down"}`
6255
- }
6256
- )
6257
- }
6258
- )
6345
+ className: "Layer__bank-transaction__submit-btn",
6346
+ processing: bankTransaction.processing,
6347
+ active: open,
6348
+ action: categorized ? "save" /* SAVE */ : "update" /* UPDATE */
6349
+ },
6350
+ categorized ? "Update" : "Approve"
6351
+ ) : null,
6352
+ /* @__PURE__ */ React81.createElement(
6353
+ IconButton,
6354
+ {
6355
+ onClick: toggleOpen,
6356
+ className: "Layer__bank-transaction-row__expand-button",
6357
+ active: open,
6358
+ icon: /* @__PURE__ */ React81.createElement(
6359
+ ChevronDownFill_default,
6360
+ {
6361
+ className: `Layer__chevron ${open ? "Layer__chevron__up" : "Layer__chevron__down"}`
6362
+ }
6363
+ )
6364
+ }
6259
6365
  )
6260
6366
  )
6261
- ), /* @__PURE__ */ React81.createElement("tr", null, /* @__PURE__ */ React81.createElement("td", { colSpan: 5, className: "Layer__bank-transaction-row__expanded-td" }, /* @__PURE__ */ React81.createElement(
6367
+ )), /* @__PURE__ */ React81.createElement("tr", null, /* @__PURE__ */ React81.createElement("td", { colSpan: 5, className: "Layer__bank-transaction-row__expanded-td" }, /* @__PURE__ */ React81.createElement(
6262
6368
  ExpandedBankTransactionRow,
6263
6369
  {
6264
6370
  ref: expandedRowRef,
@@ -6320,11 +6426,11 @@ var BankTransactionListItem = ({
6320
6426
  editable,
6321
6427
  showDescriptions,
6322
6428
  showReceiptUploads,
6323
- containerWidth
6429
+ containerWidth,
6430
+ removeTransaction
6324
6431
  }) => {
6325
6432
  const expandedRowRef = useRef11(null);
6326
6433
  const [showRetry, setShowRetry] = useState15(false);
6327
- const [removed, setRemoved] = useState15(false);
6328
6434
  const { categorize: categorizeBankTransaction2, match: matchBankTransaction2 } = useBankTransactionsContext();
6329
6435
  const [selectedCategory, setSelectedCategory] = useState15(
6330
6436
  getDefaultSelectedCategory(bankTransaction)
@@ -6346,6 +6452,13 @@ var BankTransactionListItem = ({
6346
6452
  setShowRetry(true);
6347
6453
  }
6348
6454
  }, [bankTransaction.error]);
6455
+ useEffect12(() => {
6456
+ if (editable && bankTransaction.recently_categorized) {
6457
+ setTimeout(() => {
6458
+ removeTransaction(bankTransaction);
6459
+ }, 300);
6460
+ }
6461
+ }, [bankTransaction.recently_categorized]);
6349
6462
  const save = () => {
6350
6463
  if (open && expandedRowRef?.current) {
6351
6464
  expandedRowRef?.current?.save();
@@ -6363,9 +6476,6 @@ var BankTransactionListItem = ({
6363
6476
  category: getCategorizePayload(selectedCategory)
6364
6477
  });
6365
6478
  };
6366
- if (removed) {
6367
- return null;
6368
- }
6369
6479
  const categorized = isCategorized(bankTransaction);
6370
6480
  const className = "Layer__bank-transaction-list-item";
6371
6481
  const openClassName = open ? `${className}--expanded` : "";
@@ -6564,7 +6674,15 @@ var BusinessForm = ({ bankTransaction }) => {
6564
6674
  onClick: onCategorySelect,
6565
6675
  selected: selectedCategory
6566
6676
  }
6567
- ), options.length === 0 ? /* @__PURE__ */ React85.createElement(Button, { onClick: openDrawer, fullWidth: true }, "Select category") : null, options.length > 0 ? /* @__PURE__ */ React85.createElement(
6677
+ ), options.length === 0 ? /* @__PURE__ */ React85.createElement(
6678
+ Button,
6679
+ {
6680
+ onClick: openDrawer,
6681
+ fullWidth: true,
6682
+ variant: "secondary" /* secondary */
6683
+ },
6684
+ "Select category"
6685
+ ) : null, options.length > 0 ? /* @__PURE__ */ React85.createElement(
6568
6686
  Button,
6569
6687
  {
6570
6688
  onClick: save,
@@ -6985,8 +7103,12 @@ var BankTransactionMobileListItem = ({
6985
7103
  }, [transactionIdToOpen]);
6986
7104
  useEffect17(() => {
6987
7105
  if (!removeAnim && bankTransaction.recently_categorized) {
6988
- setRemoveAnim(true);
6989
- openNext();
7106
+ if (editable) {
7107
+ setRemoveAnim(true);
7108
+ openNext();
7109
+ } else {
7110
+ close();
7111
+ }
6990
7112
  }
6991
7113
  }, [
6992
7114
  bankTransaction.recently_categorized,
@@ -7013,6 +7135,13 @@ var BankTransactionMobileListItem = ({
7013
7135
  setShowComponent(true);
7014
7136
  }
7015
7137
  }, []);
7138
+ useEffect17(() => {
7139
+ if (editable && bankTransaction.recently_categorized) {
7140
+ setTimeout(() => {
7141
+ removeTransaction(bankTransaction);
7142
+ }, 300);
7143
+ }
7144
+ }, [bankTransaction.recently_categorized]);
7016
7145
  const onChangePurpose = (event) => setPurpose(event.target.value);
7017
7146
  const categorized = isCategorized(bankTransaction);
7018
7147
  const className = "Layer__bank-transaction-mobile-list-item";
@@ -7028,18 +7157,7 @@ var BankTransactionMobileListItem = ({
7028
7157
  {
7029
7158
  ref: itemRef,
7030
7159
  className: rowClassName,
7031
- "data-item": bankTransaction.id,
7032
- onTransitionEnd: ({ propertyName }) => {
7033
- if (propertyName === "opacity") {
7034
- close();
7035
- if (editable) {
7036
- setRemoveAnim(false);
7037
- setTimeout(() => {
7038
- removeTransaction(bankTransaction.id);
7039
- }, 500);
7040
- }
7041
- }
7042
- }
7160
+ "data-item": bankTransaction.id
7043
7161
  },
7044
7162
  /* @__PURE__ */ React91.createElement(
7045
7163
  "span",
@@ -7058,7 +7176,7 @@ var BankTransactionMobileListItem = ({
7058
7176
  centsToDollars(bankTransaction.amount)
7059
7177
  ), /* @__PURE__ */ React91.createElement("span", { className: `${className}__heading__date` }, formatTime8(parseISO10(bankTransaction.date), DATE_FORMAT2))))
7060
7178
  ),
7061
- /* @__PURE__ */ React91.createElement("div", { className: `${className}__expanded-row`, style: { height } }, open && /* @__PURE__ */ React91.createElement(
7179
+ /* @__PURE__ */ React91.createElement("div", { className: `${className}__expanded-row`, style: { height: !open || removeAnim ? 0 : height } }, open && /* @__PURE__ */ React91.createElement(
7062
7180
  "div",
7063
7181
  {
7064
7182
  className: `${className}__expanded-row__content`,
@@ -7284,7 +7402,9 @@ var Pagination = ({
7284
7402
  totalCount,
7285
7403
  siblingCount = 1,
7286
7404
  currentPage,
7287
- pageSize
7405
+ pageSize,
7406
+ hasMore,
7407
+ fetchMore
7288
7408
  }) => {
7289
7409
  const paginationRange = usePagination({
7290
7410
  currentPage,
@@ -7333,12 +7453,23 @@ var Pagination = ({
7333
7453
  onClick: () => {
7334
7454
  if (typeof pageNumber === "number") {
7335
7455
  onPageChange(pageNumber);
7456
+ if (pageNumber === lastPage && hasMore && fetchMore) {
7457
+ fetchMore();
7458
+ }
7336
7459
  }
7337
7460
  }
7338
7461
  },
7339
7462
  pageNumber
7340
7463
  );
7341
- }), /* @__PURE__ */ React97.createElement(
7464
+ }), hasMore && fetchMore ? /* @__PURE__ */ React97.createElement(
7465
+ "li",
7466
+ {
7467
+ key: `page-has-more`,
7468
+ className: "Layer__pagination-item Layer__pagination-arrow Layer__pagination-arrow--next",
7469
+ onClick: fetchMore
7470
+ },
7471
+ "..."
7472
+ ) : null, /* @__PURE__ */ React97.createElement(
7342
7473
  "li",
7343
7474
  {
7344
7475
  key: `page-last`,
@@ -7400,7 +7531,7 @@ var DownloadCloud = ({ size = 18, ...props }) => /* @__PURE__ */ React98.createE
7400
7531
  var DownloadCloud_default = DownloadCloud;
7401
7532
 
7402
7533
  // src/utils/business.ts
7403
- import { differenceInCalendarMonths, parseISO as parseISO11, startOfMonth as startOfMonth2 } from "date-fns";
7534
+ import { differenceInCalendarMonths, parseISO as parseISO11, startOfMonth } from "date-fns";
7404
7535
  var getActivationDate = (business) => {
7405
7536
  try {
7406
7537
  if (business && business.activation_at) {
@@ -7414,7 +7545,7 @@ var getActivationDate = (business) => {
7414
7545
  var getEarliestDateToBrowse = (business) => {
7415
7546
  const activationDate = getActivationDate(business);
7416
7547
  if (activationDate) {
7417
- return startOfMonth2(activationDate);
7548
+ return startOfMonth(activationDate);
7418
7549
  }
7419
7550
  return;
7420
7551
  };
@@ -7426,24 +7557,26 @@ var isDateAllowedToBrowse = (date, business) => {
7426
7557
  if (!activationDate) {
7427
7558
  return true;
7428
7559
  }
7429
- return differenceInCalendarMonths(startOfMonth2(date), activationDate) >= 0;
7560
+ return differenceInCalendarMonths(startOfMonth(date), activationDate) >= 0;
7430
7561
  };
7431
7562
 
7432
7563
  // src/components/DatePicker/DatePicker.tsx
7433
- import React100, { useEffect as useEffect18, useState as useState23 } from "react";
7564
+ import React100, { useEffect as useEffect18, useRef as useRef13, useState as useState23 } from "react";
7434
7565
  import ReactDatePicker from "react-datepicker";
7435
7566
  import "react-datepicker/dist/react-datepicker.css";
7436
7567
 
7437
7568
  // src/components/DatePicker/DatePickerOptions.tsx
7438
7569
  import React99 from "react";
7439
7570
  import {
7440
- endOfMonth as endOfMonth2,
7571
+ endOfMonth,
7441
7572
  endOfQuarter,
7442
7573
  endOfYear,
7443
- startOfMonth as startOfMonth3,
7574
+ startOfMonth as startOfMonth2,
7444
7575
  startOfQuarter,
7445
7576
  startOfYear,
7446
- subMonths
7577
+ subMonths,
7578
+ subQuarters,
7579
+ subYears
7447
7580
  } from "date-fns";
7448
7581
  var DatePickerOptions = ({
7449
7582
  options,
@@ -7459,8 +7592,8 @@ var DatePickerOptions = ({
7459
7592
  key: option,
7460
7593
  onClick: () => {
7461
7594
  setSelectedDate([
7462
- startOfMonth3(/* @__PURE__ */ new Date()),
7463
- endOfMonth2(/* @__PURE__ */ new Date())
7595
+ startOfMonth2(/* @__PURE__ */ new Date()),
7596
+ endOfMonth(/* @__PURE__ */ new Date())
7464
7597
  ]);
7465
7598
  }
7466
7599
  },
@@ -7473,8 +7606,8 @@ var DatePickerOptions = ({
7473
7606
  key: option,
7474
7607
  onClick: () => {
7475
7608
  setSelectedDate([
7476
- startOfMonth3(subMonths(/* @__PURE__ */ new Date(), 1)),
7477
- endOfMonth2(subMonths(/* @__PURE__ */ new Date(), 1))
7609
+ startOfMonth2(subMonths(/* @__PURE__ */ new Date(), 1)),
7610
+ endOfMonth(subMonths(/* @__PURE__ */ new Date(), 1))
7478
7611
  ]);
7479
7612
  }
7480
7613
  },
@@ -7494,6 +7627,21 @@ var DatePickerOptions = ({
7494
7627
  },
7495
7628
  "This quarter"
7496
7629
  );
7630
+ case "last-quarter":
7631
+ return /* @__PURE__ */ React99.createElement(
7632
+ TextButton,
7633
+ {
7634
+ key: option,
7635
+ onClick: () => {
7636
+ const lastQuarter = subQuarters(/* @__PURE__ */ new Date(), 1);
7637
+ setSelectedDate([
7638
+ startOfQuarter(lastQuarter),
7639
+ endOfQuarter(lastQuarter)
7640
+ ]);
7641
+ }
7642
+ },
7643
+ "Last quarter"
7644
+ );
7497
7645
  case "this-year":
7498
7646
  return /* @__PURE__ */ React99.createElement(
7499
7647
  TextButton,
@@ -7505,11 +7653,30 @@ var DatePickerOptions = ({
7505
7653
  },
7506
7654
  "This year"
7507
7655
  );
7656
+ case "last-year":
7657
+ return /* @__PURE__ */ React99.createElement(
7658
+ TextButton,
7659
+ {
7660
+ key: option,
7661
+ onClick: () => {
7662
+ const lastYear = subYears(/* @__PURE__ */ new Date(), 1);
7663
+ setSelectedDate([startOfYear(lastYear), endOfYear(lastYear)]);
7664
+ }
7665
+ },
7666
+ "Last year"
7667
+ );
7508
7668
  }
7509
7669
  return /* @__PURE__ */ React99.createElement(React99.Fragment, null);
7510
7670
  };
7511
7671
  if (options.length === 0) {
7512
- const allOptions = ["this-month", "last-month", "this-quarter", "this-year"];
7672
+ const allOptions = [
7673
+ "this-month",
7674
+ "last-month",
7675
+ "this-quarter",
7676
+ "last-quarter",
7677
+ "this-year",
7678
+ "last-year"
7679
+ ];
7513
7680
  allOptions.forEach((option) => {
7514
7681
  optionsComponents.push(getOptionComponent(option));
7515
7682
  });
@@ -7526,11 +7693,25 @@ var DatePickerOptions = ({
7526
7693
 
7527
7694
  // src/components/DatePicker/DatePicker.tsx
7528
7695
  import classNames37 from "classnames";
7696
+ var getDefaultRangeDate = (date, mode, selected) => {
7697
+ try {
7698
+ if (isRangeMode(mode) && selected) {
7699
+ if (date === "end") {
7700
+ return selected[1];
7701
+ }
7702
+ return selected[0];
7703
+ }
7704
+ return null;
7705
+ } catch (_err) {
7706
+ return null;
7707
+ }
7708
+ };
7709
+ var isRangeMode = (mode) => mode === "dayRangePicker" || mode === "monthRangePicker";
7529
7710
  var DatePicker = ({
7530
7711
  selected,
7531
7712
  onChange,
7532
7713
  mode = "dayPicker",
7533
- dateFormat = mode === "monthPicker" || mode === "monthRangePicker" ? "MMMM, yyyy" : mode === "timePicker" ? "h:mm aa" : "MMMM d, yyyy",
7714
+ dateFormat = mode === "monthPicker" || mode === "monthRangePicker" ? "MMM, yyyy" : mode === "timePicker" ? "h:mm aa" : "MMM d, yyyy",
7534
7715
  timeIntervals = 15,
7535
7716
  timeCaption,
7536
7717
  placeholderText,
@@ -7539,15 +7720,38 @@ var DatePicker = ({
7539
7720
  calendarClassName,
7540
7721
  popperClassName,
7541
7722
  minDate,
7723
+ maxDate = /* @__PURE__ */ new Date(),
7542
7724
  currentDateOption = true,
7725
+ navigateArrows = mode === "monthPicker",
7543
7726
  ...props
7544
7727
  }) => {
7728
+ const pickerRef = useRef13(null);
7545
7729
  const [updatePickerDate, setPickerDate] = useState23(false);
7546
7730
  const [selectedDates, setSelectedDates] = useState23(selected);
7731
+ const { isDesktop } = useSizeClass();
7732
+ const [startDate, setStartDate] = useState23(
7733
+ getDefaultRangeDate("start", mode, selected) ?? /* @__PURE__ */ new Date()
7734
+ );
7735
+ const [endDate, setEndDate] = useState23(
7736
+ getDefaultRangeDate("end", mode, selected)
7737
+ );
7547
7738
  useEffect18(() => {
7548
- setPickerDate(true);
7549
- if (selected !== selectedDates) {
7550
- setSelectedDates(selected);
7739
+ try {
7740
+ setPickerDate(true);
7741
+ if (!isRangeMode(mode) && selected !== selectedDates) {
7742
+ setSelectedDates(selected);
7743
+ return;
7744
+ }
7745
+ if (isRangeMode(mode) && Array.isArray(selected)) {
7746
+ if (startDate !== selected[0]) {
7747
+ setStartDate(selected[0]);
7748
+ }
7749
+ if (endDate !== selected[1]) {
7750
+ setEndDate(selected[1]);
7751
+ }
7752
+ }
7753
+ } catch (_err) {
7754
+ return;
7551
7755
  }
7552
7756
  }, [selected]);
7553
7757
  useEffect18(() => {
@@ -7557,9 +7761,15 @@ var DatePicker = ({
7557
7761
  setPickerDate(false);
7558
7762
  }
7559
7763
  }, [selectedDates]);
7764
+ useEffect18(() => {
7765
+ if (isRangeMode(mode)) {
7766
+ setSelectedDates([startDate, endDate]);
7767
+ }
7768
+ }, [startDate, endDate]);
7560
7769
  const wrapperClassNames = classNames37(
7561
7770
  "Layer__datepicker__wrapper",
7562
- mode === "timePicker" && "Layer__datepicker__time__wrapper"
7771
+ mode === "timePicker" && "Layer__datepicker__time__wrapper",
7772
+ navigateArrows && "Layer__datepicker__wrapper--arrows"
7563
7773
  );
7564
7774
  const datePickerWrapperClassNames = classNames37(
7565
7775
  "Layer__datepicker",
@@ -7572,9 +7782,16 @@ var DatePicker = ({
7572
7782
  );
7573
7783
  const popperClassNames = classNames37(
7574
7784
  "Layer__datepicker__popper",
7785
+ mode === "timePicker" && "Layer__datepicker__time__popper",
7575
7786
  popperClassName
7576
7787
  );
7577
7788
  const handleDateChange = (date) => {
7789
+ if (isRangeMode(mode)) {
7790
+ const [start, end] = date;
7791
+ setStartDate(start);
7792
+ setEndDate(end);
7793
+ return;
7794
+ }
7578
7795
  setSelectedDates(date);
7579
7796
  };
7580
7797
  const isCurrentDate = () => {
@@ -7596,28 +7813,77 @@ var DatePicker = ({
7596
7813
  );
7597
7814
  }
7598
7815
  };
7816
+ const isTodayOrAfter = Boolean(
7817
+ selectedDates instanceof Date && selectedDates >= /* @__PURE__ */ new Date()
7818
+ );
7819
+ const isBeforeMinDate = Boolean(
7820
+ minDate && selectedDates instanceof Date && selectedDates <= minDate
7821
+ );
7822
+ const changeDate = (value) => {
7823
+ if (mode === "dayPicker") {
7824
+ setSelectedDates(
7825
+ new Date(
7826
+ selectedDates.setDate(
7827
+ selectedDates.getDate() + value
7828
+ )
7829
+ )
7830
+ );
7831
+ } else if (mode === "monthPicker") {
7832
+ setSelectedDates(
7833
+ new Date(
7834
+ selectedDates.setMonth(
7835
+ selectedDates.getMonth() + value
7836
+ )
7837
+ )
7838
+ );
7839
+ }
7840
+ };
7599
7841
  return /* @__PURE__ */ React100.createElement("div", { className: wrapperClassNames }, /* @__PURE__ */ React100.createElement(
7600
7842
  ReactDatePicker,
7601
7843
  {
7844
+ ref: pickerRef,
7602
7845
  wrapperClassName: datePickerWrapperClassNames,
7603
- startDate: mode === "dayRangePicker" || mode === "monthRangePicker" ? selectedDates[0] : void 0,
7604
- endDate: mode === "dayRangePicker" || mode === "monthRangePicker" ? selectedDates[1] : void 0,
7846
+ startDate: isRangeMode(mode) ? startDate : void 0,
7847
+ endDate: isRangeMode(mode) ? endDate : void 0,
7605
7848
  selected: mode !== "dayRangePicker" && mode !== "monthRangePicker" ? selectedDates : void 0,
7606
7849
  onChange: handleDateChange,
7607
7850
  calendarClassName: calendarClassNames,
7608
7851
  popperClassName: popperClassNames,
7609
7852
  enableTabLoop: false,
7610
7853
  popperPlacement: "bottom-start",
7611
- selectsRange: mode === "dayRangePicker" || mode === "monthRangePicker",
7854
+ selectsRange: isRangeMode(mode),
7612
7855
  showMonthYearPicker: mode === "monthPicker" || mode === "monthRangePicker",
7613
7856
  dateFormat,
7614
7857
  renderDayContents: (day) => /* @__PURE__ */ React100.createElement("span", { className: "Layer__datepicker__day-contents" }, day),
7615
7858
  timeIntervals,
7616
7859
  timeCaption,
7860
+ timeFormat: "h mm aa",
7617
7861
  showTimeSelect: mode === "timePicker",
7618
7862
  showTimeSelectOnly: mode === "timePicker",
7619
7863
  minDate,
7620
- maxDate: /* @__PURE__ */ new Date(),
7864
+ maxDate,
7865
+ withPortal: !isDesktop,
7866
+ onCalendarOpen: () => {
7867
+ if (!isDesktop) {
7868
+ setTimeout(() => {
7869
+ document.getElementById("Layer__datepicker__portal")?.classList.remove("Layer__datepicker__portal--closed");
7870
+ document.getElementById("Layer__datepicker__portal")?.classList.add("Layer__datepicker__portal--opened");
7871
+ }, 10);
7872
+ }
7873
+ },
7874
+ onCalendarClose: () => {
7875
+ if (!isDesktop) {
7876
+ document.getElementById("Layer__datepicker__portal")?.classList.add("Layer__datepicker__portal--closed");
7877
+ document.getElementById("Layer__datepicker__portal")?.classList.remove("Layer__datepicker__portal--opened");
7878
+ }
7879
+ },
7880
+ portalId: "Layer__datepicker__portal",
7881
+ onFocus: (e) => e.target.readOnly = true,
7882
+ onInputClick: () => {
7883
+ if (pickerRef.current && !isDesktop) {
7884
+ pickerRef.current.setOpen(!pickerRef.current.isCalendarOpen);
7885
+ }
7886
+ },
7621
7887
  ...props
7622
7888
  },
7623
7889
  mode === "dayRangePicker" && /* @__PURE__ */ React100.createElement(
@@ -7627,7 +7893,39 @@ var DatePicker = ({
7627
7893
  setSelectedDate: setSelectedDates
7628
7894
  }
7629
7895
  )
7630
- ), currentDateOption && (mode === "dayPicker" || mode === "monthPicker") && /* @__PURE__ */ React100.createElement(
7896
+ ), navigateArrows && !isDesktop && /* @__PURE__ */ React100.createElement(React100.Fragment, null, /* @__PURE__ */ React100.createElement(
7897
+ Button,
7898
+ {
7899
+ "aria-label": "Previous Date",
7900
+ className: classNames37(
7901
+ "Layer__datepicker__prev-button",
7902
+ isBeforeMinDate && "Layer__datepicker__button--disabled"
7903
+ ),
7904
+ onClick: () => changeDate(-1),
7905
+ variant: "secondary" /* secondary */,
7906
+ disabled: isBeforeMinDate
7907
+ },
7908
+ /* @__PURE__ */ React100.createElement(ChevronLeft_default, { className: "Layer__datepicker__button-icon", size: 16 })
7909
+ ), /* @__PURE__ */ React100.createElement(
7910
+ Button,
7911
+ {
7912
+ "aria-label": "Next Date",
7913
+ variant: "secondary" /* secondary */,
7914
+ className: classNames37(
7915
+ "Layer__datepicker__next-button",
7916
+ isTodayOrAfter ? "Layer__datepicker__button--disabled" : void 0
7917
+ ),
7918
+ onClick: () => changeDate(1),
7919
+ disabled: isTodayOrAfter
7920
+ },
7921
+ /* @__PURE__ */ React100.createElement(
7922
+ ChevronRight_default,
7923
+ {
7924
+ className: "Layer__datepicker__button-icon",
7925
+ size: 16
7926
+ }
7927
+ )
7928
+ )), currentDateOption && (mode === "dayPicker" || mode === "monthPicker") && /* @__PURE__ */ React100.createElement(
7631
7929
  Button,
7632
7930
  {
7633
7931
  className: "Layer__datepicker__current-button",
@@ -7755,7 +8053,7 @@ var Tabs = ({ name, options, selected, onChange }) => {
7755
8053
 
7756
8054
  // src/components/BankTransactions/BankTransactionsHeader.tsx
7757
8055
  import classNames39 from "classnames";
7758
- import { endOfMonth as endOfMonth3, startOfMonth as startOfMonth4 } from "date-fns";
8056
+ import { endOfMonth as endOfMonth2, startOfMonth as startOfMonth3 } from "date-fns";
7759
8057
  var DownloadButton = () => {
7760
8058
  const { auth, businessId, apiUrl } = useLayerContext();
7761
8059
  const [requestFailed, setRequestFailed] = useState25(false);
@@ -7840,8 +8138,8 @@ var BankTransactionsHeader = ({
7840
8138
  onChange: (date) => {
7841
8139
  if (!Array.isArray(date)) {
7842
8140
  setDateRange({
7843
- startDate: startOfMonth4(date),
7844
- endDate: endOfMonth3(date)
8141
+ startDate: startOfMonth3(date),
8142
+ endDate: endOfMonth2(date)
7845
8143
  });
7846
8144
  }
7847
8145
  },
@@ -7914,19 +8212,30 @@ var Inbox_default = Inbox;
7914
8212
  // src/components/BankTransactions/DataStates.tsx
7915
8213
  var DataStates = ({
7916
8214
  bankTransactions,
8215
+ transactionsLoading,
7917
8216
  isLoading,
7918
8217
  isValidating,
7919
8218
  error,
7920
8219
  refetch,
7921
8220
  editable
7922
8221
  }) => {
8222
+ let title;
8223
+ let description;
8224
+ if (transactionsLoading) {
8225
+ title = "Data sync in progress";
8226
+ description = "Check back later to review your transactions";
8227
+ } else {
8228
+ title = editable ? "You are up to date with transactions!" : "You have no categorized transactions";
8229
+ description = editable ? "All uncategorized transaction will be displayed here" : "All transaction will be displayed here once reviewed";
8230
+ }
8231
+ const showRefreshButton = transactionsLoading || bankTransactions?.length;
7923
8232
  return /* @__PURE__ */ React105.createElement(React105.Fragment, null, !isLoading && !error && (bankTransactions === void 0 || bankTransactions !== void 0 && bankTransactions.length === 0) ? /* @__PURE__ */ React105.createElement("div", { className: "Layer__table-state-container" }, /* @__PURE__ */ React105.createElement(
7924
8233
  DataState,
7925
8234
  {
7926
- status: "allDone" /* allDone */,
7927
- title: editable ? "You are up to date with transactions!" : "You have no categorized transactions",
7928
- description: editable ? "All uncategorized transaction will be displayed here" : "All transaction will be displayed here once reviewed",
7929
- onRefresh: () => refetch(),
8235
+ status: transactionsLoading ? "info" /* info */ : "allDone" /* allDone */,
8236
+ title,
8237
+ description,
8238
+ onRefresh: showRefreshButton ? refetch : void 0,
7930
8239
  isLoading: isValidating,
7931
8240
  icon: !editable ? /* @__PURE__ */ React105.createElement(Inbox_default, null) : void 0
7932
8241
  }
@@ -7936,15 +8245,16 @@ var DataStates = ({
7936
8245
  status: "failed" /* failed */,
7937
8246
  title: "Something went wrong",
7938
8247
  description: "We couldn\u2019t load your data.",
7939
- onRefresh: () => refetch(),
8248
+ onRefresh: refetch,
7940
8249
  isLoading: isValidating
7941
8250
  }
7942
8251
  )) : null);
7943
8252
  };
7944
8253
 
7945
8254
  // src/components/BankTransactions/BankTransactions.tsx
7946
- import { endOfMonth as endOfMonth4, parseISO as parseISO12, startOfMonth as startOfMonth5 } from "date-fns";
8255
+ import { endOfMonth as endOfMonth3, parseISO as parseISO12, startOfMonth as startOfMonth4 } from "date-fns";
7947
8256
  var COMPONENT_NAME2 = "bank-transactions";
8257
+ var TEST_EMPTY_STATE = false;
7948
8258
  var BankTransactions = ({
7949
8259
  onError,
7950
8260
  ...props
@@ -7953,7 +8263,7 @@ var BankTransactions = ({
7953
8263
  };
7954
8264
  var BankTransactionsContent = ({
7955
8265
  asWidget = false,
7956
- pageSize = 15,
8266
+ pageSize = 20,
7957
8267
  categorizedOnly = false,
7958
8268
  categorizeView = true,
7959
8269
  showDescriptions = false,
@@ -7964,11 +8274,10 @@ var BankTransactionsContent = ({
7964
8274
  hideHeader = false
7965
8275
  }) => {
7966
8276
  const [currentPage, setCurrentPage] = useState26(1);
7967
- const [removedTxs, setRemovedTxs] = useState26([]);
7968
8277
  const [initialLoad, setInitialLoad] = useState26(true);
7969
8278
  const [dateRange, setDateRange] = useState26({
7970
- startDate: startOfMonth5(/* @__PURE__ */ new Date()),
7971
- endDate: endOfMonth4(/* @__PURE__ */ new Date())
8279
+ startDate: startOfMonth4(/* @__PURE__ */ new Date()),
8280
+ endDate: endOfMonth3(/* @__PURE__ */ new Date())
7972
8281
  });
7973
8282
  const {
7974
8283
  activate,
@@ -7980,9 +8289,12 @@ var BankTransactionsContent = ({
7980
8289
  refetch,
7981
8290
  setFilters,
7982
8291
  filters,
7983
- accountsList,
7984
- display
8292
+ display,
8293
+ hasMore,
8294
+ fetchMore,
8295
+ removeAfterCategorize
7985
8296
  } = useBankTransactionsContext();
8297
+ const { data: linkedAccounts } = useLinkedAccounts();
7986
8298
  useEffect20(() => {
7987
8299
  activate();
7988
8300
  }, []);
@@ -7992,24 +8304,24 @@ var BankTransactionsContent = ({
7992
8304
  setFilters({
7993
8305
  ...filters,
7994
8306
  ...inputFilters,
7995
- categorizationStatus: "TO_REVIEW" /* TO_REVIEW */
8307
+ categorizationStatus: "review" /* review */
7996
8308
  });
7997
8309
  } else if (!filters?.categorizationStatus && categorizedOnly) {
7998
8310
  setFilters({
7999
8311
  ...filters,
8000
8312
  ...inputFilters,
8001
- categorizationStatus: "CATEGORIZED" /* CATEGORIZED */
8313
+ categorizationStatus: "categorized" /* categorized */
8002
8314
  });
8003
8315
  } else {
8004
8316
  setFilters({ ...filters, ...inputFilters });
8005
8317
  }
8006
8318
  } else if (!filters?.categorizationStatus && categorizeView) {
8007
8319
  setFilters({
8008
- categorizationStatus: "TO_REVIEW" /* TO_REVIEW */
8320
+ categorizationStatus: "review" /* review */
8009
8321
  });
8010
8322
  } else if (!filters?.categorizationStatus && categorizedOnly) {
8011
8323
  setFilters({
8012
- categorizationStatus: "CATEGORIZED" /* CATEGORIZED */
8324
+ categorizationStatus: "categorized" /* categorized */
8013
8325
  });
8014
8326
  }
8015
8327
  }, [inputFilters, categorizeView, categorizedOnly]);
@@ -8021,7 +8333,7 @@ var BankTransactionsContent = ({
8021
8333
  return () => clearTimeout(timeoutLoad);
8022
8334
  }
8023
8335
  }, [loadingStatus]);
8024
- const bankTransactions = useMemo6(() => {
8336
+ const bankTransactions = TEST_EMPTY_STATE ? [] : useMemo6(() => {
8025
8337
  if (monthlyView) {
8026
8338
  return data?.filter(
8027
8339
  (x) => parseISO12(x.date) >= dateRange.startDate && parseISO12(x.date) <= dateRange.endDate
@@ -8030,10 +8342,10 @@ var BankTransactionsContent = ({
8030
8342
  const firstPageIndex = (currentPage - 1) * pageSize;
8031
8343
  const lastPageIndex = firstPageIndex + pageSize;
8032
8344
  return data?.slice(firstPageIndex, lastPageIndex);
8033
- }, [currentPage, data, removedTxs, dateRange]);
8345
+ }, [currentPage, data, dateRange]);
8034
8346
  const onCategorizationDisplayChange = (event) => {
8035
8347
  setFilters({
8036
- categorizationStatus: event.target.value === "categorized" /* categorized */ ? "CATEGORIZED" /* CATEGORIZED */ : "TO_REVIEW" /* TO_REVIEW */
8348
+ categorizationStatus: event.target.value === "categorized" /* categorized */ ? "categorized" /* categorized */ : "review" /* review */
8037
8349
  });
8038
8350
  setCurrentPage(1);
8039
8351
  };
@@ -8042,11 +8354,7 @@ var BankTransactionsContent = ({
8042
8354
  const [listView, setListView] = useState26(false);
8043
8355
  const [containerWidth, setContainerWidth] = useState26(0);
8044
8356
  const debounceContainerWidth = debounce(setContainerWidth, 500);
8045
- const removeTransaction = (id) => {
8046
- const newTxs = removedTxs.slice();
8047
- newTxs.push(id);
8048
- setRemovedTxs(newTxs);
8049
- };
8357
+ const removeTransaction = (bankTransaction) => removeAfterCategorize(bankTransaction);
8050
8358
  const containerRef = useElementSize((_el, _en, size) => {
8051
8359
  if (size?.height && size?.height >= 90) {
8052
8360
  const newShift = -Math.floor(size.height / 2) + 6;
@@ -8089,7 +8397,7 @@ var BankTransactionsContent = ({
8089
8397
  setDateRange: (v) => setDateRange(v)
8090
8398
  }
8091
8399
  ),
8092
- !listView && /* @__PURE__ */ React106.createElement(
8400
+ !listView && /* @__PURE__ */ React106.createElement("div", { className: "Layer__bank-transactions__table-wrapper" }, /* @__PURE__ */ React106.createElement(
8093
8401
  BankTransactionsTable,
8094
8402
  {
8095
8403
  categorizeView,
@@ -8102,7 +8410,7 @@ var BankTransactionsContent = ({
8102
8410
  showDescriptions,
8103
8411
  showReceiptUploads
8104
8412
  }
8105
- ),
8413
+ )),
8106
8414
  isLoading && !bankTransactions ? /* @__PURE__ */ React106.createElement("div", { className: "Layer__bank-transactions__loader-container" }, /* @__PURE__ */ React106.createElement(Loader2, null)) : null,
8107
8415
  !isLoading && listView && mobileComponent !== "mobileList" ? /* @__PURE__ */ React106.createElement(
8108
8416
  BankTransactionList,
@@ -8127,6 +8435,9 @@ var BankTransactionsContent = ({
8127
8435
  {
8128
8436
  bankTransactions,
8129
8437
  isLoading,
8438
+ transactionsLoading: Boolean(
8439
+ linkedAccounts?.some((item) => item.is_syncing)
8440
+ ),
8130
8441
  isValidating,
8131
8442
  error,
8132
8443
  refetch,
@@ -8139,7 +8450,9 @@ var BankTransactionsContent = ({
8139
8450
  currentPage,
8140
8451
  totalCount: data?.length || 0,
8141
8452
  pageSize,
8142
- onPageChange: (page) => setCurrentPage(page)
8453
+ onPageChange: (page) => setCurrentPage(page),
8454
+ fetchMore,
8455
+ hasMore
8143
8456
  }
8144
8457
  ))
8145
8458
  );
@@ -8149,7 +8462,7 @@ var BankTransactionsContent = ({
8149
8462
  import React107 from "react";
8150
8463
 
8151
8464
  // src/hooks/useQuickbooks/useQuickbooks.ts
8152
- import { useEffect as useEffect21, useRef as useRef13, useState as useState27 } from "react";
8465
+ import { useEffect as useEffect21, useRef as useRef14, useState as useState27 } from "react";
8153
8466
  var DEBUG2 = true;
8154
8467
  var useQuickbooks = () => {
8155
8468
  const { auth, businessId, apiUrl } = useLayerContext();
@@ -8157,7 +8470,7 @@ var useQuickbooks = () => {
8157
8470
  const [quickbooksIsLinked, setQuickbooksIsLinked] = useState27(
8158
8471
  null
8159
8472
  );
8160
- const syncStatusIntervalRef = useRef13(null);
8473
+ const syncStatusIntervalRef = useRef14(null);
8161
8474
  useEffect21(() => {
8162
8475
  if (isSyncingFromQuickbooks && syncStatusIntervalRef.current === null) {
8163
8476
  const interval = setInterval(() => fetchIsSyncingFromQuickbooks(), 2e3);
@@ -8298,16 +8611,16 @@ var applyShare = (items, total) => {
8298
8611
 
8299
8612
  // src/hooks/useProfitAndLoss/useProfitAndLossQuery.tsx
8300
8613
  import { useEffect as useEffect22 } from "react";
8301
- import { startOfMonth as startOfMonth6, endOfMonth as endOfMonth5, formatISO } from "date-fns";
8302
- import useSWR4 from "swr";
8614
+ import { startOfMonth as startOfMonth5, endOfMonth as endOfMonth4, formatISO } from "date-fns";
8615
+ import useSWR3 from "swr";
8303
8616
  var useProfitAndLossQuery = ({
8304
8617
  startDate,
8305
8618
  endDate,
8306
8619
  tagFilter,
8307
8620
  reportingBasis
8308
8621
  } = {
8309
- startDate: startOfMonth6(/* @__PURE__ */ new Date()),
8310
- endDate: endOfMonth5(/* @__PURE__ */ new Date())
8622
+ startDate: startOfMonth5(/* @__PURE__ */ new Date()),
8623
+ endDate: endOfMonth4(/* @__PURE__ */ new Date())
8311
8624
  }) => {
8312
8625
  const { auth, businessId, apiUrl, syncTimestamps, read, hasBeenTouched } = useLayerContext();
8313
8626
  const {
@@ -8316,7 +8629,7 @@ var useProfitAndLossQuery = ({
8316
8629
  isValidating,
8317
8630
  error: rawError,
8318
8631
  mutate
8319
- } = useSWR4(
8632
+ } = useSWR3(
8320
8633
  businessId && startDate && endDate && auth?.access_token && `profit-and-loss-${businessId}-${startDate.valueOf()}-${endDate.valueOf()}-${tagFilter?.key}-${tagFilter?.values?.join(
8321
8634
  ","
8322
8635
  )}-${reportingBasis}`,
@@ -8356,21 +8669,21 @@ var useProfitAndLossQuery = ({
8356
8669
  };
8357
8670
 
8358
8671
  // src/hooks/useProfitAndLoss/useProfitAndLoss.tsx
8359
- import { startOfMonth as startOfMonth7, endOfMonth as endOfMonth6 } from "date-fns";
8672
+ import { startOfMonth as startOfMonth6, endOfMonth as endOfMonth5 } from "date-fns";
8360
8673
  var useProfitAndLoss = ({
8361
8674
  startDate: initialStartDate,
8362
8675
  endDate: initialEndDate,
8363
8676
  tagFilter,
8364
8677
  reportingBasis
8365
8678
  } = {
8366
- startDate: startOfMonth7(/* @__PURE__ */ new Date()),
8367
- endDate: endOfMonth6(/* @__PURE__ */ new Date())
8679
+ startDate: startOfMonth6(/* @__PURE__ */ new Date()),
8680
+ endDate: endOfMonth5(/* @__PURE__ */ new Date())
8368
8681
  }) => {
8369
8682
  const [startDate, setStartDate] = useState28(
8370
- initialStartDate || startOfMonth7(Date.now())
8683
+ initialStartDate || startOfMonth6(Date.now())
8371
8684
  );
8372
8685
  const [endDate, setEndDate] = useState28(
8373
- initialEndDate || endOfMonth6(Date.now())
8686
+ initialEndDate || endOfMonth5(Date.now())
8374
8687
  );
8375
8688
  const [filters, setFilters] = useState28({
8376
8689
  expenses: void 0,
@@ -8508,14 +8821,14 @@ import React109, { useContext as useContext12, useEffect as useEffect25, useMemo
8508
8821
 
8509
8822
  // src/hooks/useProfitAndLoss/useProfitAndLossLTM.tsx
8510
8823
  import { useEffect as useEffect23, useMemo as useMemo8, useState as useState29 } from "react";
8511
- import { startOfMonth as startOfMonth8, sub } from "date-fns";
8512
- import useSWR5 from "swr";
8824
+ import { startOfMonth as startOfMonth7, sub } from "date-fns";
8825
+ import useSWR4 from "swr";
8513
8826
  var buildDates = ({ currentDate }) => {
8514
8827
  return {
8515
- startYear: startOfMonth8(currentDate).getFullYear() - 1,
8516
- startMonth: startOfMonth8(currentDate).getMonth() + 1,
8517
- endYear: startOfMonth8(currentDate).getFullYear(),
8518
- endMonth: startOfMonth8(currentDate).getMonth() + 1
8828
+ startYear: startOfMonth7(currentDate).getFullYear() - 1,
8829
+ startMonth: startOfMonth7(currentDate).getMonth() + 1,
8830
+ endYear: startOfMonth7(currentDate).getFullYear(),
8831
+ endMonth: startOfMonth7(currentDate).getMonth() + 1
8519
8832
  };
8520
8833
  };
8521
8834
  var buildMonthsArray = (startDate, endDate) => {
@@ -8544,7 +8857,7 @@ var useProfitAndLossLTM = ({ currentDate, tagFilter, reportingBasis } = {
8544
8857
  isValidating,
8545
8858
  error,
8546
8859
  mutate
8547
- } = useSWR5(
8860
+ } = useSWR4(
8548
8861
  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(
8549
8862
  ","
8550
8863
  )}-${reportingBasis}`,
@@ -8583,6 +8896,7 @@ var useProfitAndLossLTM = ({ currentDate, tagFilter, reportingBasis } = {
8583
8896
  totalExpenses: 0,
8584
8897
  uncategorizedInflows: 0,
8585
8898
  uncategorizedOutflows: 0,
8899
+ uncategorized_transactions: 0,
8586
8900
  isLoading: true
8587
8901
  });
8588
8902
  }
@@ -8633,12 +8947,16 @@ var useProfitAndLossLTM = ({ currentDate, tagFilter, reportingBasis } = {
8633
8947
  mutate();
8634
8948
  }
8635
8949
  }, [syncTimestamps]);
8950
+ const refetch = () => {
8951
+ mutate();
8952
+ };
8636
8953
  return {
8637
8954
  data,
8638
8955
  isLoading,
8639
8956
  loaded,
8640
8957
  error,
8641
- pullData
8958
+ pullData,
8959
+ refetch
8642
8960
  };
8643
8961
  };
8644
8962
 
@@ -8707,9 +9025,9 @@ import classNames40 from "classnames";
8707
9025
  import {
8708
9026
  add as add2,
8709
9027
  differenceInMonths,
8710
- endOfMonth as endOfMonth7,
9028
+ endOfMonth as endOfMonth6,
8711
9029
  format,
8712
- startOfMonth as startOfMonth9,
9030
+ startOfMonth as startOfMonth8,
8713
9031
  sub as sub2
8714
9032
  } from "date-fns";
8715
9033
  import {
@@ -8732,46 +9050,46 @@ var getChartWindow = ({
8732
9050
  currentYear,
8733
9051
  currentMonth
8734
9052
  }) => {
8735
- const today = startOfMonth9(Date.now());
9053
+ const today = startOfMonth8(Date.now());
8736
9054
  const yearAgo = sub2(today, { months: 11 });
8737
- const current = startOfMonth9(new Date(currentYear, currentMonth - 1, 1));
8738
- if (differenceInMonths(startOfMonth9(chartWindow.start), current) < 0 && differenceInMonths(startOfMonth9(chartWindow.end), current) > 1) {
9055
+ const current = startOfMonth8(new Date(currentYear, currentMonth - 1, 1));
9056
+ if (differenceInMonths(startOfMonth8(chartWindow.start), current) < 0 && differenceInMonths(startOfMonth8(chartWindow.end), current) > 1) {
8739
9057
  return chartWindow;
8740
9058
  }
8741
- if (differenceInMonths(startOfMonth9(chartWindow.start), current) === 0) {
9059
+ if (differenceInMonths(startOfMonth8(chartWindow.start), current) === 0) {
8742
9060
  return {
8743
- start: startOfMonth9(sub2(current, { months: 1 })),
8744
- end: endOfMonth7(add2(current, { months: 11 }))
9061
+ start: startOfMonth8(sub2(current, { months: 1 })),
9062
+ end: endOfMonth6(add2(current, { months: 11 }))
8745
9063
  };
8746
9064
  }
8747
- if (differenceInMonths(endOfMonth7(chartWindow.end), endOfMonth7(current)) === 1 && differenceInMonths(today, current) >= 1) {
9065
+ if (differenceInMonths(endOfMonth6(chartWindow.end), endOfMonth6(current)) === 1 && differenceInMonths(today, current) >= 1) {
8748
9066
  return {
8749
- start: startOfMonth9(sub2(current, { months: 10 })),
8750
- end: endOfMonth7(add2(current, { months: 2 }))
9067
+ start: startOfMonth8(sub2(current, { months: 10 })),
9068
+ end: endOfMonth6(add2(current, { months: 2 }))
8751
9069
  };
8752
9070
  }
8753
- if (differenceInMonths(current, startOfMonth9(chartWindow.end)) === 0 && differenceInMonths(current, startOfMonth9(today)) > 0) {
9071
+ if (differenceInMonths(current, startOfMonth8(chartWindow.end)) === 0 && differenceInMonths(current, startOfMonth8(today)) > 0) {
8754
9072
  return {
8755
- start: startOfMonth9(sub2(current, { months: 11 })),
8756
- end: endOfMonth7(add2(current, { months: 1 }))
9073
+ start: startOfMonth8(sub2(current, { months: 11 })),
9074
+ end: endOfMonth6(add2(current, { months: 1 }))
8757
9075
  };
8758
9076
  }
8759
9077
  if (current >= yearAgo) {
8760
9078
  return {
8761
- start: startOfMonth9(yearAgo),
8762
- end: endOfMonth7(today)
9079
+ start: startOfMonth8(yearAgo),
9080
+ end: endOfMonth6(today)
8763
9081
  };
8764
9082
  }
8765
9083
  if (Number(current) > Number(chartWindow.end)) {
8766
9084
  return {
8767
- start: startOfMonth9(sub2(current, { months: 12 })),
8768
- end: endOfMonth7(current)
9085
+ start: startOfMonth8(sub2(current, { months: 12 })),
9086
+ end: endOfMonth6(current)
8769
9087
  };
8770
9088
  }
8771
- if (differenceInMonths(current, startOfMonth9(chartWindow.start)) < 0) {
9089
+ if (differenceInMonths(current, startOfMonth8(chartWindow.start)) < 0) {
8772
9090
  return {
8773
- start: startOfMonth9(current),
8774
- end: endOfMonth7(add2(current, { months: 11 }))
9091
+ start: startOfMonth8(current),
9092
+ end: endOfMonth6(add2(current, { months: 11 }))
8775
9093
  };
8776
9094
  }
8777
9095
  return chartWindow;
@@ -8805,8 +9123,8 @@ var ProfitAndLossChart = () => {
8805
9123
  });
8806
9124
  const [barAnimActive, setBarAnimActive] = useState31(true);
8807
9125
  const [chartWindow, setChartWindow] = useState31({
8808
- start: startOfMonth9(sub2(Date.now(), { months: 11 })),
8809
- end: endOfMonth7(Date.now())
9126
+ start: startOfMonth8(sub2(Date.now(), { months: 11 })),
9127
+ end: endOfMonth6(Date.now())
8810
9128
  });
8811
9129
  const selectionMonth = useMemo9(
8812
9130
  () => ({
@@ -8821,24 +9139,24 @@ var ProfitAndLossChart = () => {
8821
9139
  }
8822
9140
  }, [dateRange]);
8823
9141
  const { data, loaded, pullData } = useProfitAndLossLTM({
8824
- currentDate: startOfMonth9(Date.now())
9142
+ currentDate: startOfMonth8(Date.now())
8825
9143
  });
8826
9144
  const loadingValue = useMemo9(() => getLoadingValue(data), [data]);
8827
9145
  useEffect25(() => {
8828
9146
  if (loaded === "complete" && data) {
8829
9147
  const foundCurrent = data.find(
8830
- (x) => Number(startOfMonth9(new Date(x.year, x.month - 1, 1))) >= Number(localDateRange.startDate) && Number(startOfMonth9(new Date(x.year, x.month - 1, 1))) < Number(localDateRange.endDate)
9148
+ (x) => Number(startOfMonth8(new Date(x.year, x.month - 1, 1))) >= Number(localDateRange.startDate) && Number(startOfMonth8(new Date(x.year, x.month - 1, 1))) < Number(localDateRange.endDate)
8831
9149
  );
8832
9150
  if (!foundCurrent) {
8833
- const newDate = startOfMonth9(localDateRange.startDate);
9151
+ const newDate = startOfMonth8(localDateRange.startDate);
8834
9152
  pullData(newDate);
8835
9153
  return;
8836
9154
  }
8837
9155
  const foundBefore = data.find(
8838
- (x) => Number(startOfMonth9(new Date(x.year, x.month - 1, 1))) >= Number(sub2(localDateRange.startDate, { months: 1 })) && Number(startOfMonth9(new Date(x.year, x.month - 1, 1))) < Number(sub2(localDateRange.endDate, { months: 1 }))
9156
+ (x) => Number(startOfMonth8(new Date(x.year, x.month - 1, 1))) >= Number(sub2(localDateRange.startDate, { months: 1 })) && Number(startOfMonth8(new Date(x.year, x.month - 1, 1))) < Number(sub2(localDateRange.endDate, { months: 1 }))
8839
9157
  );
8840
9158
  if (!foundBefore) {
8841
- const newDate = startOfMonth9(
9159
+ const newDate = startOfMonth8(
8842
9160
  sub2(localDateRange.startDate, { months: 1 })
8843
9161
  );
8844
9162
  pullData(newDate);
@@ -8870,8 +9188,10 @@ var ProfitAndLossChart = () => {
8870
9188
  name: getMonthName(pnl),
8871
9189
  revenue: pnl?.income || 0,
8872
9190
  revenueUncategorized: pnl?.uncategorizedInflows || 0,
8873
- expenses: -Math.abs((pnl?.income || 0) - (pnl?.netProfit || 0)),
8874
- expensesUncategorized: -Math.abs(pnl?.uncategorizedOutflows || 0),
9191
+ expenses: -(pnl?.operatingExpenses || 0),
9192
+ expensesUncategorized: -(pnl?.uncategorizedOutflows || 0),
9193
+ operatingExpensesInverse: pnl?.operatingExpensesInverse || 0,
9194
+ uncategorizedOutflowsInverse: pnl?.uncategorizedOutflowsInverse || 0,
8875
9195
  netProfit: pnl?.netProfit || 0,
8876
9196
  selected: !!pnl && pnl.month === selectionMonth.month + 1 && pnl.year === selectionMonth.year,
8877
9197
  year: pnl?.year,
@@ -8890,6 +9210,8 @@ var ProfitAndLossChart = () => {
8890
9210
  name: format(currentDate, compactView ? "LLLLL" : "LLL"),
8891
9211
  revenue: 0,
8892
9212
  revenueUncategorized: 0,
9213
+ operatingExpensesInverse: 0,
9214
+ uncategorizedOutflowsInverse: 0,
8893
9215
  expenses: 0,
8894
9216
  expensesUncategorized: 0,
8895
9217
  netProfit: 0,
@@ -8903,19 +9225,30 @@ var ProfitAndLossChart = () => {
8903
9225
  }
8904
9226
  return loadingData;
8905
9227
  }
8906
- return data?.filter(
9228
+ return data?.map((x) => {
9229
+ if (x.operatingExpenses < 0 || x.uncategorizedOutflows < 0) {
9230
+ return {
9231
+ ...x,
9232
+ operatingExpenses: x.operatingExpenses < 0 ? 0 : x.operatingExpenses,
9233
+ uncategorizedOutflows: x.uncategorizedOutflows < 0 ? 0 : x.uncategorizedOutflows,
9234
+ operatingExpensesInverse: x.operatingExpenses < 0 ? -x.operatingExpenses : 0,
9235
+ uncategorizedOutflowsInverse: x.uncategorizedOutflows < 0 ? -x.uncategorizedOutflows : 0
9236
+ };
9237
+ }
9238
+ return x;
9239
+ })?.filter(
8907
9240
  (x) => differenceInMonths(
8908
- startOfMonth9(new Date(x.year, x.month - 1, 1)),
9241
+ startOfMonth8(new Date(x.year, x.month - 1, 1)),
8909
9242
  chartWindow.start
8910
9243
  ) >= 0 && differenceInMonths(
8911
- startOfMonth9(new Date(x.year, x.month - 1, 1)),
9244
+ startOfMonth8(new Date(x.year, x.month - 1, 1)),
8912
9245
  chartWindow.start
8913
9246
  ) < 12 && differenceInMonths(
8914
9247
  chartWindow.end,
8915
- startOfMonth9(new Date(x.year, x.month - 1, 1))
9248
+ startOfMonth8(new Date(x.year, x.month - 1, 1))
8916
9249
  ) >= 0 && differenceInMonths(
8917
9250
  chartWindow.end,
8918
- startOfMonth9(new Date(x.year, x.month - 1, 1))
9251
+ startOfMonth8(new Date(x.year, x.month - 1, 1))
8919
9252
  ) <= 12
8920
9253
  ).map((x) => summarizePnL(x));
8921
9254
  }, [selectionMonth, chartWindow, data, loaded, compactView]);
@@ -8929,7 +9262,7 @@ var ProfitAndLossChart = () => {
8929
9262
  if (isMonthAllowed) {
8930
9263
  changeDateRange({
8931
9264
  startDate: new Date(year, month - 1, 1),
8932
- endDate: endOfMonth7(new Date(year, month - 1, 1))
9265
+ endDate: endOfMonth6(new Date(year, month - 1, 1))
8933
9266
  });
8934
9267
  }
8935
9268
  }
@@ -9190,6 +9523,22 @@ var ProfitAndLossChart = () => {
9190
9523
  stackId: "expenses"
9191
9524
  }
9192
9525
  ),
9526
+ /* @__PURE__ */ React109.createElement(
9527
+ Bar,
9528
+ {
9529
+ dataKey: "operatingExpensesInverse",
9530
+ barSize,
9531
+ isAnimationActive: barAnimActive,
9532
+ animationDuration: 100,
9533
+ radius: [2, 2, 0, 0],
9534
+ className: "Layer__profit-and-loss-chart__bar--expenses",
9535
+ xAxisId: "revenue",
9536
+ stackId: "revenue"
9537
+ },
9538
+ theData?.map((entry) => {
9539
+ return /* @__PURE__ */ React109.createElement(Cell, { key: entry.name, fill: "url(#layer-bar-stripe-pattern-dark)" });
9540
+ })
9541
+ ),
9193
9542
  /* @__PURE__ */ React109.createElement(
9194
9543
  Bar,
9195
9544
  {
@@ -9225,6 +9574,22 @@ var ProfitAndLossChart = () => {
9225
9574
  );
9226
9575
  })
9227
9576
  ),
9577
+ /* @__PURE__ */ React109.createElement(
9578
+ Bar,
9579
+ {
9580
+ dataKey: "uncategorizedOutflowsInverse",
9581
+ barSize,
9582
+ isAnimationActive: barAnimActive,
9583
+ animationDuration: 100,
9584
+ radius: [2, 2, 0, 0],
9585
+ className: "Layer__profit-and-loss-chart__bar--expenses-uncategorized",
9586
+ xAxisId: "revenue",
9587
+ stackId: "revenue"
9588
+ },
9589
+ theData?.map((entry) => {
9590
+ return /* @__PURE__ */ React109.createElement(Cell, { key: entry.name, fill: "url(#layer-bar-stripe-pattern-dark)" });
9591
+ })
9592
+ ),
9228
9593
  /* @__PURE__ */ React109.createElement(
9229
9594
  Bar,
9230
9595
  {
@@ -9301,7 +9666,7 @@ var ProfitAndLossChart = () => {
9301
9666
 
9302
9667
  // src/components/ProfitAndLossDatePicker/ProfitAndLossDatePicker.tsx
9303
9668
  import React110, { useContext as useContext13 } from "react";
9304
- import { endOfMonth as endOfMonth8, startOfMonth as startOfMonth10 } from "date-fns";
9669
+ import { endOfMonth as endOfMonth7, startOfMonth as startOfMonth9 } from "date-fns";
9305
9670
  var ProfitAndLossDatePicker = () => {
9306
9671
  const { business } = useLayerContext();
9307
9672
  const { changeDateRange, dateRange } = useContext13(ProfitAndLoss.Context);
@@ -9314,8 +9679,8 @@ var ProfitAndLossDatePicker = () => {
9314
9679
  onChange: (date) => {
9315
9680
  if (!Array.isArray(date)) {
9316
9681
  changeDateRange({
9317
- startDate: startOfMonth10(date),
9318
- endDate: endOfMonth8(date)
9682
+ startDate: startOfMonth9(date),
9683
+ endDate: endOfMonth7(date)
9319
9684
  });
9320
9685
  }
9321
9686
  },
@@ -10516,7 +10881,7 @@ var ProfitAndLossTable = ({ lockExpanded, asContainer }) => {
10516
10881
  };
10517
10882
 
10518
10883
  // src/components/ProfitAndLoss/ProfitAndLoss.tsx
10519
- import { endOfMonth as endOfMonth9, startOfMonth as startOfMonth11 } from "date-fns";
10884
+ import { endOfMonth as endOfMonth8, startOfMonth as startOfMonth10 } from "date-fns";
10520
10885
  var PNLContext = createContext6({
10521
10886
  data: void 0,
10522
10887
  filteredDataRevenue: [],
@@ -10527,8 +10892,8 @@ var PNLContext = createContext6({
10527
10892
  isValidating: false,
10528
10893
  error: void 0,
10529
10894
  dateRange: {
10530
- startDate: startOfMonth11(/* @__PURE__ */ new Date()),
10531
- endDate: endOfMonth9(/* @__PURE__ */ new Date())
10895
+ startDate: startOfMonth10(/* @__PURE__ */ new Date()),
10896
+ endDate: endOfMonth8(/* @__PURE__ */ new Date())
10532
10897
  },
10533
10898
  changeDateRange: () => {
10534
10899
  },
@@ -10618,11 +10983,11 @@ var TableProvider = ({ children }) => {
10618
10983
  // src/hooks/useBalanceSheet/useBalanceSheet.tsx
10619
10984
  import { useEffect as useEffect27 } from "react";
10620
10985
  import { format as format3, startOfDay } from "date-fns";
10621
- import useSWR6 from "swr";
10986
+ import useSWR5 from "swr";
10622
10987
  var useBalanceSheet = (date = /* @__PURE__ */ new Date()) => {
10623
10988
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
10624
10989
  const dateString = format3(startOfDay(date), "yyyy-MM-dd'T'HH:mm:ssXXX");
10625
- const { data, isLoading, isValidating, error, mutate } = useSWR6(
10990
+ const { data, isLoading, isValidating, error, mutate } = useSWR5(
10626
10991
  businessId && dateString && auth?.access_token && `balance-sheet-${businessId}-${dateString}`,
10627
10992
  Layer.getBalanceSheet(apiUrl, auth?.access_token, {
10628
10993
  params: {
@@ -10785,7 +11150,7 @@ var TableRow = ({
10785
11150
  };
10786
11151
 
10787
11152
  // src/components/Table/Table.tsx
10788
- import React131, { useEffect as useEffect28, useRef as useRef14 } from "react";
11153
+ import React131, { useEffect as useEffect28, useRef as useRef15 } from "react";
10789
11154
  import classNames47 from "classnames";
10790
11155
  var Table = ({
10791
11156
  componentName,
@@ -10793,8 +11158,8 @@ var Table = ({
10793
11158
  borderCollapse = "separate",
10794
11159
  bottomSpacing = true
10795
11160
  }) => {
10796
- const tableRef = useRef14(null);
10797
- const prevChildrenRef = useRef14([]);
11161
+ const tableRef = useRef15(null);
11162
+ const prevChildrenRef = useRef15([]);
10798
11163
  useEffect28(() => {
10799
11164
  if (tableRef.current) {
10800
11165
  const tbody = tableRef.current.querySelector("tbody");
@@ -11067,7 +11432,7 @@ var StatementOfCashFlowContext = createContext9({
11067
11432
  // src/hooks/useStatementOfCashFlow/useStatementOfCashFlow.tsx
11068
11433
  import { useEffect as useEffect32 } from "react";
11069
11434
  import { format as format5, startOfDay as startOfDay3 } from "date-fns";
11070
- import useSWR7 from "swr";
11435
+ import useSWR6 from "swr";
11071
11436
  var useStatementOfCashFlow = (startDate = /* @__PURE__ */ new Date(), endDate = /* @__PURE__ */ new Date()) => {
11072
11437
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
11073
11438
  const startDateString = format5(
@@ -11075,7 +11440,7 @@ var useStatementOfCashFlow = (startDate = /* @__PURE__ */ new Date(), endDate =
11075
11440
  "yyyy-MM-dd'T'HH:mm:ssXXX"
11076
11441
  );
11077
11442
  const endDateString = format5(startOfDay3(endDate), "yyyy-MM-dd'T'HH:mm:ssXXX");
11078
- const { data, isLoading, isValidating, error, mutate } = useSWR7(
11443
+ const { data, isLoading, isValidating, error, mutate } = useSWR6(
11079
11444
  businessId && startDateString && endDateString && auth?.access_token && `statement-of-cash-${businessId}-${startDateString}-${endDateString}`,
11080
11445
  Layer.getStatementOfCashFlow(apiUrl, auth?.access_token, {
11081
11446
  params: {
@@ -11256,7 +11621,7 @@ import React153, { useContext as useContext25, useState as useState44 } from "re
11256
11621
 
11257
11622
  // src/contexts/ChartOfAccountsContext/ChartOfAccountsContext.tsx
11258
11623
  import { createContext as createContext10 } from "react";
11259
- import { endOfMonth as endOfMonth10, startOfMonth as startOfMonth12 } from "date-fns";
11624
+ import { endOfMonth as endOfMonth9, startOfMonth as startOfMonth11 } from "date-fns";
11260
11625
  var ChartOfAccountsContext = createContext10(
11261
11626
  {
11262
11627
  data: void 0,
@@ -11279,8 +11644,8 @@ var ChartOfAccountsContext = createContext10(
11279
11644
  submitForm: () => {
11280
11645
  },
11281
11646
  dateRange: {
11282
- startDate: startOfMonth12(/* @__PURE__ */ new Date()),
11283
- endDate: endOfMonth10(/* @__PURE__ */ new Date())
11647
+ startDate: startOfMonth11(/* @__PURE__ */ new Date()),
11648
+ endDate: endOfMonth9(/* @__PURE__ */ new Date())
11284
11649
  },
11285
11650
  changeDateRange: () => {
11286
11651
  }
@@ -11515,8 +11880,8 @@ var LEDGER_ACCOUNT_SUBTYPES_FOR_TYPE = {
11515
11880
  };
11516
11881
 
11517
11882
  // src/hooks/useChartOfAccounts/useChartOfAccounts.tsx
11518
- import { endOfMonth as endOfMonth11, formatISO as formatISO2, startOfMonth as startOfMonth13 } from "date-fns";
11519
- import useSWR8 from "swr";
11883
+ import { endOfMonth as endOfMonth10, formatISO as formatISO2, startOfMonth as startOfMonth12 } from "date-fns";
11884
+ import useSWR7 from "swr";
11520
11885
  var validate = (formData) => {
11521
11886
  const errors = [];
11522
11887
  const nameError = validateName(formData);
@@ -11596,8 +11961,8 @@ var validateName = (formData) => {
11596
11961
  var flattenAccounts = (accounts) => accounts.flatMap((a) => [a, flattenAccounts(a.sub_accounts || [])]).flat().filter((id) => id);
11597
11962
  var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: initialEndDate } = {
11598
11963
  withDates: false,
11599
- startDate: startOfMonth13(/* @__PURE__ */ new Date()),
11600
- endDate: endOfMonth11(/* @__PURE__ */ new Date())
11964
+ startDate: startOfMonth12(/* @__PURE__ */ new Date()),
11965
+ endDate: endOfMonth10(/* @__PURE__ */ new Date())
11601
11966
  }) => {
11602
11967
  const {
11603
11968
  auth,
@@ -11612,12 +11977,12 @@ var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: ini
11612
11977
  const [sendingForm, setSendingForm] = useState38(false);
11613
11978
  const [apiError, setApiError] = useState38(void 0);
11614
11979
  const [startDate, setStartDate] = useState38(
11615
- initialStartDate ?? startOfMonth13(Date.now())
11980
+ initialStartDate ?? startOfMonth12(Date.now())
11616
11981
  );
11617
11982
  const [endDate, setEndDate] = useState38(
11618
- initialEndDate ?? endOfMonth11(Date.now())
11983
+ initialEndDate ?? endOfMonth10(Date.now())
11619
11984
  );
11620
- const { data, isLoading, isValidating, error, mutate } = useSWR8(
11985
+ const { data, isLoading, isValidating, error, mutate } = useSWR7(
11621
11986
  businessId && auth?.access_token && `chart-of-accounts-${businessId}-${startDate?.valueOf()}-${endDate?.valueOf()}`,
11622
11987
  Layer.getLedgerAccountBalances(apiUrl, auth?.access_token, {
11623
11988
  params: {
@@ -11826,12 +12191,12 @@ var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: ini
11826
12191
 
11827
12192
  // src/hooks/useLedgerAccounts/useLedgerAccounts.tsx
11828
12193
  import { useEffect as useEffect34, useState as useState39 } from "react";
11829
- import useSWR9 from "swr";
12194
+ import useSWR8 from "swr";
11830
12195
  var useLedgerAccounts = () => {
11831
12196
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
11832
12197
  const [accountId, setAccountId] = useState39();
11833
12198
  const [selectedEntryId, setSelectedEntryId] = useState39();
11834
- const { data, isLoading, isValidating, error, mutate } = useSWR9(
12199
+ const { data, isLoading, isValidating, error, mutate } = useSWR8(
11835
12200
  businessId && accountId && auth?.access_token && `ledger-accounts-lines-${businessId}-${accountId}`,
11836
12201
  Layer.getLedgerAccountsLines(apiUrl, auth?.access_token, {
11837
12202
  params: { businessId, accountId }
@@ -11843,7 +12208,7 @@ var useLedgerAccounts = () => {
11843
12208
  isLoading: isLoadingEntry,
11844
12209
  isValidating: isValdiatingEntry,
11845
12210
  error: errorEntry
11846
- } = useSWR9(
12211
+ } = useSWR8(
11847
12212
  businessId && selectedEntryId && auth?.access_token && `ledger-accounts-entry-${businessId}-${selectedEntryId}}`,
11848
12213
  Layer.getLedgerAccountsEntry(apiUrl, auth?.access_token, {
11849
12214
  params: { businessId, entryId: selectedEntryId }
@@ -11887,7 +12252,7 @@ import React145, { useContext as useContext21, useState as useState41 } from "re
11887
12252
 
11888
12253
  // src/components/ChartOfAccountsDatePicker/ChartOfAccountsDatePicker.tsx
11889
12254
  import React139, { useContext as useContext18 } from "react";
11890
- import { endOfMonth as endOfMonth12, startOfMonth as startOfMonth14 } from "date-fns";
12255
+ import { endOfMonth as endOfMonth11, startOfMonth as startOfMonth13 } from "date-fns";
11891
12256
  var ChartOfAccountsDatePicker = () => {
11892
12257
  const { changeDateRange, dateRange } = useContext18(ChartOfAccountsContext);
11893
12258
  return /* @__PURE__ */ React139.createElement(
@@ -11898,8 +12263,8 @@ var ChartOfAccountsDatePicker = () => {
11898
12263
  onChange: (date) => {
11899
12264
  if (!Array.isArray(date)) {
11900
12265
  changeDateRange({
11901
- startDate: startOfMonth14(date),
11902
- endDate: endOfMonth12(date)
12266
+ startDate: startOfMonth13(date),
12267
+ endDate: endOfMonth11(date)
11903
12268
  });
11904
12269
  }
11905
12270
  }
@@ -12938,7 +13303,7 @@ var getAccountIdentifierPayload = (journalLineItem) => {
12938
13303
  };
12939
13304
 
12940
13305
  // src/hooks/useJournal/useJournal.tsx
12941
- import useSWR10 from "swr";
13306
+ import useSWR9 from "swr";
12942
13307
  var useJournal = () => {
12943
13308
  const {
12944
13309
  auth,
@@ -12954,7 +13319,7 @@ var useJournal = () => {
12954
13319
  const [addingEntry, setAddingEntry] = useState45(false);
12955
13320
  const [sendingForm, setSendingForm] = useState45(false);
12956
13321
  const [apiError, setApiError] = useState45(void 0);
12957
- const { data, isLoading, isValidating, error, mutate } = useSWR10(
13322
+ const { data, isLoading, isValidating, error, mutate } = useSWR9(
12958
13323
  businessId && auth?.access_token && `journal-lines-${businessId}`,
12959
13324
  Layer.getJournal(apiUrl, auth?.access_token, {
12960
13325
  params: { businessId }
@@ -13859,11 +14224,11 @@ var TasksContext = createContext14({
13859
14224
 
13860
14225
  // src/hooks/useTasks/useTasks.tsx
13861
14226
  import { useEffect as useEffect40, useState as useState49 } from "react";
13862
- import useSWR11 from "swr";
14227
+ import useSWR10 from "swr";
13863
14228
  var useTasks = () => {
13864
14229
  const [loadedStatus, setLoadedStatus] = useState49("initial");
13865
14230
  const { auth, businessId, apiUrl, read, syncTimestamps, hasBeenTouched } = useLayerContext();
13866
- const { data, isLoading, isValidating, error, mutate } = useSWR11(
14231
+ const { data, isLoading, isValidating, error, mutate } = useSWR10(
13867
14232
  businessId && auth?.access_token && `tasks-${businessId}`,
13868
14233
  Layer.getTasks(apiUrl, auth?.access_token, {
13869
14234
  params: { businessId }
@@ -14481,7 +14846,7 @@ var BookkeepingOverview = ({
14481
14846
  import React175, { useState as useState55 } from "react";
14482
14847
 
14483
14848
  // src/components/TransactionToReviewCard/TransactionToReviewCard.tsx
14484
- import React174, { useContext as useContext37, useEffect as useEffect43, useMemo as useMemo20 } from "react";
14849
+ import React174, { useContext as useContext37, useEffect as useEffect43, useState as useState54 } from "react";
14485
14850
 
14486
14851
  // src/components/BadgeLoader/BadgeLoader.tsx
14487
14852
  import React172 from "react";
@@ -14508,27 +14873,33 @@ var NotificationCard = ({
14508
14873
  };
14509
14874
 
14510
14875
  // src/components/TransactionToReviewCard/TransactionToReviewCard.tsx
14876
+ import { getMonth, getYear, startOfMonth as startOfMonth14 } from "date-fns";
14511
14877
  var TransactionToReviewCard = ({
14512
14878
  onClick,
14513
14879
  usePnlDateRange
14514
14880
  }) => {
14515
- const {
14516
- data,
14517
- isLoading,
14518
- loadingStatus,
14519
- error,
14520
- refetch,
14521
- activate: activateBankTransactions
14522
- } = useBankTransactionsContext();
14523
14881
  const { dateRange: contextDateRange } = useContext37(ProfitAndLoss.Context);
14524
14882
  const dateRange = usePnlDateRange ? contextDateRange : void 0;
14883
+ const [toReview, setToReview] = useState54(0);
14884
+ const { data, loaded, error, refetch } = useProfitAndLossLTM({
14885
+ currentDate: dateRange ? dateRange.startDate : startOfMonth14(/* @__PURE__ */ new Date())
14886
+ });
14525
14887
  useEffect43(() => {
14526
- activateBankTransactions();
14888
+ checkTransactionsToReview();
14527
14889
  }, []);
14528
- const toReview = useMemo20(
14529
- () => countTransactionsToReview({ transactions: data, dateRange }),
14530
- [data, isLoading, dateRange]
14531
- );
14890
+ useEffect43(() => {
14891
+ checkTransactionsToReview();
14892
+ }, [dateRange, loaded]);
14893
+ const checkTransactionsToReview = () => {
14894
+ if (data && dateRange) {
14895
+ const monthTx = data.filter(
14896
+ (x) => x.month - 1 === getMonth(dateRange.startDate) && x.year === getYear(dateRange.startDate)
14897
+ );
14898
+ if (monthTx.length > 0) {
14899
+ setToReview(monthTx[0].uncategorized_transactions);
14900
+ }
14901
+ }
14902
+ };
14532
14903
  return /* @__PURE__ */ React174.createElement(
14533
14904
  NotificationCard,
14534
14905
  {
@@ -14536,8 +14907,8 @@ var TransactionToReviewCard = ({
14536
14907
  onClick: () => onClick && onClick()
14537
14908
  },
14538
14909
  /* @__PURE__ */ React174.createElement(Text, { size: "sm" /* sm */ }, "Transactions to review"),
14539
- loadingStatus === "initial" || loadingStatus === "loading" ? /* @__PURE__ */ React174.createElement(BadgeLoader, null) : null,
14540
- loadingStatus === "complete" && error ? /* @__PURE__ */ React174.createElement(
14910
+ loaded === "initial" || loaded === "loading" ? /* @__PURE__ */ React174.createElement(BadgeLoader, null) : null,
14911
+ loaded === "complete" && error ? /* @__PURE__ */ React174.createElement(
14541
14912
  Badge,
14542
14913
  {
14543
14914
  variant: "error" /* ERROR */,
@@ -14547,7 +14918,7 @@ var TransactionToReviewCard = ({
14547
14918
  },
14548
14919
  "Refresh"
14549
14920
  ) : null,
14550
- loadingStatus === "complete" && !error && toReview > 0 ? /* @__PURE__ */ React174.createElement(
14921
+ loaded === "complete" && !error && toReview > 0 ? /* @__PURE__ */ React174.createElement(
14551
14922
  Badge,
14552
14923
  {
14553
14924
  variant: "warning" /* WARNING */,
@@ -14557,7 +14928,7 @@ var TransactionToReviewCard = ({
14557
14928
  toReview,
14558
14929
  " pending"
14559
14930
  ) : null,
14560
- loadingStatus === "complete" && !error && toReview === 0 ? /* @__PURE__ */ React174.createElement(
14931
+ loaded === "complete" && !error && toReview === 0 ? /* @__PURE__ */ React174.createElement(
14561
14932
  Badge,
14562
14933
  {
14563
14934
  variant: "success" /* SUCCESS */,
@@ -14694,7 +15065,7 @@ var GeneralLedgerView = ({
14694
15065
  };
14695
15066
 
14696
15067
  // src/views/Reports/Reports.tsx
14697
- import React178, { useContext as useContext38, useRef as useRef15, useState as useState57 } from "react";
15068
+ import React178, { useContext as useContext38, useRef as useRef16, useState as useState57 } from "react";
14698
15069
  var DownloadButton2 = () => {
14699
15070
  const { dateRange } = useContext38(ProfitAndLoss.Context);
14700
15071
  const { auth, businessId, apiUrl } = useLayerContext();
@@ -14744,7 +15115,7 @@ var DownloadButton2 = () => {
14744
15115
  );
14745
15116
  };
14746
15117
  var Reports = ({ title = "Reports" }) => {
14747
- const containerRef = useRef15(null);
15118
+ const containerRef = useRef16(null);
14748
15119
  const [activeTab, setActiveTab] = useState57("profitAndLoss");
14749
15120
  return /* @__PURE__ */ React178.createElement(View, { title }, /* @__PURE__ */ React178.createElement("div", { className: "Layer__component Layer__header__actions" }, /* @__PURE__ */ React178.createElement(
14750
15121
  Toggle,
@@ -14784,10 +15155,10 @@ var ReportsPanel = ({ containerRef, openReport }) => {
14784
15155
  };
14785
15156
 
14786
15157
  // src/components/ProfitAndLossView/ProfitAndLossView.tsx
14787
- import React179, { useContext as useContext39, useRef as useRef16 } from "react";
15158
+ import React179, { useContext as useContext39, useRef as useRef17 } from "react";
14788
15159
  var COMPONENT_NAME7 = "profit-and-loss";
14789
15160
  var ProfitAndLossView = (props) => {
14790
- const containerRef = useRef16(null);
15161
+ const containerRef = useRef17(null);
14791
15162
  return /* @__PURE__ */ React179.createElement(Container, { name: COMPONENT_NAME7, ref: containerRef }, /* @__PURE__ */ React179.createElement(ProfitAndLoss, null, /* @__PURE__ */ React179.createElement(ProfitAndLossPanel, { containerRef, ...props })));
14792
15163
  };
14793
15164
  var ProfitAndLossPanel = ({
@@ -14844,10 +15215,12 @@ export {
14844
15215
  AccountingOverview,
14845
15216
  BalanceSheet,
14846
15217
  BankTransactions,
15218
+ BankTransactionsProvider,
14847
15219
  BankTransactionsWithLinkedAccounts,
14848
15220
  BookkeepingOverview,
14849
15221
  BookkeepingUpsellBar,
14850
15222
  ChartOfAccounts,
15223
+ DisplayState,
14851
15224
  GeneralLedgerView,
14852
15225
  Journal,
14853
15226
  LayerProvider,