@sikka/hawa 0.0.105 → 0.0.107

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 (48) hide show
  1. package/dist/styles.css +110 -30
  2. package/es/blocks/Misc/EmptyState.d.ts +4 -0
  3. package/es/blocks/Misc/index.d.ts +1 -0
  4. package/es/elements/DragDropImages.d.ts +1 -1
  5. package/es/elements/HawaCardInput.d.ts +25 -0
  6. package/es/elements/HawaMenu.d.ts +2 -1
  7. package/es/elements/HawaTimeline.d.ts +8 -0
  8. package/es/elements/index.d.ts +3 -1
  9. package/es/hooks/index.d.ts +1 -0
  10. package/es/hooks/useDiscloser.d.ts +7 -0
  11. package/es/index.d.ts +1 -0
  12. package/es/index.es.js +1 -1
  13. package/es/layout/HawaContainer.d.ts +2 -0
  14. package/lib/blocks/Misc/EmptyState.d.ts +4 -0
  15. package/lib/blocks/Misc/index.d.ts +1 -0
  16. package/lib/elements/DragDropImages.d.ts +1 -1
  17. package/lib/elements/HawaCardInput.d.ts +25 -0
  18. package/lib/elements/HawaMenu.d.ts +2 -1
  19. package/lib/elements/HawaTimeline.d.ts +8 -0
  20. package/lib/elements/index.d.ts +3 -1
  21. package/lib/hooks/index.d.ts +1 -0
  22. package/lib/hooks/useDiscloser.d.ts +7 -0
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.js +1 -1
  25. package/lib/layout/HawaContainer.d.ts +2 -0
  26. package/package.json +3 -2
  27. package/src/blocks/Misc/EmptyState.tsx +24 -0
  28. package/src/blocks/Misc/NotFound.tsx +15 -12
  29. package/src/blocks/Misc/index.ts +2 -1
  30. package/src/elements/DragDropImages.tsx +3 -3
  31. package/src/elements/HawaAccordian.tsx +21 -10
  32. package/src/elements/HawaCardInput.tsx +317 -0
  33. package/src/elements/HawaItemCard.tsx +6 -2
  34. package/src/elements/HawaMenu.tsx +10 -2
  35. package/src/elements/HawaTimeline.tsx +82 -0
  36. package/src/elements/index.ts +33 -30
  37. package/src/hooks/index.ts +1 -0
  38. package/src/hooks/useDiscloser.ts +25 -0
  39. package/src/index.ts +2 -1
  40. package/src/layout/HawaContainer.tsx +18 -2
  41. package/src/styles.css +110 -30
  42. package/storybook-static/{209.d29fd715.iframe.bundle.js → 209.05314e10.iframe.bundle.js} +2 -2
  43. package/storybook-static/{209.d29fd715.iframe.bundle.js.LICENSE.txt → 209.05314e10.iframe.bundle.js.LICENSE.txt} +0 -0
  44. package/storybook-static/iframe.html +1 -1
  45. package/storybook-static/main.7a1984b7.iframe.bundle.js +1 -0
  46. package/storybook-static/project.json +1 -1
  47. package/tsconfig.json +30 -25
  48. package/storybook-static/main.a1546405.iframe.bundle.js +0 -1
@@ -2,6 +2,8 @@ import React from "react";
2
2
  type ContainerTypes = {
3
3
  maxWidth?: "full" | "small" | "normal";
4
4
  children: React.ReactNode;
5
+ variant?: "contained" | "outlined";
6
+ centered?: boolean;
5
7
  };
6
8
  export declare const HawaContainer: React.FunctionComponent<ContainerTypes>;
7
9
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sikka/hawa",
3
- "version": "0.0.105",
3
+ "version": "0.0.107",
4
4
  "description": "UI Kit",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.es.js",
@@ -95,6 +95,7 @@
95
95
  "react-icons": "^4.6.0",
96
96
  "react-select": "^5.3.2",
97
97
  "rollup-plugin-swc": "^0.2.1",
98
- "rollup-plugin-typescript2": "^0.34.1"
98
+ "rollup-plugin-typescript2": "^0.34.1",
99
+ "start": "^5.1.0"
99
100
  }
100
101
  }
@@ -0,0 +1,24 @@
1
+ import React from "react"
2
+ import { HawaButton } from "../../elements"
3
+ import { HawaContainer } from "../../layout"
4
+ import { FaCheck } from "react-icons/fa"
5
+ type TEmptyState = {}
6
+
7
+ export const EmptyState: React.FunctionComponent<TEmptyState> = (props) => {
8
+ return (
9
+ <HawaContainer variant="outlined" centered={true}>
10
+ <div className="flex h-20 w-20 flex-col items-center justify-center rounded-3xl bg-primary-400 text-6xl font-bold">
11
+ <FaCheck size={30} />
12
+ </div>
13
+ <div className="m-2 text-center text-xl font-bold">
14
+ You're all caught up
15
+ </div>
16
+ <div className="text-center">
17
+ If you're lost please contact us help@sikka.io{" "}
18
+ </div>
19
+ <HawaButton color="primary" width="full">
20
+ Action
21
+ </HawaButton>
22
+ </HawaContainer>
23
+ )
24
+ }
@@ -6,23 +6,26 @@ type NotFoundTypes = {}
6
6
 
7
7
  export const NotFound: React.FunctionComponent<NotFoundTypes> = (props) => {
8
8
  return (
9
- <div
10
- style={{
11
- display: "flex",
12
- flexDirection: "column",
13
- alignItems: "center",
14
- }}
15
- >
16
- <div className="text-6xl font-bold">404</div>
17
- <div className="m-2 text-xl font-bold">Page Not Found</div>
18
- <HawaContainer>
9
+ <HawaContainer variant="outlined">
10
+ <div
11
+ // style={{
12
+ // display: "flex",
13
+ // flexDirection: "column",
14
+ // alignItems: "center",
15
+ // }}
16
+ className="flex flex-col items-center"
17
+ >
18
+ <div className="text-center text-6xl font-bold">404</div>
19
+ <div className="m-2 text-center text-xl font-bold">Page Not Found</div>
19
20
  <div className="text-center">
20
21
  If you're lost please contact us help@sikka.io{" "}
21
22
  </div>
23
+ {/* <div className="flex flex-col content-center items-stretch bg-red-200"> */}
22
24
  <HawaButton color="primary" width="full">
23
25
  Home
24
26
  </HawaButton>
25
- </HawaContainer>
26
- </div>
27
+ {/* </div> */}
28
+ </div>
29
+ </HawaContainer>
27
30
  )
28
31
  }
@@ -1 +1,2 @@
1
- export * from "./NotFound";
1
+ export * from "./NotFound"
2
+ export * from "./EmptyState"
@@ -15,7 +15,7 @@ type DragDropImagesTypes = {
15
15
  setFiles: any
16
16
  setDeletedFiles: any
17
17
  maxFiles: number
18
- accept: any
18
+ accept: string
19
19
  onAcceptedFiles: any
20
20
  showPreview: any
21
21
  onDeleteFile: any
@@ -157,9 +157,9 @@ export const DragDropImages: React.FunctionComponent<DragDropImagesTypes> = ({
157
157
  <div
158
158
  // variant="drop-area"
159
159
  {...getRootProps({
160
- //fix type error
161
- // style: { backgroundColor: isDragActive && "white" },
160
+ style: {backgroundColor : isDragActive ? "white" : "inherit" }
162
161
  })}
162
+ // style={{ backgroundColor: isDragActive ? "white" : "inherit" }}
163
163
  className="flex flex-col justify-center rounded-xl border border-dashed border-black"
164
164
  >
165
165
  <input {...getInputProps()} />
@@ -1,3 +1,4 @@
1
+ import clsx from "clsx"
1
2
  import React from "react"
2
3
 
3
4
  type AccordionItemTypes = {
@@ -18,12 +19,17 @@ const AccordionItem: React.FunctionComponent<AccordionItemTypes> = (props) => {
18
19
  "p-5 font-light border border-b-xl border-gray-200 dark:border-gray-700 dark:bg-gray-900"
19
20
  let accPaperRounded =
20
21
  "p-5 font-light border border-b-xl rounded-b-xl border-gray-200 dark:border-gray-700 dark:bg-gray-900"
22
+
21
23
  return (
22
- <div>
24
+ <div className="rounded-lg ">
23
25
  <h2 id={"accordion-collapse-heading-" + props.count}>
24
26
  <button
25
27
  type="button"
26
- className={props.count === 0 ? roundedTop : noRounding}
28
+ className={clsx(
29
+ // props.count === 0 ? roundedTop : noRounding,
30
+ "flex w-full items-center justify-between border border-gray-200 bg-gray-100 p-5 text-left font-medium text-gray-900 hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-800 dark:focus:ring-gray-800",
31
+ !collapse ? "rounded-t-lg" : "rounded-lg"
32
+ )}
27
33
  onClick={() => setCollapse(!collapse)}
28
34
  data-accordion-target={"#accordion-collapse-body-" + props.count}
29
35
  aria-expanded="true"
@@ -32,7 +38,7 @@ const AccordionItem: React.FunctionComponent<AccordionItemTypes> = (props) => {
32
38
  <span>{props.title}</span>
33
39
  <svg
34
40
  data-accordion-icon=""
35
- className={`h-6 w-6 ${collapse ? "" : "rotate-180"} shrink-0`}
41
+ className={`h-6 w-6 ${collapse ? "" : "rotate-180"} shrink-0 transition-all`}
36
42
  fill="currentColor"
37
43
  viewBox="0 0 20 20"
38
44
  xmlns="http://www.w3.org/2000/svg"
@@ -47,14 +53,15 @@ const AccordionItem: React.FunctionComponent<AccordionItemTypes> = (props) => {
47
53
  </h2>
48
54
  <div
49
55
  id={"accordion-collapse-body-" + props.count}
50
- className={`${collapse ? "hidden" : "block"}`}
56
+ className={clsx(
57
+ collapse ? "invisible hidden" : "visible",
58
+ "border-b-xl rounded-b-xl border border-gray-200 p-5 font-light dark:border-gray-700 dark:bg-gray-900"
59
+ )}
51
60
  aria-labelledby={"accordion-collapse-heading-" + props.count}
52
61
  >
53
- <div className={props.count === -1 ? accPaperRounded : accPaper}>
54
- <p className="mb-2 text-gray-500 dark:text-gray-400">
55
- {props.content}
56
- </p>
57
- </div>
62
+ {/* <div className={props.count === -1 ? accPaperRounded : accPaper}> */}
63
+ <p className="mb-2 text-gray-500 dark:text-gray-400">{props.content}</p>
64
+ {/* </div> */}
58
65
  </div>
59
66
  </div>
60
67
  )
@@ -66,7 +73,11 @@ export const HawaAccordian: React.FunctionComponent<AccordionTypes> = (
66
73
  props
67
74
  ) => {
68
75
  return (
69
- <div id="accordion-collapse" data-accordion="collapse">
76
+ <div
77
+ id="accordion-collapse"
78
+ data-accordion="collapse"
79
+ className="flex flex-col gap-3"
80
+ >
70
81
  {props.content.map((acc: any, i: any) => {
71
82
  return (
72
83
  <AccordionItem
@@ -0,0 +1,317 @@
1
+ import React, { useState } from "react"
2
+ import { HawaButton } from "./HawaButton"
3
+
4
+ const CARDS = {
5
+ mada: "^(4(0(0861|1757|3024|6136|6996|7(197|395)|9201)|1(0621|0685|2565|7633|9593)|2(281(7|8|9)|0(132)|1(141)|6(897)|8(1|331|67(1|2|3)))|3(1361|2328|4107|9954)|4(0(533|647|795)|5564|6(393|404|672))|5(5(036|708)|7865|7997|8456)|6(2220|854(0|1|2|3))|7(4491)|8(301(0|1|2)|4783|609(4|5|6)|931(7|8|9))|93428)|5(0(4300|6968|8160)|13213|2(0058|1076|4(130|514)|9(415|741))|3(0060|0906|1095|1196|2013|5(825|989)|6023|7767|9931)|4(3(085|357)|9760)|5(4180|7606|8563|8848)|8(5265|8(8(4(5|6|7|8|9)|5(0|1))|98(2|3))|9(005|206)))|6(0(4906|5141)|36120)|9682(0(1|2|3|4|5|6|7|8|9)|1(0|1)))",
6
+ visa: "^4",
7
+ amex: "^(34|37)",
8
+ mastercard: "^5[1-5]",
9
+ discover: "^6011",
10
+ unionpay: "^62",
11
+ troy: "^9792",
12
+ diners: "^(30[0-5]|36)",
13
+ }
14
+
15
+ const currentYear = new Date().getFullYear()
16
+ const monthsArr = Array.from({ length: 12 }, (x, i) => {
17
+ const month = i + 1
18
+ return month <= 9 ? "0" + month : month
19
+ })
20
+ const yearsArr = Array.from({ length: 9 }, (_x, i) => currentYear + i)
21
+
22
+ export const HawaCardInput = ({
23
+ cardHolder,
24
+ cardMonth,
25
+ cardYear,
26
+ cardCvv,
27
+ rememberMe,
28
+ onUpdateState,
29
+ cardNumberRef,
30
+ cardHolderRef,
31
+ cardDateRef,
32
+ cardCvvRef,
33
+ rememberMeRef,
34
+ onCardInputFocus,
35
+ onCardInputBlur,
36
+ children,
37
+ handlePaymentPayfort,
38
+ selectedPaymentMethod,
39
+ isRegister,
40
+ accessCode,
41
+ shaRequestPassphrase,
42
+ transaction,
43
+ signature,
44
+ isCheckout,
45
+ }) => {
46
+ // const token = getToken()
47
+ // const router = useRouter()
48
+ // const formRegister = useRef()
49
+ // const [loading, setLoading] = useState(false)
50
+ const [cardNumber, setCardNumber] = useState("")
51
+ const [expiryDate, setExpiryDate] = useState("")
52
+ const [binCardType, setBinCardType] = useState("")
53
+ // const [tokenName, setTokenName] = useState("")
54
+ // const [registeredCard, setRegisteredCard] = useState("")
55
+ const [registerSignature, setRegisterSignature] = useState("")
56
+ const [card, setCard] = useState("")
57
+ // const [payfortForm, setPayfortForm] = useState("")
58
+ // const classes = useStyles()
59
+ // const [value, setValue] = React.useState("")
60
+ // const [error, setError] = React.useState(false)
61
+ // const [helperText, setHelperText] = React.useState("Choose wisely")
62
+
63
+ // const { data: allCards, loading: loadingCards } = useQuery(getCards(), {
64
+ // variables: { userId: token.User._id },
65
+ // })
66
+
67
+ // const { t, lang } = useTranslation("common")
68
+
69
+ const cardType = (cardNumber) => {
70
+ const number = cardNumber.replace(/\D/g, "")
71
+ let re
72
+ for (const [card, pattern] of Object.entries(CARDS)) {
73
+ re = new RegExp(pattern)
74
+ console.log("number=", number)
75
+ console.log("card=", card)
76
+ console.log("pattern=", pattern)
77
+ console.log("res=", re.test(number))
78
+ if (number.match(re) != null) {
79
+ return card
80
+ }
81
+ }
82
+
83
+ return "" // default type
84
+ }
85
+
86
+ // TODO: We can improve the regex check with a better approach like in the card component.
87
+ const onCardNumberChange = (event) => {
88
+ let { value, name } = event.target
89
+ let cardNumber = value
90
+ value = value.replace(/\D/g, "")
91
+ if (/^3[47]\d{0,13}$/.test(value)) {
92
+ cardNumber = value
93
+ .replace(/(\d{4})/, "$1 ")
94
+ .replace(/(\d{4}) (\d{6})/, "$1 $2 ")
95
+ } else if (/^3(?:0[0-5]|[68]\d)\d{0,11}$/.test(value)) {
96
+ // diner's club, 14 digits
97
+ cardNumber = value
98
+ .replace(/(\d{4})/, "$1 ")
99
+ .replace(/(\d{4}) (\d{6})/, "$1 $2 ")
100
+ } else if (/^\d{0,16}$/.test(value)) {
101
+ // regular cc number, 16 digits
102
+ cardNumber = value
103
+ .replace(/(\d{4})/, "$1 ")
104
+ .replace(/(\d{4}) (\d{4})/, "$1 $2 ")
105
+ .replace(/(\d{4}) (\d{4}) (\d{4})/, "$1 $2 $3 ")
106
+ }
107
+
108
+ setCardNumber(cardNumber.trimRight())
109
+ setBinCardType(cardType(cardNumber.trimRight()))
110
+ onUpdateState(name, cardNumber)
111
+ }
112
+ const handleFormChange = (event) => {
113
+ const { name, value } = event.target
114
+ if (name === "rememberMe") {
115
+ onUpdateState(name, !rememberMe)
116
+ } else {
117
+ onUpdateState(name, value)
118
+ }
119
+ }
120
+
121
+ return (
122
+ <div>
123
+ <div>
124
+ <div>{children}</div>
125
+ <div>
126
+ <div className="w-fit bg-red-200 p-2">
127
+ <label htmlFor="cardNumber" className="relative">
128
+ Card Number
129
+ <input
130
+ type="tel"
131
+ name="cardNumber"
132
+ className="mb-0 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
133
+ autoComplete="off"
134
+ onChange={onCardNumberChange}
135
+ maxLength={19}
136
+ ref={cardNumberRef}
137
+ onFocus={(e) => onCardInputFocus(e, "cardNumber")}
138
+ onBlur={onCardInputBlur}
139
+ value={cardNumber}
140
+ />
141
+ {/* {binCardType && (
142
+ <img className="bg-red-700" src={`/${binCardType}.png`} />
143
+ )} */}
144
+ <img
145
+ className="absolute right-2 top-1/2 translate-y-1/2 bg-red-700"
146
+ src={`../Assets/images/card-type/${binCardType}.png`}
147
+ />
148
+ </label>
149
+ </div>
150
+
151
+ <div className="flex w-fit flex-col bg-red-300 p-2">
152
+ <label htmlFor="cardName" className="card-input__label">
153
+ Card Holder{" "}
154
+ </label>
155
+ <input
156
+ type="text"
157
+ // className="card-input__input"
158
+ className="mb-0 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
159
+ autoComplete="off"
160
+ name="cardHolder"
161
+ onChange={handleFormChange}
162
+ ref={cardHolderRef}
163
+ onFocus={(e) => onCardInputFocus(e, "cardHolder")}
164
+ onBlur={onCardInputBlur}
165
+ />
166
+ </div>
167
+
168
+ <div className="flex w-fit flex-col bg-red-400 p-2">
169
+ <div className="flex flex-col">
170
+ <label htmlFor="cardMonth" className="card-input__label">
171
+ Expiration
172
+ </label>
173
+ <div className="flex flex-row gap-2">
174
+ <select
175
+ className="rounded-lg p-2.5"
176
+ value={cardMonth}
177
+ name="cardMonth"
178
+ onChange={handleFormChange}
179
+ ref={cardDateRef}
180
+ onFocus={(e) => onCardInputFocus(e, "cardDate")}
181
+ onBlur={onCardInputBlur}
182
+ >
183
+ <option value="" disabled>
184
+ Month
185
+ </option>
186
+
187
+ {monthsArr.map((val, index) => (
188
+ <option key={index} value={val}>
189
+ {val}
190
+ </option>
191
+ ))}
192
+ </select>
193
+ <select
194
+ name="cardYear"
195
+ className="rounded-lg p-2.5"
196
+ value={cardYear}
197
+ onChange={handleFormChange}
198
+ onFocus={(e) => onCardInputFocus(e, "cardDate")}
199
+ onBlur={onCardInputBlur}
200
+ >
201
+ <option value="" disabled>
202
+ Year
203
+ </option>
204
+
205
+ {yearsArr.map((val, index) => (
206
+ <option key={index} value={val}>
207
+ {val}
208
+ </option>
209
+ ))}
210
+ </select>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ <div className="flex w-fit flex-col bg-red-500 p-2">
215
+ <label htmlFor="cardCvv">CCV</label>
216
+ <input
217
+ type="tel"
218
+ className="mb-0 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
219
+ maxLength={4}
220
+ autoComplete="off"
221
+ name="cardCvv"
222
+ onChange={handleFormChange}
223
+ // onFocus={onCvvFocus}
224
+ // onBlur={onCvvBlur}
225
+ ref={cardCvvRef}
226
+ />
227
+ </div>
228
+ {isCheckout && (
229
+ <div className="card-input">
230
+ <label htmlFor="rememberMe" className="card-input__label">
231
+ <input
232
+ type="checkbox"
233
+ autoComplete="off"
234
+ name="rememberMe"
235
+ checked={rememberMe}
236
+ onChange={handleFormChange}
237
+ ref={rememberMeRef}
238
+ />
239
+ Store Payment Details{" "}
240
+ </label>
241
+ </div>
242
+ )}
243
+ <div className="card-input" style={{ marginTop: "20px" }}>
244
+ <form
245
+ onSubmit={(e) => e.preventDefault()}
246
+ // ref={(ref) => setPayfortForm(ref)}
247
+ id="formSendToAps"
248
+ action={`${process.env.NEXT_PUBLIC_QAWAIM_PAYFORT_ENVIRONMENT_URL}`}
249
+ method="POST"
250
+ >
251
+ <input type="hidden" name="access_code" value={accessCode} />
252
+ <input
253
+ type="hidden"
254
+ name="merchant_identifier"
255
+ value={`${process.env.NEXT_PUBLIC_QAWAIM_PAYFORT_MERCHANT_ID}`}
256
+ />
257
+ <input type="hidden" name="language" value={"en"} />
258
+ <input
259
+ type="hidden"
260
+ name="card_number"
261
+ value={cardNumber.replace(/\s/g, "")}
262
+ />
263
+ <input type="hidden" name="expiry_date" value={expiryDate} />
264
+ <input
265
+ type="hidden"
266
+ name="signature"
267
+ value={isCheckout ? signature : registerSignature}
268
+ />
269
+ <input type="hidden" name="card_holder_name" value={cardHolder} />
270
+ <input
271
+ type="hidden"
272
+ name="merchant_reference"
273
+ // value={isCheckout ? transaction?._id : card?._id}
274
+ />
275
+ <input
276
+ type="hidden"
277
+ name="service_command"
278
+ value={isCheckout ? "TOKENIZATION" : "CREATE_TOKEN"}
279
+ />
280
+ <input
281
+ type="hidden"
282
+ name="return_url"
283
+ // value={
284
+ // isCheckout
285
+ // ? `${process.env.NEXT_PUBLIC_QAWAIM_USER_PORTAL_URL}/aps_online/response`
286
+ // : `${process.env.NEXT_PUBLIC_QAWAIM_USER_PORTAL_URL}/aps_online/register`
287
+ // }
288
+ />
289
+ {!isCheckout && (
290
+ <input
291
+ type="hidden"
292
+ name="currency"
293
+ // value={token.User.default_currency?.toUpperCase()}
294
+ />
295
+ )}
296
+ {isCheckout && (
297
+ <>
298
+ <input
299
+ type="hidden"
300
+ name="card_security_code"
301
+ value={cardCvv}
302
+ />
303
+
304
+ {/* {tokenName && (
305
+ <input type="hidden" name="token_name" value={tokenName} />
306
+ )} */}
307
+ </>
308
+ )}
309
+
310
+ <HawaButton>Pay</HawaButton>
311
+ </form>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ )
317
+ }
@@ -1,6 +1,7 @@
1
1
  import clsx from "clsx"
2
2
  import React, { useEffect } from "react"
3
3
  import { useState } from "react"
4
+ import useDiscloser from "../hooks/useDiscloser"
4
5
  import { HawaMenu } from "./HawaMenu"
5
6
 
6
7
  interface ItemCardTypes {
@@ -48,6 +49,8 @@ export const HawaItemCard: React.FunctionComponent<ItemCardTypes> = ({
48
49
  "inline-block rounded-lg p-1 text-sm text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-700"
49
50
 
50
51
  const [openActionHeader, setOpenActionHeader] = useState(false)
52
+ const {isOpen : isActionOpen, onClose : onActionClose, onOpen : onActionOpen} = useDiscloser();
53
+ const {isOpen : isDropDownOpen, onClose : onDropDownClose, onOpen : onDropDownOpen} = useDiscloser();
51
54
  const [openDropDown, setOpenDropDown] = useState(false)
52
55
 
53
56
  function handleOpenActionHeader() {
@@ -84,8 +87,9 @@ export const HawaItemCard: React.FunctionComponent<ItemCardTypes> = ({
84
87
  <HawaMenu
85
88
  buttonPosition="top-right"
86
89
  menuItems={headerActions}
87
- handleClose={setOpenDropDown}
88
- open={openDropDown}
90
+ handleOpen={onDropDownOpen}
91
+ handleClose={onDropDownClose}
92
+ open={isDropDownOpen}
89
93
  >
90
94
  <div
91
95
  className={clsx(headerActionsButtonStyle)}
@@ -8,7 +8,8 @@ interface TMenuTypes {
8
8
  headerTitle?: string
9
9
  headerSubtitle?: string
10
10
  open?: boolean
11
- handleClose?: (e: boolean) => void
11
+ handleClose?: () => void
12
+ handleOpen: () => void
12
13
  anchor?: any
13
14
  children?: ReactNode
14
15
  buttonPosition?: "top-right" | "top-left" | "bottom-right" | "bottom-left"
@@ -32,6 +33,7 @@ export const HawaMenu: React.FunctionComponent<TMenuTypes> = ({
32
33
  headerSubtitle,
33
34
  open,
34
35
  handleClose,
36
+ handleOpen,
35
37
  buttonPosition,
36
38
  children,
37
39
  }) => {
@@ -48,7 +50,13 @@ export const HawaMenu: React.FunctionComponent<TMenuTypes> = ({
48
50
  closed: "h-0 ",
49
51
  }
50
52
  return (
51
- <div className="relative w-fit " onClick={() => handleClose(!open)}>
53
+ <div
54
+ className="relative w-fit "
55
+ onClick={() => {
56
+ if (open) handleClose()
57
+ else handleOpen()
58
+ }}
59
+ >
52
60
  {children}
53
61
 
54
62
  <div
@@ -0,0 +1,82 @@
1
+ import React from "react"
2
+ import clsx from "clsx"
3
+
4
+ type THawaTimeline = {
5
+ steps: any[any]
6
+ currentStep: any
7
+ orientation: "vertical" | "horizontal"
8
+ }
9
+
10
+ export const HawaTimeline: React.FunctionComponent<THawaTimeline> = ({
11
+ orientation = "horizontal",
12
+ ...props
13
+ }) => {
14
+ let orientationStyles = {
15
+ vertical: "flex flex-col items-start w-fit",
16
+ horizontal: "flex flex-row items-baseline",
17
+ }
18
+ let lineStyles = {
19
+ vertical: {
20
+ default: "w-1 h-32 rounded-lg bg-primary-200 ml-6 my-2",
21
+ selected: "w-1 h-32 rounded-lg bg-primary-400 ml-6 my-2",
22
+ },
23
+ horizontal: {
24
+ default: "h-0.5 w-full rounded-lg bg-primary-200",
25
+ selected: "h-0.5 w-full rounded-lg bg-primary-400",
26
+ },
27
+ }
28
+ return (
29
+ <div className={clsx(orientationStyles[orientation])}>
30
+ {props.steps.map((step: any, i: number) => {
31
+ if (i == 0) {
32
+ return (
33
+ <TimelineStep
34
+ orientation={orientation}
35
+ current={i + 1 <= props.currentStep}
36
+ stepName={step}
37
+ stepNumber={i + 1}
38
+ />
39
+ )
40
+ } else {
41
+ return (
42
+ <>
43
+ <div
44
+ className={clsx(
45
+ i == props.currentStep
46
+ ? lineStyles[orientation].default
47
+ : lineStyles[orientation].selected
48
+ )}
49
+ ></div>
50
+ <TimelineStep
51
+ orientation={orientation}
52
+ current={i + 1 <= props.currentStep}
53
+ stepName={step}
54
+ stepNumber={i + 1}
55
+ />
56
+ </>
57
+ )
58
+ }
59
+ })}
60
+ </div>
61
+ )
62
+ }
63
+
64
+ const TimelineStep = (props) => (
65
+ <div
66
+ className={
67
+ props.orientation === "vertical"
68
+ ? "flex w-full flex-row items-center"
69
+ : "flex w-fit flex-col items-center justify-center p-2"
70
+ }
71
+ >
72
+ <div
73
+ className={clsx(
74
+ "m-2 mr-4 flex h-10 w-10 items-center justify-center rounded-xl ring-2 ring-primary-200 ring-offset-2",
75
+ props.current ? "bg-primary-500 text-white" : "bg-primary-200"
76
+ )}
77
+ >
78
+ {props.stepNumber}
79
+ </div>
80
+ <div className="whitespace-nowrap">{props.stepName}</div>
81
+ </div>
82
+ )