@gait-financial/react 0.0.16 → 0.1.0

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/wc/button.js DELETED
@@ -1,940 +0,0 @@
1
- (function(k){"use strict";function $(r,t){const e=r.replace("#",""),i=parseInt(e,16),a=i>>16&255,n=i>>8&255,o=i&255,d=Math.max(0,Math.floor(a*(1-t))),s=Math.max(0,Math.floor(n*(1-t))),l=Math.max(0,Math.floor(o*(1-t)));return`#${(d<<16|s<<8|l).toString(16).padStart(6,"0")}`}function T(r){const t=r.replace("#",""),e=parseInt(t,16),i=e>>16&255,a=e>>8&255,n=e&255;return(.299*i+.587*a+.114*n)/255<.5}const c={primary:{main:"rgb(47, 44, 37)",dark:"rgb(35, 33, 28)",contrastText:"#ffffff"},cta:{main:"#4147BF"},secondary:{main:"rgb(241, 234, 221)",dark:"rgb(235, 226, 207)",contrastText:"rgb(47, 44, 37)"}},x={sm:"8px",md:"16px",lg:"24px"},q={md:"8px"},g={normal:"250ms ease-in-out"},R={modalBackdrop:1040},b={fontFamily:{primary:'"Inter", "Helvetica", "Arial", sans-serif'},fontSize:{sm:"0.875rem",md:"1rem",lg:"1.125rem"},fontWeight:{medium:500},lineHeight:{normal:1.5}};function z(r,t,e,i){return t?{bg:t,bgHover:e(t,.15),bgActive:e(t,.25),color:i(t)?"#ffffff":"#000000"}:r==="dark"?{bg:c.primary.main,bgHover:c.primary.dark,bgActive:c.primary.dark,color:c.primary.contrastText}:{bg:c.secondary.main,bgHover:c.secondary.dark,bgActive:c.secondary.dark,color:c.secondary.contrastText}}function N(r){return{small:{padding:"8px 20px",fontSize:b.fontSize.sm,minHeight:"36px"},medium:{padding:"12px 28px",fontSize:b.fontSize.md,minHeight:"44px"},large:{padding:"16px 36px",fontSize:b.fontSize.lg,minHeight:"52px"}}[r]}function G(r,t,e,i,a){const n=z(r,e,i,a),o=N(t);return`
2
- <style>
3
- :host {
4
- display: inline-block;
5
- --gait-button-bg: ${n.bg};
6
- --gait-button-bg-hover: ${n.bgHover};
7
- --gait-button-bg-active: ${n.bgActive};
8
- --gait-button-color: ${n.color};
9
- --gait-button-padding: ${o.padding};
10
- --gait-button-font-size: ${o.fontSize};
11
- --gait-button-min-height: ${o.minHeight};
12
- }
13
-
14
- button {
15
- display: inline-flex;
16
- align-items: center;
17
- justify-content: center;
18
- gap: ${x.sm};
19
-
20
- font-family: ${b.fontFamily.primary};
21
- font-weight: ${b.fontWeight.medium};
22
- line-height: ${b.lineHeight.normal};
23
- font-size: var(--gait-button-font-size);
24
-
25
- padding: var(--gait-button-padding);
26
- min-height: var(--gait-button-min-height);
27
-
28
- background-color: var(--gait-button-bg);
29
- color: var(--gait-button-color);
30
-
31
- border: none;
32
- border-radius: ${q.md};
33
- cursor: pointer;
34
-
35
- transition: all ${g.normal};
36
-
37
- /* Remove default button styles */
38
- outline: none;
39
- text-decoration: none;
40
- user-select: none;
41
- will-change: transform, box-shadow;
42
- }
43
-
44
- button:hover:not(:disabled) {
45
- background-color: var(--gait-button-bg-hover);
46
- }
47
-
48
- button:active:not(:disabled) {
49
- background-color: var(--gait-button-bg-active);
50
- transform: translateY(1px);
51
- }
52
-
53
- button:focus-visible {
54
- outline: 2px solid var(--gait-button-bg);
55
- outline-offset: 2px;
56
- }
57
-
58
- button:disabled {
59
- opacity: 0.6;
60
- cursor: not-allowed;
61
- pointer-events: none;
62
- }
63
-
64
- /* Allow custom styling via :host */
65
- :host([style*="width"]) button {
66
- width: 100%;
67
- }
68
- </style>
69
- `}function O(){if(document.getElementById("gait-modal-styles"))return;const r=document.createElement("style");r.id="gait-modal-styles",r.textContent=`
70
- /* Modal Backdrop - The overlay behind the modal */
71
- .gait-modal-backdrop {
72
- position: fixed;
73
- top: 0;
74
- left: 0;
75
- right: 0;
76
- bottom: 0;
77
- background-color: rgba(0, 0, 0, 0.5);
78
- display: flex;
79
- align-items: center;
80
- justify-content: center;
81
- z-index: ${R.modalBackdrop};
82
- opacity: 0;
83
- transition: opacity ${g.normal};
84
- overflow: hidden;
85
- }
86
-
87
- .gait-modal-backdrop.gait-modal-open {
88
- opacity: 1;
89
- }
90
-
91
- /* Modal Container - The main modal box */
92
- .gait-modal-container {
93
- background: #fff;
94
- border-radius: 12px;
95
- max-width: 1080px;
96
- width: 60%;
97
- max-height: 90vh;
98
- display: flex;
99
- flex-direction: column;
100
- overflow: hidden;
101
- }
102
-
103
- .gait-modal-backdrop.gait-modal-open .gait-modal-container {
104
- transform: scale(1);
105
- }
106
-
107
- /* Modal Header - The title section with close icon */
108
- .gait-modal-header {
109
- padding: 16px 24px;
110
- border-bottom: 1px solid #e5e7eb;
111
- display: flex;
112
- justify-content: space-between;
113
- align-items: center;
114
- }
115
-
116
- .gait-modal-header-title {
117
- font-size: 20px;
118
- font-weight: 600;
119
- margin: 0;
120
- }
121
-
122
- .gait-modal-close-icon {
123
- background: none;
124
- border: none;
125
- padding: 8px;
126
- border-radius: 999px;
127
- cursor: pointer;
128
- display: flex;
129
- align-items: center;
130
- justify-content: center;
131
- color: #6b7280;
132
- width: 28px;
133
- height: 28px;
134
- }
135
-
136
- .gait-modal-close-icon:hover {
137
- background-color: #f3f4f6;
138
- color: #111827;
139
- }
140
-
141
- .gait-modal-close-icon svg {
142
- width: 14px;
143
- height: 14px;
144
- }
145
-
146
- /* Modal Body - The content section */
147
- .gait-modal-body {
148
- display: flex;
149
- flex: 1;
150
- overflow-y: auto;
151
- }
152
-
153
-
154
- .gait-modal-right-panel {
155
- width: 440px;
156
- padding: 24px;
157
- border-left: 1px solid #e5e7eb;
158
- background: #fafafa;
159
- }
160
-
161
- /* Responsive: Full screen drawer on mobile */
162
- @media (max-width: 768px) {
163
- .gait-modal-backdrop {
164
- align-items: flex-start;
165
- justify-content: flex-start;
166
- padding: 0;
167
- overflow: hidden;
168
- }
169
-
170
- .gait-modal-container {
171
- max-width: 100%;
172
- width: 100%;
173
- height: 100vh;
174
- max-height: 100vh;
175
- min-height: 100vh;
176
- border-radius: 0;
177
- display: flex;
178
- flex-direction: column;
179
- overflow: hidden;
180
- margin: 0;
181
- position: relative;
182
- }
183
-
184
- .gait-modal-body {
185
- flex-direction: column;
186
- flex: 1 1 auto;
187
- overflow-y: auto;
188
- overflow-x: hidden;
189
- -webkit-overflow-scrolling: touch;
190
- min-height: 0;
191
- overscroll-behavior: contain;
192
- }
193
-
194
- .gait-modal-left-panel {
195
- border-right: none;
196
- border-bottom: 1px solid #e5e7eb;
197
- flex-shrink: 0;
198
- }
199
-
200
- .gait-modal-right-panel {
201
- width: 100%;
202
- border-left: none;
203
- flex-shrink: 0;
204
- }
205
-
206
- .gait-modal-header {
207
- flex-shrink: 0;
208
- position: sticky;
209
- top: 0;
210
- background: #fff;
211
- z-index: 1;
212
- }
213
- }
214
-
215
- .gait-modal-left-panel {
216
- flex: 1;
217
- padding: 24px;
218
- }
219
-
220
- /* Items Container */
221
- .gait-modal-items-container {
222
- display: flex;
223
- flex-direction: column;
224
- gap: 16px;
225
- padding-bottom: 20px;
226
- border-bottom: 1px solid #e5e7eb;
227
- margin-bottom: 20px;
228
- }
229
-
230
- .gait-modal-item {
231
- display: flex;
232
- gap: 16px;
233
- }
234
-
235
- .gait-modal-item-image {
236
- width: 60px;
237
- height: 40px;
238
- border-radius: 4px;
239
- object-fit: cover;
240
- flex-shrink: 0;
241
- }
242
-
243
- .gait-modal-item-meta {
244
- flex: 1;
245
- min-width: 0;
246
- }
247
-
248
- .gait-modal-item-title {
249
- font-size: 15px;
250
- font-weight: 600;
251
- margin: 0 0 4px;
252
- }
253
-
254
- .gait-modal-item-quantity {
255
- font-size: 13px;
256
- color: #6b7280;
257
- }
258
-
259
- .gait-modal-item-price {
260
- margin-left: 6px;
261
- font-size: 13px;
262
- font-weight: 500;
263
- color:rgb(10, 10, 10);
264
- }
265
-
266
- /* Price Details */
267
- .gait-modal-price-section {
268
- margin-bottom: 0;
269
- }
270
-
271
- .gait-modal-price-title {
272
- font-size: 16px;
273
- font-weight: 600;
274
- margin-bottom: 12px;
275
- }
276
-
277
- .gait-modal-price-item,
278
- .gait-modal-price-total {
279
- display: flex;
280
- justify-content: space-between;
281
- font-size: 14px;
282
- margin-bottom: 8px;
283
- }
284
-
285
- .gait-modal-price-item.discount {
286
- color: #059669;
287
- }
288
-
289
- .gait-modal-price-total {
290
- padding-top: 12px;
291
- margin-top: 12px;
292
- border-top: 1px solid #e5e7eb;
293
- font-weight: 600;
294
- }
295
-
296
- .gait-modal-price-breakdown-link {
297
- font-size: 13px;
298
- color: #6b7280;
299
- text-decoration: underline;
300
- cursor: pointer;
301
- margin-top: 4px;
302
- display: inline-block;
303
- }
304
-
305
- .gait-modal-price-breakdown-link:hover {
306
- color: #374151;
307
- }
308
-
309
- /* Payment Section */
310
- .gait-modal-payment-section {
311
- margin-bottom: 0;
312
- }
313
-
314
- .gait-modal-payment-header {
315
- display: flex;
316
- justify-content: space-between;
317
- align-items: center;
318
- margin-bottom: 10px;
319
- }
320
-
321
- .gait-modal-payment-header h4 {
322
- font-size: 16px;
323
- margin: 0;
324
- font-weight: 600;
325
- }
326
-
327
- .gait-modal-payment-change {
328
- color: #6b7280;
329
- text-decoration: underline;
330
- cursor: pointer;
331
- font-size: 14px;
332
- }
333
-
334
- .gait-modal-payment-change:hover {
335
- color: #374151;
336
- }
337
-
338
- .gait-modal-payment-card {
339
- padding: 12px;
340
- border: 1px solid #e5e7eb;
341
- border-radius: 8px;
342
- background: #fff;
343
- font-size: 14px;
344
- }
345
-
346
- .gait-modal-payment-icons {
347
- display: flex;
348
- gap: 8px;
349
- margin-top: 10px;
350
- font-size: 12px;
351
- color: #6b7280;
352
- }
353
-
354
- /* Split Payment Section */
355
- .gait-modal-split-section {
356
- margin-bottom: 20px;
357
- }
358
-
359
- .gait-modal-split-title {
360
- font-size: 16px;
361
- font-weight: 600;
362
- margin: 0 0 12px;
363
- color: #111827;
364
- }
365
-
366
- .gait-modal-split-options {
367
- display: flex;
368
- gap: 8px;
369
- margin-bottom: 20px;
370
- flex-wrap: wrap;
371
- }
372
-
373
- .gait-modal-split-option {
374
- flex: 1;
375
- min-width: 100px;
376
- padding: 10px 12px;
377
- font-size: 14px;
378
- font-weight: 500;
379
- text-align: center;
380
- background: #fff;
381
- border: 1px solid #e5e7eb;
382
- border-radius: 8px;
383
- cursor: pointer;
384
- transition: all ${g.normal};
385
- color: #374151;
386
- }
387
-
388
- .gait-modal-split-option:hover {
389
- border-color: ${c.primary.main};
390
- background: rgba(47, 44, 37, 0.04);
391
- }
392
-
393
- .gait-modal-split-option.selected {
394
- background: rgba(47, 44, 37, 0.15);
395
- border: 1px solid ${c.primary.main};
396
- color: #000;
397
- }
398
-
399
- .gait-modal-email-inputs {
400
- display: flex;
401
- flex-direction: column;
402
- gap: 10px;
403
- margin-bottom: 12px;
404
- }
405
-
406
- .gait-modal-email-input {
407
- width: 100%;
408
- padding: 10px 12px;
409
- font-size: 14px;
410
- border: 1px solid #e5e7eb;
411
- border-radius: 8px;
412
- background: #fff;
413
- color: #111827;
414
- outline: none;
415
- transition: all ${g.normal};
416
- }
417
-
418
- .gait-modal-email-input:focus {
419
- border-color: ${c.primary.main};
420
- box-shadow: 0 0 0 2px rgba(47, 44, 37, 0.1);
421
- }
422
-
423
- .gait-modal-email-input::placeholder {
424
- color: #9ca3af;
425
- }
426
-
427
- .gait-modal-email-item {
428
- display: flex;
429
- align-items: center;
430
- justify-content: space-between;
431
- padding: 10px 12px;
432
- font-size: 14px;
433
- border: 1px solid #e5e7eb;
434
- border-radius: 8px;
435
- background: #fff;
436
- color: #111827;
437
- position: relative;
438
- }
439
-
440
-
441
- .gait-modal-email-item-sent-check {
442
- width: 16px;
443
- height: 16px;
444
- border-radius: 50%;
445
- background: #10b981;
446
- display: flex;
447
- align-items: center;
448
- justify-content: center;
449
- color: #fff;
450
- padding: 2px;
451
- flex-shrink: 0;
452
- }
453
-
454
- .gait-modal-email-item-sent-check svg {
455
- width: 100%;
456
- height: 100%;
457
- }
458
-
459
- .gait-modal-email-item-email {
460
- flex: 1;
461
- min-width: 0;
462
- overflow: hidden;
463
- text-overflow: ellipsis;
464
- white-space: nowrap;
465
- }
466
-
467
- .gait-modal-email-item-right {
468
- display: flex;
469
- flex-direction: column;
470
- align-items: flex-end;
471
- gap: 6px;
472
- }
473
-
474
- .gait-modal-email-item-amount-container {
475
- display: flex;
476
- align-items: center;
477
- gap: 8px;
478
- }
479
-
480
- .gait-modal-email-item-amount {
481
- font-weight: 500;
482
- color: ${c.primary.main};
483
- font-size: 14px;
484
- }
485
-
486
- .gait-modal-email-item-actions {
487
- display: flex;
488
- flex-direction: row;
489
- align-items: center;
490
- gap: 8px;
491
- }
492
-
493
- .gait-modal-email-item-edit,
494
- .gait-modal-email-item-remove {
495
- font-size: 13px;
496
- color: #6b7280;
497
- background: none;
498
- border: none;
499
- cursor: pointer;
500
- padding: 2px 4px;
501
- transition: color ${g.normal};
502
- }
503
-
504
- .gait-modal-email-item-edit:hover,
505
- .gait-modal-email-item-remove:hover {
506
- color: ${c.primary.main};
507
- }
508
-
509
- /* For "By amount" mode - two input fields side by side */
510
- .gait-modal-email-amount-row {
511
- display: flex;
512
- gap: 8px;
513
- width: 100%;
514
- }
515
-
516
- .gait-modal-email-amount-row .gait-modal-email-input {
517
- flex: 1;
518
- }
519
-
520
- .gait-modal-email-amount-row .gait-modal-email-amount-input {
521
- width: 120px;
522
- flex: 0 0 120px;
523
- }
524
-
525
- .gait-modal-done-button {
526
- padding: 8px 16px;
527
- font-size: 13px;
528
- font-weight: 500;
529
- border: 1px solid ${c.primary.main};
530
- border-radius: 6px;
531
- background: ${c.primary.main};
532
- color: ${c.primary.contrastText};
533
- cursor: pointer;
534
- transition: all ${g.normal};
535
- white-space: nowrap;
536
- }
537
-
538
- .gait-modal-done-button:hover {
539
- background: ${c.primary.dark};
540
- border-color: ${c.primary.dark};
541
- }
542
-
543
- .gait-modal-email-amount-input {
544
- width: 80px;
545
- padding: 6px 8px;
546
- font-size: 13px;
547
- border: 1px solid #e5e7eb;
548
- border-radius: 6px;
549
- background: #fff;
550
- color: #111827;
551
- outline: none;
552
- text-align: right;
553
- }
554
-
555
- .gait-modal-email-amount-input:focus {
556
- border-color: ${c.primary.main};
557
- box-shadow: 0 0 0 2px rgba(47, 44, 37, 0.1);
558
- }
559
-
560
- .gait-modal-add-email-button {
561
- padding: 8px 12px;
562
- font-size: 13px;
563
- color: #6b7280;
564
- background: none;
565
- border: none;
566
- cursor: pointer;
567
- text-align: left;
568
- transition: color ${g.normal};
569
- }
570
-
571
- .gait-modal-add-email-button:hover {
572
- color: ${c.primary.main};
573
- text-decoration: underline;
574
- }
575
-
576
- .gait-modal-split-summary {
577
- margin-top: 20px;
578
- padding-top: 16px;
579
- border-top: 1px solid #e5e7eb;
580
- }
581
-
582
- .gait-modal-split-summary-title {
583
- font-size: 14px;
584
- font-weight: 600;
585
- margin: 0 0 8px;
586
- color: #111827;
587
- }
588
-
589
- .gait-modal-split-amount {
590
- font-size: 18px;
591
- font-weight: 600;
592
- color: ${c.primary.main};
593
- }
594
-
595
- .gait-modal-send-split-button {
596
- width: 100%;
597
- padding: 12px;
598
- font-size: 14px;
599
- font-weight: 500;
600
- border-radius: 8px;
601
- border: 1px solid ${c.primary.main};
602
- background: transparent;
603
- color: ${c.primary.main};
604
- cursor: pointer;
605
- transition: all ${g.normal};
606
- margin-top: 16px;
607
- }
608
-
609
- .gait-modal-send-split-button:hover {
610
- background: rgba(47, 44, 37, 0.06);
611
- }
612
-
613
- .gait-modal-send-split-button:active {
614
- transform: translateY(1px);
615
- }
616
-
617
- .gait-modal-send-split-button:disabled {
618
- opacity: 0.6;
619
- cursor: not-allowed;
620
- }
621
-
622
- .gait-modal-confirm-button-with-amount {
623
- width: 100%;
624
- padding: 14px;
625
- font-size: 15px;
626
- font-weight: 600;
627
- border-radius: 10px;
628
- border: none;
629
- background: var(--gait-modal-button-bg, ${c.primary.main});
630
- color: var(--gait-modal-button-color, ${c.primary.contrastText});
631
- cursor: pointer;
632
- transition: all ${g.normal};
633
- margin-top: 12px;
634
- display: flex;
635
- flex-direction: row;
636
- align-items: center;
637
-
638
- justify-content: center;
639
- gap: 4px;
640
- }
641
-
642
- .gait-modal-confirm-button-with-amount:hover {
643
- background-color: var(--gait-modal-button-bg-hover, ${c.primary.dark});
644
- }
645
-
646
- .gait-modal-confirm-button-with-amount:active {
647
- transform: translateY(1px);
648
- }
649
-
650
- .gait-modal-confirm-button-label {
651
- font-size: 15px;
652
- font-weight: 600;
653
- }
654
-
655
- .gait-modal-confirm-button-amount {
656
- font-size: 13px;
657
- font-weight: 500;
658
- opacity: 0.9;
659
- }
660
-
661
- /* Terms */
662
- .gait-modal-terms {
663
- font-size: 12px;
664
- color: #6b7280;
665
- margin: 16px 0;
666
- line-height: 1.5;
667
- }
668
-
669
- .gait-modal-terms a {
670
- text-decoration: underline;
671
- cursor: pointer;
672
- color: #6b7280;
673
- }
674
-
675
- .gait-modal-terms a:hover {
676
- color: #374151;
677
- }
678
-
679
- /* Confirm Button */
680
- .gait-modal-confirm-button {
681
- width: 100%;
682
- padding: 14px;
683
- font-size: 15px;
684
- font-weight: 600;
685
- border-radius: 10px;
686
- border: none;
687
- background: var(--gait-modal-button-bg, #e91e63);
688
- color: var(--gait-modal-button-color, #fff);
689
- cursor: pointer;
690
- transition: all ${g.normal};
691
- }
692
-
693
- .gait-modal-confirm-button:hover {
694
- background-color: var(--gait-modal-button-bg-hover, #c2185b);
695
- }
696
-
697
- .gait-modal-confirm-button:active {
698
- transform: translateY(1px);
699
- }
700
-
701
- /* Modal Footer - The button section */
702
- .gait-modal-footer {
703
- padding: ${x.lg};
704
- border-top: 1px solid #e5e7eb;
705
- display: flex;
706
- justify-content: flex-end;
707
- gap: ${x.md};
708
- }
709
-
710
- /* Modal Button - The close button */
711
- .gait-modal-button {
712
- padding: ${x.sm} ${x.lg};
713
- font-family: ${b.fontFamily.primary};
714
- font-size: ${b.fontSize.md};
715
- font-weight: ${b.fontWeight.medium};
716
- border: none;
717
- border-radius: ${q.md};
718
- cursor: pointer;
719
- transition: all ${g.normal};
720
- background-color: ${c.primary.main};
721
- color: ${c.primary.contrastText};
722
- }
723
-
724
- .gait-modal-button:hover {
725
- background-color: ${c.primary.dark};
726
- }
727
-
728
- .gait-modal-button:active {
729
- transform: translateY(1px);
730
- }
731
-
732
- /* Split Payment Feedback Banner */
733
- .gait-modal-feedback {
734
- display: flex;
735
- align-items: center;
736
- gap: 12px;
737
- padding: 12px 16px;
738
- border-radius: 8px;
739
- margin-bottom: 16px;
740
- font-size: 14px;
741
- font-weight: 500;
742
- animation: slideDown 0.3s ease-out;
743
- transition: opacity 0.3s ease-out;
744
- }
745
-
746
- @keyframes slideDown {
747
- from {
748
- opacity: 0;
749
- transform: translateY(-10px);
750
- }
751
- to {
752
- opacity: 1;
753
- transform: translateY(0);
754
- }
755
- }
756
-
757
- .gait-modal-feedback-icon {
758
- display: flex;
759
- align-items: center;
760
- justify-content: center;
761
- width: 16px;
762
- height: 16px;
763
- border-radius: 50%;
764
- flex-shrink: 0;
765
- padding: 2px;
766
- }
767
-
768
- .gait-modal-feedback-icon svg {
769
- width: 100%;
770
- height: 100%;
771
- }
772
-
773
- .gait-modal-feedback-message {
774
- flex: 1;
775
- line-height: 1.4;
776
- }
777
-
778
- .gait-modal-feedback-loading {
779
- background-color: #f0f9ff;
780
- border: 1px solid #bae6fd;
781
- color: #0369a1;
782
- }
783
-
784
- .gait-modal-feedback-loading .gait-modal-feedback-icon {
785
- background-color: #0ea5e9;
786
- color: #fff;
787
- animation: spin 1s linear infinite;
788
- }
789
-
790
- @keyframes spin {
791
- from {
792
- transform: rotate(0deg);
793
- }
794
- to {
795
- transform: rotate(360deg);
796
- }
797
- }
798
-
799
- .gait-modal-feedback-success {
800
- background-color: #f0fdf4;
801
- border: 1px solid #bbf7d0;
802
- color: #166534;
803
- }
804
-
805
- .gait-modal-feedback-success .gait-modal-feedback-icon {
806
- background-color: #22c55e;
807
- color: #fff;
808
- }
809
-
810
- .gait-modal-feedback-error {
811
- background-color: #fef2f2;
812
- border: 1px solid #fecaca;
813
- color: #991b1b;
814
- }
815
-
816
- .gait-modal-feedback-error .gait-modal-feedback-icon {
817
- background-color: #ef4444;
818
- color: #fff;
819
- }
820
- `,document.head.appendChild(r)}function D(r,t,e){return`
821
- <button
822
- type="button"
823
- ${t?"disabled":""}
824
- style="${e}"
825
- >
826
- ${r}
827
- </button>
828
- `}function I(r){return`R ${r.toFixed(2)}`}const V=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
829
- <path d="M18 6L6 18M6 6l12 12" />
830
- </svg>
831
- `,C=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
832
- <path d="M20 6L9 17l-5-5" />
833
- </svg>
834
- `,j=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
835
- <path d="M18 6L6 18M6 6l12 12" />
836
- </svg>
837
- `,H=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
838
- <path d="M21 12a9 9 0 11-6.22-8.56" />
839
- </svg>
840
- `;function _(r){return!r||r.length===0?"":r.map(t=>`
841
- <div class="gait-modal-item">
842
- <img
843
- src="${t.image||""}"
844
- alt="${t.name||"Product"}"
845
- class="gait-modal-item-image"
846
- />
847
- <div class="gait-modal-item-meta">
848
- <h3 class="gait-modal-item-title">
849
- ${t.name||""}
850
- </h3>
851
- <div class="gait-modal-item-quantity">
852
- Qty: ${t.quantity||0}
853
- <span class="gait-modal-item-price">${I(t.price||0)}</span>
854
- </div>
855
- </div>
856
- </div>
857
- `).join("")}function U(r){return!r||r.length===0?"":r.map(t=>{const e=typeof t.price=="number"?t.price:parseFloat(String(t.price))||0;return`
858
- <div class="gait-modal-price-item">
859
- <span>${t.name||""}</span>
860
- <span>${I(e)}</span>
861
- </div>
862
- `}).join("")}function W(r,t,e){return`
863
- <div class="gait-modal-container">
864
- <div class="gait-modal-header">
865
- <h2 class="gait-modal-header-title">Split Payment</h2>
866
- <button class="gait-modal-close-icon" data-gait-modal-close aria-label="Close">
867
- ${V}
868
- </button>
869
- </div>
870
-
871
- <div class="gait-modal-body">
872
- <!-- LEFT -->
873
- <div class="gait-modal-left-panel">
874
- <div class="gait-modal-items-container">
875
- ${_(r)}
876
- </div>
877
-
878
- <div class="gait-modal-price-section">
879
- <h4 class="gait-modal-price-title">Price details</h4>
880
-
881
- ${U(t)}
882
-
883
- ${e>0?`
884
- <div class="gait-modal-price-total">
885
- <span>Total</span>
886
- <span>${I(e)}</span>
887
- </div>
888
- `:""}
889
- </div>
890
- </div>
891
-
892
- <!-- RIGHT -->
893
- <div class="gait-modal-right-panel">
894
- <div class="gait-modal-split-section">
895
- <!-- Feedback banner will be inserted here dynamically -->
896
- <h4 class="gait-modal-split-title">How to split</h4>
897
-
898
- <div class="gait-modal-split-options">
899
- <div class="gait-modal-split-option selected" data-split-method="equally">Equally</div>
900
- <div class="gait-modal-split-option" data-split-method="by-amount">By amount</div>
901
- </div>
902
-
903
- <div class="gait-modal-email-inputs" data-email-inputs>
904
- </div>
905
-
906
- <button class="gait-modal-add-email-button" data-add-email>
907
- Add someone
908
- </button>
909
-
910
- <button class="gait-modal-send-split-button" data-send-split>
911
- Send split
912
- </button>
913
-
914
- <button class="gait-modal-confirm-button-with-amount" data-gait-modal-confirm>
915
- <span class="gait-modal-confirm-button-label">Pay remaining - </span>
916
- <span class="gait-modal-confirm-button-amount" data-confirm-amount>R 0.00</span>
917
- </button>
918
- </div>
919
- </div>
920
- </div>
921
- </div>
922
- `}const F={fee:10};function J(r){const t={};return Array.from(r.attributes).forEach(e=>{e.name.startsWith("data-")&&(t[e.name]=e.value)}),t}function Y(r){const t={};return Array.from(r.attributes).forEach(e=>{t[e.name]=e.value}),t}function K(r){return{get label(){return r.getAttribute("label")||"Button"},get theme(){return r.getAttribute("theme")||"dark"},get dataId(){return r.getAttribute("data-id")||null},get disabled(){return r.hasAttribute("disabled")&&r.getAttribute("disabled")!=="false"},get size(){return r.getAttribute("size")||"medium"},get items(){const t=r.getAttribute("items");if(!t)return[];try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse items attribute:",e),[]}},get totalCost(){const t=r.getAttribute("total-cost");if(!t)return 0;const e=parseFloat(t);return(isNaN(e)?0:e)+F.fee},get priceBreakdown(){const t=r.getAttribute("total-cost"),e=parseFloat(t||"0");return[{name:"Subtotal",price:isNaN(e)?0:e},{name:"Split Payment Fee",price:F.fee}]},get brandColor(){return r.getAttribute("brand-color")||c.cta.main},get customer(){const t=r.getAttribute("customer");if(!t)return null;try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse customer attribute:",e),null}},get webhook(){const t=r.getAttribute("webhook");if(!t)return null;try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse webhook attribute:",e),null}},get merchantStoreUrl(){const t=r.getAttribute("merchant-store-url");return t&&t.trim()!==""?t.trim():typeof window<"u"&&window.location?window.location.origin:""}}}function y(r){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)}function P(r,t,e){if(e.length===0)return r;if(t==="equally"){const i=e.length+1,a=r/i;return Math.max(0,r-a*e.length)}else if(t==="by-amount"){let i=0;return e.forEach(a=>{const n=a.amount||0;i+=n}),Math.max(0,r-i)}return r}function E(r,t){return r/t}function B(r,t,e){const i=[],a=r.querySelectorAll("[data-email-item]");return a.forEach(n=>{const o=n.getAttribute("data-email-item")||"";if(o)if(t==="by-amount"){const d=n.querySelector(".gait-modal-email-item-amount"),s=d&&parseFloat(d.textContent?.replace(/[^\d.]/g,"")||"0")||0;i.push({email:o,amount:s})}else{const d=a.length+1,s=E(e,d);i.push({email:o,amount:s})}}),i}function L(r){const t=r.querySelectorAll("[data-email-item]"),e=r.querySelectorAll("[data-email-input]");return t.length+e.length}class Q{modalElement;totalCost;currentSplitMethod="equally";dispatchEventFn;isSplitSent=!1;isSplitLoading=!1;splitFeedbackElement=null;feedbackHandler=null;constructor(t,e,i){this.modalElement=t,this.totalCost=e,this.dispatchEventFn=i,this.setup(),this.setupFeedbackListener()}setup(){const t=this.modalElement.querySelectorAll("[data-split-method]"),e=this.modalElement.querySelector("[data-email-inputs]"),i=this.modalElement.querySelector("[data-add-email]"),a=this.modalElement.querySelector("[data-send-split]");!e||!i||!a||(t.forEach(n=>{n.addEventListener("click",()=>{if(this.isSplitSent)return;t.forEach(s=>s.classList.remove("selected")),n.classList.add("selected");const o=n.getAttribute("data-split-method")||"equally",d=this.currentSplitMethod;this.currentSplitMethod=o,d!==o&&this.updateActiveInputsForSplitMethod(d,o),this.updateEmailItemsForSplitMethod(),this.updateSplitCalculation()})}),i.addEventListener("click",()=>this.addEmailField()),e.addEventListener("input",n=>{n.target.hasAttribute("data-email-input")&&this.updateSplitCalculation()}),a.addEventListener("click",()=>this.handleSendSplit()),this.updateSplitCalculation())}addEmailField(){if(this.isSplitSent)return;const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;const e=this.findEmptyInput(t);if(e){if(e instanceof HTMLInputElement)e.focus();else{const i=e.querySelector("[data-email-input]");i&&i.focus()}return}this.currentSplitMethod==="by-amount"?this.addByAmountInput(t):this.addEquallyInput(t)}findEmptyInput(t){if(this.currentSplitMethod==="by-amount"){const e=t.querySelectorAll(".gait-modal-email-amount-row");for(const i of Array.from(e)){const a=i.querySelector("[data-email-input]");if(a&&!a.value.trim())return i}}else{const e=t.querySelectorAll("[data-email-input]");for(const i of Array.from(e))if(!i.parentElement?.classList.contains("gait-modal-email-amount-row")&&!i.value.trim())return i}return null}removeEmptyInputs(t){t.querySelectorAll(".gait-modal-email-amount-row").forEach(a=>{const n=a.querySelector("[data-email-input]");n&&!n.value.trim()&&t.removeChild(a)}),t.querySelectorAll("[data-email-input]").forEach(a=>{a.parentElement?.classList.contains("gait-modal-email-amount-row")||a.value.trim()||t.removeChild(a)})}calculateRemainingAmount(t){const e=this.modalElement.querySelector("[data-email-inputs]");if(!e)return this.totalCost;let i=0;return e.querySelectorAll("[data-email-item]").forEach(d=>{const s=d.querySelector(".gait-modal-email-item-amount");if(s){const l=s.textContent||"0.00",m=parseFloat(l.replace(/[^\d.]/g,""))||0;i+=m}}),e.querySelectorAll(".gait-modal-email-amount-row").forEach(d=>{if(d===t)return;const s=d.querySelector("[data-email-amount-input]");if(s&&s.value){const l=parseFloat(s.value)||0;i+=l}}),Math.max(0,this.totalCost-i)}updateAmountInputMaxValues(t){const e=this.modalElement.querySelector("[data-email-inputs]");if(!e)return;const i=this.calculateRemainingAmount(t),a=i.toFixed(2);e.querySelectorAll("[data-email-amount-input]").forEach(o=>{o.closest(".gait-modal-email-amount-row")!==t&&(o.max=a,(parseFloat(o.value)||0)>i&&(o.value=a,o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)))})}addByAmountInput(t){const e=document.createElement("div");e.className="gait-modal-email-amount-row";const i=document.createElement("input");i.type="email",i.className="gait-modal-email-input",i.placeholder="Email address",i.setAttribute("data-email-input","");const a=document.createElement("input");a.type="number",a.className="gait-modal-email-amount-input",a.placeholder="0.00",a.step="0.01",a.min="0",a.setAttribute("data-email-amount-input","");const n=this.calculateRemainingAmount();a.max=n.toFixed(2);const o=document.createElement("button");o.type="button",o.className="gait-modal-done-button",o.textContent="Done",o.setAttribute("data-done-email","");const d=()=>{const s=i.value.trim();let l=parseFloat(a.value)||0;const m=this.calculateRemainingAmount(e);if(l>m&&(l=m,a.value=m.toFixed(2),a.style.borderColor="#ef4444",setTimeout(()=>{a.style.borderColor=""},2e3)),s&&y(s)){const p=this.createEmailItem(s,l);t.replaceChild(p,e),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}else s||(t.removeChild(e),this.updateAmountInputMaxValues())};a.addEventListener("input",()=>{const s=this.calculateRemainingAmount(e);(parseFloat(a.value)||0)>s?(a.value=s.toFixed(2),a.style.borderColor="#ef4444",setTimeout(()=>{a.style.borderColor=""},2e3)):a.style.borderColor="",this.updateAmountInputMaxValues(e)}),o.addEventListener("click",d),i.addEventListener("blur",()=>{!i.value.trim()&&!a.value&&setTimeout(()=>{e.parentElement&&!i.value.trim()&&t.removeChild(e)},100)}),e.appendChild(i),e.appendChild(a),e.appendChild(o),t.appendChild(e),i.focus()}addEquallyInput(t){const e=document.createElement("input");e.type="email",e.className="gait-modal-email-input",e.placeholder="Email address",e.setAttribute("data-email-input","");const i=()=>{const a=e.value.trim();a&&y(a)&&(this.convertInputToEmailItem(e),this.updateSplitCalculation())};e.addEventListener("blur",()=>{const a=e.value.trim();a&&y(a)?i():a||setTimeout(()=>{e.parentElement&&!e.value.trim()&&t.removeChild(e)},100)}),e.addEventListener("keydown",a=>{a.key==="Enter"&&(a.preventDefault(),i())}),t.appendChild(e),e.focus()}createEmailItem(t,e=0,i=!1){const a=document.createElement("div");a.className=`gait-modal-email-item${i?" sent":""}`,a.setAttribute("data-email-item",t);let n=e;if(this.currentSplitMethod==="equally"){const l=this.modalElement.querySelector("[data-email-inputs]"),m=l?L(l)+1:2;n=E(this.totalCost,m)}const o=i?`<div class="gait-modal-email-item-sent-check">${C}</div>`:"";a.innerHTML=`
923
- <span class="gait-modal-email-item-email">${t}</span>
924
- <div class="gait-modal-email-item-right">
925
- <div class="gait-modal-email-item-amount-container">
926
- <span class="gait-modal-email-item-amount">R ${n.toFixed(2)}</span>
927
- ${o}
928
- </div>
929
- <div class="gait-modal-email-item-actions">
930
- <button class="gait-modal-email-item-edit" data-edit-email="${t}">Edit</button>
931
- <button class="gait-modal-email-item-remove" data-remove-email="${t}">Remove</button>
932
- </div>
933
- </div>
934
- `;const d=a.querySelector(`[data-edit-email="${t}"]`);d&&d.addEventListener("click",l=>{l.preventDefault(),l.stopPropagation(),this.convertEmailItemToInput(a)});const s=a.querySelector(`[data-remove-email="${t}"]`);return s&&s.addEventListener("click",l=>{l.preventDefault(),l.stopPropagation(),this.removeEmailItem(a)}),a}convertEmailItemToInput(t){if(!t.parentElement)return;const i=t.getAttribute("data-email-item")||"";if(this.currentSplitMethod==="by-amount"){const a=document.createElement("div");a.className="gait-modal-email-amount-row";const n=document.createElement("input");n.type="email",n.className="gait-modal-email-input",n.placeholder="Email address",n.setAttribute("data-email-input",""),n.value=i;const o=document.createElement("input");o.type="number",o.className="gait-modal-email-amount-input",o.placeholder="0.00",o.step="0.01",o.min="0",o.setAttribute("data-email-amount-input","");const d=t.querySelector(".gait-modal-email-item-amount");let s=0;if(d){const p=d.textContent||"0.00";s=parseFloat(p.replace(/[^\d.]/g,""))||0,o.value=s.toFixed(2)}const l=this.calculateRemainingAmount(a)+s;o.max=l.toFixed(2);const m=document.createElement("button");m.type="button",m.className="gait-modal-done-button",m.textContent="Done",m.setAttribute("data-done-email",""),m.addEventListener("click",()=>{const p=n.value.trim();let u=parseFloat(o.value)||0;const h=this.calculateRemainingAmount(a)+s;if(u>h&&(u=h,o.value=h.toFixed(2),o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)),p&&y(p)){const f=this.createEmailItem(p,u);a.parentElement&&a.parentElement.replaceChild(f,a),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}else p||(a.parentElement&&a.parentElement.removeChild(a),this.updateAmountInputMaxValues())}),o.addEventListener("input",()=>{const p=this.calculateRemainingAmount(a)+s;(parseFloat(o.value)||0)>p?(o.value=p.toFixed(2),o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)):o.style.borderColor="",this.updateAmountInputMaxValues(a)}),a.appendChild(n),a.appendChild(o),a.appendChild(m),t.parentElement&&t.parentElement.replaceChild(a,t),n.focus(),n.select()}else{const a=document.createElement("input");a.type="email",a.className="gait-modal-email-input",a.placeholder="Email address",a.setAttribute("data-email-input",""),a.value=i;const n=()=>{const o=a.value.trim();o&&y(o)?(this.convertInputToEmailItem(a),this.updateSplitCalculation()):o||setTimeout(()=>{a.parentElement&&!a.value.trim()&&a.parentElement.removeChild(a)},100)};a.addEventListener("blur",n),a.addEventListener("keydown",o=>{o.key==="Enter"&&(o.preventDefault(),n())}),t.parentElement&&t.parentElement.replaceChild(a,t),a.focus(),a.select()}}convertInputToEmailItem(t){const e=t.value.trim();if(!e||!y(e))return;const i=t.parentElement;if(!i)return;const a=L(i)+1,n=this.currentSplitMethod==="equally"?E(this.totalCost,a):0,o=this.createEmailItem(e,n);i.replaceChild(o,t)}removeEmailItem(t){const e=t.parentElement;e&&(e.removeChild(t),this.updateSplitCalculation(),this.updateAmountInputMaxValues())}updateActiveInputsForSplitMethod(t,e){const i=this.modalElement.querySelector("[data-email-inputs]");i&&(this.removeEmptyInputs(i),t==="equally"&&e==="by-amount"&&Array.from(i.querySelectorAll("[data-email-input]")).filter(n=>!n.parentElement?.classList.contains("gait-modal-email-amount-row")).forEach(n=>{const o=n.value.trim(),d=n.parentElement;if(!d)return;const s=document.createElement("div");s.className="gait-modal-email-amount-row";const l=document.createElement("input");l.type="email",l.className="gait-modal-email-input",l.placeholder="Email address",l.setAttribute("data-email-input",""),l.value=o;const m=document.createElement("input");m.type="number",m.className="gait-modal-email-amount-input",m.placeholder="0.00",m.step="0.01",m.min="0",m.setAttribute("data-email-amount-input","");const p=this.calculateRemainingAmount(s);m.max=p.toFixed(2);const u=document.createElement("button");u.type="button",u.className="gait-modal-done-button",u.textContent="Done",u.setAttribute("data-done-email",""),u.addEventListener("click",()=>{const h=l.value.trim();let f=parseFloat(m.value)||0;const M=this.calculateRemainingAmount(s);if(f>M&&(f=M,m.value=M.toFixed(2),m.style.borderColor="#ef4444",setTimeout(()=>{m.style.borderColor=""},2e3)),h&&y(h)){const nt=this.createEmailItem(h,f);d.replaceChild(nt,s),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}}),m.addEventListener("input",()=>{const h=this.calculateRemainingAmount(s);(parseFloat(m.value)||0)>h?(m.value=h.toFixed(2),m.style.borderColor="#ef4444",setTimeout(()=>{m.style.borderColor=""},2e3)):m.style.borderColor="",this.updateAmountInputMaxValues(s)}),s.appendChild(l),s.appendChild(m),s.appendChild(u),d.replaceChild(s,n),l.focus()}),t==="by-amount"&&e==="equally"&&i.querySelectorAll(".gait-modal-email-amount-row").forEach(n=>{const o=n.querySelector("[data-email-input]");if(!o)return;const d=o.value.trim(),s=n.parentElement;if(!s)return;const l=document.createElement("input");l.type="email",l.className="gait-modal-email-input",l.placeholder="Email address",l.setAttribute("data-email-input",""),l.value=d;const m=()=>{const p=l.value.trim();p&&y(p)&&(this.convertInputToEmailItem(l),this.updateSplitCalculation())};l.addEventListener("blur",m),l.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),m())}),s.replaceChild(l,n),l.focus()}))}updateEmailItemsForSplitMethod(){const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;const e=t.querySelectorAll("[data-email-item]"),i=e.length+1;e.forEach(a=>{const n=a.querySelector(".gait-modal-email-item-right");if(!n)return;const o=n.querySelector(".gait-modal-email-item-amount");if(o){if(this.currentSplitMethod==="equally"){const d=E(this.totalCost,i);o.textContent=`R ${d.toFixed(2)}`}else if(this.currentSplitMethod==="by-amount"){const d=o.textContent||"R 0.00",s=parseFloat(d.replace(/[^\d.]/g,""))||0;o.textContent=`R ${s.toFixed(2)}`}}})}updateSplitCalculation(){const t=this.modalElement.querySelector("[data-email-inputs]"),e=this.modalElement.querySelector("[data-confirm-amount]");if(!t||!e)return;const i=B(t,this.currentSplitMethod,this.totalCost),a=t.querySelectorAll("[data-email-input]");a.forEach(o=>{const d=o.value.trim();if(d&&y(d)){const s=i.length+a.length+1,l=this.currentSplitMethod==="equally"?E(this.totalCost,s):0;i.push({email:d,amount:l})}});const n=i.length>0?P(this.totalCost,this.currentSplitMethod,i):this.totalCost;e.textContent=`R ${n.toFixed(2)}`,this.currentSplitMethod==="by-amount"&&this.updateAmountInputMaxValues()}handleSendSplit(){const t=this.modalElement.querySelector("[data-email-inputs]"),e=this.modalElement.querySelector("[data-send-split]");if(!t||!e)return;const i=B(t,this.currentSplitMethod,this.totalCost);if(i.length===0){this.showFeedback("Please add at least one email address","error");return}if(this.isSplitSent||this.isSplitLoading)return;this.isSplitLoading=!0,e.disabled=!0,e.textContent="Sending...",this.showFeedback("Sending split payment...","loading");const a=P(this.totalCost,this.currentSplitMethod,i);this.dispatchEventFn(new CustomEvent("gait-split-sent",{detail:{splitMethod:this.currentSplitMethod,emails:i.map(n=>n.email),emailData:i,totalCost:this.totalCost,yourAmount:a,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}setupFeedbackListener(){this.feedbackHandler=t=>{const e=t;e.detail&&this.handleSplitFeedback(e.detail)},document.addEventListener("gait-split-feedback",this.feedbackHandler)}cleanup(){this.feedbackHandler&&(document.removeEventListener("gait-split-feedback",this.feedbackHandler),this.feedbackHandler=null)}handleSplitFeedback(t){this.isSplitLoading=!1;const e=this.modalElement.querySelector("[data-send-split]");t.success?(this.isSplitSent=!0,this.markEmailsAsSent(),this.disableSplitOptions(),e&&(e.disabled=!0,e.textContent="Split sent!"),this.showFeedback(t.message||"Split payment sent successfully","success")):(e&&(e.disabled=!1,e.textContent="Send split"),this.showFeedback(t.message||t.error||"Failed to send split payment","error"))}markEmailsAsSent(){const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;t.querySelectorAll("[data-email-item]").forEach(i=>{if(!i.classList.contains("sent")){i.classList.add("sent");const a=i.querySelector(".gait-modal-email-item-right");if(a){let o=a.querySelector(".gait-modal-email-item-amount-container");const d=a.querySelector(".gait-modal-email-item-amount");if(!o&&d&&(o=document.createElement("div"),o.className="gait-modal-email-item-amount-container",d.parentElement?.replaceChild(o,d),o.appendChild(d)),o&&!o.querySelector(".gait-modal-email-item-sent-check")){const s=document.createElement("div");s.className="gait-modal-email-item-sent-check",s.innerHTML=C,o.appendChild(s)}}const n=i.querySelector(".gait-modal-email-item-actions");n&&(n.style.display="none")}})}showFeedback(t,e){this.splitFeedbackElement&&(this.splitFeedbackElement.remove(),this.splitFeedbackElement=null);const i=document.createElement("div");i.className=`gait-modal-feedback gait-modal-feedback-${e}`,i.setAttribute("data-split-feedback","");const a=e==="success"?C:e==="error"?j:H;i.innerHTML=`
935
- <span class="gait-modal-feedback-icon">${a}</span>
936
- <span class="gait-modal-feedback-message">${t}</span>
937
- `;const n=this.modalElement.querySelector(".gait-modal-split-section");n&&(n.insertBefore(i,n.firstChild),this.splitFeedbackElement=i,e!=="loading"&&setTimeout(()=>{this.splitFeedbackElement===i&&(i.style.opacity="0",setTimeout(()=>{i.parentElement&&i.remove(),this.splitFeedbackElement===i&&(this.splitFeedbackElement=null)},300))},5e3))}disableSplitOptions(){this.modalElement.querySelectorAll("[data-split-method]").forEach(i=>{const a=i;a.style.pointerEvents="none",a.style.opacity="0.5",a.style.cursor="not-allowed",a.setAttribute("aria-disabled","true")});const e=this.modalElement.querySelector("[data-add-email]");e&&(e.style.pointerEvents="none",e.style.opacity="0.5",e.style.cursor="not-allowed",e.setAttribute("aria-disabled","true"))}}async function X(r,t=2e3){console.log("[SplitPaymentAPI] Sending split payment request:",r);const e="https://api.usegait.com/checkout";try{const a=await(await fetch(`${e}/v1/payments`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:AbortSignal.timeout(t)})).json().catch(()=>({success:!1,error:"Failed to parse API response"}));if(a.success){const n={success:!0,message:a.message,data:a.data};return console.log("[SplitPaymentAPI] Split payment sent successfully:",n),n}else{const n={success:!1,message:a.message,error:a.error};return console.error("[SplitPaymentAPI] Split payment failed:",n),n}}catch(i){const a={success:!1,message:"Failed to send split payment",error:i instanceof Error?i.message:"Network error or server unavailable"};return console.error("[SplitPaymentAPI] Split payment failed:",a,i),a}}let Z=r=>crypto.getRandomValues(new Uint8Array(r)),tt=(r,t,e)=>{let i=(2<<Math.log2(r.length-1))-1,a=-~(1.6*i*t/r.length);return(n=t)=>{let o="";for(;;){let d=e(a),s=a|0;for(;s--;)if(o+=r[d[s]&i]||"",o.length>=n)return o}}},et=(r,t=21)=>tt(r,t|0,Z);const A={apiGateway:{MERCHANT_SERVICE_API:"https://api.usegait.com/merchant",CHECKOUT_SERVICE_API:"https://api.usegait.com/checkout"},paylink:{DOMAIN:"https://checkout.usegait.com"}},at=A.apiGateway.MERCHANT_SERVICE_API;class it{static async getMerchant(t){try{return await(await fetch(`${at}/v1/merchant/identity/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}})).json()}catch(e){return e}}}const S=A.apiGateway.CHECKOUT_SERVICE_API;class ot{static async getPayment(t){try{return await(await fetch(`${S}/v1/payments/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}})).json()}catch(e){return e}}static async updatePaymentStatus(t,e,i){try{return await(await fetch(`${S}/v1/payments/merchants/${t}/${e}/status`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:i})})).json()}catch(a){return a}}static async createWebhook(t,e,i){try{return await(await fetch(`${S}/v1/webhooks/${t}/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)})).json()}catch(a){return a}}static async updatePayment(t,e,i){try{return await(await fetch(`${S}/v1/payments/merchants/${t}/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({paymentId:e})})).json()}catch(a){return a}}}const w=(typeof process<"u"&&process.env?"0.0.16":void 0)||"0.0.0";class v extends HTMLElement{buttonElement=null;hasRendered=!1;mutationObserver=null;modalElement=null;modalId;splitPaymentManager=null;attributeGetters;storedSplitPaymentRequest=null;merchantId=null;paymentProvider="stripe";static version=w;version=w;static get observedAttributes(){return["label","theme","data-id","disabled","size","style","items","price-breakdown","total-cost","brand-color","webhook","merchant-store-url"]}constructor(){super(),this.attachShadow({mode:"open"}),this.modalId=`gait-modal-${Math.random().toString(36).substr(2,9)}`,this.attributeGetters=K(this)}connectedCallback(){!this.hasRendered&&this.shadowRoot&&this.render(),this.setupEventListeners(),this.setupMutationObserver(),this.setupApiListeners(),setTimeout(()=>this.processData(),0)}disconnectedCallback(){this.buttonElement&&this.buttonElement.removeEventListener("click",this.handleClick),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.closeModal(),this.splitPaymentManager&&(this.splitPaymentManager=null),this.removeEventListener("gait-split-sent",this.handleSplitSent)}attributeChangedCallback(t,e,i){if(e!==i&&!(!this.isConnected||!this.shadowRoot)){if(t==="style"&&this.buttonElement&&this.hasRendered){const a=(i||"").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");this.buttonElement.setAttribute("style",a);return}this.hasRendered&&(this.render(),this.setupEventListeners()),(t==="data-id"||t.startsWith("data-"))&&(t==="data-id"&&(this.merchantId=null),setTimeout(()=>this.processData(),0))}}get label(){return this.attributeGetters.label}get theme(){return this.attributeGetters.theme}get dataId(){return this.attributeGetters.dataId}get disabled(){return this.attributeGetters.disabled}get size(){return this.attributeGetters.size}get items(){return this.attributeGetters.items}get priceBreakdown(){return this.attributeGetters.priceBreakdown}get totalCost(){return this.attributeGetters.totalCost}get brandColor(){return this.attributeGetters.brandColor}get customer(){return this.attributeGetters.customer}get webhook(){return this.attributeGetters.webhook}get merchantStoreUrl(){return this.attributeGetters.merchantStoreUrl}getDataAttributes(){return J(this)}async fetchMerchantId(){const t=this.dataId;if(!t)return console.warn("[GaitButton] No checkoutId (data-id) provided, cannot fetch merchantId"),this.showMerchantIdError(),!1;try{const e=await it.getMerchant(t);return e.success&&e.data?.merchantId?(this.merchantId=e.data.merchantId,this.paymentProvider=e.data.paymentProvider,!0):(console.error("[GaitButton] Failed to fetch merchantId:",e),this.showMerchantIdError(),!1)}catch(e){return console.error("[GaitButton] Error fetching merchantId:",e),this.showMerchantIdError(),!1}}showMerchantIdError(){const t="Unable to identify your account. Please go to your dashboard and copy your checkout identity.";alert(t),this.dispatchEvent(new CustomEvent("gait-merchant-id-error",{detail:{message:t,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}async processData(){const t=this.dataId,e=this.getDataAttributes();if(t&&!this.merchantId&&await this.fetchMerchantId(),t||Object.keys(e).length>0){const i={id:t,...e,timestamp:new Date().toISOString()};this.dispatchEvent(new CustomEvent("gait-data-processed",{detail:i,bubbles:!0,composed:!0}))}}handleClick=async t=>{if(this.disabled){t.preventDefault(),t.stopPropagation();return}const e={label:this.label,theme:this.theme,dataId:this.dataId,dataAttributes:this.getDataAttributes(),timestamp:new Date().toISOString()};this.dispatchEvent(new CustomEvent("gait-click",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("click",{detail:e,bubbles:!0,composed:!0})),!(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))&&this.openModal()};setupEventListeners(){this.shadowRoot&&(this.buttonElement&&this.buttonElement.removeEventListener("click",this.handleClick),this.buttonElement=this.shadowRoot.querySelector("button"),this.buttonElement&&this.buttonElement.addEventListener("click",this.handleClick))}setupMutationObserver(){this.mutationObserver&&this.mutationObserver.disconnect(),this.mutationObserver=new MutationObserver(t=>{let e=!1;for(const i of t)if(i.type==="attributes"){const a=i.attributeName;if(a&&a.startsWith("data-")&&!v.observedAttributes.includes(a)){e=!0;break}}e&&this.isConnected&&this.processData()}),this.mutationObserver.observe(this,{attributes:!0,attributeFilter:void 0})}setupApiListeners(){this.addEventListener("gait-split-sent",this.handleSplitSent)}handleConfirmPayment=async()=>{if(console.log("[GaitButton] Pay remaining button clicked"),!this.storedSplitPaymentRequest){console.error("[GaitButton] Split payment must be sent first before paying remaining amount");return}if(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))return;const t={merchantId:this.merchantId,splitId:this.storedSplitPaymentRequest.splitId,paymentId:this.storedSplitPaymentRequest.paymentSplits.find(a=>a.initiator)?.paymentId},i=`${A.paylink.DOMAIN}/payment/${t.paymentId}`;window.open(i,"_blank"),this.dispatchEvent(new CustomEvent("gait-confirm",{detail:t,bubbles:!0,composed:!0})),this.closeModal()};handleSplitSent=async t=>{const i=t.detail;if(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))return;const a=this.merchantId,n=this.customer;if(!n||!n.email){console.error("[GaitButton] Customer email is required for split payment");return}const o=this.webhook;if(!o||!o.url||o.body==null){console.error("[GaitButton] Webhook with url and body is required");return}const s=et("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",6),l=s(),m=[];m.push({paymentId:s(),email:n.email,amount:i.yourAmount,isPaid:!1,datePaid:null,initiator:!0}),i.emailData.forEach(u=>{m.push({paymentId:s(),email:u.email,amount:u.amount||0,isPaid:!1,datePaid:null,initiator:!1})});const p={merchantId:a,splitId:l,paymentSplits:m,splitMethod:i.splitMethod,timestamp:i.timestamp,totalCost:i.totalCost,items:this.items,priceBreakdown:this.priceBreakdown,brandColor:this.brandColor,merchantStoreUrl:this.merchantStoreUrl,subTotal:this.priceBreakdown.find(u=>u.name==="Subtotal")?.price||0,paymentProvider:this.paymentProvider};console.log("[GaitButton] Split payment request body:",JSON.stringify(p,null,2));try{const u=await X(p,2e3);if(u.success){const h=u.data?.splitId||l;this.storedSplitPaymentRequest={...p,splitId:h};try{const f=await ot.createWebhook(a,h,{url:o.url,body:o.body});console.log("[GaitButton] Webhook created:",f)}catch(f){console.error("[GaitButton] Failed to create webhook:",f)}}if(this.modalElement){const h=this.modalElement.querySelector("[data-gait-modal-confirm]");h&&(h.disabled=!1,h.style.opacity="1",h.style.cursor="pointer")}this.dispatchEvent(new CustomEvent("gait-split-feedback",{detail:{success:u.success,message:u.message,data:u.success?this.storedSplitPaymentRequest:u.data,error:u.error,timestamp:new Date().toISOString()},bubbles:!0,composed:!0})),console.log("[GaitButton] Split payment API response:",u)}catch(u){console.error("[GaitButton] Split payment API error:",u),this.dispatchEvent(new CustomEvent("gait-split-feedback",{detail:{success:!1,message:"Failed to send split payment",error:u instanceof Error?u.message:"Unknown error",timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}};openModal(){O(),this.closeModal(),this.modalElement=document.createElement("div"),this.modalElement.className="gait-modal-backdrop",this.modalElement.id=this.modalId;const t=this.brandColor;t&&this.modalElement&&(this.modalElement.style.setProperty("--gait-modal-brand-color",t),this.modalElement.style.setProperty("--gait-modal-button-bg",t),this.modalElement.style.setProperty("--gait-modal-button-bg-hover",$(t,.15)),this.modalElement.style.setProperty("--gait-modal-button-color",T(t)?"#ffffff":"#000000")),this.modalElement.innerHTML=W(this.items,this.priceBreakdown,this.totalCost);const e=this.modalElement.querySelector("[data-gait-modal-close]");e&&e.addEventListener("click",this.closeModal);const i=this.modalElement.querySelector("[data-gait-modal-confirm]");i&&(i.disabled=!0,i.style.opacity="0.5",i.style.cursor="not-allowed",i.addEventListener("click",this.handleConfirmPayment)),this.splitPaymentManager=new Q(this.modalElement,this.totalCost,n=>this.dispatchEvent(n)),this.modalElement._splitPaymentManager=this.splitPaymentManager,this.modalElement.addEventListener("click",n=>{n.target===this.modalElement&&this.closeModal()});const a=n=>{n.key==="Escape"&&this.modalElement&&(this.closeModal(),document.removeEventListener("keydown",a))};document.addEventListener("keydown",a),document.body.appendChild(this.modalElement),requestAnimationFrame(()=>{this.modalElement&&this.modalElement.classList.add("gait-modal-open")})}closeModal=()=>{this.modalElement&&(this.splitPaymentManager&&this.splitPaymentManager.cleanup(),this.modalElement.classList.remove("gait-modal-open"),setTimeout(()=>{this.modalElement&&this.modalElement.parentNode&&this.modalElement.parentNode.removeChild(this.modalElement),this.modalElement=null,this.splitPaymentManager=null},250))};render(){const t=this.shadowRoot;if(!t)return;const e=!this.hasRendered,i=G(this.theme,this.size,this.brandColor,$,T),n=(this.getAttribute("style")||"").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");if(t.innerHTML=`
938
- ${i}
939
- ${D(this.label,this.disabled,n)}
940
- `,this.hasRendered=!0,this.setupEventListeners(),e){const o=Y(this);console.log("[GaitButton] rendered",o),this.dispatchEvent(new CustomEvent("gait-loaded",{detail:{attributes:o,dataId:this.dataId,dataAttributes:this.getDataAttributes(),label:this.label,theme:this.theme,size:this.size,disabled:this.disabled,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}}}customElements.get("gait-button")||customElements.define("gait-button",v),customElements.get("gait-button")||customElements.define("gait-button",v),typeof window<"u"&&(window.GaitButton=v,window.GaitButtonVersion=w,console.log(`[GaitButton] Version: ${w}`)),k.GAIT_BUTTON_VERSION=w,k.GaitButton=v,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})})(this.GaitButton=this.GaitButton||{});