@sikka/hawa 0.1.91 → 0.1.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +66 -15
- package/dist/index.d.ts +66 -15
- package/dist/index.js +649 -362
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +836 -642
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +120 -9
- package/package.json +1 -1
- package/src/blocks/AuthForms/AppLanding.tsx +99 -51
- package/src/blocks/AuthForms/ResetPasswordForm.tsx +13 -9
- package/src/blocks/Payment/CreditCardForm.tsx +63 -2
- package/src/elements/Button.tsx +10 -1
- package/src/elements/HawaRadio.tsx +13 -13
- package/src/elements/HawaTextField.tsx +7 -2
- package/src/elements/Icons.tsx +24 -0
- package/src/elements/StickyFeatures.tsx +53 -0
- package/src/elements/Toaster.tsx +1 -3
- package/src/elements/UserReferralSource.tsx +101 -0
- package/src/elements/index.ts +2 -0
- package/src/styles.css +120 -9
- package/src/tailwind.css +16 -6
- package/src/translations/ar.json +9 -0
- package/src/translations/en.json +9 -0
package/dist/styles.css
CHANGED
|
@@ -422,7 +422,7 @@ video {
|
|
|
422
422
|
--border: 240 5.9% 90%;
|
|
423
423
|
--input: 240 5.9% 90%;
|
|
424
424
|
--ring: 240 5% 64.9%;
|
|
425
|
-
--radius:
|
|
425
|
+
--radius: 0rem;
|
|
426
426
|
--radius-inner: calc(var(--radius) - calc(var(--radius) / 3));
|
|
427
427
|
|
|
428
428
|
--layout-primary-700: #b7aff7;
|
|
@@ -470,10 +470,11 @@ video {
|
|
|
470
470
|
margin-right: 0.25em;
|
|
471
471
|
width: 0.75em;
|
|
472
472
|
vertical-align: middle;
|
|
473
|
-
color: var(--
|
|
473
|
+
color: hsl(var(--primary));
|
|
474
|
+
|
|
474
475
|
}
|
|
475
476
|
.link {
|
|
476
|
-
color: var(--
|
|
477
|
+
color: hsl(var(--primary));
|
|
477
478
|
}
|
|
478
479
|
.link:hover {
|
|
479
480
|
text-decoration: underline;
|
|
@@ -531,10 +532,10 @@ video {
|
|
|
531
532
|
height: 9px;
|
|
532
533
|
position: absolute;
|
|
533
534
|
top: 6px;
|
|
534
|
-
left:
|
|
535
|
+
left: 3px;
|
|
535
536
|
content: " ";
|
|
536
537
|
display: block;
|
|
537
|
-
background: var(--
|
|
538
|
+
background: hsl(var(--primary));
|
|
538
539
|
}
|
|
539
540
|
.radio-item-bordered input[type="radio"]:checked + label:after {
|
|
540
541
|
border-radius: 100%;
|
|
@@ -545,7 +546,7 @@ video {
|
|
|
545
546
|
left: 23px;
|
|
546
547
|
content: " ";
|
|
547
548
|
display: block;
|
|
548
|
-
background: var(--
|
|
549
|
+
background: hsl(var(--primary));
|
|
549
550
|
}
|
|
550
551
|
* {
|
|
551
552
|
border-color: hsl(var(--border));
|
|
@@ -803,6 +804,9 @@ video {
|
|
|
803
804
|
.right-0 {
|
|
804
805
|
right: 0px;
|
|
805
806
|
}
|
|
807
|
+
.right-1 {
|
|
808
|
+
right: 0.25rem;
|
|
809
|
+
}
|
|
806
810
|
.right-2 {
|
|
807
811
|
right: 0.5rem;
|
|
808
812
|
}
|
|
@@ -848,6 +852,9 @@ video {
|
|
|
848
852
|
.top-\[22px\] {
|
|
849
853
|
top: 22px;
|
|
850
854
|
}
|
|
855
|
+
.top-\[41px\] {
|
|
856
|
+
top: 41px;
|
|
857
|
+
}
|
|
851
858
|
.top-\[50\%\] {
|
|
852
859
|
top: 50%;
|
|
853
860
|
}
|
|
@@ -905,6 +912,10 @@ video {
|
|
|
905
912
|
margin-left: 0.5rem;
|
|
906
913
|
margin-right: 0.5rem;
|
|
907
914
|
}
|
|
915
|
+
.mx-auto {
|
|
916
|
+
margin-left: auto;
|
|
917
|
+
margin-right: auto;
|
|
918
|
+
}
|
|
908
919
|
.my-0 {
|
|
909
920
|
margin-top: 0px;
|
|
910
921
|
margin-bottom: 0px;
|
|
@@ -1386,6 +1397,9 @@ video {
|
|
|
1386
1397
|
.w-screen {
|
|
1387
1398
|
width: 100vw;
|
|
1388
1399
|
}
|
|
1400
|
+
.min-w-0 {
|
|
1401
|
+
min-width: 0px;
|
|
1402
|
+
}
|
|
1389
1403
|
.min-w-\[220px\] {
|
|
1390
1404
|
min-width: 220px;
|
|
1391
1405
|
}
|
|
@@ -1418,6 +1432,9 @@ video {
|
|
|
1418
1432
|
.max-w-2xs {
|
|
1419
1433
|
max-width: 250px;
|
|
1420
1434
|
}
|
|
1435
|
+
.max-w-5xl {
|
|
1436
|
+
max-width: 64rem;
|
|
1437
|
+
}
|
|
1421
1438
|
.max-w-\[200px\] {
|
|
1422
1439
|
max-width: 200px;
|
|
1423
1440
|
}
|
|
@@ -1696,6 +1713,13 @@ video {
|
|
|
1696
1713
|
-moz-column-gap: 0.75rem;
|
|
1697
1714
|
column-gap: 0.75rem;
|
|
1698
1715
|
}
|
|
1716
|
+
.gap-x-8 {
|
|
1717
|
+
-moz-column-gap: 2rem;
|
|
1718
|
+
column-gap: 2rem;
|
|
1719
|
+
}
|
|
1720
|
+
.gap-y-10 {
|
|
1721
|
+
row-gap: 2.5rem;
|
|
1722
|
+
}
|
|
1699
1723
|
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
|
|
1700
1724
|
--tw-space-x-reverse: 0;
|
|
1701
1725
|
margin-right: calc(0.25rem * var(--tw-space-x-reverse));
|
|
@@ -2104,6 +2128,10 @@ video {
|
|
|
2104
2128
|
--tw-bg-opacity: 1;
|
|
2105
2129
|
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
|
2106
2130
|
}
|
|
2131
|
+
.bg-indigo-600 {
|
|
2132
|
+
--tw-bg-opacity: 1;
|
|
2133
|
+
background-color: rgb(79 70 229 / var(--tw-bg-opacity));
|
|
2134
|
+
}
|
|
2107
2135
|
.bg-info {
|
|
2108
2136
|
--tw-bg-opacity: 1;
|
|
2109
2137
|
background-color: hsl(var(--info) / var(--tw-bg-opacity));
|
|
@@ -2337,6 +2365,10 @@ video {
|
|
|
2337
2365
|
padding-top: 0.625rem;
|
|
2338
2366
|
padding-bottom: 0.625rem;
|
|
2339
2367
|
}
|
|
2368
|
+
.py-24 {
|
|
2369
|
+
padding-top: 6rem;
|
|
2370
|
+
padding-bottom: 6rem;
|
|
2371
|
+
}
|
|
2340
2372
|
.py-3 {
|
|
2341
2373
|
padding-top: 0.75rem;
|
|
2342
2374
|
padding-bottom: 0.75rem;
|
|
@@ -2428,6 +2460,9 @@ video {
|
|
|
2428
2460
|
.text-right {
|
|
2429
2461
|
text-align: right;
|
|
2430
2462
|
}
|
|
2463
|
+
.text-start {
|
|
2464
|
+
text-align: start;
|
|
2465
|
+
}
|
|
2431
2466
|
.align-middle {
|
|
2432
2467
|
vertical-align: middle;
|
|
2433
2468
|
}
|
|
@@ -2524,6 +2559,12 @@ video {
|
|
|
2524
2559
|
.leading-4 {
|
|
2525
2560
|
line-height: 1rem;
|
|
2526
2561
|
}
|
|
2562
|
+
.leading-7 {
|
|
2563
|
+
line-height: 1.75rem;
|
|
2564
|
+
}
|
|
2565
|
+
.leading-8 {
|
|
2566
|
+
line-height: 2rem;
|
|
2567
|
+
}
|
|
2527
2568
|
.leading-\[25px\] {
|
|
2528
2569
|
line-height: 25px;
|
|
2529
2570
|
}
|
|
@@ -2608,6 +2649,10 @@ video {
|
|
|
2608
2649
|
--tw-text-opacity: 1;
|
|
2609
2650
|
color: rgb(21 128 61 / var(--tw-text-opacity));
|
|
2610
2651
|
}
|
|
2652
|
+
.text-indigo-600 {
|
|
2653
|
+
--tw-text-opacity: 1;
|
|
2654
|
+
color: rgb(79 70 229 / var(--tw-text-opacity));
|
|
2655
|
+
}
|
|
2611
2656
|
.text-info-foreground {
|
|
2612
2657
|
--tw-text-opacity: 1;
|
|
2613
2658
|
color: hsl(var(--info-foreground) / var(--tw-text-opacity));
|
|
@@ -2952,6 +2997,10 @@ video {
|
|
|
2952
2997
|
.repeat-infinite {
|
|
2953
2998
|
animation-iteration-count: infinite;
|
|
2954
2999
|
}
|
|
3000
|
+
.shadow-color-primary {
|
|
3001
|
+
--tw-shadow: 0.25rem 0.25rem hsl(var(--primary));
|
|
3002
|
+
box-shadow: var(--tw-shadow);
|
|
3003
|
+
}
|
|
2955
3004
|
/* Chrome, Safari and Opera */
|
|
2956
3005
|
.no-scrollbar::-webkit-scrollbar {
|
|
2957
3006
|
display: none;
|
|
@@ -3321,6 +3370,26 @@ body {
|
|
|
3321
3370
|
.focus-visible\:ring-offset-2:focus-visible {
|
|
3322
3371
|
--tw-ring-offset-width: 2px;
|
|
3323
3372
|
}
|
|
3373
|
+
.active\:translate-x-0:active {
|
|
3374
|
+
--tw-translate-x: 0px;
|
|
3375
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
3376
|
+
}
|
|
3377
|
+
.active\:translate-x-0\.5:active {
|
|
3378
|
+
--tw-translate-x: 0.125rem;
|
|
3379
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
3380
|
+
}
|
|
3381
|
+
.active\:translate-y-0:active {
|
|
3382
|
+
--tw-translate-y: 0px;
|
|
3383
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
3384
|
+
}
|
|
3385
|
+
.active\:translate-y-0\.5:active {
|
|
3386
|
+
--tw-translate-y: 0.125rem;
|
|
3387
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
3388
|
+
}
|
|
3389
|
+
.active\:shadow-color-primary-active:active {
|
|
3390
|
+
--tw-shadow: 0.125rem 0.125rem hsl(var(--primary));
|
|
3391
|
+
box-shadow: var(--tw-shadow);
|
|
3392
|
+
}
|
|
3324
3393
|
.disabled\:pointer-events-none:disabled {
|
|
3325
3394
|
pointer-events: none;
|
|
3326
3395
|
}
|
|
@@ -3798,6 +3867,10 @@ body {
|
|
|
3798
3867
|
:is(.dark .dark\:bg-background) {
|
|
3799
3868
|
background-color: hsl(var(--background));
|
|
3800
3869
|
}
|
|
3870
|
+
:is(.dark .dark\:bg-black) {
|
|
3871
|
+
--tw-bg-opacity: 1;
|
|
3872
|
+
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
|
3873
|
+
}
|
|
3801
3874
|
:is(.dark .dark\:bg-blue-200) {
|
|
3802
3875
|
--tw-bg-opacity: 1;
|
|
3803
3876
|
background-color: rgb(191 219 254 / var(--tw-bg-opacity));
|
|
@@ -3993,9 +4066,8 @@ body {
|
|
|
3993
4066
|
--tw-ring-opacity: 1;
|
|
3994
4067
|
--tw-ring-color: rgb(31 41 55 / var(--tw-ring-opacity));
|
|
3995
4068
|
}
|
|
3996
|
-
:is(.dark .peer:checked ~ .dark\:peer-checked\:text-
|
|
3997
|
-
|
|
3998
|
-
color: rgb(59 130 246 / var(--tw-text-opacity));
|
|
4069
|
+
:is(.dark .peer:checked ~ .dark\:peer-checked\:text-primary) {
|
|
4070
|
+
color: hsl(var(--primary));
|
|
3999
4071
|
}
|
|
4000
4072
|
@media (min-width: 440px) {
|
|
4001
4073
|
|
|
@@ -4073,6 +4145,11 @@ body {
|
|
|
4073
4145
|
padding: 5rem;
|
|
4074
4146
|
}
|
|
4075
4147
|
|
|
4148
|
+
.sm\:py-32 {
|
|
4149
|
+
padding-top: 8rem;
|
|
4150
|
+
padding-bottom: 8rem;
|
|
4151
|
+
}
|
|
4152
|
+
|
|
4076
4153
|
.sm\:text-left {
|
|
4077
4154
|
text-align: left;
|
|
4078
4155
|
}
|
|
@@ -4082,6 +4159,11 @@ body {
|
|
|
4082
4159
|
line-height: 2rem;
|
|
4083
4160
|
}
|
|
4084
4161
|
|
|
4162
|
+
.sm\:text-4xl {
|
|
4163
|
+
font-size: 2.25rem;
|
|
4164
|
+
line-height: 2.5rem;
|
|
4165
|
+
}
|
|
4166
|
+
|
|
4085
4167
|
.sm\:text-base {
|
|
4086
4168
|
font-size: 1rem;
|
|
4087
4169
|
line-height: 1.5rem;
|
|
@@ -4108,6 +4190,14 @@ body {
|
|
|
4108
4190
|
}
|
|
4109
4191
|
@media (min-width: 768px) {
|
|
4110
4192
|
|
|
4193
|
+
.md\:sticky {
|
|
4194
|
+
position: sticky;
|
|
4195
|
+
}
|
|
4196
|
+
|
|
4197
|
+
.md\:top-10 {
|
|
4198
|
+
top: 2.5rem;
|
|
4199
|
+
}
|
|
4200
|
+
|
|
4111
4201
|
.md\:mb-0 {
|
|
4112
4202
|
margin-bottom: 0px;
|
|
4113
4203
|
}
|
|
@@ -4128,6 +4218,10 @@ body {
|
|
|
4128
4218
|
margin-right: 1rem;
|
|
4129
4219
|
}
|
|
4130
4220
|
|
|
4221
|
+
.md\:mt-0 {
|
|
4222
|
+
margin-top: 0px;
|
|
4223
|
+
}
|
|
4224
|
+
|
|
4131
4225
|
.md\:h-auto {
|
|
4132
4226
|
height: auto;
|
|
4133
4227
|
}
|
|
@@ -4136,6 +4230,10 @@ body {
|
|
|
4136
4230
|
width: 12rem;
|
|
4137
4231
|
}
|
|
4138
4232
|
|
|
4233
|
+
.md\:w-\[28rem\] {
|
|
4234
|
+
width: 28rem;
|
|
4235
|
+
}
|
|
4236
|
+
|
|
4139
4237
|
.md\:w-full {
|
|
4140
4238
|
width: 100%;
|
|
4141
4239
|
}
|
|
@@ -4220,6 +4318,10 @@ body {
|
|
|
4220
4318
|
max-width: 80rem;
|
|
4221
4319
|
}
|
|
4222
4320
|
|
|
4321
|
+
.lg\:max-w-none {
|
|
4322
|
+
max-width: none;
|
|
4323
|
+
}
|
|
4324
|
+
|
|
4223
4325
|
.lg\:columns-4 {
|
|
4224
4326
|
-moz-columns: 4;
|
|
4225
4327
|
columns: 4;
|
|
@@ -4232,6 +4334,15 @@ body {
|
|
|
4232
4334
|
.lg\:grid-cols-4 {
|
|
4233
4335
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
4234
4336
|
}
|
|
4337
|
+
|
|
4338
|
+
.lg\:gap-y-16 {
|
|
4339
|
+
row-gap: 4rem;
|
|
4340
|
+
}
|
|
4341
|
+
|
|
4342
|
+
.lg\:px-8 {
|
|
4343
|
+
padding-left: 2rem;
|
|
4344
|
+
padding-right: 2rem;
|
|
4345
|
+
}
|
|
4235
4346
|
}
|
|
4236
4347
|
@media (min-width: 1280px) {
|
|
4237
4348
|
|
package/package.json
CHANGED
|
@@ -5,72 +5,121 @@ import { Button } from "../../elements/Button"
|
|
|
5
5
|
import { Icons } from "../../elements/Icons"
|
|
6
6
|
|
|
7
7
|
type AppLandingTypes = {
|
|
8
|
-
handleSignIn: () => void
|
|
9
|
-
handleSignUp: () => void
|
|
10
|
-
handleLanguage: () => void
|
|
11
|
-
handleColorMode: () => void
|
|
12
8
|
texts?: {
|
|
13
9
|
signIn: string
|
|
14
10
|
signUp: string
|
|
15
11
|
lang: string
|
|
16
12
|
newUserText?: string
|
|
17
13
|
createAccount?: string
|
|
14
|
+
continueWithGoogle?: string
|
|
15
|
+
continueWithTwitter?: string
|
|
16
|
+
continueWithApple?: string
|
|
17
|
+
continueWithMicrosoft?: string
|
|
18
|
+
continueWithGithub?: string
|
|
19
|
+
continueWithEmail?: string
|
|
20
|
+
continueWithPhone?: string
|
|
18
21
|
}
|
|
22
|
+
viaGoogle?: boolean
|
|
23
|
+
viaTwitter?: boolean
|
|
24
|
+
viaGithub?: boolean
|
|
25
|
+
viaMicrosoft?: boolean
|
|
26
|
+
viaEmail?: boolean
|
|
27
|
+
viaPhone?: boolean
|
|
28
|
+
viaApple?: boolean
|
|
29
|
+
|
|
19
30
|
withoutSignUp?: boolean
|
|
20
|
-
handleRouteToSignUp?: () => void
|
|
21
31
|
size: "small" | "normal" | "full"
|
|
32
|
+
direction: "rtl" | "ltr"
|
|
33
|
+
handleSignIn: () => void
|
|
34
|
+
handleSignUp: () => void
|
|
35
|
+
handleLanguage: () => void
|
|
36
|
+
handleColorMode: () => void
|
|
37
|
+
handleRouteToSignUp?: () => void
|
|
38
|
+
handleGoogle?: () => void
|
|
39
|
+
handleTwitter?: () => void
|
|
40
|
+
handleApple?: () => void
|
|
41
|
+
handleMicrosoft?: () => void
|
|
42
|
+
handleGithub?: () => void
|
|
43
|
+
handleEmail?: () => void
|
|
44
|
+
handlePhone?: () => void
|
|
22
45
|
}
|
|
23
46
|
|
|
24
|
-
//TODO: update Google auth button
|
|
25
47
|
export const AppLanding: FC<AppLandingTypes> = (props) => {
|
|
26
48
|
return (
|
|
27
|
-
<div>
|
|
49
|
+
<div dir={props.direction}>
|
|
28
50
|
<Card>
|
|
29
51
|
<CardContent headless className="flex flex-col gap-6">
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// <Button onClick={props.handleSignIn}>Continue With Google</Button>
|
|
52
|
+
{props.viaGoogle && (
|
|
53
|
+
<Button
|
|
54
|
+
className="flex flex-row items-center gap-2"
|
|
55
|
+
variant="outline"
|
|
56
|
+
onClick={props.handleGoogle}
|
|
57
|
+
>
|
|
58
|
+
<Icons.google className="h-4 w-4" />
|
|
59
|
+
{props.texts?.continueWithGoogle ?? "Continue With Google"}
|
|
60
|
+
</Button>
|
|
61
|
+
)}
|
|
62
|
+
{props.viaGithub && (
|
|
63
|
+
<Button
|
|
64
|
+
className="flex flex-row items-center gap-2"
|
|
65
|
+
variant="outline"
|
|
66
|
+
onClick={props.handleGithub}
|
|
67
|
+
>
|
|
68
|
+
<Icons.gitHub className="h-4 w-4" />
|
|
69
|
+
{props.texts?.continueWithGithub ?? "Continue With Github"}
|
|
70
|
+
</Button>
|
|
71
|
+
)}
|
|
72
|
+
{props.viaTwitter && (
|
|
73
|
+
<Button
|
|
74
|
+
className="flex flex-row items-center gap-2"
|
|
75
|
+
variant="outline"
|
|
76
|
+
onClick={props.handleTwitter}
|
|
77
|
+
>
|
|
78
|
+
<Icons.twitter className="h-4 w-4" />
|
|
79
|
+
{props.texts?.continueWithTwitter ?? "Continue With Twitter"}
|
|
80
|
+
</Button>
|
|
81
|
+
)}
|
|
82
|
+
{props.viaApple && (
|
|
83
|
+
<Button
|
|
84
|
+
className="flex flex-row items-center gap-2"
|
|
85
|
+
variant="outline"
|
|
86
|
+
onClick={props.handleApple}
|
|
87
|
+
>
|
|
88
|
+
<Icons.apple className="h-4 w-4" />
|
|
89
|
+
{props.texts?.continueWithApple ?? "Continue With Apple"}
|
|
90
|
+
</Button>
|
|
70
91
|
)}
|
|
71
|
-
{props.
|
|
72
|
-
<Button
|
|
73
|
-
|
|
92
|
+
{props.viaMicrosoft && (
|
|
93
|
+
<Button
|
|
94
|
+
className="flex flex-row items-center gap-2"
|
|
95
|
+
variant="outline"
|
|
96
|
+
onClick={props.handleMicrosoft}
|
|
97
|
+
>
|
|
98
|
+
<Icons.microsoft className="h-4 w-4" />
|
|
99
|
+
{props.texts?.continueWithMicrosoft ?? "Continue With Microsoft"}
|
|
100
|
+
</Button>
|
|
101
|
+
)}
|
|
102
|
+
{props.viaEmail && (
|
|
103
|
+
<Button
|
|
104
|
+
className="flex flex-row items-center gap-2"
|
|
105
|
+
variant="outline"
|
|
106
|
+
onClick={props.handleEmail}
|
|
107
|
+
>
|
|
108
|
+
<Icons.mail className="h-4 w-4" />
|
|
109
|
+
{props.texts?.continueWithEmail ?? "Continue With Email"}
|
|
110
|
+
</Button>
|
|
111
|
+
)}
|
|
112
|
+
{props.viaPhone && (
|
|
113
|
+
<Button
|
|
114
|
+
className="flex flex-row items-center gap-2"
|
|
115
|
+
variant="outline"
|
|
116
|
+
onClick={props.handlePhone}
|
|
117
|
+
>
|
|
118
|
+
<Icons.phone className="h-4 w-4" />
|
|
119
|
+
{props.texts?.continueWithPhone ?? "Continue With Phone"}
|
|
120
|
+
</Button>
|
|
121
|
+
)}
|
|
122
|
+
|
|
74
123
|
{!props.withoutSignUp && (
|
|
75
124
|
<div className="p-3 text-center text-sm font-normal dark:text-gray-300">
|
|
76
125
|
{props.texts.newUserText}{" "}
|
|
@@ -82,7 +131,6 @@ export const AppLanding: FC<AppLandingTypes> = (props) => {
|
|
|
82
131
|
</span>
|
|
83
132
|
</div>
|
|
84
133
|
)}
|
|
85
|
-
|
|
86
134
|
</CardContent>
|
|
87
135
|
</Card>
|
|
88
136
|
<div className="mt-6 flex flex-row justify-between">
|
|
@@ -25,6 +25,8 @@ type ResetPasswordType = {
|
|
|
25
25
|
signUpText: string
|
|
26
26
|
dontHaveAccount: string
|
|
27
27
|
}
|
|
28
|
+
headless?: boolean
|
|
29
|
+
direction?: "rtl" | "ltr"
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export const ResetPasswordForm: FC<ResetPasswordType> = (props) => {
|
|
@@ -36,17 +38,19 @@ export const ResetPasswordForm: FC<ResetPasswordType> = (props) => {
|
|
|
36
38
|
control,
|
|
37
39
|
} = methods
|
|
38
40
|
return (
|
|
39
|
-
<Card>
|
|
41
|
+
<Card dir={props.direction}>
|
|
40
42
|
{!props.sent ? (
|
|
41
43
|
<>
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
{!props.headless && (
|
|
45
|
+
<CardHeader>
|
|
46
|
+
<CardTitle>Reset Password</CardTitle>
|
|
47
|
+
<CardDescription>
|
|
48
|
+
Enter your email to reset your account password
|
|
49
|
+
</CardDescription>
|
|
50
|
+
</CardHeader>
|
|
51
|
+
)}
|
|
48
52
|
<form onSubmit={handleSubmit(props.handleResetPassword)}>
|
|
49
|
-
<CardContent>
|
|
53
|
+
<CardContent headless={props.headless}>
|
|
50
54
|
<Controller
|
|
51
55
|
control={control}
|
|
52
56
|
name="email"
|
|
@@ -70,7 +74,7 @@ export const ResetPasswordForm: FC<ResetPasswordType> = (props) => {
|
|
|
70
74
|
},
|
|
71
75
|
}}
|
|
72
76
|
/>
|
|
73
|
-
<div className="
|
|
77
|
+
<div className="pb-2 text-start text-sm dark:text-gray-300">
|
|
74
78
|
{props.texts?.dontHaveAccount ?? "Don't have an account? "}
|
|
75
79
|
<span
|
|
76
80
|
onClick={props.handleRouteToSignUp}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC } from "react"
|
|
1
|
+
import React, { FC, useEffect, useState } from "react"
|
|
2
2
|
import { HawaTextField } from "../../elements"
|
|
3
3
|
import { Controller, useForm } from "react-hook-form"
|
|
4
4
|
import { Card, CardContent, CardFooter } from "../../elements/Card"
|
|
@@ -10,6 +10,8 @@ type CreditCardFormTypes = {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const CreditCardForm: FC<CreditCardFormTypes> = (props) => {
|
|
13
|
+
const [cardNumber, setCardNumber] = useState("")
|
|
14
|
+
const [cardType, setCardType] = useState("")
|
|
13
15
|
const methods = useForm()
|
|
14
16
|
const {
|
|
15
17
|
formState: { errors },
|
|
@@ -17,6 +19,56 @@ export const CreditCardForm: FC<CreditCardFormTypes> = (props) => {
|
|
|
17
19
|
control,
|
|
18
20
|
} = methods
|
|
19
21
|
|
|
22
|
+
const getCardType = (card_bin) => {
|
|
23
|
+
const visa_regex = /^4[0-9]{0,15}$/m
|
|
24
|
+
const mastercard_regex = /^5$|^5[0-5][0-9]{0,16}$/m
|
|
25
|
+
const amex_regex = /^3$|^3[47][0-9]{0,13}$/m
|
|
26
|
+
const mada_regex =
|
|
27
|
+
/^(440647|440795|446404|457865|968208|457997|474491|636120|417633|468540|468541|468542|468543|968201|446393|409201|458456|484783|462220|455708|410621|455036|486094|486095|486096|504300|440533|489318|489319|445564|968211|410685|406996|432328|428671|428672|428673|968206|446672|543357|434107|407197|407395|412565|431361|604906|521076|529415|535825|543085|524130|554180|549760|968209|524514|529741|537767|535989|536023|513213|520058|558563|588982|589005|531095|530906|532013|968204|422817|422818|422819|428331|483010|483011|483012|589206|968207|419593|439954|530060|531196|420132)/
|
|
28
|
+
const meeza_regex =
|
|
29
|
+
/^507803[0-6][0-9]|507808[3-9][0-9]|507809[0-9][0-9]|507810[0-2][0-9]/
|
|
30
|
+
let card_type = "visa"
|
|
31
|
+
if (card_bin.replace(/[^\d]/g, "").match(mada_regex)) {
|
|
32
|
+
card_type = "mada"
|
|
33
|
+
} else if (card_bin.replace(/[^\d]/g, "").match(meeza_regex)) {
|
|
34
|
+
card_type = "meeza"
|
|
35
|
+
} else if (card_bin.replace(/[^\d]/g, "").match(visa_regex)) {
|
|
36
|
+
card_type = "visa"
|
|
37
|
+
} else if (card_bin.replace(/[^\d]/g, "").match(mastercard_regex)) {
|
|
38
|
+
card_type = "mastercard"
|
|
39
|
+
} else if (card_bin.replace(/[^\d]/g, "").match(amex_regex)) {
|
|
40
|
+
card_type = "amex"
|
|
41
|
+
}
|
|
42
|
+
return card_type
|
|
43
|
+
}
|
|
44
|
+
const onCardNumberChange = (event) => {
|
|
45
|
+
let { value, name } = event.target
|
|
46
|
+
let cardNumber = value
|
|
47
|
+
value = value.replace(/\D/g, "")
|
|
48
|
+
if (/^3[47]\d{0,13}$/.test(value)) {
|
|
49
|
+
cardNumber = value
|
|
50
|
+
.replace(/(\d{4})/, "$1 ")
|
|
51
|
+
.replace(/(\d{4}) (\d{6})/, "$1 $2 ")
|
|
52
|
+
} else if (/^3(?:0[0-5]|[68]\d)\d{0,11}$/.test(value)) {
|
|
53
|
+
// diner's club, 14 digits
|
|
54
|
+
cardNumber = value
|
|
55
|
+
.replace(/(\d{4})/, "$1 ")
|
|
56
|
+
.replace(/(\d{4}) (\d{6})/, "$1 $2 ")
|
|
57
|
+
} else if (/^\d{0,16}$/.test(value)) {
|
|
58
|
+
// regular cc number, 16 digits
|
|
59
|
+
cardNumber = value
|
|
60
|
+
.replace(/(\d{4})/, "$1 ")
|
|
61
|
+
.replace(/(\d{4}) (\d{4})/, "$1 $2 ")
|
|
62
|
+
.replace(/(\d{4}) (\d{4}) (\d{4})/, "$1 $2 $3 ")
|
|
63
|
+
}
|
|
64
|
+
console.log("card number is ", cardNumber.trimRight())
|
|
65
|
+
setCardNumber(cardNumber.trimRight())
|
|
66
|
+
// onUpdateState(name, cardNumber);
|
|
67
|
+
}
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
let cardTypeSlug = getCardType(cardNumber)
|
|
70
|
+
setCardType(cardTypeSlug)
|
|
71
|
+
})
|
|
20
72
|
return (
|
|
21
73
|
<Card>
|
|
22
74
|
<form onSubmit={handleSubmit(props.handle)}>
|
|
@@ -24,15 +76,24 @@ export const CreditCardForm: FC<CreditCardFormTypes> = (props) => {
|
|
|
24
76
|
<div className="flex flex-row gap-4">
|
|
25
77
|
<Controller
|
|
26
78
|
control={control}
|
|
27
|
-
name="
|
|
79
|
+
name="cardNumber"
|
|
28
80
|
render={({ field }) => (
|
|
29
81
|
<HawaTextField
|
|
30
82
|
width="full"
|
|
31
83
|
name="cardNumber"
|
|
32
84
|
placeholder="1234 1234 1234 1234"
|
|
33
85
|
type="number"
|
|
86
|
+
onChange={onCardNumberChange}
|
|
87
|
+
// onChange={(e) => setCardNumber(e.target.value)}
|
|
34
88
|
label="Card Number"
|
|
35
89
|
helpertext={errors.password?.message}
|
|
90
|
+
iconInside={
|
|
91
|
+
<img
|
|
92
|
+
src={`https://sikka-images.s3.ap-southeast-1.amazonaws.com/payment-symbols/borderless/${cardType}.png`}
|
|
93
|
+
alt=""
|
|
94
|
+
className="h-8"
|
|
95
|
+
/>
|
|
96
|
+
}
|
|
36
97
|
/>
|
|
37
98
|
)}
|
|
38
99
|
rules={{
|
package/src/elements/Button.tsx
CHANGED
|
@@ -19,6 +19,8 @@ const buttonVariants = cva(
|
|
|
19
19
|
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
20
20
|
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
21
21
|
link: "text-primary underline-offset-4 hover:underline",
|
|
22
|
+
neoBrutalism:
|
|
23
|
+
"cursor-pointer transition-all uppercase font-mono dark:bg-black font-bold py-2 px-4 rounded border-2 border-primary shadow-color-primary transition-[transform_50ms, box-shadow_50ms] active:translate-x-0.5 active:translate-y-0.5 active:shadow-color-primary-active",
|
|
22
24
|
},
|
|
23
25
|
size: {
|
|
24
26
|
default: "h-10 px-4 py-2",
|
|
@@ -59,6 +61,13 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
59
61
|
ref
|
|
60
62
|
) => {
|
|
61
63
|
const Comp = "button"
|
|
64
|
+
|
|
65
|
+
// Determine the color for the HawaLoading component based on the variant
|
|
66
|
+
const loadingColor =
|
|
67
|
+
variant === "outline" || variant === "ghost" || variant === "neoBrutalism"
|
|
68
|
+
? "bg-primary"
|
|
69
|
+
: "bg-primary-foreground"
|
|
70
|
+
|
|
62
71
|
return (
|
|
63
72
|
<Comp
|
|
64
73
|
className={cn(buttonVariants({ variant, size, className }))}
|
|
@@ -68,7 +77,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
68
77
|
{isLoading ? (
|
|
69
78
|
<HawaLoading
|
|
70
79
|
design="dots-pulse"
|
|
71
|
-
color=
|
|
80
|
+
color={loadingColor} // Apply the computed color here
|
|
72
81
|
size="button"
|
|
73
82
|
/>
|
|
74
83
|
) : (
|