@layerfi/components 0.1.52 → 0.1.54
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 +1316 -1269
- package/dist/esm/index.js.map +4 -4
- package/dist/index.d.ts +15 -6
- package/dist/index.js +1411 -1363
- 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,1278 +703,1289 @@ var BankTransactionsContext = createContext3({
|
|
|
673
703
|
var useBankTransactionsContext = () => useContext4(BankTransactionsContext);
|
|
674
704
|
|
|
675
705
|
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
676
|
-
import { useEffect as
|
|
677
|
-
|
|
678
|
-
// src/components/BankTransactions/constants.ts
|
|
679
|
-
var CategorizedCategories = [
|
|
680
|
-
"CATEGORIZED" /* CATEGORIZED */,
|
|
681
|
-
"JOURNALING" /* JOURNALING */,
|
|
682
|
-
"SPLIT" /* SPLIT */,
|
|
683
|
-
"MATCHED" /* MATCHED */
|
|
684
|
-
];
|
|
685
|
-
var ReviewCategories = [
|
|
686
|
-
"READY_FOR_INPUT" /* READY_FOR_INPUT */,
|
|
687
|
-
"LAYER_REVIEW" /* LAYER_REVIEW */
|
|
688
|
-
];
|
|
706
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef, useState as useState5 } from "react";
|
|
689
707
|
|
|
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);
|
|
708
|
+
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
709
|
+
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
710
|
+
import { usePlaidLink } from "react-plaid-link";
|
|
701
711
|
|
|
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
|
-
|
|
712
|
+
// src/hooks/useLinkedAccounts/mockData.ts
|
|
713
|
+
var LINKED_ACCOUNTS_MOCK_DATA = [
|
|
714
|
+
{
|
|
715
|
+
id: "d800ada8-8075-4436-a712-08efabcbd51a",
|
|
716
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
717
|
+
external_account_source: "PLAID",
|
|
718
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
719
|
+
mask: "1234",
|
|
720
|
+
latest_balance_timestamp: {
|
|
721
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
722
|
+
external_account_source: "PLAID",
|
|
723
|
+
balance: 435121,
|
|
724
|
+
at: "2024-04-03T13:00:00Z",
|
|
725
|
+
created_at: "2024-04-06T22:47:59.715458Z"
|
|
726
|
+
},
|
|
727
|
+
current_ledger_balance: 373717,
|
|
728
|
+
institution: {
|
|
729
|
+
name: "Chase",
|
|
730
|
+
logo: ""
|
|
731
|
+
},
|
|
732
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
733
|
+
connection_external_id: "11111",
|
|
734
|
+
connection_needs_repair_as_of: null,
|
|
735
|
+
requires_user_confirmation_as_of: null,
|
|
736
|
+
is_syncing: true
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
id: "f98ec50a-c370-484d-a35b-d00207436075",
|
|
740
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
741
|
+
external_account_source: "PLAID",
|
|
742
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
743
|
+
mask: "1234",
|
|
744
|
+
latest_balance_timestamp: {
|
|
745
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
746
|
+
external_account_source: "PLAID",
|
|
747
|
+
balance: 435121,
|
|
748
|
+
at: "2024-04-03T13:00:00Z",
|
|
749
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
750
|
+
},
|
|
751
|
+
current_ledger_balance: 373717,
|
|
752
|
+
institution: {
|
|
753
|
+
name: "Chase",
|
|
754
|
+
logo: ""
|
|
755
|
+
},
|
|
756
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
757
|
+
connection_external_id: "11111",
|
|
758
|
+
connection_needs_repair_as_of: null,
|
|
759
|
+
requires_user_confirmation_as_of: null,
|
|
760
|
+
is_syncing: false
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
id: "843f1748-fdaa-422d-a73d-2489a40c8dc7",
|
|
764
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
765
|
+
external_account_source: "PLAID",
|
|
766
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
767
|
+
mask: "1234",
|
|
768
|
+
latest_balance_timestamp: {
|
|
769
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
770
|
+
external_account_source: "PLAID",
|
|
771
|
+
balance: 435121,
|
|
772
|
+
at: "2024-04-03T13:00:00Z",
|
|
773
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
774
|
+
},
|
|
775
|
+
current_ledger_balance: 373717,
|
|
776
|
+
institution: {
|
|
777
|
+
name: "Chase",
|
|
778
|
+
logo: ""
|
|
779
|
+
},
|
|
780
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
781
|
+
connection_external_id: "11111",
|
|
782
|
+
connection_needs_repair_as_of: "2024-03-06T16:44:35.715458Z",
|
|
783
|
+
requires_user_confirmation_as_of: null,
|
|
784
|
+
is_syncing: false
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
id: "8f430e29-e339-4d71-a08a-fce469c7a7c1",
|
|
788
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
789
|
+
external_account_source: "PLAID",
|
|
790
|
+
external_account_name: "Citi Double Cash\xAE Card",
|
|
791
|
+
mask: "1234",
|
|
792
|
+
latest_balance_timestamp: {
|
|
793
|
+
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
794
|
+
external_account_source: "PLAID",
|
|
795
|
+
balance: 435121,
|
|
796
|
+
at: "2024-04-03T13:00:00Z",
|
|
797
|
+
created_at: "2024-04-06T16:44:35.715458Z"
|
|
798
|
+
},
|
|
799
|
+
current_ledger_balance: 373717,
|
|
800
|
+
institution: {
|
|
801
|
+
name: "Chase",
|
|
802
|
+
logo: ""
|
|
803
|
+
},
|
|
804
|
+
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
805
|
+
connection_external_id: "11111",
|
|
806
|
+
connection_needs_repair_as_of: null,
|
|
807
|
+
requires_user_confirmation_as_of: "2024-03-06T16:44:35.715458Z",
|
|
808
|
+
is_syncing: false
|
|
745
809
|
}
|
|
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
|
-
};
|
|
810
|
+
];
|
|
764
811
|
|
|
765
|
-
// src/hooks/
|
|
766
|
-
import
|
|
767
|
-
var
|
|
812
|
+
// src/hooks/useLinkedAccounts/useLinkedAccounts.ts
|
|
813
|
+
import useSWR from "swr";
|
|
814
|
+
var DEBUG = true;
|
|
815
|
+
var USE_MOCK_RESPONSE_DATA = false;
|
|
816
|
+
var useLinkedAccounts = () => {
|
|
768
817
|
const {
|
|
769
818
|
auth,
|
|
770
819
|
businessId,
|
|
771
820
|
apiUrl,
|
|
772
|
-
|
|
821
|
+
usePlaidSandbox,
|
|
773
822
|
touch,
|
|
774
823
|
read,
|
|
775
824
|
syncTimestamps,
|
|
776
|
-
hasBeenTouched
|
|
777
|
-
eventCallbacks
|
|
825
|
+
hasBeenTouched
|
|
778
826
|
} = 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);
|
|
827
|
+
const [linkToken, setLinkToken] = useState4(null);
|
|
792
828
|
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
|
-
};
|
|
829
|
+
const USE_PLAID_SANDBOX = usePlaidSandbox ?? true;
|
|
830
|
+
const [linkMode, setLinkMode] = useState4("add");
|
|
831
|
+
const queryKey = businessId && auth?.access_token && `linked-accounts-${businessId}`;
|
|
808
832
|
const {
|
|
809
|
-
data:
|
|
833
|
+
data: responseData,
|
|
810
834
|
isLoading,
|
|
811
835
|
isValidating,
|
|
812
836
|
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
|
-
}
|
|
837
|
+
mutate
|
|
838
|
+
} = useSWR(
|
|
839
|
+
queryKey,
|
|
840
|
+
Layer.getLinkedAccounts(apiUrl, auth?.access_token, {
|
|
841
|
+
params: { businessId }
|
|
842
|
+
})
|
|
833
843
|
);
|
|
834
|
-
|
|
835
|
-
if (
|
|
836
|
-
|
|
844
|
+
useEffect2(() => {
|
|
845
|
+
if (!isLoading && responseData?.data.external_accounts) {
|
|
846
|
+
setLoadingStatus("complete");
|
|
847
|
+
return;
|
|
837
848
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (rawResponseData && rawResponseData.length > 0) {
|
|
842
|
-
return rawResponseData[rawResponseData.length - 1].meta;
|
|
849
|
+
if (isLoading && loadingStatus === "initial") {
|
|
850
|
+
setLoadingStatus("loading");
|
|
851
|
+
return;
|
|
843
852
|
}
|
|
844
|
-
|
|
845
|
-
|
|
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
|
-
);
|
|
853
|
+
if (!isLoading && loadingStatus === "loading") {
|
|
854
|
+
setLoadingStatus("complete");
|
|
852
855
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
setLoadingStatus("loading");
|
|
862
|
-
return;
|
|
856
|
+
}, [isLoading]);
|
|
857
|
+
const fetchPlaidLinkToken = async () => {
|
|
858
|
+
if (auth?.access_token) {
|
|
859
|
+
const linkToken2 = (await Layer.getPlaidLinkToken(apiUrl, auth.access_token, {
|
|
860
|
+
params: { businessId }
|
|
861
|
+
})).data.link_token;
|
|
862
|
+
setLinkMode("add");
|
|
863
|
+
setLinkToken(linkToken2);
|
|
863
864
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
865
|
+
};
|
|
866
|
+
const fetchPlaidUpdateModeLinkToken = async (plaidItemPlaidId) => {
|
|
867
|
+
if (auth?.access_token) {
|
|
868
|
+
const linkToken2 = (await Layer.getPlaidUpdateModeLinkToken(apiUrl, auth.access_token, {
|
|
869
|
+
params: { businessId },
|
|
870
|
+
body: { plaid_item_id: plaidItemPlaidId }
|
|
871
|
+
})).data.link_token;
|
|
872
|
+
setLinkMode("update");
|
|
873
|
+
setLinkToken(linkToken2);
|
|
867
874
|
}
|
|
868
|
-
}, [isLoading]);
|
|
869
|
-
const activate = () => {
|
|
870
|
-
setActive(true);
|
|
871
875
|
};
|
|
872
|
-
const
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
+
const exchangePlaidPublicToken2 = async (publicToken, metadata) => {
|
|
877
|
+
await Layer.exchangePlaidPublicToken(apiUrl, auth?.access_token, {
|
|
878
|
+
params: { businessId },
|
|
879
|
+
body: { public_token: publicToken, institution: metadata.institution }
|
|
876
880
|
});
|
|
881
|
+
refetchAccounts();
|
|
877
882
|
};
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
883
|
+
const { open: plaidLinkStart, ready: plaidLinkReady } = usePlaidLink({
|
|
884
|
+
token: linkToken,
|
|
885
|
+
// If in update mode, we don't need to exchange the public token for an access token.
|
|
886
|
+
// The existing access token will automatically become valid again
|
|
887
|
+
onSuccess: async (publicToken, metadata) => {
|
|
888
|
+
if (linkMode == "add") {
|
|
889
|
+
exchangePlaidPublicToken2(publicToken, metadata);
|
|
890
|
+
} else {
|
|
891
|
+
await updateConnectionStatus2();
|
|
892
|
+
refetchAccounts();
|
|
893
|
+
setLinkMode("add");
|
|
894
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
onExit: () => setLinkMode("add"),
|
|
898
|
+
env: USE_PLAID_SANDBOX ? "sandbox" : void 0
|
|
899
|
+
});
|
|
900
|
+
useEffect2(() => {
|
|
901
|
+
if (plaidLinkReady) {
|
|
902
|
+
plaidLinkStart();
|
|
891
903
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
904
|
+
}, [plaidLinkStart, plaidLinkReady]);
|
|
905
|
+
const mockResponseData = {
|
|
906
|
+
data: LINKED_ACCOUNTS_MOCK_DATA,
|
|
907
|
+
meta: {},
|
|
908
|
+
error: void 0
|
|
909
|
+
};
|
|
910
|
+
const addConnection = (source) => {
|
|
911
|
+
if (source === "PLAID") {
|
|
912
|
+
fetchPlaidLinkToken();
|
|
913
|
+
} else {
|
|
914
|
+
console.error(
|
|
915
|
+
`Adding a connection with source ${source} not yet supported`
|
|
896
916
|
);
|
|
897
917
|
}
|
|
898
|
-
|
|
899
|
-
|
|
918
|
+
};
|
|
919
|
+
const repairConnection = async (source, connectionExternalId) => {
|
|
920
|
+
if (source === "PLAID") {
|
|
921
|
+
await fetchPlaidUpdateModeLinkToken(connectionExternalId);
|
|
922
|
+
} else {
|
|
923
|
+
console.error(
|
|
924
|
+
`Repairing a connection with source ${source} not yet supported`
|
|
925
|
+
);
|
|
900
926
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
927
|
+
};
|
|
928
|
+
const removeConnection = async (source, connectionExternalId) => {
|
|
929
|
+
if (source === "PLAID") {
|
|
930
|
+
await unlinkPlaidItem2(connectionExternalId);
|
|
931
|
+
await refetchAccounts();
|
|
932
|
+
} else {
|
|
933
|
+
console.error(
|
|
934
|
+
`Removing a connection with source ${source} not yet supported`
|
|
935
|
+
);
|
|
907
936
|
}
|
|
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
|
|
937
|
+
};
|
|
938
|
+
const unlinkAccount2 = async (source, accountId) => {
|
|
939
|
+
DEBUG && console.log("unlinking account");
|
|
940
|
+
if (source === "PLAID") {
|
|
941
|
+
await Layer.unlinkAccount(apiUrl, auth?.access_token, {
|
|
942
|
+
params: { businessId, accountId }
|
|
943
|
+
});
|
|
944
|
+
await refetchAccounts();
|
|
945
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
946
|
+
} else {
|
|
947
|
+
console.error(
|
|
948
|
+
`Unlinking an account with source ${source} not yet supported`
|
|
926
949
|
);
|
|
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
|
-
});
|
|
950
|
+
}
|
|
938
951
|
};
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
if (
|
|
942
|
-
|
|
952
|
+
const confirmAccount = async (source, accountId) => {
|
|
953
|
+
DEBUG && console.log("confirming account");
|
|
954
|
+
if (source === "PLAID") {
|
|
955
|
+
await Layer.confirmConnection(apiUrl, auth?.access_token, {
|
|
956
|
+
params: {
|
|
957
|
+
businessId,
|
|
958
|
+
accountId
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
await refetchAccounts();
|
|
962
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
963
|
+
} else {
|
|
964
|
+
console.error(
|
|
965
|
+
`Confirming an account with source ${source} not yet supported`
|
|
966
|
+
);
|
|
943
967
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
968
|
+
};
|
|
969
|
+
const denyAccount = async (source, accountId) => {
|
|
970
|
+
DEBUG && console.log("confirming account");
|
|
971
|
+
if (source === "PLAID") {
|
|
972
|
+
await Layer.denyConnection(apiUrl, auth?.access_token, {
|
|
973
|
+
params: {
|
|
974
|
+
businessId,
|
|
975
|
+
accountId
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
await refetchAccounts();
|
|
979
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
980
|
+
} else {
|
|
981
|
+
console.error(
|
|
982
|
+
`Denying an account with source ${source} not yet supported`
|
|
950
983
|
);
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
const breakConnection = async (source, connectionExternalId) => {
|
|
987
|
+
DEBUG && console.log("Breaking sandbox plaid item connection");
|
|
988
|
+
if (source === "PLAID") {
|
|
989
|
+
await Layer.breakPlaidItemConnection(apiUrl, auth?.access_token, {
|
|
990
|
+
params: {
|
|
991
|
+
businessId,
|
|
992
|
+
plaidItemPlaidId: connectionExternalId
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
await refetchAccounts();
|
|
996
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
997
|
+
} else {
|
|
998
|
+
console.error(
|
|
999
|
+
`Breaking a sandbox connection with source ${source} not yet supported`
|
|
967
1000
|
);
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
const refetchAccounts = async () => {
|
|
1004
|
+
DEBUG && console.log("refetching accounts...");
|
|
1005
|
+
await mutate();
|
|
1006
|
+
};
|
|
1007
|
+
const syncAccounts = async () => {
|
|
1008
|
+
DEBUG && console.log("resyncing accounts...");
|
|
1009
|
+
await Layer.syncConnection(apiUrl, auth?.access_token, {
|
|
1010
|
+
params: { businessId }
|
|
978
1011
|
});
|
|
979
1012
|
};
|
|
980
|
-
const
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
data: page.data?.map(
|
|
985
|
-
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
986
|
-
)
|
|
987
|
-
};
|
|
1013
|
+
const updateConnectionStatus2 = async () => {
|
|
1014
|
+
DEBUG && console.log("updating connection status...");
|
|
1015
|
+
await Layer.updateConnectionStatus(apiUrl, auth?.access_token, {
|
|
1016
|
+
params: { businessId }
|
|
988
1017
|
});
|
|
989
|
-
mutate(updatedData, { revalidate: false });
|
|
990
1018
|
};
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
setSize(size + 1);
|
|
999
|
-
}
|
|
1019
|
+
const unlinkPlaidItem2 = async (plaidItemPlaidId) => {
|
|
1020
|
+
DEBUG && console.log("unlinking plaid item");
|
|
1021
|
+
await Layer.unlinkPlaidItem(apiUrl, auth?.access_token, {
|
|
1022
|
+
params: { businessId, plaidItemPlaidId }
|
|
1023
|
+
});
|
|
1024
|
+
await refetchAccounts();
|
|
1025
|
+
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1000
1026
|
};
|
|
1001
1027
|
useEffect2(() => {
|
|
1002
|
-
if (isLoading || isValidating) {
|
|
1003
|
-
read("
|
|
1028
|
+
if (queryKey && (isLoading || isValidating)) {
|
|
1029
|
+
read("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */, queryKey);
|
|
1004
1030
|
}
|
|
1005
1031
|
}, [isLoading, isValidating]);
|
|
1006
1032
|
useEffect2(() => {
|
|
1007
|
-
if (hasBeenTouched(
|
|
1008
|
-
|
|
1033
|
+
if (queryKey && hasBeenTouched(queryKey)) {
|
|
1034
|
+
refetchAccounts();
|
|
1009
1035
|
}
|
|
1010
1036
|
}, [syncTimestamps]);
|
|
1011
1037
|
return {
|
|
1012
|
-
data:
|
|
1013
|
-
metadata: lastMetadata,
|
|
1014
|
-
loadingStatus,
|
|
1038
|
+
data: USE_MOCK_RESPONSE_DATA ? mockResponseData.data : responseData?.data.external_accounts,
|
|
1015
1039
|
isLoading,
|
|
1040
|
+
loadingStatus,
|
|
1016
1041
|
isValidating,
|
|
1017
|
-
refetch,
|
|
1018
1042
|
error: responseError,
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
hasMore
|
|
1043
|
+
addConnection,
|
|
1044
|
+
removeConnection,
|
|
1045
|
+
repairConnection,
|
|
1046
|
+
refetchAccounts,
|
|
1047
|
+
unlinkAccount: unlinkAccount2,
|
|
1048
|
+
confirmAccount,
|
|
1049
|
+
denyAccount,
|
|
1050
|
+
breakConnection,
|
|
1051
|
+
syncAccounts,
|
|
1052
|
+
updateConnectionStatus: updateConnectionStatus2
|
|
1030
1053
|
};
|
|
1031
1054
|
};
|
|
1032
1055
|
|
|
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 {};
|
|
1056
|
+
// src/hooks/useBankTransactions/utils.ts
|
|
1057
|
+
var collectAccounts = (transactions) => {
|
|
1058
|
+
const accounts = [];
|
|
1059
|
+
if (!transactions) {
|
|
1060
|
+
return accounts;
|
|
1083
1061
|
}
|
|
1084
|
-
|
|
1085
|
-
if (
|
|
1086
|
-
|
|
1062
|
+
transactions.forEach((x) => {
|
|
1063
|
+
if (!accounts.find((y) => y.id === x.source_account_id)) {
|
|
1064
|
+
accounts.push({
|
|
1065
|
+
id: x.source_account_id,
|
|
1066
|
+
name: x.account_name || ""
|
|
1067
|
+
});
|
|
1087
1068
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
return {};
|
|
1091
|
-
}
|
|
1069
|
+
});
|
|
1070
|
+
return accounts.sort((a, b) => a.name.localeCompare(b.name));
|
|
1092
1071
|
};
|
|
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
|
-
};
|
|
1072
|
+
var applyAmountFilter = (data, filter) => {
|
|
1073
|
+
return data?.filter((x) => {
|
|
1074
|
+
if ((filter?.min || filter?.min === 0) && (filter?.max || filter?.max === 0)) {
|
|
1075
|
+
return x.amount >= filter.min * 100 && x.amount <= filter.max * 100;
|
|
1104
1076
|
}
|
|
1105
|
-
if (
|
|
1106
|
-
|
|
1107
|
-
return {
|
|
1108
|
-
[`--color-${colorName}-h`]: h,
|
|
1109
|
-
[`--color-${colorName}-s`]: `${s}%`,
|
|
1110
|
-
[`--color-${colorName}-l`]: `${l}%`
|
|
1111
|
-
};
|
|
1077
|
+
if (filter?.min || filter?.min === 0) {
|
|
1078
|
+
return x.amount >= filter.min * 100;
|
|
1112
1079
|
}
|
|
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
|
-
};
|
|
1080
|
+
if (filter?.max || filter?.max === 0) {
|
|
1081
|
+
return x.amount <= filter.max * 100;
|
|
1128
1082
|
}
|
|
1129
|
-
|
|
1130
|
-
} catch (_err) {
|
|
1131
|
-
return {};
|
|
1132
|
-
}
|
|
1083
|
+
});
|
|
1133
1084
|
};
|
|
1134
|
-
var
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1085
|
+
var applyAccountFilter = (data, filter) => data?.filter((x) => filter && filter.includes(x.source_account_id));
|
|
1086
|
+
|
|
1087
|
+
// src/hooks/useBankTransactions/useBankTransactions.tsx
|
|
1088
|
+
import useSWRInfinite from "swr/infinite";
|
|
1089
|
+
var INITIAL_POLL_INTERVAL_MS = 1e3;
|
|
1090
|
+
var POLL_INTERVAL_AFTER_TXNS_RECEIVED_MS = 5e3;
|
|
1091
|
+
function useTriggerOnChange(data, anyAccountSyncing, callback) {
|
|
1092
|
+
const prevDataRef = useRef();
|
|
1093
|
+
useEffect3(() => {
|
|
1094
|
+
if (anyAccountSyncing && prevDataRef.current !== void 0 && prevDataRef.current !== data) {
|
|
1095
|
+
callback(data);
|
|
1145
1096
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1097
|
+
prevDataRef.current = data;
|
|
1098
|
+
}, [data, anyAccountSyncing, callback]);
|
|
1099
|
+
}
|
|
1100
|
+
var filtersSettingString = (filters) => {
|
|
1101
|
+
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()}` : ""}`;
|
|
1102
|
+
};
|
|
1103
|
+
var useBankTransactions = (params) => {
|
|
1104
|
+
const {
|
|
1105
|
+
auth,
|
|
1106
|
+
businessId,
|
|
1107
|
+
apiUrl,
|
|
1108
|
+
addToast,
|
|
1109
|
+
touch,
|
|
1110
|
+
read,
|
|
1111
|
+
syncTimestamps,
|
|
1112
|
+
hasBeenTouched,
|
|
1113
|
+
eventCallbacks
|
|
1114
|
+
} = useLayerContext();
|
|
1115
|
+
const { scope = void 0 } = params ?? {};
|
|
1116
|
+
const [filters, setTheFilters] = useState5(
|
|
1117
|
+
scope ? { categorizationStatus: scope } : void 0
|
|
1118
|
+
);
|
|
1119
|
+
const display = useMemo2(() => {
|
|
1120
|
+
if (filters?.categorizationStatus === "review" /* review */) {
|
|
1121
|
+
return "review" /* review */;
|
|
1122
|
+
} else if (filters?.categorizationStatus === "all" /* all */) {
|
|
1123
|
+
return "all" /* all */;
|
|
1153
1124
|
}
|
|
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
|
-
};
|
|
1125
|
+
return "categorized" /* categorized */;
|
|
1126
|
+
}, [filters?.categorizationStatus]);
|
|
1127
|
+
const [active, setActive] = useState5(false);
|
|
1128
|
+
const [loadingStatus, setLoadingStatus] = useState5("initial");
|
|
1129
|
+
const getKey = (index, prevData) => {
|
|
1130
|
+
if (!auth?.access_token || !active) {
|
|
1131
|
+
return [false, void 0];
|
|
1169
1132
|
}
|
|
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
|
|
1133
|
+
if (index === 0) {
|
|
1134
|
+
return [
|
|
1135
|
+
businessId && auth?.access_token && `${filtersSettingString(filters)}-${businessId}`,
|
|
1136
|
+
void 0
|
|
1137
|
+
];
|
|
1138
|
+
}
|
|
1139
|
+
return [
|
|
1140
|
+
businessId && auth?.access_token && `${filtersSettingString(filters)}-${businessId}-${prevData?.meta?.pagination?.cursor}`,
|
|
1141
|
+
prevData?.meta?.pagination?.cursor.toString()
|
|
1142
|
+
];
|
|
1189
1143
|
};
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
hsl: lightColor,
|
|
1215
|
-
rgb: hslToRgb(lightColor),
|
|
1216
|
-
hex: hslToHex(lightColor)
|
|
1217
|
-
},
|
|
1218
|
-
500: buildColorShade(500, darkColor),
|
|
1219
|
-
600: buildColorShade(600, darkColor),
|
|
1220
|
-
700: buildColorShade(700, darkColor),
|
|
1221
|
-
800: buildColorShade(800, darkColor),
|
|
1222
|
-
900: {
|
|
1223
|
-
hsl: darkColor,
|
|
1224
|
-
rgb: hslToRgb(darkColor),
|
|
1225
|
-
hex: hslToHex(darkColor)
|
|
1144
|
+
const {
|
|
1145
|
+
data: rawResponseData,
|
|
1146
|
+
isLoading,
|
|
1147
|
+
isValidating,
|
|
1148
|
+
error: responseError,
|
|
1149
|
+
mutate,
|
|
1150
|
+
size,
|
|
1151
|
+
setSize
|
|
1152
|
+
} = useSWRInfinite(
|
|
1153
|
+
getKey,
|
|
1154
|
+
async ([_query, nextCursor]) => {
|
|
1155
|
+
if (auth?.access_token) {
|
|
1156
|
+
return Layer.getBankTransactions(apiUrl, auth?.access_token, {
|
|
1157
|
+
params: {
|
|
1158
|
+
businessId,
|
|
1159
|
+
cursor: nextCursor ?? "",
|
|
1160
|
+
categorized: filters?.categorizationStatus ? filters?.categorizationStatus === "categorized" /* categorized */ ? "true" : filters?.categorizationStatus === "review" /* review */ ? "false" : "" : "",
|
|
1161
|
+
direction: filters?.direction?.length === 1 ? filters.direction[0] === "CREDIT" /* CREDIT */ ? "INFLOW" : "OUTFLOW" : void 0,
|
|
1162
|
+
startDate: filters?.dateRange?.startDate?.toISOString() ?? void 0,
|
|
1163
|
+
endDate: filters?.dateRange?.endDate?.toISOString() ?? void 0
|
|
1164
|
+
}
|
|
1165
|
+
}).call(false);
|
|
1166
|
+
}
|
|
1167
|
+
return {};
|
|
1226
1168
|
},
|
|
1227
|
-
|
|
1169
|
+
{
|
|
1170
|
+
initialSize: 1,
|
|
1171
|
+
revalidateFirstPage: false
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1174
|
+
const data = useMemo2(() => {
|
|
1175
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1176
|
+
return rawResponseData?.map((x) => x?.data).flat().filter((x) => !!x);
|
|
1177
|
+
}
|
|
1178
|
+
return void 0;
|
|
1179
|
+
}, [rawResponseData]);
|
|
1180
|
+
const lastMetadata = useMemo2(() => {
|
|
1181
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1182
|
+
return rawResponseData[rawResponseData.length - 1].meta;
|
|
1183
|
+
}
|
|
1184
|
+
return void 0;
|
|
1185
|
+
}, [rawResponseData]);
|
|
1186
|
+
const hasMore = useMemo2(() => {
|
|
1187
|
+
if (rawResponseData && rawResponseData.length > 0) {
|
|
1188
|
+
const lastElement = rawResponseData[rawResponseData.length - 1];
|
|
1189
|
+
return Boolean(
|
|
1190
|
+
lastElement.meta?.pagination?.cursor && lastElement.meta?.pagination?.has_more
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
return false;
|
|
1194
|
+
}, [rawResponseData]);
|
|
1195
|
+
const accountsList = useMemo2(
|
|
1196
|
+
() => data ? collectAccounts(data) : [],
|
|
1197
|
+
[data]
|
|
1198
|
+
);
|
|
1199
|
+
useEffect3(() => {
|
|
1200
|
+
if (isLoading && loadingStatus === "initial") {
|
|
1201
|
+
setLoadingStatus("loading");
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
if (!isLoading && loadingStatus === "loading") {
|
|
1205
|
+
setLoadingStatus("complete");
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
}, [isLoading]);
|
|
1209
|
+
const activate = () => {
|
|
1210
|
+
setActive(true);
|
|
1228
1211
|
};
|
|
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)
|
|
1212
|
+
const setFilters = (value) => {
|
|
1213
|
+
setTheFilters({
|
|
1214
|
+
...filters,
|
|
1215
|
+
...value ?? {}
|
|
1216
|
+
});
|
|
1266
1217
|
};
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1218
|
+
const filteredData = useMemo2(() => {
|
|
1219
|
+
let filtered = data;
|
|
1220
|
+
if (!filtered) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
if (filters?.amount?.min || filters?.amount?.max) {
|
|
1224
|
+
filtered = applyAmountFilter(filtered, filters.amount);
|
|
1225
|
+
}
|
|
1226
|
+
if (filters?.account) {
|
|
1227
|
+
filtered = applyAccountFilter(filtered, filters.account);
|
|
1228
|
+
}
|
|
1229
|
+
return filtered;
|
|
1230
|
+
}, [filters, data]);
|
|
1231
|
+
const categorize = (id, newCategory, notify) => {
|
|
1232
|
+
const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
|
|
1233
|
+
if (foundBT) {
|
|
1234
|
+
updateOneLocal({ ...foundBT, processing: true, error: void 0 });
|
|
1235
|
+
}
|
|
1236
|
+
return Layer.categorizeBankTransaction(apiUrl, auth.access_token, {
|
|
1237
|
+
params: { businessId, bankTransactionId: id },
|
|
1238
|
+
body: newCategory
|
|
1239
|
+
}).then(({ data: newBT, errors }) => {
|
|
1240
|
+
if (newBT) {
|
|
1241
|
+
newBT.recently_categorized = true;
|
|
1242
|
+
updateOneLocal(newBT);
|
|
1243
|
+
}
|
|
1244
|
+
if (errors) {
|
|
1245
|
+
console.error(errors);
|
|
1246
|
+
throw errors;
|
|
1247
|
+
}
|
|
1248
|
+
if (newBT?.recently_categorized === true && notify) {
|
|
1249
|
+
addToast({ content: "Transaction saved" });
|
|
1250
|
+
}
|
|
1251
|
+
}).catch((err) => {
|
|
1252
|
+
const newBT = data?.find(
|
|
1253
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1254
|
+
);
|
|
1255
|
+
if (newBT) {
|
|
1256
|
+
updateOneLocal({
|
|
1257
|
+
...newBT,
|
|
1258
|
+
error: err.message,
|
|
1259
|
+
processing: false
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
}).finally(() => {
|
|
1263
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1264
|
+
eventCallbacks?.onTransactionCategorized?.(id);
|
|
1265
|
+
});
|
|
1276
1266
|
};
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1267
|
+
const match = (id, matchId, notify) => {
|
|
1268
|
+
const foundBT = data?.find((x) => x.business_id === businessId && x.id === id);
|
|
1269
|
+
if (foundBT) {
|
|
1270
|
+
updateOneLocal({ ...foundBT, processing: true, error: void 0 });
|
|
1271
|
+
}
|
|
1272
|
+
return Layer.matchBankTransaction(apiUrl, auth.access_token, {
|
|
1273
|
+
params: { businessId, bankTransactionId: id },
|
|
1274
|
+
body: { match_id: matchId, type: "Confirm_Match" /* CONFIRM_MATCH */ }
|
|
1275
|
+
}).then(({ data: bt, errors }) => {
|
|
1276
|
+
const newBT = data?.find(
|
|
1277
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1278
|
+
);
|
|
1279
|
+
if (newBT) {
|
|
1280
|
+
newBT.recently_categorized = true;
|
|
1281
|
+
newBT.match = bt;
|
|
1282
|
+
newBT.categorization_status = "MATCHED" /* MATCHED */;
|
|
1283
|
+
updateOneLocal(newBT);
|
|
1284
|
+
}
|
|
1285
|
+
if (errors) {
|
|
1286
|
+
console.error(errors);
|
|
1287
|
+
throw errors;
|
|
1288
|
+
}
|
|
1289
|
+
if (newBT?.recently_categorized === true && notify) {
|
|
1290
|
+
addToast({ content: "Transaction saved" });
|
|
1291
|
+
}
|
|
1292
|
+
}).catch((err) => {
|
|
1293
|
+
const newBT = data?.find(
|
|
1294
|
+
(x) => x.business_id === businessId && x.id === id
|
|
1295
|
+
);
|
|
1296
|
+
if (newBT) {
|
|
1297
|
+
updateOneLocal({
|
|
1298
|
+
...newBT,
|
|
1299
|
+
error: err.message,
|
|
1300
|
+
processing: false
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
}).finally(() => {
|
|
1304
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1305
|
+
eventCallbacks?.onTransactionCategorized?.(id);
|
|
1306
|
+
});
|
|
1307
|
+
};
|
|
1308
|
+
const updateOneLocal = (newBankTransaction) => {
|
|
1309
|
+
const updatedData = rawResponseData?.map((page) => {
|
|
1301
1310
|
return {
|
|
1302
|
-
...
|
|
1303
|
-
|
|
1304
|
-
(
|
|
1311
|
+
...page,
|
|
1312
|
+
data: page.data?.map(
|
|
1313
|
+
(bt) => bt.id === newBankTransaction.id ? newBankTransaction : bt
|
|
1305
1314
|
)
|
|
1306
1315
|
};
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1316
|
+
});
|
|
1317
|
+
mutate(updatedData, { revalidate: false });
|
|
1318
|
+
};
|
|
1319
|
+
const shouldHideAfterCategorize = (bankTransaction) => {
|
|
1320
|
+
return filters?.categorizationStatus === "review" /* review */;
|
|
1321
|
+
};
|
|
1322
|
+
const removeAfterCategorize = (bankTransaction) => {
|
|
1323
|
+
if (shouldHideAfterCategorize(bankTransaction)) {
|
|
1324
|
+
const updatedData = rawResponseData?.map((page) => {
|
|
1325
|
+
return {
|
|
1326
|
+
...page,
|
|
1327
|
+
data: page.data?.filter((bt) => bt.id !== bankTransaction.id)
|
|
1328
|
+
};
|
|
1329
|
+
});
|
|
1330
|
+
mutate(updatedData, { revalidate: false });
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
const refetch = () => {
|
|
1334
|
+
mutate();
|
|
1335
|
+
};
|
|
1336
|
+
const fetchMore = () => {
|
|
1337
|
+
if (hasMore) {
|
|
1338
|
+
setSize(size + 1);
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
const getCacheKey = (txnFilters) => {
|
|
1342
|
+
return filtersSettingString(txnFilters);
|
|
1343
|
+
};
|
|
1344
|
+
useEffect3(() => {
|
|
1345
|
+
if (isLoading || isValidating) {
|
|
1346
|
+
read("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */, getCacheKey(filters));
|
|
1347
|
+
}
|
|
1348
|
+
}, [isLoading, isValidating]);
|
|
1349
|
+
useEffect3(() => {
|
|
1350
|
+
if (hasBeenTouched(getCacheKey(filters))) {
|
|
1351
|
+
refetch();
|
|
1352
|
+
}
|
|
1353
|
+
}, [syncTimestamps, filters]);
|
|
1354
|
+
const { data: linkedAccounts, refetchAccounts } = useLinkedAccounts();
|
|
1355
|
+
const anyAccountSyncing = useMemo2(
|
|
1356
|
+
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
1357
|
+
[linkedAccounts]
|
|
1358
|
+
);
|
|
1359
|
+
const [pollIntervalMs, setPollIntervalMs] = useState5(INITIAL_POLL_INTERVAL_MS);
|
|
1360
|
+
const transactionsNotSynced = useMemo2(
|
|
1361
|
+
() => loadingStatus === "complete" && anyAccountSyncing && (!data || data?.length === 0),
|
|
1362
|
+
[data, anyAccountSyncing, loadingStatus]
|
|
1363
|
+
);
|
|
1364
|
+
let intervalId = void 0;
|
|
1365
|
+
const [refreshTrigger, setRefreshTrigger] = useState5(-1);
|
|
1366
|
+
useEffect3(() => {
|
|
1367
|
+
if (refreshTrigger !== -1) {
|
|
1368
|
+
refetch();
|
|
1369
|
+
refetchAccounts();
|
|
1370
|
+
}
|
|
1371
|
+
}, [refreshTrigger]);
|
|
1372
|
+
useEffect3(() => {
|
|
1373
|
+
if (anyAccountSyncing) {
|
|
1374
|
+
intervalId = setInterval(() => {
|
|
1375
|
+
setRefreshTrigger(Math.random());
|
|
1376
|
+
}, pollIntervalMs);
|
|
1377
|
+
} else {
|
|
1378
|
+
if (intervalId) {
|
|
1379
|
+
clearInterval(intervalId);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
return () => {
|
|
1383
|
+
if (intervalId) {
|
|
1384
|
+
clearInterval(intervalId);
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1387
|
+
}, [anyAccountSyncing, transactionsNotSynced, pollIntervalMs]);
|
|
1388
|
+
useTriggerOnChange(data, anyAccountSyncing, (newTransactionList) => {
|
|
1389
|
+
clearInterval(intervalId);
|
|
1390
|
+
setPollIntervalMs(POLL_INTERVAL_AFTER_TXNS_RECEIVED_MS);
|
|
1391
|
+
touch("BANK_TRANSACTIONS" /* BANK_TRANSACTIONS */);
|
|
1392
|
+
});
|
|
1393
|
+
return {
|
|
1394
|
+
data: filteredData,
|
|
1395
|
+
metadata: lastMetadata,
|
|
1396
|
+
loadingStatus,
|
|
1397
|
+
isLoading,
|
|
1398
|
+
isValidating,
|
|
1399
|
+
refetch,
|
|
1400
|
+
error: responseError,
|
|
1401
|
+
categorize,
|
|
1402
|
+
match,
|
|
1403
|
+
updateOneLocal,
|
|
1404
|
+
shouldHideAfterCategorize,
|
|
1405
|
+
removeAfterCategorize,
|
|
1406
|
+
filters,
|
|
1407
|
+
setFilters,
|
|
1408
|
+
accountsList,
|
|
1409
|
+
activate,
|
|
1410
|
+
display,
|
|
1411
|
+
fetchMore,
|
|
1412
|
+
hasMore
|
|
1413
|
+
};
|
|
1315
1414
|
};
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1415
|
+
|
|
1416
|
+
// src/providers/BankTransactionsProvider/BankTransactionsProvider.tsx
|
|
1417
|
+
var BankTransactionsProvider = ({
|
|
1418
|
+
children
|
|
1419
|
+
}) => {
|
|
1420
|
+
const bankTransactionsContextData = useBankTransactions();
|
|
1421
|
+
return /* @__PURE__ */ React6.createElement(BankTransactionsContext.Provider, { value: bankTransactionsContextData }, children);
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
// src/config/theme.ts
|
|
1425
|
+
var SHADES = {
|
|
1426
|
+
50: { s: 1, l: 98 },
|
|
1427
|
+
100: { s: 1, l: 96 },
|
|
1428
|
+
200: { s: 1, l: 94 },
|
|
1429
|
+
300: { s: 2, l: 92 },
|
|
1430
|
+
500: { s: 5, l: 53 },
|
|
1431
|
+
600: { s: 7, l: 40 },
|
|
1432
|
+
700: { s: 9, l: 27 },
|
|
1433
|
+
800: { s: 12, l: 20 },
|
|
1434
|
+
1e3: { s: 20, l: 7 }
|
|
1435
|
+
};
|
|
1436
|
+
var COLORS = {
|
|
1437
|
+
dark: {
|
|
1438
|
+
h: 0,
|
|
1439
|
+
s: 0,
|
|
1440
|
+
l: 7
|
|
1331
1441
|
},
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1442
|
+
light: {
|
|
1443
|
+
h: 0,
|
|
1444
|
+
s: 0,
|
|
1445
|
+
l: 100
|
|
1336
1446
|
}
|
|
1337
1447
|
};
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
theme
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
auth: {
|
|
1361
|
-
access_token: "",
|
|
1362
|
-
token_type: "",
|
|
1363
|
-
expires_in: 0,
|
|
1364
|
-
expires_at: new Date(2e3, 1, 1)
|
|
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
|
-
}
|
|
1411
|
-
});
|
|
1448
|
+
|
|
1449
|
+
// src/utils/colors.ts
|
|
1450
|
+
var parseStylesFromThemeConfig = (theme) => {
|
|
1451
|
+
let styles = {};
|
|
1452
|
+
if (!theme) {
|
|
1453
|
+
return styles;
|
|
1454
|
+
}
|
|
1455
|
+
if (theme.colors) {
|
|
1456
|
+
const darkColor = parseColorFromTheme("dark", theme.colors.dark);
|
|
1457
|
+
const lightColor = parseColorFromTheme("light", theme.colors.light);
|
|
1458
|
+
const textColor = parseTextColorFromTheme(theme.colors.text);
|
|
1459
|
+
styles = { ...styles, ...darkColor, ...lightColor, ...textColor };
|
|
1460
|
+
}
|
|
1461
|
+
return styles;
|
|
1462
|
+
};
|
|
1463
|
+
var parseTextColorFromTheme = (color) => {
|
|
1464
|
+
if (!color) {
|
|
1465
|
+
return {};
|
|
1466
|
+
}
|
|
1467
|
+
try {
|
|
1468
|
+
if ("hex" in color) {
|
|
1469
|
+
return { "--text-color-primary": color.hex };
|
|
1412
1470
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1471
|
+
return {};
|
|
1472
|
+
} catch (_err) {
|
|
1473
|
+
return {};
|
|
1474
|
+
}
|
|
1475
|
+
};
|
|
1476
|
+
var parseColorFromTheme = (colorName, color) => {
|
|
1477
|
+
if (!color) {
|
|
1478
|
+
return {};
|
|
1479
|
+
}
|
|
1480
|
+
try {
|
|
1481
|
+
if ("h" in color && "s" in color && "l" in color) {
|
|
1482
|
+
return {
|
|
1483
|
+
[`--color-${colorName}-h`]: color.h,
|
|
1484
|
+
[`--color-${colorName}-s`]: color.s,
|
|
1485
|
+
[`--color-${colorName}-l`]: color.l
|
|
1486
|
+
};
|
|
1429
1487
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
}
|
|
1488
|
+
if ("r" in color && "g" in color && "b" in color) {
|
|
1489
|
+
const { h, s, l } = rgbToHsl(color);
|
|
1490
|
+
return {
|
|
1491
|
+
[`--color-${colorName}-h`]: h,
|
|
1492
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
1493
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
1494
|
+
};
|
|
1437
1495
|
}
|
|
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
|
-
}
|
|
1496
|
+
if ("hex" in color) {
|
|
1497
|
+
const rgb = hexToRgb(color.hex);
|
|
1498
|
+
if (!rgb) {
|
|
1499
|
+
return {};
|
|
1453
1500
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
dispatch({
|
|
1459
|
-
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1460
|
-
payload: { business: businessData.data || [] }
|
|
1501
|
+
const { h, s, l } = rgbToHsl({
|
|
1502
|
+
r: rgb.r.toString(),
|
|
1503
|
+
g: rgb.g.toString(),
|
|
1504
|
+
b: rgb.b.toString()
|
|
1461
1505
|
});
|
|
1506
|
+
return {
|
|
1507
|
+
[`--color-${colorName}-h`]: h,
|
|
1508
|
+
[`--color-${colorName}-s`]: `${s}%`,
|
|
1509
|
+
[`--color-${colorName}-l`]: `${l}%`
|
|
1510
|
+
};
|
|
1462
1511
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
const setTextColor = (color) => {
|
|
1493
|
-
setTheme({
|
|
1494
|
-
...state.theme ?? {},
|
|
1495
|
-
colors: {
|
|
1496
|
-
...state.theme?.colors ?? {},
|
|
1497
|
-
text: color
|
|
1512
|
+
return {};
|
|
1513
|
+
} catch (_err) {
|
|
1514
|
+
return {};
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
var parseColorFromThemeToHsl = (color) => {
|
|
1518
|
+
if (!color) {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
try {
|
|
1522
|
+
if ("h" in color && "s" in color && "l" in color) {
|
|
1523
|
+
return {
|
|
1524
|
+
h: Number(color.h),
|
|
1525
|
+
s: Number(color.s),
|
|
1526
|
+
l: Number(color.l)
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
if ("r" in color && "g" in color && "b" in color) {
|
|
1530
|
+
const { h, s, l } = rgbToHsl(color);
|
|
1531
|
+
return {
|
|
1532
|
+
h,
|
|
1533
|
+
s,
|
|
1534
|
+
l
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
if ("hex" in color) {
|
|
1538
|
+
const rgb = hexToRgb(color.hex);
|
|
1539
|
+
if (!rgb) {
|
|
1540
|
+
return void 0;
|
|
1498
1541
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1542
|
+
const { h, s, l } = rgbToHsl({
|
|
1543
|
+
r: rgb.r.toString(),
|
|
1544
|
+
g: rgb.g.toString(),
|
|
1545
|
+
b: rgb.b.toString()
|
|
1546
|
+
});
|
|
1547
|
+
return {
|
|
1548
|
+
h,
|
|
1549
|
+
s,
|
|
1550
|
+
l
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
return;
|
|
1554
|
+
} catch (_err) {
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
var rgbToHsl = (color) => {
|
|
1559
|
+
let r = Number(color.r);
|
|
1560
|
+
let g = Number(color.g);
|
|
1561
|
+
let b = Number(color.b);
|
|
1562
|
+
r /= 255;
|
|
1563
|
+
g /= 255;
|
|
1564
|
+
b /= 255;
|
|
1565
|
+
const l = Math.max(r, g, b);
|
|
1566
|
+
const s = l - Math.min(r, g, b);
|
|
1567
|
+
const h = s ? l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s : 0;
|
|
1568
|
+
return {
|
|
1569
|
+
h: 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
1570
|
+
s: 100 * (s ? l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s)) : 0),
|
|
1571
|
+
l: 100 * (2 * l - s) / 2
|
|
1503
1572
|
};
|
|
1504
|
-
|
|
1505
|
-
|
|
1573
|
+
};
|
|
1574
|
+
var hexToRgb = (hex) => {
|
|
1575
|
+
const values = hex.replace(
|
|
1576
|
+
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
|
1577
|
+
(m, r, g, b) => "#" + r + r + g + g + b + b
|
|
1578
|
+
).substring(1).match(/.{2}/g)?.map((x) => parseInt(x, 16));
|
|
1579
|
+
if (!values) {
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
return {
|
|
1583
|
+
r: values[0],
|
|
1584
|
+
g: values[1],
|
|
1585
|
+
b: values[2]
|
|
1506
1586
|
};
|
|
1507
|
-
|
|
1508
|
-
|
|
1587
|
+
};
|
|
1588
|
+
var buildColorsPalette = (theme) => {
|
|
1589
|
+
const darkColor = parseColorFromThemeToHsl(theme?.colors?.dark) ?? COLORS.dark;
|
|
1590
|
+
const lightColor = parseColorFromThemeToHsl(theme?.colors?.light) ?? COLORS.light;
|
|
1591
|
+
return {
|
|
1592
|
+
50: buildColorShade(50, darkColor),
|
|
1593
|
+
100: buildColorShade(100, darkColor),
|
|
1594
|
+
200: buildColorShade(200, darkColor),
|
|
1595
|
+
300: buildColorShade(300, darkColor),
|
|
1596
|
+
400: {
|
|
1597
|
+
hsl: lightColor,
|
|
1598
|
+
rgb: hslToRgb(lightColor),
|
|
1599
|
+
hex: hslToHex(lightColor)
|
|
1600
|
+
},
|
|
1601
|
+
500: buildColorShade(500, darkColor),
|
|
1602
|
+
600: buildColorShade(600, darkColor),
|
|
1603
|
+
700: buildColorShade(700, darkColor),
|
|
1604
|
+
800: buildColorShade(800, darkColor),
|
|
1605
|
+
900: {
|
|
1606
|
+
hsl: darkColor,
|
|
1607
|
+
rgb: hslToRgb(darkColor),
|
|
1608
|
+
hex: hslToHex(darkColor)
|
|
1609
|
+
},
|
|
1610
|
+
1e3: buildColorShade(1e3, darkColor)
|
|
1509
1611
|
};
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1612
|
+
};
|
|
1613
|
+
var buildColorShade = (shade, darkColorHsl) => {
|
|
1614
|
+
const hsl = { h: darkColorHsl.h, ...SHADES[shade] };
|
|
1615
|
+
const rgb = hslToRgb(hsl);
|
|
1616
|
+
const hex = hslToHex(hsl);
|
|
1617
|
+
return { hsl, rgb, hex };
|
|
1618
|
+
};
|
|
1619
|
+
var hueToRgb = (p, q, t) => {
|
|
1620
|
+
if (t < 0)
|
|
1621
|
+
t += 1;
|
|
1622
|
+
if (t > 1)
|
|
1623
|
+
t -= 1;
|
|
1624
|
+
if (t < 1 / 6)
|
|
1625
|
+
return p + (q - p) * 6 * t;
|
|
1626
|
+
if (t < 1 / 2)
|
|
1627
|
+
return q;
|
|
1628
|
+
if (t < 2 / 3)
|
|
1629
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
1630
|
+
return p;
|
|
1631
|
+
};
|
|
1632
|
+
var hslToRgb = (hsl) => {
|
|
1633
|
+
let r, g, b;
|
|
1634
|
+
let l = hsl.l / 100;
|
|
1635
|
+
let s = hsl.s / 100;
|
|
1636
|
+
if (hsl.s === 0) {
|
|
1637
|
+
r = g = b = l;
|
|
1638
|
+
} else {
|
|
1639
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1640
|
+
const p = 2 * l - q;
|
|
1641
|
+
r = hueToRgb(p, q, hsl.h + 1 / 3);
|
|
1642
|
+
g = hueToRgb(p, q, hsl.h);
|
|
1643
|
+
b = hueToRgb(p, q, hsl.h - 1 / 3);
|
|
1644
|
+
}
|
|
1645
|
+
return {
|
|
1646
|
+
r: Math.round(r * 255),
|
|
1647
|
+
g: Math.round(g * 255),
|
|
1648
|
+
b: Math.round(b * 255)
|
|
1520
1649
|
};
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
const
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
return;
|
|
1650
|
+
};
|
|
1651
|
+
var hslToHex = (hsl) => {
|
|
1652
|
+
const l = hsl.l / 100;
|
|
1653
|
+
const s = hsl.s;
|
|
1654
|
+
const a = s * Math.min(l, 1 - l) / 100;
|
|
1655
|
+
const f = (n) => {
|
|
1656
|
+
const k = (n + hsl.h / 30) % 12;
|
|
1657
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
1658
|
+
return Math.round(255 * color).toString(16).padStart(2, "0");
|
|
1530
1659
|
};
|
|
1531
|
-
|
|
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
|
-
));
|
|
1660
|
+
return `#${f(0)}${f(8)}${f(4)}`;
|
|
1561
1661
|
};
|
|
1562
1662
|
|
|
1563
|
-
// src/
|
|
1564
|
-
import
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1663
|
+
// src/providers/LayerProvider/LayerProvider.tsx
|
|
1664
|
+
import { add, isBefore } from "date-fns";
|
|
1665
|
+
import useSWR2, { SWRConfig } from "swr";
|
|
1666
|
+
var reducer = (state, action) => {
|
|
1667
|
+
switch (action.type) {
|
|
1668
|
+
case "LayerContext.setAuth" /* setAuth */:
|
|
1669
|
+
case "LayerContext.setBusiness" /* setBusiness */:
|
|
1670
|
+
case "LayerContext.setCategories" /* setCategories */:
|
|
1671
|
+
case "LayerContext.setTheme" /* setTheme */:
|
|
1672
|
+
case "LayerContext.setOnboardingStep" /* setOnboardingStep */:
|
|
1673
|
+
case "LayerContext.setColors" /* setColors */:
|
|
1674
|
+
return { ...state, ...action.payload };
|
|
1675
|
+
case "LayerContext.setToast" /* setToast */:
|
|
1676
|
+
return {
|
|
1677
|
+
...state,
|
|
1678
|
+
toasts: [
|
|
1679
|
+
...state.toasts,
|
|
1680
|
+
{ ...action.payload.toast, isExiting: false }
|
|
1681
|
+
]
|
|
1682
|
+
};
|
|
1683
|
+
case "LayerContext.setToastExit" /* setToastExit */:
|
|
1684
|
+
return {
|
|
1685
|
+
...state,
|
|
1686
|
+
toasts: state.toasts.map(
|
|
1687
|
+
(toast) => toast.id === action.payload.toast.id ? { ...toast, isExiting: false } : toast
|
|
1688
|
+
)
|
|
1689
|
+
};
|
|
1690
|
+
case "LayerContext.removeToast" /* removeToast */:
|
|
1691
|
+
return {
|
|
1692
|
+
...state,
|
|
1693
|
+
toasts: state.toasts.filter((t) => t.id !== action.payload.toast.id)
|
|
1694
|
+
};
|
|
1695
|
+
default:
|
|
1696
|
+
return state;
|
|
1593
1697
|
}
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1601
|
-
import { usePlaidLink } from "react-plaid-link";
|
|
1602
|
-
|
|
1603
|
-
// src/hooks/useLinkedAccounts/mockData.ts
|
|
1604
|
-
var LINKED_ACCOUNTS_MOCK_DATA = [
|
|
1605
|
-
{
|
|
1606
|
-
id: "d800ada8-8075-4436-a712-08efabcbd51a",
|
|
1607
|
-
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1608
|
-
external_account_source: "PLAID",
|
|
1609
|
-
external_account_name: "Citi Double Cash\xAE Card",
|
|
1610
|
-
mask: "1234",
|
|
1611
|
-
latest_balance_timestamp: {
|
|
1612
|
-
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1613
|
-
external_account_source: "PLAID",
|
|
1614
|
-
balance: 435121,
|
|
1615
|
-
at: "2024-04-03T13:00:00Z",
|
|
1616
|
-
created_at: "2024-04-06T22:47:59.715458Z"
|
|
1617
|
-
},
|
|
1618
|
-
current_ledger_balance: 373717,
|
|
1619
|
-
institution: {
|
|
1620
|
-
name: "Chase",
|
|
1621
|
-
logo: ""
|
|
1622
|
-
},
|
|
1623
|
-
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1624
|
-
connection_external_id: "11111",
|
|
1625
|
-
connection_needs_repair_as_of: null,
|
|
1626
|
-
requires_user_confirmation_as_of: null,
|
|
1627
|
-
is_syncing: true
|
|
1698
|
+
};
|
|
1699
|
+
var LayerEnvironment = {
|
|
1700
|
+
production: {
|
|
1701
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1702
|
+
scope: "https://api.layerfi.com/production",
|
|
1703
|
+
apiUrl: "https://api.layerfi.com"
|
|
1628
1704
|
},
|
|
1629
|
-
{
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
external_account_name: "Citi Double Cash\xAE Card",
|
|
1634
|
-
mask: "1234",
|
|
1635
|
-
latest_balance_timestamp: {
|
|
1636
|
-
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1637
|
-
external_account_source: "PLAID",
|
|
1638
|
-
balance: 435121,
|
|
1639
|
-
at: "2024-04-03T13:00:00Z",
|
|
1640
|
-
created_at: "2024-04-06T16:44:35.715458Z"
|
|
1641
|
-
},
|
|
1642
|
-
current_ledger_balance: 373717,
|
|
1643
|
-
institution: {
|
|
1644
|
-
name: "Chase",
|
|
1645
|
-
logo: ""
|
|
1646
|
-
},
|
|
1647
|
-
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1648
|
-
connection_external_id: "11111",
|
|
1649
|
-
connection_needs_repair_as_of: null,
|
|
1650
|
-
requires_user_confirmation_as_of: null,
|
|
1651
|
-
is_syncing: false
|
|
1705
|
+
sandbox: {
|
|
1706
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1707
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1708
|
+
apiUrl: "https://sandbox.layerfi.com"
|
|
1652
1709
|
},
|
|
1653
|
-
{
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
external_account_name: "Citi Double Cash\xAE Card",
|
|
1658
|
-
mask: "1234",
|
|
1659
|
-
latest_balance_timestamp: {
|
|
1660
|
-
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1661
|
-
external_account_source: "PLAID",
|
|
1662
|
-
balance: 435121,
|
|
1663
|
-
at: "2024-04-03T13:00:00Z",
|
|
1664
|
-
created_at: "2024-04-06T16:44:35.715458Z"
|
|
1665
|
-
},
|
|
1666
|
-
current_ledger_balance: 373717,
|
|
1667
|
-
institution: {
|
|
1668
|
-
name: "Chase",
|
|
1669
|
-
logo: ""
|
|
1670
|
-
},
|
|
1671
|
-
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1672
|
-
connection_external_id: "11111",
|
|
1673
|
-
connection_needs_repair_as_of: "2024-03-06T16:44:35.715458Z",
|
|
1674
|
-
requires_user_confirmation_as_of: null,
|
|
1675
|
-
is_syncing: false
|
|
1710
|
+
staging: {
|
|
1711
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1712
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1713
|
+
apiUrl: "https://sandbox.layerfi.com"
|
|
1676
1714
|
},
|
|
1677
|
-
{
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
external_account_name: "Citi Double Cash\xAE Card",
|
|
1682
|
-
mask: "1234",
|
|
1683
|
-
latest_balance_timestamp: {
|
|
1684
|
-
external_account_external_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1685
|
-
external_account_source: "PLAID",
|
|
1686
|
-
balance: 435121,
|
|
1687
|
-
at: "2024-04-03T13:00:00Z",
|
|
1688
|
-
created_at: "2024-04-06T16:44:35.715458Z"
|
|
1689
|
-
},
|
|
1690
|
-
current_ledger_balance: 373717,
|
|
1691
|
-
institution: {
|
|
1692
|
-
name: "Chase",
|
|
1693
|
-
logo: ""
|
|
1694
|
-
},
|
|
1695
|
-
connection_id: "0Br385JmgbTryJn8nEBnUb4A5ydv06U9Vbqqq",
|
|
1696
|
-
connection_external_id: "11111",
|
|
1697
|
-
connection_needs_repair_as_of: null,
|
|
1698
|
-
requires_user_confirmation_as_of: "2024-03-06T16:44:35.715458Z",
|
|
1699
|
-
is_syncing: false
|
|
1715
|
+
internalStaging: {
|
|
1716
|
+
url: "https://auth.layerfi.com/oauth2/token",
|
|
1717
|
+
scope: "https://sandbox.layerfi.com/sandbox",
|
|
1718
|
+
apiUrl: "https://staging.layerfi.com"
|
|
1700
1719
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1720
|
+
};
|
|
1721
|
+
var LayerProvider = ({
|
|
1722
|
+
appId,
|
|
1723
|
+
appSecret,
|
|
1724
|
+
businessId,
|
|
1725
|
+
children,
|
|
1726
|
+
businessAccessToken,
|
|
1727
|
+
environment = "production",
|
|
1728
|
+
theme,
|
|
1729
|
+
usePlaidSandbox,
|
|
1730
|
+
onError,
|
|
1731
|
+
eventCallbacks
|
|
1732
|
+
}) => {
|
|
1733
|
+
const defaultSWRConfig = {
|
|
1734
|
+
revalidateInterval: 0,
|
|
1735
|
+
revalidateOnFocus: false,
|
|
1736
|
+
revalidateOnReconnect: false,
|
|
1737
|
+
revalidateIfStale: false
|
|
1738
|
+
};
|
|
1739
|
+
errorHandler.setOnError(onError);
|
|
1740
|
+
const colors = buildColorsPalette(theme);
|
|
1741
|
+
const { url, scope, apiUrl } = LayerEnvironment[environment];
|
|
1742
|
+
const [state, dispatch] = useReducer(reducer, {
|
|
1743
|
+
auth: {
|
|
1744
|
+
access_token: "",
|
|
1745
|
+
token_type: "",
|
|
1746
|
+
expires_in: 0,
|
|
1747
|
+
expires_at: new Date(2e3, 1, 1)
|
|
1748
|
+
},
|
|
1710
1749
|
businessId,
|
|
1750
|
+
business: void 0,
|
|
1751
|
+
categories: [],
|
|
1711
1752
|
apiUrl,
|
|
1753
|
+
theme,
|
|
1754
|
+
colors,
|
|
1712
1755
|
usePlaidSandbox,
|
|
1756
|
+
onboardingStep: void 0,
|
|
1757
|
+
environment,
|
|
1758
|
+
toasts: [],
|
|
1759
|
+
eventCallbacks: {}
|
|
1760
|
+
});
|
|
1761
|
+
const {
|
|
1713
1762
|
touch,
|
|
1714
|
-
read,
|
|
1715
1763
|
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
|
-
});
|
|
1764
|
+
read,
|
|
1765
|
+
readTimestamps,
|
|
1766
|
+
hasBeenTouched,
|
|
1767
|
+
resetCaches
|
|
1768
|
+
} = useDataSync();
|
|
1769
|
+
const { data: auth } = appId !== void 0 && appSecret !== void 0 ? useSWR2(
|
|
1770
|
+
businessAccessToken === void 0 && appId !== void 0 && appSecret !== void 0 && isBefore(state.auth.expires_at, /* @__PURE__ */ new Date()) && "authenticate",
|
|
1771
|
+
Layer.authenticate({
|
|
1772
|
+
appId,
|
|
1773
|
+
appSecret,
|
|
1774
|
+
authenticationUrl: url,
|
|
1775
|
+
scope
|
|
1776
|
+
}),
|
|
1777
|
+
defaultSWRConfig
|
|
1778
|
+
) : { data: void 0 };
|
|
1791
1779
|
useEffect4(() => {
|
|
1792
|
-
if (
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
} else {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
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 }
|
|
1780
|
+
if (businessAccessToken) {
|
|
1781
|
+
dispatch({
|
|
1782
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
1783
|
+
payload: {
|
|
1784
|
+
auth: {
|
|
1785
|
+
access_token: businessAccessToken,
|
|
1786
|
+
token_type: "Bearer",
|
|
1787
|
+
expires_in: 3600,
|
|
1788
|
+
expires_at: add(/* @__PURE__ */ new Date(), { seconds: 3600 })
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
});
|
|
1792
|
+
} else if (auth?.access_token) {
|
|
1793
|
+
dispatch({
|
|
1794
|
+
type: "LayerContext.setAuth" /* setAuth */,
|
|
1795
|
+
payload: {
|
|
1796
|
+
auth: {
|
|
1797
|
+
...auth,
|
|
1798
|
+
expires_at: add(/* @__PURE__ */ new Date(), { seconds: auth.expires_in })
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1834
1801
|
});
|
|
1835
|
-
await refetchAccounts();
|
|
1836
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1837
|
-
} else {
|
|
1838
|
-
console.error(
|
|
1839
|
-
`Unlinking an account with source ${source} not yet supported`
|
|
1840
|
-
);
|
|
1841
1802
|
}
|
|
1842
|
-
};
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1803
|
+
}, [businessAccessToken, auth?.access_token]);
|
|
1804
|
+
const { data: categoriesData } = useSWR2(
|
|
1805
|
+
businessId && state.auth?.access_token && `categories-${businessId}`,
|
|
1806
|
+
Layer.getCategories(apiUrl, state.auth?.access_token, {
|
|
1807
|
+
params: { businessId }
|
|
1808
|
+
}),
|
|
1809
|
+
{
|
|
1810
|
+
...defaultSWRConfig,
|
|
1811
|
+
onSuccess: (response) => {
|
|
1812
|
+
if (response?.data?.categories?.length) {
|
|
1813
|
+
dispatch({
|
|
1814
|
+
type: "LayerContext.setCategories" /* setCategories */,
|
|
1815
|
+
payload: { categories: response.data.categories || [] }
|
|
1816
|
+
});
|
|
1850
1817
|
}
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
);
|
|
1821
|
+
useEffect4(() => {
|
|
1822
|
+
if (categoriesData?.data?.categories?.length) {
|
|
1823
|
+
dispatch({
|
|
1824
|
+
type: "LayerContext.setCategories" /* setCategories */,
|
|
1825
|
+
payload: { categories: categoriesData.data.categories || [] }
|
|
1851
1826
|
});
|
|
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
1827
|
}
|
|
1859
|
-
};
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1828
|
+
}, [categoriesData]);
|
|
1829
|
+
const { data: businessData } = useSWR2(
|
|
1830
|
+
businessId && state?.auth?.access_token && `business-${businessId}`,
|
|
1831
|
+
Layer.getBusiness(apiUrl, state?.auth?.access_token, {
|
|
1832
|
+
params: { businessId }
|
|
1833
|
+
}),
|
|
1834
|
+
{
|
|
1835
|
+
...defaultSWRConfig,
|
|
1836
|
+
onSuccess: (response) => {
|
|
1837
|
+
if (response?.data) {
|
|
1838
|
+
dispatch({
|
|
1839
|
+
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1840
|
+
payload: { business: response.data || [] }
|
|
1841
|
+
});
|
|
1867
1842
|
}
|
|
1868
|
-
}
|
|
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
|
-
);
|
|
1843
|
+
}
|
|
1875
1844
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
businessId,
|
|
1883
|
-
plaidItemPlaidId: connectionExternalId
|
|
1884
|
-
}
|
|
1845
|
+
);
|
|
1846
|
+
useEffect4(() => {
|
|
1847
|
+
if (businessData?.data) {
|
|
1848
|
+
dispatch({
|
|
1849
|
+
type: "LayerContext.setBusiness" /* setBusiness */,
|
|
1850
|
+
payload: { business: businessData.data || [] }
|
|
1885
1851
|
});
|
|
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
1852
|
}
|
|
1853
|
+
}, [businessData]);
|
|
1854
|
+
const setTheme = (theme2) => {
|
|
1855
|
+
dispatch({
|
|
1856
|
+
type: "LayerContext.setTheme" /* setTheme */,
|
|
1857
|
+
payload: { theme: theme2 }
|
|
1858
|
+
});
|
|
1859
|
+
dispatch({
|
|
1860
|
+
type: "LayerContext.setColors" /* setColors */,
|
|
1861
|
+
payload: { colors: buildColorsPalette(theme2) }
|
|
1862
|
+
});
|
|
1893
1863
|
};
|
|
1894
|
-
const
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
params: { businessId }
|
|
1864
|
+
const setLightColor = (color) => {
|
|
1865
|
+
setTheme({
|
|
1866
|
+
...state.theme ?? {},
|
|
1867
|
+
colors: {
|
|
1868
|
+
...state.theme?.colors ?? {},
|
|
1869
|
+
light: color
|
|
1870
|
+
}
|
|
1902
1871
|
});
|
|
1903
1872
|
};
|
|
1904
|
-
const
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1873
|
+
const setDarkColor = (color) => {
|
|
1874
|
+
setTheme({
|
|
1875
|
+
...state.theme ?? {},
|
|
1876
|
+
colors: {
|
|
1877
|
+
...state.theme?.colors ?? {},
|
|
1878
|
+
dark: color
|
|
1879
|
+
}
|
|
1908
1880
|
});
|
|
1909
1881
|
};
|
|
1910
|
-
const
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1882
|
+
const setTextColor = (color) => {
|
|
1883
|
+
setTheme({
|
|
1884
|
+
...state.theme ?? {},
|
|
1885
|
+
colors: {
|
|
1886
|
+
...state.theme?.colors ?? {},
|
|
1887
|
+
text: color
|
|
1888
|
+
}
|
|
1914
1889
|
});
|
|
1915
|
-
await refetchAccounts();
|
|
1916
|
-
touch("LINKED_ACCOUNTS" /* LINKED_ACCOUNTS */);
|
|
1917
1890
|
};
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1891
|
+
const setToast = (toast) => {
|
|
1892
|
+
dispatch({ type: "LayerContext.setToast" /* setToast */, payload: { toast } });
|
|
1893
|
+
};
|
|
1894
|
+
const removeToast = (toast) => {
|
|
1895
|
+
dispatch({ type: "LayerContext.removeToast" /* removeToast */, payload: { toast } });
|
|
1896
|
+
};
|
|
1897
|
+
const setToastExit = (toast) => {
|
|
1898
|
+
dispatch({ type: "LayerContext.setToastExit" /* setToastExit */, payload: { toast } });
|
|
1899
|
+
};
|
|
1900
|
+
const addToast = (toast) => {
|
|
1901
|
+
const id = `${Date.now()}-${Math.random()}`;
|
|
1902
|
+
const newToast = { id, isExiting: false, ...toast };
|
|
1903
|
+
setToast(newToast);
|
|
1904
|
+
setTimeout(() => {
|
|
1905
|
+
removeToast(newToast);
|
|
1906
|
+
setTimeout(() => {
|
|
1907
|
+
setToastExit(newToast);
|
|
1908
|
+
}, 1e3);
|
|
1909
|
+
}, toast.duration || 2e3);
|
|
1910
|
+
};
|
|
1911
|
+
const setColors = (colors2) => setTheme({
|
|
1912
|
+
...state.theme ?? {},
|
|
1913
|
+
colors: colors2
|
|
1914
|
+
});
|
|
1915
|
+
const getColor = (shade) => {
|
|
1916
|
+
if (state.colors && shade in state.colors) {
|
|
1917
|
+
return state.colors[shade];
|
|
1926
1918
|
}
|
|
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
|
|
1919
|
+
return;
|
|
1944
1920
|
};
|
|
1921
|
+
const setOnboardingStep = (value) => dispatch({
|
|
1922
|
+
type: "LayerContext.setOnboardingStep" /* setOnboardingStep */,
|
|
1923
|
+
payload: { onboardingStep: value }
|
|
1924
|
+
});
|
|
1925
|
+
const drawerContextData = useDrawer();
|
|
1926
|
+
return /* @__PURE__ */ React7.createElement(SWRConfig, { value: defaultSWRConfig }, /* @__PURE__ */ React7.createElement(
|
|
1927
|
+
LayerContext.Provider,
|
|
1928
|
+
{
|
|
1929
|
+
value: {
|
|
1930
|
+
...state,
|
|
1931
|
+
setTheme,
|
|
1932
|
+
getColor,
|
|
1933
|
+
setLightColor,
|
|
1934
|
+
setDarkColor,
|
|
1935
|
+
setTextColor,
|
|
1936
|
+
setColors,
|
|
1937
|
+
setOnboardingStep,
|
|
1938
|
+
addToast,
|
|
1939
|
+
removeToast,
|
|
1940
|
+
onError: errorHandler.onError,
|
|
1941
|
+
touch,
|
|
1942
|
+
read,
|
|
1943
|
+
syncTimestamps,
|
|
1944
|
+
readTimestamps,
|
|
1945
|
+
expireDataCaches: resetCaches,
|
|
1946
|
+
hasBeenTouched,
|
|
1947
|
+
eventCallbacks
|
|
1948
|
+
}
|
|
1949
|
+
},
|
|
1950
|
+
/* @__PURE__ */ React7.createElement(BankTransactionsProvider, null, /* @__PURE__ */ React7.createElement(DrawerContext.Provider, { value: drawerContextData }, children, /* @__PURE__ */ React7.createElement(GlobalWidgets, null)))
|
|
1951
|
+
));
|
|
1945
1952
|
};
|
|
1946
1953
|
|
|
1954
|
+
// src/components/Onboarding/Onboarding.tsx
|
|
1955
|
+
import React44, { useContext as useContext6, useEffect as useEffect6, useState as useState8 } from "react";
|
|
1956
|
+
|
|
1957
|
+
// src/contexts/LinkedAccountsContext/LinkedAccountsContext.ts
|
|
1958
|
+
import { createContext as createContext4 } from "react";
|
|
1959
|
+
var LinkedAccountsContext = createContext4({
|
|
1960
|
+
data: void 0,
|
|
1961
|
+
isLoading: false,
|
|
1962
|
+
loadingStatus: "initial",
|
|
1963
|
+
isValidating: false,
|
|
1964
|
+
error: void 0,
|
|
1965
|
+
updateConnectionStatus: () => {
|
|
1966
|
+
},
|
|
1967
|
+
addConnection: () => {
|
|
1968
|
+
},
|
|
1969
|
+
removeConnection: () => {
|
|
1970
|
+
},
|
|
1971
|
+
repairConnection: () => {
|
|
1972
|
+
},
|
|
1973
|
+
refetchAccounts: () => {
|
|
1974
|
+
},
|
|
1975
|
+
unlinkAccount: () => {
|
|
1976
|
+
},
|
|
1977
|
+
denyAccount: () => {
|
|
1978
|
+
},
|
|
1979
|
+
confirmAccount: () => {
|
|
1980
|
+
},
|
|
1981
|
+
breakConnection: () => {
|
|
1982
|
+
},
|
|
1983
|
+
syncAccounts: () => {
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
|
|
1947
1987
|
// src/providers/LinkedAccountsProvider/LinkedAccountsProvider.tsx
|
|
1988
|
+
import React8 from "react";
|
|
1948
1989
|
var LinkedAccountsProvider = ({
|
|
1949
1990
|
children
|
|
1950
1991
|
}) => {
|
|
@@ -2218,8 +2259,32 @@ var Sunrise = ({ size = 12, ...props }) => /* @__PURE__ */ React16.createElement
|
|
|
2218
2259
|
);
|
|
2219
2260
|
var Sunrise_default = Sunrise;
|
|
2220
2261
|
|
|
2262
|
+
// src/components/BankTransactions/constants.ts
|
|
2263
|
+
var CategorizedCategories = [
|
|
2264
|
+
"CATEGORIZED" /* CATEGORIZED */,
|
|
2265
|
+
"JOURNALING" /* JOURNALING */,
|
|
2266
|
+
"SPLIT" /* SPLIT */,
|
|
2267
|
+
"MATCHED" /* MATCHED */
|
|
2268
|
+
];
|
|
2269
|
+
var ReviewCategories = [
|
|
2270
|
+
"READY_FOR_INPUT" /* READY_FOR_INPUT */,
|
|
2271
|
+
"LAYER_REVIEW" /* LAYER_REVIEW */
|
|
2272
|
+
];
|
|
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,
|
|
@@ -5633,7 +5698,7 @@ import classNames32 from "classnames";
|
|
|
5633
5698
|
var isAlreadyMatched2 = (bankTransaction) => {
|
|
5634
5699
|
if (bankTransaction?.match) {
|
|
5635
5700
|
const foundMatch = bankTransaction.suggested_matches?.find(
|
|
5636
|
-
(x) => x.details.id === bankTransaction?.match?.details.id
|
|
5701
|
+
(x) => x.details.id === bankTransaction?.match?.details.id || x.details.id === bankTransaction?.match?.bank_transaction.id
|
|
5637
5702
|
);
|
|
5638
5703
|
return foundMatch?.id;
|
|
5639
5704
|
}
|
|
@@ -5671,13 +5736,13 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5671
5736
|
bankTransaction.category ? "categorize" /* categorize */ : hasMatch(bankTransaction) ? "match" /* match */ : "categorize" /* categorize */
|
|
5672
5737
|
);
|
|
5673
5738
|
const [selectedMatchId, setSelectedMatchId] = useState13(
|
|
5674
|
-
isAlreadyMatched2(bankTransaction)
|
|
5739
|
+
isAlreadyMatched2(bankTransaction) ?? bankTransaction?.suggested_matches?.[0]?.id
|
|
5675
5740
|
);
|
|
5676
5741
|
const [matchFormError, setMatchFormError] = useState13();
|
|
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,
|
|
@@ -5795,9 +5859,12 @@ var ExpandedBankTransactionRow = forwardRef5(
|
|
|
5795
5859
|
if (purpose === "match" /* match */) {
|
|
5796
5860
|
if (!selectedMatchId) {
|
|
5797
5861
|
setMatchFormError("Select an option to match the transaction");
|
|
5862
|
+
return;
|
|
5798
5863
|
} else if (selectedMatchId && selectedMatchId !== isAlreadyMatched2(bankTransaction)) {
|
|
5799
|
-
onMatchSubmit(selectedMatchId);
|
|
5864
|
+
await onMatchSubmit(selectedMatchId);
|
|
5865
|
+
return;
|
|
5800
5866
|
}
|
|
5867
|
+
close();
|
|
5801
5868
|
return;
|
|
5802
5869
|
}
|
|
5803
5870
|
if (!validateSplit(rowState)) {
|
|
@@ -6148,7 +6215,7 @@ var SplitTooltipDetails = ({
|
|
|
6148
6215
|
|
|
6149
6216
|
// src/components/BankTransactionRow/BankTransactionRow.tsx
|
|
6150
6217
|
import classNames33 from "classnames";
|
|
6151
|
-
import { parseISO as
|
|
6218
|
+
import { parseISO as parseISO6, format as formatTime5 } from "date-fns";
|
|
6152
6219
|
var extractDescriptionForSplit = (category) => {
|
|
6153
6220
|
if (!category.entries) {
|
|
6154
6221
|
return "";
|
|
@@ -6180,12 +6247,12 @@ var BankTransactionRow = ({
|
|
|
6180
6247
|
showReceiptUploads,
|
|
6181
6248
|
stringOverrides
|
|
6182
6249
|
}) => {
|
|
6183
|
-
const expandedRowRef =
|
|
6250
|
+
const expandedRowRef = useRef11(null);
|
|
6184
6251
|
const [showRetry, setShowRetry] = useState14(false);
|
|
6185
6252
|
const {
|
|
6186
|
-
filters,
|
|
6187
6253
|
categorize: categorizeBankTransaction2,
|
|
6188
|
-
match: matchBankTransaction2
|
|
6254
|
+
match: matchBankTransaction2,
|
|
6255
|
+
shouldHideAfterCategorize
|
|
6189
6256
|
} = useBankTransactionsContext();
|
|
6190
6257
|
const [selectedCategory, setSelectedCategory] = useState14(
|
|
6191
6258
|
getDefaultSelectedCategory(bankTransaction)
|
|
@@ -6223,7 +6290,7 @@ var BankTransactionRow = ({
|
|
|
6223
6290
|
}
|
|
6224
6291
|
}, [bankTransaction.error]);
|
|
6225
6292
|
useEffect11(() => {
|
|
6226
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6293
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6227
6294
|
setTimeout(() => {
|
|
6228
6295
|
removeTransaction(bankTransaction);
|
|
6229
6296
|
}, 300);
|
|
@@ -6256,7 +6323,7 @@ var BankTransactionRow = ({
|
|
|
6256
6323
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6257
6324
|
const rowClassName = classNames33(
|
|
6258
6325
|
className,
|
|
6259
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6326
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6260
6327
|
open ? openClassName : "",
|
|
6261
6328
|
initialLoad ? "initial-load" : "",
|
|
6262
6329
|
showComponent ? "show" : ""
|
|
@@ -6267,7 +6334,7 @@ var BankTransactionRow = ({
|
|
|
6267
6334
|
className: "Layer__table-cell Layer__bank-transaction-table__date-col",
|
|
6268
6335
|
...openRow
|
|
6269
6336
|
},
|
|
6270
|
-
/* @__PURE__ */ React82.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(
|
|
6337
|
+
/* @__PURE__ */ React82.createElement("span", { className: "Layer__table-cell-content" }, formatTime5(parseISO6(bankTransaction.date), dateFormat))
|
|
6271
6338
|
), /* @__PURE__ */ React82.createElement(
|
|
6272
6339
|
"td",
|
|
6273
6340
|
{
|
|
@@ -6357,7 +6424,7 @@ var BankTransactionRow = ({
|
|
|
6357
6424
|
dateFormat
|
|
6358
6425
|
}
|
|
6359
6426
|
), /* @__PURE__ */ React82.createElement("span", { className: `${className}__category-text__text` }, `${formatTime5(
|
|
6360
|
-
|
|
6427
|
+
parseISO6(bankTransaction.match.bank_transaction.date),
|
|
6361
6428
|
dateFormat
|
|
6362
6429
|
)}, ${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
6430
|
!categorized && !open && showRetry ? /* @__PURE__ */ React82.createElement(
|
|
@@ -6432,7 +6499,7 @@ var BankTransactionRow = ({
|
|
|
6432
6499
|
|
|
6433
6500
|
// src/components/BankTransactionList/Assignment.tsx
|
|
6434
6501
|
import React83 from "react";
|
|
6435
|
-
import { parseISO as
|
|
6502
|
+
import { parseISO as parseISO7, format as formatTime6 } from "date-fns";
|
|
6436
6503
|
var Assignment = ({ bankTransaction }) => {
|
|
6437
6504
|
if (bankTransaction.match && bankTransaction.categorization_status === "MATCHED" /* MATCHED */) {
|
|
6438
6505
|
return /* @__PURE__ */ React83.createElement(React83.Fragment, null, /* @__PURE__ */ React83.createElement(
|
|
@@ -6444,7 +6511,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6444
6511
|
text: "Matched"
|
|
6445
6512
|
}
|
|
6446
6513
|
), /* @__PURE__ */ React83.createElement(Text, { className: "Layer__bank-transaction-list-item__category-text__text" }, `${formatTime6(
|
|
6447
|
-
|
|
6514
|
+
parseISO7(bankTransaction.match.bank_transaction.date),
|
|
6448
6515
|
DATE_FORMAT
|
|
6449
6516
|
)}, ${bankTransaction.match.bank_transaction.description ?? bankTransaction.match?.details?.description}`));
|
|
6450
6517
|
}
|
|
@@ -6469,7 +6536,7 @@ var Assignment = ({ bankTransaction }) => {
|
|
|
6469
6536
|
|
|
6470
6537
|
// src/components/BankTransactionList/BankTransactionListItem.tsx
|
|
6471
6538
|
import classNames34 from "classnames";
|
|
6472
|
-
import { parseISO as
|
|
6539
|
+
import { parseISO as parseISO8, format as formatTime7 } from "date-fns";
|
|
6473
6540
|
var BankTransactionListItem = ({
|
|
6474
6541
|
index = 0,
|
|
6475
6542
|
dateFormat,
|
|
@@ -6482,9 +6549,13 @@ var BankTransactionListItem = ({
|
|
|
6482
6549
|
removeTransaction,
|
|
6483
6550
|
stringOverrides
|
|
6484
6551
|
}) => {
|
|
6485
|
-
const expandedRowRef =
|
|
6552
|
+
const expandedRowRef = useRef12(null);
|
|
6486
6553
|
const [showRetry, setShowRetry] = useState15(false);
|
|
6487
|
-
const {
|
|
6554
|
+
const {
|
|
6555
|
+
categorize: categorizeBankTransaction2,
|
|
6556
|
+
match: matchBankTransaction2,
|
|
6557
|
+
shouldHideAfterCategorize
|
|
6558
|
+
} = useBankTransactionsContext();
|
|
6488
6559
|
const [selectedCategory, setSelectedCategory] = useState15(
|
|
6489
6560
|
getDefaultSelectedCategory(bankTransaction)
|
|
6490
6561
|
);
|
|
@@ -6506,7 +6577,7 @@ var BankTransactionListItem = ({
|
|
|
6506
6577
|
}
|
|
6507
6578
|
}, [bankTransaction.error]);
|
|
6508
6579
|
useEffect12(() => {
|
|
6509
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
6580
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
6510
6581
|
setTimeout(() => {
|
|
6511
6582
|
removeTransaction(bankTransaction);
|
|
6512
6583
|
}, 300);
|
|
@@ -6534,11 +6605,11 @@ var BankTransactionListItem = ({
|
|
|
6534
6605
|
const openClassName = open ? `${className}--expanded` : "";
|
|
6535
6606
|
const rowClassName = classNames34(
|
|
6536
6607
|
className,
|
|
6537
|
-
bankTransaction.recently_categorized && editable ? "Layer__bank-transaction-row--removing" : "",
|
|
6608
|
+
bankTransaction.recently_categorized && editable && shouldHideAfterCategorize(bankTransaction) ? "Layer__bank-transaction-row--removing" : "",
|
|
6538
6609
|
open ? openClassName : "",
|
|
6539
6610
|
showComponent ? "show" : ""
|
|
6540
6611
|
);
|
|
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(
|
|
6612
|
+
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
6613
|
"div",
|
|
6543
6614
|
{
|
|
6544
6615
|
onClick: toggleOpen,
|
|
@@ -6648,7 +6719,7 @@ var BankTransactionList = ({
|
|
|
6648
6719
|
import React93 from "react";
|
|
6649
6720
|
|
|
6650
6721
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
6651
|
-
import React92, { useContext as useContext11, useEffect as useEffect17, useRef as
|
|
6722
|
+
import React92, { useContext as useContext11, useEffect as useEffect17, useRef as useRef13, useState as useState22 } from "react";
|
|
6652
6723
|
|
|
6653
6724
|
// src/components/BankTransactionMobileList/BankTransactionMobileForms.tsx
|
|
6654
6725
|
import React91 from "react";
|
|
@@ -7105,7 +7176,7 @@ var TransactionToOpenContext = createContext5({
|
|
|
7105
7176
|
|
|
7106
7177
|
// src/components/BankTransactionMobileList/BankTransactionMobileListItem.tsx
|
|
7107
7178
|
import classNames36 from "classnames";
|
|
7108
|
-
import { parseISO as
|
|
7179
|
+
import { parseISO as parseISO9, format as formatTime8 } from "date-fns";
|
|
7109
7180
|
var DATE_FORMAT2 = "LLL d";
|
|
7110
7181
|
var getAssignedValue2 = (bankTransaction) => {
|
|
7111
7182
|
if (bankTransaction.categorization_status === "SPLIT" /* SPLIT */) {
|
|
@@ -7130,13 +7201,14 @@ var BankTransactionMobileListItem = ({
|
|
|
7130
7201
|
setTransactionIdToOpen,
|
|
7131
7202
|
clearTransactionIdToOpen
|
|
7132
7203
|
} = useContext11(TransactionToOpenContext);
|
|
7204
|
+
const { shouldHideAfterCategorize } = useBankTransactionsContext();
|
|
7133
7205
|
const formRowRef = useElementSize(
|
|
7134
7206
|
(_a, _b, { height: height2 }) => setHeight(height2)
|
|
7135
7207
|
);
|
|
7136
7208
|
const headingRowRef = useElementSize((_a, _b, { height: height2 }) => {
|
|
7137
7209
|
setHeadingHeight(height2);
|
|
7138
7210
|
});
|
|
7139
|
-
const itemRef =
|
|
7211
|
+
const itemRef = useRef13(null);
|
|
7140
7212
|
const [removeAnim, setRemoveAnim] = useState22(false);
|
|
7141
7213
|
const [purpose, setPurpose] = useState22(
|
|
7142
7214
|
bankTransaction.category ? bankTransaction.categorization_status === "SPLIT" /* SPLIT */ ? "more" /* more */ : "business" /* business */ : hasMatch(bankTransaction) ? "more" /* more */ : "business" /* business */
|
|
@@ -7163,7 +7235,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7163
7235
|
}, [transactionIdToOpen]);
|
|
7164
7236
|
useEffect17(() => {
|
|
7165
7237
|
if (!removeAnim && bankTransaction.recently_categorized) {
|
|
7166
|
-
if (editable) {
|
|
7238
|
+
if (editable && shouldHideAfterCategorize(bankTransaction)) {
|
|
7167
7239
|
setRemoveAnim(true);
|
|
7168
7240
|
openNext();
|
|
7169
7241
|
} else {
|
|
@@ -7196,7 +7268,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7196
7268
|
}
|
|
7197
7269
|
}, []);
|
|
7198
7270
|
useEffect17(() => {
|
|
7199
|
-
if (editable && bankTransaction.recently_categorized) {
|
|
7271
|
+
if (editable && bankTransaction.recently_categorized && shouldHideAfterCategorize(bankTransaction)) {
|
|
7200
7272
|
setTimeout(() => {
|
|
7201
7273
|
removeTransaction(bankTransaction);
|
|
7202
7274
|
}, 300);
|
|
@@ -7227,7 +7299,7 @@ var BankTransactionMobileListItem = ({
|
|
|
7227
7299
|
},
|
|
7228
7300
|
isCredit(bankTransaction) ? "+$" : " $",
|
|
7229
7301
|
centsToDollars(bankTransaction.amount)
|
|
7230
|
-
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(
|
|
7302
|
+
), /* @__PURE__ */ React92.createElement("span", { className: `${className}__heading__date` }, formatTime8(parseISO9(bankTransaction.date), DATE_FORMAT2))))
|
|
7231
7303
|
), categorizationEnabled(mode) ? /* @__PURE__ */ React92.createElement(
|
|
7232
7304
|
"div",
|
|
7233
7305
|
{
|
|
@@ -7750,11 +7822,11 @@ var DownloadCloud = ({ size = 18, ...props }) => /* @__PURE__ */ React103.create
|
|
|
7750
7822
|
var DownloadCloud_default = DownloadCloud;
|
|
7751
7823
|
|
|
7752
7824
|
// src/utils/business.ts
|
|
7753
|
-
import { differenceInCalendarMonths, parseISO as
|
|
7825
|
+
import { differenceInCalendarMonths, parseISO as parseISO10, startOfMonth } from "date-fns";
|
|
7754
7826
|
var getActivationDate = (business) => {
|
|
7755
7827
|
try {
|
|
7756
7828
|
if (business && business.activation_at) {
|
|
7757
|
-
return
|
|
7829
|
+
return parseISO10(business.activation_at);
|
|
7758
7830
|
}
|
|
7759
7831
|
return;
|
|
7760
7832
|
} catch (_err) {
|
|
@@ -7780,7 +7852,7 @@ var isDateAllowedToBrowse = (date, business) => {
|
|
|
7780
7852
|
};
|
|
7781
7853
|
|
|
7782
7854
|
// src/components/DatePicker/DatePicker.tsx
|
|
7783
|
-
import React105, { useEffect as useEffect18, useRef as
|
|
7855
|
+
import React105, { useEffect as useEffect18, useRef as useRef14, useState as useState23 } from "react";
|
|
7784
7856
|
import ReactDatePicker from "react-datepicker";
|
|
7785
7857
|
|
|
7786
7858
|
// src/components/DatePicker/DatePickerOptions.tsx
|
|
@@ -7943,7 +8015,7 @@ var DatePicker = ({
|
|
|
7943
8015
|
navigateArrows = mode === "monthPicker",
|
|
7944
8016
|
...props
|
|
7945
8017
|
}) => {
|
|
7946
|
-
const pickerRef =
|
|
8018
|
+
const pickerRef = useRef14(null);
|
|
7947
8019
|
const [updatePickerDate, setPickerDate] = useState23(false);
|
|
7948
8020
|
const [selectedDates, setSelectedDates] = useState23(selected);
|
|
7949
8021
|
const { isDesktop } = useSizeClass();
|
|
@@ -8339,7 +8411,7 @@ var DataStates = ({
|
|
|
8339
8411
|
editable
|
|
8340
8412
|
}) => {
|
|
8341
8413
|
let title = editable ? "You are up to date with transactions!" : "You have no categorized transactions";
|
|
8342
|
-
let description = editable ? "All uncategorized
|
|
8414
|
+
let description = editable ? "All uncategorized transactions will be displayed here" : "All transactions will be displayed here once reviewed";
|
|
8343
8415
|
const showRefreshButton = bankTransactions?.length;
|
|
8344
8416
|
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
8417
|
DataState,
|
|
@@ -8364,10 +8436,9 @@ var DataStates = ({
|
|
|
8364
8436
|
};
|
|
8365
8437
|
|
|
8366
8438
|
// src/components/BankTransactions/BankTransactions.tsx
|
|
8367
|
-
import { endOfMonth as endOfMonth3, parseISO as
|
|
8439
|
+
import { endOfMonth as endOfMonth3, parseISO as parseISO11, startOfMonth as startOfMonth4 } from "date-fns";
|
|
8368
8440
|
var COMPONENT_NAME2 = "bank-transactions";
|
|
8369
8441
|
var TEST_EMPTY_STATE = false;
|
|
8370
|
-
var POLL_INTERVAL = 1e3;
|
|
8371
8442
|
var categorizationEnabled = (mode) => {
|
|
8372
8443
|
if (mode === "bookkeeping-client") {
|
|
8373
8444
|
return false;
|
|
@@ -8415,39 +8486,11 @@ var BankTransactionsContent = ({
|
|
|
8415
8486
|
fetchMore,
|
|
8416
8487
|
removeAfterCategorize
|
|
8417
8488
|
} = useBankTransactionsContext();
|
|
8418
|
-
const { data: linkedAccounts
|
|
8489
|
+
const { data: linkedAccounts } = useLinkedAccounts();
|
|
8419
8490
|
const isSyncing = useMemo6(
|
|
8420
8491
|
() => Boolean(linkedAccounts?.some((item) => item.is_syncing)),
|
|
8421
8492
|
[linkedAccounts]
|
|
8422
8493
|
);
|
|
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
8494
|
useEffect19(() => {
|
|
8452
8495
|
activate();
|
|
8453
8496
|
}, []);
|
|
@@ -8489,7 +8532,7 @@ var BankTransactionsContent = ({
|
|
|
8489
8532
|
const bankTransactions = TEST_EMPTY_STATE ? [] : useMemo6(() => {
|
|
8490
8533
|
if (monthlyView) {
|
|
8491
8534
|
return data?.filter(
|
|
8492
|
-
(x) =>
|
|
8535
|
+
(x) => parseISO11(x.date) >= dateRange.startDate && parseISO11(x.date) <= dateRange.endDate
|
|
8493
8536
|
);
|
|
8494
8537
|
}
|
|
8495
8538
|
const firstPageIndex = (currentPage - 1) * pageSize;
|
|
@@ -8625,7 +8668,7 @@ var BankTransactionsContent = ({
|
|
|
8625
8668
|
import React110 from "react";
|
|
8626
8669
|
|
|
8627
8670
|
// src/hooks/useQuickbooks/useQuickbooks.ts
|
|
8628
|
-
import { useEffect as useEffect20, useRef as
|
|
8671
|
+
import { useEffect as useEffect20, useRef as useRef16, useState as useState26 } from "react";
|
|
8629
8672
|
var DEBUG2 = true;
|
|
8630
8673
|
var useQuickbooks = () => {
|
|
8631
8674
|
const { auth, businessId, apiUrl } = useLayerContext();
|
|
@@ -8633,7 +8676,7 @@ var useQuickbooks = () => {
|
|
|
8633
8676
|
const [quickbooksIsLinked, setQuickbooksIsLinked] = useState26(
|
|
8634
8677
|
null
|
|
8635
8678
|
);
|
|
8636
|
-
const syncStatusIntervalRef =
|
|
8679
|
+
const syncStatusIntervalRef = useRef16(null);
|
|
8637
8680
|
useEffect20(() => {
|
|
8638
8681
|
if (isSyncingFromQuickbooks && syncStatusIntervalRef.current === null) {
|
|
8639
8682
|
const interval = setInterval(() => fetchIsSyncingFromQuickbooks(), 2e3);
|
|
@@ -11084,7 +11127,7 @@ var TableRow = ({
|
|
|
11084
11127
|
};
|
|
11085
11128
|
|
|
11086
11129
|
// src/components/Table/Table.tsx
|
|
11087
|
-
import React128, { useEffect as useEffect26, useRef as
|
|
11130
|
+
import React128, { useEffect as useEffect26, useRef as useRef17 } from "react";
|
|
11088
11131
|
import classNames47 from "classnames";
|
|
11089
11132
|
var Table = ({
|
|
11090
11133
|
componentName,
|
|
@@ -11092,8 +11135,8 @@ var Table = ({
|
|
|
11092
11135
|
borderCollapse = "separate",
|
|
11093
11136
|
bottomSpacing = true
|
|
11094
11137
|
}) => {
|
|
11095
|
-
const tableRef =
|
|
11096
|
-
const prevChildrenRef =
|
|
11138
|
+
const tableRef = useRef17(null);
|
|
11139
|
+
const prevChildrenRef = useRef17([]);
|
|
11097
11140
|
useEffect26(() => {
|
|
11098
11141
|
if (tableRef.current) {
|
|
11099
11142
|
const tbody = tableRef.current.querySelector("tbody");
|
|
@@ -12304,7 +12347,10 @@ var useChartOfAccounts = ({ withDates, startDate: initialStartDate, endDate: ini
|
|
|
12304
12347
|
}
|
|
12305
12348
|
const data2 = {
|
|
12306
12349
|
name: form.data.name ?? "",
|
|
12307
|
-
stable_name: form.data.stable_name
|
|
12350
|
+
stable_name: form.data.stable_name ? {
|
|
12351
|
+
type: "StableName",
|
|
12352
|
+
stable_name: form.data.stable_name
|
|
12353
|
+
} : void 0,
|
|
12308
12354
|
parent_id: form.data.parent ? {
|
|
12309
12355
|
type: "AccountId",
|
|
12310
12356
|
id: form.data.parent.value
|
|
@@ -13081,7 +13127,7 @@ var Card = ({ children, className }) => {
|
|
|
13081
13127
|
|
|
13082
13128
|
// src/components/DateTime/DateTime.tsx
|
|
13083
13129
|
import React149 from "react";
|
|
13084
|
-
import { parseISO as
|
|
13130
|
+
import { parseISO as parseISO12, format as formatTime9 } from "date-fns";
|
|
13085
13131
|
var DateTime = ({
|
|
13086
13132
|
value,
|
|
13087
13133
|
format: format7,
|
|
@@ -13091,10 +13137,10 @@ var DateTime = ({
|
|
|
13091
13137
|
onlyTime
|
|
13092
13138
|
}) => {
|
|
13093
13139
|
if (format7) {
|
|
13094
|
-
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(
|
|
13140
|
+
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, formatTime9(parseISO12(value), format7));
|
|
13095
13141
|
}
|
|
13096
|
-
const date = formatTime9(
|
|
13097
|
-
const time = formatTime9(
|
|
13142
|
+
const date = formatTime9(parseISO12(value), dateFormat ?? DATE_FORMAT);
|
|
13143
|
+
const time = formatTime9(parseISO12(value), timeFormat ?? TIME_FORMAT);
|
|
13098
13144
|
return /* @__PURE__ */ React149.createElement(Text, { className: "Layer__datetime" }, !onlyTime && /* @__PURE__ */ React149.createElement(
|
|
13099
13145
|
Text,
|
|
13100
13146
|
{
|
|
@@ -13259,7 +13305,7 @@ var LedgerAccountEntryDetails = ({ stringOverrides }) => {
|
|
|
13259
13305
|
// src/components/LedgerAccount/LedgerAccountRow.tsx
|
|
13260
13306
|
import React153, { useContext as useContext23, useEffect as useEffect36, useState as useState40 } from "react";
|
|
13261
13307
|
import classNames54 from "classnames";
|
|
13262
|
-
import { parseISO as
|
|
13308
|
+
import { parseISO as parseISO13, format as formatTime10 } from "date-fns";
|
|
13263
13309
|
var LedgerAccountRow = ({
|
|
13264
13310
|
row,
|
|
13265
13311
|
index,
|
|
@@ -13298,7 +13344,7 @@ var LedgerAccountRow = ({
|
|
|
13298
13344
|
}
|
|
13299
13345
|
}
|
|
13300
13346
|
},
|
|
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(
|
|
13347
|
+
/* @__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
13348
|
Text,
|
|
13303
13349
|
{
|
|
13304
13350
|
weight: "normal" /* normal */,
|
|
@@ -13331,7 +13377,7 @@ var LedgerAccountRow = ({
|
|
|
13331
13377
|
}
|
|
13332
13378
|
}
|
|
13333
13379
|
},
|
|
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(
|
|
13380
|
+
/* @__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
13381
|
Text,
|
|
13336
13382
|
{
|
|
13337
13383
|
weight: "normal" /* normal */,
|
|
@@ -13360,7 +13406,7 @@ var LedgerAccountRow = ({
|
|
|
13360
13406
|
}
|
|
13361
13407
|
}
|
|
13362
13408
|
},
|
|
13363
|
-
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.date && formatTime10(
|
|
13409
|
+
/* @__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
13410
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.entry_id.substring(0, 5))),
|
|
13365
13411
|
/* @__PURE__ */ React153.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React153.createElement("span", { className: "Layer__table-cell-content" }, row.source?.display_description ?? "")),
|
|
13366
13412
|
/* @__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 +13916,7 @@ import React161, { useContext as useContext31, useMemo as useMemo17, useState as
|
|
|
13870
13916
|
// src/components/JournalRow/JournalRow.tsx
|
|
13871
13917
|
import React156, { useContext as useContext26, useEffect as useEffect39, useState as useState44 } from "react";
|
|
13872
13918
|
import classNames56 from "classnames";
|
|
13873
|
-
import { parseISO as
|
|
13919
|
+
import { parseISO as parseISO14, format as formatTime11 } from "date-fns";
|
|
13874
13920
|
var INDENTATION2 = 24;
|
|
13875
13921
|
var EXPANDED_STYLE3 = {
|
|
13876
13922
|
height: "100%",
|
|
@@ -13983,7 +14029,7 @@ var JournalRow = ({
|
|
|
13983
14029
|
)
|
|
13984
14030
|
))),
|
|
13985
14031
|
/* @__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(
|
|
14032
|
+
/* @__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
14033
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, humanizeEnum(row.entry_type))),
|
|
13988
14034
|
/* @__PURE__ */ React156.createElement("td", { className: "Layer__table-cell" }, /* @__PURE__ */ React156.createElement("span", { className: "Layer__table-cell-content" }, `(${row.line_items.length})`)),
|
|
13989
14035
|
/* @__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 +15507,7 @@ var GeneralLedgerView = ({
|
|
|
15461
15507
|
};
|
|
15462
15508
|
|
|
15463
15509
|
// src/views/Reports/Reports.tsx
|
|
15464
|
-
import React180, { useContext as useContext38, useRef as
|
|
15510
|
+
import React180, { useContext as useContext38, useRef as useRef18, useState as useState55 } from "react";
|
|
15465
15511
|
var DownloadButton2 = ({
|
|
15466
15512
|
stringOverrides
|
|
15467
15513
|
}) => {
|
|
@@ -15533,7 +15579,7 @@ var Reports = ({
|
|
|
15533
15579
|
stringOverrides,
|
|
15534
15580
|
enabledReports = ["profitAndLoss", "balanceSheet", "statementOfCashFlow"]
|
|
15535
15581
|
}) => {
|
|
15536
|
-
const containerRef =
|
|
15582
|
+
const containerRef = useRef18(null);
|
|
15537
15583
|
const [activeTab, setActiveTab] = useState55(enabledReports[0]);
|
|
15538
15584
|
const options = getOptions(enabledReports);
|
|
15539
15585
|
const defaultTitle = enabledReports.length > 1 ? "Reports" : options.find((option) => option.value = enabledReports[0])?.label;
|
|
@@ -15601,10 +15647,10 @@ var ReportsPanel = ({
|
|
|
15601
15647
|
};
|
|
15602
15648
|
|
|
15603
15649
|
// src/components/ProfitAndLossView/ProfitAndLossView.tsx
|
|
15604
|
-
import React181, { useContext as useContext39, useRef as
|
|
15650
|
+
import React181, { useContext as useContext39, useRef as useRef19 } from "react";
|
|
15605
15651
|
var COMPONENT_NAME7 = "profit-and-loss";
|
|
15606
15652
|
var ProfitAndLossView = (props) => {
|
|
15607
|
-
const containerRef =
|
|
15653
|
+
const containerRef = useRef19(null);
|
|
15608
15654
|
return /* @__PURE__ */ React181.createElement(Container, { name: COMPONENT_NAME7, ref: containerRef }, /* @__PURE__ */ React181.createElement(ProfitAndLoss, null, /* @__PURE__ */ React181.createElement(ProfitAndLossPanel, { containerRef, ...props })));
|
|
15609
15655
|
};
|
|
15610
15656
|
var ProfitAndLossPanel = ({
|
|
@@ -15699,6 +15745,7 @@ export {
|
|
|
15699
15745
|
StatementOfCashFlow,
|
|
15700
15746
|
Tasks,
|
|
15701
15747
|
useBankTransactionsContext,
|
|
15748
|
+
useDataSync,
|
|
15702
15749
|
useLayerContext
|
|
15703
15750
|
};
|
|
15704
15751
|
//# sourceMappingURL=index.js.map
|