@doujins/payments-ui 0.0.1 → 0.0.2

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.js CHANGED
@@ -1,17 +1,24 @@
1
+ import * as React3 from 'react';
1
2
  import { createContext, useMemo, useEffect, useContext, useState, useCallback, useRef } from 'react';
2
3
  import { createStore } from 'zustand/vanilla';
3
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { User, MapPin, ChevronDown, Search, Loader2, CreditCard, WalletCards, Trash2, X, Sparkles, CheckCircle, XCircle, RotateCcw, Wallet, RefreshCw } from 'lucide-react';
5
+ import { ChevronDown, ChevronUp, Check, X, User, MapPin, Loader2, CreditCard, WalletCards, Trash2, Sparkles, Wallet, CheckCircle, XCircle, RotateCcw, RefreshCw } from 'lucide-react';
5
6
  import countryList from 'country-list';
6
- import clsx from 'clsx';
7
- import * as Dialog2 from '@radix-ui/react-dialog';
7
+ import { cva } from 'class-variance-authority';
8
+ import { clsx } from 'clsx';
9
+ import { twMerge } from 'tailwind-merge';
10
+ import * as LabelPrimitive from '@radix-ui/react-label';
11
+ import * as SelectPrimitive from '@radix-ui/react-select';
8
12
  import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
13
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
14
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
9
15
  import { useWallet, useConnection } from '@solana/wallet-adapter-react';
10
16
  import { Buffer } from 'buffer';
11
17
  import { Connection, VersionedTransaction, Transaction, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
12
18
  import { getAssociatedTokenAddress, getAccount, TOKEN_PROGRAM_ID } from '@solana/spl-token';
13
19
  import QRCode from 'qrcode';
14
20
  import { useStore } from 'zustand';
21
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
15
22
 
16
23
  // src/context/PaymentContext.tsx
17
24
 
@@ -519,38 +526,261 @@ var customCountries = [
519
526
  ];
520
527
  countryList.overwrite(customCountries);
521
528
  var countries = countryList.getData().sort((a, b) => a.name.localeCompare(b.name));
522
-
523
- // src/hooks/useCountryDropdown.ts
524
- function useCountryDropdown() {
525
- const [country, setCountry] = useState("");
526
- const [countryOpen, setCountryOpen] = useState(false);
527
- const [countrySearch, setCountrySearch] = useState("");
528
- const countryDropdownRef = useRef(null);
529
- const filteredCountries = countries.filter(
530
- (country2) => country2.name.toLowerCase().includes(countrySearch.toLowerCase())
531
- );
532
- useEffect(() => {
533
- function handleClickOutside(event) {
534
- if (countryDropdownRef.current && !countryDropdownRef.current.contains(event.target)) {
535
- setCountryOpen(false);
529
+ function setRef(ref, value) {
530
+ if (typeof ref === "function") {
531
+ return ref(value);
532
+ } else if (ref !== null && ref !== void 0) {
533
+ ref.current = value;
534
+ }
535
+ }
536
+ function composeRefs(...refs) {
537
+ return (node) => {
538
+ let hasCleanup = false;
539
+ const cleanups = refs.map((ref) => {
540
+ const cleanup = setRef(ref, node);
541
+ if (!hasCleanup && typeof cleanup == "function") {
542
+ hasCleanup = true;
536
543
  }
544
+ return cleanup;
545
+ });
546
+ if (hasCleanup) {
547
+ return () => {
548
+ for (let i = 0; i < cleanups.length; i++) {
549
+ const cleanup = cleanups[i];
550
+ if (typeof cleanup == "function") {
551
+ cleanup();
552
+ } else {
553
+ setRef(refs[i], null);
554
+ }
555
+ }
556
+ };
537
557
  }
538
- document.addEventListener("mousedown", handleClickOutside);
539
- return () => {
540
- document.removeEventListener("mousedown", handleClickOutside);
541
- };
542
- }, []);
543
- return {
544
- country,
545
- setCountry,
546
- countryOpen,
547
- setCountryOpen,
548
- countrySearch,
549
- setCountrySearch,
550
- countryDropdownRef,
551
- filteredCountries
552
558
  };
553
559
  }
560
+ // @__NO_SIDE_EFFECTS__
561
+ function createSlot(ownerName) {
562
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
563
+ const Slot2 = React3.forwardRef((props, forwardedRef) => {
564
+ const { children, ...slotProps } = props;
565
+ const childrenArray = React3.Children.toArray(children);
566
+ const slottable = childrenArray.find(isSlottable);
567
+ if (slottable) {
568
+ const newElement = slottable.props.children;
569
+ const newChildren = childrenArray.map((child) => {
570
+ if (child === slottable) {
571
+ if (React3.Children.count(newElement) > 1) return React3.Children.only(null);
572
+ return React3.isValidElement(newElement) ? newElement.props.children : null;
573
+ } else {
574
+ return child;
575
+ }
576
+ });
577
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React3.isValidElement(newElement) ? React3.cloneElement(newElement, void 0, newChildren) : null });
578
+ }
579
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
580
+ });
581
+ Slot2.displayName = `${ownerName}.Slot`;
582
+ return Slot2;
583
+ }
584
+ var Slot = /* @__PURE__ */ createSlot("Slot");
585
+ // @__NO_SIDE_EFFECTS__
586
+ function createSlotClone(ownerName) {
587
+ const SlotClone = React3.forwardRef((props, forwardedRef) => {
588
+ const { children, ...slotProps } = props;
589
+ if (React3.isValidElement(children)) {
590
+ const childrenRef = getElementRef(children);
591
+ const props2 = mergeProps(slotProps, children.props);
592
+ if (children.type !== React3.Fragment) {
593
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
594
+ }
595
+ return React3.cloneElement(children, props2);
596
+ }
597
+ return React3.Children.count(children) > 1 ? React3.Children.only(null) : null;
598
+ });
599
+ SlotClone.displayName = `${ownerName}.SlotClone`;
600
+ return SlotClone;
601
+ }
602
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
603
+ function isSlottable(child) {
604
+ return React3.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
605
+ }
606
+ function mergeProps(slotProps, childProps) {
607
+ const overrideProps = { ...childProps };
608
+ for (const propName in childProps) {
609
+ const slotPropValue = slotProps[propName];
610
+ const childPropValue = childProps[propName];
611
+ const isHandler = /^on[A-Z]/.test(propName);
612
+ if (isHandler) {
613
+ if (slotPropValue && childPropValue) {
614
+ overrideProps[propName] = (...args) => {
615
+ const result = childPropValue(...args);
616
+ slotPropValue(...args);
617
+ return result;
618
+ };
619
+ } else if (slotPropValue) {
620
+ overrideProps[propName] = slotPropValue;
621
+ }
622
+ } else if (propName === "style") {
623
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
624
+ } else if (propName === "className") {
625
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
626
+ }
627
+ }
628
+ return { ...slotProps, ...overrideProps };
629
+ }
630
+ function getElementRef(element) {
631
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
632
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
633
+ if (mayWarn) {
634
+ return element.ref;
635
+ }
636
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
637
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
638
+ if (mayWarn) {
639
+ return element.props.ref;
640
+ }
641
+ return element.props.ref || element.ref;
642
+ }
643
+ function cn(...inputs) {
644
+ return twMerge(clsx(inputs));
645
+ }
646
+ var buttonVariants = cva(
647
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
648
+ {
649
+ variants: {
650
+ variant: {
651
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
652
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
653
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
654
+ ghost: "hover:bg-accent hover:text-accent-foreground",
655
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
656
+ link: "text-primary underline-offset-4 hover:underline"
657
+ },
658
+ size: {
659
+ default: "h-10 px-4 py-2",
660
+ sm: "h-9 rounded-md px-3",
661
+ lg: "h-11 rounded-md px-8",
662
+ icon: "h-10 w-10"
663
+ }
664
+ },
665
+ defaultVariants: {
666
+ variant: "default",
667
+ size: "default"
668
+ }
669
+ }
670
+ );
671
+ var Button = React3.forwardRef(
672
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
673
+ const Comp = asChild ? Slot : "button";
674
+ return /* @__PURE__ */ jsx(
675
+ Comp,
676
+ {
677
+ className: cn(buttonVariants({ variant, size, className })),
678
+ ref,
679
+ ...props
680
+ }
681
+ );
682
+ }
683
+ );
684
+ Button.displayName = "Button";
685
+ var Input = React3.forwardRef(
686
+ ({ className, type, ...props }, ref) => {
687
+ return /* @__PURE__ */ jsx(
688
+ "input",
689
+ {
690
+ type,
691
+ className: cn(
692
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
693
+ className
694
+ ),
695
+ ref,
696
+ ...props
697
+ }
698
+ );
699
+ }
700
+ );
701
+ Input.displayName = "Input";
702
+ var Label = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
703
+ LabelPrimitive.Root,
704
+ {
705
+ ref,
706
+ className: cn(
707
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
708
+ className
709
+ ),
710
+ ...props
711
+ }
712
+ ));
713
+ Label.displayName = LabelPrimitive.Root.displayName;
714
+ var Select = SelectPrimitive.Root;
715
+ var SelectValue = SelectPrimitive.Value;
716
+ var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
717
+ SelectPrimitive.Trigger,
718
+ {
719
+ ref,
720
+ className: cn(
721
+ "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
722
+ className
723
+ ),
724
+ ...props,
725
+ children: [
726
+ children,
727
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
728
+ ]
729
+ }
730
+ ));
731
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
732
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
733
+ SelectPrimitive.Content,
734
+ {
735
+ ref,
736
+ className: cn(
737
+ "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
738
+ className
739
+ ),
740
+ position,
741
+ ...props,
742
+ children: [
743
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) }),
744
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: "p-1", children }),
745
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) })
746
+ ]
747
+ }
748
+ ) }));
749
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
750
+ var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
751
+ SelectPrimitive.Label,
752
+ {
753
+ ref,
754
+ className: cn("px-2 py-1.5 text-sm font-semibold text-muted-foreground", className),
755
+ ...props
756
+ }
757
+ ));
758
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
759
+ var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
760
+ SelectPrimitive.Item,
761
+ {
762
+ ref,
763
+ className: cn(
764
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
765
+ className
766
+ ),
767
+ ...props,
768
+ children: [
769
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
770
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
771
+ ]
772
+ }
773
+ ));
774
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
775
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
776
+ SelectPrimitive.Separator,
777
+ {
778
+ ref,
779
+ className: cn("mx-1 my-1 h-px bg-muted", className),
780
+ ...props
781
+ }
782
+ ));
783
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
554
784
  var defaultBilling = {
555
785
  firstName: "",
556
786
  lastName: "",
@@ -597,14 +827,6 @@ var CardDetailsForm = ({
597
827
  const [email, setEmail] = useState(mergedDefaults.email ?? "");
598
828
  const [localError, setLocalError] = useState(null);
599
829
  const [isTokenizing, setIsTokenizing] = useState(false);
600
- const {
601
- countryDropdownRef,
602
- countryOpen,
603
- setCountryOpen,
604
- countrySearch,
605
- setCountrySearch,
606
- filteredCountries
607
- } = useCountryDropdown();
608
830
  useEffect(() => {
609
831
  if (!visible) {
610
832
  setLocalError(null);
@@ -725,38 +947,43 @@ var CardDetailsForm = ({
725
947
  window.CollectJS.startPaymentRequest();
726
948
  };
727
949
  const errorMessage = localError ?? externalError;
950
+ const collectFieldClass = "flex h-11 w-full items-center rounded-md border border-dashed border-muted-foreground/40 bg-muted/20 px-3 text-sm text-muted-foreground";
728
951
  return /* @__PURE__ */ jsxs(
729
952
  "form",
730
953
  {
731
- className: clsx("payments-ui-card-form", className),
954
+ className: cn(
955
+ "space-y-6 rounded-2xl border border-border/60 bg-card/90 p-6 shadow-lg",
956
+ className
957
+ ),
732
958
  onSubmit: handleSubmit,
733
959
  noValidate: true,
734
960
  children: [
735
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-grid", children: [
736
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
737
- /* @__PURE__ */ jsxs("span", { children: [
738
- /* @__PURE__ */ jsx(User, { className: "payments-ui-icon" }),
961
+ errorMessage && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: errorMessage }),
962
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
963
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
964
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-first", className: "flex items-center gap-2 text-muted-foreground", children: [
965
+ /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
739
966
  " First name"
740
967
  ] }),
741
968
  /* @__PURE__ */ jsx(
742
- "input",
969
+ Input,
743
970
  {
744
- className: "payments-ui-input",
971
+ id: "payments-first",
745
972
  value: firstName,
746
973
  onChange: (e) => setFirstName(e.target.value),
747
974
  required: true
748
975
  }
749
976
  )
750
977
  ] }),
751
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
752
- /* @__PURE__ */ jsxs("span", { children: [
753
- /* @__PURE__ */ jsx(User, { className: "payments-ui-icon" }),
978
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
979
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-last", className: "flex items-center gap-2 text-muted-foreground", children: [
980
+ /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
754
981
  " Last name"
755
982
  ] }),
756
983
  /* @__PURE__ */ jsx(
757
- "input",
984
+ Input,
758
985
  {
759
- className: "payments-ui-input",
986
+ id: "payments-last",
760
987
  value: lastName,
761
988
  onChange: (e) => setLastName(e.target.value),
762
989
  required: true
@@ -764,171 +991,125 @@ var CardDetailsForm = ({
764
991
  )
765
992
  ] })
766
993
  ] }),
767
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
768
- /* @__PURE__ */ jsx("span", { children: "Email" }),
994
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
995
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-email", children: "Email" }),
769
996
  /* @__PURE__ */ jsx(
770
- "input",
997
+ Input,
771
998
  {
999
+ id: "payments-email",
772
1000
  type: "email",
773
- className: "payments-ui-input",
774
1001
  value: email,
775
1002
  onChange: (e) => setEmail(e.target.value),
776
1003
  required: true
777
1004
  }
778
1005
  )
779
1006
  ] }),
780
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
781
- /* @__PURE__ */ jsx("span", { children: "Address line 1" }),
1007
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1008
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-address1", children: "Address line 1" }),
782
1009
  /* @__PURE__ */ jsx(
783
- "input",
1010
+ Input,
784
1011
  {
785
- className: "payments-ui-input",
1012
+ id: "payments-address1",
786
1013
  value: address1,
787
1014
  onChange: (e) => setAddress1(e.target.value),
788
1015
  required: true
789
1016
  }
790
1017
  )
791
1018
  ] }),
792
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
793
- /* @__PURE__ */ jsx("span", { children: "Address line 2 (optional)" }),
1019
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1020
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-address2", children: "Address line 2 (optional)" }),
794
1021
  /* @__PURE__ */ jsx(
795
- "input",
1022
+ Input,
796
1023
  {
797
- className: "payments-ui-input",
1024
+ id: "payments-address2",
798
1025
  value: address2,
799
1026
  onChange: (e) => setAddress2(e.target.value)
800
1027
  }
801
1028
  )
802
1029
  ] }),
803
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-grid", children: [
804
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
805
- /* @__PURE__ */ jsx("span", { children: "City" }),
1030
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1031
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1032
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-city", children: "City" }),
806
1033
  /* @__PURE__ */ jsx(
807
- "input",
1034
+ Input,
808
1035
  {
809
- className: "payments-ui-input",
1036
+ id: "payments-city",
810
1037
  value: city,
811
1038
  onChange: (e) => setCity(e.target.value),
812
1039
  required: true
813
1040
  }
814
1041
  )
815
1042
  ] }),
816
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
817
- /* @__PURE__ */ jsx("span", { children: "State / Region" }),
1043
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1044
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-state", children: "State / Region" }),
818
1045
  /* @__PURE__ */ jsx(
819
- "input",
1046
+ Input,
820
1047
  {
821
- className: "payments-ui-input",
1048
+ id: "payments-state",
822
1049
  value: stateRegion,
823
1050
  onChange: (e) => setStateRegion(e.target.value)
824
1051
  }
825
1052
  )
826
1053
  ] })
827
1054
  ] }),
828
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-grid", children: [
829
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
830
- /* @__PURE__ */ jsxs("span", { children: [
831
- /* @__PURE__ */ jsx(MapPin, { className: "payments-ui-icon" }),
1055
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1056
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1057
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-postal", className: "flex items-center gap-2 text-muted-foreground", children: [
1058
+ /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
832
1059
  " Postal code"
833
1060
  ] }),
834
1061
  /* @__PURE__ */ jsx(
835
- "input",
1062
+ Input,
836
1063
  {
837
- className: "payments-ui-input",
1064
+ id: "payments-postal",
838
1065
  value: postalCode,
839
1066
  onChange: (e) => setPostalCode(e.target.value),
840
1067
  required: true
841
1068
  }
842
1069
  )
843
1070
  ] }),
844
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-label", children: [
845
- /* @__PURE__ */ jsx("span", { children: "Country" }),
846
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-country", ref: countryDropdownRef, children: [
847
- /* @__PURE__ */ jsxs(
848
- "button",
849
- {
850
- type: "button",
851
- className: "payments-ui-country-toggle",
852
- onClick: () => setCountryOpen((prev) => !prev),
853
- children: [
854
- /* @__PURE__ */ jsx("span", { children: country }),
855
- /* @__PURE__ */ jsx(ChevronDown, { className: "payments-ui-icon" })
856
- ]
857
- }
858
- ),
859
- countryOpen && /* @__PURE__ */ jsxs("div", { className: "payments-ui-country-menu", children: [
860
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-country-search", children: [
861
- /* @__PURE__ */ jsx(Search, { className: "payments-ui-icon" }),
862
- /* @__PURE__ */ jsx(
863
- "input",
864
- {
865
- placeholder: "Search country",
866
- value: countrySearch,
867
- onChange: (e) => setCountrySearch(e.target.value)
868
- }
869
- )
870
- ] }),
871
- /* @__PURE__ */ jsx("ul", { children: filteredCountries.map((option) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
872
- "button",
873
- {
874
- type: "button",
875
- onClick: () => {
876
- setCountry(option.code);
877
- setCountryOpen(false);
878
- },
879
- children: option.name
880
- }
881
- ) }, option.code)) })
882
- ] })
1071
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1072
+ /* @__PURE__ */ jsx(Label, { children: "Country" }),
1073
+ /* @__PURE__ */ jsxs(Select, { value: country, onValueChange: setCountry, children: [
1074
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a country" }) }),
1075
+ /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: countries.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.code, children: option.name }, option.code)) })
883
1076
  ] })
884
1077
  ] })
885
1078
  ] }),
886
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-label", children: [
887
- /* @__PURE__ */ jsx("span", { children: "Card number" }),
888
- /* @__PURE__ */ jsx(
889
- "div",
890
- {
891
- id: buildSelector(collectPrefix, "ccnumber").slice(1),
892
- className: "payments-ui-collect-field"
893
- }
894
- )
1079
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1080
+ /* @__PURE__ */ jsx(Label, { children: "Card number" }),
1081
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccnumber").slice(1), className: collectFieldClass })
895
1082
  ] }),
896
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-grid", children: [
897
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-label", children: [
898
- /* @__PURE__ */ jsx("span", { children: "Expiry" }),
899
- /* @__PURE__ */ jsx(
900
- "div",
901
- {
902
- id: buildSelector(collectPrefix, "ccexp").slice(1),
903
- className: "payments-ui-collect-field"
904
- }
905
- )
1083
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1084
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1085
+ /* @__PURE__ */ jsx(Label, { children: "Expiry" }),
1086
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccexp").slice(1), className: collectFieldClass })
906
1087
  ] }),
907
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-label", children: [
908
- /* @__PURE__ */ jsx("span", { children: "CVV" }),
909
- /* @__PURE__ */ jsx(
910
- "div",
911
- {
912
- id: buildSelector(collectPrefix, "cvv").slice(1),
913
- className: "payments-ui-collect-field"
914
- }
915
- )
1088
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1089
+ /* @__PURE__ */ jsx(Label, { children: "CVV" }),
1090
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "cvv").slice(1), className: collectFieldClass })
916
1091
  ] })
917
1092
  ] }),
918
- errorMessage && /* @__PURE__ */ jsx("p", { className: "payments-ui-error", children: errorMessage }),
919
- /* @__PURE__ */ jsxs(
920
- "button",
1093
+ /* @__PURE__ */ jsx(
1094
+ Button,
921
1095
  {
922
1096
  type: "submit",
923
- className: "payments-ui-button",
924
- disabled: submitting || isTokenizing || submitDisabled,
925
- children: [
926
- (submitting || isTokenizing) && /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }),
927
- /* @__PURE__ */ jsx(CreditCard, { className: "payments-ui-icon" }),
928
- submitting || isTokenizing ? "Processing..." : submitLabel
929
- ]
1097
+ className: "w-full",
1098
+ disabled: submitting || submitDisabled || isTokenizing,
1099
+ children: submitting || isTokenizing ? /* @__PURE__ */ jsxs(Fragment, { children: [
1100
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1101
+ " Processing\u2026"
1102
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1103
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
1104
+ " ",
1105
+ submitLabel
1106
+ ] })
930
1107
  }
931
- )
1108
+ ),
1109
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
1110
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
1111
+ " Your payment information is encrypted and processed securely."
1112
+ ] })
932
1113
  ]
933
1114
  }
934
1115
  );
@@ -980,6 +1161,149 @@ var usePaymentMethods = () => {
980
1161
  deleteMutation
981
1162
  };
982
1163
  };
1164
+ var Dialog = DialogPrimitive.Root;
1165
+ var DialogPortal = ({ className, ...props }) => /* @__PURE__ */ jsx(DialogPrimitive.Portal, { className: cn(className), ...props });
1166
+ DialogPortal.displayName = DialogPrimitive.Portal.displayName;
1167
+ var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1168
+ DialogPrimitive.Overlay,
1169
+ {
1170
+ ref,
1171
+ className: cn(
1172
+ "fixed inset-0 z-50 bg-black/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
1173
+ className
1174
+ ),
1175
+ ...props
1176
+ }
1177
+ ));
1178
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
1179
+ var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
1180
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
1181
+ /* @__PURE__ */ jsxs(
1182
+ DialogPrimitive.Content,
1183
+ {
1184
+ ref,
1185
+ className: cn(
1186
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
1187
+ className
1188
+ ),
1189
+ ...props,
1190
+ children: [
1191
+ children,
1192
+ /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [
1193
+ /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
1194
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1195
+ ] })
1196
+ ]
1197
+ }
1198
+ )
1199
+ ] }));
1200
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
1201
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
1202
+ DialogHeader.displayName = "DialogHeader";
1203
+ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1204
+ DialogPrimitive.Title,
1205
+ {
1206
+ ref,
1207
+ className: cn("text-lg font-semibold leading-none tracking-tight", className),
1208
+ ...props
1209
+ }
1210
+ ));
1211
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
1212
+ var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1213
+ DialogPrimitive.Description,
1214
+ {
1215
+ ref,
1216
+ className: cn("text-sm text-muted-foreground", className),
1217
+ ...props
1218
+ }
1219
+ ));
1220
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
1221
+ var badgeVariants = cva(
1222
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none",
1223
+ {
1224
+ variants: {
1225
+ variant: {
1226
+ default: "border-transparent bg-primary text-primary-foreground",
1227
+ secondary: "border-transparent bg-secondary text-secondary-foreground",
1228
+ outline: "text-foreground",
1229
+ destructive: "border-transparent bg-destructive text-destructive-foreground"
1230
+ }
1231
+ },
1232
+ defaultVariants: {
1233
+ variant: "default"
1234
+ }
1235
+ }
1236
+ );
1237
+ function Badge({ className, variant, ...props }) {
1238
+ return /* @__PURE__ */ jsx("div", { className: cn(badgeVariants({ variant }), className), ...props });
1239
+ }
1240
+ var ScrollArea = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1241
+ ScrollAreaPrimitive.Root,
1242
+ {
1243
+ ref,
1244
+ className: cn("relative overflow-hidden", className),
1245
+ ...props,
1246
+ children: [
1247
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
1248
+ /* @__PURE__ */ jsx(ScrollBar, {}),
1249
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
1250
+ ]
1251
+ }
1252
+ ));
1253
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
1254
+ var ScrollBar = React3.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
1255
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
1256
+ {
1257
+ ref,
1258
+ orientation,
1259
+ className: cn(
1260
+ "flex touch-none select-none transition-colors",
1261
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
1262
+ orientation === "horizontal" && "h-2.5 border-t border-t-transparent p-[1px]",
1263
+ className
1264
+ ),
1265
+ ...props,
1266
+ children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
1267
+ }
1268
+ ));
1269
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
1270
+ var Card = React3.forwardRef(
1271
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1272
+ "div",
1273
+ {
1274
+ ref,
1275
+ className: cn("rounded-xl border bg-card text-card-foreground shadow", className),
1276
+ ...props
1277
+ }
1278
+ )
1279
+ );
1280
+ Card.displayName = "Card";
1281
+ var CardHeader = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1282
+ "div",
1283
+ {
1284
+ ref,
1285
+ className: cn("flex flex-col space-y-1.5 p-6", className),
1286
+ ...props
1287
+ }
1288
+ ));
1289
+ CardHeader.displayName = "CardHeader";
1290
+ var CardTitle = React3.forwardRef(
1291
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
1292
+ );
1293
+ CardTitle.displayName = "CardTitle";
1294
+ var CardDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
1295
+ CardDescription.displayName = "CardDescription";
1296
+ var CardContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
1297
+ CardContent.displayName = "CardContent";
1298
+ var CardFooter = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1299
+ "div",
1300
+ {
1301
+ ref,
1302
+ className: cn("flex items-center p-6 pt-0", className),
1303
+ ...props
1304
+ }
1305
+ ));
1306
+ CardFooter.displayName = "CardFooter";
983
1307
  var formatCardLabel = (method) => {
984
1308
  const brand = method.card_type ? method.card_type.toUpperCase() : "CARD";
985
1309
  const lastFour = method.last_four ? `\u2022\u2022\u2022\u2022 ${method.last_four}` : "";
@@ -1008,67 +1332,72 @@ var StoredPaymentMethods = ({
1008
1332
  }
1009
1333
  );
1010
1334
  };
1011
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel", children: [
1012
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel-header", children: [
1013
- /* @__PURE__ */ jsxs("div", { children: [
1014
- /* @__PURE__ */ jsxs("p", { className: "payments-ui-panel-title", children: [
1015
- /* @__PURE__ */ jsx(WalletCards, { className: "payments-ui-icon" }),
1335
+ return /* @__PURE__ */ jsxs(Card, { className: "border-border/60 bg-card/95", children: [
1336
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between space-y-0", children: [
1337
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1338
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base font-semibold text-foreground", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [
1339
+ /* @__PURE__ */ jsx(WalletCards, { className: "h-4 w-4" }),
1016
1340
  " ",
1017
1341
  heading
1018
- ] }),
1019
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-description", children: description })
1342
+ ] }) }),
1343
+ /* @__PURE__ */ jsx(CardDescription, { children: description })
1020
1344
  ] }),
1021
- showAddButton && /* @__PURE__ */ jsxs(
1022
- "button",
1023
- {
1024
- className: "payments-ui-button",
1025
- type: "button",
1026
- onClick: () => setIsModalOpen(true),
1027
- children: [
1028
- /* @__PURE__ */ jsx(CreditCard, { className: "payments-ui-icon" }),
1029
- " Add card"
1030
- ]
1031
- }
1032
- )
1345
+ showAddButton && /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => setIsModalOpen(true), children: [
1346
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
1347
+ " Add card"
1348
+ ] })
1033
1349
  ] }),
1034
- /* @__PURE__ */ jsx("div", { className: "payments-ui-panel-body", children: listQuery.isLoading ? /* @__PURE__ */ jsxs("div", { className: "payments-ui-empty", children: [
1035
- /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }),
1036
- " Loading cards..."
1037
- ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "payments-ui-empty", children: "No saved payment methods yet." }) : /* @__PURE__ */ jsx("div", { className: "payments-ui-method-list", children: payments.map((method) => {
1350
+ /* @__PURE__ */ jsx(CardContent, { children: listQuery.isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center rounded-lg border border-dashed border-border/60 bg-muted/10 py-8 text-sm text-muted-foreground", children: [
1351
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1352
+ " Loading cards\u2026"
1353
+ ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed border-border/60 bg-muted/10 px-4 py-6 text-sm text-muted-foreground", children: "No saved payment methods yet." }) : /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[320px] pr-2", children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => {
1038
1354
  const isSelected = selectedMethodId === method.id;
1039
1355
  return /* @__PURE__ */ jsxs(
1040
1356
  "div",
1041
1357
  {
1042
- className: clsx("payments-ui-method-item", {
1043
- "is-selected": isSelected
1044
- }),
1358
+ className: cn(
1359
+ "flex flex-col gap-3 rounded-lg border px-4 py-3 transition-colors md:flex-row md:items-center md:justify-between",
1360
+ isSelected ? "border-primary/60 bg-primary/5" : "border-border/60 bg-background"
1361
+ ),
1045
1362
  children: [
1046
- /* @__PURE__ */ jsxs("div", { children: [
1047
- /* @__PURE__ */ jsx("p", { className: "payments-ui-method-label", children: formatCardLabel(method) }),
1048
- /* @__PURE__ */ jsxs("p", { className: "payments-ui-method-meta", children: [
1363
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1364
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: formatCardLabel(method) }),
1365
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
1049
1366
  "Added on",
1050
1367
  " ",
1051
1368
  method.created_at ? new Date(method.created_at).toLocaleDateString() : "unknown"
1052
1369
  ] })
1053
1370
  ] }),
1054
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-method-actions", children: [
1371
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1372
+ /* @__PURE__ */ jsx(
1373
+ Badge,
1374
+ {
1375
+ variant: method.is_active ? "default" : "secondary",
1376
+ className: cn(
1377
+ method.is_active ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground"
1378
+ ),
1379
+ children: method.is_active ? "Active" : "Inactive"
1380
+ }
1381
+ ),
1382
+ method.failure_reason && /* @__PURE__ */ jsx(Badge, { variant: "destructive", children: method.failure_reason }),
1055
1383
  onMethodSelect && /* @__PURE__ */ jsx(
1056
- "button",
1384
+ Button,
1057
1385
  {
1058
- type: "button",
1059
- className: "payments-ui-text-button",
1386
+ size: "sm",
1387
+ variant: isSelected ? "default" : "outline",
1060
1388
  onClick: () => onMethodSelect(method),
1061
1389
  children: isSelected ? "Selected" : "Use card"
1062
1390
  }
1063
1391
  ),
1064
1392
  /* @__PURE__ */ jsx(
1065
- "button",
1393
+ Button,
1066
1394
  {
1067
- type: "button",
1068
- className: "payments-ui-icon-button payments-ui-danger",
1395
+ size: "icon",
1396
+ variant: "outline",
1397
+ className: "text-destructive",
1069
1398
  onClick: () => handleDelete(method),
1070
1399
  disabled: deletingId === method.id && deleteMutation.isPending,
1071
- children: deletingId === method.id && deleteMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }) : /* @__PURE__ */ jsx(Trash2, { className: "payments-ui-icon" })
1400
+ children: deletingId === method.id && deleteMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
1072
1401
  }
1073
1402
  )
1074
1403
  ] })
@@ -1076,29 +1405,23 @@ var StoredPaymentMethods = ({
1076
1405
  },
1077
1406
  method.id
1078
1407
  );
1079
- }) }) }),
1080
- /* @__PURE__ */ jsx(Dialog2.Root, { open: isModalOpen, onOpenChange: setIsModalOpen, children: /* @__PURE__ */ jsxs(Dialog2.Portal, { children: [
1081
- /* @__PURE__ */ jsx(Dialog2.Overlay, { className: "payments-ui-modal-overlay" }),
1082
- /* @__PURE__ */ jsxs(Dialog2.Content, { className: "payments-ui-modal", children: [
1083
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-modal-header", children: [
1084
- /* @__PURE__ */ jsxs("div", { children: [
1085
- /* @__PURE__ */ jsx("h3", { children: "Add a new card" }),
1086
- /* @__PURE__ */ jsx("p", { children: "Your card details are tokenized securely via our payment provider." })
1087
- ] }),
1088
- /* @__PURE__ */ jsx(Dialog2.Close, { className: "payments-ui-icon-button", children: /* @__PURE__ */ jsx(X, { className: "payments-ui-icon" }) })
1089
- ] }),
1090
- /* @__PURE__ */ jsx(
1091
- CardDetailsForm,
1092
- {
1093
- visible: isModalOpen,
1094
- collectPrefix: "payments-ui-card",
1095
- submitting: createMutation.isPending,
1096
- submitLabel: "Save card",
1097
- externalError: createMutation.error?.message ?? null,
1098
- onTokenize: handleCardTokenize
1099
- }
1100
- )
1101
- ] })
1408
+ }) }) }) }),
1409
+ /* @__PURE__ */ jsx(Dialog, { open: isModalOpen, onOpenChange: setIsModalOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-h-[90vh] overflow-y-auto", children: [
1410
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1411
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Add a new card" }),
1412
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Your card details are tokenized securely via our payment provider." })
1413
+ ] }),
1414
+ /* @__PURE__ */ jsx(
1415
+ CardDetailsForm,
1416
+ {
1417
+ visible: isModalOpen,
1418
+ collectPrefix: "payments-ui-card",
1419
+ submitting: createMutation.isPending,
1420
+ submitLabel: "Save card",
1421
+ externalError: createMutation.error?.message ?? null,
1422
+ onTokenize: handleCardTokenize
1423
+ }
1424
+ )
1102
1425
  ] }) })
1103
1426
  ] });
1104
1427
  };
@@ -1371,33 +1694,34 @@ var DirectPayment = ({
1371
1694
  onSuccess: onPaymentSuccess,
1372
1695
  onError: onPaymentError
1373
1696
  });
1374
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel", children: [
1375
- /* @__PURE__ */ jsx("div", { className: "payments-ui-panel-header", children: /* @__PURE__ */ jsxs("div", { children: [
1376
- /* @__PURE__ */ jsxs("p", { className: "payments-ui-panel-title", children: [
1377
- /* @__PURE__ */ jsx(Wallet, { className: "payments-ui-icon" }),
1697
+ return /* @__PURE__ */ jsxs(Card, { className: "space-y-4 border border-border/60 bg-background/80 p-6", children: [
1698
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1699
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: [
1700
+ /* @__PURE__ */ jsx(Wallet, { className: "h-4 w-4" }),
1378
1701
  " Pay with connected wallet"
1379
1702
  ] }),
1380
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-description", children: "Sign the transaction directly in your Solana wallet." })
1381
- ] }) }),
1382
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel-body", children: [
1383
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-balance-row", children: [
1384
- /* @__PURE__ */ jsx("span", { children: "Available balance" }),
1385
- isBalanceLoading ? /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }) : /* @__PURE__ */ jsx("strong", { children: balanceLabel })
1386
- ] }),
1387
- /* @__PURE__ */ jsxs(
1388
- "button",
1389
- {
1390
- type: "button",
1391
- className: "payments-ui-button",
1392
- disabled: !canPay,
1393
- onClick: pay,
1394
- children: [
1395
- isProcessing ? /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }) : /* @__PURE__ */ jsx(Wallet, { className: "payments-ui-icon" }),
1396
- isProcessing ? "Processing..." : "Pay with wallet"
1397
- ]
1398
- }
1399
- )
1400
- ] })
1703
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Sign the transaction directly in your Solana wallet." })
1704
+ ] }),
1705
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg border border-border/50 bg-muted/10 px-4 py-3 text-sm", children: [
1706
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Available balance" }),
1707
+ isBalanceLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: balanceLabel })
1708
+ ] }),
1709
+ /* @__PURE__ */ jsx(
1710
+ Button,
1711
+ {
1712
+ type: "button",
1713
+ className: "w-full",
1714
+ disabled: !canPay,
1715
+ onClick: pay,
1716
+ children: isProcessing ? /* @__PURE__ */ jsxs(Fragment, { children: [
1717
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1718
+ " Processing\u2026"
1719
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1720
+ /* @__PURE__ */ jsx(Wallet, { className: "mr-2 h-4 w-4" }),
1721
+ " Pay with wallet"
1722
+ ] })
1723
+ }
1724
+ )
1401
1725
  ] });
1402
1726
  };
1403
1727
  var useSolanaQrPayment = (options) => {
@@ -1563,31 +1887,32 @@ var QRCodePayment = ({
1563
1887
  onSuccess: onPaymentSuccess
1564
1888
  });
1565
1889
  if (!selectedToken) {
1566
- return /* @__PURE__ */ jsx("div", { className: "payments-ui-empty", children: "Select a token to continue." });
1890
+ return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-dashed border-border/60 bg-muted/10 px-4 py-6 text-center text-sm text-muted-foreground", children: "Select a token to continue." });
1567
1891
  }
1568
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel", children: [
1569
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel-header", children: [
1892
+ return /* @__PURE__ */ jsxs(Card, { className: "space-y-4 border border-border/60 bg-background/80 p-6", children: [
1893
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
1570
1894
  /* @__PURE__ */ jsxs("div", { children: [
1571
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-title", children: "Scan with Solana Pay" }),
1572
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-description", children: "Use any Solana Pay compatible wallet to scan and confirm." })
1895
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Scan with Solana Pay" }),
1896
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Use any Solana Pay compatible wallet to scan and confirm." })
1573
1897
  ] }),
1574
1898
  /* @__PURE__ */ jsx(
1575
- "button",
1899
+ Button,
1576
1900
  {
1577
1901
  type: "button",
1578
- className: "payments-ui-icon-button",
1902
+ variant: "outline",
1903
+ size: "icon",
1579
1904
  onClick: () => refresh(),
1580
1905
  disabled: isLoading,
1581
- children: isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "payments-ui-icon" })
1906
+ children: isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" })
1582
1907
  }
1583
1908
  )
1584
1909
  ] }),
1585
- error && /* @__PURE__ */ jsx("div", { className: "payments-ui-error", children: error }),
1586
- /* @__PURE__ */ jsx("div", { className: "payments-ui-qr-wrapper", children: qrDataUri ? /* @__PURE__ */ jsx("img", { src: qrDataUri, alt: "Solana Pay QR" }) : /* @__PURE__ */ jsx("div", { className: "payments-ui-empty", children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
1587
- /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }),
1588
- "Generating QR code..."
1910
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: error }),
1911
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center rounded-2xl border border-dashed border-border/70 bg-muted/5 p-6", children: qrDataUri ? /* @__PURE__ */ jsx("img", { src: qrDataUri, alt: "Solana Pay QR", className: "h-72 w-72 rounded-lg border border-border/40 bg-card" }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center gap-2 text-sm text-muted-foreground", children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
1912
+ /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin" }),
1913
+ " Generating QR code\u2026"
1589
1914
  ] }) : "QR code unavailable" }) }),
1590
- intent && /* @__PURE__ */ jsxs("div", { className: "payments-ui-countdown", children: [
1915
+ intent && /* @__PURE__ */ jsxs("div", { className: "text-center text-sm text-muted-foreground", children: [
1591
1916
  "Expires in ",
1592
1917
  timeRemaining,
1593
1918
  "s \xB7 ",
@@ -1601,54 +1926,55 @@ var PaymentStatus = ({
1601
1926
  state,
1602
1927
  usdAmount,
1603
1928
  solAmount,
1604
- errorMessage,
1605
1929
  transactionId,
1930
+ errorMessage,
1606
1931
  onRetry,
1607
1932
  onClose
1608
1933
  }) => {
1934
+ if (state === "processing" || state === "confirming") {
1935
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [
1936
+ /* @__PURE__ */ jsx(Loader2, { className: "h-10 w-10 animate-spin text-primary" }),
1937
+ /* @__PURE__ */ jsxs("div", { children: [
1938
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: state === "processing" ? "Processing payment\u2026" : "Awaiting confirmation\u2026" }),
1939
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
1940
+ "$",
1941
+ usdAmount.toFixed(2),
1942
+ " ",
1943
+ solAmount ? `\xB7 \u2248 ${solAmount.toFixed(4)} SOL` : ""
1944
+ ] })
1945
+ ] })
1946
+ ] });
1947
+ }
1609
1948
  if (state === "success") {
1610
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-status success", children: [
1611
- /* @__PURE__ */ jsx(CheckCircle, { className: "payments-ui-status-icon" }),
1612
- /* @__PURE__ */ jsx("h3", { children: "Payment confirmed" }),
1613
- /* @__PURE__ */ jsxs("p", { children: [
1614
- usdAmount.toFixed(2),
1615
- " USD (~",
1616
- solAmount.toFixed(4),
1617
- " SOL)."
1618
- ] }),
1619
- transactionId && /* @__PURE__ */ jsxs("p", { className: "payments-ui-status-meta", children: [
1620
- "Txn: ",
1621
- transactionId
1949
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
1950
+ /* @__PURE__ */ jsx(CheckCircle, { className: "h-12 w-12 text-primary" }),
1951
+ /* @__PURE__ */ jsxs("div", { children: [
1952
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: "Payment complete" }),
1953
+ transactionId && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
1954
+ "Txn: ",
1955
+ transactionId
1956
+ ] })
1622
1957
  ] }),
1623
- /* @__PURE__ */ jsx("button", { className: "payments-ui-button", type: "button", onClick: onClose, children: "Close" })
1958
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, className: "w-full", children: "Close" })
1624
1959
  ] });
1625
1960
  }
1626
1961
  if (state === "error") {
1627
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-status error", children: [
1628
- /* @__PURE__ */ jsx(XCircle, { className: "payments-ui-status-icon" }),
1629
- /* @__PURE__ */ jsx("h3", { children: "Payment failed" }),
1630
- /* @__PURE__ */ jsx("p", { children: errorMessage ?? "Please try again." }),
1631
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-status-actions", children: [
1632
- /* @__PURE__ */ jsxs("button", { className: "payments-ui-button", type: "button", onClick: onRetry, children: [
1633
- /* @__PURE__ */ jsx(RotateCcw, { className: "payments-ui-icon" }),
1634
- " Retry"
1962
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
1963
+ /* @__PURE__ */ jsx(XCircle, { className: "h-12 w-12 text-destructive" }),
1964
+ /* @__PURE__ */ jsxs("div", { children: [
1965
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: "Payment failed" }),
1966
+ errorMessage && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: errorMessage })
1967
+ ] }),
1968
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-2 sm:flex-row", children: [
1969
+ onRetry && /* @__PURE__ */ jsxs(Button, { variant: "secondary", className: "flex-1", onClick: onRetry, children: [
1970
+ /* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 h-4 w-4" }),
1971
+ " Try again"
1635
1972
  ] }),
1636
- /* @__PURE__ */ jsx("button", { className: "payments-ui-text-button", type: "button", onClick: onClose, children: "Cancel" })
1973
+ /* @__PURE__ */ jsx(Button, { className: "flex-1", onClick: onClose, children: "Close" })
1637
1974
  ] })
1638
1975
  ] });
1639
1976
  }
1640
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-status pending", children: [
1641
- /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }),
1642
- /* @__PURE__ */ jsx("h3", { children: state === "confirming" ? "Waiting for confirmations" : "Processing payment" }),
1643
- /* @__PURE__ */ jsxs("p", { children: [
1644
- "Paying ",
1645
- usdAmount.toFixed(2),
1646
- " USD (~",
1647
- solAmount.toFixed(4),
1648
- " SOL)."
1649
- ] }),
1650
- /* @__PURE__ */ jsx("p", { className: "payments-ui-status-meta", children: "This can take up to 60 seconds on Solana mainnet." })
1651
- ] });
1977
+ return null;
1652
1978
  };
1653
1979
  var useSupportedTokens = () => {
1654
1980
  const solanaService = useSolanaService();
@@ -1828,6 +2154,43 @@ var selectSolanaFlow = (state) => ({
1828
2154
  failSolanaPayment: state.failSolanaPayment,
1829
2155
  resetSolanaPayment: state.resetSolanaPayment
1830
2156
  });
2157
+ var Tabs = TabsPrimitive.Root;
2158
+ var TabsList = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2159
+ TabsPrimitive.List,
2160
+ {
2161
+ ref,
2162
+ className: cn(
2163
+ "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
2164
+ className
2165
+ ),
2166
+ ...props
2167
+ }
2168
+ ));
2169
+ TabsList.displayName = TabsPrimitive.List.displayName;
2170
+ var TabsTrigger = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2171
+ TabsPrimitive.Trigger,
2172
+ {
2173
+ ref,
2174
+ className: cn(
2175
+ "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
2176
+ className
2177
+ ),
2178
+ ...props
2179
+ }
2180
+ ));
2181
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
2182
+ var TabsContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2183
+ TabsPrimitive.Content,
2184
+ {
2185
+ ref,
2186
+ className: cn(
2187
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
2188
+ className
2189
+ ),
2190
+ ...props
2191
+ }
2192
+ ));
2193
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
1831
2194
  var SolanaPaymentSelector = ({
1832
2195
  isOpen,
1833
2196
  onClose,
@@ -1934,8 +2297,8 @@ var SolanaPaymentSelector = ({
1934
2297
  setTokenAmount(usdAmount / price);
1935
2298
  }, [isOpen, usdAmount, selectedToken, setTokenAmount]);
1936
2299
  const handleTokenChange = useCallback(
1937
- (event) => {
1938
- setSelectedTokenSymbol(event.target.value);
2300
+ (value) => {
2301
+ setSelectedTokenSymbol(value);
1939
2302
  },
1940
2303
  [setSelectedTokenSymbol]
1941
2304
  );
@@ -1949,124 +2312,98 @@ var SolanaPaymentSelector = ({
1949
2312
  }
1950
2313
  wasConnectedRef.current = connected;
1951
2314
  }, [connected, setTab]);
1952
- const renderSelector = () => {
1953
- if (tokensLoading) {
1954
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-empty", children: [
1955
- /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }),
1956
- " Loading tokens\u2026"
1957
- ] });
1958
- }
1959
- if (tokensError) {
1960
- return /* @__PURE__ */ jsx("div", { className: "payments-ui-error", children: tokensError });
1961
- }
1962
- if (!tokens.length) {
1963
- return /* @__PURE__ */ jsx("div", { className: "payments-ui-empty", children: "No payment tokens available." });
2315
+ const renderBody = () => {
2316
+ if (paymentState !== "selecting") {
2317
+ return /* @__PURE__ */ jsx(
2318
+ PaymentStatus,
2319
+ {
2320
+ state: paymentState,
2321
+ usdAmount,
2322
+ solAmount: tokenAmount,
2323
+ onRetry: handleRetry,
2324
+ onClose: handleClose,
2325
+ errorMessage,
2326
+ transactionId
2327
+ }
2328
+ );
1964
2329
  }
1965
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-token-select", children: [
1966
- /* @__PURE__ */ jsxs("label", { children: [
1967
- "Payment token",
1968
- /* @__PURE__ */ jsx("select", { value: selectedTokenSymbol ?? "", onChange: handleTokenChange, children: tokens.map((token) => /* @__PURE__ */ jsxs("option", { value: token.symbol, children: [
2330
+ return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: tokensLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center rounded-lg border border-dashed border-border/60 bg-muted/10 py-8 text-sm text-muted-foreground", children: [
2331
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
2332
+ " Loading supported tokens\u2026"
2333
+ ] }) : tokensError ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: tokensError }) : !tokens.length ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed border-border/60 bg-muted/10 px-4 py-6 text-sm text-muted-foreground", children: "No payment tokens available." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2334
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border/60 bg-muted/10 p-4 text-center", children: [
2335
+ /* @__PURE__ */ jsxs("div", { className: "text-2xl font-semibold text-foreground", children: [
2336
+ "$",
2337
+ usdAmount.toFixed(2),
2338
+ " USD"
2339
+ ] }),
2340
+ selectedToken && tokenAmount > 0 && /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
2341
+ "\u2248 ",
2342
+ tokenAmount.toFixed(selectedToken.symbol === "SOL" ? 4 : 2),
2343
+ " ",
2344
+ selectedToken.symbol
2345
+ ] })
2346
+ ] }),
2347
+ /* @__PURE__ */ jsxs(Select, { value: selectedToken?.symbol ?? "", onValueChange: handleTokenChange, children: [
2348
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select token" }) }),
2349
+ /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: tokens.map((token) => /* @__PURE__ */ jsxs(SelectItem, { value: token.symbol, children: [
1969
2350
  token.name,
1970
2351
  " (",
1971
2352
  token.symbol,
1972
2353
  ")"
1973
2354
  ] }, token.symbol)) })
1974
2355
  ] }),
1975
- /* @__PURE__ */ jsxs("p", { className: "payments-ui-token-meta", children: [
1976
- "\u2248 ",
1977
- tokenAmount.toFixed(4),
1978
- " ",
1979
- selectedToken?.symbol
1980
- ] })
1981
- ] });
1982
- };
1983
- if (paymentState !== "selecting") {
1984
- return /* @__PURE__ */ jsx(Dialog2.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog2.Portal, { children: [
1985
- /* @__PURE__ */ jsx(Dialog2.Overlay, { className: "payments-ui-modal-overlay" }),
1986
- /* @__PURE__ */ jsxs(Dialog2.Content, { className: "payments-ui-modal", children: [
1987
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-modal-header", children: [
1988
- /* @__PURE__ */ jsxs("div", { children: [
1989
- /* @__PURE__ */ jsx("h3", { children: "Complete your payment" }),
1990
- /* @__PURE__ */ jsx("p", { children: "Follow the prompts below to finish." })
1991
- ] }),
1992
- /* @__PURE__ */ jsx(
1993
- Dialog2.Close,
1994
- {
1995
- className: "payments-ui-icon-button",
1996
- disabled: paymentState === "processing" || paymentState === "confirming",
1997
- children: /* @__PURE__ */ jsx(X, { className: "payments-ui-icon" })
1998
- }
1999
- )
2000
- ] }),
2001
- /* @__PURE__ */ jsx(
2002
- PaymentStatus,
2003
- {
2004
- state: paymentState,
2005
- usdAmount,
2006
- solAmount: tokenAmount,
2007
- onRetry: handleRetry,
2008
- onClose: handleClose,
2009
- errorMessage,
2010
- transactionId
2011
- }
2012
- )
2013
- ] })
2014
- ] }) });
2015
- }
2016
- return /* @__PURE__ */ jsx(Dialog2.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog2.Portal, { children: [
2017
- /* @__PURE__ */ jsx(Dialog2.Overlay, { className: "payments-ui-modal-overlay" }),
2018
- /* @__PURE__ */ jsxs(Dialog2.Content, { className: "payments-ui-modal", children: [
2019
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-modal-header", children: [
2020
- /* @__PURE__ */ jsxs("div", { children: [
2021
- /* @__PURE__ */ jsx("h3", { children: "Complete your payment" }),
2022
- /* @__PURE__ */ jsx("p", { children: "Select a token and preferred method." })
2023
- ] }),
2024
- /* @__PURE__ */ jsx(Dialog2.Close, { className: "payments-ui-icon-button", children: /* @__PURE__ */ jsx(X, { className: "payments-ui-icon" }) })
2025
- ] }),
2026
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-tab-header", children: [
2027
- /* @__PURE__ */ jsx(
2028
- "button",
2029
- {
2030
- type: "button",
2031
- className: activeTab === "wallet" ? "active" : "",
2032
- onClick: () => setTab("wallet"),
2033
- disabled: !connected,
2034
- children: "Pay with wallet"
2035
- }
2036
- ),
2037
- /* @__PURE__ */ jsx(
2038
- "button",
2039
- {
2040
- type: "button",
2041
- className: activeTab === "qr" ? "active" : "",
2042
- onClick: () => setTab("qr"),
2043
- children: "Scan QR"
2044
- }
2045
- )
2046
- ] }),
2047
- renderSelector(),
2048
- activeTab === "wallet" ? /* @__PURE__ */ jsx(
2049
- DirectPayment,
2050
- {
2051
- priceId,
2052
- tokenAmount,
2053
- selectedToken,
2054
- supportedTokens: tokens,
2055
- onPaymentStart: handlePaymentStart,
2056
- onPaymentConfirming: handlePaymentConfirming,
2057
- onPaymentSuccess: handlePaymentSuccess,
2058
- onPaymentError: handlePaymentError
2059
- }
2060
- ) : /* @__PURE__ */ jsx(
2061
- QRCodePayment,
2356
+ /* @__PURE__ */ jsxs(
2357
+ Tabs,
2062
2358
  {
2063
- priceId,
2064
- selectedToken,
2065
- onPaymentError: handlePaymentError,
2066
- onPaymentSuccess: handlePaymentSuccess
2359
+ value: activeTab,
2360
+ onValueChange: (value) => setTab(value),
2361
+ className: "w-full",
2362
+ children: [
2363
+ /* @__PURE__ */ jsxs(TabsList, { className: "grid w-full grid-cols-2 bg-muted/20", children: [
2364
+ /* @__PURE__ */ jsxs(TabsTrigger, { value: "wallet", disabled: !connected, children: [
2365
+ /* @__PURE__ */ jsx(Wallet, { className: "mr-2 h-4 w-4" }),
2366
+ " Pay with Wallet"
2367
+ ] }),
2368
+ /* @__PURE__ */ jsxs(TabsTrigger, { value: "qr", children: [
2369
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
2370
+ " Scan QR Code"
2371
+ ] })
2372
+ ] }),
2373
+ /* @__PURE__ */ jsx(TabsContent, { value: "wallet", className: "mt-4", children: /* @__PURE__ */ jsx(
2374
+ DirectPayment,
2375
+ {
2376
+ priceId,
2377
+ tokenAmount,
2378
+ selectedToken,
2379
+ supportedTokens: tokens,
2380
+ onPaymentStart: handlePaymentStart,
2381
+ onPaymentConfirming: handlePaymentConfirming,
2382
+ onPaymentSuccess: handlePaymentSuccess,
2383
+ onPaymentError: handlePaymentError
2384
+ }
2385
+ ) }),
2386
+ /* @__PURE__ */ jsx(TabsContent, { value: "qr", className: "mt-4", children: /* @__PURE__ */ jsx(
2387
+ QRCodePayment,
2388
+ {
2389
+ priceId,
2390
+ selectedToken,
2391
+ onPaymentError: handlePaymentError,
2392
+ onPaymentSuccess: handlePaymentSuccess
2393
+ }
2394
+ ) })
2395
+ ]
2067
2396
  }
2068
- )
2069
- ] })
2397
+ ),
2398
+ !connected && activeTab === "wallet" && /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-amber-500/40 bg-amber-500/10 p-4 text-sm text-amber-100", children: "Please connect your Solana wallet to complete this payment, or switch to QR mode." })
2399
+ ] }) });
2400
+ };
2401
+ return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
2402
+ /* @__PURE__ */ jsxs(DialogHeader, { className: "space-y-1", children: [
2403
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Complete your payment" }),
2404
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Select a token and preferred method. We\u2019ll guide you through the rest." })
2405
+ ] }),
2406
+ renderBody()
2070
2407
  ] }) });
2071
2408
  };
2072
2409
  var PaymentExperience = ({
@@ -2129,81 +2466,74 @@ var PaymentExperience = ({
2129
2466
  failSavedPayment(message);
2130
2467
  }
2131
2468
  };
2132
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-experience", children: [
2133
- /* @__PURE__ */ jsxs("header", { className: "payments-ui-experience-header", children: [
2134
- /* @__PURE__ */ jsxs("div", { children: [
2135
- /* @__PURE__ */ jsxs("h2", { children: [
2136
- /* @__PURE__ */ jsx(CreditCard, { className: "payments-ui-icon" }),
2137
- " Secure checkout"
2469
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
2470
+ /* @__PURE__ */ jsxs(Card, { className: "border-border/60 bg-card/95", children: [
2471
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2472
+ /* @__PURE__ */ jsxs("div", { children: [
2473
+ /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-lg text-foreground", children: [
2474
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-5 w-5 text-primary" }),
2475
+ " Secure checkout"
2476
+ ] }),
2477
+ /* @__PURE__ */ jsxs(CardDescription, { children: [
2478
+ "Amount due: $",
2479
+ usdAmount.toFixed(2)
2480
+ ] })
2138
2481
  ] }),
2139
- /* @__PURE__ */ jsxs("p", { children: [
2140
- "Amount due: $",
2141
- usdAmount.toFixed(2)
2142
- ] })
2482
+ checkoutSummary && /* @__PURE__ */ jsx("div", { children: checkoutSummary })
2143
2483
  ] }),
2144
- checkoutSummary && /* @__PURE__ */ jsx("div", { className: "payments-ui-summary", children: checkoutSummary })
2145
- ] }),
2146
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-experience-grid", children: [
2147
- showStored && /* @__PURE__ */ jsxs("div", { className: "payments-ui-column", children: [
2148
- /* @__PURE__ */ jsx(
2149
- StoredPaymentMethods,
2150
- {
2151
- selectedMethodId,
2152
- onMethodSelect: handleMethodSelect,
2153
- heading: "Saved cards",
2154
- description: "Use or manage your saved payment methods."
2155
- }
2156
- ),
2157
- onSavedMethodPayment && /* @__PURE__ */ jsx(
2158
- "button",
2159
- {
2160
- type: "button",
2161
- className: "payments-ui-button",
2162
- disabled: !selectedMethodId || savedStatus === "processing",
2163
- onClick: handleSavedPayment,
2164
- children: savedStatus === "processing" ? "Processing\u2026" : "Pay with selected card"
2165
- }
2166
- ),
2167
- savedError && /* @__PURE__ */ jsx("p", { className: "payments-ui-error", children: savedError })
2168
- ] }),
2169
- showNewCard && /* @__PURE__ */ jsx("div", { className: "payments-ui-column", children: /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel", children: [
2170
- /* @__PURE__ */ jsx("div", { className: "payments-ui-panel-header", children: /* @__PURE__ */ jsxs("div", { children: [
2171
- /* @__PURE__ */ jsxs("p", { className: "payments-ui-panel-title", children: [
2172
- /* @__PURE__ */ jsx(CreditCard, { className: "payments-ui-icon" }),
2173
- " Pay with a new card"
2484
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("div", { className: "grid gap-8 lg:grid-cols-2", children: [
2485
+ showStored && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2486
+ /* @__PURE__ */ jsx(
2487
+ StoredPaymentMethods,
2488
+ {
2489
+ selectedMethodId,
2490
+ onMethodSelect: handleMethodSelect,
2491
+ heading: "Saved cards",
2492
+ description: "Use or manage your saved payment methods."
2493
+ }
2494
+ ),
2495
+ onSavedMethodPayment && /* @__PURE__ */ jsx(
2496
+ Button,
2497
+ {
2498
+ className: "w-full",
2499
+ disabled: !selectedMethodId || savedStatus === "processing",
2500
+ onClick: handleSavedPayment,
2501
+ children: savedStatus === "processing" ? "Processing\u2026" : "Pay with selected card"
2502
+ }
2503
+ ),
2504
+ savedError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: savedError })
2505
+ ] }),
2506
+ showNewCard && /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border/60 bg-background/80 p-6", children: [
2507
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-1", children: [
2508
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: [
2509
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
2510
+ " Pay with a new card"
2511
+ ] }),
2512
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Card details are tokenized via Collect.js and never hit your server." })
2174
2513
  ] }),
2175
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-description", children: "Card details are tokenized via Collect.js and never hit your server." })
2176
- ] }) }),
2177
- /* @__PURE__ */ jsx(
2178
- CardDetailsForm,
2179
- {
2180
- visible: true,
2181
- submitLabel: "Pay now",
2182
- submitting: newCardStatus === "processing",
2183
- externalError: newCardError,
2184
- onTokenize: handleNewCardTokenize
2185
- }
2186
- )
2514
+ /* @__PURE__ */ jsx(
2515
+ CardDetailsForm,
2516
+ {
2517
+ visible: true,
2518
+ submitLabel: "Pay now",
2519
+ submitting: newCardStatus === "processing",
2520
+ externalError: newCardError,
2521
+ onTokenize: handleNewCardTokenize
2522
+ }
2523
+ )
2524
+ ] }) })
2187
2525
  ] }) })
2188
2526
  ] }),
2189
- enableSolanaPay && /* @__PURE__ */ jsxs("div", { className: "payments-ui-solana-banner", children: [
2527
+ enableSolanaPay && /* @__PURE__ */ jsx(Card, { className: "border border-primary/40 bg-primary/5", children: /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-col gap-4 text-sm text-primary md:flex-row md:items-center md:justify-between", children: [
2190
2528
  /* @__PURE__ */ jsxs("div", { children: [
2191
- /* @__PURE__ */ jsxs("h3", { children: [
2192
- /* @__PURE__ */ jsx(Sparkles, { className: "payments-ui-icon" }),
2529
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-base font-semibold text-primary", children: [
2530
+ /* @__PURE__ */ jsx(Sparkles, { className: "h-4 w-4" }),
2193
2531
  " Prefer Solana Pay?"
2194
2532
  ] }),
2195
- /* @__PURE__ */ jsx("p", { children: "Use a Solana wallet or QR code for instant settlement." })
2533
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-primary/80", children: "Use a Solana wallet or QR code for instant settlement." })
2196
2534
  ] }),
2197
- /* @__PURE__ */ jsx(
2198
- "button",
2199
- {
2200
- type: "button",
2201
- className: "payments-ui-button",
2202
- onClick: () => setSolanaModalOpen(true),
2203
- children: "Open Solana Pay"
2204
- }
2205
- )
2206
- ] }),
2535
+ /* @__PURE__ */ jsx(Button, { onClick: () => setSolanaModalOpen(true), children: "Open Solana Pay" })
2536
+ ] }) }),
2207
2537
  enableSolanaPay && /* @__PURE__ */ jsx(
2208
2538
  SolanaPaymentSelector,
2209
2539
  {