@layerfi/components 0.1.51 → 0.1.53
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 +1299 -1253
- package/dist/esm/index.js.map +4 -4
- package/dist/index.d.ts +14 -7
- package/dist/index.js +1395 -1347
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/providers/LayerProvider/LayerProvider.tsx
|
|
2
|
-
import React7, { useReducer, useEffect as
|
|
2
|
+
import React7, { useReducer, useEffect as useEffect4 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/api/util.ts
|
|
5
5
|
var formStringFromObject = (object) => Object.entries(object).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
|
|
@@ -148,9 +148,12 @@ var getBankTransactions = get(
|
|
|
148
148
|
businessId,
|
|
149
149
|
cursor,
|
|
150
150
|
categorized,
|
|
151
|
+
direction,
|
|
152
|
+
startDate,
|
|
153
|
+
endDate,
|
|
151
154
|
sortBy = "date",
|
|
152
155
|
sortOrder = "DESC"
|
|
153
|
-
}) => `/v1/businesses/${businessId}/bank-transactions?${cursor ? `cursor=${cursor}&` : ""}${categorized !== void 0 && categorized !== "" ? `categorized=${categorized}&` : ""}sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
|
|
156
|
+
}) => `/v1/businesses/${businessId}/bank-transactions?${cursor !== void 0 && cursor !== "" ? `cursor=${cursor}&` : ""}${categorized !== void 0 && categorized !== "" ? `categorized=${categorized}&` : ""}${direction !== void 0 ? `direction=${direction}&` : ""}${startDate !== void 0 && startDate !== "" ? `start_date=${startDate}&` : ""}${endDate !== void 0 && endDate !== "" ? `end_date=${endDate}&` : ""}sort_by=${sortBy}&sort_order=${sortOrder}&limit=200`
|
|
154
157
|
);
|
|
155
158
|
var categorizeBankTransaction = put(
|
|
156
159
|
({ businessId, bankTransactionId }) => `/v1/businesses/${businessId}/bank-transactions/${bankTransactionId}/categorize`
|
|
@@ -491,6 +494,7 @@ var LayerContext = createContext2({
|
|
|
491
494
|
syncTimestamps: {},
|
|
492
495
|
readTimestamps: {},
|
|
493
496
|
hasBeenTouched: () => false,
|
|
497
|
+
expireDataCaches: () => void 0,
|
|
494
498
|
eventCallbacks: {}
|
|
495
499
|
});
|
|
496
500
|
var useLayerContext = () => useContext2(LayerContext);
|
|
@@ -547,9 +551,19 @@ var DEPENDENCIES = {
|
|
|
547
551
|
["CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */]: ALL_TOUCHABLE,
|
|
548
552
|
["JOURNAL" /* JOURNAL */]: ALL_TOUCHABLE,
|
|
549
553
|
["LEDGER_ACCOUNTS" /* LEDGER_ACCOUNTS */]: ALL_TOUCHABLE,
|
|
550
|
-
["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]:
|
|
554
|
+
["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]: [
|
|
555
|
+
"BUSINESS" /* BUSINESS */,
|
|
556
|
+
"LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */,
|
|
557
|
+
"CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */
|
|
558
|
+
],
|
|
551
559
|
["PROFIT_AND_LOSS" /* PROFIT_AND_LOSS */]: ALL_TOUCHABLE,
|
|
552
|
-
["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: ALL_TOUCHABLE
|
|
560
|
+
["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: ALL_TOUCHABLE,
|
|
561
|
+
["BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */]: [
|
|
562
|
+
"LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */,
|
|
563
|
+
"BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */,
|
|
564
|
+
"BUSINESS" /* BUSINESS */,
|
|
565
|
+
"CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */
|
|
566
|
+
]
|
|
553
567
|
};
|
|
554
568
|
var readTimestampsG = {};
|
|
555
569
|
var useDataSync = () => {
|
|
@@ -561,7 +575,8 @@ var useDataSync = () => {
|
|
|
561
575
|
["LEDGER_ACCOUNTS" /* LEDGER_ACCOUNTS */]: initialTimestamp,
|
|
562
576
|
["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]: initialTimestamp,
|
|
563
577
|
["PROFIT_AND_LOSS" /* PROFIT_AND_LOSS */]: initialTimestamp,
|
|
564
|
-
["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: initialTimestamp
|
|
578
|
+
["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: initialTimestamp,
|
|
579
|
+
["BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */]: initialTimestamp
|
|
565
580
|
});
|
|
566
581
|
const [readTimestamps, setReadTimestamps] = useState2({});
|
|
567
582
|
const touch = (model) => {
|
|
@@ -591,12 +606,26 @@ var useDataSync = () => {
|
|
|
591
606
|
})
|
|
592
607
|
);
|
|
593
608
|
};
|
|
609
|
+
const resetCaches = () => {
|
|
610
|
+
const now = Date.now();
|
|
611
|
+
setSyncTimestamps({
|
|
612
|
+
["BALANCE_SHEET" /* BALANCE_SHEET */]: now,
|
|
613
|
+
["CHART_OF_ACCOUNTS" /* CHART_OF_ACCOUNTS */]: now,
|
|
614
|
+
["JOURNAL" /* JOURNAL */]: now,
|
|
615
|
+
["LEDGER_ACCOUNTS" /* LEDGER_ACCOUNTS */]: now,
|
|
616
|
+
["LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */]: now,
|
|
617
|
+
["PROFIT_AND_LOSS" /* PROFIT_AND_LOSS */]: now,
|
|
618
|
+
["STATEMENT_OF_CASH_FLOWS" /* STATEMENT_OF_CASH_FLOWS */]: now,
|
|
619
|
+
["BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */]: now
|
|
620
|
+
});
|
|
621
|
+
};
|
|
594
622
|
return {
|
|
595
623
|
touch,
|
|
596
624
|
read,
|
|
597
625
|
syncTimestamps,
|
|
598
626
|
readTimestamps,
|
|
599
|
-
hasBeenTouched
|
|
627
|
+
hasBeenTouched,
|
|
628
|
+
resetCaches
|
|
600
629
|
};
|
|
601
630
|
};
|
|
602
631
|
|
|
@@ -628,12 +657,13 @@ import React6 from "react";
|
|
|
628
657
|
import { createContext as createContext3, useContext as useContext4 } from "react";
|
|
629
658
|
|
|
630
659
|
// src/types/bank_transactions.ts
|
|
631
|
-
var Direction = /* @__PURE__ */ ((
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
return
|
|
660
|
+
var Direction = /* @__PURE__ */ ((Direction2) => {
|
|
661
|
+
Direction2["CREDIT"] = "CREDIT";
|
|
662
|
+
Direction2["DEBIT"] = "DEBIT";
|
|
663
|
+
return Direction2;
|
|
635
664
|
})(Direction || {});
|
|
636
665
|
var DisplayState = /* @__PURE__ */ ((DisplayState2) => {
|
|
666
|
+
DisplayState2["all"] = "all";
|
|
637
667
|
DisplayState2["review"] = "review";
|
|
638
668
|
DisplayState2["categorized"] = "categorized";
|
|
639
669
|
return DisplayState2;
|
|
@@ -662,6 +692,7 @@ var BankTransactionsContext = createContext3({
|
|
|
662
692
|
pagination: void 0
|
|
663
693
|
},
|
|
664
694
|
updateOneLocal: () => void 0,
|
|
695
|
+
shouldHideAfterCategorize: () => false,
|
|
665
696
|
removeAfterCategorize: () => void 0,
|
|
666
697
|
activate: () => void 0,
|
|
667
698
|
display: "review" /* review */,
|
|
@@ -672,7 +703,7 @@ var BankTransactionsContext = createContext3({
|
|
|
672
703
|
var useBankTransactionsContext = () => useContext4(BankTransactionsContext);
|
|
673
704
|
|
|
674
705
|
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
675
|
-
import { useEffect as
|
|
706
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef, useState as useState5 } from "react";
|
|
676
707
|
|
|
677
708
|
// src/components/BankTransactions/constants.ts
|
|
678
709
|
var CategorizedCategories = [
|
|
@@ -686,1262 +717,1287 @@ var ReviewCategories = [
|
|
|
686
717
|
"LAYER_REVIEW" /* LAYER_REVIEW */
|
|
687
718
|
];
|
|
688
719
|
|
|
689
|
-
// src/
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
bankTransaction.categorization_status
|
|
693
|
-
);
|
|
694
|
-
const inReview = ReviewCategories.includes(
|
|
695
|
-
bankTransaction.categorization_status
|
|
696
|
-
);
|
|
697
|
-
return scope === "review" /* review */ && inReview || scope === "categorized" /* categorized */ && categorized;
|
|
698
|
-
};
|
|
699
|
-
var isCategorized = (bankTransaction) => CategorizedCategories.includes(bankTransaction.categorization_status);
|
|
720
|
+
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
721
|
+
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
722
|
+
import { usePlaidLink } from "react-plaid-link";
|
|
700
723
|
|
|
701
|
-
// src/hooks/
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
724
|
+
// src/hooks/useLinkedAccounts/mockData.ts
|
|
725
|
+
var LINKED_ACCOUNTS_MOCK_DATA = [
|
|
726
|
+
{
|
|
727
|
+
id: "d800ada8-8075-4436-a712-08efabcbd51a",
|
|
728
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
729
|
+
external_account_source: "PLAID",
|
|
730
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
731
|
+
mask: "1234",
|
|
732
|
+
latest_balance_timestamp: {
|
|
733
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
734
|
+
external_account_source: "PLAID",
|
|
735
|
+
balance: 435121,
|
|
736
|
+
at: "2024-04-03T13:00:00Z",
|
|
737
|
+
created_at: "2024-04-06T22:47:59.715458Z"
|
|
738
|
+
},
|
|
739
|
+
current_ledger_balance: 373717,
|
|
740
|
+
institution: {
|
|
741
|
+
name: "Chase",
|
|
742
|
+
logo: ""
|
|
743
|
+
},
|
|
744
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
745
|
+
connection_external_id: "11111",
|
|
746
|
+
connection_needs_repair_as_of: null,
|
|
747
|
+
requires_user_confirmation_as_of: null,
|
|
748
|
+
is_syncing: true
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
id: "f98ec50a-c370-484d-a35b-d00207436075",
|
|
752
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
753
|
+
external_account_source: "PLAID",
|
|
754
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
755
|
+
mask: "1234",
|
|
756
|
+
latest_balance_timestamp: {
|
|
757
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
758
|
+
external_account_source: "PLAID",
|
|
759
|
+
balance: 435121,
|
|
760
|
+
at: "2024-04-03T13:00:00Z",
|
|
761
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
762
|
+
},
|
|
763
|
+
current_ledger_balance: 373717,
|
|
764
|
+
institution: {
|
|
765
|
+
name: "Chase",
|
|
766
|
+
logo: ""
|
|
767
|
+
},
|
|
768
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
769
|
+
connection_external_id: "11111",
|
|
770
|
+
connection_needs_repair_as_of: null,
|
|
771
|
+
requires_user_confirmation_as_of: null,
|
|
772
|
+
is_syncing: false
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
id: "843f1748-fdaa-422d-a73d-2489a40c8dc7",
|
|
776
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
777
|
+
external_account_source: "PLAID",
|
|
778
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
779
|
+
mask: "1234",
|
|
780
|
+
latest_balance_timestamp: {
|
|
781
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
782
|
+
external_account_source: "PLAID",
|
|
783
|
+
balance: 435121,
|
|
784
|
+
at: "2024-04-03T13:00:00Z",
|
|
785
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
786
|
+
},
|
|
787
|
+
current_ledger_balance: 373717,
|
|
788
|
+
institution: {
|
|
789
|
+
name: "Chase",
|
|
790
|
+
logo: ""
|
|
791
|
+
},
|
|
792
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
793
|
+
connection_external_id: "11111",
|
|
794
|
+
connection_needs_repair_as_of: "2024-03-06T16:44:35.715458Z",
|
|
795
|
+
requires_user_confirmation_as_of: null,
|
|
796
|
+
is_syncing: false
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
id: "8f430e29-e339-4d71-a08a-fce469c7a7c1",
|
|
800
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
801
|
+
external_account_source: "PLAID",
|
|
802
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
803
|
+
mask: "1234",
|
|
804
|
+
latest_balance_timestamp: {
|
|
805
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
806
|
+
external_account_source: "PLAID",
|
|
807
|
+
balance: 435121,
|
|
808
|
+
at: "2024-04-03T13:00:00Z",
|
|
809
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
810
|
+
},
|
|
811
|
+
current_ledger_balance: 373717,
|
|
812
|
+
institution: {
|
|
813
|
+
name: "Chase",
|
|
814
|
+
logo: ""
|
|
815
|
+
},
|
|
816
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
817
|
+
connection_external_id: "11111",
|
|
818
|
+
connection_needs_repair_as_of: null,
|
|
819
|
+
requires_user_confirmation_as_of: "2024-03-06T16:44:35.715458Z",
|
|
820
|
+
is_syncing: false
|
|
744
821
|
}
|
|
745
|
-
|
|
746
|
-
(tx) => filterVisibility(filter, tx) || filter === "review" /* review */ && tx.recently_categorized || filter === "categorized" /* categorized */ && tx.recently_categorized
|
|
747
|
-
);
|
|
748
|
-
};
|
|
749
|
-
var appplyDateRangeFilter = (data, filter) => {
|
|
750
|
-
return data?.filter((x) => {
|
|
751
|
-
const txDate = parseISO(x.date);
|
|
752
|
-
if (filter?.startDate && filter?.endDate) {
|
|
753
|
-
return txDate >= filter.startDate && txDate <= filter.endDate;
|
|
754
|
-
}
|
|
755
|
-
if (filter?.startDate) {
|
|
756
|
-
return txDate >= filter.startDate;
|
|
757
|
-
}
|
|
758
|
-
if (filter?.endDate) {
|
|
759
|
-
return txDate <= filter.endDate;
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
};
|
|
822
|
+
];
|
|
763
823
|
|
|
764
|
-
// src/hooks/
|
|
765
|
-
import
|
|
766
|
-
var
|
|
824
|
+
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
825
|
+
import useSWR from "swr";
|
|
826
|
+
var DEBUG = true;
|
|
827
|
+
var USE_MOCK_RESPONSE_DATA = false;
|
|
828
|
+
var useLinkedAccounts = () => {
|
|
767
829
|
const {
|
|
768
830
|
auth,
|
|
769
831
|
businessId,
|
|
770
832
|
apiUrl,
|
|
771
|
-
|
|
833
|
+
usePlaidSandbox,
|
|
772
834
|
touch,
|
|
773
835
|
read,
|
|
774
836
|
syncTimestamps,
|
|
775
|
-
hasBeenTouched
|
|
776
|
-
eventCallbacks
|
|
837
|
+
hasBeenTouched
|
|
777
838
|
} = useLayerContext();
|
|
778
|
-
const
|
|
779
|
-
const [filters, setTheFilters] = useState4(
|
|
780
|
-
scope ? { categorizationStatus: scope } : void 0
|
|
781
|
-
);
|
|
782
|
-
const display = useMemo2(() => {
|
|
783
|
-
if (filters?.categorizationStatus === "review" /* review */) {
|
|
784
|
-
return "review" /* review */;
|
|
785
|
-
}
|
|
786
|
-
return "categorized" /* categorized */;
|
|
787
|
-
}, [filters?.categorizationStatus]);
|
|
788
|
-
const [active, setActive] = useState4(false);
|
|
839
|
+
const [linkToken, setLinkToken] = useState4(null);
|
|
789
840
|
const [loadingStatus, setLoadingStatus] = useState4("initial");
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
}
|
|
794
|
-
if (!prevData?.meta?.pagination?.cursor) {
|
|
795
|
-
return [
|
|
796
|
-
businessId && auth?.access_token && `bank-transactions-${businessId}`,
|
|
797
|
-
void 0
|
|
798
|
-
];
|
|
799
|
-
}
|
|
800
|
-
return [
|
|
801
|
-
businessId && auth?.access_token && `bank-transactions-${businessId}-${prevData.meta.pagination.cursor}`,
|
|
802
|
-
prevData.meta.pagination.cursor
|
|
803
|
-
];
|
|
804
|
-
};
|
|
841
|
+
const USE_PLAID_SANDBOX = usePlaidSandbox ?? true;
|
|
842
|
+
const [linkMode, setLinkMode] = useState4("add");
|
|
843
|
+
const queryKey = businessId && auth?.access_token && `linked-accounts-${businessId}`;
|
|
805
844
|
const {
|
|
806
|
-
data:
|
|
845
|
+
data: responseData,
|
|
807
846
|
isLoading,
|
|
808
847
|
isValidating,
|
|
809
848
|
error: responseError,
|
|
810
|
-
mutate
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
if (auth?.access_token) {
|
|
817
|
-
return Layer.getBankTransactions(apiUrl, auth?.access_token, {
|
|
818
|
-
params: {
|
|
819
|
-
businessId,
|
|
820
|
-
cursor: nextCursor
|
|
821
|
-
}
|
|
822
|
-
}).call(false);
|
|
823
|
-
}
|
|
824
|
-
return {};
|
|
825
|
-
},
|
|
826
|
-
{
|
|
827
|
-
initialSize: 1,
|
|
828
|
-
revalidateFirstPage: false
|
|
829
|
-
}
|
|
830
|
-
);
|
|
831
|
-
const data = useMemo2(() => {
|
|
832
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
833
|
-
return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
|
|
834
|
-
}
|
|
835
|
-
return void 0;
|
|
836
|
-
}, [rawResponseData]);
|
|
837
|
-
const lastMetadata = useMemo2(() => {
|
|
838
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
839
|
-
return rawResponseData[rawResponseData.length - 1].meta;
|
|
840
|
-
}
|
|
841
|
-
return void 0;
|
|
842
|
-
}, [rawResponseData]);
|
|
843
|
-
const hasMore = useMemo2(() => {
|
|
844
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
845
|
-
const lastElement = rawResponseData[rawResponseData.length - 1];
|
|
846
|
-
return Boolean(
|
|
847
|
-
lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more
|
|
848
|
-
);
|
|
849
|
-
}
|
|
850
|
-
return false;
|
|
851
|
-
}, [rawResponseData]);
|
|
852
|
-
const accountsList = useMemo2(
|
|
853
|
-
() => data ? collectAccounts(data) : [],
|
|
854
|
-
[data]
|
|
849
|
+
mutate
|
|
850
|
+
} = useSWR(
|
|
851
|
+
queryKey,
|
|
852
|
+
Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
|
|
853
|
+
params: { businessId }
|
|
854
|
+
})
|
|
855
855
|
);
|
|
856
856
|
useEffect2(() => {
|
|
857
|
+
if (!isLoading && responseData?.data.external_accounts) {
|
|
858
|
+
setLoadingStatus("complete");
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
857
861
|
if (isLoading && loadingStatus === "initial") {
|
|
858
862
|
setLoadingStatus("loading");
|
|
859
863
|
return;
|
|
860
864
|
}
|
|
861
865
|
if (!isLoading && loadingStatus === "loading") {
|
|
862
866
|
setLoadingStatus("complete");
|
|
863
|
-
return;
|
|
864
867
|
}
|
|
865
868
|
}, [isLoading]);
|
|
866
|
-
const
|
|
867
|
-
|
|
869
|
+
const fetchPlaidLinkToken = async () => {
|
|
870
|
+
if (auth?.access_token) {
|
|
871
|
+
const linkToken2 = (await Layer.getPlaidLinkToken(apiUrl, auth.access_token, {
|
|
872
|
+
params: { businessId }
|
|
873
|
+
})).data.link_token;
|
|
874
|
+
setLinkMode("add");
|
|
875
|
+
setLinkToken(linkToken2);
|
|
876
|
+
}
|
|
868
877
|
};
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
878
|
+
const fetchPlaidUpdateModeLinkToken = async (plaidItemPlaidId) => {
|
|
879
|
+
if (auth?.access_token) {
|
|
880
|
+
const linkToken2 = (await Layer.getPlaidUpdateModeLinkToken(apiUrl, auth.access_token, {
|
|
881
|
+
params: { businessId },
|
|
882
|
+
body: { plaid_item_id: plaidItemPlaidId }
|
|
883
|
+
})).data.link_token;
|
|
884
|
+
setLinkMode("update");
|
|
885
|
+
setLinkToken(linkToken2);
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
const exchangePlaidPublicToken2 = async (publicToken, metadata) => {
|
|
889
|
+
await Layer.exchangePlaidPublicToken(apiUrl, auth?.access_token, {
|
|
890
|
+
params: { businessId },
|
|
891
|
+
body: { public_token: publicToken, institution: metadata.institution }
|
|
873
892
|
});
|
|
893
|
+
refetchAccounts();
|
|
874
894
|
};
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
895
|
+
const { open: plaidLinkStart, ready: plaidLinkReady } = usePlaidLink({
|
|
896
|
+
token: linkToken,
|
|
897
|
+
// If in update mode, we don't need to exchange the public token for an access token.
|
|
898
|
+
// The existing access token will automatically become valid again
|
|
899
|
+
onSuccess: async (publicToken, metadata) => {
|
|
900
|
+
if (linkMode == "add") {
|
|
901
|
+
exchangePlaidPublicToken2(publicToken, metadata);
|
|
902
|
+
} else {
|
|
903
|
+
await updateConnectionStatus2();
|
|
904
|
+
refetchAccounts();
|
|
905
|
+
setLinkMode("add");
|
|
906
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
907
|
+
}
|
|
908
|
+
},
|
|
909
|
+
onExit: () => setLinkMode("add"),
|
|
910
|
+
env: USE_PLAID_SANDBOX ? "sandbox" : void 0
|
|
911
|
+
});
|
|
912
|
+
useEffect2(() => {
|
|
913
|
+
if (plaidLinkReady) {
|
|
914
|
+
plaidLinkStart();
|
|
888
915
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
916
|
+
}, [plaidLinkStart, plaidLinkReady]);
|
|
917
|
+
const mockResponseData = {
|
|
918
|
+
data: LINKED_ACCOUNTS_MOCK_DATA,
|
|
919
|
+
meta: {},
|
|
920
|
+
error: void 0
|
|
921
|
+
};
|
|
922
|
+
const addConnection = (source) => {
|
|
923
|
+
if (source === "PLAID") {
|
|
924
|
+
fetchPlaidLinkToken();
|
|
925
|
+
} else {
|
|
926
|
+
console.error(
|
|
927
|
+
`Adding a connection with source ${source} not yet supported`
|
|
893
928
|
);
|
|
894
929
|
}
|
|
895
|
-
|
|
896
|
-
|
|
930
|
+
};
|
|
931
|
+
const repairConnection = async (source, connectionExternalId) => {
|
|
932
|
+
if (source === "PLAID") {
|
|
933
|
+
await fetchPlaidUpdateModeLinkToken(connectionExternalId);
|
|
934
|
+
} else {
|
|
935
|
+
console.error(
|
|
936
|
+
`Repairing a connection with source ${source} not yet supported`
|
|
937
|
+
);
|
|
897
938
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
939
|
+
};
|
|
940
|
+
const removeConnection = async (source, connectionExternalId) => {
|
|
941
|
+
if (source === "PLAID") {
|
|
942
|
+
await unlinkPlaidItem2(connectionExternalId);
|
|
943
|
+
await refetchAccounts();
|
|
944
|
+
} else {
|
|
945
|
+
console.error(
|
|
946
|
+
`Removing a connection with source ${source} not yet supported`
|
|
947
|
+
);
|
|
904
948
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (newBT?.recently_categorized === true && notify) {
|
|
918
|
-
addToast({ content: "Transaction saved" });
|
|
919
|
-
}
|
|
920
|
-
}).catch((err) => {
|
|
921
|
-
const newBT = data?.find(
|
|
922
|
-
(x) => x.business_id === businessId && x.id === id
|
|
949
|
+
};
|
|
950
|
+
const unlinkAccount2 = async (source, accountId) => {
|
|
951
|
+
DEBUG && console.log("unlinking account");
|
|
952
|
+
if (source === "PLAID") {
|
|
953
|
+
await Layer.unlinkAccount(apiUrl, auth?.access_token, {
|
|
954
|
+
params: { businessId, accountId }
|
|
955
|
+
});
|
|
956
|
+
await refetchAccounts();
|
|
957
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
958
|
+
} else {
|
|
959
|
+
console.error(
|
|
960
|
+
`Unlinking an account with source ${source} not yet supported`
|
|
923
961
|
);
|
|
924
|
-
|
|
925
|
-
updateOneLocal({
|
|
926
|
-
...newBT,
|
|
927
|
-
error: err.message,
|
|
928
|
-
processing: false
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
}).finally(() => {
|
|
932
|
-
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
933
|
-
eventCallbacks?.onTransactionCategorized?.(id);
|
|
934
|
-
});
|
|
962
|
+
}
|
|
935
963
|
};
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
if (
|
|
939
|
-
|
|
964
|
+
const confirmAccount = async (source, accountId) => {
|
|
965
|
+
DEBUG && console.log("confirming account");
|
|
966
|
+
if (source === "PLAID") {
|
|
967
|
+
await Layer.confirmConnection(apiUrl, auth?.access_token, {
|
|
968
|
+
params: {
|
|
969
|
+
businessId,
|
|
970
|
+
accountId
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
await refetchAccounts();
|
|
974
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
975
|
+
} else {
|
|
976
|
+
console.error(
|
|
977
|
+
`Confirming an account with source ${source} not yet supported`
|
|
978
|
+
);
|
|
940
979
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
980
|
+
};
|
|
981
|
+
const denyAccount = async (source, accountId) => {
|
|
982
|
+
DEBUG && console.log("confirming account");
|
|
983
|
+
if (source === "PLAID") {
|
|
984
|
+
await Layer.denyConnection(apiUrl, auth?.access_token, {
|
|
985
|
+
params: {
|
|
986
|
+
businessId,
|
|
987
|
+
accountId
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
await refetchAccounts();
|
|
991
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
992
|
+
} else {
|
|
993
|
+
console.error(
|
|
994
|
+
`Denying an account with source ${source} not yet supported`
|
|
947
995
|
);
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
const breakConnection = async (source, connectionExternalId) => {
|
|
999
|
+
DEBUG && console.log("Breaking sandbox plaid item connection");
|
|
1000
|
+
if (source === "PLAID") {
|
|
1001
|
+
await Layer.breakPlaidItemConnection(apiUrl, auth?.access_token, {
|
|
1002
|
+
params: {
|
|
1003
|
+
businessId,
|
|
1004
|
+
plaidItemPlaidId: connectionExternalId
|
|
1005
|
+
}
|
|
1006
|
+
});
|
|
1007
|
+
await refetchAccounts();
|
|
1008
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1009
|
+
} else {
|
|
1010
|
+
console.error(
|
|
1011
|
+
`Breaking a sandbox connection with source ${source} not yet supported`
|
|
964
1012
|
);
|
|
965
|
-
|
|
966
|
-
updateOneLocal({
|
|
967
|
-
...newBT,
|
|
968
|
-
error: err.message,
|
|
969
|
-
processing: false
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
}).finally(() => {
|
|
973
|
-
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
974
|
-
eventCallbacks?.onTransactionCategorized?.(id);
|
|
975
|
-
});
|
|
1013
|
+
}
|
|
976
1014
|
};
|
|
977
|
-
const
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
...page,
|
|
981
|
-
data: page.data?.map(
|
|
982
|
-
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
983
|
-
)
|
|
984
|
-
};
|
|
985
|
-
});
|
|
986
|
-
mutate(updatedData, { revalidate: false });
|
|
1015
|
+
const refetchAccounts = async () => {
|
|
1016
|
+
DEBUG && console.log("refetching accounts...");
|
|
1017
|
+
await mutate();
|
|
987
1018
|
};
|
|
988
|
-
const
|
|
1019
|
+
const syncAccounts = async () => {
|
|
1020
|
+
DEBUG && console.log("resyncing accounts...");
|
|
1021
|
+
await Layer.syncConnection(apiUrl, auth?.access_token, {
|
|
1022
|
+
params: { businessId }
|
|
1023
|
+
});
|
|
989
1024
|
};
|
|
990
|
-
const
|
|
991
|
-
|
|
1025
|
+
const updateConnectionStatus2 = async () => {
|
|
1026
|
+
DEBUG && console.log("updating connection status...");
|
|
1027
|
+
await Layer.updateConnectionStatus(apiUrl, auth?.access_token, {
|
|
1028
|
+
params: { businessId }
|
|
1029
|
+
});
|
|
992
1030
|
};
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1031
|
+
const unlinkPlaidItem2 = async (plaidItemPlaidId) => {
|
|
1032
|
+
DEBUG && console.log("unlinking plaid item");
|
|
1033
|
+
await Layer.unlinkPlaidItem(apiUrl, auth?.access_token, {
|
|
1034
|
+
params: { businessId, plaidItemPlaidId }
|
|
1035
|
+
});
|
|
1036
|
+
await refetchAccounts();
|
|
1037
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
997
1038
|
};
|
|
998
1039
|
useEffect2(() => {
|
|
999
|
-
if (isLoading || isValidating) {
|
|
1000
|
-
read("
|
|
1040
|
+
if (queryKey && (isLoading || isValidating)) {
|
|
1041
|
+
read("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */, queryKey);
|
|
1001
1042
|
}
|
|
1002
1043
|
}, [isLoading, isValidating]);
|
|
1003
1044
|
useEffect2(() => {
|
|
1004
|
-
if (hasBeenTouched(
|
|
1005
|
-
|
|
1045
|
+
if (queryKey && hasBeenTouched(queryKey)) {
|
|
1046
|
+
refetchAccounts();
|
|
1006
1047
|
}
|
|
1007
1048
|
}, [syncTimestamps]);
|
|
1008
1049
|
return {
|
|
1009
|
-
data:
|
|
1010
|
-
metadata: lastMetadata,
|
|
1011
|
-
loadingStatus,
|
|
1050
|
+
data: USE_MOCK_RESPONSE_DATA ? mockResponseData.data : responseData?.data.external_accounts,
|
|
1012
1051
|
isLoading,
|
|
1052
|
+
loadingStatus,
|
|
1013
1053
|
isValidating,
|
|
1014
|
-
refetch,
|
|
1015
1054
|
error: responseError,
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
hasMore
|
|
1055
|
+
addConnection,
|
|
1056
|
+
removeConnection,
|
|
1057
|
+
repairConnection,
|
|
1058
|
+
refetchAccounts,
|
|
1059
|
+
unlinkAccount: unlinkAccount2,
|
|
1060
|
+
confirmAccount,
|
|
1061
|
+
denyAccount,
|
|
1062
|
+
breakConnection,
|
|
1063
|
+
syncAccounts,
|
|
1064
|
+
updateConnectionStatus: updateConnectionStatus2
|
|
1027
1065
|
};
|
|
1028
1066
|
};
|
|
1029
1067
|
|
|
1030
|
-
// src/
|
|
1031
|
-
var
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
return /* @__PURE__ */ React6.createElement(BankTransactionsContext.Provider, { value: bankTransactionsContextData }, children);
|
|
1036
|
-
};
|
|
1037
|
-
|
|
1038
|
-
// src/config/theme.ts
|
|
1039
|
-
var SHADES = {
|
|
1040
|
-
50: { s: 1, l: 98 },
|
|
1041
|
-
100: { s: 1, l: 96 },
|
|
1042
|
-
200: { s: 1, l: 94 },
|
|
1043
|
-
300: { s: 2, l: 92 },
|
|
1044
|
-
500: { s: 5, l: 53 },
|
|
1045
|
-
600: { s: 7, l: 40 },
|
|
1046
|
-
700: { s: 9, l: 27 },
|
|
1047
|
-
800: { s: 12, l: 20 },
|
|
1048
|
-
1e3: { s: 20, l: 7 }
|
|
1049
|
-
};
|
|
1050
|
-
var COLORS = {
|
|
1051
|
-
dark: {
|
|
1052
|
-
h: 0,
|
|
1053
|
-
s: 0,
|
|
1054
|
-
l: 7
|
|
1055
|
-
},
|
|
1056
|
-
light: {
|
|
1057
|
-
h: 0,
|
|
1058
|
-
s: 0,
|
|
1059
|
-
l: 100
|
|
1068
|
+
// src/hooks/useBankTransactions/utils.ts
|
|
1069
|
+
var collectAccounts = (transactions) => {
|
|
1070
|
+
const accounts = [];
|
|
1071
|
+
if (!transactions) {
|
|
1072
|
+
return accounts;
|
|
1060
1073
|
}
|
|
1074
|
+
transactions.forEach((x) => {
|
|
1075
|
+
if (!accounts.find((y) => y.id === x.source_account_id)) {
|
|
1076
|
+
accounts.push({
|
|
1077
|
+
id: x.source_account_id,
|
|
1078
|
+
name: x.account_name || ""
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
return accounts.sort((a, b) => a.name.localeCompare(b.name));
|
|
1061
1083
|
};
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
}
|
|
1075
|
-
return styles;
|
|
1084
|
+
var applyAmountFilter = (data, filter) => {
|
|
1085
|
+
return data?.filter((x) => {
|
|
1086
|
+
if ((filter?.min || filter?.min === 0) && (filter?.max || filter?.max === 0)) {
|
|
1087
|
+
return x.amount >= filter.min * 100 && x.amount <= filter.max * 100;
|
|
1088
|
+
}
|
|
1089
|
+
if (filter?.min || filter?.min === 0) {
|
|
1090
|
+
return x.amount >= filter.min * 100;
|
|
1091
|
+
}
|
|
1092
|
+
if (filter?.max || filter?.max === 0) {
|
|
1093
|
+
return x.amount <= filter.max * 100;
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1076
1096
|
};
|
|
1077
|
-
var
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1097
|
+
var applyAccountFilter = (data, filter) => data?.filter((x) => filter && filter.includes(x.source_account_id));
|
|
1098
|
+
|
|
1099
|
+
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
1100
|
+
import useSWRInfinite from "swr/infinite";
|
|
1101
|
+
var INITIAL_POLL_INTERVAL_MS = 1e3;
|
|
1102
|
+
var POLL_INTERVAL_AFTER_TXNS_RECEIVED_MS = 5e3;
|
|
1103
|
+
function useTriggerOnChange(data, anyAccountSyncing, callback) {
|
|
1104
|
+
const prevDataRef = useRef();
|
|
1105
|
+
useEffect3(() => {
|
|
1106
|
+
if (anyAccountSyncing && prevDataRef.current !== void 0 && prevDataRef.current !== data) {
|
|
1107
|
+
callback(data);
|
|
1084
1108
|
}
|
|
1085
|
-
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1109
|
+
prevDataRef.current = data;
|
|
1110
|
+
}, [data, anyAccountSyncing, callback]);
|
|
1111
|
+
}
|
|
1112
|
+
var filtersSettingString = (filters) => {
|
|
1113
|
+
return `bank-transactions${filters?.categorizationStatus ? `-categorizationStatus-${filters.categorizationStatus}` : `-categorizationStatus-${"all" /* all */}`}${filters?.direction?.length === 1 ? `-direction-${filters.direction.join("-")}` : ""}${filters?.dateRange?.startDate ? `-startDate-${filters.dateRange.startDate.toISOString()}` : ""}${filters?.dateRange?.endDate ? `-endDate-${filters.dateRange.endDate.toISOString()}` : ""}`;
|
|
1089
1114
|
};
|
|
1090
|
-
var
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1115
|
+
var useBankTransactions = (params) => {
|
|
1116
|
+
const {
|
|
1117
|
+
auth,
|
|
1118
|
+
businessId,
|
|
1119
|
+
apiUrl,
|
|
1120
|
+
addToast,
|
|
1121
|
+
touch,
|
|
1122
|
+
read,
|
|
1123
|
+
syncTimestamps,
|
|
1124
|
+
hasBeenTouched,
|
|
1125
|
+
eventCallbacks
|
|
1126
|
+
} = useLayerContext();
|
|
1127
|
+
const { scope = void 0 } = params ?? {};
|
|
1128
|
+
const [filters, setTheFilters] = useState5(
|
|
1129
|
+
scope ? { categorizationStatus: scope } : void 0
|
|
1130
|
+
);
|
|
1131
|
+
const display = useMemo2(() => {
|
|
1132
|
+
if (filters?.categorizationStatus === "review" /* review */) {
|
|
1133
|
+
return "review" /* review */;
|
|
1134
|
+
} else if (filters?.categorizationStatus === "all" /* all */) {
|
|
1135
|
+
return "all" /* all */;
|
|
1101
1136
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1137
|
+
return "categorized" /* categorized */;
|
|
1138
|
+
}, [filters?.categorizationStatus]);
|
|
1139
|
+
const [active, setActive] = useState5(false);
|
|
1140
|
+
const [loadingStatus, setLoadingStatus] = useState5("initial");
|
|
1141
|
+
const getKey = (index, prevData) => {
|
|
1142
|
+
if (!auth?.access_token || !active) {
|
|
1143
|
+
return [false, void 0];
|
|
1109
1144
|
}
|
|
1110
|
-
if (
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1145
|
+
if (index === 0) {
|
|
1146
|
+
return [
|
|
1147
|
+
businessId && auth?.access_token && `${filtersSettingString(filters)}-${businessId}`,
|
|
1148
|
+
void 0
|
|
1149
|
+
];
|
|
1150
|
+
}
|
|
1151
|
+
return [
|
|
1152
|
+
businessId && auth?.access_token && `${filtersSettingString(filters)}-${businessId}-${prevData?.meta?.pagination?.cursor}`,
|
|
1153
|
+
prevData?.meta?.pagination?.cursor.toString()
|
|
1154
|
+
];
|
|
1155
|
+
};
|
|
1156
|
+
const {
|
|
1157
|
+
data: rawResponseData,
|
|
1158
|
+
isLoading,
|
|
1159
|
+
isValidating,
|
|
1160
|
+
error: responseError,
|
|
1161
|
+
mutate,
|
|
1162
|
+
size,
|
|
1163
|
+
setSize
|
|
1164
|
+
} = useSWRInfinite(
|
|
1165
|
+
getKey,
|
|
1166
|
+
async ([_query, nextCursor]) => {
|
|
1167
|
+
if (auth?.access_token) {
|
|
1168
|
+
return Layer.getBankTransactions(apiUrl, auth?.access_token, {
|
|
1169
|
+
params: {
|
|
1170
|
+
businessId,
|
|
1171
|
+
cursor: nextCursor ?? "",
|
|
1172
|
+
categorized: filters?.categorizationStatus ? filters?.categorizationStatus === "categorized" /* categorized */ ? "true" : filters?.categorizationStatus === "review" /* review */ ? "false" : "" : "",
|
|
1173
|
+
direction: filters?.direction?.length === 1 ? filters.direction[0] === "CREDIT" /* CREDIT */ ? "INFLOW" : "OUTFLOW" : void 0,
|
|
1174
|
+
startDate: filters?.dateRange?.startDate?.toISOString() ?? void 0,
|
|
1175
|
+
endDate: filters?.dateRange?.endDate?.toISOString() ?? void 0
|
|
1176
|
+
}
|
|
1177
|
+
}).call(false);
|
|
1114
1178
|
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
return {
|
|
1121
|
-
[`--color-${colorName}-h`]: h,
|
|
1122
|
-
[`--color-${colorName}-s`]: `${s}%`,
|
|
1123
|
-
[`--color-${colorName}-l`]: `${l}%`
|
|
1124
|
-
};
|
|
1179
|
+
return {};
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
initialSize: 1,
|
|
1183
|
+
revalidateFirstPage: false
|
|
1125
1184
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
};
|
|
1131
|
-
var parseColorFromThemeToHsl = (color) => {
|
|
1132
|
-
if (!color) {
|
|
1133
|
-
return;
|
|
1134
|
-
}
|
|
1135
|
-
try {
|
|
1136
|
-
if ("h" in color && "s" in color && "l" in color) {
|
|
1137
|
-
return {
|
|
1138
|
-
h: Number(color.h),
|
|
1139
|
-
s: Number(color.s),
|
|
1140
|
-
l: Number(color.l)
|
|
1141
|
-
};
|
|
1185
|
+
);
|
|
1186
|
+
const data = useMemo2(() => {
|
|
1187
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1188
|
+
return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
|
|
1142
1189
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
l
|
|
1149
|
-
};
|
|
1190
|
+
return void 0;
|
|
1191
|
+
}, [rawResponseData]);
|
|
1192
|
+
const lastMetadata = useMemo2(() => {
|
|
1193
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1194
|
+
return rawResponseData[rawResponseData.length - 1].meta;
|
|
1150
1195
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
b: rgb.b.toString()
|
|
1160
|
-
});
|
|
1161
|
-
return {
|
|
1162
|
-
h,
|
|
1163
|
-
s,
|
|
1164
|
-
l
|
|
1165
|
-
};
|
|
1196
|
+
return void 0;
|
|
1197
|
+
}, [rawResponseData]);
|
|
1198
|
+
const hasMore = useMemo2(() => {
|
|
1199
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1200
|
+
const lastElement = rawResponseData[rawResponseData.length - 1];
|
|
1201
|
+
return Boolean(
|
|
1202
|
+
lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more
|
|
1203
|
+
);
|
|
1166
1204
|
}
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
l: 100 * (2 * l - s) / 2
|
|
1186
|
-
};
|
|
1187
|
-
};
|
|
1188
|
-
var hexToRgb = (hex) => {
|
|
1189
|
-
const values = hex.replace(
|
|
1190
|
-
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
|
1191
|
-
(m, r, g, b) => "#" + r + r + g + g + b + b
|
|
1192
|
-
).substring(1).match(/.{2}/g)?.map((x) => parseInt(x, 16));
|
|
1193
|
-
if (!values) {
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
return {
|
|
1197
|
-
r: values[0],
|
|
1198
|
-
g: values[1],
|
|
1199
|
-
b: values[2]
|
|
1205
|
+
return false;
|
|
1206
|
+
}, [rawResponseData]);
|
|
1207
|
+
const accountsList = useMemo2(
|
|
1208
|
+
() => data ? collectAccounts(data) : [],
|
|
1209
|
+
[data]
|
|
1210
|
+
);
|
|
1211
|
+
useEffect3(() => {
|
|
1212
|
+
if (isLoading && loadingStatus === "initial") {
|
|
1213
|
+
setLoadingStatus("loading");
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
if (!isLoading && loadingStatus === "loading") {
|
|
1217
|
+
setLoadingStatus("complete");
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
}, [isLoading]);
|
|
1221
|
+
const activate = () => {
|
|
1222
|
+
setActive(true);
|
|
1200
1223
|
};
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
50: buildColorShade(50, darkColor),
|
|
1207
|
-
100: buildColorShade(100, darkColor),
|
|
1208
|
-
200: buildColorShade(200, darkColor),
|
|
1209
|
-
300: buildColorShade(300, darkColor),
|
|
1210
|
-
400: {
|
|
1211
|
-
hsl: lightColor,
|
|
1212
|
-
rgb: hslToRgb(lightColor),
|
|
1213
|
-
hex: hslToHex(lightColor)
|
|
1214
|
-
},
|
|
1215
|
-
500: buildColorShade(500, darkColor),
|
|
1216
|
-
600: buildColorShade(600, darkColor),
|
|
1217
|
-
700: buildColorShade(700, darkColor),
|
|
1218
|
-
800: buildColorShade(800, darkColor),
|
|
1219
|
-
900: {
|
|
1220
|
-
hsl: darkColor,
|
|
1221
|
-
rgb: hslToRgb(darkColor),
|
|
1222
|
-
hex: hslToHex(darkColor)
|
|
1223
|
-
},
|
|
1224
|
-
1e3: buildColorShade(1e3, darkColor)
|
|
1224
|
+
const setFilters = (value) => {
|
|
1225
|
+
setTheFilters({
|
|
1226
|
+
...filters,
|
|
1227
|
+
...value ?? {}
|
|
1228
|
+
});
|
|
1225
1229
|
};
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1230
|
+
const filteredData = useMemo2(() => {
|
|
1231
|
+
let filtered = data;
|
|
1232
|
+
if (!filtered) {
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
if (filters?.amount?.min || filters?.amount?.max) {
|
|
1236
|
+
filtered = applyAmountFilter(filtered, filters.amount);
|
|
1237
|
+
}
|
|
1238
|
+
if (filters?.account) {
|
|
1239
|
+
filtered = applyAccountFilter(filtered, filters.account);
|
|
1240
|
+
}
|
|
1241
|
+
return filtered;
|
|
1242
|
+
}, [filters, data]);
|
|
1243
|
+
const categorize = (id, newCategory, notify) => {
|
|
1244
|
+
const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
|
|
1245
|
+
if (foundBT) {
|
|
1246
|
+
updateOneLocal({ ...foundBT, processing: true, error: void 0 });
|
|
1247
|
+
}
|
|
1248
|
+
return Layer.categorizeBankTransaction(apiUrl, auth.access_token, {
|
|
1249
|
+
params: { businessId, bankTransactionId: id },
|
|
1250
|
+
body: newCategory
|
|
1251
|
+
}).then(({ data: newBT, errors }) => {
|
|
1252
|
+
if (newBT) {
|
|
1253
|
+
newBT.recently_categorized = true;
|
|
1254
|
+
updateOneLocal(newBT);
|
|
1255
|
+
}
|
|
1256
|
+
if (errors) {
|
|
1257
|
+
console.error(errors);
|
|
1258
|
+
throw errors;
|
|
1259
|
+
}
|
|
1260
|
+
if (newBT?.recently_categorized === true && notify) {
|
|
1261
|
+
addToast({ content: "Transaction saved" });
|
|
1262
|
+
}
|
|
1263
|
+
}).catch((err) => {
|
|
1264
|
+
const newBT = data?.find(
|
|
1265
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1266
|
+
);
|
|
1267
|
+
if (newBT) {
|
|
1268
|
+
updateOneLocal({
|
|
1269
|
+
...newBT,
|
|
1270
|
+
error: err.message,
|
|
1271
|
+
processing: false
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
}).finally(() => {
|
|
1275
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1276
|
+
eventCallbacks?.onTransactionCategorized?.(id);
|
|
1277
|
+
});
|
|
1263
1278
|
};
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1279
|
+
const match = (id, matchId, notify) => {
|
|
1280
|
+
const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
|
|
1281
|
+
if (foundBT) {
|
|
1282
|
+
updateOneLocal({ ...foundBT, processing: true, error: void 0 });
|
|
1283
|
+
}
|
|
1284
|
+
return Layer.matchBankTransaction(apiUrl, auth.access_token, {
|
|
1285
|
+
params: { businessId, bankTransactionId: id },
|
|
1286
|
+
body: { match_id: matchId, type: "Confirm_Match" /* CONFIRM_MATCH */ }
|
|
1287
|
+
}).then(({ data: bt, errors }) => {
|
|
1288
|
+
const newBT = data?.find(
|
|
1289
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1290
|
+
);
|
|
1291
|
+
if (newBT) {
|
|
1292
|
+
newBT.recently_categorized = true;
|
|
1293
|
+
newBT.match = bt;
|
|
1294
|
+
newBT.categorization_status = "MATCHED" /* MATCHED */;
|
|
1295
|
+
updateOneLocal(newBT);
|
|
1296
|
+
}
|
|
1297
|
+
if (errors) {
|
|
1298
|
+
console.error(errors);
|
|
1299
|
+
throw errors;
|
|
1300
|
+
}
|
|
1301
|
+
if (newBT?.recently_categorized === true && notify) {
|
|
1302
|
+
addToast({ content: "Transaction saved" });
|
|
1303
|
+
}
|
|
1304
|
+
}).catch((err) => {
|
|
1305
|
+
const newBT = data?.find(
|
|
1306
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1307
|
+
);
|
|
1308
|
+
if (newBT) {
|
|
1309
|
+
updateOneLocal({
|
|
1310
|
+
...newBT,
|
|
1311
|
+
error: err.message,
|
|
1312
|
+
processing: false
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
}).finally(() => {
|
|
1316
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1317
|
+
eventCallbacks?.onTransactionCategorized?.(id);
|
|
1318
|
+
});
|
|
1273
1319
|
};
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
// src/providers/LayerProvider/LayerProvider.tsx
|
|
1278
|
-
import { add, isBefore } from "date-fns";
|
|
1279
|
-
import useSWR, { SWRConfig } from "swr";
|
|
1280
|
-
var reducer = (state, action) => {
|
|
1281
|
-
switch (action.type) {
|
|
1282
|
-
case "LayerContext.setAuth" /* setAuth */:
|
|
1283
|
-
case "LayerContext.setBusiness" /* setBusiness */:
|
|
1284
|
-
case "LayerContext.setCategories" /* setCategories */:
|
|
1285
|
-
case "LayerContext.setTheme" /* setTheme */:
|
|
1286
|
-
case "LayerContext.setOnboardingStep" /* setOnboardingStep */:
|
|
1287
|
-
case "LayerContext.setColors" /* setColors */:
|
|
1288
|
-
return { ...state, ...action.payload };
|
|
1289
|
-
case "LayerContext.setToast" /* setToast */:
|
|
1290
|
-
return {
|
|
1291
|
-
...state,
|
|
1292
|
-
toasts: [
|
|
1293
|
-
...state.toasts,
|
|
1294
|
-
{ ...action.payload.toast, isExiting: false }
|
|
1295
|
-
]
|
|
1296
|
-
};
|
|
1297
|
-
case "LayerContext.setToastExit" /* setToastExit */:
|
|
1320
|
+
const updateOneLocal = (newBankTransaction) => {
|
|
1321
|
+
const updatedData = rawResponseData?.map((page) => {
|
|
1298
1322
|
return {
|
|
1299
|
-
...
|
|
1300
|
-
|
|
1301
|
-
(
|
|
1323
|
+
...page,
|
|
1324
|
+
data: page.data?.map(
|
|
1325
|
+
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
1302
1326
|
)
|
|
1303
1327
|
};
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
...state,
|
|
1307
|
-
toasts: state.toasts.filter((t) => t.id !== action.payload.toast.id)
|
|
1308
|
-
};
|
|
1309
|
-
default:
|
|
1310
|
-
return state;
|
|
1311
|
-
}
|
|
1312
|
-
};
|
|
1313
|
-
var LayerEnvironment = {
|
|
1314
|
-
production: {
|
|
1315
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1316
|
-
scope: "https://api.layerfi.com/production",
|
|
1317
|
-
apiUrl: "https://api.layerfi.com"
|
|
1318
|
-
},
|
|
1319
|
-
sandbox: {
|
|
1320
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1321
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1322
|
-
apiUrl: "https://sandbox.layerfi.com"
|
|
1323
|
-
},
|
|
1324
|
-
staging: {
|
|
1325
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1326
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1327
|
-
apiUrl: "https://sandbox.layerfi.com"
|
|
1328
|
-
},
|
|
1329
|
-
internalStaging: {
|
|
1330
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1331
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1332
|
-
apiUrl: "https://staging.layerfi.com"
|
|
1333
|
-
}
|
|
1334
|
-
};
|
|
1335
|
-
var LayerProvider = ({
|
|
1336
|
-
appId,
|
|
1337
|
-
appSecret,
|
|
1338
|
-
businessId,
|
|
1339
|
-
children,
|
|
1340
|
-
businessAccessToken,
|
|
1341
|
-
environment = "production",
|
|
1342
|
-
theme,
|
|
1343
|
-
usePlaidSandbox,
|
|
1344
|
-
onError,
|
|
1345
|
-
eventCallbacks
|
|
1346
|
-
}) => {
|
|
1347
|
-
const defaultSWRConfig = {
|
|
1348
|
-
revalidateInterval: 0,
|
|
1349
|
-
revalidateOnFocus: false,
|
|
1350
|
-
revalidateOnReconnect: false,
|
|
1351
|
-
revalidateIfStale: false
|
|
1328
|
+
});
|
|
1329
|
+
mutate(updatedData, { revalidate: false });
|
|
1352
1330
|
};
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
const
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
businessId,
|
|
1364
|
-
business: void 0,
|
|
1365
|
-
categories: [],
|
|
1366
|
-
apiUrl,
|
|
1367
|
-
theme,
|
|
1368
|
-
colors,
|
|
1369
|
-
usePlaidSandbox,
|
|
1370
|
-
onboardingStep: void 0,
|
|
1371
|
-
environment,
|
|
1372
|
-
toasts: [],
|
|
1373
|
-
eventCallbacks: {}
|
|
1374
|
-
});
|
|
1375
|
-
const { touch, syncTimestamps, read, readTimestamps, hasBeenTouched } = useDataSync();
|
|
1376
|
-
const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR(
|
|
1377
|
-
businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && isBefore(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
|
|
1378
|
-
Layer.authenticate({
|
|
1379
|
-
appId,
|
|
1380
|
-
appSecret,
|
|
1381
|
-
authenticationUrl: url,
|
|
1382
|
-
scope
|
|
1383
|
-
}),
|
|
1384
|
-
defaultSWRConfig
|
|
1385
|
-
) : { data: void 0 };
|
|
1386
|
-
useEffect3(() => {
|
|
1387
|
-
if (businessAccessToken) {
|
|
1388
|
-
dispatch({
|
|
1389
|
-
type: "LayerContext.setAuth" /* setAuth */,
|
|
1390
|
-
payload: {
|
|
1391
|
-
auth: {
|
|
1392
|
-
access_token: businessAccessToken,
|
|
1393
|
-
token_type: "Bearer",
|
|
1394
|
-
expires_in: 3600,
|
|
1395
|
-
expires_at: add(/* @__PURE__ */ new Date(), { seconds: 3600 })
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
} else if (auth?.access_token) {
|
|
1400
|
-
dispatch({
|
|
1401
|
-
type: "LayerContext.setAuth" /* setAuth */,
|
|
1402
|
-
payload: {
|
|
1403
|
-
auth: {
|
|
1404
|
-
...auth,
|
|
1405
|
-
expires_at: add(/* @__PURE__ */ new Date(), { seconds: auth.expires_in })
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1331
|
+
const shouldHideAfterCategorize = (bankTransaction) => {
|
|
1332
|
+
return filters?.categorizationStatus === "review" /* review */ && ReviewCategories.includes(bankTransaction.categorization_status);
|
|
1333
|
+
};
|
|
1334
|
+
const removeAfterCategorize = (bankTransaction) => {
|
|
1335
|
+
if (shouldHideAfterCategorize(bankTransaction)) {
|
|
1336
|
+
const updatedData = rawResponseData?.map((page) => {
|
|
1337
|
+
return {
|
|
1338
|
+
...page,
|
|
1339
|
+
data: page.data?.filter((bt) => bt.id !== bankTransaction.id)
|
|
1340
|
+
};
|
|
1408
1341
|
});
|
|
1342
|
+
mutate(updatedData, { revalidate: false });
|
|
1409
1343
|
}
|
|
1410
|
-
}
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
...defaultSWRConfig,
|
|
1418
|
-
onSuccess: (response) => {
|
|
1419
|
-
if (response?.data?.categories?.length) {
|
|
1420
|
-
dispatch({
|
|
1421
|
-
type: "LayerContext.setCategories" /* setCategories */,
|
|
1422
|
-
payload: { categories: response.data.categories || [] }
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1344
|
+
};
|
|
1345
|
+
const refetch = () => {
|
|
1346
|
+
mutate();
|
|
1347
|
+
};
|
|
1348
|
+
const fetchMore = () => {
|
|
1349
|
+
if (hasMore) {
|
|
1350
|
+
setSize(size + 1);
|
|
1426
1351
|
}
|
|
1427
|
-
|
|
1352
|
+
};
|
|
1353
|
+
const getCacheKey = (txnFilters) => {
|
|
1354
|
+
return filtersSettingString(txnFilters);
|
|
1355
|
+
};
|
|
1428
1356
|
useEffect3(() => {
|
|
1429
|
-
if (
|
|
1430
|
-
|
|
1431
|
-
type: "LayerContext.setCategories" /* setCategories */,
|
|
1432
|
-
payload: { categories: categoriesData.data.categories || [] }
|
|
1433
|
-
});
|
|
1357
|
+
if (isLoading || isValidating) {
|
|
1358
|
+
read("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */, getCacheKey(filters));
|
|
1434
1359
|
}
|
|
1435
|
-
}, [
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
params: { businessId }
|
|
1440
|
-
}),
|
|
1441
|
-
{
|
|
1442
|
-
...defaultSWRConfig,
|
|
1443
|
-
onSuccess: (response) => {
|
|
1444
|
-
if (response?.data) {
|
|
1445
|
-
dispatch({
|
|
1446
|
-
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1447
|
-
payload: { business: response.data || [] }
|
|
1448
|
-
});
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1360
|
+
}, [isLoading, isValidating]);
|
|
1361
|
+
useEffect3(() => {
|
|
1362
|
+
if (hasBeenTouched(getCacheKey(filters))) {
|
|
1363
|
+
refetch();
|
|
1451
1364
|
}
|
|
1365
|
+
}, [syncTimestamps, filters]);
|
|
1366
|
+
const { data: linkedAccounts, refetchAccounts } = useLinkedAccounts();
|
|
1367
|
+
const anyAccountSyncing = useMemo2(
|
|
1368
|
+
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
1369
|
+
[linkedAccounts]
|
|
1452
1370
|
);
|
|
1371
|
+
const [pollIntervalMs, setPollIntervalMs] = useState5(INITIAL_POLL_INTERVAL_MS);
|
|
1372
|
+
const transactionsNotSynced = useMemo2(
|
|
1373
|
+
() => loadingStatus === "complete" && anyAccountSyncing && (!data || data?.length === 0),
|
|
1374
|
+
[data, anyAccountSyncing, loadingStatus]
|
|
1375
|
+
);
|
|
1376
|
+
let intervalId = void 0;
|
|
1377
|
+
const [refreshTrigger, setRefreshTrigger] = useState5(-1);
|
|
1453
1378
|
useEffect3(() => {
|
|
1454
|
-
if (
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
payload: { business: businessData.data || [] }
|
|
1458
|
-
});
|
|
1379
|
+
if (refreshTrigger !== -1) {
|
|
1380
|
+
refetch();
|
|
1381
|
+
refetchAccounts();
|
|
1459
1382
|
}
|
|
1460
|
-
}, [
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
});
|
|
1470
|
-
};
|
|
1471
|
-
const setLightColor = (color) => {
|
|
1472
|
-
setTheme({
|
|
1473
|
-
...state.theme ?? {},
|
|
1474
|
-
colors: {
|
|
1475
|
-
...state.theme?.colors ?? {},
|
|
1476
|
-
light: color
|
|
1477
|
-
}
|
|
1478
|
-
});
|
|
1479
|
-
};
|
|
1480
|
-
const setDarkColor = (color) => {
|
|
1481
|
-
setTheme({
|
|
1482
|
-
...state.theme ?? {},
|
|
1483
|
-
colors: {
|
|
1484
|
-
...state.theme?.colors ?? {},
|
|
1485
|
-
dark: color
|
|
1383
|
+
}, [refreshTrigger]);
|
|
1384
|
+
useEffect3(() => {
|
|
1385
|
+
if (anyAccountSyncing) {
|
|
1386
|
+
intervalId = setInterval(() => {
|
|
1387
|
+
setRefreshTrigger(Math.random());
|
|
1388
|
+
}, pollIntervalMs);
|
|
1389
|
+
} else {
|
|
1390
|
+
if (intervalId) {
|
|
1391
|
+
clearInterval(intervalId);
|
|
1486
1392
|
}
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
...state.theme ?? {},
|
|
1492
|
-
colors: {
|
|
1493
|
-
...state.theme?.colors ?? {},
|
|
1494
|
-
text: color
|
|
1393
|
+
}
|
|
1394
|
+
return () => {
|
|
1395
|
+
if (intervalId) {
|
|
1396
|
+
clearInterval(intervalId);
|
|
1495
1397
|
}
|
|
1496
|
-
}
|
|
1497
|
-
};
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
dispatch({ type: "LayerContext.removeToast" /* removeToast */, payload: { toast } });
|
|
1503
|
-
};
|
|
1504
|
-
const setToastExit = (toast) => {
|
|
1505
|
-
dispatch({ type: "LayerContext.setToastExit" /* setToastExit */, payload: { toast } });
|
|
1506
|
-
};
|
|
1507
|
-
const addToast = (toast) => {
|
|
1508
|
-
const id = `${Date.now()}-${Math.random()}`;
|
|
1509
|
-
const newToast = { id, isExiting: false, ...toast };
|
|
1510
|
-
setToast(newToast);
|
|
1511
|
-
setTimeout(() => {
|
|
1512
|
-
removeToast(newToast);
|
|
1513
|
-
setTimeout(() => {
|
|
1514
|
-
setToastExit(newToast);
|
|
1515
|
-
}, 1e3);
|
|
1516
|
-
}, toast.duration || 2e3);
|
|
1517
|
-
};
|
|
1518
|
-
const setColors = (colors2) => setTheme({
|
|
1519
|
-
...state.theme ?? {},
|
|
1520
|
-
colors: colors2
|
|
1398
|
+
};
|
|
1399
|
+
}, [anyAccountSyncing, transactionsNotSynced, pollIntervalMs]);
|
|
1400
|
+
useTriggerOnChange(data, anyAccountSyncing, (newTransactionList) => {
|
|
1401
|
+
clearInterval(intervalId);
|
|
1402
|
+
setPollIntervalMs(POLL_INTERVAL_AFTER_TXNS_RECEIVED_MS);
|
|
1403
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1521
1404
|
});
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1405
|
+
return {
|
|
1406
|
+
data: filteredData,
|
|
1407
|
+
metadata: lastMetadata,
|
|
1408
|
+
loadingStatus,
|
|
1409
|
+
isLoading,
|
|
1410
|
+
isValidating,
|
|
1411
|
+
refetch,
|
|
1412
|
+
error: responseError,
|
|
1413
|
+
categorize,
|
|
1414
|
+
match,
|
|
1415
|
+
updateOneLocal,
|
|
1416
|
+
shouldHideAfterCategorize,
|
|
1417
|
+
removeAfterCategorize,
|
|
1418
|
+
filters,
|
|
1419
|
+
setFilters,
|
|
1420
|
+
accountsList,
|
|
1421
|
+
activate,
|
|
1422
|
+
display,
|
|
1423
|
+
fetchMore,
|
|
1424
|
+
hasMore
|
|
1527
1425
|
};
|
|
1528
|
-
const setOnboardingStep = (value) => dispatch({
|
|
1529
|
-
type: "LayerContext.setOnboardingStep" /* setOnboardingStep */,
|
|
1530
|
-
payload: { onboardingStep: value }
|
|
1531
|
-
});
|
|
1532
|
-
const drawerContextData = useDrawer();
|
|
1533
|
-
return /* @__PURE__ */ React7.createElement(SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ React7.createElement(
|
|
1534
|
-
LayerContext.Provider,
|
|
1535
|
-
{
|
|
1536
|
-
value: {
|
|
1537
|
-
...state,
|
|
1538
|
-
setTheme,
|
|
1539
|
-
getColor,
|
|
1540
|
-
setLightColor,
|
|
1541
|
-
setDarkColor,
|
|
1542
|
-
setTextColor,
|
|
1543
|
-
setColors,
|
|
1544
|
-
setOnboardingStep,
|
|
1545
|
-
addToast,
|
|
1546
|
-
removeToast,
|
|
1547
|
-
onError: errorHandler.onError,
|
|
1548
|
-
touch,
|
|
1549
|
-
read,
|
|
1550
|
-
syncTimestamps,
|
|
1551
|
-
readTimestamps,
|
|
1552
|
-
hasBeenTouched,
|
|
1553
|
-
eventCallbacks
|
|
1554
|
-
}
|
|
1555
|
-
},
|
|
1556
|
-
/* @__PURE__ */ React7.createElement(BankTransactionsProvider, null, /* @__PURE__ */ React7.createElement(DrawerContext.Provider, { value: drawerContextData }, children, /* @__PURE__ */ React7.createElement(GlobalWidgets, null)))
|
|
1557
|
-
));
|
|
1558
1426
|
};
|
|
1559
1427
|
|
|
1560
|
-
// src/
|
|
1561
|
-
|
|
1428
|
+
// src/providers/BankTransactionsProvider/BankTransactionsProvider.tsx
|
|
1429
|
+
var BankTransactionsProvider = ({
|
|
1430
|
+
children
|
|
1431
|
+
}) => {
|
|
1432
|
+
const bankTransactionsContextData = useBankTransactions();
|
|
1433
|
+
return /* @__PURE__ */ React6.createElement(BankTransactionsContext.Provider, { value: bankTransactionsContextData }, children);
|
|
1434
|
+
};
|
|
1562
1435
|
|
|
1563
|
-
// src/
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
},
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
},
|
|
1581
|
-
unlinkAccount: () => {
|
|
1582
|
-
},
|
|
1583
|
-
denyAccount: () => {
|
|
1584
|
-
},
|
|
1585
|
-
confirmAccount: () => {
|
|
1586
|
-
},
|
|
1587
|
-
breakConnection: () => {
|
|
1436
|
+
// src/config/theme.ts
|
|
1437
|
+
var SHADES = {
|
|
1438
|
+
50: { s: 1, l: 98 },
|
|
1439
|
+
100: { s: 1, l: 96 },
|
|
1440
|
+
200: { s: 1, l: 94 },
|
|
1441
|
+
300: { s: 2, l: 92 },
|
|
1442
|
+
500: { s: 5, l: 53 },
|
|
1443
|
+
600: { s: 7, l: 40 },
|
|
1444
|
+
700: { s: 9, l: 27 },
|
|
1445
|
+
800: { s: 12, l: 20 },
|
|
1446
|
+
1e3: { s: 20, l: 7 }
|
|
1447
|
+
};
|
|
1448
|
+
var COLORS = {
|
|
1449
|
+
dark: {
|
|
1450
|
+
h: 0,
|
|
1451
|
+
s: 0,
|
|
1452
|
+
l: 7
|
|
1588
1453
|
},
|
|
1589
|
-
|
|
1454
|
+
light: {
|
|
1455
|
+
h: 0,
|
|
1456
|
+
s: 0,
|
|
1457
|
+
l: 100
|
|
1590
1458
|
}
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
// src/providers/LinkedAccountsProvider/LinkedAccountsProvider.tsx
|
|
1594
|
-
import React8 from "react";
|
|
1595
|
-
|
|
1596
|
-
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
1597
|
-
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1598
|
-
import { usePlaidLink } from "react-plaid-link";
|
|
1459
|
+
};
|
|
1599
1460
|
|
|
1600
|
-
// src/
|
|
1601
|
-
var
|
|
1602
|
-
{
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1461
|
+
// src/utils/colors.ts
|
|
1462
|
+
var parseStylesFromThemeConfig = (theme) => {
|
|
1463
|
+
let styles = {};
|
|
1464
|
+
if (!theme) {
|
|
1465
|
+
return styles;
|
|
1466
|
+
}
|
|
1467
|
+
if (theme.colors) {
|
|
1468
|
+
const darkColor = parseColorFromTheme("dark", theme.colors.dark);
|
|
1469
|
+
const lightColor = parseColorFromTheme("light", theme.colors.light);
|
|
1470
|
+
const textColor = parseTextColorFromTheme(theme.colors.text);
|
|
1471
|
+
styles = { ...styles, ...darkColor, ...lightColor, ...textColor };
|
|
1472
|
+
}
|
|
1473
|
+
return styles;
|
|
1474
|
+
};
|
|
1475
|
+
var parseTextColorFromTheme = (color) => {
|
|
1476
|
+
if (!color) {
|
|
1477
|
+
return {};
|
|
1478
|
+
}
|
|
1479
|
+
try {
|
|
1480
|
+
if ("hex" in color) {
|
|
1481
|
+
return { "--text-color-primary": color.hex };
|
|
1482
|
+
}
|
|
1483
|
+
return {};
|
|
1484
|
+
} catch (_err) {
|
|
1485
|
+
return {};
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
var parseColorFromTheme = (colorName, color) => {
|
|
1489
|
+
if (!color) {
|
|
1490
|
+
return {};
|
|
1491
|
+
}
|
|
1492
|
+
try {
|
|
1493
|
+
if ("h" in color && "s" in color && "l" in color) {
|
|
1494
|
+
return {
|
|
1495
|
+
[`--color-${colorName}-h`]: color.h,
|
|
1496
|
+
[`--color-${colorName}-s`]: color.s,
|
|
1497
|
+
[`--color-${colorName}-l`]: color.l
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
if ("r" in color && "g" in color && "b" in color) {
|
|
1501
|
+
const { h, s, l } = rgbToHsl(color);
|
|
1502
|
+
return {
|
|
1503
|
+
[`--color-${colorName}-h`]: h,
|
|
1504
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
1505
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
if ("hex" in color) {
|
|
1509
|
+
const rgb = hexToRgb(color.hex);
|
|
1510
|
+
if (!rgb) {
|
|
1511
|
+
return {};
|
|
1512
|
+
}
|
|
1513
|
+
const { h, s, l } = rgbToHsl({
|
|
1514
|
+
r: rgb.r.toString(),
|
|
1515
|
+
g: rgb.g.toString(),
|
|
1516
|
+
b: rgb.b.toString()
|
|
1517
|
+
});
|
|
1518
|
+
return {
|
|
1519
|
+
[`--color-${colorName}-h`]: h,
|
|
1520
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
1521
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1524
|
+
return {};
|
|
1525
|
+
} catch (_err) {
|
|
1526
|
+
return {};
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
var parseColorFromThemeToHsl = (color) => {
|
|
1530
|
+
if (!color) {
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
try {
|
|
1534
|
+
if ("h" in color && "s" in color && "l" in color) {
|
|
1535
|
+
return {
|
|
1536
|
+
h: Number(color.h),
|
|
1537
|
+
s: Number(color.s),
|
|
1538
|
+
l: Number(color.l)
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1541
|
+
if ("r" in color && "g" in color && "b" in color) {
|
|
1542
|
+
const { h, s, l } = rgbToHsl(color);
|
|
1543
|
+
return {
|
|
1544
|
+
h,
|
|
1545
|
+
s,
|
|
1546
|
+
l
|
|
1547
|
+
};
|
|
1548
|
+
}
|
|
1549
|
+
if ("hex" in color) {
|
|
1550
|
+
const rgb = hexToRgb(color.hex);
|
|
1551
|
+
if (!rgb) {
|
|
1552
|
+
return void 0;
|
|
1553
|
+
}
|
|
1554
|
+
const { h, s, l } = rgbToHsl({
|
|
1555
|
+
r: rgb.r.toString(),
|
|
1556
|
+
g: rgb.g.toString(),
|
|
1557
|
+
b: rgb.b.toString()
|
|
1558
|
+
});
|
|
1559
|
+
return {
|
|
1560
|
+
h,
|
|
1561
|
+
s,
|
|
1562
|
+
l
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
return;
|
|
1566
|
+
} catch (_err) {
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
var rgbToHsl = (color) => {
|
|
1571
|
+
let r = Number(color.r);
|
|
1572
|
+
let g = Number(color.g);
|
|
1573
|
+
let b = Number(color.b);
|
|
1574
|
+
r /= 255;
|
|
1575
|
+
g /= 255;
|
|
1576
|
+
b /= 255;
|
|
1577
|
+
const l = Math.max(r, g, b);
|
|
1578
|
+
const s = l - Math.min(r, g, b);
|
|
1579
|
+
const h = s ? l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s : 0;
|
|
1580
|
+
return {
|
|
1581
|
+
h: 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
1582
|
+
s: 100 * (s ? l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s)) : 0),
|
|
1583
|
+
l: 100 * (2 * l - s) / 2
|
|
1584
|
+
};
|
|
1585
|
+
};
|
|
1586
|
+
var hexToRgb = (hex) => {
|
|
1587
|
+
const values = hex.replace(
|
|
1588
|
+
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
|
1589
|
+
(m, r, g, b) => "#" + r + r + g + g + b + b
|
|
1590
|
+
).substring(1).match(/.{2}/g)?.map((x) => parseInt(x, 16));
|
|
1591
|
+
if (!values) {
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1594
|
+
return {
|
|
1595
|
+
r: values[0],
|
|
1596
|
+
g: values[1],
|
|
1597
|
+
b: values[2]
|
|
1598
|
+
};
|
|
1599
|
+
};
|
|
1600
|
+
var buildColorsPalette = (theme) => {
|
|
1601
|
+
const darkColor = parseColorFromThemeToHsl(theme?.colors?.dark) ?? COLORS.dark;
|
|
1602
|
+
const lightColor = parseColorFromThemeToHsl(theme?.colors?.light) ?? COLORS.light;
|
|
1603
|
+
return {
|
|
1604
|
+
50: buildColorShade(50, darkColor),
|
|
1605
|
+
100: buildColorShade(100, darkColor),
|
|
1606
|
+
200: buildColorShade(200, darkColor),
|
|
1607
|
+
300: buildColorShade(300, darkColor),
|
|
1608
|
+
400: {
|
|
1609
|
+
hsl: lightColor,
|
|
1610
|
+
rgb: hslToRgb(lightColor),
|
|
1611
|
+
hex: hslToHex(lightColor)
|
|
1686
1612
|
},
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1613
|
+
500: buildColorShade(500, darkColor),
|
|
1614
|
+
600: buildColorShade(600, darkColor),
|
|
1615
|
+
700: buildColorShade(700, darkColor),
|
|
1616
|
+
800: buildColorShade(800, darkColor),
|
|
1617
|
+
900: {
|
|
1618
|
+
hsl: darkColor,
|
|
1619
|
+
rgb: hslToRgb(darkColor),
|
|
1620
|
+
hex: hslToHex(darkColor)
|
|
1691
1621
|
},
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1622
|
+
1e3: buildColorShade(1e3, darkColor)
|
|
1623
|
+
};
|
|
1624
|
+
};
|
|
1625
|
+
var buildColorShade = (shade, darkColorHsl) => {
|
|
1626
|
+
const hsl = { h: darkColorHsl.h, ...SHADES[shade] };
|
|
1627
|
+
const rgb = hslToRgb(hsl);
|
|
1628
|
+
const hex = hslToHex(hsl);
|
|
1629
|
+
return { hsl, rgb, hex };
|
|
1630
|
+
};
|
|
1631
|
+
var hueToRgb = (p, q, t) => {
|
|
1632
|
+
if (t < 0)
|
|
1633
|
+
t += 1;
|
|
1634
|
+
if (t > 1)
|
|
1635
|
+
t -= 1;
|
|
1636
|
+
if (t < 1 / 6)
|
|
1637
|
+
return p + (q - p) * 6 * t;
|
|
1638
|
+
if (t < 1 / 2)
|
|
1639
|
+
return q;
|
|
1640
|
+
if (t < 2 / 3)
|
|
1641
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
1642
|
+
return p;
|
|
1643
|
+
};
|
|
1644
|
+
var hslToRgb = (hsl) => {
|
|
1645
|
+
let r, g, b;
|
|
1646
|
+
let l = hsl.l / 100;
|
|
1647
|
+
let s = hsl.s / 100;
|
|
1648
|
+
if (hsl.s === 0) {
|
|
1649
|
+
r = g = b = l;
|
|
1650
|
+
} else {
|
|
1651
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1652
|
+
const p = 2 * l - q;
|
|
1653
|
+
r = hueToRgb(p, q, hsl.h + 1 / 3);
|
|
1654
|
+
g = hueToRgb(p, q, hsl.h);
|
|
1655
|
+
b = hueToRgb(p, q, hsl.h - 1 / 3);
|
|
1656
|
+
}
|
|
1657
|
+
return {
|
|
1658
|
+
r: Math.round(r * 255),
|
|
1659
|
+
g: Math.round(g * 255),
|
|
1660
|
+
b: Math.round(b * 255)
|
|
1661
|
+
};
|
|
1662
|
+
};
|
|
1663
|
+
var hslToHex = (hsl) => {
|
|
1664
|
+
const l = hsl.l / 100;
|
|
1665
|
+
const s = hsl.s;
|
|
1666
|
+
const a = s * Math.min(l, 1 - l) / 100;
|
|
1667
|
+
const f = (n) => {
|
|
1668
|
+
const k = (n + hsl.h / 30) % 12;
|
|
1669
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
1670
|
+
return Math.round(255 * color).toString(16).padStart(2, "0");
|
|
1671
|
+
};
|
|
1672
|
+
return `#${f(0)}${f(8)}${f(4)}`;
|
|
1673
|
+
};
|
|
1674
|
+
|
|
1675
|
+
// src/providers/LayerProvider/LayerProvider.tsx
|
|
1676
|
+
import { add, isBefore } from "date-fns";
|
|
1677
|
+
import useSWR2, { SWRConfig } from "swr";
|
|
1678
|
+
var reducer = (state, action) => {
|
|
1679
|
+
switch (action.type) {
|
|
1680
|
+
case "LayerContext.setAuth" /* setAuth */:
|
|
1681
|
+
case "LayerContext.setBusiness" /* setBusiness */:
|
|
1682
|
+
case "LayerContext.setCategories" /* setCategories */:
|
|
1683
|
+
case "LayerContext.setTheme" /* setTheme */:
|
|
1684
|
+
case "LayerContext.setOnboardingStep" /* setOnboardingStep */:
|
|
1685
|
+
case "LayerContext.setColors" /* setColors */:
|
|
1686
|
+
return { ...state, ...action.payload };
|
|
1687
|
+
case "LayerContext.setToast" /* setToast */:
|
|
1688
|
+
return {
|
|
1689
|
+
...state,
|
|
1690
|
+
toasts: [
|
|
1691
|
+
...state.toasts,
|
|
1692
|
+
{ ...action.payload.toast, isExiting: false }
|
|
1693
|
+
]
|
|
1694
|
+
};
|
|
1695
|
+
case "LayerContext.setToastExit" /* setToastExit */:
|
|
1696
|
+
return {
|
|
1697
|
+
...state,
|
|
1698
|
+
toasts: state.toasts.map(
|
|
1699
|
+
(toast) => toast.id === action.payload.toast.id ? { ...toast, isExiting: false } : toast
|
|
1700
|
+
)
|
|
1701
|
+
};
|
|
1702
|
+
case "LayerContext.removeToast" /* removeToast */:
|
|
1703
|
+
return {
|
|
1704
|
+
...state,
|
|
1705
|
+
toasts: state.toasts.filter((t) => t.id !== action.payload.toast.id)
|
|
1706
|
+
};
|
|
1707
|
+
default:
|
|
1708
|
+
return state;
|
|
1697
1709
|
}
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
auth,
|
|
1710
|
+
};
|
|
1711
|
+
var LayerEnvironment = {
|
|
1712
|
+
production: {
|
|
1713
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1714
|
+
scope: "https://api.layerfi.com/production",
|
|
1715
|
+
apiUrl: "https://api.layerfi.com"
|
|
1716
|
+
},
|
|
1717
|
+
sandbox: {
|
|
1718
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1719
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1720
|
+
apiUrl: "https://sandbox.layerfi.com"
|
|
1721
|
+
},
|
|
1722
|
+
staging: {
|
|
1723
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1724
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1725
|
+
apiUrl: "https://sandbox.layerfi.com"
|
|
1726
|
+
},
|
|
1727
|
+
internalStaging: {
|
|
1728
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1729
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1730
|
+
apiUrl: "https://staging.layerfi.com"
|
|
1731
|
+
}
|
|
1732
|
+
};
|
|
1733
|
+
var LayerProvider = ({
|
|
1734
|
+
appId,
|
|
1735
|
+
appSecret,
|
|
1736
|
+
businessId,
|
|
1737
|
+
children,
|
|
1738
|
+
businessAccessToken,
|
|
1739
|
+
environment = "production",
|
|
1740
|
+
theme,
|
|
1741
|
+
usePlaidSandbox,
|
|
1742
|
+
onError,
|
|
1743
|
+
eventCallbacks
|
|
1744
|
+
}) => {
|
|
1745
|
+
const defaultSWRConfig = {
|
|
1746
|
+
revalidateInterval: 0,
|
|
1747
|
+
revalidateOnFocus: false,
|
|
1748
|
+
revalidateOnReconnect: false,
|
|
1749
|
+
revalidateIfStale: false
|
|
1750
|
+
};
|
|
1751
|
+
errorHandler.setOnError(onError);
|
|
1752
|
+
const colors = buildColorsPalette(theme);
|
|
1753
|
+
const { url, scope, apiUrl } = LayerEnvironment[environment];
|
|
1754
|
+
const [state, dispatch] = useReducer(reducer, {
|
|
1755
|
+
auth: {
|
|
1756
|
+
access_token: "",
|
|
1757
|
+
token_type: "",
|
|
1758
|
+
expires_in: 0,
|
|
1759
|
+
expires_at: new Date(2e3, 1, 1)
|
|
1760
|
+
},
|
|
1707
1761
|
businessId,
|
|
1762
|
+
business: void 0,
|
|
1763
|
+
categories: [],
|
|
1708
1764
|
apiUrl,
|
|
1765
|
+
theme,
|
|
1766
|
+
colors,
|
|
1709
1767
|
usePlaidSandbox,
|
|
1768
|
+
onboardingStep: void 0,
|
|
1769
|
+
environment,
|
|
1770
|
+
toasts: [],
|
|
1771
|
+
eventCallbacks: {}
|
|
1772
|
+
});
|
|
1773
|
+
const {
|
|
1710
1774
|
touch,
|
|
1711
|
-
read,
|
|
1712
1775
|
syncTimestamps,
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
|
|
1729
|
-
params: { businessId }
|
|
1730
|
-
})
|
|
1731
|
-
);
|
|
1732
|
-
useEffect4(() => {
|
|
1733
|
-
if (!isLoading && responseData?.data.external_accounts) {
|
|
1734
|
-
setLoadingStatus("complete");
|
|
1735
|
-
return;
|
|
1736
|
-
}
|
|
1737
|
-
if (isLoading && loadingStatus === "initial") {
|
|
1738
|
-
setLoadingStatus("loading");
|
|
1739
|
-
return;
|
|
1740
|
-
}
|
|
1741
|
-
if (!isLoading && loadingStatus === "loading") {
|
|
1742
|
-
setLoadingStatus("complete");
|
|
1743
|
-
}
|
|
1744
|
-
}, [isLoading]);
|
|
1745
|
-
const fetchPlaidLinkToken = async () => {
|
|
1746
|
-
if (auth?.access_token) {
|
|
1747
|
-
const linkToken2 = (await Layer.getPlaidLinkToken(apiUrl, auth.access_token, {
|
|
1748
|
-
params: { businessId }
|
|
1749
|
-
})).data.link_token;
|
|
1750
|
-
setLinkMode("add");
|
|
1751
|
-
setLinkToken(linkToken2);
|
|
1752
|
-
}
|
|
1753
|
-
};
|
|
1754
|
-
const fetchPlaidUpdateModeLinkToken = async (plaidItemPlaidId) => {
|
|
1755
|
-
if (auth?.access_token) {
|
|
1756
|
-
const linkToken2 = (await Layer.getPlaidUpdateModeLinkToken(apiUrl, auth.access_token, {
|
|
1757
|
-
params: { businessId },
|
|
1758
|
-
body: { plaid_item_id: plaidItemPlaidId }
|
|
1759
|
-
})).data.link_token;
|
|
1760
|
-
setLinkMode("update");
|
|
1761
|
-
setLinkToken(linkToken2);
|
|
1762
|
-
}
|
|
1763
|
-
};
|
|
1764
|
-
const exchangePlaidPublicToken2 = async (publicToken, metadata) => {
|
|
1765
|
-
await Layer.exchangePlaidPublicToken(apiUrl, auth?.access_token, {
|
|
1766
|
-
params: { businessId },
|
|
1767
|
-
body: { public_token: publicToken, institution: metadata.institution }
|
|
1768
|
-
});
|
|
1769
|
-
refetchAccounts();
|
|
1770
|
-
};
|
|
1771
|
-
const { open: plaidLinkStart, ready: plaidLinkReady } = usePlaidLink({
|
|
1772
|
-
token: linkToken,
|
|
1773
|
-
// If in update mode, we don't need to exchange the public token for an access token.
|
|
1774
|
-
// The existing access token will automatically become valid again
|
|
1775
|
-
onSuccess: async (publicToken, metadata) => {
|
|
1776
|
-
if (linkMode == "add") {
|
|
1777
|
-
exchangePlaidPublicToken2(publicToken, metadata);
|
|
1778
|
-
} else {
|
|
1779
|
-
await updateConnectionStatus2();
|
|
1780
|
-
refetchAccounts();
|
|
1781
|
-
setLinkMode("add");
|
|
1782
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1783
|
-
}
|
|
1784
|
-
},
|
|
1785
|
-
onExit: () => setLinkMode("add"),
|
|
1786
|
-
env: USE_PLAID_SANDBOX ? "sandbox" : void 0
|
|
1787
|
-
});
|
|
1776
|
+
read,
|
|
1777
|
+
readTimestamps,
|
|
1778
|
+
hasBeenTouched,
|
|
1779
|
+
resetCaches
|
|
1780
|
+
} = useDataSync();
|
|
1781
|
+
const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR2(
|
|
1782
|
+
businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && isBefore(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
|
|
1783
|
+
Layer.authenticate({
|
|
1784
|
+
appId,
|
|
1785
|
+
appSecret,
|
|
1786
|
+
authenticationUrl: url,
|
|
1787
|
+
scope
|
|
1788
|
+
}),
|
|
1789
|
+
defaultSWRConfig
|
|
1790
|
+
) : { data: void 0 };
|
|
1788
1791
|
useEffect4(() => {
|
|
1789
|
-
if (
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
fetchPlaidLinkToken();
|
|
1801
|
-
} else {
|
|
1802
|
-
console.error(
|
|
1803
|
-
`Adding a connection with source ${source} not yet supported`
|
|
1804
|
-
);
|
|
1805
|
-
}
|
|
1806
|
-
};
|
|
1807
|
-
const repairConnection = async (source, connectionExternalId) => {
|
|
1808
|
-
if (source === "PLAID") {
|
|
1809
|
-
await fetchPlaidUpdateModeLinkToken(connectionExternalId);
|
|
1810
|
-
} else {
|
|
1811
|
-
console.error(
|
|
1812
|
-
`Repairing a connection with source ${source} not yet supported`
|
|
1813
|
-
);
|
|
1814
|
-
}
|
|
1815
|
-
};
|
|
1816
|
-
const removeConnection = async (source, connectionExternalId) => {
|
|
1817
|
-
if (source === "PLAID") {
|
|
1818
|
-
await unlinkPlaidItem2(connectionExternalId);
|
|
1819
|
-
await refetchAccounts();
|
|
1820
|
-
} else {
|
|
1821
|
-
console.error(
|
|
1822
|
-
`Removing a connection with source ${source} not yet supported`
|
|
1823
|
-
);
|
|
1824
|
-
}
|
|
1825
|
-
};
|
|
1826
|
-
const unlinkAccount2 = async (source, accountId) => {
|
|
1827
|
-
DEBUG && console.log("unlinking account");
|
|
1828
|
-
if (source === "PLAID") {
|
|
1829
|
-
await Layer.unlinkAccount(apiUrl, auth?.access_token, {
|
|
1830
|
-
params: { businessId, accountId }
|
|
1792
|
+
if (businessAccessToken) {
|
|
1793
|
+
dispatch({
|
|
1794
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
1795
|
+
payload: {
|
|
1796
|
+
auth: {
|
|
1797
|
+
access_token: businessAccessToken,
|
|
1798
|
+
token_type: "Bearer",
|
|
1799
|
+
expires_in: 3600,
|
|
1800
|
+
expires_at: add(/* @__PURE__ */ new Date(), { seconds: 3600 })
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1831
1803
|
});
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
const confirmAccount = async (source, accountId) => {
|
|
1841
|
-
DEBUG && console.log("confirming account");
|
|
1842
|
-
if (source === "PLAID") {
|
|
1843
|
-
await Layer.confirmConnection(apiUrl, auth?.access_token, {
|
|
1844
|
-
params: {
|
|
1845
|
-
businessId,
|
|
1846
|
-
accountId
|
|
1804
|
+
} else if (auth?.access_token) {
|
|
1805
|
+
dispatch({
|
|
1806
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
1807
|
+
payload: {
|
|
1808
|
+
auth: {
|
|
1809
|
+
...auth,
|
|
1810
|
+
expires_at: add(/* @__PURE__ */ new Date(), { seconds: auth.expires_in })
|
|
1811
|
+
}
|
|
1847
1812
|
}
|
|
1848
1813
|
});
|
|
1849
|
-
await refetchAccounts();
|
|
1850
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1851
|
-
} else {
|
|
1852
|
-
console.error(
|
|
1853
|
-
`Confirming an account with source ${source} not yet supported`
|
|
1854
|
-
);
|
|
1855
1814
|
}
|
|
1856
|
-
};
|
|
1857
|
-
const
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1815
|
+
}, [businessAccessToken, auth?.access_token]);
|
|
1816
|
+
const { data: categoriesData } = useSWR2(
|
|
1817
|
+
businessId && state.auth?.access_token && `categories-${businessId}`,
|
|
1818
|
+
Layer.getCategories(apiUrl, state.auth?.access_token, {
|
|
1819
|
+
params: { businessId }
|
|
1820
|
+
}),
|
|
1821
|
+
{
|
|
1822
|
+
...defaultSWRConfig,
|
|
1823
|
+
onSuccess: (response) => {
|
|
1824
|
+
if (response?.data?.categories?.length) {
|
|
1825
|
+
dispatch({
|
|
1826
|
+
type: "LayerContext.setCategories" /* setCategories */,
|
|
1827
|
+
payload: { categories: response.data.categories || [] }
|
|
1828
|
+
});
|
|
1864
1829
|
}
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
);
|
|
1833
|
+
useEffect4(() => {
|
|
1834
|
+
if (categoriesData?.data?.categories?.length) {
|
|
1835
|
+
dispatch({
|
|
1836
|
+
type: "LayerContext.setCategories" /* setCategories */,
|
|
1837
|
+
payload: { categories: categoriesData.data.categories || [] }
|
|
1865
1838
|
});
|
|
1866
|
-
await refetchAccounts();
|
|
1867
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1868
|
-
} else {
|
|
1869
|
-
console.error(
|
|
1870
|
-
`Denying an account with source ${source} not yet supported`
|
|
1871
|
-
);
|
|
1872
1839
|
}
|
|
1873
|
-
};
|
|
1874
|
-
const
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1840
|
+
}, [categoriesData]);
|
|
1841
|
+
const { data: businessData } = useSWR2(
|
|
1842
|
+
businessId && state?.auth?.access_token && `business-${businessId}`,
|
|
1843
|
+
Layer.getBusiness(apiUrl, state?.auth?.access_token, {
|
|
1844
|
+
params: { businessId }
|
|
1845
|
+
}),
|
|
1846
|
+
{
|
|
1847
|
+
...defaultSWRConfig,
|
|
1848
|
+
onSuccess: (response) => {
|
|
1849
|
+
if (response?.data) {
|
|
1850
|
+
dispatch({
|
|
1851
|
+
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1852
|
+
payload: { business: response.data || [] }
|
|
1853
|
+
});
|
|
1881
1854
|
}
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
);
|
|
1858
|
+
useEffect4(() => {
|
|
1859
|
+
if (businessData?.data) {
|
|
1860
|
+
dispatch({
|
|
1861
|
+
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1862
|
+
payload: { business: businessData.data || [] }
|
|
1882
1863
|
});
|
|
1883
|
-
await refetchAccounts();
|
|
1884
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1885
|
-
} else {
|
|
1886
|
-
console.error(
|
|
1887
|
-
`Breaking a sandbox connection with source ${source} not yet supported`
|
|
1888
|
-
);
|
|
1889
1864
|
}
|
|
1865
|
+
}, [businessData]);
|
|
1866
|
+
const setTheme = (theme2) => {
|
|
1867
|
+
dispatch({
|
|
1868
|
+
type: "LayerContext.setTheme" /* setTheme */,
|
|
1869
|
+
payload: { theme: theme2 }
|
|
1870
|
+
});
|
|
1871
|
+
dispatch({
|
|
1872
|
+
type: "LayerContext.setColors" /* setColors */,
|
|
1873
|
+
payload: { colors: buildColorsPalette(theme2) }
|
|
1874
|
+
});
|
|
1890
1875
|
};
|
|
1891
|
-
const
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
params: { businessId }
|
|
1876
|
+
const setLightColor = (color) => {
|
|
1877
|
+
setTheme({
|
|
1878
|
+
...state.theme ?? {},
|
|
1879
|
+
colors: {
|
|
1880
|
+
...state.theme?.colors ?? {},
|
|
1881
|
+
light: color
|
|
1882
|
+
}
|
|
1899
1883
|
});
|
|
1900
1884
|
};
|
|
1901
|
-
const
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1885
|
+
const setDarkColor = (color) => {
|
|
1886
|
+
setTheme({
|
|
1887
|
+
...state.theme ?? {},
|
|
1888
|
+
colors: {
|
|
1889
|
+
...state.theme?.colors ?? {},
|
|
1890
|
+
dark: color
|
|
1891
|
+
}
|
|
1905
1892
|
});
|
|
1906
1893
|
};
|
|
1907
|
-
const
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1894
|
+
const setTextColor = (color) => {
|
|
1895
|
+
setTheme({
|
|
1896
|
+
...state.theme ?? {},
|
|
1897
|
+
colors: {
|
|
1898
|
+
...state.theme?.colors ?? {},
|
|
1899
|
+
text: color
|
|
1900
|
+
}
|
|
1911
1901
|
});
|
|
1912
|
-
await refetchAccounts();
|
|
1913
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1914
1902
|
};
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1903
|
+
const setToast = (toast) => {
|
|
1904
|
+
dispatch({ type: "LayerContext.setToast" /* setToast */, payload: { toast } });
|
|
1905
|
+
};
|
|
1906
|
+
const removeToast = (toast) => {
|
|
1907
|
+
dispatch({ type: "LayerContext.removeToast" /* removeToast */, payload: { toast } });
|
|
1908
|
+
};
|
|
1909
|
+
const setToastExit = (toast) => {
|
|
1910
|
+
dispatch({ type: "LayerContext.setToastExit" /* setToastExit */, payload: { toast } });
|
|
1911
|
+
};
|
|
1912
|
+
const addToast = (toast) => {
|
|
1913
|
+
const id = `${Date.now()}-${Math.random()}`;
|
|
1914
|
+
const newToast = { id, isExiting: false, ...toast };
|
|
1915
|
+
setToast(newToast);
|
|
1916
|
+
setTimeout(() => {
|
|
1917
|
+
removeToast(newToast);
|
|
1918
|
+
setTimeout(() => {
|
|
1919
|
+
setToastExit(newToast);
|
|
1920
|
+
}, 1e3);
|
|
1921
|
+
}, toast.duration || 2e3);
|
|
1922
|
+
};
|
|
1923
|
+
const setColors = (colors2) => setTheme({
|
|
1924
|
+
...state.theme ?? {},
|
|
1925
|
+
colors: colors2
|
|
1926
|
+
});
|
|
1927
|
+
const getColor = (shade) => {
|
|
1928
|
+
if (state.colors && shade in state.colors) {
|
|
1929
|
+
return state.colors[shade];
|
|
1923
1930
|
}
|
|
1924
|
-
|
|
1925
|
-
return {
|
|
1926
|
-
data: USE_MOCK_RESPONSE_DATA ? mockResponseData.data : responseData?.data.external_accounts,
|
|
1927
|
-
isLoading,
|
|
1928
|
-
loadingStatus,
|
|
1929
|
-
isValidating,
|
|
1930
|
-
error: responseError,
|
|
1931
|
-
addConnection,
|
|
1932
|
-
removeConnection,
|
|
1933
|
-
repairConnection,
|
|
1934
|
-
refetchAccounts,
|
|
1935
|
-
unlinkAccount: unlinkAccount2,
|
|
1936
|
-
confirmAccount,
|
|
1937
|
-
denyAccount,
|
|
1938
|
-
breakConnection,
|
|
1939
|
-
syncAccounts,
|
|
1940
|
-
updateConnectionStatus: updateConnectionStatus2
|
|
1931
|
+
return;
|
|
1941
1932
|
};
|
|
1933
|
+
const setOnboardingStep = (value) => dispatch({
|
|
1934
|
+
type: "LayerContext.setOnboardingStep" /* setOnboardingStep */,
|
|
1935
|
+
payload: { onboardingStep: value }
|
|
1936
|
+
});
|
|
1937
|
+
const drawerContextData = useDrawer();
|
|
1938
|
+
return /* @__PURE__ */ React7.createElement(SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ React7.createElement(
|
|
1939
|
+
LayerContext.Provider,
|
|
1940
|
+
{
|
|
1941
|
+
value: {
|
|
1942
|
+
...state,
|
|
1943
|
+
setTheme,
|
|
1944
|
+
getColor,
|
|
1945
|
+
setLightColor,
|
|
1946
|
+
setDarkColor,
|
|
1947
|
+
setTextColor,
|
|
1948
|
+
setColors,
|
|
1949
|
+
setOnboardingStep,
|
|
1950
|
+
addToast,
|
|
1951
|
+
removeToast,
|
|
1952
|
+
onError: errorHandler.onError,
|
|
1953
|
+
touch,
|
|
1954
|
+
read,
|
|
1955
|
+
syncTimestamps,
|
|
1956
|
+
readTimestamps,
|
|
1957
|
+
expireDataCaches: resetCaches,
|
|
1958
|
+
hasBeenTouched,
|
|
1959
|
+
eventCallbacks
|
|
1960
|
+
}
|
|
1961
|
+
},
|
|
1962
|
+
/* @__PURE__ */ React7.createElement(BankTransactionsProvider, null, /* @__PURE__ */ React7.createElement(DrawerContext.Provider, { value: drawerContextData }, children, /* @__PURE__ */ React7.createElement(GlobalWidgets, null)))
|
|
1963
|
+
));
|
|
1942
1964
|
};
|
|
1943
1965
|
|
|
1966
|
+
// src/components/Onboarding/Onboarding.tsx
|
|
1967
|
+
import React44, { useContext as useContext6, useEffect as useEffect6, useState as useState8 } from "react";
|
|
1968
|
+
|
|
1969
|
+
// src/contexts/LinkedAccountsContext/LinkedAccountsContext.ts
|
|
1970
|
+
import { createContext as createContext4 } from "react";
|
|
1971
|
+
var LinkedAccountsContext = createContext4({
|
|
1972
|
+
data: void 0,
|
|
1973
|
+
isLoading: false,
|
|
1974
|
+
loadingStatus: "initial",
|
|
1975
|
+
isValidating: false,
|
|
1976
|
+
error: void 0,
|
|
1977
|
+
updateConnectionStatus: () => {
|
|
1978
|
+
},
|
|
1979
|
+
addConnection: () => {
|
|
1980
|
+
},
|
|
1981
|
+
removeConnection: () => {
|
|
1982
|
+
},
|
|
1983
|
+
repairConnection: () => {
|
|
1984
|
+
},
|
|
1985
|
+
refetchAccounts: () => {
|
|
1986
|
+
},
|
|
1987
|
+
unlinkAccount: () => {
|
|
1988
|
+
},
|
|
1989
|
+
denyAccount: () => {
|
|
1990
|
+
},
|
|
1991
|
+
confirmAccount: () => {
|
|
1992
|
+
},
|
|
1993
|
+
breakConnection: () => {
|
|
1994
|
+
},
|
|
1995
|
+
syncAccounts: () => {
|
|
1996
|
+
}
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1944
1999
|
// src/providers/LinkedAccountsProvider/LinkedAccountsProvider.tsx
|
|
2000
|
+
import React8 from "react";
|
|
1945
2001
|
var LinkedAccountsProvider = ({
|
|
1946
2002
|
children
|
|
1947
2003
|
}) => {
|
|
@@ -2215,8 +2271,20 @@ var Sunrise = ({ size = 12, ...props }) => /* @__PURE__ */ React16.createElement
|
|
|
2215
2271
|
);
|
|
2216
2272
|
var Sunrise_default = Sunrise;
|
|
2217
2273
|
|
|
2274
|
+
// src/components/BankTransactions/utils.ts
|
|
2275
|
+
var filterVisibility = (scope, bankTransaction) => {
|
|
2276
|
+
const categorized = CategorizedCategories.includes(
|
|
2277
|
+
bankTransaction.categorization_status
|
|
2278
|
+
);
|
|
2279
|
+
const inReview = ReviewCategories.includes(
|
|
2280
|
+
bankTransaction.categorization_status
|
|
2281
|
+
);
|
|
2282
|
+
return scope === "all" /* all */ || scope === "review" /* review */ && inReview || scope === "categorized" /* categorized */ && categorized;
|
|
2283
|
+
};
|
|
2284
|
+
var isCategorized = (bankTransaction) => CategorizedCategories.includes(bankTransaction.categorization_status);
|
|
2285
|
+
|
|
2218
2286
|
// src/utils/bankTransactions.ts
|
|
2219
|
-
import { isWithinInterval, parseISO
|
|
2287
|
+
import { isWithinInterval, parseISO } from "date-fns";
|
|
2220
2288
|
var hasMatch = (bankTransaction) => {
|
|
2221
2289
|
return Boolean(
|
|
2222
2290
|
bankTransaction?.suggested_matches && bankTransaction?.suggested_matches?.length > 0 || bankTransaction?.match
|
|
@@ -2244,7 +2312,7 @@ var countTransactionsToReview = ({
|
|
|
2244
2312
|
};
|
|
2245
2313
|
return transactions.filter((tx) => {
|
|
2246
2314
|
try {
|
|
2247
|
-
return filterVisibility("review" /* review */, tx) && isWithinInterval(
|
|
2315
|
+
return filterVisibility("review" /* review */, tx) && isWithinInterval(parseISO(tx.date), dateRangeInterval);
|
|
2248
2316
|
} catch (_err) {
|
|
2249
2317
|
return false;
|
|
2250
2318
|
}
|
|
@@ -2301,7 +2369,7 @@ var ChevronRight = ({ size = 18, ...props }) => /* @__PURE__ */ React17.createEl
|
|
|
2301
2369
|
var ChevronRight_default = ChevronRight;
|
|
2302
2370
|
|
|
2303
2371
|
// src/components/Button/Button.tsx
|
|
2304
|
-
import React18, { useRef } from "react";
|
|
2372
|
+
import React18, { useRef as useRef2 } from "react";
|
|
2305
2373
|
import classNames4 from "classnames";
|
|
2306
2374
|
var Button = ({
|
|
2307
2375
|
className,
|
|
@@ -2315,7 +2383,7 @@ var Button = ({
|
|
|
2315
2383
|
fullWidth,
|
|
2316
2384
|
...props
|
|
2317
2385
|
}) => {
|
|
2318
|
-
const buttonRef =
|
|
2386
|
+
const buttonRef = useRef2(null);
|
|
2319
2387
|
let justifyContent = "center";
|
|
2320
2388
|
if (justify) {
|
|
2321
2389
|
justifyContent = justify;
|
|
@@ -2986,7 +3054,7 @@ var ExpandButton = ({
|
|
|
2986
3054
|
|
|
2987
3055
|
// src/components/Button/Link.tsx
|
|
2988
3056
|
import React35, {
|
|
2989
|
-
useRef as
|
|
3057
|
+
useRef as useRef5
|
|
2990
3058
|
} from "react";
|
|
2991
3059
|
import classNames12 from "classnames";
|
|
2992
3060
|
var Link2 = ({
|
|
@@ -3001,7 +3069,7 @@ var Link2 = ({
|
|
|
3001
3069
|
fullWidth,
|
|
3002
3070
|
...props
|
|
3003
3071
|
}) => {
|
|
3004
|
-
const linkRef =
|
|
3072
|
+
const linkRef = useRef5(null);
|
|
3005
3073
|
let justifyContent = "center";
|
|
3006
3074
|
if (justify) {
|
|
3007
3075
|
justifyContent = justify;
|
|
@@ -3059,7 +3127,7 @@ var Link2 = ({
|
|
|
3059
3127
|
};
|
|
3060
3128
|
|
|
3061
3129
|
// src/components/Typography/Text.tsx
|
|
3062
|
-
import React36, { useRef as
|
|
3130
|
+
import React36, { useRef as useRef6, useState as useState7, useEffect as useEffect5 } from "react";
|
|
3063
3131
|
import classNames13 from "classnames";
|
|
3064
3132
|
var Text = ({
|
|
3065
3133
|
as: Component2 = "p",
|
|
@@ -3100,7 +3168,7 @@ var TextWithTooltip = ({
|
|
|
3100
3168
|
tooltipOptions,
|
|
3101
3169
|
...props
|
|
3102
3170
|
}) => {
|
|
3103
|
-
const textElementRef =
|
|
3171
|
+
const textElementRef = useRef6();
|
|
3104
3172
|
const compareSize = () => {
|
|
3105
3173
|
if (textElementRef.current) {
|
|
3106
3174
|
const compare = textElementRef.current.children[0].scrollWidth > textElementRef.current.children[0].clientWidth;
|
|
@@ -3557,11 +3625,11 @@ var MoreVertical = ({ size = 18, ...props }) => {
|
|
|
3557
3625
|
var MoreVertical_default = MoreVertical;
|
|
3558
3626
|
|
|
3559
3627
|
// src/components/HoverMenu/HoverMenu.tsx
|
|
3560
|
-
import React49, { useEffect as useEffect7, useRef as
|
|
3628
|
+
import React49, { useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
|
|
3561
3629
|
import classNames17 from "classnames";
|
|
3562
3630
|
var HoverMenu = ({ children, config }) => {
|
|
3563
3631
|
const [openMenu, setOpenMenu] = useState9(false);
|
|
3564
|
-
const hoverMenuRef =
|
|
3632
|
+
const hoverMenuRef = useRef7(null);
|
|
3565
3633
|
const hoverMenuClassName = classNames17(
|
|
3566
3634
|
"Layer__hover-menu",
|
|
3567
3635
|
openMenu && "Layer__hover-menu--open"
|
|
@@ -4201,12 +4269,12 @@ var LinkedAccountsComponent = ({
|
|
|
4201
4269
|
};
|
|
4202
4270
|
|
|
4203
4271
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
4204
|
-
import React109, {
|
|
4272
|
+
import React109, { useEffect as useEffect19, useMemo as useMemo6, useState as useState25 } from "react";
|
|
4205
4273
|
|
|
4206
4274
|
// src/hooks/useElementSize/useElementSize.ts
|
|
4207
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
4275
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef8 } from "react";
|
|
4208
4276
|
var useElementSize = (callback) => {
|
|
4209
|
-
const ref =
|
|
4277
|
+
const ref = useRef8(null);
|
|
4210
4278
|
useLayoutEffect2(() => {
|
|
4211
4279
|
const element = ref?.current;
|
|
4212
4280
|
if (!element) {
|
|
@@ -4247,7 +4315,7 @@ var debounce = (fnc, timeout = 300) => {
|
|
|
4247
4315
|
import React85 from "react";
|
|
4248
4316
|
|
|
4249
4317
|
// src/components/BankTransactionList/BankTransactionListItem.tsx
|
|
4250
|
-
import React84, { useEffect as useEffect12, useRef as
|
|
4318
|
+
import React84, { useEffect as useEffect12, useRef as useRef12, useState as useState15 } from "react";
|
|
4251
4319
|
|
|
4252
4320
|
// src/icons/ChevronDownFill.tsx
|
|
4253
4321
|
import * as React57 from "react";
|
|
@@ -4275,7 +4343,7 @@ var ChevronDownFill = ({ size = 18, ...props }) => /* @__PURE__ */ React57.creat
|
|
|
4275
4343
|
var ChevronDownFill_default = ChevronDownFill;
|
|
4276
4344
|
|
|
4277
4345
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
4278
|
-
import React82, { useEffect as useEffect11, useRef as
|
|
4346
|
+
import React82, { useEffect as useEffect11, useRef as useRef11, useState as useState14 } from "react";
|
|
4279
4347
|
|
|
4280
4348
|
// src/icons/Scissors.tsx
|
|
4281
4349
|
import * as React58 from "react";
|
|
@@ -4693,7 +4761,7 @@ var CategorySelectDrawerContent = ({
|
|
|
4693
4761
|
|
|
4694
4762
|
// src/components/CategorySelect/CategorySelect.tsx
|
|
4695
4763
|
import classNames23 from "classnames";
|
|
4696
|
-
import { parseISO as
|
|
4764
|
+
import { parseISO as parseISO2, format as formatTime } from "date-fns";
|
|
4697
4765
|
var mapCategoryToOption2 = (category) => {
|
|
4698
4766
|
return {
|
|
4699
4767
|
type: "category" /* CATEGORY */,
|
|
@@ -4745,7 +4813,7 @@ var Option2 = (props) => {
|
|
|
4745
4813
|
...props,
|
|
4746
4814
|
className: `${props.className} Layer__select__option-content__match`
|
|
4747
4815
|
},
|
|
4748
|
-
/* @__PURE__ */ React65.createElement("div", { className: "Layer__select__option-content__match__main-row" }, /* @__PURE__ */ React65.createElement("span", { className: "Layer__select__option-content__match__date" }, props.data.payload.date && formatTime(
|
|
4816
|
+
/* @__PURE__ */ React65.createElement("div", { className: "Layer__select__option-content__match__main-row" }, /* @__PURE__ */ React65.createElement("span", { className: "Layer__select__option-content__match__date" }, props.data.payload.date && formatTime(parseISO2(props.data.payload.date), DATE_FORMAT)), /* @__PURE__ */ React65.createElement("span", { className: "Layer__select__option-content__match__description" }, props.data.payload.display_name)),
|
|
4749
4817
|
/* @__PURE__ */ React65.createElement("div", { className: "Layer__select__option-content__match__amount-row" }, /* @__PURE__ */ React65.createElement("span", { className: "Layer__select__option-content__match__amount" }, "$", centsToDollars(props.data.payload.amount)))
|
|
4750
4818
|
);
|
|
4751
4819
|
}
|
|
@@ -4875,7 +4943,7 @@ import React80, {
|
|
|
4875
4943
|
useState as useState13,
|
|
4876
4944
|
useCallback,
|
|
4877
4945
|
useEffect as useEffect10,
|
|
4878
|
-
useRef as
|
|
4946
|
+
useRef as useRef10
|
|
4879
4947
|
} from "react";
|
|
4880
4948
|
|
|
4881
4949
|
// src/icons/ScissorsFullOpen.tsx
|
|
@@ -5037,7 +5105,7 @@ var InputGroup = ({
|
|
|
5037
5105
|
};
|
|
5038
5106
|
|
|
5039
5107
|
// src/components/Input/FileInput.tsx
|
|
5040
|
-
import React71, { useRef as
|
|
5108
|
+
import React71, { useRef as useRef9 } from "react";
|
|
5041
5109
|
|
|
5042
5110
|
// src/icons/UploadCloud.tsx
|
|
5043
5111
|
import * as React70 from "react";
|
|
@@ -5092,7 +5160,7 @@ var UploadCloud_default = UploadCloud;
|
|
|
5092
5160
|
|
|
5093
5161
|
// src/components/Input/FileInput.tsx
|
|
5094
5162
|
var FileInput = ({ text = "Upload", onUpload }) => {
|
|
5095
|
-
const hiddenFileInput =
|
|
5163
|
+
const hiddenFileInput = useRef9(null);
|
|
5096
5164
|
const onClick = () => {
|
|
5097
5165
|
if (hiddenFileInput.current) {
|
|
5098
5166
|
hiddenFileInput.current.click();
|
|
@@ -5193,7 +5261,7 @@ import React75 from "react";
|
|
|
5193
5261
|
|
|
5194
5262
|
// src/components/BankTransactionRow/MatchBadge.tsx
|
|
5195
5263
|
import React74 from "react";
|
|
5196
|
-
import { parseISO as
|
|
5264
|
+
import { parseISO as parseISO3, format as formatTime2 } from "date-fns";
|
|
5197
5265
|
var MatchBadge = ({
|
|
5198
5266
|
bankTransaction,
|
|
5199
5267
|
classNamePrefix,
|
|
@@ -5206,7 +5274,7 @@ var MatchBadge = ({
|
|
|
5206
5274
|
Badge,
|
|
5207
5275
|
{
|
|
5208
5276
|
icon: /* @__PURE__ */ React74.createElement(MinimizeTwo_default, { size: 11 }),
|
|
5209
|
-
tooltip: /* @__PURE__ */ React74.createElement("span", { className: `${classNamePrefix}__match-tooltip` }, /* @__PURE__ */ React74.createElement("div", { className: `${classNamePrefix}__match-tooltip__date` }, formatTime2(
|
|
5277
|
+
tooltip: /* @__PURE__ */ React74.createElement("span", { className: `${classNamePrefix}__match-tooltip` }, /* @__PURE__ */ React74.createElement("div", { className: `${classNamePrefix}__match-tooltip__date` }, formatTime2(parseISO3(date), dateFormat)), /* @__PURE__ */ React74.createElement("div", { className: `${classNamePrefix}__match-tooltip__description` }, bankTransaction.match?.details?.description ?? ""), /* @__PURE__ */ React74.createElement("div", { className: `${classNamePrefix}__match-tooltip__amount` }, "$", centsToDollars(amount)))
|
|
5210
5278
|
},
|
|
5211
5279
|
text
|
|
5212
5280
|
);
|
|
@@ -5216,7 +5284,7 @@ var MatchBadge = ({
|
|
|
5216
5284
|
|
|
5217
5285
|
// src/components/MatchForm/MatchForm.tsx
|
|
5218
5286
|
import classNames28 from "classnames";
|
|
5219
|
-
import { parseISO as
|
|
5287
|
+
import { parseISO as parseISO4, format as formatTime3 } from "date-fns";
|
|
5220
5288
|
var MatchForm = ({
|
|
5221
5289
|
classNamePrefix,
|
|
5222
5290
|
bankTransaction,
|
|
@@ -5255,7 +5323,7 @@ var MatchForm = ({
|
|
|
5255
5323
|
{
|
|
5256
5324
|
className: `Layer__nowrap ${classNamePrefix}__match-table__date`
|
|
5257
5325
|
},
|
|
5258
|
-
/* @__PURE__ */ React75.createElement("span", null, formatTime3(
|
|
5326
|
+
/* @__PURE__ */ React75.createElement("span", null, formatTime3(parseISO4(match.details.date), DATE_FORMAT)),
|
|
5259
5327
|
/* @__PURE__ */ React75.createElement("span", { className: "amount-next-to-date" }, "$", centsToDollars(match.details.amount))
|
|
5260
5328
|
),
|
|
5261
5329
|
/* @__PURE__ */ React75.createElement("div", { className: `${classNamePrefix}__match-table__desc` }, /* @__PURE__ */ React75.createElement(
|
|
@@ -5298,7 +5366,7 @@ var MatchForm = ({
|
|
|
5298
5366
|
// src/components/MatchForm/MatchFormMobile.tsx
|
|
5299
5367
|
import React76 from "react";
|
|
5300
5368
|
import classNames29 from "classnames";
|
|
5301
|
-
import { parseISO as
|
|
5369
|
+
import { parseISO as parseISO5, format as formatTime4 } from "date-fns";
|
|
5302
5370
|
var MatchFormMobile = ({
|
|
5303
5371
|
classNamePrefix,
|
|
5304
5372
|
bankTransaction,
|
|
@@ -5345,7 +5413,7 @@ var MatchFormMobile = ({
|
|
|
5345
5413
|
size: "sm" /* sm */,
|
|
5346
5414
|
as: "span"
|
|
5347
5415
|
},
|
|
5348
|
-
formatTime4(
|
|
5416
|
+
formatTime4(parseISO5(match.details.date), MONTH_DAY_FORMAT)
|
|
5349
5417
|
))),
|
|
5350
5418
|
/* @__PURE__ */ React76.createElement("div", { className: `${classNamePrefix}__match-item__col-status` }, selectedMatchId && selectedMatchId === match.id ? /* @__PURE__ */ React76.createElement(
|
|
5351
5419
|
Check_default,
|
|
@@ -5674,7 +5742,7 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5674
5742
|
const [splitFormError, setSplitFormError] = useState13();
|
|
5675
5743
|
const [height, setHeight] = useState13(0);
|
|
5676
5744
|
const [isOver, setOver] = useState13(false);
|
|
5677
|
-
const bodyRef =
|
|
5745
|
+
const bodyRef = useRef10(null);
|
|
5678
5746
|
const [memoText, setMemoText] = useState13();
|
|
5679
5747
|
const [receiptUrls, setReceiptUrls] = useState13([]);
|
|
5680
5748
|
const [isLoaded, setIsLoaded] = useState13(false);
|
|
@@ -5773,7 +5841,6 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5773
5841
|
setSplitFormError(void 0);
|
|
5774
5842
|
};
|
|
5775
5843
|
const save = async () => {
|
|
5776
|
-
const endpoint = `/v1/businesses/${businessId}/bank-transactions/${bankTransaction.id}/metadata`;
|
|
5777
5844
|
if (showDescriptions && memoText != void 0) {
|
|
5778
5845
|
const result = await Layer.updateBankTransactionMetadata(
|
|
5779
5846
|
apiUrl,
|
|
@@ -6145,7 +6212,7 @@ var SplitTooltipDetails = ({
|
|
|
6145
6212
|
|
|
6146
6213
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
6147
6214
|
import classNames33 from "classnames";
|
|
6148
|
-
import { parseISO as
|
|
6215
|
+
import { parseISO as parseISO6, format as formatTime5 } from "date-fns";
|
|
6149
6216
|
var extractDescriptionForSplit = (category) => {
|
|
6150
6217
|
if (!category.entries) {
|
|
6151
6218
|
return "";
|
|
@@ -6177,12 +6244,12 @@ var BankTransactionRow = ({
|
|
|
6177
6244
|
showReceiptUploads,
|
|
6178
6245
|
stringOverrides
|
|
6179
6246
|
}) => {
|
|
6180
|
-
const expandedRowRef =
|
|
6247
|
+
const expandedRowRef = useRef11(null);
|
|
6181
6248
|
const [showRetry, setShowRetry] = useState14(false);
|
|
6182
6249
|
const {
|
|
6183
|
-
filters,
|
|
6184
6250
|
categorize: categorizeBankTransaction2,
|
|
6185
|
-
match: matchBankTransaction2
|
|
6251
|
+
match: matchBankTransaction2,
|
|
6252
|
+
shouldHideAfterCategorize
|
|
6186
6253
|
} = useBankTransactionsContext();
|
|
6187
6254
|
const [selectedCategory, setSelectedCategory] = useState14(
|
|
6188
6255
|
getDefaultSelectedCategory(bankTransaction)
|
|
@@ -6220,7 +6287,7 @@ var BankTransactionRow = ({
|
|
|
6220
6287
|
}
|
|
6221
6288
|
}, [bankTransaction.error]);
|
|
6222
6289
|
useEffect11(() => {
|
|
6223
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6290
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6224
6291
|
setTimeout(() => {
|
|
6225
6292
|
removeTransaction(bankTransaction);
|
|
6226
6293
|
}, 300);
|
|
@@ -6253,7 +6320,7 @@ var BankTransactionRow = ({
|
|
|
6253
6320
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6254
6321
|
const rowClassName = classNames33(
|
|
6255
6322
|
className,
|
|
6256
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6323
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6257
6324
|
open ? openClassName : "",
|
|
6258
6325
|
initialLoad ? "initial-load" : "",
|
|
6259
6326
|
showComponent ? "show" : ""
|
|
@@ -6264,7 +6331,7 @@ var BankTransactionRow = ({
|
|
|
6264
6331
|
className: "Layer__table-cell Layer__bank-transaction-table__date-col",
|
|
6265
6332
|
...openRow
|
|
6266
6333
|
},
|
|
6267
|
-
/* @__PURE__ */ React82.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(
|
|
6334
|
+
/* @__PURE__ */ React82.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(parseISO6(bankTransaction.date), dateFormat))
|
|
6268
6335
|
), /* @__PURE__ */ React82.createElement(
|
|
6269
6336
|
"td",
|
|
6270
6337
|
{
|
|
@@ -6354,7 +6421,7 @@ var BankTransactionRow = ({
|
|
|
6354
6421
|
dateFormat
|
|
6355
6422
|
}
|
|
6356
6423
|
), /* @__PURE__ */ React82.createElement("span", { className: `${className}__category-text__text` }, `${formatTime5(
|
|
6357
|
-
|
|
6424
|
+
parseISO6(bankTransaction.match.bank_transaction.date),
|
|
6358
6425
|
dateFormat
|
|
6359
6426
|
)}, ${bankTransaction.match?.details?.description}`)), bankTransaction?.categorization_status !== "MATCHED" /* MATCHED */ && bankTransaction?.categorization_status !== "SPLIT" /* SPLIT */ && /* @__PURE__ */ React82.createElement("span", { className: `${className}__category-text__text` }, bankTransaction?.category?.display_name)) : null,
|
|
6360
6427
|
!categorized && !open && showRetry ? /* @__PURE__ */ React82.createElement(
|
|
@@ -6429,7 +6496,7 @@ var BankTransactionRow = ({
|
|
|
6429
6496
|
|
|
6430
6497
|
// src/components/BankTransactionList/Assignment.tsx
|
|
6431
6498
|
import React83 from "react";
|
|
6432
|
-
import { parseISO as
|
|
6499
|
+
import { parseISO as parseISO7, format as formatTime6 } from "date-fns";
|
|
6433
6500
|
var Assignment = ({ bankTransaction }) => {
|
|
6434
6501
|
if (bankTransaction.match && bankTransaction.categorization_status === "MATCHED" /* MATCHED */) {
|
|
6435
6502
|
return /* @__PURE__ */ React83.createElement(React83.Fragment, null, /* @__PURE__ */ React83.createElement(
|
|
@@ -6441,7 +6508,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6441
6508
|
text: "Matched"
|
|
6442
6509
|
}
|
|
6443
6510
|
), /* @__PURE__ */ React83.createElement(Text, { className: "Layer__bank-transaction-list-item__category-text__text" }, `${formatTime6(
|
|
6444
|
-
|
|
6511
|
+
parseISO7(bankTransaction.match.bank_transaction.date),
|
|
6445
6512
|
DATE_FORMAT
|
|
6446
6513
|
)}, ${bankTransaction.match.bank_transaction.description ?? bankTransaction.match?.details?.description}`));
|
|
6447
6514
|
}
|
|
@@ -6466,7 +6533,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6466
6533
|
|
|
6467
6534
|
// src/components/BankTransactionList/BankTransactionListItem.tsx
|
|
6468
6535
|
import classNames34 from "classnames";
|
|
6469
|
-
import { parseISO as
|
|
6536
|
+
import { parseISO as parseISO8, format as formatTime7 } from "date-fns";
|
|
6470
6537
|
var BankTransactionListItem = ({
|
|
6471
6538
|
index = 0,
|
|
6472
6539
|
dateFormat,
|
|
@@ -6479,9 +6546,13 @@ var BankTransactionListItem = ({
|
|
|
6479
6546
|
removeTransaction,
|
|
6480
6547
|
stringOverrides
|
|
6481
6548
|
}) => {
|
|
6482
|
-
const expandedRowRef =
|
|
6549
|
+
const expandedRowRef = useRef12(null);
|
|
6483
6550
|
const [showRetry, setShowRetry] = useState15(false);
|
|
6484
|
-
const {
|
|
6551
|
+
const {
|
|
6552
|
+
categorize: categorizeBankTransaction2,
|
|
6553
|
+
match: matchBankTransaction2,
|
|
6554
|
+
shouldHideAfterCategorize
|
|
6555
|
+
} = useBankTransactionsContext();
|
|
6485
6556
|
const [selectedCategory, setSelectedCategory] = useState15(
|
|
6486
6557
|
getDefaultSelectedCategory(bankTransaction)
|
|
6487
6558
|
);
|
|
@@ -6503,7 +6574,7 @@ var BankTransactionListItem = ({
|
|
|
6503
6574
|
}
|
|
6504
6575
|
}, [bankTransaction.error]);
|
|
6505
6576
|
useEffect12(() => {
|
|
6506
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6577
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6507
6578
|
setTimeout(() => {
|
|
6508
6579
|
removeTransaction(bankTransaction);
|
|
6509
6580
|
}, 300);
|
|
@@ -6531,11 +6602,11 @@ var BankTransactionListItem = ({
|
|
|
6531
6602
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6532
6603
|
const rowClassName = classNames34(
|
|
6533
6604
|
className,
|
|
6534
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6605
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6535
6606
|
open ? openClassName : "",
|
|
6536
6607
|
showComponent ? "show" : ""
|
|
6537
6608
|
);
|
|
6538
|
-
return /* @__PURE__ */ React84.createElement("li", { className: rowClassName }, /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading` }, /* @__PURE__ */ React84.createElement("div", { className: `${className}__heading__main` }, /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading-date` }, formatTime7(
|
|
6609
|
+
return /* @__PURE__ */ React84.createElement("li", { className: rowClassName }, /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading` }, /* @__PURE__ */ React84.createElement("div", { className: `${className}__heading__main` }, /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading-date` }, formatTime7(parseISO8(bankTransaction.date), dateFormat)), /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading-separator` }), /* @__PURE__ */ React84.createElement("span", { className: `${className}__heading-account-name` }, bankTransaction.account_name ?? "")), /* @__PURE__ */ React84.createElement(
|
|
6539
6610
|
"div",
|
|
6540
6611
|
{
|
|
6541
6612
|
onClick: toggleOpen,
|
|
@@ -6645,7 +6716,7 @@ var BankTransactionList = ({
|
|
|
6645
6716
|
import React93 from "react";
|
|
6646
6717
|
|
|
6647
6718
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
6648
|
-
import React92, { useContext as useContext11, useEffect as useEffect17, useRef as
|
|
6719
|
+
import React92, { useContext as useContext11, useEffect as useEffect17, useRef as useRef13, useState as useState22 } from "react";
|
|
6649
6720
|
|
|
6650
6721
|
// src/components/BankTransactionMobileList/BankTransactionMobileForms.tsx
|
|
6651
6722
|
import React91 from "react";
|
|
@@ -7102,7 +7173,7 @@ var TransactionToOpenContext = createContext5({
|
|
|
7102
7173
|
|
|
7103
7174
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
7104
7175
|
import classNames36 from "classnames";
|
|
7105
|
-
import { parseISO as
|
|
7176
|
+
import { parseISO as parseISO9, format as formatTime8 } from "date-fns";
|
|
7106
7177
|
var DATE_FORMAT2 = "LLL d";
|
|
7107
7178
|
var getAssignedValue2 = (bankTransaction) => {
|
|
7108
7179
|
if (bankTransaction.categorization_status === "SPLIT" /* SPLIT */) {
|
|
@@ -7127,13 +7198,14 @@ var BankTransactionMobileListItem = ({
|
|
|
7127
7198
|
setTransactionIdToOpen,
|
|
7128
7199
|
clearTransactionIdToOpen
|
|
7129
7200
|
} = useContext11(TransactionToOpenContext);
|
|
7201
|
+
const { shouldHideAfterCategorize } = useBankTransactionsContext();
|
|
7130
7202
|
const formRowRef = useElementSize(
|
|
7131
7203
|
(_a, _b, { height: height2 }) => setHeight(height2)
|
|
7132
7204
|
);
|
|
7133
7205
|
const headingRowRef = useElementSize((_a, _b, { height: height2 }) => {
|
|
7134
7206
|
setHeadingHeight(height2);
|
|
7135
7207
|
});
|
|
7136
|
-
const itemRef =
|
|
7208
|
+
const itemRef = useRef13(null);
|
|
7137
7209
|
const [removeAnim, setRemoveAnim] = useState22(false);
|
|
7138
7210
|
const [purpose, setPurpose] = useState22(
|
|
7139
7211
|
bankTransaction.category ? bankTransaction.categorization_status === "SPLIT" /* SPLIT */ ? "more" /* more */ : "business" /* business */ : hasMatch(bankTransaction) ? "more" /* more */ : "business" /* business */
|
|
@@ -7160,7 +7232,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7160
7232
|
}, [transactionIdToOpen]);
|
|
7161
7233
|
useEffect17(() => {
|
|
7162
7234
|
if (!removeAnim && bankTransaction.recently_categorized) {
|
|
7163
|
-
if (editable) {
|
|
7235
|
+
if (editable && shouldHideAfterCategorize(bankTransaction)) {
|
|
7164
7236
|
setRemoveAnim(true);
|
|
7165
7237
|
openNext();
|
|
7166
7238
|
} else {
|
|
@@ -7193,7 +7265,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7193
7265
|
}
|
|
7194
7266
|
}, []);
|
|
7195
7267
|
useEffect17(() => {
|
|
7196
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
7268
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
7197
7269
|
setTimeout(() => {
|
|
7198
7270
|
removeTransaction(bankTransaction);
|
|
7199
7271
|
}, 300);
|
|
@@ -7224,7 +7296,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7224
7296
|
},
|
|
7225
7297
|
isCredit(bankTransaction) ? "+$" : " $",
|
|
7226
7298
|
centsToDollars(bankTransaction.amount)
|
|
7227
|
-
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(
|
|
7299
|
+
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(parseISO9(bankTransaction.date), DATE_FORMAT2))))
|
|
7228
7300
|
), categorizationEnabled(mode) ? /* @__PURE__ */ React92.createElement(
|
|
7229
7301
|
"div",
|
|
7230
7302
|
{
|
|
@@ -7747,11 +7819,11 @@ var DownloadCloud = ({ size = 18, ...props }) => /* @__PURE__ */ React103.create
|
|
|
7747
7819
|
var DownloadCloud_default = DownloadCloud;
|
|
7748
7820
|
|
|
7749
7821
|
// src/utils/business.ts
|
|
7750
|
-
import { differenceInCalendarMonths, parseISO as
|
|
7822
|
+
import { differenceInCalendarMonths, parseISO as parseISO10, startOfMonth } from "date-fns";
|
|
7751
7823
|
var getActivationDate = (business) => {
|
|
7752
7824
|
try {
|
|
7753
7825
|
if (business && business.activation_at) {
|
|
7754
|
-
return
|
|
7826
|
+
return parseISO10(business.activation_at);
|
|
7755
7827
|
}
|
|
7756
7828
|
return;
|
|
7757
7829
|
} catch (_err) {
|
|
@@ -7777,7 +7849,7 @@ var isDateAllowedToBrowse = (date, business) => {
|
|
|
7777
7849
|
};
|
|
7778
7850
|
|
|
7779
7851
|
// src/components/DatePicker/DatePicker.tsx
|
|
7780
|
-
import React105, { useEffect as useEffect18, useRef as
|
|
7852
|
+
import React105, { useEffect as useEffect18, useRef as useRef14, useState as useState23 } from "react";
|
|
7781
7853
|
import ReactDatePicker from "react-datepicker";
|
|
7782
7854
|
|
|
7783
7855
|
// src/components/DatePicker/DatePickerOptions.tsx
|
|
@@ -7940,7 +8012,7 @@ var DatePicker = ({
|
|
|
7940
8012
|
navigateArrows = mode === "monthPicker",
|
|
7941
8013
|
...props
|
|
7942
8014
|
}) => {
|
|
7943
|
-
const pickerRef =
|
|
8015
|
+
const pickerRef = useRef14(null);
|
|
7944
8016
|
const [updatePickerDate, setPickerDate] = useState23(false);
|
|
7945
8017
|
const [selectedDates, setSelectedDates] = useState23(selected);
|
|
7946
8018
|
const { isDesktop } = useSizeClass();
|
|
@@ -8336,7 +8408,7 @@ var DataStates = ({
|
|
|
8336
8408
|
editable
|
|
8337
8409
|
}) => {
|
|
8338
8410
|
let title = editable ? "You are up to date with transactions!" : "You have no categorized transactions";
|
|
8339
|
-
let description = editable ? "All uncategorized
|
|
8411
|
+
let description = editable ? "All uncategorized transactions will be displayed here" : "All transactions will be displayed here once reviewed";
|
|
8340
8412
|
const showRefreshButton = bankTransactions?.length;
|
|
8341
8413
|
return /* @__PURE__ */ React108.createElement(React108.Fragment, null, !isLoading && !error && (bankTransactions === void 0 || bankTransactions !== void 0 && bankTransactions.length === 0) ? /* @__PURE__ */ React108.createElement("div", { className: "Layer__table-state-container" }, /* @__PURE__ */ React108.createElement(
|
|
8342
8414
|
DataState,
|
|
@@ -8361,10 +8433,9 @@ var DataStates = ({
|
|
|
8361
8433
|
};
|
|
8362
8434
|
|
|
8363
8435
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
8364
|
-
import { endOfMonth as endOfMonth3, parseISO as
|
|
8436
|
+
import { endOfMonth as endOfMonth3, parseISO as parseISO11, startOfMonth as startOfMonth4 } from "date-fns";
|
|
8365
8437
|
var COMPONENT_NAME2 = "bank-transactions";
|
|
8366
8438
|
var TEST_EMPTY_STATE = false;
|
|
8367
|
-
var POLL_INTERVAL = 1e3;
|
|
8368
8439
|
var categorizationEnabled = (mode) => {
|
|
8369
8440
|
if (mode === "bookkeeping-client") {
|
|
8370
8441
|
return false;
|
|
@@ -8384,6 +8455,7 @@ var BankTransactionsContent = ({
|
|
|
8384
8455
|
showDescriptions = false,
|
|
8385
8456
|
showReceiptUploads = false,
|
|
8386
8457
|
monthlyView = false,
|
|
8458
|
+
categorizeView: categorizeViewProp,
|
|
8387
8459
|
mobileComponent,
|
|
8388
8460
|
filters: inputFilters,
|
|
8389
8461
|
hideHeader = false,
|
|
@@ -8395,7 +8467,7 @@ var BankTransactionsContent = ({
|
|
|
8395
8467
|
startDate: startOfMonth4(/* @__PURE__ */ new Date()),
|
|
8396
8468
|
endDate: endOfMonth3(/* @__PURE__ */ new Date())
|
|
8397
8469
|
});
|
|
8398
|
-
const categorizeView = categorizationEnabled(mode);
|
|
8470
|
+
const categorizeView = categorizeViewProp ?? categorizationEnabled(mode);
|
|
8399
8471
|
const {
|
|
8400
8472
|
activate,
|
|
8401
8473
|
data,
|
|
@@ -8411,51 +8483,23 @@ var BankTransactionsContent = ({
|
|
|
8411
8483
|
fetchMore,
|
|
8412
8484
|
removeAfterCategorize
|
|
8413
8485
|
} = useBankTransactionsContext();
|
|
8414
|
-
const { data: linkedAccounts
|
|
8486
|
+
const { data: linkedAccounts } = useLinkedAccounts();
|
|
8415
8487
|
const isSyncing = useMemo6(
|
|
8416
8488
|
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
8417
8489
|
[linkedAccounts]
|
|
8418
8490
|
);
|
|
8419
|
-
const transactionsNotSynced = useMemo6(
|
|
8420
|
-
() => loadingStatus === "complete" && isSyncing && (!data || data?.length === 0),
|
|
8421
|
-
[data, isSyncing, loadingStatus]
|
|
8422
|
-
);
|
|
8423
|
-
let intervalId = void 0;
|
|
8424
|
-
const [refreshTrigger, setRefreshTrigger] = useState25(-1);
|
|
8425
|
-
useEffect19(() => {
|
|
8426
|
-
if (refreshTrigger !== -1) {
|
|
8427
|
-
refetch();
|
|
8428
|
-
refetchAccounts();
|
|
8429
|
-
}
|
|
8430
|
-
}, [refreshTrigger]);
|
|
8431
|
-
useEffect19(() => {
|
|
8432
|
-
if (isSyncing) {
|
|
8433
|
-
intervalId = setInterval(() => {
|
|
8434
|
-
setRefreshTrigger(Math.random());
|
|
8435
|
-
}, POLL_INTERVAL);
|
|
8436
|
-
} else {
|
|
8437
|
-
if (intervalId) {
|
|
8438
|
-
clearInterval(intervalId);
|
|
8439
|
-
}
|
|
8440
|
-
}
|
|
8441
|
-
return () => {
|
|
8442
|
-
if (intervalId) {
|
|
8443
|
-
clearInterval(intervalId);
|
|
8444
|
-
}
|
|
8445
|
-
};
|
|
8446
|
-
}, [isSyncing, transactionsNotSynced]);
|
|
8447
8491
|
useEffect19(() => {
|
|
8448
8492
|
activate();
|
|
8449
8493
|
}, []);
|
|
8450
8494
|
useEffect19(() => {
|
|
8451
8495
|
if (JSON.stringify(inputFilters) !== JSON.stringify(filters)) {
|
|
8452
|
-
if (!
|
|
8496
|
+
if (!inputFilters?.categorizationStatus && categorizeView) {
|
|
8453
8497
|
setFilters({
|
|
8454
8498
|
...filters,
|
|
8455
8499
|
...inputFilters,
|
|
8456
8500
|
categorizationStatus: "review" /* review */
|
|
8457
8501
|
});
|
|
8458
|
-
} else if (!
|
|
8502
|
+
} else if (!inputFilters?.categorizationStatus && !categorizationEnabled(mode)) {
|
|
8459
8503
|
setFilters({
|
|
8460
8504
|
...filters,
|
|
8461
8505
|
...inputFilters,
|
|
@@ -8464,11 +8508,11 @@ var BankTransactionsContent = ({
|
|
|
8464
8508
|
} else {
|
|
8465
8509
|
setFilters({ ...filters, ...inputFilters });
|
|
8466
8510
|
}
|
|
8467
|
-
} else if (!
|
|
8511
|
+
} else if (!inputFilters?.categorizationStatus && categorizeView) {
|
|
8468
8512
|
setFilters({
|
|
8469
8513
|
categorizationStatus: "review" /* review */
|
|
8470
8514
|
});
|
|
8471
|
-
} else if (!
|
|
8515
|
+
} else if (!inputFilters?.categorizationStatus && !categorizationEnabled(mode)) {
|
|
8472
8516
|
setFilters({
|
|
8473
8517
|
categorizationStatus: "categorized" /* categorized */
|
|
8474
8518
|
});
|
|
@@ -8485,7 +8529,7 @@ var BankTransactionsContent = ({
|
|
|
8485
8529
|
const bankTransactions = TEST_EMPTY_STATE ? [] : useMemo6(() => {
|
|
8486
8530
|
if (monthlyView) {
|
|
8487
8531
|
return data?.filter(
|
|
8488
|
-
(x) =>
|
|
8532
|
+
(x) => parseISO11(x.date) >= dateRange.startDate && parseISO11(x.date) <= dateRange.endDate
|
|
8489
8533
|
);
|
|
8490
8534
|
}
|
|
8491
8535
|
const firstPageIndex = (currentPage - 1) * pageSize;
|
|
@@ -8494,7 +8538,7 @@ var BankTransactionsContent = ({
|
|
|
8494
8538
|
}, [currentPage, data, dateRange]);
|
|
8495
8539
|
const onCategorizationDisplayChange = (event) => {
|
|
8496
8540
|
setFilters({
|
|
8497
|
-
categorizationStatus: event.target.value === "categorized" /* categorized */ ? "categorized" /* categorized */ : "review" /* review */
|
|
8541
|
+
categorizationStatus: event.target.value === "categorized" /* categorized */ ? "categorized" /* categorized */ : event.target.value === "all" /* all */ ? "all" /* all */ : "review" /* review */
|
|
8498
8542
|
});
|
|
8499
8543
|
setCurrentPage(1);
|
|
8500
8544
|
};
|
|
@@ -8520,7 +8564,7 @@ var BankTransactionsContent = ({
|
|
|
8520
8564
|
}
|
|
8521
8565
|
debounceContainerWidth(size?.width);
|
|
8522
8566
|
});
|
|
8523
|
-
const editable = display === "review" /* review */;
|
|
8567
|
+
const editable = display === "review" /* review */ || display === "all" /* all */;
|
|
8524
8568
|
const isLastPage = data && !hasMore && Math.ceil((data?.length || 0) / pageSize) === currentPage;
|
|
8525
8569
|
return /* @__PURE__ */ React109.createElement(
|
|
8526
8570
|
Container,
|
|
@@ -8621,7 +8665,7 @@ var BankTransactionsContent = ({
|
|
|
8621
8665
|
import React110 from "react";
|
|
8622
8666
|
|
|
8623
8667
|
// src/hooks/useQuickbooks/useQuickbooks.ts
|
|
8624
|
-
import { useEffect as useEffect20, useRef as
|
|
8668
|
+
import { useEffect as useEffect20, useRef as useRef16, useState as useState26 } from "react";
|
|
8625
8669
|
var DEBUG2 = true;
|
|
8626
8670
|
var useQuickbooks = () => {
|
|
8627
8671
|
const { auth, businessId, apiUrl } = useLayerContext();
|
|
@@ -8629,7 +8673,7 @@ var useQuickbooks = () => {
|
|
|
8629
8673
|
const [quickbooksIsLinked, setQuickbooksIsLinked] = useState26(
|
|
8630
8674
|
null
|
|
8631
8675
|
);
|
|
8632
|
-
const syncStatusIntervalRef =
|
|
8676
|
+
const syncStatusIntervalRef = useRef16(null);
|
|
8633
8677
|
useEffect20(() => {
|
|
8634
8678
|
if (isSyncingFromQuickbooks && syncStatusIntervalRef.current === null) {
|
|
8635
8679
|
const interval = setInterval(() => fetchIsSyncingFromQuickbooks(), 2e3);
|
|
@@ -11080,7 +11124,7 @@ var TableRow = ({
|
|
|
11080
11124
|
};
|
|
11081
11125
|
|
|
11082
11126
|
// src/components/Table/Table.tsx
|
|
11083
|
-
import React128, { useEffect as useEffect26, useRef as
|
|
11127
|
+
import React128, { useEffect as useEffect26, useRef as useRef17 } from "react";
|
|
11084
11128
|
import classNames47 from "classnames";
|
|
11085
11129
|
var Table = ({
|
|
11086
11130
|
componentName,
|
|
@@ -11088,8 +11132,8 @@ var Table = ({
|
|
|
11088
11132
|
borderCollapse = "separate",
|
|
11089
11133
|
bottomSpacing = true
|
|
11090
11134
|
}) => {
|
|
11091
|
-
const tableRef =
|
|
11092
|
-
const prevChildrenRef =
|
|
11135
|
+
const tableRef = useRef17(null);
|
|
11136
|
+
const prevChildrenRef = useRef17([]);
|
|
11093
11137
|
useEffect26(() => {
|
|
11094
11138
|
if (tableRef.current) {
|
|
11095
11139
|
const tbody = tableRef.current.querySelector("tbody");
|
|
@@ -13077,7 +13121,7 @@ var Card = ({ children, className }) => {
|
|
|
13077
13121
|
|
|
13078
13122
|
// src/components/DateTime/DateTime.tsx
|
|
13079
13123
|
import React149 from "react";
|
|
13080
|
-
import { parseISO as
|
|
13124
|
+
import { parseISO as parseISO12, format as formatTime9 } from "date-fns";
|
|
13081
13125
|
var DateTime = ({
|
|
13082
13126
|
value,
|
|
13083
13127
|
format: format7,
|
|
@@ -13087,10 +13131,10 @@ var DateTime = ({
|
|
|
13087
13131
|
onlyTime
|
|
13088
13132
|
}) => {
|
|
13089
13133
|
if (format7) {
|
|
13090
|
-
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(
|
|
13134
|
+
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(parseISO12(value), format7));
|
|
13091
13135
|
}
|
|
13092
|
-
const date = formatTime9(
|
|
13093
|
-
const time = formatTime9(
|
|
13136
|
+
const date = formatTime9(parseISO12(value), dateFormat ?? DATE_FORMAT);
|
|
13137
|
+
const time = formatTime9(parseISO12(value), timeFormat ?? TIME_FORMAT);
|
|
13094
13138
|
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, !onlyTime && /* @__PURE__ */ React149.createElement(
|
|
13095
13139
|
Text,
|
|
13096
13140
|
{
|
|
@@ -13255,7 +13299,7 @@ var LedgerAccountEntryDetails = ({ stringOverrides }) => {
|
|
|
13255
13299
|
// src/components/LedgerAccount/LedgerAccountRow.tsx
|
|
13256
13300
|
import React153, { useContext as useContext23, useEffect as useEffect36, useState as useState40 } from "react";
|
|
13257
13301
|
import classNames54 from "classnames";
|
|
13258
|
-
import { parseISO as
|
|
13302
|
+
import { parseISO as parseISO13, format as formatTime10 } from "date-fns";
|
|
13259
13303
|
var LedgerAccountRow = ({
|
|
13260
13304
|
row,
|
|
13261
13305
|
index,
|
|
@@ -13294,7 +13338,7 @@ var LedgerAccountRow = ({
|
|
|
13294
13338
|
}
|
|
13295
13339
|
}
|
|
13296
13340
|
},
|
|
13297
|
-
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell Layer__ledger-account-table__tablet-main-col" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React153.createElement("div", { className: "Layer__ledger-account-table__tablet-main-col__date" }, /* @__PURE__ */ React153.createElement(Text, null, row.date && formatTime10(
|
|
13341
|
+
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell Layer__ledger-account-table__tablet-main-col" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React153.createElement("div", { className: "Layer__ledger-account-table__tablet-main-col__date" }, /* @__PURE__ */ React153.createElement(Text, null, row.date && formatTime10(parseISO13(row.date), DATE_FORMAT)), /* @__PURE__ */ React153.createElement(
|
|
13298
13342
|
Text,
|
|
13299
13343
|
{
|
|
13300
13344
|
weight: "normal" /* normal */,
|
|
@@ -13327,7 +13371,7 @@ var LedgerAccountRow = ({
|
|
|
13327
13371
|
}
|
|
13328
13372
|
}
|
|
13329
13373
|
},
|
|
13330
|
-
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell Layer__ledger-account-table__tablet-main-col" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React153.createElement("div", { className: "Layer__ledger-account-table__tablet-main-col__date" }, /* @__PURE__ */ React153.createElement(Text, null, row.date && formatTime10(
|
|
13374
|
+
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell Layer__ledger-account-table__tablet-main-col" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, /* @__PURE__ */ React153.createElement("div", { className: "Layer__ledger-account-table__tablet-main-col__date" }, /* @__PURE__ */ React153.createElement(Text, null, row.date && formatTime10(parseISO13(row.date), DATE_FORMAT)), /* @__PURE__ */ React153.createElement(
|
|
13331
13375
|
Text,
|
|
13332
13376
|
{
|
|
13333
13377
|
weight: "normal" /* normal */,
|
|
@@ -13356,7 +13400,7 @@ var LedgerAccountRow = ({
|
|
|
13356
13400
|
}
|
|
13357
13401
|
}
|
|
13358
13402
|
},
|
|
13359
|
-
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.date && formatTime10(
|
|
13403
|
+
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.date && formatTime10(parseISO13(row.date), DATE_FORMAT))),
|
|
13360
13404
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.entry_id.substring(0, 5))),
|
|
13361
13405
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.source?.display_description ?? "")),
|
|
13362
13406
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell Layer__table-cell--primary" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content Layer__table-cell--amount" }, row.direction === "DEBIT" /* DEBIT */ && `$${centsToDollars(row?.amount || 0)}`)),
|
|
@@ -13866,7 +13910,7 @@ import React161, { useContext as useContext31, useMemo as useMemo17, useState as
|
|
|
13866
13910
|
// src/components/JournalRow/JournalRow.tsx
|
|
13867
13911
|
import React156, { useContext as useContext26, useEffect as useEffect39, useState as useState44 } from "react";
|
|
13868
13912
|
import classNames56 from "classnames";
|
|
13869
|
-
import { parseISO as
|
|
13913
|
+
import { parseISO as parseISO14, format as formatTime11 } from "date-fns";
|
|
13870
13914
|
var INDENTATION2 = 24;
|
|
13871
13915
|
var EXPANDED_STYLE3 = {
|
|
13872
13916
|
height: "100%",
|
|
@@ -13979,7 +14023,7 @@ var JournalRow = ({
|
|
|
13979
14023
|
)
|
|
13980
14024
|
))),
|
|
13981
14025
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, row.id.substring(0, 5))),
|
|
13982
|
-
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, row.date && formatTime11(
|
|
14026
|
+
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, row.date && formatTime11(parseISO14(row.date), DATE_FORMAT))),
|
|
13983
14027
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, humanizeEnum(row.entry_type))),
|
|
13984
14028
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, `(${row.line_items.length})`)),
|
|
13985
14029
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell Layer__table-cell--primary" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content Layer__table-cell--amount" }, "$", centsToDollars(
|
|
@@ -15457,7 +15501,7 @@ var GeneralLedgerView = ({
|
|
|
15457
15501
|
};
|
|
15458
15502
|
|
|
15459
15503
|
// src/views/Reports/Reports.tsx
|
|
15460
|
-
import React180, { useContext as useContext38, useRef as
|
|
15504
|
+
import React180, { useContext as useContext38, useRef as useRef18, useState as useState55 } from "react";
|
|
15461
15505
|
var DownloadButton2 = ({
|
|
15462
15506
|
stringOverrides
|
|
15463
15507
|
}) => {
|
|
@@ -15529,7 +15573,7 @@ var Reports = ({
|
|
|
15529
15573
|
stringOverrides,
|
|
15530
15574
|
enabledReports = ["profitAndLoss", "balanceSheet", "statementOfCashFlow"]
|
|
15531
15575
|
}) => {
|
|
15532
|
-
const containerRef =
|
|
15576
|
+
const containerRef = useRef18(null);
|
|
15533
15577
|
const [activeTab, setActiveTab] = useState55(enabledReports[0]);
|
|
15534
15578
|
const options = getOptions(enabledReports);
|
|
15535
15579
|
const defaultTitle = enabledReports.length > 1 ? "Reports" : options.find((option) => option.value = enabledReports[0])?.label;
|
|
@@ -15597,10 +15641,10 @@ var ReportsPanel = ({
|
|
|
15597
15641
|
};
|
|
15598
15642
|
|
|
15599
15643
|
// src/components/ProfitAndLossView/ProfitAndLossView.tsx
|
|
15600
|
-
import React181, { useContext as useContext39, useRef as
|
|
15644
|
+
import React181, { useContext as useContext39, useRef as useRef19 } from "react";
|
|
15601
15645
|
var COMPONENT_NAME7 = "profit-and-loss";
|
|
15602
15646
|
var ProfitAndLossView = (props) => {
|
|
15603
|
-
const containerRef =
|
|
15647
|
+
const containerRef = useRef19(null);
|
|
15604
15648
|
return /* @__PURE__ */ React181.createElement(Container, { name: COMPONENT_NAME7, ref: containerRef }, /* @__PURE__ */ React181.createElement(ProfitAndLoss, null, /* @__PURE__ */ React181.createElement(ProfitAndLossPanel, { containerRef, ...props })));
|
|
15605
15649
|
};
|
|
15606
15650
|
var ProfitAndLossPanel = ({
|
|
@@ -15681,6 +15725,7 @@ export {
|
|
|
15681
15725
|
BookkeepingOverview,
|
|
15682
15726
|
BookkeepingUpsellBar,
|
|
15683
15727
|
ChartOfAccounts,
|
|
15728
|
+
Direction,
|
|
15684
15729
|
DisplayState,
|
|
15685
15730
|
GeneralLedgerView,
|
|
15686
15731
|
Journal,
|
|
@@ -15694,6 +15739,7 @@ export {
|
|
|
15694
15739
|
StatementOfCashFlow,
|
|
15695
15740
|
Tasks,
|
|
15696
15741
|
useBankTransactionsContext,
|
|
15742
|
+
useDataSync,
|
|
15697
15743
|
useLayerContext
|
|
15698
15744
|
};
|
|
15699
15745
|
//# sourceMappingURL=index.js.map
|