@churchapps/apphelper 0.0.14 → 0.1.1

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 (292) hide show
  1. package/.eslintignore +3 -3
  2. package/.eslintrc.json +22 -22
  3. package/LICENSE +21 -21
  4. package/README.md +22 -16
  5. package/dist/components/FormSubmissionEdit.d.ts.map +1 -1
  6. package/dist/components/FormSubmissionEdit.js +9 -2
  7. package/dist/components/FormSubmissionEdit.js.map +1 -1
  8. package/dist/components/QuestionEdit.d.ts.map +1 -1
  9. package/dist/components/QuestionEdit.js +2 -1
  10. package/dist/components/QuestionEdit.js.map +1 -1
  11. package/dist/components/iconPicker/IconNamesList.d.ts.map +1 -0
  12. package/dist/components/iconPicker/IconNamesList.js.map +1 -0
  13. package/dist/components/iconPicker/IconPicker.d.ts.map +1 -0
  14. package/dist/components/iconPicker/IconPicker.js.map +1 -0
  15. package/dist/components/index.d.ts +2 -1
  16. package/dist/components/index.d.ts.map +1 -1
  17. package/dist/components/index.js +4 -2
  18. package/dist/components/index.js.map +1 -1
  19. package/dist/components/markdownEditor/editor.css +787 -787
  20. package/dist/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  21. package/dist/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  22. package/dist/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  23. package/dist/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  24. package/dist/components/markdownEditor/images/icons/code.svg +2 -2
  25. package/dist/components/markdownEditor/images/icons/journal-code.svg +4 -4
  26. package/dist/components/markdownEditor/images/icons/journal-text.svg +4 -4
  27. package/dist/components/markdownEditor/images/icons/justify.svg +2 -2
  28. package/dist/components/markdownEditor/images/icons/link.svg +3 -3
  29. package/dist/components/markdownEditor/images/icons/list-ol.svg +3 -3
  30. package/dist/components/markdownEditor/images/icons/list-ul.svg +2 -2
  31. package/dist/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  32. package/dist/components/markdownEditor/images/icons/text-center.svg +2 -2
  33. package/dist/components/markdownEditor/images/icons/text-left.svg +2 -2
  34. package/dist/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  35. package/dist/components/markdownEditor/images/icons/text-right.svg +2 -2
  36. package/dist/components/markdownEditor/images/icons/type-bold.svg +2 -2
  37. package/dist/components/markdownEditor/images/icons/type-h1.svg +2 -2
  38. package/dist/components/markdownEditor/images/icons/type-h2.svg +2 -2
  39. package/dist/components/markdownEditor/images/icons/type-h3.svg +2 -2
  40. package/dist/components/markdownEditor/images/icons/type-h4.svg +12 -12
  41. package/dist/components/markdownEditor/images/icons/type-italic.svg +2 -2
  42. package/dist/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  43. package/dist/components/markdownEditor/images/icons/type-underline.svg +2 -2
  44. package/dist/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.js +1 -1
  45. package/dist/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.js.map +1 -1
  46. package/dist/components/markdownEditor/plugins/emoji/EmojiNodeTransform.js +1 -1
  47. package/dist/components/markdownEditor/plugins/emoji/EmojiNodeTransform.js.map +1 -1
  48. package/dist/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.js +1 -1
  49. package/dist/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.js.map +1 -1
  50. package/dist/components/markdownEditor/plugins/emoji/EmojisPlugin.js +1 -1
  51. package/dist/components/markdownEditor/plugins/emoji/EmojisPlugin.js.map +1 -1
  52. package/dist/components/notes/Notes.d.ts +1 -0
  53. package/dist/components/notes/Notes.d.ts.map +1 -1
  54. package/dist/components/notes/Notes.js +18 -1
  55. package/dist/components/notes/Notes.js.map +1 -1
  56. package/dist/components/wrapper/AppList.d.ts.map +1 -0
  57. package/dist/components/wrapper/AppList.js.map +1 -0
  58. package/dist/components/wrapper/ChurchList.d.ts.map +1 -0
  59. package/dist/components/wrapper/ChurchList.js.map +1 -0
  60. package/dist/components/wrapper/Drawers.d.ts +22 -0
  61. package/dist/components/wrapper/Drawers.d.ts.map +1 -0
  62. package/dist/components/wrapper/Drawers.js +51 -0
  63. package/dist/components/wrapper/Drawers.js.map +1 -0
  64. package/dist/components/wrapper/NavItem.d.ts.map +1 -0
  65. package/dist/components/wrapper/NavItem.js.map +1 -0
  66. package/dist/components/wrapper/NewPrivateMessage.d.ts.map +1 -0
  67. package/dist/components/wrapper/NewPrivateMessage.js.map +1 -0
  68. package/dist/components/wrapper/NotificationMenu.d.ts +14 -0
  69. package/dist/components/wrapper/NotificationMenu.d.ts.map +1 -0
  70. package/dist/components/wrapper/NotificationMenu.js +60 -0
  71. package/dist/components/wrapper/NotificationMenu.js.map +1 -0
  72. package/dist/components/wrapper/Notifications.d.ts +8 -0
  73. package/dist/components/wrapper/Notifications.d.ts.map +1 -0
  74. package/dist/components/wrapper/Notifications.js +67 -0
  75. package/dist/components/wrapper/Notifications.js.map +1 -0
  76. package/dist/components/wrapper/PrivateMessageDetails.d.ts.map +1 -0
  77. package/dist/components/{material → wrapper}/PrivateMessageDetails.js +1 -1
  78. package/dist/components/wrapper/PrivateMessageDetails.js.map +1 -0
  79. package/dist/components/wrapper/PrivateMessages.d.ts.map +1 -0
  80. package/dist/components/{material → wrapper}/PrivateMessages.js +1 -1
  81. package/dist/components/wrapper/PrivateMessages.js.map +1 -0
  82. package/dist/components/wrapper/SiteWrapper.d.ts.map +1 -0
  83. package/dist/components/{material → wrapper}/SiteWrapper.js +13 -49
  84. package/dist/components/wrapper/SiteWrapper.js.map +1 -0
  85. package/dist/components/wrapper/TabPanel.d.ts +9 -0
  86. package/dist/components/wrapper/TabPanel.d.ts.map +1 -0
  87. package/dist/components/wrapper/TabPanel.js +24 -0
  88. package/dist/components/wrapper/TabPanel.js.map +1 -0
  89. package/dist/components/wrapper/UserMenu.d.ts.map +1 -0
  90. package/dist/components/{material → wrapper}/UserMenu.js +14 -31
  91. package/dist/components/wrapper/UserMenu.js.map +1 -0
  92. package/dist/components/{material → wrapper}/index.d.ts +0 -1
  93. package/dist/components/wrapper/index.d.ts.map +1 -0
  94. package/dist/components/{material → wrapper}/index.js +1 -3
  95. package/dist/components/wrapper/index.js.map +1 -0
  96. package/dist/interfaces/Messaging.d.ts +10 -0
  97. package/dist/interfaces/Messaging.d.ts.map +1 -1
  98. package/package.json +85 -84
  99. package/src/components/CreatePerson.tsx +80 -80
  100. package/src/components/DisplayBox.tsx +68 -68
  101. package/src/components/ErrorMessages.tsx +26 -26
  102. package/src/components/ExportLink.tsx +67 -67
  103. package/src/components/FloatingSupport.tsx +16 -16
  104. package/src/components/FormSubmissionEdit.tsx +129 -120
  105. package/src/components/HelpIcon.tsx +10 -10
  106. package/src/components/ImageEditor.tsx +126 -126
  107. package/src/components/InputBox.tsx +73 -73
  108. package/src/components/Loading.tsx +29 -29
  109. package/src/components/PersonAdd.tsx +75 -75
  110. package/src/components/QuestionEdit.tsx +63 -62
  111. package/src/components/SmallButton.tsx +39 -39
  112. package/src/components/SupportModal.tsx +26 -26
  113. package/src/components/TabPanel.tsx +34 -34
  114. package/src/components/gallery/GalleryModal.tsx +102 -102
  115. package/src/components/gallery/StockPhotos.tsx +74 -74
  116. package/src/components/gallery/index.ts +1 -1
  117. package/src/components/{material/iconPicker → iconPicker}/IconNamesList.ts +2240 -2240
  118. package/src/components/{material/iconPicker → iconPicker}/IconPicker.tsx +153 -153
  119. package/src/components/index.tsx +24 -23
  120. package/src/components/markdownEditor/Editor.tsx +132 -132
  121. package/src/components/markdownEditor/MarkdownEditor.tsx +16 -16
  122. package/src/components/markdownEditor/MarkdownModal.tsx +46 -46
  123. package/src/components/markdownEditor/MarkdownPreview.tsx +14 -14
  124. package/src/components/markdownEditor/editor.css +787 -787
  125. package/src/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  126. package/src/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  127. package/src/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  128. package/src/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  129. package/src/components/markdownEditor/images/icons/code.svg +2 -2
  130. package/src/components/markdownEditor/images/icons/journal-code.svg +4 -4
  131. package/src/components/markdownEditor/images/icons/journal-text.svg +4 -4
  132. package/src/components/markdownEditor/images/icons/justify.svg +2 -2
  133. package/src/components/markdownEditor/images/icons/link.svg +3 -3
  134. package/src/components/markdownEditor/images/icons/list-ol.svg +3 -3
  135. package/src/components/markdownEditor/images/icons/list-ul.svg +2 -2
  136. package/src/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  137. package/src/components/markdownEditor/images/icons/text-center.svg +2 -2
  138. package/src/components/markdownEditor/images/icons/text-left.svg +2 -2
  139. package/src/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  140. package/src/components/markdownEditor/images/icons/text-right.svg +2 -2
  141. package/src/components/markdownEditor/images/icons/type-bold.svg +2 -2
  142. package/src/components/markdownEditor/images/icons/type-h1.svg +2 -2
  143. package/src/components/markdownEditor/images/icons/type-h2.svg +2 -2
  144. package/src/components/markdownEditor/images/icons/type-h3.svg +2 -2
  145. package/src/components/markdownEditor/images/icons/type-h4.svg +12 -12
  146. package/src/components/markdownEditor/images/icons/type-italic.svg +2 -2
  147. package/src/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  148. package/src/components/markdownEditor/images/icons/type-underline.svg +2 -2
  149. package/src/components/markdownEditor/index.ts +2 -2
  150. package/src/components/markdownEditor/plugins/AutoLinkPlugin.tsx +35 -35
  151. package/src/components/markdownEditor/plugins/ControlledEditorPlugin.tsx +24 -24
  152. package/src/components/markdownEditor/plugins/ListMaxIndentLevelPlugin.tsx +68 -68
  153. package/src/components/markdownEditor/plugins/MarkdownTransformers.ts +106 -106
  154. package/src/components/markdownEditor/plugins/ReadOnlyPlugin.tsx +15 -15
  155. package/src/components/markdownEditor/plugins/ToolbarPlugin.tsx +401 -401
  156. package/src/components/markdownEditor/plugins/customLink/CustomLinkNode.tsx +224 -224
  157. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodePlugin.tsx +32 -32
  158. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.tsx +102 -102
  159. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.tsx +243 -243
  160. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.types.ts +11 -11
  161. package/src/components/markdownEditor/plugins/emoji/EmojiNode.tsx +95 -95
  162. package/src/components/markdownEditor/plugins/emoji/EmojiNodeTransform.ts +41 -41
  163. package/src/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.tsx +152 -152
  164. package/src/components/markdownEditor/plugins/emoji/EmojisPlugin.tsx +65 -65
  165. package/src/components/markdownEditor/plugins/index.ts +6 -6
  166. package/src/components/markdownEditor/theme.ts +65 -65
  167. package/src/components/notes/AddNote.tsx +90 -90
  168. package/src/components/notes/Conversation.tsx +82 -82
  169. package/src/components/notes/Conversations.tsx +58 -58
  170. package/src/components/notes/NewConversation.tsx +78 -78
  171. package/src/components/notes/Note.tsx +44 -44
  172. package/src/components/notes/Notes.tsx +68 -52
  173. package/src/components/notes/index.ts +5 -5
  174. package/src/components/reporting/ChartReport.tsx +98 -98
  175. package/src/components/reporting/ReportFilter.tsx +54 -54
  176. package/src/components/reporting/ReportFilterField.tsx +160 -160
  177. package/src/components/reporting/ReportOutput.tsx +79 -79
  178. package/src/components/reporting/ReportWithFilter.tsx +70 -70
  179. package/src/components/reporting/TableReport.tsx +57 -57
  180. package/src/components/reporting/TreeReport.tsx +111 -111
  181. package/src/components/reporting/index.ts +4 -4
  182. package/src/components/{material → wrapper}/AppList.tsx +20 -20
  183. package/src/components/{material → wrapper}/ChurchList.tsx +22 -22
  184. package/src/components/wrapper/Drawers.tsx +60 -0
  185. package/src/components/{material → wrapper}/NavItem.tsx +41 -41
  186. package/src/components/{material → wrapper}/NewPrivateMessage.tsx +103 -103
  187. package/src/components/wrapper/NotificationMenu.tsx +85 -0
  188. package/src/components/wrapper/Notifications.tsx +50 -0
  189. package/src/components/{material → wrapper}/PrivateMessageDetails.tsx +23 -23
  190. package/src/components/{material → wrapper}/PrivateMessages.tsx +87 -87
  191. package/src/components/{material → wrapper}/SiteWrapper.tsx +96 -145
  192. package/src/components/wrapper/TabPanel.tsx +30 -0
  193. package/src/components/{material → wrapper}/UserMenu.tsx +106 -141
  194. package/src/components/{material → wrapper}/index.tsx +5 -6
  195. package/src/donationComponents/DonationPage.tsx +136 -136
  196. package/src/donationComponents/components/BankForm.tsx +159 -159
  197. package/src/donationComponents/components/CardForm.tsx +104 -104
  198. package/src/donationComponents/components/DonationForm.tsx +235 -235
  199. package/src/donationComponents/components/FundDonation.tsx +49 -49
  200. package/src/donationComponents/components/FundDonations.tsx +39 -39
  201. package/src/donationComponents/components/NonAuthDonation.tsx +31 -31
  202. package/src/donationComponents/components/NonAuthDonationInner.tsx +259 -259
  203. package/src/donationComponents/components/PaymentMethods.tsx +135 -135
  204. package/src/donationComponents/components/RecurringDonations.tsx +121 -121
  205. package/src/donationComponents/components/RecurringDonationsEdit.tsx +93 -93
  206. package/src/donationComponents/components/index.tsx +9 -9
  207. package/src/donationComponents/index.ts +3 -3
  208. package/src/donationComponents/modals/DonationPreviewModal.tsx +66 -66
  209. package/src/helpers/AnalyticsHelper.ts +33 -33
  210. package/src/helpers/ApiHelper.ts +125 -125
  211. package/src/helpers/AppearanceHelper.ts +69 -69
  212. package/src/helpers/ArrayHelper.ts +81 -81
  213. package/src/helpers/CommonEnvironmentHelper.ts +80 -80
  214. package/src/helpers/CurrencyHelper.ts +10 -10
  215. package/src/helpers/DateHelper.ts +108 -108
  216. package/src/helpers/DonationHelper.ts +26 -26
  217. package/src/helpers/ErrorHelper.ts +36 -36
  218. package/src/helpers/EventHelper.ts +52 -52
  219. package/src/helpers/FileHelper.ts +31 -31
  220. package/src/helpers/PersonHelper.ts +60 -60
  221. package/src/helpers/SocketHelper.ts +76 -76
  222. package/src/helpers/Themes.ts +14 -14
  223. package/src/helpers/UniqueIdHelper.ts +36 -36
  224. package/src/helpers/UserHelper.ts +59 -59
  225. package/src/helpers/createEmotionCache.ts +17 -17
  226. package/src/helpers/index.ts +18 -18
  227. package/src/hooks/index.ts +1 -1
  228. package/src/hooks/useMountedState.ts +16 -16
  229. package/src/index.ts +6 -6
  230. package/src/interfaces/Access.ts +24 -24
  231. package/src/interfaces/Attendance.ts +8 -8
  232. package/src/interfaces/Content.ts +10 -10
  233. package/src/interfaces/Doing.ts +24 -24
  234. package/src/interfaces/Donation.ts +45 -45
  235. package/src/interfaces/Error.ts +17 -17
  236. package/src/interfaces/Membership.ts +51 -51
  237. package/src/interfaces/Messaging.ts +21 -20
  238. package/src/interfaces/Permissions.ts +68 -68
  239. package/src/interfaces/Reporting.ts +7 -7
  240. package/src/interfaces/UserContextInterface.ts +13 -13
  241. package/src/interfaces/index.ts +13 -13
  242. package/src/pageComponents/LoginPage.tsx +244 -244
  243. package/src/pageComponents/LogoutPage.tsx +28 -28
  244. package/src/pageComponents/components/Forgot.tsx +79 -79
  245. package/src/pageComponents/components/Login.tsx +54 -54
  246. package/src/pageComponents/components/LoginSetPassword.tsx +63 -63
  247. package/src/pageComponents/components/Register.tsx +107 -107
  248. package/src/pageComponents/components/SelectChurchModal.tsx +41 -41
  249. package/src/pageComponents/components/SelectChurchRegister.tsx +88 -88
  250. package/src/pageComponents/components/SelectChurchSearch.tsx +69 -69
  251. package/src/pageComponents/components/SelectableChurch.tsx +38 -38
  252. package/src/pageComponents/index.ts +3 -3
  253. package/tsconfig.json +34 -34
  254. package/tslint.json +14 -14
  255. package/dist/components/material/AppList.d.ts.map +0 -1
  256. package/dist/components/material/AppList.js.map +0 -1
  257. package/dist/components/material/ChurchList.d.ts.map +0 -1
  258. package/dist/components/material/ChurchList.js.map +0 -1
  259. package/dist/components/material/NavItem.d.ts.map +0 -1
  260. package/dist/components/material/NavItem.js.map +0 -1
  261. package/dist/components/material/NewPrivateMessage.d.ts.map +0 -1
  262. package/dist/components/material/NewPrivateMessage.js.map +0 -1
  263. package/dist/components/material/PrivateMessageDetails.d.ts.map +0 -1
  264. package/dist/components/material/PrivateMessageDetails.js.map +0 -1
  265. package/dist/components/material/PrivateMessages.d.ts.map +0 -1
  266. package/dist/components/material/PrivateMessages.js.map +0 -1
  267. package/dist/components/material/SiteWrapper.d.ts.map +0 -1
  268. package/dist/components/material/SiteWrapper.js.map +0 -1
  269. package/dist/components/material/UserMenu.d.ts.map +0 -1
  270. package/dist/components/material/UserMenu.js.map +0 -1
  271. package/dist/components/material/iconPicker/IconNamesList.d.ts.map +0 -1
  272. package/dist/components/material/iconPicker/IconNamesList.js.map +0 -1
  273. package/dist/components/material/iconPicker/IconPicker.d.ts.map +0 -1
  274. package/dist/components/material/iconPicker/IconPicker.js.map +0 -1
  275. package/dist/components/material/index.d.ts.map +0 -1
  276. package/dist/components/material/index.js.map +0 -1
  277. /package/dist/components/{material/iconPicker → iconPicker}/IconNamesList.d.ts +0 -0
  278. /package/dist/components/{material/iconPicker → iconPicker}/IconNamesList.js +0 -0
  279. /package/dist/components/{material/iconPicker → iconPicker}/IconPicker.d.ts +0 -0
  280. /package/dist/components/{material/iconPicker → iconPicker}/IconPicker.js +0 -0
  281. /package/dist/components/{material → wrapper}/AppList.d.ts +0 -0
  282. /package/dist/components/{material → wrapper}/AppList.js +0 -0
  283. /package/dist/components/{material → wrapper}/ChurchList.d.ts +0 -0
  284. /package/dist/components/{material → wrapper}/ChurchList.js +0 -0
  285. /package/dist/components/{material → wrapper}/NavItem.d.ts +0 -0
  286. /package/dist/components/{material → wrapper}/NavItem.js +0 -0
  287. /package/dist/components/{material → wrapper}/NewPrivateMessage.d.ts +0 -0
  288. /package/dist/components/{material → wrapper}/NewPrivateMessage.js +0 -0
  289. /package/dist/components/{material → wrapper}/PrivateMessageDetails.d.ts +0 -0
  290. /package/dist/components/{material → wrapper}/PrivateMessages.d.ts +0 -0
  291. /package/dist/components/{material → wrapper}/SiteWrapper.d.ts +0 -0
  292. /package/dist/components/{material → wrapper}/UserMenu.d.ts +0 -0
@@ -1,235 +1,235 @@
1
- /* eslint-disable multiline-ternary */
2
- import React from "react";
3
- import { Stripe } from "@stripe/stripe-js";
4
- import { InputBox, ErrorMessages } from "../../components";
5
- import { FundDonations } from ".";
6
- import { DonationPreviewModal } from "../modals/DonationPreviewModal";
7
- import { ApiHelper, CurrencyHelper, DateHelper } from "../../helpers";
8
- import { PersonInterface, StripePaymentMethod, StripeDonationInterface, FundDonationInterface, FundInterface, ChurchInterface } from "../../interfaces";
9
- import { Grid, InputLabel, MenuItem, Select, TextField, FormControl, Button, SelectChangeEvent, FormControlLabel, Checkbox, FormGroup, Typography } from "@mui/material"
10
- import { DonationHelper } from "../../helpers";
11
-
12
- interface Props { person: PersonInterface, customerId: string, paymentMethods: StripePaymentMethod[], stripePromise: Promise<Stripe>, donationSuccess: (message: string) => void, church?: ChurchInterface, churchLogo?: string }
13
-
14
- export const DonationForm: React.FC<Props> = (props) => {
15
- const [errorMessage, setErrorMessage] = React.useState<string>();
16
- const [fundDonations, setFundDonations] = React.useState<FundDonationInterface[]>();
17
- const [funds, setFunds] = React.useState<FundInterface[]>([]);
18
- const [fundsTotal, setFundsTotal] = React.useState<number>(0);
19
- const [transactionFee, setTransactionFee] = React.useState<number>(0);
20
- const [payFee, setPayFee] = React.useState<number>(0);
21
- const [total, setTotal] = React.useState<number>(0);
22
- const [paymentMethodName, setPaymentMethodName] = React.useState<string>(`${props?.paymentMethods[0]?.name} ****${props?.paymentMethods[0]?.last4}`);
23
- const [donationType, setDonationType] = React.useState<string>();
24
- const [showDonationPreviewModal, setShowDonationPreviewModal] = React.useState<boolean>(false);
25
- const [interval, setInterval] = React.useState("one_month");
26
- const [gateway, setGateway] = React.useState(null);
27
- const [donation, setDonation] = React.useState<StripeDonationInterface>({
28
- id: props?.paymentMethods[0]?.id,
29
- type: props?.paymentMethods[0]?.type,
30
- customerId: props.customerId,
31
- person: {
32
- id: props.person?.id,
33
- email: props.person?.contactInfo.email,
34
- name: props.person?.name.display
35
- },
36
- amount: 0,
37
- billing_cycle_anchor: + new Date(),
38
- interval: {
39
- interval_count: 1,
40
- interval: "month"
41
- },
42
- funds: []
43
- });
44
-
45
- const loadData = () => {
46
- ApiHelper.get("/funds", "GivingApi").then(data => {
47
- setFunds(data);
48
- if (data.length) setFundDonations([{ fundId: data[0].id }]);
49
- });
50
- ApiHelper.get("/gateways", "GivingApi").then((data) => {
51
- if (data.length !== 0) setGateway(data[0]);
52
- });
53
- }
54
-
55
- const handleKeyDown = (e: React.KeyboardEvent<any>) => { if (e.key === "Enter") { e.preventDefault(); handleSave(); } }
56
-
57
- const handleCheckChange = (e: React.SyntheticEvent<Element, Event>, checked: boolean) => {
58
- let d = { ...donation } as StripeDonationInterface;
59
- d.amount = checked ? fundsTotal + transactionFee : fundsTotal;
60
- let showFee = checked ? transactionFee : 0;
61
- setTotal(d.amount);
62
- setPayFee(showFee);
63
- setDonation(d);
64
- }
65
-
66
- const handleAutoPayFee = () => {
67
- let d = { ...donation } as StripeDonationInterface;
68
- d.amount = fundsTotal + transactionFee;
69
- let showFee = transactionFee;
70
- setTotal(d.amount);
71
- setPayFee(showFee);
72
- setDonation(d);
73
- }
74
-
75
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
76
- setErrorMessage(null);
77
- let d = { ...donation } as StripeDonationInterface;
78
- let value = e.target.value;
79
- switch (e.target.name) {
80
- case "method":
81
- d.id = value;
82
- let pm = props.paymentMethods.find(pm => pm.id === value);
83
- d.type = pm.type;
84
- setPaymentMethodName(`${pm.name} ****${pm.last4}`);
85
- break;
86
- case "type": setDonationType(value); break;
87
- case "date": d.billing_cycle_anchor = + new Date(value); break;
88
- case "interval":
89
- setInterval(value);
90
- d.interval = DonationHelper.getInterval(value);
91
- break;
92
- case "notes": d.notes = value; break;
93
- case "transaction-fee":
94
- const element = e.target as HTMLInputElement
95
- d.amount = element.checked ? fundsTotal + transactionFee : fundsTotal;
96
- let showFee = element.checked ? transactionFee : 0;
97
- setTotal(d.amount);
98
- setPayFee(showFee);
99
- }
100
- setDonation(d);
101
- }
102
-
103
- const handleCancel = () => { setDonationType(null); }
104
- const handleSave = () => {
105
- if (donation.amount < .5) setErrorMessage("Donation amount must be greater than $0.50");
106
- else setShowDonationPreviewModal(true);
107
- }
108
- const handleDonationSelect = (type: string) => {
109
- let dt = donationType === type ? null : type;
110
- setDonationType(dt);
111
- }
112
-
113
- const makeDonation = async (message: string) => {
114
- let results;
115
-
116
- const churchObj = {
117
- name: props?.church?.name,
118
- subDomain: props?.church?.subDomain,
119
- churchURL: typeof window !== "undefined" && window.location.origin,
120
- logo: props?.churchLogo
121
- }
122
-
123
- if (donationType === "once") results = await ApiHelper.post("/donate/charge/", {...donation, church: churchObj }, "GivingApi");
124
- if (donationType === "recurring") results = await ApiHelper.post("/donate/subscribe/", {...donation, church: churchObj }, "GivingApi");
125
-
126
- if (results?.status === "succeeded" || results?.status === "pending" || results?.status === "active") {
127
- setShowDonationPreviewModal(false);
128
- setDonationType(null);
129
- props.donationSuccess(message);
130
- }
131
- if (results?.raw?.message) {
132
- setShowDonationPreviewModal(false);
133
- setErrorMessage("Error: " + results?.raw?.message);
134
- }
135
- }
136
-
137
- const handleFundDonationsChange = (fd: FundDonationInterface[]) => {
138
- setErrorMessage(null);
139
- setFundDonations(fd);
140
- let totalAmount = 0;
141
- let selectedFunds: any = [];
142
- for (const fundDonation of fd) {
143
- totalAmount += fundDonation.amount || 0;
144
- let fund = funds.find((fund: FundInterface) => fund.id === fundDonation.fundId);
145
- selectedFunds.push({ id: fundDonation.fundId, amount: fundDonation.amount || 0, name: fund.name });
146
- }
147
- let d = { ...donation };
148
- d.amount = totalAmount;
149
- d.funds = selectedFunds;
150
- setDonation(d);
151
- setFundsTotal(totalAmount);
152
- setTotal(totalAmount);
153
- setTransactionFee(getTransactionFee(totalAmount));
154
- }
155
-
156
- const getTransactionFee = (amount: number) => {
157
- const fixedFee = 0.30;
158
- const fixedPercent = 0.029;
159
- return Math.round(((amount + fixedFee) / (1 - fixedPercent) - amount) * 100) / 100;
160
- }
161
-
162
- React.useEffect(loadData, [props.person?.id]);
163
- // eslint-disable-next-line react-hooks/exhaustive-deps
164
- React.useEffect(() => { gateway && gateway.payFees === true && handleAutoPayFee() }, [fundDonations]);
165
-
166
- if (!funds.length || !props?.paymentMethods[0]?.id) return null;
167
- else return (
168
- <>
169
- <DonationPreviewModal show={showDonationPreviewModal} onHide={() => setShowDonationPreviewModal(false)} handleDonate={makeDonation} donation={donation} donationType={donationType} payFee={payFee} paymentMethodName={paymentMethodName} funds={funds} />
170
- <InputBox id="donationBox" aria-label="donation-box" headerIcon="volunteer_activism" headerText="Donate" ariaLabelSave="save-button" cancelFunction={donationType ? handleCancel : undefined} saveFunction={donationType ? handleSave : undefined} saveText="Preview Donation">
171
- <Grid container spacing={3}>
172
- <Grid item md={6} xs={12}>
173
- <Button aria-label="single-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "once" ? "contained" : "outlined"} onClick={() => handleDonationSelect("once")}>Make a Donation</Button>
174
- </Grid>
175
- <Grid item md={6} xs={12}>
176
- <Button aria-label="recurring-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "recurring" ? "contained" : "outlined"} onClick={() => handleDonationSelect("recurring")}>Make a Recurring Donation</Button>
177
- </Grid>
178
- </Grid>
179
- {donationType
180
- && <div style={{ marginTop: "20px" }}>
181
- <Grid container spacing={3}>
182
- <Grid item md={12} xs={12}>
183
- <FormControl fullWidth>
184
- <InputLabel>Method</InputLabel>
185
- <Select label="Method" name="method" aria-label="method" value={donation.id} className="capitalize" onChange={handleChange}>
186
- {props.paymentMethods.map((paymentMethod: any, i: number) => <MenuItem key={i} value={paymentMethod.id}>{paymentMethod.name} ****{paymentMethod.last4}</MenuItem>)}
187
- </Select>
188
- </FormControl>
189
- </Grid>
190
- </Grid>
191
- {donationType === "recurring"
192
- && <Grid container spacing={3} style={{marginTop:10}}>
193
- <Grid item md={6} xs={12}>
194
- <TextField fullWidth name="date" type="date" aria-label="date" label="Start Date" value={DateHelper.formatHtml5Date(new Date(donation.billing_cycle_anchor))} onChange={handleChange} onKeyDown={handleKeyDown} />
195
- </Grid>
196
- <Grid item md={6} xs={12}>
197
- <FormControl fullWidth>
198
- <InputLabel>Frequency</InputLabel>
199
- <Select label="Frequency" name="interval" aria-label="interval" value={interval} onChange={handleChange}>
200
- <MenuItem value="one_week">Weekly</MenuItem>
201
- <MenuItem value="two_week">Bi-Weekly</MenuItem>
202
- <MenuItem value="one_month">Monthly</MenuItem>
203
- <MenuItem value="three_month">Quarterly</MenuItem>
204
- <MenuItem value="one_year">Annually</MenuItem>
205
- </Select>
206
- </FormControl>
207
- </Grid>
208
- </Grid>
209
- }
210
- <div className="form-group">
211
- {funds && fundDonations
212
- && <>
213
- <h4>Fund</h4>
214
- <FundDonations fundDonations={fundDonations} funds={funds} updatedFunction={handleFundDonationsChange} />
215
- </>
216
- }
217
- {fundsTotal > 0
218
- && <>
219
- {(gateway && gateway.payFees === true) ? <Typography fontSize={14} fontStyle="italic">*Transaction fees of {CurrencyHelper.formatCurrency(transactionFee)} are applied.</Typography> : (
220
- <FormGroup>
221
- <FormControlLabel control={<Checkbox />} name="transaction-fee" label={`I'll generously add ${CurrencyHelper.formatCurrency(transactionFee)} to cover the transaction fees so you can keep 100% of my donation.`} onChange={handleCheckChange} />
222
- </FormGroup>
223
- )}
224
- <p>Total Donation Amount: ${total}</p>
225
- </>
226
- }
227
- <TextField fullWidth label="Notes" multiline aria-label="note" name="notes" value={donation.notes || ""} onChange={handleChange} onKeyDown={handleKeyDown} />
228
- </div>
229
- {errorMessage && <ErrorMessages errors={[errorMessage]}></ErrorMessages>}
230
- </div>
231
- }
232
- </InputBox>
233
- </>
234
- );
235
- }
1
+ /* eslint-disable multiline-ternary */
2
+ import React from "react";
3
+ import { Stripe } from "@stripe/stripe-js";
4
+ import { InputBox, ErrorMessages } from "../../components";
5
+ import { FundDonations } from ".";
6
+ import { DonationPreviewModal } from "../modals/DonationPreviewModal";
7
+ import { ApiHelper, CurrencyHelper, DateHelper } from "../../helpers";
8
+ import { PersonInterface, StripePaymentMethod, StripeDonationInterface, FundDonationInterface, FundInterface, ChurchInterface } from "../../interfaces";
9
+ import { Grid, InputLabel, MenuItem, Select, TextField, FormControl, Button, SelectChangeEvent, FormControlLabel, Checkbox, FormGroup, Typography } from "@mui/material"
10
+ import { DonationHelper } from "../../helpers";
11
+
12
+ interface Props { person: PersonInterface, customerId: string, paymentMethods: StripePaymentMethod[], stripePromise: Promise<Stripe>, donationSuccess: (message: string) => void, church?: ChurchInterface, churchLogo?: string }
13
+
14
+ export const DonationForm: React.FC<Props> = (props) => {
15
+ const [errorMessage, setErrorMessage] = React.useState<string>();
16
+ const [fundDonations, setFundDonations] = React.useState<FundDonationInterface[]>();
17
+ const [funds, setFunds] = React.useState<FundInterface[]>([]);
18
+ const [fundsTotal, setFundsTotal] = React.useState<number>(0);
19
+ const [transactionFee, setTransactionFee] = React.useState<number>(0);
20
+ const [payFee, setPayFee] = React.useState<number>(0);
21
+ const [total, setTotal] = React.useState<number>(0);
22
+ const [paymentMethodName, setPaymentMethodName] = React.useState<string>(`${props?.paymentMethods[0]?.name} ****${props?.paymentMethods[0]?.last4}`);
23
+ const [donationType, setDonationType] = React.useState<string>();
24
+ const [showDonationPreviewModal, setShowDonationPreviewModal] = React.useState<boolean>(false);
25
+ const [interval, setInterval] = React.useState("one_month");
26
+ const [gateway, setGateway] = React.useState(null);
27
+ const [donation, setDonation] = React.useState<StripeDonationInterface>({
28
+ id: props?.paymentMethods[0]?.id,
29
+ type: props?.paymentMethods[0]?.type,
30
+ customerId: props.customerId,
31
+ person: {
32
+ id: props.person?.id,
33
+ email: props.person?.contactInfo.email,
34
+ name: props.person?.name.display
35
+ },
36
+ amount: 0,
37
+ billing_cycle_anchor: + new Date(),
38
+ interval: {
39
+ interval_count: 1,
40
+ interval: "month"
41
+ },
42
+ funds: []
43
+ });
44
+
45
+ const loadData = () => {
46
+ ApiHelper.get("/funds", "GivingApi").then(data => {
47
+ setFunds(data);
48
+ if (data.length) setFundDonations([{ fundId: data[0].id }]);
49
+ });
50
+ ApiHelper.get("/gateways", "GivingApi").then((data) => {
51
+ if (data.length !== 0) setGateway(data[0]);
52
+ });
53
+ }
54
+
55
+ const handleKeyDown = (e: React.KeyboardEvent<any>) => { if (e.key === "Enter") { e.preventDefault(); handleSave(); } }
56
+
57
+ const handleCheckChange = (e: React.SyntheticEvent<Element, Event>, checked: boolean) => {
58
+ let d = { ...donation } as StripeDonationInterface;
59
+ d.amount = checked ? fundsTotal + transactionFee : fundsTotal;
60
+ let showFee = checked ? transactionFee : 0;
61
+ setTotal(d.amount);
62
+ setPayFee(showFee);
63
+ setDonation(d);
64
+ }
65
+
66
+ const handleAutoPayFee = () => {
67
+ let d = { ...donation } as StripeDonationInterface;
68
+ d.amount = fundsTotal + transactionFee;
69
+ let showFee = transactionFee;
70
+ setTotal(d.amount);
71
+ setPayFee(showFee);
72
+ setDonation(d);
73
+ }
74
+
75
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
76
+ setErrorMessage(null);
77
+ let d = { ...donation } as StripeDonationInterface;
78
+ let value = e.target.value;
79
+ switch (e.target.name) {
80
+ case "method":
81
+ d.id = value;
82
+ let pm = props.paymentMethods.find(pm => pm.id === value);
83
+ d.type = pm.type;
84
+ setPaymentMethodName(`${pm.name} ****${pm.last4}`);
85
+ break;
86
+ case "type": setDonationType(value); break;
87
+ case "date": d.billing_cycle_anchor = + new Date(value); break;
88
+ case "interval":
89
+ setInterval(value);
90
+ d.interval = DonationHelper.getInterval(value);
91
+ break;
92
+ case "notes": d.notes = value; break;
93
+ case "transaction-fee":
94
+ const element = e.target as HTMLInputElement
95
+ d.amount = element.checked ? fundsTotal + transactionFee : fundsTotal;
96
+ let showFee = element.checked ? transactionFee : 0;
97
+ setTotal(d.amount);
98
+ setPayFee(showFee);
99
+ }
100
+ setDonation(d);
101
+ }
102
+
103
+ const handleCancel = () => { setDonationType(null); }
104
+ const handleSave = () => {
105
+ if (donation.amount < .5) setErrorMessage("Donation amount must be greater than $0.50");
106
+ else setShowDonationPreviewModal(true);
107
+ }
108
+ const handleDonationSelect = (type: string) => {
109
+ let dt = donationType === type ? null : type;
110
+ setDonationType(dt);
111
+ }
112
+
113
+ const makeDonation = async (message: string) => {
114
+ let results;
115
+
116
+ const churchObj = {
117
+ name: props?.church?.name,
118
+ subDomain: props?.church?.subDomain,
119
+ churchURL: typeof window !== "undefined" && window.location.origin,
120
+ logo: props?.churchLogo
121
+ }
122
+
123
+ if (donationType === "once") results = await ApiHelper.post("/donate/charge/", {...donation, church: churchObj }, "GivingApi");
124
+ if (donationType === "recurring") results = await ApiHelper.post("/donate/subscribe/", {...donation, church: churchObj }, "GivingApi");
125
+
126
+ if (results?.status === "succeeded" || results?.status === "pending" || results?.status === "active") {
127
+ setShowDonationPreviewModal(false);
128
+ setDonationType(null);
129
+ props.donationSuccess(message);
130
+ }
131
+ if (results?.raw?.message) {
132
+ setShowDonationPreviewModal(false);
133
+ setErrorMessage("Error: " + results?.raw?.message);
134
+ }
135
+ }
136
+
137
+ const handleFundDonationsChange = (fd: FundDonationInterface[]) => {
138
+ setErrorMessage(null);
139
+ setFundDonations(fd);
140
+ let totalAmount = 0;
141
+ let selectedFunds: any = [];
142
+ for (const fundDonation of fd) {
143
+ totalAmount += fundDonation.amount || 0;
144
+ let fund = funds.find((fund: FundInterface) => fund.id === fundDonation.fundId);
145
+ selectedFunds.push({ id: fundDonation.fundId, amount: fundDonation.amount || 0, name: fund.name });
146
+ }
147
+ let d = { ...donation };
148
+ d.amount = totalAmount;
149
+ d.funds = selectedFunds;
150
+ setDonation(d);
151
+ setFundsTotal(totalAmount);
152
+ setTotal(totalAmount);
153
+ setTransactionFee(getTransactionFee(totalAmount));
154
+ }
155
+
156
+ const getTransactionFee = (amount: number) => {
157
+ const fixedFee = 0.30;
158
+ const fixedPercent = 0.029;
159
+ return Math.round(((amount + fixedFee) / (1 - fixedPercent) - amount) * 100) / 100;
160
+ }
161
+
162
+ React.useEffect(loadData, [props.person?.id]);
163
+ // eslint-disable-next-line react-hooks/exhaustive-deps
164
+ React.useEffect(() => { gateway && gateway.payFees === true && handleAutoPayFee() }, [fundDonations]);
165
+
166
+ if (!funds.length || !props?.paymentMethods[0]?.id) return null;
167
+ else return (
168
+ <>
169
+ <DonationPreviewModal show={showDonationPreviewModal} onHide={() => setShowDonationPreviewModal(false)} handleDonate={makeDonation} donation={donation} donationType={donationType} payFee={payFee} paymentMethodName={paymentMethodName} funds={funds} />
170
+ <InputBox id="donationBox" aria-label="donation-box" headerIcon="volunteer_activism" headerText="Donate" ariaLabelSave="save-button" cancelFunction={donationType ? handleCancel : undefined} saveFunction={donationType ? handleSave : undefined} saveText="Preview Donation">
171
+ <Grid container spacing={3}>
172
+ <Grid item md={6} xs={12}>
173
+ <Button aria-label="single-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "once" ? "contained" : "outlined"} onClick={() => handleDonationSelect("once")}>Make a Donation</Button>
174
+ </Grid>
175
+ <Grid item md={6} xs={12}>
176
+ <Button aria-label="recurring-donation" size="small" fullWidth style={{ minHeight: "50px" }} variant={donationType === "recurring" ? "contained" : "outlined"} onClick={() => handleDonationSelect("recurring")}>Make a Recurring Donation</Button>
177
+ </Grid>
178
+ </Grid>
179
+ {donationType
180
+ && <div style={{ marginTop: "20px" }}>
181
+ <Grid container spacing={3}>
182
+ <Grid item md={12} xs={12}>
183
+ <FormControl fullWidth>
184
+ <InputLabel>Method</InputLabel>
185
+ <Select label="Method" name="method" aria-label="method" value={donation.id} className="capitalize" onChange={handleChange}>
186
+ {props.paymentMethods.map((paymentMethod: any, i: number) => <MenuItem key={i} value={paymentMethod.id}>{paymentMethod.name} ****{paymentMethod.last4}</MenuItem>)}
187
+ </Select>
188
+ </FormControl>
189
+ </Grid>
190
+ </Grid>
191
+ {donationType === "recurring"
192
+ && <Grid container spacing={3} style={{marginTop:10}}>
193
+ <Grid item md={6} xs={12}>
194
+ <TextField fullWidth name="date" type="date" aria-label="date" label="Start Date" value={DateHelper.formatHtml5Date(new Date(donation.billing_cycle_anchor))} onChange={handleChange} onKeyDown={handleKeyDown} />
195
+ </Grid>
196
+ <Grid item md={6} xs={12}>
197
+ <FormControl fullWidth>
198
+ <InputLabel>Frequency</InputLabel>
199
+ <Select label="Frequency" name="interval" aria-label="interval" value={interval} onChange={handleChange}>
200
+ <MenuItem value="one_week">Weekly</MenuItem>
201
+ <MenuItem value="two_week">Bi-Weekly</MenuItem>
202
+ <MenuItem value="one_month">Monthly</MenuItem>
203
+ <MenuItem value="three_month">Quarterly</MenuItem>
204
+ <MenuItem value="one_year">Annually</MenuItem>
205
+ </Select>
206
+ </FormControl>
207
+ </Grid>
208
+ </Grid>
209
+ }
210
+ <div className="form-group">
211
+ {funds && fundDonations
212
+ && <>
213
+ <h4>Fund</h4>
214
+ <FundDonations fundDonations={fundDonations} funds={funds} updatedFunction={handleFundDonationsChange} />
215
+ </>
216
+ }
217
+ {fundsTotal > 0
218
+ && <>
219
+ {(gateway && gateway.payFees === true) ? <Typography fontSize={14} fontStyle="italic">*Transaction fees of {CurrencyHelper.formatCurrency(transactionFee)} are applied.</Typography> : (
220
+ <FormGroup>
221
+ <FormControlLabel control={<Checkbox />} name="transaction-fee" label={`I'll generously add ${CurrencyHelper.formatCurrency(transactionFee)} to cover the transaction fees so you can keep 100% of my donation.`} onChange={handleCheckChange} />
222
+ </FormGroup>
223
+ )}
224
+ <p>Total Donation Amount: ${total}</p>
225
+ </>
226
+ }
227
+ <TextField fullWidth label="Notes" multiline aria-label="note" name="notes" value={donation.notes || ""} onChange={handleChange} onKeyDown={handleKeyDown} />
228
+ </div>
229
+ {errorMessage && <ErrorMessages errors={[errorMessage]}></ErrorMessages>}
230
+ </div>
231
+ }
232
+ </InputBox>
233
+ </>
234
+ );
235
+ }
@@ -1,49 +1,49 @@
1
- import React from "react";
2
- import { FundDonationInterface, FundInterface } from "../../interfaces";
3
- import { FormControl, Grid, InputLabel, MenuItem, Select, SelectChangeEvent, TextField } from "@mui/material"
4
-
5
- interface Props {
6
- fundDonation: FundDonationInterface,
7
- funds: FundInterface[],
8
- index: number,
9
- updatedFunction: (fundDonation: FundDonationInterface, index: number) => void
10
- }
11
-
12
- export const FundDonation: React.FC<Props> = (props) => {
13
-
14
- const getOptions = () => {
15
- let result = [];
16
- for (let i = 0; i < props.funds.length; i++) result.push(<MenuItem key={i} value={props.funds[i].id}>{props.funds[i].name}</MenuItem>);
17
- return result;
18
- }
19
-
20
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
21
- let fd = { ...props.fundDonation }
22
- switch (e.target.name) {
23
- case "amount":
24
- fd.amount = parseFloat(e.target.value.replace("$", "").replace(",", ""));
25
- break;
26
- case "fund":
27
- fd.fundId = e.target.value;
28
- break;
29
- }
30
- props.updatedFunction(fd, props.index);
31
- }
32
-
33
- return (
34
- <Grid container spacing={3}>
35
- <Grid item md={6} xs={12}>
36
- <TextField fullWidth name="amount" label="Amount" type="number" aria-label="amount" lang="en-150" value={props.fundDonation.amount || ""} onChange={handleChange} />
37
- </Grid>
38
- <Grid item md={6} xs={12}>
39
- <FormControl fullWidth>
40
- <InputLabel>Fund</InputLabel>
41
- <Select fullWidth label="Fund" name="fund" aria-label="fund" value={props.fundDonation.fundId} onChange={handleChange}>
42
- {getOptions()}
43
- </Select>
44
- </FormControl>
45
- </Grid>
46
- </Grid>
47
- );
48
- }
49
-
1
+ import React from "react";
2
+ import { FundDonationInterface, FundInterface } from "../../interfaces";
3
+ import { FormControl, Grid, InputLabel, MenuItem, Select, SelectChangeEvent, TextField } from "@mui/material"
4
+
5
+ interface Props {
6
+ fundDonation: FundDonationInterface,
7
+ funds: FundInterface[],
8
+ index: number,
9
+ updatedFunction: (fundDonation: FundDonationInterface, index: number) => void
10
+ }
11
+
12
+ export const FundDonation: React.FC<Props> = (props) => {
13
+
14
+ const getOptions = () => {
15
+ let result = [];
16
+ for (let i = 0; i < props.funds.length; i++) result.push(<MenuItem key={i} value={props.funds[i].id}>{props.funds[i].name}</MenuItem>);
17
+ return result;
18
+ }
19
+
20
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | SelectChangeEvent<string>) => {
21
+ let fd = { ...props.fundDonation }
22
+ switch (e.target.name) {
23
+ case "amount":
24
+ fd.amount = parseFloat(e.target.value.replace("$", "").replace(",", ""));
25
+ break;
26
+ case "fund":
27
+ fd.fundId = e.target.value;
28
+ break;
29
+ }
30
+ props.updatedFunction(fd, props.index);
31
+ }
32
+
33
+ return (
34
+ <Grid container spacing={3}>
35
+ <Grid item md={6} xs={12}>
36
+ <TextField fullWidth name="amount" label="Amount" type="number" aria-label="amount" lang="en-150" value={props.fundDonation.amount || ""} onChange={handleChange} />
37
+ </Grid>
38
+ <Grid item md={6} xs={12}>
39
+ <FormControl fullWidth>
40
+ <InputLabel>Fund</InputLabel>
41
+ <Select fullWidth label="Fund" name="fund" aria-label="fund" value={props.fundDonation.fundId} onChange={handleChange}>
42
+ {getOptions()}
43
+ </Select>
44
+ </FormControl>
45
+ </Grid>
46
+ </Grid>
47
+ );
48
+ }
49
+