@sikka/hawa 0.0.3 → 0.0.6

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 (158) hide show
  1. package/.github/workflows/hawa-publish-push.yml +45 -0
  2. package/.github/workflows/hawa-publish.yml +2 -0
  3. package/es/index.es.js +1 -0
  4. package/lib/index.js +1 -0
  5. package/package.json +24 -13
  6. package/rollup.config.js +2 -2
  7. package/src/Assets/images/card-background/1.jpeg +0 -0
  8. package/src/Assets/images/card-background/10.jpeg +0 -0
  9. package/src/Assets/images/card-background/11.jpeg +0 -0
  10. package/src/Assets/images/card-background/12.jpeg +0 -0
  11. package/src/Assets/images/card-background/13.jpeg +0 -0
  12. package/src/Assets/images/card-background/14.jpeg +0 -0
  13. package/src/Assets/images/card-background/15.jpeg +0 -0
  14. package/src/Assets/images/card-background/16.jpeg +0 -0
  15. package/src/Assets/images/card-background/17.jpeg +0 -0
  16. package/src/Assets/images/card-background/18.jpeg +0 -0
  17. package/src/Assets/images/card-background/19.jpeg +0 -0
  18. package/src/Assets/images/card-background/2.jpeg +0 -0
  19. package/src/Assets/images/card-background/20.jpeg +0 -0
  20. package/src/Assets/images/card-background/21.jpeg +0 -0
  21. package/src/Assets/images/card-background/22.jpeg +0 -0
  22. package/src/Assets/images/card-background/23.jpeg +0 -0
  23. package/src/Assets/images/card-background/24.jpeg +0 -0
  24. package/src/Assets/images/card-background/25.jpeg +0 -0
  25. package/src/Assets/images/card-background/3.jpeg +0 -0
  26. package/src/Assets/images/card-background/4.jpeg +0 -0
  27. package/src/Assets/images/card-background/5.jpeg +0 -0
  28. package/src/Assets/images/card-background/6.jpeg +0 -0
  29. package/src/Assets/images/card-background/7.jpeg +0 -0
  30. package/src/Assets/images/card-background/8.jpeg +0 -0
  31. package/src/Assets/images/card-background/9.jpeg +0 -0
  32. package/src/Assets/images/card-type/amex.png +0 -0
  33. package/src/Assets/images/card-type/diners.png +0 -0
  34. package/src/Assets/images/card-type/discover.png +0 -0
  35. package/src/Assets/images/card-type/mastercard.png +0 -0
  36. package/src/Assets/images/card-type/troy.png +0 -0
  37. package/src/Assets/images/card-type/unionpay.png +0 -0
  38. package/src/Assets/images/card-type/visa.png +0 -0
  39. package/src/blocks/Account/UserProfile.js +11 -11
  40. package/src/blocks/Account/UserSettings.js +11 -11
  41. package/src/blocks/AuthForms/NewPasswordForm.js +83 -10
  42. package/src/blocks/AuthForms/ResetPasswordForm.js +50 -8
  43. package/src/blocks/AuthForms/SignInForm.js +96 -13
  44. package/src/blocks/AuthForms/SignUpForm.js +113 -13
  45. package/src/blocks/Payment/ChargeWalletForm.js +32 -0
  46. package/src/blocks/Payment/CreditCardForm.js +31 -0
  47. package/src/blocks/Payment/Form/CForm.js +328 -0
  48. package/src/blocks/Payment/Form/Card.js +242 -0
  49. package/src/blocks/Payment/Gateway/GooglePay.js +251 -0
  50. package/src/blocks/Payment/Gateway/Payfort.js +90 -0
  51. package/src/blocks/Payment/Gateway/Paypal.js +138 -0
  52. package/src/blocks/Payment/Gateway/Wallet.js +149 -0
  53. package/src/blocks/Payment/PayWithWallet.js +35 -0
  54. package/src/blocks/Payment/PaymentMethod.js +132 -0
  55. package/src/blocks/Payment/SelectPayment.js +94 -0
  56. package/src/blocks/Payment/index.js +18 -0
  57. package/src/index.js +4 -1
  58. package/src/layout/Box.js +30 -17
  59. package/src/stories/BlocksStories/AuthForm.stories.js +105 -0
  60. package/src/stories/BlocksStories/PaymentForm.stories.js +82 -0
  61. package/src/stories/{UserAccount.stories.js → BlocksStories/UserAccount.stories.js} +2 -2
  62. package/src/stories/GlobalVariables.stories.js +33 -90
  63. package/src/stories/HawaProvider.stories.js +0 -1
  64. package/src/stories/Introduction.stories.js +132 -110
  65. package/src/stories/LayoutStories/Box.stories.js +56 -0
  66. package/src/stories/UIStories/ActionButton.stories.js +53 -0
  67. package/src/stories/{AdaptiveButton.stories.js → UIStories/AdaptiveButton.stories.js} +3 -3
  68. package/src/stories/UIStories/Alert.stories.js +55 -0
  69. package/src/stories/{CheckBox.stories.js → UIStories/CheckBox.stories.js} +3 -4
  70. package/src/stories/UIStories/InputLabel.stories.js +13 -0
  71. package/src/stories/{RadioSelector.stories.js → UIStories/RadioSelector.stories.js} +5 -6
  72. package/src/stories/{TextField.stories.js → UIStories/TextField.stories.js} +4 -5
  73. package/src/styles.scss +679 -0
  74. package/src/themes/HawaProvider.js +110 -16
  75. package/src/ui/ActionButton.js +35 -10
  76. package/src/ui/AdaptiveButton.js +29 -29
  77. package/src/ui/ApplePayButton.js +93 -0
  78. package/src/ui/AutoCompleteField.js +0 -1
  79. package/src/ui/DragDropImages.js +2 -2
  80. package/src/ui/GithubButton.js +90 -0
  81. package/src/ui/GoogleButton.js +82 -0
  82. package/src/ui/GooglePayButton.js +93 -0
  83. package/src/ui/HawaAlert.js +37 -0
  84. package/src/ui/HawaButton.js +48 -0
  85. package/src/ui/{Checkbox.js → HawaCheckbox.js} +3 -3
  86. package/src/ui/HawaInputLabel.js +32 -0
  87. package/src/ui/HawaLogoButton.js +48 -0
  88. package/src/ui/{RadioSelector.js → HawaRadio.js} +1 -1
  89. package/src/ui/{TextArea.js → HawaTextArea.js} +2 -2
  90. package/src/ui/HawaTextField.js +113 -0
  91. package/src/ui/HawaTypography.js +29 -0
  92. package/src/ui/MadaButton.js +93 -0
  93. package/src/ui/PayPalButton.js +93 -0
  94. package/src/ui/RadioBox.js +2 -2
  95. package/src/ui/STCPayButton.js +93 -0
  96. package/src/ui/SelectedField.js +4 -4
  97. package/src/ui/StyledTooltip.js +1 -1
  98. package/src/ui/TabPanel.js +1 -1
  99. package/src/ui/TwitterButton.js +83 -0
  100. package/src/ui/VisaMasterButton.js +93 -0
  101. package/src/ui/WalletButton.js +24 -0
  102. package/src/ui/index.js +23 -11
  103. package/storybook-static/0.0d994c92.iframe.bundle.js +3 -0
  104. package/storybook-static/{1.4e43f671.iframe.bundle.js.LICENSE.txt → 0.0d994c92.iframe.bundle.js.LICENSE.txt} +0 -0
  105. package/storybook-static/0.0d994c92.iframe.bundle.js.map +1 -0
  106. package/storybook-static/0.f47eb24a4893a96ec307.manager.bundle.js +1 -0
  107. package/storybook-static/1.aabc3f3a.iframe.bundle.js +1 -0
  108. package/storybook-static/{3.c1dc7159.iframe.bundle.js → 2.430bf1e3.iframe.bundle.js} +1 -1
  109. package/storybook-static/4.0fcda1281dc1961dbe94.manager.bundle.js +2 -0
  110. package/storybook-static/{4.8c311a6b48cad9f29317.manager.bundle.js.LICENSE.txt → 4.0fcda1281dc1961dbe94.manager.bundle.js.LICENSE.txt} +0 -0
  111. package/storybook-static/{5.88fe62ee92ff5ca67829.manager.bundle.js → 5.63ab4f94d50a3acf080d.manager.bundle.js} +1 -1
  112. package/storybook-static/{7.69d2e532.iframe.bundle.js → 6.704d1e8d.iframe.bundle.js} +1 -1
  113. package/storybook-static/{6.96d184f368dea006cb52.manager.bundle.js → 6.a6d45262f7e98f3f18d3.manager.bundle.js} +2 -2
  114. package/storybook-static/{6.96d184f368dea006cb52.manager.bundle.js.LICENSE.txt → 6.a6d45262f7e98f3f18d3.manager.bundle.js.LICENSE.txt} +0 -0
  115. package/storybook-static/{7.5ec31f3702b08ab0b71c.manager.bundle.js → 7.097710753af9a1c41b80.manager.bundle.js} +1 -1
  116. package/storybook-static/{8.68cd1217.iframe.bundle.js → 7.9ce807e3.iframe.bundle.js} +3 -3
  117. package/storybook-static/{8.68cd1217.iframe.bundle.js.LICENSE.txt → 7.9ce807e3.iframe.bundle.js.LICENSE.txt} +0 -0
  118. package/storybook-static/7.9ce807e3.iframe.bundle.js.map +1 -0
  119. package/storybook-static/{8.5ce13be7612bd3a6b864.manager.bundle.js → 8.76c3cbf398692028e834.manager.bundle.js} +1 -1
  120. package/storybook-static/{9.488e3969.iframe.bundle.js → 8.c4cb6081.iframe.bundle.js} +1 -1
  121. package/storybook-static/iframe.html +1 -1
  122. package/storybook-static/index.html +1 -1
  123. package/storybook-static/main.ac6e4b72b033097dad76.manager.bundle.js +1 -0
  124. package/storybook-static/main.e55ce615.iframe.bundle.js +1 -0
  125. package/storybook-static/{runtime~main.cc29f4c2175f187a3707.manager.bundle.js → runtime~main.c8dac23bc753439736f0.manager.bundle.js} +1 -1
  126. package/storybook-static/runtime~main.cfefe972.iframe.bundle.js +1 -0
  127. package/storybook-static/vendors~main.30a2c5d7.iframe.bundle.js +76 -0
  128. package/storybook-static/{vendors~main.d144d840.iframe.bundle.js.LICENSE.txt → vendors~main.30a2c5d7.iframe.bundle.js.LICENSE.txt} +3 -30
  129. package/storybook-static/vendors~main.30a2c5d7.iframe.bundle.js.map +1 -0
  130. package/storybook-static/vendors~main.a697e07137d366f95f76.manager.bundle.js +2 -0
  131. package/storybook-static/{vendors~main.f228d62e92b69563cefb.manager.bundle.js.LICENSE.txt → vendors~main.a697e07137d366f95f76.manager.bundle.js.LICENSE.txt} +0 -0
  132. package/tools/build-styles.js +17 -0
  133. package/src/blocks/AuthForms/viaFacebook.js +0 -0
  134. package/src/blocks/AuthForms/viaGithub.js +0 -0
  135. package/src/blocks/AuthForms/viaGoogle.js +0 -0
  136. package/src/blocks/AuthForms/viaTwitter.js +0 -0
  137. package/src/stories/ActionButton.stories.js +0 -49
  138. package/src/stories/Alert.stories.js +0 -41
  139. package/src/stories/AuthForm.stories.js +0 -79
  140. package/src/stories/Box.stories.js +0 -64
  141. package/src/stories/InputLabel.stories.js +0 -92
  142. package/src/ui/StyledAlert.js +0 -30
  143. package/src/ui/StyledInputLabel.js +0 -19
  144. package/src/ui/TextField.js +0 -62
  145. package/storybook-static/0.d3bc3395610cf5d3ee94.manager.bundle.js +0 -1
  146. package/storybook-static/0.dd3d47f5.iframe.bundle.js +0 -1
  147. package/storybook-static/1.4e43f671.iframe.bundle.js +0 -3
  148. package/storybook-static/1.4e43f671.iframe.bundle.js.map +0 -1
  149. package/storybook-static/2.9a757207.iframe.bundle.js +0 -1
  150. package/storybook-static/4.8c311a6b48cad9f29317.manager.bundle.js +0 -2
  151. package/storybook-static/8.68cd1217.iframe.bundle.js.map +0 -1
  152. package/storybook-static/main.65cb2769.iframe.bundle.js +0 -1
  153. package/storybook-static/main.7e391cf7bf72b0d18ea5.manager.bundle.js +0 -1
  154. package/storybook-static/runtime~main.6e2e1544.iframe.bundle.js +0 -1
  155. package/storybook-static/vendors~main.d144d840.iframe.bundle.js +0 -3
  156. package/storybook-static/vendors~main.d144d840.iframe.bundle.js.map +0 -1
  157. package/storybook-static/vendors~main.f228d62e92b69563cefb.manager.bundle.js +0 -2
  158. package/yarn-error.log +0 -10910
@@ -1,19 +1,102 @@
1
- import React, { useContext } from "react";
2
- import { ThemeProvider } from "../../themes/HawaProvider";
3
- import { StyledTextField, StyledInputLabel } from "../../ui";
4
- import { Box } from '../../layout'
5
- export const SignInForm = (props) => {
6
- const theme = useContext(ThemeProvider);
7
- return (
8
- <Box maxWidth={400}>
1
+ import React from "react";
2
+ import {
3
+ HawaTextField,
4
+ ActionButton,
5
+ GoogleButton,
6
+ TwitterButton,
7
+ GithubButton,
8
+ HawaAlert
9
+ } from "../../ui";
10
+ import { Box } from "../../layout";
11
+ import { FormProvider, useForm } from "react-hook-form";
12
+ import { TextField } from "@mui/material";
9
13
 
10
- <StyledInputLabel label="Email" />
11
- <StyledTextField type="text" />
12
- <StyledInputLabel label="Password" />
13
- <StyledTextField type="text" />
14
+ export const SignInForm = (props) => {
15
+ const methods = useForm();
16
+ const {
17
+ formState: { errors },
18
+ handleSubmit,
19
+ getValues,
20
+ register,
21
+ watch,
22
+ reset,
23
+ setValue
24
+ } = methods;
14
25
 
15
- {props.children}
26
+ return (
27
+ <Box themeType={props.theme} maxWidth={400} noColor noMargin noPadding>
28
+ <Box themeType={props.theme} noMargin>
29
+ {props.error && (
30
+ <HawaAlert
31
+ themeType={props.theme}
32
+ text="This is a sign in alert"
33
+ severity="error"
34
+ />
35
+ )}
36
+ <FormProvider {...methods}>
37
+ <form onSubmit={handleSubmit(props.handleSignIn)}>
38
+ <HawaTextField
39
+ type="text"
40
+ name="email"
41
+ inputLabel="Email"
42
+ placeholder="Email"
43
+ themeType={props.theme}
44
+ rules={{
45
+ required: "Email is required",
46
+ pattern: {
47
+ value:
48
+ /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
49
+ message: "Invalid email address"
50
+ }
51
+ }}
52
+ helperText={errors.email?.message}
53
+ />
16
54
 
55
+ <HawaTextField
56
+ name="password"
57
+ placeholder="Password"
58
+ themeType={props.theme}
59
+ type="password"
60
+ inputLabel="Password"
61
+ rules={{
62
+ required: "Password is rquired"
63
+ }}
64
+ helperText={errors.password?.message}
65
+ />
66
+ <ActionButton
67
+ type="submit"
68
+ fullWidth
69
+ last={"true"}
70
+ text={"Sign In"}
71
+ themeType={props.theme}
72
+ />
73
+ </form>
74
+ </FormProvider>
75
+ </Box>
76
+ {props.viaGoogle && (
77
+ <GoogleButton
78
+ themeType={props.theme}
79
+ outlined
80
+ buttonText={props.googleButtonLabel}
81
+ handleClick={props.handleGoogleSignIn}
82
+ />
83
+ )}
84
+ {props.viaGithub && (
85
+ <GithubButton
86
+ outlined
87
+ themeType={props.theme}
88
+ buttonText={props.githubButtonLabel}
89
+ handleClick={props.handleGithubSignIn}
90
+ />
91
+ )}
92
+ {props.viaTwitter && (
93
+ <TwitterButton
94
+ outlined
95
+ themeType={props.theme}
96
+ buttonText={props.twitterButtonLabel}
97
+ handleClick={props.handleTwitterSignIn}
98
+ />
99
+ )}
17
100
  </Box>
18
101
  );
19
102
  };
@@ -1,20 +1,120 @@
1
- import React, { useContext } from "react";
1
+ import React from "react";
2
2
  import { Box } from "../../layout";
3
- import { ThemeProvider } from "../../themes/HawaProvider";
4
- import { StyledTextField, StyledInputLabel } from "../../ui";
3
+ import {
4
+ HawaTextField,
5
+ ActionButton,
6
+ GoogleButton,
7
+ GithubButton,
8
+ TwitterButton,
9
+ HawaAlert
10
+ } from "../../ui";
11
+ import PropTypes from "prop-types";
12
+ import { FormProvider, useForm } from "react-hook-form";
5
13
 
6
14
  export const SignUpForm = (props) => {
7
- const theme = useContext(ThemeProvider);
8
- return (
9
- <Box maxWidth={400}>
15
+ const methods = useForm();
16
+ const {
17
+ formState: { errors },
18
+ handleSubmit,
19
+ getValues,
20
+ register,
21
+ watch,
22
+ reset,
23
+ setValue
24
+ } = methods;
10
25
 
11
- <StyledInputLabel label="Email" />
12
- <StyledTextField type="text" />
13
- <StyledInputLabel label="Password" />
14
- <StyledTextField type="text" />
15
- <StyledInputLabel label="Confirm Password" />
16
- <StyledTextField type="text" />
17
- {props.children}
26
+ return (
27
+ <Box themeType={props.theme} maxWidth={400} noColor noMargin noPadding>
28
+ <Box themeType={props.theme} noMargin>
29
+ {props.error && (
30
+ <HawaAlert
31
+ themeType={props.theme}
32
+ text="This is a sign in alert"
33
+ severity="error"
34
+ />
35
+ )}
36
+ <FormProvider {...methods}>
37
+ <form onSubmit={handleSubmit(props.handleSignUp)}>
38
+ <HawaTextField
39
+ themeType={props.theme}
40
+ type="text"
41
+ inputLabel="Email"
42
+ placeholder="Email"
43
+ name="email"
44
+ rules={{
45
+ required: "Email is required",
46
+ pattern: {
47
+ value:
48
+ /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
49
+ message: "Invalid email address"
50
+ }
51
+ }}
52
+ helperText={errors.email?.message}
53
+ />
54
+ <HawaTextField
55
+ name="password"
56
+ placeholder="Password"
57
+ themeType={props.theme}
58
+ type="password"
59
+ inputLabel="Password"
60
+ rules={{
61
+ required: "Password is rquired"
62
+ }}
63
+ helperText={errors.password?.message}
64
+ />
65
+ <HawaTextField
66
+ name="confirmPassword"
67
+ placeholder="Password"
68
+ themeType={props.theme}
69
+ type="password"
70
+ inputLabel="Confirm Password"
71
+ rules={{
72
+ required: "Password is rquired"
73
+ }}
74
+ helperText={errors.confirmPassword?.message}
75
+ />
76
+ <ActionButton
77
+ fullWidth
78
+ type="submit"
79
+ text="Sign Up"
80
+ last
81
+ themeType={props.theme}
82
+ />
83
+ </form>
84
+ </FormProvider>
85
+ </Box>
86
+ {props.viaGoogle && (
87
+ <GoogleButton
88
+ outlined
89
+ themeType={props.theme}
90
+ buttonText={props.googleButtonLabel}
91
+ handleClick={props.handleGoogleSignIn}
92
+ />
93
+ )}
94
+ {props.viaGithub && (
95
+ <GithubButton
96
+ outlined
97
+ themeType={props.theme}
98
+ buttonText={props.githubButtonLabel}
99
+ handleClick={props.handleGithubSignUp}
100
+ />
101
+ )}
102
+ {props.viaTwitter && (
103
+ <TwitterButton
104
+ outlined
105
+ themeType={props.theme}
106
+ buttonText={props.twitterButtonLabel}
107
+ handleClick={props.handleTwitterSignIn}
108
+ />
109
+ )}
18
110
  </Box>
19
111
  );
20
112
  };
113
+
114
+ SignUpForm.propTypes = {
115
+ theme: PropTypes.oneOf(["secondary", "primary"])
116
+ // buttonLabel: PropTypes.string,
117
+ // danger: PropTypes.bool,
118
+ // disabled: PropTypes.bool,
119
+ // showText: PropTypes.bool
120
+ };
@@ -0,0 +1,32 @@
1
+ import React, { useState } from "react";
2
+ import { HawaTextField, ActionButton, HawaTypography } from "../../ui";
3
+ import { Box } from "../../layout";
4
+
5
+ export const ChargeWalletForm = (props) => {
6
+ const [walletAmount, setWalletAmount] = useState(0);
7
+ return (
8
+ <Box themeType={props.theme} maxWidth={400} noColor noMargin noPadding>
9
+ <Box themeType={props.theme} noMargin>
10
+ <HawaTypography variant="h2" align="center" themeType={props.theme}>
11
+ {walletAmount.toLocaleString("en")}{" "}
12
+ <span style={{ fontSize: 20, letterSpacing: 1 }}>
13
+ {props.currency}
14
+ </span>
15
+ </HawaTypography>
16
+ <HawaTypography themeType={props.theme}></HawaTypography>
17
+ <HawaTextField
18
+ themeType={props.theme}
19
+ type="number"
20
+ inputLabel="Amount" //move this to props
21
+ onChange={(e) => setWalletAmount(e.target.value)}
22
+ />
23
+ <ActionButton
24
+ last
25
+ text={"Charge Wallet"} //move this to props
26
+ themeType={props.theme}
27
+ onClick={props.handleSignIn}
28
+ />
29
+ </Box>
30
+ </Box>
31
+ );
32
+ };
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import {
3
+ HawaTextField,
4
+ ActionButton,
5
+ GoogleButton,
6
+ TwitterButton,
7
+ GithubButton
8
+ } from "../../ui";
9
+ import { Box } from "../../layout";
10
+
11
+ export const CreditCardForm = (props) => {
12
+ return (
13
+ <Box themeType={props.theme} maxWidth={400} noColor noMargin noPadding>
14
+ <Box themeType={props.theme} noMargin>
15
+ <HawaTextField themeType={props.theme} type="text" inputLabel="Email" />
16
+
17
+ <HawaTextField
18
+ themeType={props.theme}
19
+ type="text"
20
+ inputLabel="Password"
21
+ />
22
+ <ActionButton
23
+ last
24
+ text={"Sign In"}
25
+ themeType={props.theme}
26
+ onClick={props.handleSignIn}
27
+ />
28
+ </Box>
29
+ </Box>
30
+ );
31
+ };
@@ -0,0 +1,328 @@
1
+ import React, { useEffect, useState, useRef } from "react";
2
+ import sha256 from "crypto-js/sha256";
3
+ import Button from "@mui/material/Button";
4
+ import CircularProgress from "@mui/material/CircularProgress";
5
+ import useTranslation from "next-translate/useTranslation";
6
+ import axios from "axios";
7
+
8
+ const currentYear = new Date().getFullYear();
9
+ const monthsArr = Array.from({ length: 12 }, (x, i) => {
10
+ const month = i + 1;
11
+ return month <= 9 ? "0" + month : month;
12
+ });
13
+ const yearsArr = Array.from({ length: 9 }, (_x, i) => currentYear + i);
14
+
15
+ export default function CForm({
16
+ cardHolder,
17
+ cardMonth,
18
+ cardYear,
19
+ cardCvv,
20
+ onUpdateState,
21
+ cardNumberRef,
22
+ cardHolderRef,
23
+ cardDateRef,
24
+ cardCvvRef,
25
+ onCardInputFocus,
26
+ onCardInputBlur,
27
+ children,
28
+ selectedPaymentMethod,
29
+ transaction
30
+ }) {
31
+ const payfortFormref = useRef();
32
+ const [loading, setLoading] = useState(false);
33
+ const [cardNumber, setCardNumber] = useState("");
34
+ const [accessCode, setAccessCode] = useState("");
35
+ const [merchantIdentifier, setMerchantIdentifier] = useState("");
36
+ const [shaRequestPassphrase, setSHARequestPassphrase] = useState("");
37
+ const [expiryDate, setExpiryDate] = useState("");
38
+ const [signature, setSignature] = useState("");
39
+ const [ip, setIP] = useState("");
40
+ const { t, lang } = useTranslation("common");
41
+
42
+ const handleFormChange = (event) => {
43
+ const { name, value } = event.target;
44
+
45
+ onUpdateState(name, value);
46
+ };
47
+
48
+ const getData = async () => {
49
+ const res = await axios.get("https://geolocation-db.com/json/");
50
+ console.log(res.data);
51
+ setIP(res.data.IPv4);
52
+ };
53
+
54
+ const generateSignature = () => {
55
+ // Calculate request signature
56
+ let shaString = "";
57
+
58
+ // array request
59
+ let arrData = {
60
+ access_code: process.env.NEXT_PUBLIC_QAWAIM_SOFTWARE_PAYFOR_ACCESS_TOKEN,
61
+ language: lang,
62
+ merchant_identifier:
63
+ process.env.NEXT_PUBLIC_QAWAIM_SOFTWARE_PAYFOR_MERCHANT_ID,
64
+ merchant_reference: "",
65
+ return_url: `${process.env.NEXT_PUBLIC_QAWAIM_USER_PORTAL_URL}/aps_online/response`,
66
+ service_command: "TOKENIZATION"
67
+ };
68
+
69
+ if (
70
+ transaction &&
71
+ transaction?.getTransactionByIDInvoice?.transaction_payment_token
72
+ ) {
73
+ arrData.token_name =
74
+ transaction?.getTransactionByIDInvoice?.transaction_payment_token;
75
+ }
76
+
77
+ console.log("arrData=", arrData);
78
+
79
+ shaString = `${process.env.NEXT_PUBLIC_QAWAIM_SOFTWARE_PAYFOR_SHA_REQUEST_PHRASE}${shaString}`;
80
+ for (const [key, value] of Object.entries(arrData)) {
81
+ shaString = `${shaString}${key}=${value}`;
82
+ }
83
+ shaString = `${shaString}${process.env.NEXT_PUBLIC_QAWAIM_SOFTWARE_PAYFOR_SHA_REQUEST_PHRASE}`;
84
+
85
+ console.log("shaString=", shaString);
86
+
87
+ // your request signature
88
+ let signature = sha256(shaString);
89
+
90
+ console.log("signature=", signature);
91
+ setSignature(signature);
92
+ };
93
+ useEffect(() => {
94
+ if (selectedPaymentMethod && selectedPaymentMethod !== "APPLEPAY") {
95
+ getData();
96
+ generateSignature();
97
+ }
98
+ }, [selectedPaymentMethod, accessCode, shaRequestPassphrase]);
99
+
100
+ useEffect(() => {
101
+ if (cardMonth && cardYear) {
102
+ setExpiryDate(`${cardYear.substring(2)}${cardMonth}`);
103
+ }
104
+ }, [cardMonth, cardYear]);
105
+
106
+ // TODO: We can improve the regex check with a better approach like in the card component.
107
+ const onCardNumberChange = (event) => {
108
+ let { value, name } = event.target;
109
+ let cardNumber = value;
110
+ value = value.replace(/\D/g, "");
111
+ if (/^3[47]\d{0,13}$/.test(value)) {
112
+ cardNumber = value
113
+ .replace(/(\d{4})/, "$1 ")
114
+ .replace(/(\d{4}) (\d{6})/, "$1 $2 ");
115
+ } else if (/^3(?:0[0-5]|[68]\d)\d{0,11}$/.test(value)) {
116
+ // diner's club, 14 digits
117
+ cardNumber = value
118
+ .replace(/(\d{4})/, "$1 ")
119
+ .replace(/(\d{4}) (\d{6})/, "$1 $2 ");
120
+ } else if (/^\d{0,16}$/.test(value)) {
121
+ // regular cc number, 16 digits
122
+ cardNumber = value
123
+ .replace(/(\d{4})/, "$1 ")
124
+ .replace(/(\d{4}) (\d{4})/, "$1 $2 ")
125
+ .replace(/(\d{4}) (\d{4}) (\d{4})/, "$1 $2 $3 ");
126
+ }
127
+
128
+ setCardNumber(cardNumber.trimRight());
129
+ onUpdateState(name, cardNumber);
130
+ };
131
+
132
+ const onCvvFocus = (event) => {
133
+ onUpdateState("isCardFlipped", true);
134
+ };
135
+
136
+ const onCvvBlur = (event) => {
137
+ onUpdateState("isCardFlipped", false);
138
+ };
139
+
140
+ const handlePayfortForm = (e) => {};
141
+
142
+ // NOTE: Currently the cursor on the card number field gets reset if we remove a number, the code bellow was used
143
+ // in class components, need to transform this to work with functional components.
144
+ // getSnapshotBeforeUpdate() {
145
+ // return this.props.cardNumberRef.current.selectionStart;
146
+ // }
147
+
148
+ // const componentDidUpdate = function (prevProps, prevState, cursorIdx) {
149
+ // const node = cardNumberRef.current;
150
+ // const { cardNumber: cardNum } = state;
151
+ // const { cardNumber: prevCardNum } = prevState;
152
+ // if (
153
+ // cardNum.length > prevCardNum.length &&
154
+ // cardNum[cursorIdx - 1] === ' '
155
+ // ) {
156
+ // cursorIdx += 1;
157
+ // } else if (prevCardNum[cursorIdx - 1] === ' ') {
158
+ // cursorIdx -= 1;
159
+ // }
160
+ // node.selectionStart = node.selectionEnd = cursorIdx;
161
+ // };
162
+
163
+ return (
164
+ <div className="card-form">
165
+ <div className="card-list">{children}</div>
166
+ <div className="card-form__inner">
167
+ <div className="card-input">
168
+ <label htmlFor="cardNumber" className="card-input__label">
169
+ {t("cardNumber")}
170
+ </label>
171
+ <input
172
+ type="tel"
173
+ name="cardNumber"
174
+ className="card-input__input"
175
+ autoComplete="off"
176
+ onChange={onCardNumberChange}
177
+ maxLength="19"
178
+ ref={cardNumberRef}
179
+ onFocus={(e) => onCardInputFocus(e, "cardNumber")}
180
+ onBlur={onCardInputBlur}
181
+ value={cardNumber}
182
+ />
183
+ </div>
184
+
185
+ <div className="card-input">
186
+ <label htmlFor="cardName" className="card-input__label">
187
+ {t("cardHolder")}
188
+ </label>
189
+ <input
190
+ type="text"
191
+ className="card-input__input"
192
+ autoComplete="off"
193
+ name="cardHolder"
194
+ onChange={handleFormChange}
195
+ ref={cardHolderRef}
196
+ onFocus={(e) => onCardInputFocus(e, "cardHolder")}
197
+ onBlur={onCardInputBlur}
198
+ />
199
+ </div>
200
+
201
+ <div className="card-form__row">
202
+ <div className="card-form__col">
203
+ <div className="card-form__group">
204
+ <label htmlFor="cardMonth" className="card-input__label">
205
+ {t("cardExpiration")}
206
+ </label>
207
+ <select
208
+ className="card-input__input -select"
209
+ value={cardMonth}
210
+ name="cardMonth"
211
+ onChange={handleFormChange}
212
+ ref={cardDateRef}
213
+ onFocus={(e) => onCardInputFocus(e, "cardDate")}
214
+ onBlur={onCardInputBlur}
215
+ >
216
+ <option value="" disabled>
217
+ {t("cardMonth")}
218
+ </option>
219
+
220
+ {monthsArr.map((val, index) => (
221
+ <option key={index} value={val}>
222
+ {val}
223
+ </option>
224
+ ))}
225
+ </select>
226
+ <select
227
+ name="cardYear"
228
+ className="card-input__input -select"
229
+ value={cardYear}
230
+ onChange={handleFormChange}
231
+ onFocus={(e) => onCardInputFocus(e, "cardDate")}
232
+ onBlur={onCardInputBlur}
233
+ >
234
+ <option value="" disabled>
235
+ {t("cardYear")}
236
+ </option>
237
+
238
+ {yearsArr.map((val, index) => (
239
+ <option key={index} value={val}>
240
+ {val}
241
+ </option>
242
+ ))}
243
+ </select>
244
+ </div>
245
+ </div>
246
+ <div className="card-form__col -cvv">
247
+ <div className="card-input">
248
+ <label htmlFor="cardCvv" className="card-input__label">
249
+ {t("cvv")}
250
+ </label>
251
+ <input
252
+ type="tel"
253
+ className="card-input__input"
254
+ maxLength="4"
255
+ autoComplete="off"
256
+ name="cardCvv"
257
+ onChange={handleFormChange}
258
+ onFocus={onCvvFocus}
259
+ onBlur={onCvvBlur}
260
+ ref={cardCvvRef}
261
+ />
262
+ </div>
263
+ </div>
264
+ </div>
265
+ <div className="card-input" style={{ marginTop: "20px" }}>
266
+ <form
267
+ ref={payfortFormref}
268
+ action={`${process.env.NEXT_PUBLIC_QAWAIM_SOFTWARE_PAYFOR_ENVIRONMENT_URL}`}
269
+ method="POST"
270
+ >
271
+ <input type="hidden" name="access_code" value={`${accessCode}`} />
272
+ <input type="hidden" name="card_holder_name" value={cardHolder} />
273
+ <input
274
+ type="hidden"
275
+ name="card_number"
276
+ value={cardNumber.replace(/\s/g, "")}
277
+ />
278
+ <input type="hidden" name="card_security_code" value={cardCvv} />
279
+ <input type="hidden" name="expiry_date" value={expiryDate} />
280
+ <input type="hidden" name="language" value={lang} />
281
+ <input
282
+ type="hidden"
283
+ name="merchant_identifier"
284
+ value={`${merchantIdentifier}`}
285
+ />
286
+ <input type="hidden" name="merchant_reference" value={""} />
287
+ <input type="hidden" name="remember_me" value="NO" />
288
+ <input
289
+ type="hidden"
290
+ name="return_url"
291
+ value={`${process.env.NEXT_PUBLIC_QAWAIM_USER_PORTAL_URL}/aps_online/register`}
292
+ />
293
+ <input type="hidden" name="service_command" value="TOKENIZATION" />
294
+ <input type="hidden" name="signature" value={signature} />
295
+ {transaction &&
296
+ transaction?.getTransactionByIDInvoice
297
+ ?.transaction_payment_token && (
298
+ <input
299
+ type="hidden"
300
+ name="token_name"
301
+ value={
302
+ transaction?.getTransactionByIDInvoice
303
+ ?.transaction_payment_token
304
+ }
305
+ />
306
+ )}
307
+ </form>
308
+ <Button
309
+ variant="contained"
310
+ color="primary"
311
+ fullWidth
312
+ onClick={handlePayfortForm}
313
+ >
314
+ {loading ? (
315
+ <CircularProgress
316
+ variant="indeterminate"
317
+ style={{ color: "white", display: "none" }}
318
+ size={25}
319
+ />
320
+ ) : (
321
+ <span className="pay-new-btn-txt">{t("pay-now")}</span>
322
+ )}
323
+ </Button>
324
+ </div>
325
+ </div>
326
+ </div>
327
+ );
328
+ }