@churchapps/apphelper 0.4.7 → 0.4.9

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.
Files changed (174) hide show
  1. package/CHUMS_COMPONENT_EXTRACTION_CANDIDATES.md +210 -0
  2. package/COMPONENT_USAGE_REPORT.md +322 -0
  3. package/b1app-specific-components.md +146 -0
  4. package/component-usage-analysis.md +169 -0
  5. package/dist/components/ImageEditor.d.ts +1 -1
  6. package/dist/components/ImageEditor.d.ts.map +1 -1
  7. package/dist/components/ImageEditor.js +1 -1
  8. package/dist/components/ImageEditor.js.map +1 -1
  9. package/dist/components/header/SecondaryMenu.js +3 -3
  10. package/dist/components/header/SecondaryMenu.js.map +1 -1
  11. package/dist/components/index.d.ts +0 -5
  12. package/dist/components/index.d.ts.map +1 -1
  13. package/dist/components/index.js +1 -10
  14. package/dist/components/index.js.map +1 -1
  15. package/dist/components/markdownEditor/IconNamesList.d.ts.map +1 -0
  16. package/dist/components/markdownEditor/IconNamesList.js +16 -0
  17. package/dist/components/markdownEditor/IconNamesList.js.map +1 -0
  18. package/dist/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.js +1 -1
  19. package/dist/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.js.map +1 -1
  20. package/dist/components/markdownEditor/plugins/emoji/EmojiNodeTransform.js +1 -1
  21. package/dist/components/markdownEditor/plugins/emoji/EmojiNodeTransform.js.map +1 -1
  22. package/dist/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.js +1 -1
  23. package/dist/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.js.map +1 -1
  24. package/dist/components/markdownEditor/plugins/emoji/EmojisPlugin.js +1 -1
  25. package/dist/components/markdownEditor/plugins/emoji/EmojisPlugin.js.map +1 -1
  26. package/dist/components/notes/index.d.ts +0 -2
  27. package/dist/components/notes/index.d.ts.map +1 -1
  28. package/dist/components/notes/index.js +1 -5
  29. package/dist/components/notes/index.js.map +1 -1
  30. package/dist/helpers/FileHelper.d.ts +1 -1
  31. package/dist/helpers/FileHelper.d.ts.map +1 -1
  32. package/dist/helpers/FileHelper.js +2 -6
  33. package/dist/helpers/FileHelper.js.map +1 -1
  34. package/dist/index.d.ts +0 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +0 -1
  37. package/dist/index.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/components/ImageEditor.tsx +1 -1
  40. package/src/components/header/SecondaryMenu.tsx +3 -3
  41. package/src/components/index.tsx +0 -5
  42. package/src/components/markdownEditor/IconNamesList.ts +14 -0
  43. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.tsx +1 -1
  44. package/src/components/markdownEditor/plugins/emoji/EmojiNodeTransform.ts +1 -1
  45. package/src/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.tsx +1 -1
  46. package/src/components/markdownEditor/plugins/emoji/EmojisPlugin.tsx +1 -1
  47. package/src/components/notes/index.ts +0 -2
  48. package/src/helpers/FileHelper.ts +3 -6
  49. package/src/index.ts +0 -1
  50. package/dist/components/B1ShareModal.d.ts +0 -9
  51. package/dist/components/B1ShareModal.d.ts.map +0 -1
  52. package/dist/components/B1ShareModal.js +0 -77
  53. package/dist/components/B1ShareModal.js.map +0 -1
  54. package/dist/components/CreatePerson.d.ts +0 -15
  55. package/dist/components/CreatePerson.d.ts.map +0 -1
  56. package/dist/components/CreatePerson.js +0 -100
  57. package/dist/components/CreatePerson.js.map +0 -1
  58. package/dist/components/PersonAdd.d.ts +0 -16
  59. package/dist/components/PersonAdd.d.ts.map +0 -1
  60. package/dist/components/PersonAdd.js +0 -52
  61. package/dist/components/PersonAdd.js.map +0 -1
  62. package/dist/components/gallery/GalleryModal.d.ts +0 -9
  63. package/dist/components/gallery/GalleryModal.d.ts.map +0 -1
  64. package/dist/components/gallery/GalleryModal.js +0 -111
  65. package/dist/components/gallery/GalleryModal.js.map +0 -1
  66. package/dist/components/gallery/StockPhotos.d.ts +0 -9
  67. package/dist/components/gallery/StockPhotos.d.ts.map +0 -1
  68. package/dist/components/gallery/StockPhotos.js +0 -79
  69. package/dist/components/gallery/StockPhotos.js.map +0 -1
  70. package/dist/components/gallery/index.d.ts +0 -2
  71. package/dist/components/gallery/index.d.ts.map +0 -1
  72. package/dist/components/gallery/index.js +0 -6
  73. package/dist/components/gallery/index.js.map +0 -1
  74. package/dist/components/iconPicker/IconNamesList.d.ts.map +0 -1
  75. package/dist/components/iconPicker/IconNamesList.js +0 -2241
  76. package/dist/components/iconPicker/IconNamesList.js.map +0 -1
  77. package/dist/components/iconPicker/IconPicker.d.ts +0 -6
  78. package/dist/components/iconPicker/IconPicker.d.ts.map +0 -1
  79. package/dist/components/iconPicker/IconPicker.js +0 -142
  80. package/dist/components/iconPicker/IconPicker.js.map +0 -1
  81. package/dist/components/notes/Conversation.d.ts +0 -10
  82. package/dist/components/notes/Conversation.d.ts.map +0 -1
  83. package/dist/components/notes/Conversation.js +0 -55
  84. package/dist/components/notes/Conversation.js.map +0 -1
  85. package/dist/components/notes/Conversations.d.ts +0 -10
  86. package/dist/components/notes/Conversations.d.ts.map +0 -1
  87. package/dist/components/notes/Conversations.js +0 -54
  88. package/dist/components/notes/Conversations.js.map +0 -1
  89. package/dist/components/notes/NewConversation.d.ts +0 -12
  90. package/dist/components/notes/NewConversation.d.ts.map +0 -1
  91. package/dist/components/notes/NewConversation.js +0 -54
  92. package/dist/components/notes/NewConversation.js.map +0 -1
  93. package/dist/donationComponents/DonationPage.d.ts +0 -11
  94. package/dist/donationComponents/DonationPage.d.ts.map +0 -1
  95. package/dist/donationComponents/DonationPage.js +0 -150
  96. package/dist/donationComponents/DonationPage.js.map +0 -1
  97. package/dist/donationComponents/components/BankForm.d.ts +0 -14
  98. package/dist/donationComponents/components/BankForm.d.ts.map +0 -1
  99. package/dist/donationComponents/components/BankForm.js +0 -125
  100. package/dist/donationComponents/components/BankForm.js.map +0 -1
  101. package/dist/donationComponents/components/CardForm.d.ts +0 -13
  102. package/dist/donationComponents/components/CardForm.d.ts.map +0 -1
  103. package/dist/donationComponents/components/CardForm.js +0 -122
  104. package/dist/donationComponents/components/CardForm.js.map +0 -1
  105. package/dist/donationComponents/components/DonationForm.d.ts +0 -15
  106. package/dist/donationComponents/components/DonationForm.d.ts.map +0 -1
  107. package/dist/donationComponents/components/DonationForm.js +0 -200
  108. package/dist/donationComponents/components/DonationForm.js.map +0 -1
  109. package/dist/donationComponents/components/FundDonation.d.ts +0 -12
  110. package/dist/donationComponents/components/FundDonation.d.ts.map +0 -1
  111. package/dist/donationComponents/components/FundDonation.js +0 -32
  112. package/dist/donationComponents/components/FundDonation.js.map +0 -1
  113. package/dist/donationComponents/components/FundDonations.d.ts +0 -11
  114. package/dist/donationComponents/components/FundDonations.d.ts.map +0 -1
  115. package/dist/donationComponents/components/FundDonations.js +0 -33
  116. package/dist/donationComponents/components/FundDonations.js.map +0 -1
  117. package/dist/donationComponents/components/NonAuthDonation.d.ts +0 -12
  118. package/dist/donationComponents/components/NonAuthDonation.d.ts.map +0 -1
  119. package/dist/donationComponents/components/NonAuthDonation.js +0 -27
  120. package/dist/donationComponents/components/NonAuthDonation.js.map +0 -1
  121. package/dist/donationComponents/components/NonAuthDonationInner.d.ts +0 -12
  122. package/dist/donationComponents/components/NonAuthDonationInner.d.ts.map +0 -1
  123. package/dist/donationComponents/components/NonAuthDonationInner.js +0 -276
  124. package/dist/donationComponents/components/NonAuthDonationInner.js.map +0 -1
  125. package/dist/donationComponents/components/PaymentMethods.d.ts +0 -14
  126. package/dist/donationComponents/components/PaymentMethods.d.ts.map +0 -1
  127. package/dist/donationComponents/components/PaymentMethods.js +0 -86
  128. package/dist/donationComponents/components/PaymentMethods.js.map +0 -1
  129. package/dist/donationComponents/components/RecurringDonations.d.ts +0 -10
  130. package/dist/donationComponents/components/RecurringDonations.d.ts.map +0 -1
  131. package/dist/donationComponents/components/RecurringDonations.js +0 -93
  132. package/dist/donationComponents/components/RecurringDonations.js.map +0 -1
  133. package/dist/donationComponents/components/RecurringDonationsEdit.d.ts +0 -11
  134. package/dist/donationComponents/components/RecurringDonationsEdit.d.ts.map +0 -1
  135. package/dist/donationComponents/components/RecurringDonationsEdit.js +0 -66
  136. package/dist/donationComponents/components/RecurringDonationsEdit.js.map +0 -1
  137. package/dist/donationComponents/components/index.d.ts +0 -10
  138. package/dist/donationComponents/components/index.d.ts.map +0 -1
  139. package/dist/donationComponents/components/index.js +0 -22
  140. package/dist/donationComponents/components/index.js.map +0 -1
  141. package/dist/donationComponents/index.d.ts +0 -4
  142. package/dist/donationComponents/index.d.ts.map +0 -1
  143. package/dist/donationComponents/index.js +0 -10
  144. package/dist/donationComponents/index.js.map +0 -1
  145. package/dist/donationComponents/modals/DonationPreviewModal.d.ts +0 -15
  146. package/dist/donationComponents/modals/DonationPreviewModal.d.ts.map +0 -1
  147. package/dist/donationComponents/modals/DonationPreviewModal.js +0 -33
  148. package/dist/donationComponents/modals/DonationPreviewModal.js.map +0 -1
  149. package/src/components/B1ShareModal.tsx +0 -104
  150. package/src/components/CreatePerson.tsx +0 -135
  151. package/src/components/PersonAdd.tsx +0 -81
  152. package/src/components/gallery/GalleryModal.tsx +0 -139
  153. package/src/components/gallery/StockPhotos.tsx +0 -75
  154. package/src/components/gallery/index.ts +0 -1
  155. package/src/components/iconPicker/IconNamesList.ts +0 -2240
  156. package/src/components/iconPicker/IconPicker.tsx +0 -160
  157. package/src/components/notes/Conversation.tsx +0 -84
  158. package/src/components/notes/Conversations.tsx +0 -60
  159. package/src/components/notes/NewConversation.tsx +0 -80
  160. package/src/donationComponents/DonationPage.tsx +0 -215
  161. package/src/donationComponents/components/BankForm.tsx +0 -161
  162. package/src/donationComponents/components/CardForm.tsx +0 -106
  163. package/src/donationComponents/components/DonationForm.tsx +0 -255
  164. package/src/donationComponents/components/FundDonation.tsx +0 -58
  165. package/src/donationComponents/components/FundDonations.tsx +0 -44
  166. package/src/donationComponents/components/NonAuthDonation.tsx +0 -33
  167. package/src/donationComponents/components/NonAuthDonationInner.tsx +0 -295
  168. package/src/donationComponents/components/PaymentMethods.tsx +0 -137
  169. package/src/donationComponents/components/RecurringDonations.tsx +0 -123
  170. package/src/donationComponents/components/RecurringDonationsEdit.tsx +0 -95
  171. package/src/donationComponents/components/index.tsx +0 -9
  172. package/src/donationComponents/index.ts +0 -3
  173. package/src/donationComponents/modals/DonationPreviewModal.tsx +0 -68
  174. /package/dist/components/{iconPicker → markdownEditor}/IconNamesList.d.ts +0 -0
@@ -1,161 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { FormControl, Grid, InputLabel, MenuItem, Select, SelectChangeEvent, TextField } from "@mui/material"
5
- import { useStripe } from "@stripe/react-stripe-js";
6
- import { InputBox, ErrorMessages } from "../../components";
7
- import { ApiHelper, Locale } from "../../helpers";
8
- import { PersonInterface, StripePaymentMethod, PaymentMethodInterface, StripeBankAccountInterface, StripeBankAccountUpdateInterface, StripeBankAccountVerifyInterface } from "@churchapps/helpers";
9
-
10
- interface Props { bank: StripePaymentMethod, showVerifyForm: boolean, customerId: string, person: PersonInterface, setMode: any, deletePayment: any, updateList: (message?: string) => void }
11
-
12
- export const BankForm: React.FC<Props> = (props) => {
13
- const stripe = useStripe();
14
- const [bankAccount, setBankAccount] = React.useState<StripeBankAccountInterface>({ account_holder_name: props.bank.account_holder_name, account_holder_type: props.bank.account_holder_type, country: "US", currency: "usd" } as StripeBankAccountInterface);
15
- const [paymentMethod] = React.useState<PaymentMethodInterface>({ customerId: props.customerId, personId: props.person.id, email: props.person.contactInfo.email, name: props.person.name.display });
16
- const [updateBankData] = React.useState<StripeBankAccountUpdateInterface>({ paymentMethodId: props.bank.id, customerId: props.customerId, personId: props.person.id, bankData: { account_holder_name: props.bank.account_holder_name, account_holder_type: props.bank.account_holder_type } } as StripeBankAccountUpdateInterface);
17
- const [verifyBankData, setVerifyBankData] = React.useState<StripeBankAccountVerifyInterface>({ paymentMethodId: props.bank.id, customerId: props.customerId, amountData: { amounts: [] } });
18
- const [showSave, setShowSave] = React.useState<boolean>(true);
19
- const [errorMessage, setErrorMessage] = React.useState<string>(null);
20
- const saveDisabled = () => { }
21
- const handleCancel = () => { props.setMode("display"); }
22
- const handleDelete = () => { props.deletePayment(); }
23
- const handleSave = () => {
24
- setShowSave(false);
25
- if (props.showVerifyForm) verifyBank();
26
- else props.bank.id ? updateBank() : createBank();
27
- }
28
-
29
- const createBank = async () => {
30
- if (!bankAccount.routing_number || !bankAccount.account_number) setErrorMessage(Locale.label("donation.bankForm.validate.accountNumber"))
31
- else {
32
- await stripe.createToken("bank_account", bankAccount).then(response => {
33
- if (response?.error?.message) setErrorMessage(response.error.message);
34
- else {
35
- const pm = { ...paymentMethod };
36
- pm.id = response.token.id;
37
- ApiHelper.post("/paymentmethods/addbankaccount", pm, "GivingApi").then(result => {
38
- if (result?.raw?.message) setErrorMessage(result.raw.message);
39
- else {
40
- props.updateList(Locale.label("donation.bankForm.added"));
41
- props.setMode("display");
42
- }
43
- });
44
- }
45
- });
46
- }
47
- setShowSave(true);
48
- }
49
-
50
- const updateBank = () => {
51
- if (bankAccount.account_holder_name === "") setErrorMessage(Locale.label("donation.bankForm.validate.holderName"));
52
- else {
53
- let bank = { ...updateBankData };
54
- bank.bankData.account_holder_name = bankAccount.account_holder_name;
55
- bank.bankData.account_holder_type = bankAccount.account_holder_type;
56
- ApiHelper.post("/paymentmethods/updatebank", bank, "GivingApi").then(response => {
57
- if (response?.raw?.message) setErrorMessage(response.raw.message);
58
- else {
59
- props.updateList(Locale.label("donation.bankForm.updated"));
60
- props.setMode("display");
61
- }
62
- });
63
- }
64
- setShowSave(true);
65
- }
66
-
67
- const verifyBank = () => {
68
- const amounts = verifyBankData?.amountData?.amounts;
69
- if (amounts && amounts.length === 2 && amounts[0] !== "" && amounts[1] !== "") {
70
- ApiHelper.post("/paymentmethods/verifyBank", verifyBankData, "GivingApi").then(response => {
71
- if (response?.raw?.message) setErrorMessage(response.raw.message);
72
- else {
73
- props.updateList(Locale.label("donation.bankForm.verified"));
74
- props.setMode("display");
75
- }
76
- });
77
- }
78
- else setErrorMessage("Both deposit amounts are required.");
79
- setShowSave(true);
80
- }
81
-
82
- const getHeaderText = () => props.bank.id
83
- ? `${props.bank.name.toUpperCase()} ****${props.bank.last4}`
84
- : "Add New Bank Account"
85
-
86
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
87
- const bankData = { ...bankAccount };
88
- const inputData = { [e.target.name]: e.target.value };
89
- setBankAccount({ ...bankData, ...inputData });
90
- setShowSave(true);
91
- }
92
-
93
- const handleKeyPress = (e: React.KeyboardEvent<any>) => {
94
- const pattern = /^\d+$/;
95
- if (!pattern.test(e.key)) e.preventDefault();
96
- }
97
-
98
- const handleVerify = (e: React.ChangeEvent<HTMLInputElement>) => {
99
- const verifyData = { ...verifyBankData };
100
- if (e.currentTarget.name === "amount1") verifyData.amountData.amounts[0] = e.currentTarget.value;
101
- if (e.currentTarget.name === "amount2") verifyData.amountData.amounts[1] = e.currentTarget.value;
102
- setVerifyBankData(verifyData);
103
- }
104
-
105
- const getForm = () => {
106
- if (props.showVerifyForm) {
107
- return (<>
108
- <p>{Locale.label("donation.bankForm.twoDeposits")}</p>
109
- <Grid container columnSpacing={2}>
110
- <Grid size={{ xs: 12, md: 6 }}>
111
- <TextField fullWidth aria-label="amount1" label={Locale.label("donation.bankForm.firstDeposit")} name="amount1" placeholder="00" inputProps={{ maxLength: 2 }} onChange={handleVerify} onKeyPress={handleKeyPress} />
112
- </Grid>
113
- <Grid size={{ xs: 12, md: 6 }}>
114
- <TextField fullWidth aria-label="amount2" label={Locale.label("donation.bankForm.secondDeposit")} name="amount2" placeholder="00" inputProps={{ maxLength: 2 }} onChange={handleVerify} onKeyPress={handleKeyPress} />
115
- </Grid>
116
- </Grid>
117
- </>);
118
-
119
- } else {
120
- let accountDetails = <></>
121
- if (!props.bank.id) accountDetails = (
122
- <Grid container spacing={3}>
123
- <Grid size={{ xs: 12, md: 6 }} style={{ marginBottom: "20px" }}>
124
- <TextField fullWidth label={Locale.label("donation.bankForm.routingNumber")} type="number" name="routing_number" aria-label="routing-number" placeholder="Routing Number" className="form-control" onChange={handleChange} />
125
- </Grid>
126
- <Grid size={{ xs: 12, md: 6 }} style={{ marginBottom: "20px" }}>
127
- <TextField fullWidth label={Locale.label("donation.bankForm.accountNumber")} type="number" name="account_number" aria-label="account-number" placeholder="Account Number" className="form-control" onChange={handleChange} />
128
- </Grid>
129
- </Grid>
130
- );
131
- return (<>
132
- <Grid container spacing={3}>
133
- <Grid size={{ xs: 12, md: 6 }} style={{ marginBottom: "20px" }}>
134
- <TextField fullWidth label="Account Holder Name" name="account_holder_name" required aria-label="account-holder-name" placeholder="Account Holder Name" value={bankAccount.account_holder_name} className="form-control" onChange={handleChange} />
135
- </Grid>
136
- <Grid size={{ xs: 12, md: 6 }} style={{ marginBottom: "20px" }}>
137
- <FormControl fullWidth>
138
- <InputLabel>{Locale.label("donation.bankForm.name")}</InputLabel>
139
- <Select label={Locale.label("donation.bankForm.name")} name="account_holder_type" aria-label="account-holder-type" value={bankAccount.account_holder_type} onChange={handleChange}>
140
- <MenuItem value="individual">{Locale.label("donation.bankForm.individual")}</MenuItem>
141
- <MenuItem value="company">{Locale.label("donation.bankForm.company")}</MenuItem>
142
- </Select>
143
- </FormControl>
144
- </Grid>
145
- </Grid>
146
- {accountDetails}
147
- </>);
148
- }
149
- }
150
-
151
- return (
152
- <InputBox headerIcon="volunteer_activism" headerText={getHeaderText()} ariaLabelSave="save-button" ariaLabelDelete="delete-button" cancelFunction={handleCancel} saveFunction={showSave ? handleSave : saveDisabled} deleteFunction={props.bank.id && !props.showVerifyForm ? handleDelete : undefined}>
153
- {errorMessage && <ErrorMessages errors={[errorMessage]}></ErrorMessages>}
154
- <div>
155
- {!props.bank.id && <p>{Locale.label("donation.bankForm.needVerified")}</p>}
156
- {getForm()}
157
- </div>
158
- </InputBox>
159
- );
160
-
161
- }
@@ -1,106 +0,0 @@
1
- "use client";
2
-
3
- import React, { useEffect } from "react";
4
- import { Grid, TextField } from "@mui/material"
5
- import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
6
- import { InputBox, ErrorMessages } from "../../components";
7
- import { ApiHelper, Locale } from "../../helpers";
8
- import { PersonInterface, StripePaymentMethod, PaymentMethodInterface, StripeCardUpdateInterface } from "@churchapps/helpers";
9
-
10
- interface Props { card: StripePaymentMethod, customerId: string, person: PersonInterface, setMode: any, deletePayment: any, updateList: (message: string) => void }
11
-
12
- export const CardForm: React.FC<Props> = (props) => {
13
- const stripe = useStripe();
14
- const elements = useElements();
15
- const formStyling = { style: { base: { fontSize: "18px" } } };
16
- const [showSave, setShowSave] = React.useState(true);
17
- const [paymentMethod] = React.useState<PaymentMethodInterface>({ id: props.card.id, customerId: props.customerId, personId: props.person.id, email: props.person.contactInfo.email, name: props.person.name.display });
18
- const [cardUpdate, setCardUpdate] = React.useState<StripeCardUpdateInterface>({ personId: props.person.id, paymentMethodId: props.card.id, cardData: { card: {} } } as StripeCardUpdateInterface);
19
- const [errorMessage, setErrorMessage] = React.useState<string>(null);
20
- const handleCancel = () => { props.setMode("display"); }
21
- const handleSave = () => { setShowSave(false); props.card.id ? updateCard() : createCard(); }
22
- const saveDisabled = () => { }
23
- const handleDelete = () => { props.deletePayment(); }
24
-
25
- const handleKeyPress = (e: React.KeyboardEvent<any>) => {
26
- const pattern = /^\d+$/;
27
- if (!pattern.test(e.key)) e.preventDefault();
28
- }
29
-
30
- useEffect(() => {
31
- setCardUpdate({ ...cardUpdate, cardData: { card: { exp_year: props.card?.exp_year?.toString().slice(2) || "", exp_month: props.card?.exp_month || "" } } });
32
- }, []) //eslint-disable-line
33
-
34
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
35
- const card = { ...cardUpdate };
36
- if (e.currentTarget.name === "exp_month") card.cardData.card.exp_month = e.currentTarget.value;
37
- if (e.currentTarget.name === "exp_year") card.cardData.card.exp_year = e.currentTarget.value;
38
- setCardUpdate(card);
39
- setShowSave(true);
40
- }
41
-
42
- const createCard = async () => {
43
- const cardData = elements.getElement(CardElement);
44
- const stripePM = await stripe.createPaymentMethod({
45
- type: "card",
46
- card: cardData
47
- });
48
- if (stripePM.error) {
49
- setErrorMessage(stripePM.error.message);
50
- setShowSave(true);
51
- } else {
52
- let pm = { ...paymentMethod };
53
- pm.id = stripePM.paymentMethod.id;
54
- await ApiHelper.post("/paymentmethods/addcard", pm, "GivingApi").then(result => {
55
- if (result?.raw?.message) {
56
- setErrorMessage(result.raw.message);
57
- setShowSave(true);
58
- }
59
- else {
60
- props.updateList(Locale.label("donation.cardForm.added"));
61
- props.setMode("display");
62
- }
63
- });
64
- }
65
- }
66
-
67
- const updateCard = async () => {
68
- if (!cardUpdate.cardData.card.exp_month || !cardUpdate.cardData.card.exp_year) setErrorMessage("Expiration month and year cannot be blank.");
69
- else {
70
- await ApiHelper.post("/paymentmethods/updatecard", cardUpdate, "GivingApi").then(result => {
71
- if (result?.raw?.message) {
72
- setErrorMessage(result.raw.message);
73
- setShowSave(true);
74
- }
75
- else {
76
- props.updateList(Locale.label("donation.cardForm.updated"));
77
- props.setMode("display");
78
- }
79
- });
80
- }
81
- }
82
-
83
- const getHeaderText = () => props.card.id
84
- ? `${props.card.name.toUpperCase()} ****${props.card.last4}`
85
- : Locale.label("donation.cardForm.addNew")
86
-
87
- return (
88
- <InputBox headerIcon="volunteer_activism" headerText={getHeaderText()} ariaLabelSave="save-button" ariaLabelDelete="delete-button" cancelFunction={handleCancel} saveFunction={showSave ? handleSave : saveDisabled} deleteFunction={props.card.id ? handleDelete : undefined}>
89
- {errorMessage && <ErrorMessages errors={[errorMessage]}></ErrorMessages>}
90
- <div>
91
- {!props.card.id
92
- ? <CardElement options={formStyling} />
93
- : <Grid container spacing={3}>
94
- <Grid size={{ xs: 12, md: 6 }}>
95
- <TextField fullWidth aria-label="card-exp-month" label={Locale.label("donation.cardForm.expirationMonth")} name="exp_month" value={cardUpdate.cardData.card.exp_month} placeholder="MM" inputProps={{ maxLength: 2 }} onChange={handleChange} onKeyPress={handleKeyPress} />
96
- </Grid>
97
- <Grid size={{ xs: 12, md: 6 }}>
98
- <TextField fullWidth aria-label="card-exp-year" label={Locale.label("donation.cardForm.expirationYear")} name="exp_year" value={cardUpdate.cardData.card.exp_year} placeholder="YY" inputProps={{ maxLength: 2 }} onChange={handleChange} onKeyPress={handleKeyPress} />
99
- </Grid>
100
- </Grid>
101
- }
102
- </div>
103
- </InputBox>
104
- );
105
-
106
- }
@@ -1,255 +0,0 @@
1
- "use client";
2
-
3
- /* eslint-disable multiline-ternary */
4
- import React from "react";
5
- import { Stripe } from "@stripe/stripe-js";
6
- import { InputBox, ErrorMessages } from "../../components";
7
- import { FundDonations } from ".";
8
- import { DonationPreviewModal } from "../modals/DonationPreviewModal";
9
- import { ApiHelper, CurrencyHelper, DateHelper, Locale } from "../../helpers";
10
- import { PersonInterface, StripePaymentMethod, StripeDonationInterface, FundDonationInterface, FundInterface, ChurchInterface } from "@churchapps/helpers";
11
- import { Grid, InputLabel, MenuItem, Select, TextField, FormControl, Button, SelectChangeEvent, FormControlLabel, Checkbox, FormGroup, Typography } from "@mui/material"
12
- import { DonationHelper } from "../../helpers";
13
-
14
- interface Props { person: PersonInterface, customerId: string, paymentMethods: StripePaymentMethod[], stripePromise: Promise<Stripe>, donationSuccess: (message: string) => void, church?: ChurchInterface, churchLogo?: string }
15
-
16
- export const DonationForm: React.FC<Props> = (props) => {
17
- const [errorMessage, setErrorMessage] = React.useState<string>();
18
- const [fundDonations, setFundDonations] = React.useState<FundDonationInterface[]>();
19
- const [funds, setFunds] = React.useState<FundInterface[]>([]);
20
- const [fundsTotal, setFundsTotal] = React.useState<number>(0);
21
- const [transactionFee, setTransactionFee] = React.useState<number>(0);
22
- const [payFee, setPayFee] = React.useState<number>(0);
23
- const [total, setTotal] = React.useState<number>(0);
24
- const [paymentMethodName, setPaymentMethodName] = React.useState<string>(`${props?.paymentMethods[0]?.name} ****${props?.paymentMethods[0]?.last4}`);
25
- const [donationType, setDonationType] = React.useState<string>();
26
- const [showDonationPreviewModal, setShowDonationPreviewModal] = React.useState<boolean>(false);
27
- const [interval, setInterval] = React.useState("one_month");
28
- const [gateway, setGateway] = React.useState(null);
29
- const [donation, setDonation] = React.useState<StripeDonationInterface>({
30
- id: props?.paymentMethods[0]?.id,
31
- type: props?.paymentMethods[0]?.type,
32
- customerId: props.customerId,
33
- person: {
34
- id: props.person?.id,
35
- email: props.person?.contactInfo.email,
36
- name: props.person?.name.display
37
- },
38
- amount: 0,
39
- billing_cycle_anchor: + new Date(),
40
- interval: {
41
- interval_count: 1,
42
- interval: "month"
43
- },
44
- funds: []
45
- });
46
-
47
- const loadData = () => {
48
- ApiHelper.get("/funds", "GivingApi").then(data => {
49
- setFunds(data);
50
- if (data.length) setFundDonations([{ fundId: data[0].id }]);
51
- });
52
- ApiHelper.get("/gateways", "GivingApi").then((data) => {
53
- if (data.length !== 0) setGateway(data[0]);
54
- });
55
- }
56
-
57
- const handleKeyDown = (e: React.KeyboardEvent<any>) => { if (e.key === "Enter") { e.preventDefault(); handleSave(); } }
58
-
59
- const handleCheckChange = (e: React.SyntheticEvent<Element, Event>, checked: boolean) => {
60
- let d = { ...donation } as StripeDonationInterface;
61
- d.amount = checked ? fundsTotal + transactionFee : fundsTotal;
62
- let showFee = checked ? transactionFee : 0;
63
- setTotal(d.amount);
64
- setPayFee(showFee);
65
- setDonation(d);
66
- }
67
-
68
- const handleAutoPayFee = () => {
69
- let d = { ...donation } as StripeDonationInterface;
70
- d.amount = fundsTotal + transactionFee;
71
- let showFee = transactionFee;
72
- setTotal(d.amount);
73
- setPayFee(showFee);
74
- setDonation(d);
75
- }
76
-
77
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
78
- setErrorMessage(null);
79
- let d = { ...donation } as StripeDonationInterface;
80
- let value = e.target.value;
81
- switch (e.target.name) {
82
- case "method":
83
- d.id = value;
84
- let pm = props.paymentMethods.find(pm => pm.id === value);
85
- d.type = pm.type;
86
- setPaymentMethodName(`${pm.name} ****${pm.last4}`);
87
- break;
88
- case "type": setDonationType(value); break;
89
- case "date": d.billing_cycle_anchor = + new Date(value); break;
90
- case "interval":
91
- setInterval(value);
92
- d.interval = DonationHelper.getInterval(value);
93
- break;
94
- case "notes": d.notes = value; break;
95
- case "transaction-fee":
96
- const element = e.target as HTMLInputElement
97
- d.amount = element.checked ? fundsTotal + transactionFee : fundsTotal;
98
- let showFee = element.checked ? transactionFee : 0;
99
- setTotal(d.amount);
100
- setPayFee(showFee);
101
- }
102
- setDonation(d);
103
- }
104
-
105
- const handleCancel = () => { setDonationType(null); }
106
- const handleSave = () => {
107
- if (donation.amount < .5) setErrorMessage(Locale.label("donation.donationForm.tooLow"));
108
- else setShowDonationPreviewModal(true);
109
- }
110
- const handleDonationSelect = (type: string) => {
111
- let dt = donationType === type ? null : type;
112
- setDonationType(dt);
113
- }
114
-
115
- const makeDonation = async (message: string) => {
116
- let results;
117
-
118
- const churchObj = {
119
- name: props?.church?.name,
120
- subDomain: props?.church?.subDomain,
121
- churchURL: typeof window !== "undefined" && window.location.origin,
122
- logo: props?.churchLogo
123
- }
124
-
125
- if (donationType === "once") results = await ApiHelper.post("/donate/charge/", {...donation, church: churchObj }, "GivingApi");
126
- if (donationType === "recurring") results = await ApiHelper.post("/donate/subscribe/", {...donation, church: churchObj }, "GivingApi");
127
-
128
- if (results?.status === "succeeded" || results?.status === "pending" || results?.status === "active") {
129
- setShowDonationPreviewModal(false);
130
- setDonationType(null);
131
- props.donationSuccess(message);
132
- }
133
- if (results?.raw?.message) {
134
- setShowDonationPreviewModal(false);
135
- setErrorMessage(Locale.label("donation.common.error") + ": " + results?.raw?.message);
136
- }
137
- }
138
-
139
- const handleFundDonationsChange = async (fd: FundDonationInterface[]) => {
140
- setErrorMessage(null);
141
- setFundDonations(fd);
142
- let totalAmount = 0;
143
- let selectedFunds: any = [];
144
- for (const fundDonation of fd) {
145
- totalAmount += fundDonation.amount || 0;
146
- let fund = funds.find((fund: FundInterface) => fund.id === fundDonation.fundId);
147
- selectedFunds.push({ id: fundDonation.fundId, amount: fundDonation.amount || 0, name: fund.name });
148
- }
149
- let d = { ...donation };
150
- d.amount = totalAmount;
151
- d.funds = selectedFunds;
152
- setFundsTotal(totalAmount);
153
-
154
- const fee = await getTransactionFee(totalAmount);
155
- setTransactionFee(fee);
156
-
157
- if (gateway && gateway.payFees === true) {
158
- d.amount = totalAmount + fee;
159
- setPayFee(fee);
160
- }
161
- setTotal(d.amount);
162
- setDonation(d)
163
- }
164
-
165
- const getTransactionFee = async (amount: number) => {
166
- if (amount > 0) {
167
- let dt: string = "";
168
- if (donation.type === "card") dt = "creditCard";
169
- if (donation.type === "bank") dt = "ach";
170
- try {
171
- const response = await ApiHelper.post("/donate/fee?churchId=" + props?.church?.id, { type: dt, amount }, "GivingApi");
172
- return response.calculatedFee;
173
- } catch (error) {
174
- console.log("Error calculating transaction fee: ", error);
175
- return 0;
176
- }
177
- } else {
178
- return 0;
179
- }
180
- }
181
-
182
- React.useEffect(loadData, [props.person?.id]);
183
- // eslint-disable-next-line react-hooks/exhaustive-deps
184
- // React.useEffect(() => { gateway && gateway.payFees === true && handleAutoPayFee() }, [fundDonations]);
185
-
186
- if (!funds.length || !props?.paymentMethods[0]?.id) return null;
187
- else return (
188
- <>
189
- <DonationPreviewModal show={showDonationPreviewModal} onHide={() => setShowDonationPreviewModal(false)} handleDonate={makeDonation} donation={donation} donationType={donationType} payFee={payFee} paymentMethodName={paymentMethodName} funds={funds} />
190
- <InputBox id="donationBox" aria-label="donation-box" headerIcon="volunteer_activism" headerText={Locale.label("donation.donationForm.donate")} ariaLabelSave="save-button" cancelFunction={donationType ? handleCancel : undefined} saveFunction={donationType ? handleSave : undefined} saveText={Locale.label("donation.donationForm.preview")}>
191
- <Grid container spacing={3}>
192
- <Grid size={{ xs: 12, md: 6 }}>
193
- <Button aria-label="single-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "once" ? "contained" : "outlined"} onClick={() => handleDonationSelect("once")}>{Locale.label("donation.donationForm.make")}</Button>
194
- </Grid>
195
- <Grid size={{ xs: 12, md: 6 }}>
196
- <Button aria-label="recurring-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "recurring" ? "contained" : "outlined"} onClick={() => handleDonationSelect("recurring")}>{Locale.label("donation.donationForm.makeRecurring")}</Button>
197
- </Grid>
198
- </Grid>
199
- {donationType
200
- && <div style={{ marginTop: "20px" }}>
201
- <Grid container spacing={3}>
202
- <Grid size={12}>
203
- <FormControl fullWidth>
204
- <InputLabel>{Locale.label("donation.donationForm.method")}</InputLabel>
205
- <Select label={Locale.label("donation.donationForm.method")} name="method" aria-label="method" value={donation.id} className="capitalize" onChange={handleChange}>
206
- {props.paymentMethods.map((paymentMethod: any, i: number) => <MenuItem key={i} value={paymentMethod.id}>{paymentMethod.name} ****{paymentMethod.last4}</MenuItem>)}
207
- </Select>
208
- </FormControl>
209
- </Grid>
210
- </Grid>
211
- {donationType === "recurring"
212
- && <Grid container spacing={3} style={{marginTop:10}}>
213
- <Grid size={{ xs: 12, md: 6 }}>
214
- <TextField fullWidth name="date" type="date" aria-label="date" label={Locale.label("donation.donationForm.startDate")} value={DateHelper.formatHtml5Date(new Date(donation.billing_cycle_anchor))} onChange={handleChange} onKeyDown={handleKeyDown} />
215
- </Grid>
216
- <Grid size={{ xs: 12, md: 6 }}>
217
- <FormControl fullWidth>
218
- <InputLabel>{Locale.label("donation.donationForm.frequency")}</InputLabel>
219
- <Select label={Locale.label("donation.donationForm.frequency")} name="interval" aria-label="interval" value={interval} onChange={handleChange}>
220
- <MenuItem value="one_week">{Locale.label("donation.donationForm.weekly")}</MenuItem>
221
- <MenuItem value="two_week">{Locale.label("donation.donationForm.biWeekly")}</MenuItem>
222
- <MenuItem value="one_month">{Locale.label("donation.donationForm.monthly")}</MenuItem>
223
- <MenuItem value="three_month">{Locale.label("donation.donationForm.quarterly")}</MenuItem>
224
- <MenuItem value="one_year">{Locale.label("donation.donationForm.annually")}</MenuItem>
225
- </Select>
226
- </FormControl>
227
- </Grid>
228
- </Grid>
229
- }
230
- <div className="form-group">
231
- {funds && fundDonations
232
- && <>
233
- <h4>{Locale.label("donation.donationForm.fund")}</h4>
234
- <FundDonations fundDonations={fundDonations} funds={funds} updatedFunction={handleFundDonationsChange} />
235
- </>
236
- }
237
- {fundsTotal > 0
238
- && <>
239
- {(gateway && gateway.payFees === true) ? <Typography fontSize={14} fontStyle="italic">*{Locale.label("donation.donationForm.fees").replace("{}", CurrencyHelper.formatCurrency(transactionFee))}</Typography> : (
240
- <FormGroup>
241
- <FormControlLabel control={<Checkbox />} name="transaction-fee" label={Locale.label("donation.donationForm.cover").replace("{}", CurrencyHelper.formatCurrency(transactionFee))} onChange={handleCheckChange} />
242
- </FormGroup>
243
- )}
244
- <p>{Locale.label("donation.donationForm.total")}: ${total}</p>
245
- </>
246
- }
247
- <TextField fullWidth label={Locale.label("donation.donationForm.notes")} multiline aria-label="note" name="notes" value={donation.notes || ""} onChange={handleChange} onKeyDown={handleKeyDown} />
248
- </div>
249
- {errorMessage && <ErrorMessages errors={[errorMessage]}></ErrorMessages>}
250
- </div>
251
- }
252
- </InputBox>
253
- </>
254
- );
255
- }
@@ -1,58 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { FundDonationInterface, FundInterface } from "@churchapps/helpers";
5
- import { FormControl, Grid, InputLabel, MenuItem, Select, SelectChangeEvent, TextField } from "@mui/material"
6
- import { Locale } from "../../helpers";
7
-
8
- interface Props {
9
- fundDonation: FundDonationInterface,
10
- funds: FundInterface[],
11
- index: number,
12
- updatedFunction: (fundDonation: FundDonationInterface, index: number) => void,
13
- params?: any,
14
- }
15
-
16
- export const FundDonation: React.FC<Props> = (props) => {
17
-
18
- const getOptions = () => {
19
- let result = [];
20
- for (let i = 0; i < props.funds.length; i++) {
21
- const getDisabled = (props?.params?.fundId && props.params.fundId !== "") ? props.params.fundId !== props.funds[i].id : false;
22
- result.push(<MenuItem key={i} value={props.funds[i].id} disabled={getDisabled}>{props.funds[i].name}</MenuItem>);
23
- }
24
- return result;
25
- }
26
-
27
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
28
- let fd = { ...props.fundDonation }
29
- switch (e.target.name) {
30
- case "amount":
31
- fd.amount = parseFloat(e.target.value.replace("$", "").replace(",", ""));
32
- break;
33
- case "fund":
34
- fd.fundId = e.target.value;
35
- break;
36
- }
37
- props.updatedFunction(fd, props.index);
38
- }
39
-
40
- return (
41
- <>
42
- <Grid container spacing={3}>
43
- <Grid size={{ xs: 12, md: 6 }}>
44
- <TextField fullWidth name="amount" label={Locale.label("donation.fundDonations.amount")} type="number" disabled={props.params?.amount && props.params.amount !== ""} aria-label="amount" lang="en-150" value={props.fundDonation.amount || ""} onChange={handleChange} />
45
- </Grid>
46
- <Grid size={{ xs: 12, md: 6 }}>
47
- <FormControl fullWidth>
48
- <InputLabel>{Locale.label("donation.fundDonations.fund")}</InputLabel>
49
- <Select fullWidth label={Locale.label("donation.fundDonations.fund")} name="fund" aria-label="fund" value={props.fundDonation.fundId} onChange={handleChange}>
50
- {getOptions()}
51
- </Select>
52
- </FormControl>
53
- </Grid>
54
- </Grid>
55
- </>
56
- );
57
- }
58
-
@@ -1,44 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { FundDonation } from ".";
5
- import { FundDonationInterface, FundInterface } from "@churchapps/helpers";
6
- import { Locale } from "../../helpers";
7
-
8
- interface Props { fundDonations: FundDonationInterface[], funds: FundInterface[], params?: any, updatedFunction: (fundDonations: FundDonationInterface[]) => void }
9
-
10
- export const FundDonations: React.FC<Props> = (props) => {
11
- const handleUpdated = (fundDonation: FundDonationInterface, index: number) => {
12
- let fundDonations = [...props.fundDonations];
13
- fundDonations[index] = fundDonation;
14
- props.updatedFunction(fundDonations);
15
- }
16
-
17
- const addRow = (e: React.MouseEvent) => {
18
- e.preventDefault();
19
- let fundDonations = [...props.fundDonations];
20
- let fd = { fundId: props.funds[0].id } as FundDonationInterface;
21
- fundDonations.push(fd);
22
- props.updatedFunction(fundDonations);
23
- }
24
-
25
- const getRows = () => {
26
- let result = [];
27
- for (let i = 0; i < props.fundDonations.length; i++) {
28
- let fd = props.fundDonations[i];
29
- result.push(<FundDonation fundDonation={fd} funds={props.funds} updatedFunction={handleUpdated} params={props?.params} key={i} index={i} />)
30
- }
31
-
32
- return result;
33
- }
34
-
35
- return (
36
- <>
37
- {getRows()}
38
- {(!props?.params?.fundId || props?.params?.fundId === "") &&
39
- <a href="about:blank" aria-label="add-fund-donation" className="text-decoration" style={{ display: "block", marginBottom: "15px" }} onClick={addRow}>{Locale.label("donation.fundDonations.addMore")}</a>
40
- }
41
- </>
42
- );
43
- }
44
-
@@ -1,33 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { Elements } from "@stripe/react-stripe-js";
5
- import { loadStripe, Stripe } from "@stripe/stripe-js";
6
- import { ApiHelper } from "../../helpers";
7
- import { NonAuthDonationInner } from "./NonAuthDonationInner";
8
- import { PaperProps } from "@mui/material";
9
-
10
- interface Props { churchId: string, mainContainerCssProps?: PaperProps, showHeader?: boolean, recaptchaSiteKey: string, churchLogo?: string }
11
-
12
- export const NonAuthDonation: React.FC<Props> = ({ mainContainerCssProps, showHeader, ...props }) => {
13
- const [stripePromise, setStripe] = React.useState<Promise<Stripe>>(null);
14
-
15
- const init = () => {
16
- ApiHelper.get("/gateways/churchId/" + props.churchId, "GivingApi").then(data => {
17
- if (data.length && data[0]?.publicKey) {
18
- setStripe(loadStripe(data[0].publicKey));
19
- }
20
- });
21
- }
22
-
23
- React.useEffect(init, []); //eslint-disable-line
24
-
25
- return (
26
- <>
27
- <Elements stripe={stripePromise}>
28
- <NonAuthDonationInner churchId={props.churchId} mainContainerCssProps={mainContainerCssProps} showHeader={showHeader} recaptchaSiteKey={props.recaptchaSiteKey} churchLogo={props?.churchLogo} />
29
- </Elements>
30
- </>
31
- );
32
- }
33
-