@layerfi/components 0.1.52 → 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 +1290 -1249
- package/dist/esm/index.js.map +4 -4
- package/dist/index.d.ts +11 -5
- package/dist/index.js +1322 -1280
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/.idea/codeStyles/Project.xml +0 -61
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/layer-react.iml +0 -9
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
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,10 +657,10 @@ 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) => {
|
|
637
666
|
DisplayState2["all"] = "all";
|
|
@@ -663,6 +692,7 @@ var BankTransactionsContext = createContext3({
|
|
|
663
692
|
pagination: void 0
|
|
664
693
|
},
|
|
665
694
|
updateOneLocal: () => void 0,
|
|
695
|
+
shouldHideAfterCategorize: () => false,
|
|
666
696
|
removeAfterCategorize: () => void 0,
|
|
667
697
|
activate: () => void 0,
|
|
668
698
|
display: "review" /* review */,
|
|
@@ -673,7 +703,7 @@ var BankTransactionsContext = createContext3({
|
|
|
673
703
|
var useBankTransactionsContext = () => useContext4(BankTransactionsContext);
|
|
674
704
|
|
|
675
705
|
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
676
|
-
import { useEffect as
|
|
706
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef, useState as useState5 } from "react";
|
|
677
707
|
|
|
678
708
|
// src/components/BankTransactions/constants.ts
|
|
679
709
|
var CategorizedCategories = [
|
|
@@ -687,1264 +717,1287 @@ var ReviewCategories = [
|
|
|
687
717
|
"LAYER_REVIEW" /* LAYER_REVIEW */
|
|
688
718
|
];
|
|
689
719
|
|
|
690
|
-
// src/
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
bankTransaction.categorization_status
|
|
694
|
-
);
|
|
695
|
-
const inReview = ReviewCategories.includes(
|
|
696
|
-
bankTransaction.categorization_status
|
|
697
|
-
);
|
|
698
|
-
return scope === "all" /* all */ || scope === "review" /* review */ && inReview || scope === "categorized" /* categorized */ && categorized;
|
|
699
|
-
};
|
|
700
|
-
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";
|
|
701
723
|
|
|
702
|
-
// src/hooks/
|
|
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
|
-
|
|
744
|
-
|
|
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
|
|
745
821
|
}
|
|
746
|
-
|
|
747
|
-
(tx) => filterVisibility(filter, tx) || filter === "all" /* all */ || filter === "review" /* review */ && tx.recently_categorized || filter === "categorized" /* categorized */ && tx.recently_categorized
|
|
748
|
-
);
|
|
749
|
-
};
|
|
750
|
-
var appplyDateRangeFilter = (data, filter) => {
|
|
751
|
-
return data?.filter((x) => {
|
|
752
|
-
const txDate = parseISO(x.date);
|
|
753
|
-
if (filter?.startDate && filter?.endDate) {
|
|
754
|
-
return txDate >= filter.startDate && txDate <= filter.endDate;
|
|
755
|
-
}
|
|
756
|
-
if (filter?.startDate) {
|
|
757
|
-
return txDate >= filter.startDate;
|
|
758
|
-
}
|
|
759
|
-
if (filter?.endDate) {
|
|
760
|
-
return txDate <= filter.endDate;
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
};
|
|
822
|
+
];
|
|
764
823
|
|
|
765
|
-
// src/hooks/
|
|
766
|
-
import
|
|
767
|
-
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 = () => {
|
|
768
829
|
const {
|
|
769
830
|
auth,
|
|
770
831
|
businessId,
|
|
771
832
|
apiUrl,
|
|
772
|
-
|
|
833
|
+
usePlaidSandbox,
|
|
773
834
|
touch,
|
|
774
835
|
read,
|
|
775
836
|
syncTimestamps,
|
|
776
|
-
hasBeenTouched
|
|
777
|
-
eventCallbacks
|
|
837
|
+
hasBeenTouched
|
|
778
838
|
} = useLayerContext();
|
|
779
|
-
const
|
|
780
|
-
const [filters, setTheFilters] = useState4(
|
|
781
|
-
scope ? { categorizationStatus: scope } : void 0
|
|
782
|
-
);
|
|
783
|
-
const display = useMemo2(() => {
|
|
784
|
-
if (filters?.categorizationStatus === "review" /* review */) {
|
|
785
|
-
return "review" /* review */;
|
|
786
|
-
} else if (filters?.categorizationStatus === "all" /* all */) {
|
|
787
|
-
return "all" /* all */;
|
|
788
|
-
}
|
|
789
|
-
return "categorized" /* categorized */;
|
|
790
|
-
}, [filters?.categorizationStatus]);
|
|
791
|
-
const [active, setActive] = useState4(false);
|
|
839
|
+
const [linkToken, setLinkToken] = useState4(null);
|
|
792
840
|
const [loadingStatus, setLoadingStatus] = useState4("initial");
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
if (!prevData?.meta?.pagination?.cursor) {
|
|
798
|
-
return [
|
|
799
|
-
businessId && auth?.access_token && `bank-transactions-${businessId}`,
|
|
800
|
-
void 0
|
|
801
|
-
];
|
|
802
|
-
}
|
|
803
|
-
return [
|
|
804
|
-
businessId && auth?.access_token && `bank-transactions-${businessId}-${prevData.meta.pagination.cursor}`,
|
|
805
|
-
prevData.meta.pagination.cursor
|
|
806
|
-
];
|
|
807
|
-
};
|
|
841
|
+
const USE_PLAID_SANDBOX = usePlaidSandbox ?? true;
|
|
842
|
+
const [linkMode, setLinkMode] = useState4("add");
|
|
843
|
+
const queryKey = businessId && auth?.access_token && `linked-accounts-${businessId}`;
|
|
808
844
|
const {
|
|
809
|
-
data:
|
|
845
|
+
data: responseData,
|
|
810
846
|
isLoading,
|
|
811
847
|
isValidating,
|
|
812
848
|
error: responseError,
|
|
813
|
-
mutate
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
if (auth?.access_token) {
|
|
820
|
-
return Layer.getBankTransactions(apiUrl, auth?.access_token, {
|
|
821
|
-
params: {
|
|
822
|
-
businessId,
|
|
823
|
-
cursor: nextCursor
|
|
824
|
-
}
|
|
825
|
-
}).call(false);
|
|
826
|
-
}
|
|
827
|
-
return {};
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
initialSize: 1,
|
|
831
|
-
revalidateFirstPage: false
|
|
832
|
-
}
|
|
833
|
-
);
|
|
834
|
-
const data = useMemo2(() => {
|
|
835
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
836
|
-
return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
|
|
837
|
-
}
|
|
838
|
-
return void 0;
|
|
839
|
-
}, [rawResponseData]);
|
|
840
|
-
const lastMetadata = useMemo2(() => {
|
|
841
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
842
|
-
return rawResponseData[rawResponseData.length - 1].meta;
|
|
843
|
-
}
|
|
844
|
-
return void 0;
|
|
845
|
-
}, [rawResponseData]);
|
|
846
|
-
const hasMore = useMemo2(() => {
|
|
847
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
848
|
-
const lastElement = rawResponseData[rawResponseData.length - 1];
|
|
849
|
-
return Boolean(
|
|
850
|
-
lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more
|
|
851
|
-
);
|
|
852
|
-
}
|
|
853
|
-
return false;
|
|
854
|
-
}, [rawResponseData]);
|
|
855
|
-
const accountsList = useMemo2(
|
|
856
|
-
() => data ? collectAccounts(data) : [],
|
|
857
|
-
[data]
|
|
849
|
+
mutate
|
|
850
|
+
} = useSWR(
|
|
851
|
+
queryKey,
|
|
852
|
+
Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
|
|
853
|
+
params: { businessId }
|
|
854
|
+
})
|
|
858
855
|
);
|
|
859
856
|
useEffect2(() => {
|
|
857
|
+
if (!isLoading && responseData?.data.external_accounts) {
|
|
858
|
+
setLoadingStatus("complete");
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
860
861
|
if (isLoading && loadingStatus === "initial") {
|
|
861
862
|
setLoadingStatus("loading");
|
|
862
863
|
return;
|
|
863
864
|
}
|
|
864
865
|
if (!isLoading && loadingStatus === "loading") {
|
|
865
866
|
setLoadingStatus("complete");
|
|
866
|
-
return;
|
|
867
867
|
}
|
|
868
868
|
}, [isLoading]);
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
});
|
|
877
|
-
};
|
|
878
|
-
const filteredData = useMemo2(() => {
|
|
879
|
-
let filtered = data;
|
|
880
|
-
if (!filtered) {
|
|
881
|
-
return;
|
|
882
|
-
}
|
|
883
|
-
if (filters?.amount?.min || filters?.amount?.max) {
|
|
884
|
-
filtered = applyAmountFilter(filtered, filters.amount);
|
|
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);
|
|
885
876
|
}
|
|
886
|
-
|
|
887
|
-
|
|
877
|
+
};
|
|
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);
|
|
888
886
|
}
|
|
889
|
-
|
|
890
|
-
|
|
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 }
|
|
892
|
+
});
|
|
893
|
+
refetchAccounts();
|
|
894
|
+
};
|
|
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();
|
|
891
915
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
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`
|
|
896
928
|
);
|
|
897
929
|
}
|
|
898
|
-
|
|
899
|
-
|
|
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
|
+
);
|
|
900
938
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
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
|
+
);
|
|
907
948
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
if (newBT?.recently_categorized === true && notify) {
|
|
921
|
-
addToast({ content: "Transaction saved" });
|
|
922
|
-
}
|
|
923
|
-
}).catch((err) => {
|
|
924
|
-
const newBT = data?.find(
|
|
925
|
-
(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`
|
|
926
961
|
);
|
|
927
|
-
|
|
928
|
-
updateOneLocal({
|
|
929
|
-
...newBT,
|
|
930
|
-
error: err.message,
|
|
931
|
-
processing: false
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
|
-
}).finally(() => {
|
|
935
|
-
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
936
|
-
eventCallbacks?.onTransactionCategorized?.(id);
|
|
937
|
-
});
|
|
962
|
+
}
|
|
938
963
|
};
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
if (
|
|
942
|
-
|
|
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
|
+
);
|
|
943
979
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
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`
|
|
950
995
|
);
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
|
|
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`
|
|
967
1012
|
);
|
|
968
|
-
|
|
969
|
-
updateOneLocal({
|
|
970
|
-
...newBT,
|
|
971
|
-
error: err.message,
|
|
972
|
-
processing: false
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
}).finally(() => {
|
|
976
|
-
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
977
|
-
eventCallbacks?.onTransactionCategorized?.(id);
|
|
978
|
-
});
|
|
1013
|
+
}
|
|
979
1014
|
};
|
|
980
|
-
const
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
...page,
|
|
984
|
-
data: page.data?.map(
|
|
985
|
-
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
986
|
-
)
|
|
987
|
-
};
|
|
988
|
-
});
|
|
989
|
-
mutate(updatedData, { revalidate: false });
|
|
1015
|
+
const refetchAccounts = async () => {
|
|
1016
|
+
DEBUG && console.log("refetching accounts...");
|
|
1017
|
+
await mutate();
|
|
990
1018
|
};
|
|
991
|
-
const
|
|
1019
|
+
const syncAccounts = async () => {
|
|
1020
|
+
DEBUG && console.log("resyncing accounts...");
|
|
1021
|
+
await Layer.syncConnection(apiUrl, auth?.access_token, {
|
|
1022
|
+
params: { businessId }
|
|
1023
|
+
});
|
|
992
1024
|
};
|
|
993
|
-
const
|
|
994
|
-
|
|
1025
|
+
const updateConnectionStatus2 = async () => {
|
|
1026
|
+
DEBUG && console.log("updating connection status...");
|
|
1027
|
+
await Layer.updateConnectionStatus(apiUrl, auth?.access_token, {
|
|
1028
|
+
params: { businessId }
|
|
1029
|
+
});
|
|
995
1030
|
};
|
|
996
|
-
const
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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 */);
|
|
1000
1038
|
};
|
|
1001
1039
|
useEffect2(() => {
|
|
1002
|
-
if (isLoading || isValidating) {
|
|
1003
|
-
read("
|
|
1040
|
+
if (queryKey && (isLoading || isValidating)) {
|
|
1041
|
+
read("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */, queryKey);
|
|
1004
1042
|
}
|
|
1005
1043
|
}, [isLoading, isValidating]);
|
|
1006
1044
|
useEffect2(() => {
|
|
1007
|
-
if (hasBeenTouched(
|
|
1008
|
-
|
|
1045
|
+
if (queryKey && hasBeenTouched(queryKey)) {
|
|
1046
|
+
refetchAccounts();
|
|
1009
1047
|
}
|
|
1010
1048
|
}, [syncTimestamps]);
|
|
1011
1049
|
return {
|
|
1012
|
-
data:
|
|
1013
|
-
metadata: lastMetadata,
|
|
1014
|
-
loadingStatus,
|
|
1050
|
+
data: USE_MOCK_RESPONSE_DATA ? mockResponseData.data : responseData?.data.external_accounts,
|
|
1015
1051
|
isLoading,
|
|
1052
|
+
loadingStatus,
|
|
1016
1053
|
isValidating,
|
|
1017
|
-
refetch,
|
|
1018
1054
|
error: responseError,
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
hasMore
|
|
1055
|
+
addConnection,
|
|
1056
|
+
removeConnection,
|
|
1057
|
+
repairConnection,
|
|
1058
|
+
refetchAccounts,
|
|
1059
|
+
unlinkAccount: unlinkAccount2,
|
|
1060
|
+
confirmAccount,
|
|
1061
|
+
denyAccount,
|
|
1062
|
+
breakConnection,
|
|
1063
|
+
syncAccounts,
|
|
1064
|
+
updateConnectionStatus: updateConnectionStatus2
|
|
1030
1065
|
};
|
|
1031
1066
|
};
|
|
1032
1067
|
|
|
1033
|
-
// src/
|
|
1034
|
-
var
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
return /* @__PURE__ */ React6.createElement(BankTransactionsContext.Provider, { value: bankTransactionsContextData }, children);
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
|
-
// src/config/theme.ts
|
|
1042
|
-
var SHADES = {
|
|
1043
|
-
50: { s: 1, l: 98 },
|
|
1044
|
-
100: { s: 1, l: 96 },
|
|
1045
|
-
200: { s: 1, l: 94 },
|
|
1046
|
-
300: { s: 2, l: 92 },
|
|
1047
|
-
500: { s: 5, l: 53 },
|
|
1048
|
-
600: { s: 7, l: 40 },
|
|
1049
|
-
700: { s: 9, l: 27 },
|
|
1050
|
-
800: { s: 12, l: 20 },
|
|
1051
|
-
1e3: { s: 20, l: 7 }
|
|
1052
|
-
};
|
|
1053
|
-
var COLORS = {
|
|
1054
|
-
dark: {
|
|
1055
|
-
h: 0,
|
|
1056
|
-
s: 0,
|
|
1057
|
-
l: 7
|
|
1058
|
-
},
|
|
1059
|
-
light: {
|
|
1060
|
-
h: 0,
|
|
1061
|
-
s: 0,
|
|
1062
|
-
l: 100
|
|
1063
|
-
}
|
|
1064
|
-
};
|
|
1065
|
-
|
|
1066
|
-
// src/utils/colors.ts
|
|
1067
|
-
var parseStylesFromThemeConfig = (theme) => {
|
|
1068
|
-
let styles = {};
|
|
1069
|
-
if (!theme) {
|
|
1070
|
-
return styles;
|
|
1071
|
-
}
|
|
1072
|
-
if (theme.colors) {
|
|
1073
|
-
const darkColor = parseColorFromTheme("dark", theme.colors.dark);
|
|
1074
|
-
const lightColor = parseColorFromTheme("light", theme.colors.light);
|
|
1075
|
-
const textColor = parseTextColorFromTheme(theme.colors.text);
|
|
1076
|
-
styles = { ...styles, ...darkColor, ...lightColor, ...textColor };
|
|
1077
|
-
}
|
|
1078
|
-
return styles;
|
|
1079
|
-
};
|
|
1080
|
-
var parseTextColorFromTheme = (color) => {
|
|
1081
|
-
if (!color) {
|
|
1082
|
-
return {};
|
|
1068
|
+
// src/hooks/useBankTransactions/utils.ts
|
|
1069
|
+
var collectAccounts = (transactions) => {
|
|
1070
|
+
const accounts = [];
|
|
1071
|
+
if (!transactions) {
|
|
1072
|
+
return accounts;
|
|
1083
1073
|
}
|
|
1084
|
-
|
|
1085
|
-
if (
|
|
1086
|
-
|
|
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
|
+
});
|
|
1087
1080
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
return {};
|
|
1091
|
-
}
|
|
1081
|
+
});
|
|
1082
|
+
return accounts.sort((a, b) => a.name.localeCompare(b.name));
|
|
1092
1083
|
};
|
|
1093
|
-
var
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
try {
|
|
1098
|
-
if ("h" in color && "s" in color && "l" in color) {
|
|
1099
|
-
return {
|
|
1100
|
-
[`--color-${colorName}-h`]: color.h,
|
|
1101
|
-
[`--color-${colorName}-s`]: color.s,
|
|
1102
|
-
[`--color-${colorName}-l`]: color.l
|
|
1103
|
-
};
|
|
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;
|
|
1104
1088
|
}
|
|
1105
|
-
if (
|
|
1106
|
-
|
|
1107
|
-
return {
|
|
1108
|
-
[`--color-${colorName}-h`]: h,
|
|
1109
|
-
[`--color-${colorName}-s`]: `${s}%`,
|
|
1110
|
-
[`--color-${colorName}-l`]: `${l}%`
|
|
1111
|
-
};
|
|
1089
|
+
if (filter?.min || filter?.min === 0) {
|
|
1090
|
+
return x.amount >= filter.min * 100;
|
|
1112
1091
|
}
|
|
1113
|
-
if (
|
|
1114
|
-
|
|
1115
|
-
if (!rgb) {
|
|
1116
|
-
return {};
|
|
1117
|
-
}
|
|
1118
|
-
const { h, s, l } = rgbToHsl({
|
|
1119
|
-
r: rgb.r.toString(),
|
|
1120
|
-
g: rgb.g.toString(),
|
|
1121
|
-
b: rgb.b.toString()
|
|
1122
|
-
});
|
|
1123
|
-
return {
|
|
1124
|
-
[`--color-${colorName}-h`]: h,
|
|
1125
|
-
[`--color-${colorName}-s`]: `${s}%`,
|
|
1126
|
-
[`--color-${colorName}-l`]: `${l}%`
|
|
1127
|
-
};
|
|
1092
|
+
if (filter?.max || filter?.max === 0) {
|
|
1093
|
+
return x.amount <= filter.max * 100;
|
|
1128
1094
|
}
|
|
1129
|
-
|
|
1130
|
-
} catch (_err) {
|
|
1131
|
-
return {};
|
|
1132
|
-
}
|
|
1095
|
+
});
|
|
1133
1096
|
};
|
|
1134
|
-
var
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
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);
|
|
1145
1108
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
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()}` : ""}`;
|
|
1114
|
+
};
|
|
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 */;
|
|
1153
1136
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
g: rgb.g.toString(),
|
|
1162
|
-
b: rgb.b.toString()
|
|
1163
|
-
});
|
|
1164
|
-
return {
|
|
1165
|
-
h,
|
|
1166
|
-
s,
|
|
1167
|
-
l
|
|
1168
|
-
};
|
|
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];
|
|
1169
1144
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
g /= 255;
|
|
1181
|
-
b /= 255;
|
|
1182
|
-
const l = Math.max(r, g, b);
|
|
1183
|
-
const s = l - Math.min(r, g, b);
|
|
1184
|
-
const h = s ? l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s : 0;
|
|
1185
|
-
return {
|
|
1186
|
-
h: 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
1187
|
-
s: 100 * (s ? l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s)) : 0),
|
|
1188
|
-
l: 100 * (2 * l - s) / 2
|
|
1189
|
-
};
|
|
1190
|
-
};
|
|
1191
|
-
var hexToRgb = (hex) => {
|
|
1192
|
-
const values = hex.replace(
|
|
1193
|
-
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
|
1194
|
-
(m, r, g, b) => "#" + r + r + g + g + b + b
|
|
1195
|
-
).substring(1).match(/.{2}/g)?.map((x) => parseInt(x, 16));
|
|
1196
|
-
if (!values) {
|
|
1197
|
-
return;
|
|
1198
|
-
}
|
|
1199
|
-
return {
|
|
1200
|
-
r: values[0],
|
|
1201
|
-
g: values[1],
|
|
1202
|
-
b: values[2]
|
|
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
|
+
];
|
|
1203
1155
|
};
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
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);
|
|
1178
|
+
}
|
|
1179
|
+
return {};
|
|
1226
1180
|
},
|
|
1227
|
-
|
|
1181
|
+
{
|
|
1182
|
+
initialSize: 1,
|
|
1183
|
+
revalidateFirstPage: false
|
|
1184
|
+
}
|
|
1185
|
+
);
|
|
1186
|
+
const data = useMemo2(() => {
|
|
1187
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1188
|
+
return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
|
|
1189
|
+
}
|
|
1190
|
+
return void 0;
|
|
1191
|
+
}, [rawResponseData]);
|
|
1192
|
+
const lastMetadata = useMemo2(() => {
|
|
1193
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1194
|
+
return rawResponseData[rawResponseData.length - 1].meta;
|
|
1195
|
+
}
|
|
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
|
+
);
|
|
1204
|
+
}
|
|
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);
|
|
1228
1223
|
};
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
return { hsl, rgb, hex };
|
|
1235
|
-
};
|
|
1236
|
-
var hueToRgb = (p, q, t) => {
|
|
1237
|
-
if (t < 0)
|
|
1238
|
-
t += 1;
|
|
1239
|
-
if (t > 1)
|
|
1240
|
-
t -= 1;
|
|
1241
|
-
if (t < 1 / 6)
|
|
1242
|
-
return p + (q - p) * 6 * t;
|
|
1243
|
-
if (t < 1 / 2)
|
|
1244
|
-
return q;
|
|
1245
|
-
if (t < 2 / 3)
|
|
1246
|
-
return p + (q - p) * (2 / 3 - t) * 6;
|
|
1247
|
-
return p;
|
|
1248
|
-
};
|
|
1249
|
-
var hslToRgb = (hsl) => {
|
|
1250
|
-
let r, g, b;
|
|
1251
|
-
let l = hsl.l / 100;
|
|
1252
|
-
let s = hsl.s / 100;
|
|
1253
|
-
if (hsl.s === 0) {
|
|
1254
|
-
r = g = b = l;
|
|
1255
|
-
} else {
|
|
1256
|
-
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1257
|
-
const p = 2 * l - q;
|
|
1258
|
-
r = hueToRgb(p, q, hsl.h + 1 / 3);
|
|
1259
|
-
g = hueToRgb(p, q, hsl.h);
|
|
1260
|
-
b = hueToRgb(p, q, hsl.h - 1 / 3);
|
|
1261
|
-
}
|
|
1262
|
-
return {
|
|
1263
|
-
r: Math.round(r * 255),
|
|
1264
|
-
g: Math.round(g * 255),
|
|
1265
|
-
b: Math.round(b * 255)
|
|
1224
|
+
const setFilters = (value) => {
|
|
1225
|
+
setTheFilters({
|
|
1226
|
+
...filters,
|
|
1227
|
+
...value ?? {}
|
|
1228
|
+
});
|
|
1266
1229
|
};
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
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
|
+
});
|
|
1276
1278
|
};
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
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
|
+
});
|
|
1319
|
+
};
|
|
1320
|
+
const updateOneLocal = (newBankTransaction) => {
|
|
1321
|
+
const updatedData = rawResponseData?.map((page) => {
|
|
1301
1322
|
return {
|
|
1302
|
-
...
|
|
1303
|
-
|
|
1304
|
-
(
|
|
1323
|
+
...page,
|
|
1324
|
+
data: page.data?.map(
|
|
1325
|
+
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
1305
1326
|
)
|
|
1306
1327
|
};
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
...state,
|
|
1310
|
-
toasts: state.toasts.filter((t) => t.id !== action.payload.toast.id)
|
|
1311
|
-
};
|
|
1312
|
-
default:
|
|
1313
|
-
return state;
|
|
1314
|
-
}
|
|
1315
|
-
};
|
|
1316
|
-
var LayerEnvironment = {
|
|
1317
|
-
production: {
|
|
1318
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1319
|
-
scope: "https://api.layerfi.com/production",
|
|
1320
|
-
apiUrl: "https://api.layerfi.com"
|
|
1321
|
-
},
|
|
1322
|
-
sandbox: {
|
|
1323
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1324
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1325
|
-
apiUrl: "https://sandbox.layerfi.com"
|
|
1326
|
-
},
|
|
1327
|
-
staging: {
|
|
1328
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1329
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1330
|
-
apiUrl: "https://sandbox.layerfi.com"
|
|
1331
|
-
},
|
|
1332
|
-
internalStaging: {
|
|
1333
|
-
url: "https://auth.layerfi.com/oauth2/token",
|
|
1334
|
-
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1335
|
-
apiUrl: "https://staging.layerfi.com"
|
|
1336
|
-
}
|
|
1337
|
-
};
|
|
1338
|
-
var LayerProvider = ({
|
|
1339
|
-
appId,
|
|
1340
|
-
appSecret,
|
|
1341
|
-
businessId,
|
|
1342
|
-
children,
|
|
1343
|
-
businessAccessToken,
|
|
1344
|
-
environment = "production",
|
|
1345
|
-
theme,
|
|
1346
|
-
usePlaidSandbox,
|
|
1347
|
-
onError,
|
|
1348
|
-
eventCallbacks
|
|
1349
|
-
}) => {
|
|
1350
|
-
const defaultSWRConfig = {
|
|
1351
|
-
revalidateInterval: 0,
|
|
1352
|
-
revalidateOnFocus: false,
|
|
1353
|
-
revalidateOnReconnect: false,
|
|
1354
|
-
revalidateIfStale: false
|
|
1328
|
+
});
|
|
1329
|
+
mutate(updatedData, { revalidate: false });
|
|
1355
1330
|
};
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
businessId,
|
|
1367
|
-
business: void 0,
|
|
1368
|
-
categories: [],
|
|
1369
|
-
apiUrl,
|
|
1370
|
-
theme,
|
|
1371
|
-
colors,
|
|
1372
|
-
usePlaidSandbox,
|
|
1373
|
-
onboardingStep: void 0,
|
|
1374
|
-
environment,
|
|
1375
|
-
toasts: [],
|
|
1376
|
-
eventCallbacks: {}
|
|
1377
|
-
});
|
|
1378
|
-
const { touch, syncTimestamps, read, readTimestamps, hasBeenTouched } = useDataSync();
|
|
1379
|
-
const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR(
|
|
1380
|
-
businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && isBefore(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
|
|
1381
|
-
Layer.authenticate({
|
|
1382
|
-
appId,
|
|
1383
|
-
appSecret,
|
|
1384
|
-
authenticationUrl: url,
|
|
1385
|
-
scope
|
|
1386
|
-
}),
|
|
1387
|
-
defaultSWRConfig
|
|
1388
|
-
) : { data: void 0 };
|
|
1389
|
-
useEffect3(() => {
|
|
1390
|
-
if (businessAccessToken) {
|
|
1391
|
-
dispatch({
|
|
1392
|
-
type: "LayerContext.setAuth" /* setAuth */,
|
|
1393
|
-
payload: {
|
|
1394
|
-
auth: {
|
|
1395
|
-
access_token: businessAccessToken,
|
|
1396
|
-
token_type: "Bearer",
|
|
1397
|
-
expires_in: 3600,
|
|
1398
|
-
expires_at: add(/* @__PURE__ */ new Date(), { seconds: 3600 })
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
});
|
|
1402
|
-
} else if (auth?.access_token) {
|
|
1403
|
-
dispatch({
|
|
1404
|
-
type: "LayerContext.setAuth" /* setAuth */,
|
|
1405
|
-
payload: {
|
|
1406
|
-
auth: {
|
|
1407
|
-
...auth,
|
|
1408
|
-
expires_at: add(/* @__PURE__ */ new Date(), { seconds: auth.expires_in })
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
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
|
+
};
|
|
1411
1341
|
});
|
|
1342
|
+
mutate(updatedData, { revalidate: false });
|
|
1412
1343
|
}
|
|
1413
|
-
}
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
...defaultSWRConfig,
|
|
1421
|
-
onSuccess: (response) => {
|
|
1422
|
-
if (response?.data?.categories?.length) {
|
|
1423
|
-
dispatch({
|
|
1424
|
-
type: "LayerContext.setCategories" /* setCategories */,
|
|
1425
|
-
payload: { categories: response.data.categories || [] }
|
|
1426
|
-
});
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1344
|
+
};
|
|
1345
|
+
const refetch = () => {
|
|
1346
|
+
mutate();
|
|
1347
|
+
};
|
|
1348
|
+
const fetchMore = () => {
|
|
1349
|
+
if (hasMore) {
|
|
1350
|
+
setSize(size + 1);
|
|
1429
1351
|
}
|
|
1430
|
-
|
|
1352
|
+
};
|
|
1353
|
+
const getCacheKey = (txnFilters) => {
|
|
1354
|
+
return filtersSettingString(txnFilters);
|
|
1355
|
+
};
|
|
1431
1356
|
useEffect3(() => {
|
|
1432
|
-
if (
|
|
1433
|
-
|
|
1434
|
-
type: "LayerContext.setCategories" /* setCategories */,
|
|
1435
|
-
payload: { categories: categoriesData.data.categories || [] }
|
|
1436
|
-
});
|
|
1357
|
+
if (isLoading || isValidating) {
|
|
1358
|
+
read("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */, getCacheKey(filters));
|
|
1437
1359
|
}
|
|
1438
|
-
}, [
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
params: { businessId }
|
|
1443
|
-
}),
|
|
1444
|
-
{
|
|
1445
|
-
...defaultSWRConfig,
|
|
1446
|
-
onSuccess: (response) => {
|
|
1447
|
-
if (response?.data) {
|
|
1448
|
-
dispatch({
|
|
1449
|
-
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1450
|
-
payload: { business: response.data || [] }
|
|
1451
|
-
});
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1360
|
+
}, [isLoading, isValidating]);
|
|
1361
|
+
useEffect3(() => {
|
|
1362
|
+
if (hasBeenTouched(getCacheKey(filters))) {
|
|
1363
|
+
refetch();
|
|
1454
1364
|
}
|
|
1365
|
+
}, [syncTimestamps, filters]);
|
|
1366
|
+
const { data: linkedAccounts, refetchAccounts } = useLinkedAccounts();
|
|
1367
|
+
const anyAccountSyncing = useMemo2(
|
|
1368
|
+
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
1369
|
+
[linkedAccounts]
|
|
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]
|
|
1455
1375
|
);
|
|
1376
|
+
let intervalId = void 0;
|
|
1377
|
+
const [refreshTrigger, setRefreshTrigger] = useState5(-1);
|
|
1456
1378
|
useEffect3(() => {
|
|
1457
|
-
if (
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
payload: { business: businessData.data || [] }
|
|
1461
|
-
});
|
|
1379
|
+
if (refreshTrigger !== -1) {
|
|
1380
|
+
refetch();
|
|
1381
|
+
refetchAccounts();
|
|
1462
1382
|
}
|
|
1463
|
-
}, [
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
});
|
|
1473
|
-
};
|
|
1474
|
-
const setLightColor = (color) => {
|
|
1475
|
-
setTheme({
|
|
1476
|
-
...state.theme ?? {},
|
|
1477
|
-
colors: {
|
|
1478
|
-
...state.theme?.colors ?? {},
|
|
1479
|
-
light: color
|
|
1480
|
-
}
|
|
1481
|
-
});
|
|
1482
|
-
};
|
|
1483
|
-
const setDarkColor = (color) => {
|
|
1484
|
-
setTheme({
|
|
1485
|
-
...state.theme ?? {},
|
|
1486
|
-
colors: {
|
|
1487
|
-
...state.theme?.colors ?? {},
|
|
1488
|
-
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);
|
|
1489
1392
|
}
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
...state.theme ?? {},
|
|
1495
|
-
colors: {
|
|
1496
|
-
...state.theme?.colors ?? {},
|
|
1497
|
-
text: color
|
|
1393
|
+
}
|
|
1394
|
+
return () => {
|
|
1395
|
+
if (intervalId) {
|
|
1396
|
+
clearInterval(intervalId);
|
|
1498
1397
|
}
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
dispatch({ type: "LayerContext.removeToast" /* removeToast */, payload: { toast } });
|
|
1506
|
-
};
|
|
1507
|
-
const setToastExit = (toast) => {
|
|
1508
|
-
dispatch({ type: "LayerContext.setToastExit" /* setToastExit */, payload: { toast } });
|
|
1509
|
-
};
|
|
1510
|
-
const addToast = (toast) => {
|
|
1511
|
-
const id = `${Date.now()}-${Math.random()}`;
|
|
1512
|
-
const newToast = { id, isExiting: false, ...toast };
|
|
1513
|
-
setToast(newToast);
|
|
1514
|
-
setTimeout(() => {
|
|
1515
|
-
removeToast(newToast);
|
|
1516
|
-
setTimeout(() => {
|
|
1517
|
-
setToastExit(newToast);
|
|
1518
|
-
}, 1e3);
|
|
1519
|
-
}, toast.duration || 2e3);
|
|
1520
|
-
};
|
|
1521
|
-
const setColors = (colors2) => setTheme({
|
|
1522
|
-
...state.theme ?? {},
|
|
1523
|
-
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 */);
|
|
1524
1404
|
});
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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
|
|
1530
1425
|
};
|
|
1531
|
-
const setOnboardingStep = (value) => dispatch({
|
|
1532
|
-
type: "LayerContext.setOnboardingStep" /* setOnboardingStep */,
|
|
1533
|
-
payload: { onboardingStep: value }
|
|
1534
|
-
});
|
|
1535
|
-
const drawerContextData = useDrawer();
|
|
1536
|
-
return /* @__PURE__ */ React7.createElement(SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ React7.createElement(
|
|
1537
|
-
LayerContext.Provider,
|
|
1538
|
-
{
|
|
1539
|
-
value: {
|
|
1540
|
-
...state,
|
|
1541
|
-
setTheme,
|
|
1542
|
-
getColor,
|
|
1543
|
-
setLightColor,
|
|
1544
|
-
setDarkColor,
|
|
1545
|
-
setTextColor,
|
|
1546
|
-
setColors,
|
|
1547
|
-
setOnboardingStep,
|
|
1548
|
-
addToast,
|
|
1549
|
-
removeToast,
|
|
1550
|
-
onError: errorHandler.onError,
|
|
1551
|
-
touch,
|
|
1552
|
-
read,
|
|
1553
|
-
syncTimestamps,
|
|
1554
|
-
readTimestamps,
|
|
1555
|
-
hasBeenTouched,
|
|
1556
|
-
eventCallbacks
|
|
1557
|
-
}
|
|
1558
|
-
},
|
|
1559
|
-
/* @__PURE__ */ React7.createElement(BankTransactionsProvider, null, /* @__PURE__ */ React7.createElement(DrawerContext.Provider, { value: drawerContextData }, children, /* @__PURE__ */ React7.createElement(GlobalWidgets, null)))
|
|
1560
|
-
));
|
|
1561
1426
|
};
|
|
1562
1427
|
|
|
1563
|
-
// src/
|
|
1564
|
-
|
|
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
|
+
};
|
|
1565
1435
|
|
|
1566
|
-
// src/
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
},
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
},
|
|
1584
|
-
unlinkAccount: () => {
|
|
1585
|
-
},
|
|
1586
|
-
denyAccount: () => {
|
|
1587
|
-
},
|
|
1588
|
-
confirmAccount: () => {
|
|
1589
|
-
},
|
|
1590
|
-
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
|
|
1591
1453
|
},
|
|
1592
|
-
|
|
1454
|
+
light: {
|
|
1455
|
+
h: 0,
|
|
1456
|
+
s: 0,
|
|
1457
|
+
l: 100
|
|
1593
1458
|
}
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
// src/providers/LinkedAccountsProvider/LinkedAccountsProvider.tsx
|
|
1597
|
-
import React8 from "react";
|
|
1598
|
-
|
|
1599
|
-
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
1600
|
-
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1601
|
-
import { usePlaidLink } from "react-plaid-link";
|
|
1459
|
+
};
|
|
1602
1460
|
|
|
1603
|
-
// src/
|
|
1604
|
-
var
|
|
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
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
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)
|
|
1689
1612
|
},
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
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)
|
|
1694
1621
|
},
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
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;
|
|
1700
1709
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
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
|
+
},
|
|
1710
1761
|
businessId,
|
|
1762
|
+
business: void 0,
|
|
1763
|
+
categories: [],
|
|
1711
1764
|
apiUrl,
|
|
1765
|
+
theme,
|
|
1766
|
+
colors,
|
|
1712
1767
|
usePlaidSandbox,
|
|
1768
|
+
onboardingStep: void 0,
|
|
1769
|
+
environment,
|
|
1770
|
+
toasts: [],
|
|
1771
|
+
eventCallbacks: {}
|
|
1772
|
+
});
|
|
1773
|
+
const {
|
|
1713
1774
|
touch,
|
|
1714
|
-
read,
|
|
1715
1775
|
syncTimestamps,
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
const
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
|
|
1732
|
-
params: { businessId }
|
|
1733
|
-
})
|
|
1734
|
-
);
|
|
1735
|
-
useEffect4(() => {
|
|
1736
|
-
if (!isLoading && responseData?.data.external_accounts) {
|
|
1737
|
-
setLoadingStatus("complete");
|
|
1738
|
-
return;
|
|
1739
|
-
}
|
|
1740
|
-
if (isLoading && loadingStatus === "initial") {
|
|
1741
|
-
setLoadingStatus("loading");
|
|
1742
|
-
return;
|
|
1743
|
-
}
|
|
1744
|
-
if (!isLoading && loadingStatus === "loading") {
|
|
1745
|
-
setLoadingStatus("complete");
|
|
1746
|
-
}
|
|
1747
|
-
}, [isLoading]);
|
|
1748
|
-
const fetchPlaidLinkToken = async () => {
|
|
1749
|
-
if (auth?.access_token) {
|
|
1750
|
-
const linkToken2 = (await Layer.getPlaidLinkToken(apiUrl, auth.access_token, {
|
|
1751
|
-
params: { businessId }
|
|
1752
|
-
})).data.link_token;
|
|
1753
|
-
setLinkMode("add");
|
|
1754
|
-
setLinkToken(linkToken2);
|
|
1755
|
-
}
|
|
1756
|
-
};
|
|
1757
|
-
const fetchPlaidUpdateModeLinkToken = async (plaidItemPlaidId) => {
|
|
1758
|
-
if (auth?.access_token) {
|
|
1759
|
-
const linkToken2 = (await Layer.getPlaidUpdateModeLinkToken(apiUrl, auth.access_token, {
|
|
1760
|
-
params: { businessId },
|
|
1761
|
-
body: { plaid_item_id: plaidItemPlaidId }
|
|
1762
|
-
})).data.link_token;
|
|
1763
|
-
setLinkMode("update");
|
|
1764
|
-
setLinkToken(linkToken2);
|
|
1765
|
-
}
|
|
1766
|
-
};
|
|
1767
|
-
const exchangePlaidPublicToken2 = async (publicToken, metadata) => {
|
|
1768
|
-
await Layer.exchangePlaidPublicToken(apiUrl, auth?.access_token, {
|
|
1769
|
-
params: { businessId },
|
|
1770
|
-
body: { public_token: publicToken, institution: metadata.institution }
|
|
1771
|
-
});
|
|
1772
|
-
refetchAccounts();
|
|
1773
|
-
};
|
|
1774
|
-
const { open: plaidLinkStart, ready: plaidLinkReady } = usePlaidLink({
|
|
1775
|
-
token: linkToken,
|
|
1776
|
-
// If in update mode, we don't need to exchange the public token for an access token.
|
|
1777
|
-
// The existing access token will automatically become valid again
|
|
1778
|
-
onSuccess: async (publicToken, metadata) => {
|
|
1779
|
-
if (linkMode == "add") {
|
|
1780
|
-
exchangePlaidPublicToken2(publicToken, metadata);
|
|
1781
|
-
} else {
|
|
1782
|
-
await updateConnectionStatus2();
|
|
1783
|
-
refetchAccounts();
|
|
1784
|
-
setLinkMode("add");
|
|
1785
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1786
|
-
}
|
|
1787
|
-
},
|
|
1788
|
-
onExit: () => setLinkMode("add"),
|
|
1789
|
-
env: USE_PLAID_SANDBOX ? "sandbox" : void 0
|
|
1790
|
-
});
|
|
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 };
|
|
1791
1791
|
useEffect4(() => {
|
|
1792
|
-
if (
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
fetchPlaidLinkToken();
|
|
1804
|
-
} else {
|
|
1805
|
-
console.error(
|
|
1806
|
-
`Adding a connection with source ${source} not yet supported`
|
|
1807
|
-
);
|
|
1808
|
-
}
|
|
1809
|
-
};
|
|
1810
|
-
const repairConnection = async (source, connectionExternalId) => {
|
|
1811
|
-
if (source === "PLAID") {
|
|
1812
|
-
await fetchPlaidUpdateModeLinkToken(connectionExternalId);
|
|
1813
|
-
} else {
|
|
1814
|
-
console.error(
|
|
1815
|
-
`Repairing a connection with source ${source} not yet supported`
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
};
|
|
1819
|
-
const removeConnection = async (source, connectionExternalId) => {
|
|
1820
|
-
if (source === "PLAID") {
|
|
1821
|
-
await unlinkPlaidItem2(connectionExternalId);
|
|
1822
|
-
await refetchAccounts();
|
|
1823
|
-
} else {
|
|
1824
|
-
console.error(
|
|
1825
|
-
`Removing a connection with source ${source} not yet supported`
|
|
1826
|
-
);
|
|
1827
|
-
}
|
|
1828
|
-
};
|
|
1829
|
-
const unlinkAccount2 = async (source, accountId) => {
|
|
1830
|
-
DEBUG && console.log("unlinking account");
|
|
1831
|
-
if (source === "PLAID") {
|
|
1832
|
-
await Layer.unlinkAccount(apiUrl, auth?.access_token, {
|
|
1833
|
-
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
|
+
}
|
|
1834
1803
|
});
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
const confirmAccount = async (source, accountId) => {
|
|
1844
|
-
DEBUG && console.log("confirming account");
|
|
1845
|
-
if (source === "PLAID") {
|
|
1846
|
-
await Layer.confirmConnection(apiUrl, auth?.access_token, {
|
|
1847
|
-
params: {
|
|
1848
|
-
businessId,
|
|
1849
|
-
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
|
+
}
|
|
1850
1812
|
}
|
|
1851
1813
|
});
|
|
1852
|
-
await refetchAccounts();
|
|
1853
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1854
|
-
} else {
|
|
1855
|
-
console.error(
|
|
1856
|
-
`Confirming an account with source ${source} not yet supported`
|
|
1857
|
-
);
|
|
1858
1814
|
}
|
|
1859
|
-
};
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
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
|
+
});
|
|
1867
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 || [] }
|
|
1868
1838
|
});
|
|
1869
|
-
await refetchAccounts();
|
|
1870
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1871
|
-
} else {
|
|
1872
|
-
console.error(
|
|
1873
|
-
`Denying an account with source ${source} not yet supported`
|
|
1874
|
-
);
|
|
1875
1839
|
}
|
|
1876
|
-
};
|
|
1877
|
-
const
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
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
|
+
});
|
|
1884
1854
|
}
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
);
|
|
1858
|
+
useEffect4(() => {
|
|
1859
|
+
if (businessData?.data) {
|
|
1860
|
+
dispatch({
|
|
1861
|
+
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1862
|
+
payload: { business: businessData.data || [] }
|
|
1885
1863
|
});
|
|
1886
|
-
await refetchAccounts();
|
|
1887
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1888
|
-
} else {
|
|
1889
|
-
console.error(
|
|
1890
|
-
`Breaking a sandbox connection with source ${source} not yet supported`
|
|
1891
|
-
);
|
|
1892
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
|
+
});
|
|
1893
1875
|
};
|
|
1894
|
-
const
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
params: { businessId }
|
|
1876
|
+
const setLightColor = (color) => {
|
|
1877
|
+
setTheme({
|
|
1878
|
+
...state.theme ?? {},
|
|
1879
|
+
colors: {
|
|
1880
|
+
...state.theme?.colors ?? {},
|
|
1881
|
+
light: color
|
|
1882
|
+
}
|
|
1902
1883
|
});
|
|
1903
1884
|
};
|
|
1904
|
-
const
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1885
|
+
const setDarkColor = (color) => {
|
|
1886
|
+
setTheme({
|
|
1887
|
+
...state.theme ?? {},
|
|
1888
|
+
colors: {
|
|
1889
|
+
...state.theme?.colors ?? {},
|
|
1890
|
+
dark: color
|
|
1891
|
+
}
|
|
1908
1892
|
});
|
|
1909
1893
|
};
|
|
1910
|
-
const
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1894
|
+
const setTextColor = (color) => {
|
|
1895
|
+
setTheme({
|
|
1896
|
+
...state.theme ?? {},
|
|
1897
|
+
colors: {
|
|
1898
|
+
...state.theme?.colors ?? {},
|
|
1899
|
+
text: color
|
|
1900
|
+
}
|
|
1914
1901
|
});
|
|
1915
|
-
await refetchAccounts();
|
|
1916
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1917
1902
|
};
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
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];
|
|
1926
1930
|
}
|
|
1927
|
-
|
|
1928
|
-
return {
|
|
1929
|
-
data: USE_MOCK_RESPONSE_DATA ? mockResponseData.data : responseData?.data.external_accounts,
|
|
1930
|
-
isLoading,
|
|
1931
|
-
loadingStatus,
|
|
1932
|
-
isValidating,
|
|
1933
|
-
error: responseError,
|
|
1934
|
-
addConnection,
|
|
1935
|
-
removeConnection,
|
|
1936
|
-
repairConnection,
|
|
1937
|
-
refetchAccounts,
|
|
1938
|
-
unlinkAccount: unlinkAccount2,
|
|
1939
|
-
confirmAccount,
|
|
1940
|
-
denyAccount,
|
|
1941
|
-
breakConnection,
|
|
1942
|
-
syncAccounts,
|
|
1943
|
-
updateConnectionStatus: updateConnectionStatus2
|
|
1931
|
+
return;
|
|
1944
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
|
+
));
|
|
1945
1964
|
};
|
|
1946
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
|
+
|
|
1947
1999
|
// src/providers/LinkedAccountsProvider/LinkedAccountsProvider.tsx
|
|
2000
|
+
import React8 from "react";
|
|
1948
2001
|
var LinkedAccountsProvider = ({
|
|
1949
2002
|
children
|
|
1950
2003
|
}) => {
|
|
@@ -2218,8 +2271,20 @@ var Sunrise = ({ size = 12, ...props }) => /* @__PURE__ */ React16.createElement
|
|
|
2218
2271
|
);
|
|
2219
2272
|
var Sunrise_default = Sunrise;
|
|
2220
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
|
+
|
|
2221
2286
|
// src/utils/bankTransactions.ts
|
|
2222
|
-
import { isWithinInterval, parseISO
|
|
2287
|
+
import { isWithinInterval, parseISO } from "date-fns";
|
|
2223
2288
|
var hasMatch = (bankTransaction) => {
|
|
2224
2289
|
return Boolean(
|
|
2225
2290
|
bankTransaction?.suggested_matches && bankTransaction?.suggested_matches?.length > 0 || bankTransaction?.match
|
|
@@ -2247,7 +2312,7 @@ var countTransactionsToReview = ({
|
|
|
2247
2312
|
};
|
|
2248
2313
|
return transactions.filter((tx) => {
|
|
2249
2314
|
try {
|
|
2250
|
-
return filterVisibility("review" /* review */, tx) && isWithinInterval(
|
|
2315
|
+
return filterVisibility("review" /* review */, tx) && isWithinInterval(parseISO(tx.date), dateRangeInterval);
|
|
2251
2316
|
} catch (_err) {
|
|
2252
2317
|
return false;
|
|
2253
2318
|
}
|
|
@@ -2304,7 +2369,7 @@ var ChevronRight = ({ size = 18, ...props }) => /* @__PURE__ */ React17.createEl
|
|
|
2304
2369
|
var ChevronRight_default = ChevronRight;
|
|
2305
2370
|
|
|
2306
2371
|
// src/components/Button/Button.tsx
|
|
2307
|
-
import React18, { useRef } from "react";
|
|
2372
|
+
import React18, { useRef as useRef2 } from "react";
|
|
2308
2373
|
import classNames4 from "classnames";
|
|
2309
2374
|
var Button = ({
|
|
2310
2375
|
className,
|
|
@@ -2318,7 +2383,7 @@ var Button = ({
|
|
|
2318
2383
|
fullWidth,
|
|
2319
2384
|
...props
|
|
2320
2385
|
}) => {
|
|
2321
|
-
const buttonRef =
|
|
2386
|
+
const buttonRef = useRef2(null);
|
|
2322
2387
|
let justifyContent = "center";
|
|
2323
2388
|
if (justify) {
|
|
2324
2389
|
justifyContent = justify;
|
|
@@ -2989,7 +3054,7 @@ var ExpandButton = ({
|
|
|
2989
3054
|
|
|
2990
3055
|
// src/components/Button/Link.tsx
|
|
2991
3056
|
import React35, {
|
|
2992
|
-
useRef as
|
|
3057
|
+
useRef as useRef5
|
|
2993
3058
|
} from "react";
|
|
2994
3059
|
import classNames12 from "classnames";
|
|
2995
3060
|
var Link2 = ({
|
|
@@ -3004,7 +3069,7 @@ var Link2 = ({
|
|
|
3004
3069
|
fullWidth,
|
|
3005
3070
|
...props
|
|
3006
3071
|
}) => {
|
|
3007
|
-
const linkRef =
|
|
3072
|
+
const linkRef = useRef5(null);
|
|
3008
3073
|
let justifyContent = "center";
|
|
3009
3074
|
if (justify) {
|
|
3010
3075
|
justifyContent = justify;
|
|
@@ -3062,7 +3127,7 @@ var Link2 = ({
|
|
|
3062
3127
|
};
|
|
3063
3128
|
|
|
3064
3129
|
// src/components/Typography/Text.tsx
|
|
3065
|
-
import React36, { useRef as
|
|
3130
|
+
import React36, { useRef as useRef6, useState as useState7, useEffect as useEffect5 } from "react";
|
|
3066
3131
|
import classNames13 from "classnames";
|
|
3067
3132
|
var Text = ({
|
|
3068
3133
|
as: Component2 = "p",
|
|
@@ -3103,7 +3168,7 @@ var TextWithTooltip = ({
|
|
|
3103
3168
|
tooltipOptions,
|
|
3104
3169
|
...props
|
|
3105
3170
|
}) => {
|
|
3106
|
-
const textElementRef =
|
|
3171
|
+
const textElementRef = useRef6();
|
|
3107
3172
|
const compareSize = () => {
|
|
3108
3173
|
if (textElementRef.current) {
|
|
3109
3174
|
const compare = textElementRef.current.children[0].scrollWidth > textElementRef.current.children[0].clientWidth;
|
|
@@ -3560,11 +3625,11 @@ var MoreVertical = ({ size = 18, ...props }) => {
|
|
|
3560
3625
|
var MoreVertical_default = MoreVertical;
|
|
3561
3626
|
|
|
3562
3627
|
// src/components/HoverMenu/HoverMenu.tsx
|
|
3563
|
-
import React49, { useEffect as useEffect7, useRef as
|
|
3628
|
+
import React49, { useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
|
|
3564
3629
|
import classNames17 from "classnames";
|
|
3565
3630
|
var HoverMenu = ({ children, config }) => {
|
|
3566
3631
|
const [openMenu, setOpenMenu] = useState9(false);
|
|
3567
|
-
const hoverMenuRef =
|
|
3632
|
+
const hoverMenuRef = useRef7(null);
|
|
3568
3633
|
const hoverMenuClassName = classNames17(
|
|
3569
3634
|
"Layer__hover-menu",
|
|
3570
3635
|
openMenu && "Layer__hover-menu--open"
|
|
@@ -4207,9 +4272,9 @@ var LinkedAccountsComponent = ({
|
|
|
4207
4272
|
import React109, { useEffect as useEffect19, useMemo as useMemo6, useState as useState25 } from "react";
|
|
4208
4273
|
|
|
4209
4274
|
// src/hooks/useElementSize/useElementSize.ts
|
|
4210
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
4275
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef8 } from "react";
|
|
4211
4276
|
var useElementSize = (callback) => {
|
|
4212
|
-
const ref =
|
|
4277
|
+
const ref = useRef8(null);
|
|
4213
4278
|
useLayoutEffect2(() => {
|
|
4214
4279
|
const element = ref?.current;
|
|
4215
4280
|
if (!element) {
|
|
@@ -4250,7 +4315,7 @@ var debounce = (fnc, timeout = 300) => {
|
|
|
4250
4315
|
import React85 from "react";
|
|
4251
4316
|
|
|
4252
4317
|
// src/components/BankTransactionList/BankTransactionListItem.tsx
|
|
4253
|
-
import React84, { useEffect as useEffect12, useRef as
|
|
4318
|
+
import React84, { useEffect as useEffect12, useRef as useRef12, useState as useState15 } from "react";
|
|
4254
4319
|
|
|
4255
4320
|
// src/icons/ChevronDownFill.tsx
|
|
4256
4321
|
import * as React57 from "react";
|
|
@@ -4278,7 +4343,7 @@ var ChevronDownFill = ({ size = 18, ...props }) => /* @__PURE__ */ React57.creat
|
|
|
4278
4343
|
var ChevronDownFill_default = ChevronDownFill;
|
|
4279
4344
|
|
|
4280
4345
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
4281
|
-
import React82, { useEffect as useEffect11, useRef as
|
|
4346
|
+
import React82, { useEffect as useEffect11, useRef as useRef11, useState as useState14 } from "react";
|
|
4282
4347
|
|
|
4283
4348
|
// src/icons/Scissors.tsx
|
|
4284
4349
|
import * as React58 from "react";
|
|
@@ -4696,7 +4761,7 @@ var CategorySelectDrawerContent = ({
|
|
|
4696
4761
|
|
|
4697
4762
|
// src/components/CategorySelect/CategorySelect.tsx
|
|
4698
4763
|
import classNames23 from "classnames";
|
|
4699
|
-
import { parseISO as
|
|
4764
|
+
import { parseISO as parseISO2, format as formatTime } from "date-fns";
|
|
4700
4765
|
var mapCategoryToOption2 = (category) => {
|
|
4701
4766
|
return {
|
|
4702
4767
|
type: "category" /* CATEGORY */,
|
|
@@ -4748,7 +4813,7 @@ var Option2 = (props) => {
|
|
|
4748
4813
|
...props,
|
|
4749
4814
|
className: `${props.className} Layer__select__option-content__match`
|
|
4750
4815
|
},
|
|
4751
|
-
/* @__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)),
|
|
4752
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)))
|
|
4753
4818
|
);
|
|
4754
4819
|
}
|
|
@@ -4878,7 +4943,7 @@ import React80, {
|
|
|
4878
4943
|
useState as useState13,
|
|
4879
4944
|
useCallback,
|
|
4880
4945
|
useEffect as useEffect10,
|
|
4881
|
-
useRef as
|
|
4946
|
+
useRef as useRef10
|
|
4882
4947
|
} from "react";
|
|
4883
4948
|
|
|
4884
4949
|
// src/icons/ScissorsFullOpen.tsx
|
|
@@ -5040,7 +5105,7 @@ var InputGroup = ({
|
|
|
5040
5105
|
};
|
|
5041
5106
|
|
|
5042
5107
|
// src/components/Input/FileInput.tsx
|
|
5043
|
-
import React71, { useRef as
|
|
5108
|
+
import React71, { useRef as useRef9 } from "react";
|
|
5044
5109
|
|
|
5045
5110
|
// src/icons/UploadCloud.tsx
|
|
5046
5111
|
import * as React70 from "react";
|
|
@@ -5095,7 +5160,7 @@ var UploadCloud_default = UploadCloud;
|
|
|
5095
5160
|
|
|
5096
5161
|
// src/components/Input/FileInput.tsx
|
|
5097
5162
|
var FileInput = ({ text = "Upload", onUpload }) => {
|
|
5098
|
-
const hiddenFileInput =
|
|
5163
|
+
const hiddenFileInput = useRef9(null);
|
|
5099
5164
|
const onClick = () => {
|
|
5100
5165
|
if (hiddenFileInput.current) {
|
|
5101
5166
|
hiddenFileInput.current.click();
|
|
@@ -5196,7 +5261,7 @@ import React75 from "react";
|
|
|
5196
5261
|
|
|
5197
5262
|
// src/components/BankTransactionRow/MatchBadge.tsx
|
|
5198
5263
|
import React74 from "react";
|
|
5199
|
-
import { parseISO as
|
|
5264
|
+
import { parseISO as parseISO3, format as formatTime2 } from "date-fns";
|
|
5200
5265
|
var MatchBadge = ({
|
|
5201
5266
|
bankTransaction,
|
|
5202
5267
|
classNamePrefix,
|
|
@@ -5209,7 +5274,7 @@ var MatchBadge = ({
|
|
|
5209
5274
|
Badge,
|
|
5210
5275
|
{
|
|
5211
5276
|
icon: /* @__PURE__ */ React74.createElement(MinimizeTwo_default, { size: 11 }),
|
|
5212
|
-
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)))
|
|
5213
5278
|
},
|
|
5214
5279
|
text
|
|
5215
5280
|
);
|
|
@@ -5219,7 +5284,7 @@ var MatchBadge = ({
|
|
|
5219
5284
|
|
|
5220
5285
|
// src/components/MatchForm/MatchForm.tsx
|
|
5221
5286
|
import classNames28 from "classnames";
|
|
5222
|
-
import { parseISO as
|
|
5287
|
+
import { parseISO as parseISO4, format as formatTime3 } from "date-fns";
|
|
5223
5288
|
var MatchForm = ({
|
|
5224
5289
|
classNamePrefix,
|
|
5225
5290
|
bankTransaction,
|
|
@@ -5258,7 +5323,7 @@ var MatchForm = ({
|
|
|
5258
5323
|
{
|
|
5259
5324
|
className: `Layer__nowrap ${classNamePrefix}__match-table__date`
|
|
5260
5325
|
},
|
|
5261
|
-
/* @__PURE__ */ React75.createElement("span", null, formatTime3(
|
|
5326
|
+
/* @__PURE__ */ React75.createElement("span", null, formatTime3(parseISO4(match.details.date), DATE_FORMAT)),
|
|
5262
5327
|
/* @__PURE__ */ React75.createElement("span", { className: "amount-next-to-date" }, "$", centsToDollars(match.details.amount))
|
|
5263
5328
|
),
|
|
5264
5329
|
/* @__PURE__ */ React75.createElement("div", { className: `${classNamePrefix}__match-table__desc` }, /* @__PURE__ */ React75.createElement(
|
|
@@ -5301,7 +5366,7 @@ var MatchForm = ({
|
|
|
5301
5366
|
// src/components/MatchForm/MatchFormMobile.tsx
|
|
5302
5367
|
import React76 from "react";
|
|
5303
5368
|
import classNames29 from "classnames";
|
|
5304
|
-
import { parseISO as
|
|
5369
|
+
import { parseISO as parseISO5, format as formatTime4 } from "date-fns";
|
|
5305
5370
|
var MatchFormMobile = ({
|
|
5306
5371
|
classNamePrefix,
|
|
5307
5372
|
bankTransaction,
|
|
@@ -5348,7 +5413,7 @@ var MatchFormMobile = ({
|
|
|
5348
5413
|
size: "sm" /* sm */,
|
|
5349
5414
|
as: "span"
|
|
5350
5415
|
},
|
|
5351
|
-
formatTime4(
|
|
5416
|
+
formatTime4(parseISO5(match.details.date), MONTH_DAY_FORMAT)
|
|
5352
5417
|
))),
|
|
5353
5418
|
/* @__PURE__ */ React76.createElement("div", { className: `${classNamePrefix}__match-item__col-status` }, selectedMatchId && selectedMatchId === match.id ? /* @__PURE__ */ React76.createElement(
|
|
5354
5419
|
Check_default,
|
|
@@ -5677,7 +5742,7 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5677
5742
|
const [splitFormError, setSplitFormError] = useState13();
|
|
5678
5743
|
const [height, setHeight] = useState13(0);
|
|
5679
5744
|
const [isOver, setOver] = useState13(false);
|
|
5680
|
-
const bodyRef =
|
|
5745
|
+
const bodyRef = useRef10(null);
|
|
5681
5746
|
const [memoText, setMemoText] = useState13();
|
|
5682
5747
|
const [receiptUrls, setReceiptUrls] = useState13([]);
|
|
5683
5748
|
const [isLoaded, setIsLoaded] = useState13(false);
|
|
@@ -5776,7 +5841,6 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5776
5841
|
setSplitFormError(void 0);
|
|
5777
5842
|
};
|
|
5778
5843
|
const save = async () => {
|
|
5779
|
-
const endpoint = `/v1/businesses/${businessId}/bank-transactions/${bankTransaction.id}/metadata`;
|
|
5780
5844
|
if (showDescriptions && memoText != void 0) {
|
|
5781
5845
|
const result = await Layer.updateBankTransactionMetadata(
|
|
5782
5846
|
apiUrl,
|
|
@@ -6148,7 +6212,7 @@ var SplitTooltipDetails = ({
|
|
|
6148
6212
|
|
|
6149
6213
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
6150
6214
|
import classNames33 from "classnames";
|
|
6151
|
-
import { parseISO as
|
|
6215
|
+
import { parseISO as parseISO6, format as formatTime5 } from "date-fns";
|
|
6152
6216
|
var extractDescriptionForSplit = (category) => {
|
|
6153
6217
|
if (!category.entries) {
|
|
6154
6218
|
return "";
|
|
@@ -6180,12 +6244,12 @@ var BankTransactionRow = ({
|
|
|
6180
6244
|
showReceiptUploads,
|
|
6181
6245
|
stringOverrides
|
|
6182
6246
|
}) => {
|
|
6183
|
-
const expandedRowRef =
|
|
6247
|
+
const expandedRowRef = useRef11(null);
|
|
6184
6248
|
const [showRetry, setShowRetry] = useState14(false);
|
|
6185
6249
|
const {
|
|
6186
|
-
filters,
|
|
6187
6250
|
categorize: categorizeBankTransaction2,
|
|
6188
|
-
match: matchBankTransaction2
|
|
6251
|
+
match: matchBankTransaction2,
|
|
6252
|
+
shouldHideAfterCategorize
|
|
6189
6253
|
} = useBankTransactionsContext();
|
|
6190
6254
|
const [selectedCategory, setSelectedCategory] = useState14(
|
|
6191
6255
|
getDefaultSelectedCategory(bankTransaction)
|
|
@@ -6223,7 +6287,7 @@ var BankTransactionRow = ({
|
|
|
6223
6287
|
}
|
|
6224
6288
|
}, [bankTransaction.error]);
|
|
6225
6289
|
useEffect11(() => {
|
|
6226
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6290
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6227
6291
|
setTimeout(() => {
|
|
6228
6292
|
removeTransaction(bankTransaction);
|
|
6229
6293
|
}, 300);
|
|
@@ -6256,7 +6320,7 @@ var BankTransactionRow = ({
|
|
|
6256
6320
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6257
6321
|
const rowClassName = classNames33(
|
|
6258
6322
|
className,
|
|
6259
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6323
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6260
6324
|
open ? openClassName : "",
|
|
6261
6325
|
initialLoad ? "initial-load" : "",
|
|
6262
6326
|
showComponent ? "show" : ""
|
|
@@ -6267,7 +6331,7 @@ var BankTransactionRow = ({
|
|
|
6267
6331
|
className: "Layer__table-cell Layer__bank-transaction-table__date-col",
|
|
6268
6332
|
...openRow
|
|
6269
6333
|
},
|
|
6270
|
-
/* @__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))
|
|
6271
6335
|
), /* @__PURE__ */ React82.createElement(
|
|
6272
6336
|
"td",
|
|
6273
6337
|
{
|
|
@@ -6357,7 +6421,7 @@ var BankTransactionRow = ({
|
|
|
6357
6421
|
dateFormat
|
|
6358
6422
|
}
|
|
6359
6423
|
), /* @__PURE__ */ React82.createElement("span", { className: `${className}__category-text__text` }, `${formatTime5(
|
|
6360
|
-
|
|
6424
|
+
parseISO6(bankTransaction.match.bank_transaction.date),
|
|
6361
6425
|
dateFormat
|
|
6362
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,
|
|
6363
6427
|
!categorized && !open && showRetry ? /* @__PURE__ */ React82.createElement(
|
|
@@ -6432,7 +6496,7 @@ var BankTransactionRow = ({
|
|
|
6432
6496
|
|
|
6433
6497
|
// src/components/BankTransactionList/Assignment.tsx
|
|
6434
6498
|
import React83 from "react";
|
|
6435
|
-
import { parseISO as
|
|
6499
|
+
import { parseISO as parseISO7, format as formatTime6 } from "date-fns";
|
|
6436
6500
|
var Assignment = ({ bankTransaction }) => {
|
|
6437
6501
|
if (bankTransaction.match && bankTransaction.categorization_status === "MATCHED" /* MATCHED */) {
|
|
6438
6502
|
return /* @__PURE__ */ React83.createElement(React83.Fragment, null, /* @__PURE__ */ React83.createElement(
|
|
@@ -6444,7 +6508,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6444
6508
|
text: "Matched"
|
|
6445
6509
|
}
|
|
6446
6510
|
), /* @__PURE__ */ React83.createElement(Text, { className: "Layer__bank-transaction-list-item__category-text__text" }, `${formatTime6(
|
|
6447
|
-
|
|
6511
|
+
parseISO7(bankTransaction.match.bank_transaction.date),
|
|
6448
6512
|
DATE_FORMAT
|
|
6449
6513
|
)}, ${bankTransaction.match.bank_transaction.description ?? bankTransaction.match?.details?.description}`));
|
|
6450
6514
|
}
|
|
@@ -6469,7 +6533,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6469
6533
|
|
|
6470
6534
|
// src/components/BankTransactionList/BankTransactionListItem.tsx
|
|
6471
6535
|
import classNames34 from "classnames";
|
|
6472
|
-
import { parseISO as
|
|
6536
|
+
import { parseISO as parseISO8, format as formatTime7 } from "date-fns";
|
|
6473
6537
|
var BankTransactionListItem = ({
|
|
6474
6538
|
index = 0,
|
|
6475
6539
|
dateFormat,
|
|
@@ -6482,9 +6546,13 @@ var BankTransactionListItem = ({
|
|
|
6482
6546
|
removeTransaction,
|
|
6483
6547
|
stringOverrides
|
|
6484
6548
|
}) => {
|
|
6485
|
-
const expandedRowRef =
|
|
6549
|
+
const expandedRowRef = useRef12(null);
|
|
6486
6550
|
const [showRetry, setShowRetry] = useState15(false);
|
|
6487
|
-
const {
|
|
6551
|
+
const {
|
|
6552
|
+
categorize: categorizeBankTransaction2,
|
|
6553
|
+
match: matchBankTransaction2,
|
|
6554
|
+
shouldHideAfterCategorize
|
|
6555
|
+
} = useBankTransactionsContext();
|
|
6488
6556
|
const [selectedCategory, setSelectedCategory] = useState15(
|
|
6489
6557
|
getDefaultSelectedCategory(bankTransaction)
|
|
6490
6558
|
);
|
|
@@ -6506,7 +6574,7 @@ var BankTransactionListItem = ({
|
|
|
6506
6574
|
}
|
|
6507
6575
|
}, [bankTransaction.error]);
|
|
6508
6576
|
useEffect12(() => {
|
|
6509
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6577
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6510
6578
|
setTimeout(() => {
|
|
6511
6579
|
removeTransaction(bankTransaction);
|
|
6512
6580
|
}, 300);
|
|
@@ -6534,11 +6602,11 @@ var BankTransactionListItem = ({
|
|
|
6534
6602
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6535
6603
|
const rowClassName = classNames34(
|
|
6536
6604
|
className,
|
|
6537
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6605
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6538
6606
|
open ? openClassName : "",
|
|
6539
6607
|
showComponent ? "show" : ""
|
|
6540
6608
|
);
|
|
6541
|
-
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(
|
|
6542
6610
|
"div",
|
|
6543
6611
|
{
|
|
6544
6612
|
onClick: toggleOpen,
|
|
@@ -6648,7 +6716,7 @@ var BankTransactionList = ({
|
|
|
6648
6716
|
import React93 from "react";
|
|
6649
6717
|
|
|
6650
6718
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
6651
|
-
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";
|
|
6652
6720
|
|
|
6653
6721
|
// src/components/BankTransactionMobileList/BankTransactionMobileForms.tsx
|
|
6654
6722
|
import React91 from "react";
|
|
@@ -7105,7 +7173,7 @@ var TransactionToOpenContext = createContext5({
|
|
|
7105
7173
|
|
|
7106
7174
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
7107
7175
|
import classNames36 from "classnames";
|
|
7108
|
-
import { parseISO as
|
|
7176
|
+
import { parseISO as parseISO9, format as formatTime8 } from "date-fns";
|
|
7109
7177
|
var DATE_FORMAT2 = "LLL d";
|
|
7110
7178
|
var getAssignedValue2 = (bankTransaction) => {
|
|
7111
7179
|
if (bankTransaction.categorization_status === "SPLIT" /* SPLIT */) {
|
|
@@ -7130,13 +7198,14 @@ var BankTransactionMobileListItem = ({
|
|
|
7130
7198
|
setTransactionIdToOpen,
|
|
7131
7199
|
clearTransactionIdToOpen
|
|
7132
7200
|
} = useContext11(TransactionToOpenContext);
|
|
7201
|
+
const { shouldHideAfterCategorize } = useBankTransactionsContext();
|
|
7133
7202
|
const formRowRef = useElementSize(
|
|
7134
7203
|
(_a, _b, { height: height2 }) => setHeight(height2)
|
|
7135
7204
|
);
|
|
7136
7205
|
const headingRowRef = useElementSize((_a, _b, { height: height2 }) => {
|
|
7137
7206
|
setHeadingHeight(height2);
|
|
7138
7207
|
});
|
|
7139
|
-
const itemRef =
|
|
7208
|
+
const itemRef = useRef13(null);
|
|
7140
7209
|
const [removeAnim, setRemoveAnim] = useState22(false);
|
|
7141
7210
|
const [purpose, setPurpose] = useState22(
|
|
7142
7211
|
bankTransaction.category ? bankTransaction.categorization_status === "SPLIT" /* SPLIT */ ? "more" /* more */ : "business" /* business */ : hasMatch(bankTransaction) ? "more" /* more */ : "business" /* business */
|
|
@@ -7163,7 +7232,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7163
7232
|
}, [transactionIdToOpen]);
|
|
7164
7233
|
useEffect17(() => {
|
|
7165
7234
|
if (!removeAnim && bankTransaction.recently_categorized) {
|
|
7166
|
-
if (editable) {
|
|
7235
|
+
if (editable && shouldHideAfterCategorize(bankTransaction)) {
|
|
7167
7236
|
setRemoveAnim(true);
|
|
7168
7237
|
openNext();
|
|
7169
7238
|
} else {
|
|
@@ -7196,7 +7265,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7196
7265
|
}
|
|
7197
7266
|
}, []);
|
|
7198
7267
|
useEffect17(() => {
|
|
7199
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
7268
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
7200
7269
|
setTimeout(() => {
|
|
7201
7270
|
removeTransaction(bankTransaction);
|
|
7202
7271
|
}, 300);
|
|
@@ -7227,7 +7296,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7227
7296
|
},
|
|
7228
7297
|
isCredit(bankTransaction) ? "+$" : " $",
|
|
7229
7298
|
centsToDollars(bankTransaction.amount)
|
|
7230
|
-
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(
|
|
7299
|
+
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(parseISO9(bankTransaction.date), DATE_FORMAT2))))
|
|
7231
7300
|
), categorizationEnabled(mode) ? /* @__PURE__ */ React92.createElement(
|
|
7232
7301
|
"div",
|
|
7233
7302
|
{
|
|
@@ -7750,11 +7819,11 @@ var DownloadCloud = ({ size = 18, ...props }) => /* @__PURE__ */ React103.create
|
|
|
7750
7819
|
var DownloadCloud_default = DownloadCloud;
|
|
7751
7820
|
|
|
7752
7821
|
// src/utils/business.ts
|
|
7753
|
-
import { differenceInCalendarMonths, parseISO as
|
|
7822
|
+
import { differenceInCalendarMonths, parseISO as parseISO10, startOfMonth } from "date-fns";
|
|
7754
7823
|
var getActivationDate = (business) => {
|
|
7755
7824
|
try {
|
|
7756
7825
|
if (business && business.activation_at) {
|
|
7757
|
-
return
|
|
7826
|
+
return parseISO10(business.activation_at);
|
|
7758
7827
|
}
|
|
7759
7828
|
return;
|
|
7760
7829
|
} catch (_err) {
|
|
@@ -7780,7 +7849,7 @@ var isDateAllowedToBrowse = (date, business) => {
|
|
|
7780
7849
|
};
|
|
7781
7850
|
|
|
7782
7851
|
// src/components/DatePicker/DatePicker.tsx
|
|
7783
|
-
import React105, { useEffect as useEffect18, useRef as
|
|
7852
|
+
import React105, { useEffect as useEffect18, useRef as useRef14, useState as useState23 } from "react";
|
|
7784
7853
|
import ReactDatePicker from "react-datepicker";
|
|
7785
7854
|
|
|
7786
7855
|
// src/components/DatePicker/DatePickerOptions.tsx
|
|
@@ -7943,7 +8012,7 @@ var DatePicker = ({
|
|
|
7943
8012
|
navigateArrows = mode === "monthPicker",
|
|
7944
8013
|
...props
|
|
7945
8014
|
}) => {
|
|
7946
|
-
const pickerRef =
|
|
8015
|
+
const pickerRef = useRef14(null);
|
|
7947
8016
|
const [updatePickerDate, setPickerDate] = useState23(false);
|
|
7948
8017
|
const [selectedDates, setSelectedDates] = useState23(selected);
|
|
7949
8018
|
const { isDesktop } = useSizeClass();
|
|
@@ -8339,7 +8408,7 @@ var DataStates = ({
|
|
|
8339
8408
|
editable
|
|
8340
8409
|
}) => {
|
|
8341
8410
|
let title = editable ? "You are up to date with transactions!" : "You have no categorized transactions";
|
|
8342
|
-
let description = editable ? "All uncategorized
|
|
8411
|
+
let description = editable ? "All uncategorized transactions will be displayed here" : "All transactions will be displayed here once reviewed";
|
|
8343
8412
|
const showRefreshButton = bankTransactions?.length;
|
|
8344
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(
|
|
8345
8414
|
DataState,
|
|
@@ -8364,10 +8433,9 @@ var DataStates = ({
|
|
|
8364
8433
|
};
|
|
8365
8434
|
|
|
8366
8435
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
8367
|
-
import { endOfMonth as endOfMonth3, parseISO as
|
|
8436
|
+
import { endOfMonth as endOfMonth3, parseISO as parseISO11, startOfMonth as startOfMonth4 } from "date-fns";
|
|
8368
8437
|
var COMPONENT_NAME2 = "bank-transactions";
|
|
8369
8438
|
var TEST_EMPTY_STATE = false;
|
|
8370
|
-
var POLL_INTERVAL = 1e3;
|
|
8371
8439
|
var categorizationEnabled = (mode) => {
|
|
8372
8440
|
if (mode === "bookkeeping-client") {
|
|
8373
8441
|
return false;
|
|
@@ -8415,39 +8483,11 @@ var BankTransactionsContent = ({
|
|
|
8415
8483
|
fetchMore,
|
|
8416
8484
|
removeAfterCategorize
|
|
8417
8485
|
} = useBankTransactionsContext();
|
|
8418
|
-
const { data: linkedAccounts
|
|
8486
|
+
const { data: linkedAccounts } = useLinkedAccounts();
|
|
8419
8487
|
const isSyncing = useMemo6(
|
|
8420
8488
|
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
8421
8489
|
[linkedAccounts]
|
|
8422
8490
|
);
|
|
8423
|
-
const transactionsNotSynced = useMemo6(
|
|
8424
|
-
() => loadingStatus === "complete" && isSyncing && (!data || data?.length === 0),
|
|
8425
|
-
[data, isSyncing, loadingStatus]
|
|
8426
|
-
);
|
|
8427
|
-
let intervalId = void 0;
|
|
8428
|
-
const [refreshTrigger, setRefreshTrigger] = useState25(-1);
|
|
8429
|
-
useEffect19(() => {
|
|
8430
|
-
if (refreshTrigger !== -1) {
|
|
8431
|
-
refetch();
|
|
8432
|
-
refetchAccounts();
|
|
8433
|
-
}
|
|
8434
|
-
}, [refreshTrigger]);
|
|
8435
|
-
useEffect19(() => {
|
|
8436
|
-
if (isSyncing) {
|
|
8437
|
-
intervalId = setInterval(() => {
|
|
8438
|
-
setRefreshTrigger(Math.random());
|
|
8439
|
-
}, POLL_INTERVAL);
|
|
8440
|
-
} else {
|
|
8441
|
-
if (intervalId) {
|
|
8442
|
-
clearInterval(intervalId);
|
|
8443
|
-
}
|
|
8444
|
-
}
|
|
8445
|
-
return () => {
|
|
8446
|
-
if (intervalId) {
|
|
8447
|
-
clearInterval(intervalId);
|
|
8448
|
-
}
|
|
8449
|
-
};
|
|
8450
|
-
}, [isSyncing, transactionsNotSynced]);
|
|
8451
8491
|
useEffect19(() => {
|
|
8452
8492
|
activate();
|
|
8453
8493
|
}, []);
|
|
@@ -8489,7 +8529,7 @@ var BankTransactionsContent = ({
|
|
|
8489
8529
|
const bankTransactions = TEST_EMPTY_STATE ? [] : useMemo6(() => {
|
|
8490
8530
|
if (monthlyView) {
|
|
8491
8531
|
return data?.filter(
|
|
8492
|
-
(x) =>
|
|
8532
|
+
(x) => parseISO11(x.date) >= dateRange.startDate && parseISO11(x.date) <= dateRange.endDate
|
|
8493
8533
|
);
|
|
8494
8534
|
}
|
|
8495
8535
|
const firstPageIndex = (currentPage - 1) * pageSize;
|
|
@@ -8625,7 +8665,7 @@ var BankTransactionsContent = ({
|
|
|
8625
8665
|
import React110 from "react";
|
|
8626
8666
|
|
|
8627
8667
|
// src/hooks/useQuickbooks/useQuickbooks.ts
|
|
8628
|
-
import { useEffect as useEffect20, useRef as
|
|
8668
|
+
import { useEffect as useEffect20, useRef as useRef16, useState as useState26 } from "react";
|
|
8629
8669
|
var DEBUG2 = true;
|
|
8630
8670
|
var useQuickbooks = () => {
|
|
8631
8671
|
const { auth, businessId, apiUrl } = useLayerContext();
|
|
@@ -8633,7 +8673,7 @@ var useQuickbooks = () => {
|
|
|
8633
8673
|
const [quickbooksIsLinked, setQuickbooksIsLinked] = useState26(
|
|
8634
8674
|
null
|
|
8635
8675
|
);
|
|
8636
|
-
const syncStatusIntervalRef =
|
|
8676
|
+
const syncStatusIntervalRef = useRef16(null);
|
|
8637
8677
|
useEffect20(() => {
|
|
8638
8678
|
if (isSyncingFromQuickbooks && syncStatusIntervalRef.current === null) {
|
|
8639
8679
|
const interval = setInterval(() => fetchIsSyncingFromQuickbooks(), 2e3);
|
|
@@ -11084,7 +11124,7 @@ var TableRow = ({
|
|
|
11084
11124
|
};
|
|
11085
11125
|
|
|
11086
11126
|
// src/components/Table/Table.tsx
|
|
11087
|
-
import React128, { useEffect as useEffect26, useRef as
|
|
11127
|
+
import React128, { useEffect as useEffect26, useRef as useRef17 } from "react";
|
|
11088
11128
|
import classNames47 from "classnames";
|
|
11089
11129
|
var Table = ({
|
|
11090
11130
|
componentName,
|
|
@@ -11092,8 +11132,8 @@ var Table = ({
|
|
|
11092
11132
|
borderCollapse = "separate",
|
|
11093
11133
|
bottomSpacing = true
|
|
11094
11134
|
}) => {
|
|
11095
|
-
const tableRef =
|
|
11096
|
-
const prevChildrenRef =
|
|
11135
|
+
const tableRef = useRef17(null);
|
|
11136
|
+
const prevChildrenRef = useRef17([]);
|
|
11097
11137
|
useEffect26(() => {
|
|
11098
11138
|
if (tableRef.current) {
|
|
11099
11139
|
const tbody = tableRef.current.querySelector("tbody");
|
|
@@ -13081,7 +13121,7 @@ var Card = ({ children, className }) => {
|
|
|
13081
13121
|
|
|
13082
13122
|
// src/components/DateTime/DateTime.tsx
|
|
13083
13123
|
import React149 from "react";
|
|
13084
|
-
import { parseISO as
|
|
13124
|
+
import { parseISO as parseISO12, format as formatTime9 } from "date-fns";
|
|
13085
13125
|
var DateTime = ({
|
|
13086
13126
|
value,
|
|
13087
13127
|
format: format7,
|
|
@@ -13091,10 +13131,10 @@ var DateTime = ({
|
|
|
13091
13131
|
onlyTime
|
|
13092
13132
|
}) => {
|
|
13093
13133
|
if (format7) {
|
|
13094
|
-
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(
|
|
13134
|
+
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(parseISO12(value), format7));
|
|
13095
13135
|
}
|
|
13096
|
-
const date = formatTime9(
|
|
13097
|
-
const time = formatTime9(
|
|
13136
|
+
const date = formatTime9(parseISO12(value), dateFormat ?? DATE_FORMAT);
|
|
13137
|
+
const time = formatTime9(parseISO12(value), timeFormat ?? TIME_FORMAT);
|
|
13098
13138
|
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, !onlyTime && /* @__PURE__ */ React149.createElement(
|
|
13099
13139
|
Text,
|
|
13100
13140
|
{
|
|
@@ -13259,7 +13299,7 @@ var LedgerAccountEntryDetails = ({ stringOverrides }) => {
|
|
|
13259
13299
|
// src/components/LedgerAccount/LedgerAccountRow.tsx
|
|
13260
13300
|
import React153, { useContext as useContext23, useEffect as useEffect36, useState as useState40 } from "react";
|
|
13261
13301
|
import classNames54 from "classnames";
|
|
13262
|
-
import { parseISO as
|
|
13302
|
+
import { parseISO as parseISO13, format as formatTime10 } from "date-fns";
|
|
13263
13303
|
var LedgerAccountRow = ({
|
|
13264
13304
|
row,
|
|
13265
13305
|
index,
|
|
@@ -13298,7 +13338,7 @@ var LedgerAccountRow = ({
|
|
|
13298
13338
|
}
|
|
13299
13339
|
}
|
|
13300
13340
|
},
|
|
13301
|
-
/* @__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(
|
|
13302
13342
|
Text,
|
|
13303
13343
|
{
|
|
13304
13344
|
weight: "normal" /* normal */,
|
|
@@ -13331,7 +13371,7 @@ var LedgerAccountRow = ({
|
|
|
13331
13371
|
}
|
|
13332
13372
|
}
|
|
13333
13373
|
},
|
|
13334
|
-
/* @__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(
|
|
13335
13375
|
Text,
|
|
13336
13376
|
{
|
|
13337
13377
|
weight: "normal" /* normal */,
|
|
@@ -13360,7 +13400,7 @@ var LedgerAccountRow = ({
|
|
|
13360
13400
|
}
|
|
13361
13401
|
}
|
|
13362
13402
|
},
|
|
13363
|
-
/* @__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))),
|
|
13364
13404
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.entry_id.substring(0, 5))),
|
|
13365
13405
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.source?.display_description ?? "")),
|
|
13366
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)}`)),
|
|
@@ -13870,7 +13910,7 @@ import React161, { useContext as useContext31, useMemo as useMemo17, useState as
|
|
|
13870
13910
|
// src/components/JournalRow/JournalRow.tsx
|
|
13871
13911
|
import React156, { useContext as useContext26, useEffect as useEffect39, useState as useState44 } from "react";
|
|
13872
13912
|
import classNames56 from "classnames";
|
|
13873
|
-
import { parseISO as
|
|
13913
|
+
import { parseISO as parseISO14, format as formatTime11 } from "date-fns";
|
|
13874
13914
|
var INDENTATION2 = 24;
|
|
13875
13915
|
var EXPANDED_STYLE3 = {
|
|
13876
13916
|
height: "100%",
|
|
@@ -13983,7 +14023,7 @@ var JournalRow = ({
|
|
|
13983
14023
|
)
|
|
13984
14024
|
))),
|
|
13985
14025
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, row.id.substring(0, 5))),
|
|
13986
|
-
/* @__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))),
|
|
13987
14027
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, humanizeEnum(row.entry_type))),
|
|
13988
14028
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, `(${row.line_items.length})`)),
|
|
13989
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(
|
|
@@ -15461,7 +15501,7 @@ var GeneralLedgerView = ({
|
|
|
15461
15501
|
};
|
|
15462
15502
|
|
|
15463
15503
|
// src/views/Reports/Reports.tsx
|
|
15464
|
-
import React180, { useContext as useContext38, useRef as
|
|
15504
|
+
import React180, { useContext as useContext38, useRef as useRef18, useState as useState55 } from "react";
|
|
15465
15505
|
var DownloadButton2 = ({
|
|
15466
15506
|
stringOverrides
|
|
15467
15507
|
}) => {
|
|
@@ -15533,7 +15573,7 @@ var Reports = ({
|
|
|
15533
15573
|
stringOverrides,
|
|
15534
15574
|
enabledReports = ["profitAndLoss", "balanceSheet", "statementOfCashFlow"]
|
|
15535
15575
|
}) => {
|
|
15536
|
-
const containerRef =
|
|
15576
|
+
const containerRef = useRef18(null);
|
|
15537
15577
|
const [activeTab, setActiveTab] = useState55(enabledReports[0]);
|
|
15538
15578
|
const options = getOptions(enabledReports);
|
|
15539
15579
|
const defaultTitle = enabledReports.length > 1 ? "Reports" : options.find((option) => option.value = enabledReports[0])?.label;
|
|
@@ -15601,10 +15641,10 @@ var ReportsPanel = ({
|
|
|
15601
15641
|
};
|
|
15602
15642
|
|
|
15603
15643
|
// src/components/ProfitAndLossView/ProfitAndLossView.tsx
|
|
15604
|
-
import React181, { useContext as useContext39, useRef as
|
|
15644
|
+
import React181, { useContext as useContext39, useRef as useRef19 } from "react";
|
|
15605
15645
|
var COMPONENT_NAME7 = "profit-and-loss";
|
|
15606
15646
|
var ProfitAndLossView = (props) => {
|
|
15607
|
-
const containerRef =
|
|
15647
|
+
const containerRef = useRef19(null);
|
|
15608
15648
|
return /* @__PURE__ */ React181.createElement(Container, { name: COMPONENT_NAME7, ref: containerRef }, /* @__PURE__ */ React181.createElement(ProfitAndLoss, null, /* @__PURE__ */ React181.createElement(ProfitAndLossPanel, { containerRef, ...props })));
|
|
15609
15649
|
};
|
|
15610
15650
|
var ProfitAndLossPanel = ({
|
|
@@ -15699,6 +15739,7 @@ export {
|
|
|
15699
15739
|
StatementOfCashFlow,
|
|
15700
15740
|
Tasks,
|
|
15701
15741
|
useBankTransactionsContext,
|
|
15742
|
+
useDataSync,
|
|
15702
15743
|
useLayerContext
|
|
15703
15744
|
};
|
|
15704
15745
|
//# sourceMappingURL=index.js.map
|