@doujins/payments-ui 0.0.1 → 0.0.3

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
 
@@ -28,7 +35,7 @@ var loadCollectJs = (tokenizationKey) => {
28
35
  if (existing) return;
29
36
  const script = document.createElement("script");
30
37
  script.src = SCRIPT_SRC;
31
- script.setAttribute("data-tokenization-key", trimmed);
38
+ script.setAttribute("data-tokenization-key", "8u8B78-23Z347-c2svF3-pbEb7G");
32
39
  script.setAttribute("data-field-ccnumber-placeholder", "0000 0000 0000 0000");
33
40
  script.setAttribute("data-field-ccexp-placeholder", "10 / 25");
34
41
  script.setAttribute("data-field-cvv-placeholder", "123");
@@ -414,12 +421,30 @@ var createPaymentStore = (options) => createStore((set, get) => {
414
421
  };
415
422
  return {
416
423
  ...initialState,
417
- setSelectedMethod: (methodId) => set({ selectedMethodId: methodId }),
418
- setSolanaModalOpen: (open) => set({ solanaModalOpen: open }),
419
- setSolanaTab: (tab) => set({ solanaTab: tab }),
420
- setSolanaSelectedToken: (symbol) => set({ solanaSelectedToken: symbol }),
421
- setSolanaTokenAmount: (amount) => set({ solanaTokenAmount: amount }),
422
- setSolanaTransactionId: (txId) => set({ solanaTransactionId: txId }),
424
+ setSelectedMethod: (methodId) => {
425
+ if (get().selectedMethodId === methodId) return;
426
+ set({ selectedMethodId: methodId });
427
+ },
428
+ setSolanaModalOpen: (open) => {
429
+ if (get().solanaModalOpen === open) return;
430
+ set({ solanaModalOpen: open });
431
+ },
432
+ setSolanaTab: (tab) => {
433
+ if (get().solanaTab === tab) return;
434
+ set({ solanaTab: tab });
435
+ },
436
+ setSolanaSelectedToken: (symbol) => {
437
+ if (get().solanaSelectedToken === symbol) return;
438
+ set({ solanaSelectedToken: symbol });
439
+ },
440
+ setSolanaTokenAmount: (amount) => {
441
+ if (get().solanaTokenAmount === amount) return;
442
+ set({ solanaTokenAmount: amount });
443
+ },
444
+ setSolanaTransactionId: (txId) => {
445
+ if (get().solanaTransactionId === txId) return;
446
+ set({ solanaTransactionId: txId });
447
+ },
423
448
  startSavedPayment: () => {
424
449
  notifyStatus("processing", { source: "saved-payment" });
425
450
  set({ savedPaymentStatus: "processing", savedPaymentError: null });
@@ -519,38 +544,261 @@ var customCountries = [
519
544
  ];
520
545
  countryList.overwrite(customCountries);
521
546
  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);
547
+ function setRef(ref, value) {
548
+ if (typeof ref === "function") {
549
+ return ref(value);
550
+ } else if (ref !== null && ref !== void 0) {
551
+ ref.current = value;
552
+ }
553
+ }
554
+ function composeRefs(...refs) {
555
+ return (node) => {
556
+ let hasCleanup = false;
557
+ const cleanups = refs.map((ref) => {
558
+ const cleanup = setRef(ref, node);
559
+ if (!hasCleanup && typeof cleanup == "function") {
560
+ hasCleanup = true;
536
561
  }
562
+ return cleanup;
563
+ });
564
+ if (hasCleanup) {
565
+ return () => {
566
+ for (let i = 0; i < cleanups.length; i++) {
567
+ const cleanup = cleanups[i];
568
+ if (typeof cleanup == "function") {
569
+ cleanup();
570
+ } else {
571
+ setRef(refs[i], null);
572
+ }
573
+ }
574
+ };
537
575
  }
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
576
  };
553
577
  }
578
+ // @__NO_SIDE_EFFECTS__
579
+ function createSlot(ownerName) {
580
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
581
+ const Slot2 = React3.forwardRef((props, forwardedRef) => {
582
+ const { children, ...slotProps } = props;
583
+ const childrenArray = React3.Children.toArray(children);
584
+ const slottable = childrenArray.find(isSlottable);
585
+ if (slottable) {
586
+ const newElement = slottable.props.children;
587
+ const newChildren = childrenArray.map((child) => {
588
+ if (child === slottable) {
589
+ if (React3.Children.count(newElement) > 1) return React3.Children.only(null);
590
+ return React3.isValidElement(newElement) ? newElement.props.children : null;
591
+ } else {
592
+ return child;
593
+ }
594
+ });
595
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React3.isValidElement(newElement) ? React3.cloneElement(newElement, void 0, newChildren) : null });
596
+ }
597
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
598
+ });
599
+ Slot2.displayName = `${ownerName}.Slot`;
600
+ return Slot2;
601
+ }
602
+ var Slot = /* @__PURE__ */ createSlot("Slot");
603
+ // @__NO_SIDE_EFFECTS__
604
+ function createSlotClone(ownerName) {
605
+ const SlotClone = React3.forwardRef((props, forwardedRef) => {
606
+ const { children, ...slotProps } = props;
607
+ if (React3.isValidElement(children)) {
608
+ const childrenRef = getElementRef(children);
609
+ const props2 = mergeProps(slotProps, children.props);
610
+ if (children.type !== React3.Fragment) {
611
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
612
+ }
613
+ return React3.cloneElement(children, props2);
614
+ }
615
+ return React3.Children.count(children) > 1 ? React3.Children.only(null) : null;
616
+ });
617
+ SlotClone.displayName = `${ownerName}.SlotClone`;
618
+ return SlotClone;
619
+ }
620
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
621
+ function isSlottable(child) {
622
+ return React3.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
623
+ }
624
+ function mergeProps(slotProps, childProps) {
625
+ const overrideProps = { ...childProps };
626
+ for (const propName in childProps) {
627
+ const slotPropValue = slotProps[propName];
628
+ const childPropValue = childProps[propName];
629
+ const isHandler = /^on[A-Z]/.test(propName);
630
+ if (isHandler) {
631
+ if (slotPropValue && childPropValue) {
632
+ overrideProps[propName] = (...args) => {
633
+ const result = childPropValue(...args);
634
+ slotPropValue(...args);
635
+ return result;
636
+ };
637
+ } else if (slotPropValue) {
638
+ overrideProps[propName] = slotPropValue;
639
+ }
640
+ } else if (propName === "style") {
641
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
642
+ } else if (propName === "className") {
643
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
644
+ }
645
+ }
646
+ return { ...slotProps, ...overrideProps };
647
+ }
648
+ function getElementRef(element) {
649
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
650
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
651
+ if (mayWarn) {
652
+ return element.ref;
653
+ }
654
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
655
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
656
+ if (mayWarn) {
657
+ return element.props.ref;
658
+ }
659
+ return element.props.ref || element.ref;
660
+ }
661
+ function cn(...inputs) {
662
+ return twMerge(clsx(inputs));
663
+ }
664
+ var buttonVariants = cva(
665
+ "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",
666
+ {
667
+ variants: {
668
+ variant: {
669
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
670
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
671
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
672
+ ghost: "hover:bg-accent hover:text-accent-foreground",
673
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
674
+ link: "text-primary underline-offset-4 hover:underline"
675
+ },
676
+ size: {
677
+ default: "h-10 px-4 py-2",
678
+ sm: "h-9 rounded-md px-3",
679
+ lg: "h-11 rounded-md px-8",
680
+ icon: "h-10 w-10"
681
+ }
682
+ },
683
+ defaultVariants: {
684
+ variant: "default",
685
+ size: "default"
686
+ }
687
+ }
688
+ );
689
+ var Button = React3.forwardRef(
690
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
691
+ const Comp = asChild ? Slot : "button";
692
+ return /* @__PURE__ */ jsx(
693
+ Comp,
694
+ {
695
+ className: cn(buttonVariants({ variant, size, className })),
696
+ ref,
697
+ ...props
698
+ }
699
+ );
700
+ }
701
+ );
702
+ Button.displayName = "Button";
703
+ var Input = React3.forwardRef(
704
+ ({ className, type, ...props }, ref) => {
705
+ return /* @__PURE__ */ jsx(
706
+ "input",
707
+ {
708
+ type,
709
+ className: cn(
710
+ "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",
711
+ className
712
+ ),
713
+ ref,
714
+ ...props
715
+ }
716
+ );
717
+ }
718
+ );
719
+ Input.displayName = "Input";
720
+ var Label = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
721
+ LabelPrimitive.Root,
722
+ {
723
+ ref,
724
+ className: cn(
725
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
726
+ className
727
+ ),
728
+ ...props
729
+ }
730
+ ));
731
+ Label.displayName = LabelPrimitive.Root.displayName;
732
+ var Select = SelectPrimitive.Root;
733
+ var SelectValue = SelectPrimitive.Value;
734
+ var SelectTrigger = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
735
+ SelectPrimitive.Trigger,
736
+ {
737
+ ref,
738
+ className: cn(
739
+ "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",
740
+ className
741
+ ),
742
+ ...props,
743
+ children: [
744
+ children,
745
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
746
+ ]
747
+ }
748
+ ));
749
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
750
+ var SelectContent = React3.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
751
+ SelectPrimitive.Content,
752
+ {
753
+ ref,
754
+ className: cn(
755
+ "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",
756
+ className
757
+ ),
758
+ position,
759
+ ...props,
760
+ children: [
761
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) }),
762
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: "p-1", children }),
763
+ /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) })
764
+ ]
765
+ }
766
+ ) }));
767
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
768
+ var SelectLabel = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
769
+ SelectPrimitive.Label,
770
+ {
771
+ ref,
772
+ className: cn("px-2 py-1.5 text-sm font-semibold text-muted-foreground", className),
773
+ ...props
774
+ }
775
+ ));
776
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
777
+ var SelectItem = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
778
+ SelectPrimitive.Item,
779
+ {
780
+ ref,
781
+ className: cn(
782
+ "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",
783
+ className
784
+ ),
785
+ ...props,
786
+ children: [
787
+ /* @__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" }) }) }),
788
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
789
+ ]
790
+ }
791
+ ));
792
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
793
+ var SelectSeparator = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
794
+ SelectPrimitive.Separator,
795
+ {
796
+ ref,
797
+ className: cn("mx-1 my-1 h-px bg-muted", className),
798
+ ...props
799
+ }
800
+ ));
801
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
554
802
  var defaultBilling = {
555
803
  firstName: "",
556
804
  lastName: "",
@@ -597,14 +845,6 @@ var CardDetailsForm = ({
597
845
  const [email, setEmail] = useState(mergedDefaults.email ?? "");
598
846
  const [localError, setLocalError] = useState(null);
599
847
  const [isTokenizing, setIsTokenizing] = useState(false);
600
- const {
601
- countryDropdownRef,
602
- countryOpen,
603
- setCountryOpen,
604
- countrySearch,
605
- setCountrySearch,
606
- filteredCountries
607
- } = useCountryDropdown();
608
848
  useEffect(() => {
609
849
  if (!visible) {
610
850
  setLocalError(null);
@@ -725,38 +965,43 @@ var CardDetailsForm = ({
725
965
  window.CollectJS.startPaymentRequest();
726
966
  };
727
967
  const errorMessage = localError ?? externalError;
968
+ 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
969
  return /* @__PURE__ */ jsxs(
729
970
  "form",
730
971
  {
731
- className: clsx("payments-ui-card-form", className),
972
+ className: cn(
973
+ "space-y-6 rounded-2xl border border-border/60 bg-card/90 p-6 shadow-lg",
974
+ className
975
+ ),
732
976
  onSubmit: handleSubmit,
733
977
  noValidate: true,
734
978
  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" }),
979
+ errorMessage && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: errorMessage }),
980
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
981
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
982
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-first", className: "flex items-center gap-2 text-muted-foreground", children: [
983
+ /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
739
984
  " First name"
740
985
  ] }),
741
986
  /* @__PURE__ */ jsx(
742
- "input",
987
+ Input,
743
988
  {
744
- className: "payments-ui-input",
989
+ id: "payments-first",
745
990
  value: firstName,
746
991
  onChange: (e) => setFirstName(e.target.value),
747
992
  required: true
748
993
  }
749
994
  )
750
995
  ] }),
751
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
752
- /* @__PURE__ */ jsxs("span", { children: [
753
- /* @__PURE__ */ jsx(User, { className: "payments-ui-icon" }),
996
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
997
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-last", className: "flex items-center gap-2 text-muted-foreground", children: [
998
+ /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
754
999
  " Last name"
755
1000
  ] }),
756
1001
  /* @__PURE__ */ jsx(
757
- "input",
1002
+ Input,
758
1003
  {
759
- className: "payments-ui-input",
1004
+ id: "payments-last",
760
1005
  value: lastName,
761
1006
  onChange: (e) => setLastName(e.target.value),
762
1007
  required: true
@@ -764,171 +1009,125 @@ var CardDetailsForm = ({
764
1009
  )
765
1010
  ] })
766
1011
  ] }),
767
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
768
- /* @__PURE__ */ jsx("span", { children: "Email" }),
1012
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1013
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-email", children: "Email" }),
769
1014
  /* @__PURE__ */ jsx(
770
- "input",
1015
+ Input,
771
1016
  {
1017
+ id: "payments-email",
772
1018
  type: "email",
773
- className: "payments-ui-input",
774
1019
  value: email,
775
1020
  onChange: (e) => setEmail(e.target.value),
776
1021
  required: true
777
1022
  }
778
1023
  )
779
1024
  ] }),
780
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
781
- /* @__PURE__ */ jsx("span", { children: "Address line 1" }),
1025
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1026
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-address1", children: "Address line 1" }),
782
1027
  /* @__PURE__ */ jsx(
783
- "input",
1028
+ Input,
784
1029
  {
785
- className: "payments-ui-input",
1030
+ id: "payments-address1",
786
1031
  value: address1,
787
1032
  onChange: (e) => setAddress1(e.target.value),
788
1033
  required: true
789
1034
  }
790
1035
  )
791
1036
  ] }),
792
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
793
- /* @__PURE__ */ jsx("span", { children: "Address line 2 (optional)" }),
1037
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1038
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-address2", children: "Address line 2 (optional)" }),
794
1039
  /* @__PURE__ */ jsx(
795
- "input",
1040
+ Input,
796
1041
  {
797
- className: "payments-ui-input",
1042
+ id: "payments-address2",
798
1043
  value: address2,
799
1044
  onChange: (e) => setAddress2(e.target.value)
800
1045
  }
801
1046
  )
802
1047
  ] }),
803
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-grid", children: [
804
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
805
- /* @__PURE__ */ jsx("span", { children: "City" }),
1048
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1049
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1050
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-city", children: "City" }),
806
1051
  /* @__PURE__ */ jsx(
807
- "input",
1052
+ Input,
808
1053
  {
809
- className: "payments-ui-input",
1054
+ id: "payments-city",
810
1055
  value: city,
811
1056
  onChange: (e) => setCity(e.target.value),
812
1057
  required: true
813
1058
  }
814
1059
  )
815
1060
  ] }),
816
- /* @__PURE__ */ jsxs("label", { className: "payments-ui-label", children: [
817
- /* @__PURE__ */ jsx("span", { children: "State / Region" }),
1061
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1062
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-state", children: "State / Region" }),
818
1063
  /* @__PURE__ */ jsx(
819
- "input",
1064
+ Input,
820
1065
  {
821
- className: "payments-ui-input",
1066
+ id: "payments-state",
822
1067
  value: stateRegion,
823
1068
  onChange: (e) => setStateRegion(e.target.value)
824
1069
  }
825
1070
  )
826
1071
  ] })
827
1072
  ] }),
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" }),
1073
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1074
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1075
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-postal", className: "flex items-center gap-2 text-muted-foreground", children: [
1076
+ /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
832
1077
  " Postal code"
833
1078
  ] }),
834
1079
  /* @__PURE__ */ jsx(
835
- "input",
1080
+ Input,
836
1081
  {
837
- className: "payments-ui-input",
1082
+ id: "payments-postal",
838
1083
  value: postalCode,
839
1084
  onChange: (e) => setPostalCode(e.target.value),
840
1085
  required: true
841
1086
  }
842
1087
  )
843
1088
  ] }),
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
- ] })
1089
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1090
+ /* @__PURE__ */ jsx(Label, { children: "Country" }),
1091
+ /* @__PURE__ */ jsxs(Select, { value: country, onValueChange: setCountry, children: [
1092
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a country" }) }),
1093
+ /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: countries.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.code, children: option.name }, option.code)) })
883
1094
  ] })
884
1095
  ] })
885
1096
  ] }),
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
- )
1097
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1098
+ /* @__PURE__ */ jsx(Label, { children: "Card number" }),
1099
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccnumber").slice(1), className: collectFieldClass })
895
1100
  ] }),
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
- )
1101
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
1102
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1103
+ /* @__PURE__ */ jsx(Label, { children: "Expiry" }),
1104
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccexp").slice(1), className: collectFieldClass })
906
1105
  ] }),
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
- )
1106
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1107
+ /* @__PURE__ */ jsx(Label, { children: "CVV" }),
1108
+ /* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "cvv").slice(1), className: collectFieldClass })
916
1109
  ] })
917
1110
  ] }),
918
- errorMessage && /* @__PURE__ */ jsx("p", { className: "payments-ui-error", children: errorMessage }),
919
- /* @__PURE__ */ jsxs(
920
- "button",
1111
+ /* @__PURE__ */ jsx(
1112
+ Button,
921
1113
  {
922
1114
  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
- ]
1115
+ className: "w-full",
1116
+ disabled: submitting || submitDisabled || isTokenizing,
1117
+ children: submitting || isTokenizing ? /* @__PURE__ */ jsxs(Fragment, { children: [
1118
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1119
+ " Processing\u2026"
1120
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1121
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
1122
+ " ",
1123
+ submitLabel
1124
+ ] })
930
1125
  }
931
- )
1126
+ ),
1127
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
1128
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
1129
+ " Your payment information is encrypted and processed securely."
1130
+ ] })
932
1131
  ]
933
1132
  }
934
1133
  );
@@ -980,6 +1179,149 @@ var usePaymentMethods = () => {
980
1179
  deleteMutation
981
1180
  };
982
1181
  };
1182
+ var Dialog = DialogPrimitive.Root;
1183
+ var DialogPortal = ({ className, ...props }) => /* @__PURE__ */ jsx(DialogPrimitive.Portal, { className: cn(className), ...props });
1184
+ DialogPortal.displayName = DialogPrimitive.Portal.displayName;
1185
+ var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1186
+ DialogPrimitive.Overlay,
1187
+ {
1188
+ ref,
1189
+ className: cn(
1190
+ "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",
1191
+ className
1192
+ ),
1193
+ ...props
1194
+ }
1195
+ ));
1196
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
1197
+ var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
1198
+ /* @__PURE__ */ jsx(DialogOverlay, {}),
1199
+ /* @__PURE__ */ jsxs(
1200
+ DialogPrimitive.Content,
1201
+ {
1202
+ ref,
1203
+ className: cn(
1204
+ "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%]",
1205
+ className
1206
+ ),
1207
+ ...props,
1208
+ children: [
1209
+ children,
1210
+ /* @__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: [
1211
+ /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
1212
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1213
+ ] })
1214
+ ]
1215
+ }
1216
+ )
1217
+ ] }));
1218
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
1219
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
1220
+ DialogHeader.displayName = "DialogHeader";
1221
+ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1222
+ DialogPrimitive.Title,
1223
+ {
1224
+ ref,
1225
+ className: cn("text-lg font-semibold leading-none tracking-tight", className),
1226
+ ...props
1227
+ }
1228
+ ));
1229
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
1230
+ var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1231
+ DialogPrimitive.Description,
1232
+ {
1233
+ ref,
1234
+ className: cn("text-sm text-muted-foreground", className),
1235
+ ...props
1236
+ }
1237
+ ));
1238
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
1239
+ var badgeVariants = cva(
1240
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none",
1241
+ {
1242
+ variants: {
1243
+ variant: {
1244
+ default: "border-transparent bg-primary text-primary-foreground",
1245
+ secondary: "border-transparent bg-secondary text-secondary-foreground",
1246
+ outline: "text-foreground",
1247
+ destructive: "border-transparent bg-destructive text-destructive-foreground"
1248
+ }
1249
+ },
1250
+ defaultVariants: {
1251
+ variant: "default"
1252
+ }
1253
+ }
1254
+ );
1255
+ function Badge({ className, variant, ...props }) {
1256
+ return /* @__PURE__ */ jsx("div", { className: cn(badgeVariants({ variant }), className), ...props });
1257
+ }
1258
+ var ScrollArea = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1259
+ ScrollAreaPrimitive.Root,
1260
+ {
1261
+ ref,
1262
+ className: cn("relative overflow-hidden", className),
1263
+ ...props,
1264
+ children: [
1265
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
1266
+ /* @__PURE__ */ jsx(ScrollBar, {}),
1267
+ /* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
1268
+ ]
1269
+ }
1270
+ ));
1271
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
1272
+ var ScrollBar = React3.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
1273
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
1274
+ {
1275
+ ref,
1276
+ orientation,
1277
+ className: cn(
1278
+ "flex touch-none select-none transition-colors",
1279
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
1280
+ orientation === "horizontal" && "h-2.5 border-t border-t-transparent p-[1px]",
1281
+ className
1282
+ ),
1283
+ ...props,
1284
+ children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
1285
+ }
1286
+ ));
1287
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
1288
+ var Card = React3.forwardRef(
1289
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1290
+ "div",
1291
+ {
1292
+ ref,
1293
+ className: cn("rounded-xl border bg-card text-card-foreground shadow", className),
1294
+ ...props
1295
+ }
1296
+ )
1297
+ );
1298
+ Card.displayName = "Card";
1299
+ var CardHeader = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1300
+ "div",
1301
+ {
1302
+ ref,
1303
+ className: cn("flex flex-col space-y-1.5 p-6", className),
1304
+ ...props
1305
+ }
1306
+ ));
1307
+ CardHeader.displayName = "CardHeader";
1308
+ var CardTitle = React3.forwardRef(
1309
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
1310
+ );
1311
+ CardTitle.displayName = "CardTitle";
1312
+ var CardDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
1313
+ CardDescription.displayName = "CardDescription";
1314
+ var CardContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
1315
+ CardContent.displayName = "CardContent";
1316
+ var CardFooter = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1317
+ "div",
1318
+ {
1319
+ ref,
1320
+ className: cn("flex items-center p-6 pt-0", className),
1321
+ ...props
1322
+ }
1323
+ ));
1324
+ CardFooter.displayName = "CardFooter";
983
1325
  var formatCardLabel = (method) => {
984
1326
  const brand = method.card_type ? method.card_type.toUpperCase() : "CARD";
985
1327
  const lastFour = method.last_four ? `\u2022\u2022\u2022\u2022 ${method.last_four}` : "";
@@ -1008,67 +1350,72 @@ var StoredPaymentMethods = ({
1008
1350
  }
1009
1351
  );
1010
1352
  };
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" }),
1353
+ return /* @__PURE__ */ jsxs(Card, { className: "border-border/60 bg-card/95", children: [
1354
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between space-y-0", children: [
1355
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1356
+ /* @__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: [
1357
+ /* @__PURE__ */ jsx(WalletCards, { className: "h-4 w-4" }),
1016
1358
  " ",
1017
1359
  heading
1018
- ] }),
1019
- /* @__PURE__ */ jsx("p", { className: "payments-ui-panel-description", children: description })
1360
+ ] }) }),
1361
+ /* @__PURE__ */ jsx(CardDescription, { children: description })
1020
1362
  ] }),
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
- )
1363
+ showAddButton && /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => setIsModalOpen(true), children: [
1364
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
1365
+ " Add card"
1366
+ ] })
1033
1367
  ] }),
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) => {
1368
+ /* @__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: [
1369
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1370
+ " Loading cards\u2026"
1371
+ ] }) : 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
1372
  const isSelected = selectedMethodId === method.id;
1039
1373
  return /* @__PURE__ */ jsxs(
1040
1374
  "div",
1041
1375
  {
1042
- className: clsx("payments-ui-method-item", {
1043
- "is-selected": isSelected
1044
- }),
1376
+ className: cn(
1377
+ "flex flex-col gap-3 rounded-lg border px-4 py-3 transition-colors md:flex-row md:items-center md:justify-between",
1378
+ isSelected ? "border-primary/60 bg-primary/5" : "border-border/60 bg-background"
1379
+ ),
1045
1380
  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: [
1381
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1382
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: formatCardLabel(method) }),
1383
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
1049
1384
  "Added on",
1050
1385
  " ",
1051
1386
  method.created_at ? new Date(method.created_at).toLocaleDateString() : "unknown"
1052
1387
  ] })
1053
1388
  ] }),
1054
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-method-actions", children: [
1389
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1390
+ /* @__PURE__ */ jsx(
1391
+ Badge,
1392
+ {
1393
+ variant: method.is_active ? "default" : "secondary",
1394
+ className: cn(
1395
+ method.is_active ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground"
1396
+ ),
1397
+ children: method.is_active ? "Active" : "Inactive"
1398
+ }
1399
+ ),
1400
+ method.failure_reason && /* @__PURE__ */ jsx(Badge, { variant: "destructive", children: method.failure_reason }),
1055
1401
  onMethodSelect && /* @__PURE__ */ jsx(
1056
- "button",
1402
+ Button,
1057
1403
  {
1058
- type: "button",
1059
- className: "payments-ui-text-button",
1404
+ size: "sm",
1405
+ variant: isSelected ? "default" : "outline",
1060
1406
  onClick: () => onMethodSelect(method),
1061
1407
  children: isSelected ? "Selected" : "Use card"
1062
1408
  }
1063
1409
  ),
1064
1410
  /* @__PURE__ */ jsx(
1065
- "button",
1411
+ Button,
1066
1412
  {
1067
- type: "button",
1068
- className: "payments-ui-icon-button payments-ui-danger",
1413
+ size: "icon",
1414
+ variant: "outline",
1415
+ className: "text-destructive",
1069
1416
  onClick: () => handleDelete(method),
1070
1417
  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" })
1418
+ 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
1419
  }
1073
1420
  )
1074
1421
  ] })
@@ -1076,29 +1423,23 @@ var StoredPaymentMethods = ({
1076
1423
  },
1077
1424
  method.id
1078
1425
  );
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
- ] })
1426
+ }) }) }) }),
1427
+ /* @__PURE__ */ jsx(Dialog, { open: isModalOpen, onOpenChange: setIsModalOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-h-[90vh] overflow-y-auto", children: [
1428
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
1429
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Add a new card" }),
1430
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Your card details are tokenized securely via our payment provider." })
1431
+ ] }),
1432
+ /* @__PURE__ */ jsx(
1433
+ CardDetailsForm,
1434
+ {
1435
+ visible: isModalOpen,
1436
+ collectPrefix: "payments-ui-card",
1437
+ submitting: createMutation.isPending,
1438
+ submitLabel: "Save card",
1439
+ externalError: createMutation.error?.message ?? null,
1440
+ onTokenize: handleCardTokenize
1441
+ }
1442
+ )
1102
1443
  ] }) })
1103
1444
  ] });
1104
1445
  };
@@ -1371,33 +1712,34 @@ var DirectPayment = ({
1371
1712
  onSuccess: onPaymentSuccess,
1372
1713
  onError: onPaymentError
1373
1714
  });
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" }),
1715
+ return /* @__PURE__ */ jsxs(Card, { className: "space-y-4 border border-border/60 bg-background/80 p-6", children: [
1716
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1717
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: [
1718
+ /* @__PURE__ */ jsx(Wallet, { className: "h-4 w-4" }),
1378
1719
  " Pay with connected wallet"
1379
1720
  ] }),
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
- ] })
1721
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Sign the transaction directly in your Solana wallet." })
1722
+ ] }),
1723
+ /* @__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: [
1724
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Available balance" }),
1725
+ isBalanceLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx("strong", { className: "text-foreground", children: balanceLabel })
1726
+ ] }),
1727
+ /* @__PURE__ */ jsx(
1728
+ Button,
1729
+ {
1730
+ type: "button",
1731
+ className: "w-full",
1732
+ disabled: !canPay,
1733
+ onClick: pay,
1734
+ children: isProcessing ? /* @__PURE__ */ jsxs(Fragment, { children: [
1735
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1736
+ " Processing\u2026"
1737
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1738
+ /* @__PURE__ */ jsx(Wallet, { className: "mr-2 h-4 w-4" }),
1739
+ " Pay with wallet"
1740
+ ] })
1741
+ }
1742
+ )
1401
1743
  ] });
1402
1744
  };
1403
1745
  var useSolanaQrPayment = (options) => {
@@ -1563,31 +1905,32 @@ var QRCodePayment = ({
1563
1905
  onSuccess: onPaymentSuccess
1564
1906
  });
1565
1907
  if (!selectedToken) {
1566
- return /* @__PURE__ */ jsx("div", { className: "payments-ui-empty", children: "Select a token to continue." });
1908
+ 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
1909
  }
1568
- return /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel", children: [
1569
- /* @__PURE__ */ jsxs("div", { className: "payments-ui-panel-header", children: [
1910
+ return /* @__PURE__ */ jsxs(Card, { className: "space-y-4 border border-border/60 bg-background/80 p-6", children: [
1911
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
1570
1912
  /* @__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." })
1913
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Scan with Solana Pay" }),
1914
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Use any Solana Pay compatible wallet to scan and confirm." })
1573
1915
  ] }),
1574
1916
  /* @__PURE__ */ jsx(
1575
- "button",
1917
+ Button,
1576
1918
  {
1577
1919
  type: "button",
1578
- className: "payments-ui-icon-button",
1920
+ variant: "outline",
1921
+ size: "icon",
1579
1922
  onClick: () => refresh(),
1580
1923
  disabled: isLoading,
1581
- children: isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "payments-ui-spinner" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "payments-ui-icon" })
1924
+ children: isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" })
1582
1925
  }
1583
1926
  )
1584
1927
  ] }),
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..."
1928
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: error }),
1929
+ /* @__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: [
1930
+ /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin" }),
1931
+ " Generating QR code\u2026"
1589
1932
  ] }) : "QR code unavailable" }) }),
1590
- intent && /* @__PURE__ */ jsxs("div", { className: "payments-ui-countdown", children: [
1933
+ intent && /* @__PURE__ */ jsxs("div", { className: "text-center text-sm text-muted-foreground", children: [
1591
1934
  "Expires in ",
1592
1935
  timeRemaining,
1593
1936
  "s \xB7 ",
@@ -1601,54 +1944,55 @@ var PaymentStatus = ({
1601
1944
  state,
1602
1945
  usdAmount,
1603
1946
  solAmount,
1604
- errorMessage,
1605
1947
  transactionId,
1948
+ errorMessage,
1606
1949
  onRetry,
1607
1950
  onClose
1608
1951
  }) => {
1952
+ if (state === "processing" || state === "confirming") {
1953
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [
1954
+ /* @__PURE__ */ jsx(Loader2, { className: "h-10 w-10 animate-spin text-primary" }),
1955
+ /* @__PURE__ */ jsxs("div", { children: [
1956
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: state === "processing" ? "Processing payment\u2026" : "Awaiting confirmation\u2026" }),
1957
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
1958
+ "$",
1959
+ usdAmount.toFixed(2),
1960
+ " ",
1961
+ solAmount ? `\xB7 \u2248 ${solAmount.toFixed(4)} SOL` : ""
1962
+ ] })
1963
+ ] })
1964
+ ] });
1965
+ }
1609
1966
  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
1967
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
1968
+ /* @__PURE__ */ jsx(CheckCircle, { className: "h-12 w-12 text-primary" }),
1969
+ /* @__PURE__ */ jsxs("div", { children: [
1970
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: "Payment complete" }),
1971
+ transactionId && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
1972
+ "Txn: ",
1973
+ transactionId
1974
+ ] })
1622
1975
  ] }),
1623
- /* @__PURE__ */ jsx("button", { className: "payments-ui-button", type: "button", onClick: onClose, children: "Close" })
1976
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, className: "w-full", children: "Close" })
1624
1977
  ] });
1625
1978
  }
1626
1979
  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"
1980
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
1981
+ /* @__PURE__ */ jsx(XCircle, { className: "h-12 w-12 text-destructive" }),
1982
+ /* @__PURE__ */ jsxs("div", { children: [
1983
+ /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold text-foreground", children: "Payment failed" }),
1984
+ errorMessage && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: errorMessage })
1985
+ ] }),
1986
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-2 sm:flex-row", children: [
1987
+ onRetry && /* @__PURE__ */ jsxs(Button, { variant: "secondary", className: "flex-1", onClick: onRetry, children: [
1988
+ /* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 h-4 w-4" }),
1989
+ " Try again"
1635
1990
  ] }),
1636
- /* @__PURE__ */ jsx("button", { className: "payments-ui-text-button", type: "button", onClick: onClose, children: "Cancel" })
1991
+ /* @__PURE__ */ jsx(Button, { className: "flex-1", onClick: onClose, children: "Close" })
1637
1992
  ] })
1638
1993
  ] });
1639
1994
  }
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
- ] });
1995
+ return null;
1652
1996
  };
1653
1997
  var useSupportedTokens = () => {
1654
1998
  const solanaService = useSolanaService();
@@ -1828,6 +2172,43 @@ var selectSolanaFlow = (state) => ({
1828
2172
  failSolanaPayment: state.failSolanaPayment,
1829
2173
  resetSolanaPayment: state.resetSolanaPayment
1830
2174
  });
2175
+ var Tabs = TabsPrimitive.Root;
2176
+ var TabsList = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2177
+ TabsPrimitive.List,
2178
+ {
2179
+ ref,
2180
+ className: cn(
2181
+ "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
2182
+ className
2183
+ ),
2184
+ ...props
2185
+ }
2186
+ ));
2187
+ TabsList.displayName = TabsPrimitive.List.displayName;
2188
+ var TabsTrigger = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2189
+ TabsPrimitive.Trigger,
2190
+ {
2191
+ ref,
2192
+ className: cn(
2193
+ "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",
2194
+ className
2195
+ ),
2196
+ ...props
2197
+ }
2198
+ ));
2199
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
2200
+ var TabsContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
2201
+ TabsPrimitive.Content,
2202
+ {
2203
+ ref,
2204
+ className: cn(
2205
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
2206
+ className
2207
+ ),
2208
+ ...props
2209
+ }
2210
+ ));
2211
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
1831
2212
  var SolanaPaymentSelector = ({
1832
2213
  isOpen,
1833
2214
  onClose,
@@ -1934,8 +2315,8 @@ var SolanaPaymentSelector = ({
1934
2315
  setTokenAmount(usdAmount / price);
1935
2316
  }, [isOpen, usdAmount, selectedToken, setTokenAmount]);
1936
2317
  const handleTokenChange = useCallback(
1937
- (event) => {
1938
- setSelectedTokenSymbol(event.target.value);
2318
+ (value) => {
2319
+ setSelectedTokenSymbol(value);
1939
2320
  },
1940
2321
  [setSelectedTokenSymbol]
1941
2322
  );
@@ -1949,124 +2330,98 @@ var SolanaPaymentSelector = ({
1949
2330
  }
1950
2331
  wasConnectedRef.current = connected;
1951
2332
  }, [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." });
2333
+ const renderBody = () => {
2334
+ if (paymentState !== "selecting") {
2335
+ return /* @__PURE__ */ jsx(
2336
+ PaymentStatus,
2337
+ {
2338
+ state: paymentState,
2339
+ usdAmount,
2340
+ solAmount: tokenAmount,
2341
+ onRetry: handleRetry,
2342
+ onClose: handleClose,
2343
+ errorMessage,
2344
+ transactionId
2345
+ }
2346
+ );
1964
2347
  }
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: [
2348
+ 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: [
2349
+ /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
2350
+ " Loading supported tokens\u2026"
2351
+ ] }) : 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: [
2352
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border/60 bg-muted/10 p-4 text-center", children: [
2353
+ /* @__PURE__ */ jsxs("div", { className: "text-2xl font-semibold text-foreground", children: [
2354
+ "$",
2355
+ usdAmount.toFixed(2),
2356
+ " USD"
2357
+ ] }),
2358
+ selectedToken && tokenAmount > 0 && /* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
2359
+ "\u2248 ",
2360
+ tokenAmount.toFixed(selectedToken.symbol === "SOL" ? 4 : 2),
2361
+ " ",
2362
+ selectedToken.symbol
2363
+ ] })
2364
+ ] }),
2365
+ /* @__PURE__ */ jsxs(Select, { value: selectedToken?.symbol ?? "", onValueChange: handleTokenChange, children: [
2366
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select token" }) }),
2367
+ /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: tokens.map((token) => /* @__PURE__ */ jsxs(SelectItem, { value: token.symbol, children: [
1969
2368
  token.name,
1970
2369
  " (",
1971
2370
  token.symbol,
1972
2371
  ")"
1973
2372
  ] }, token.symbol)) })
1974
2373
  ] }),
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,
2374
+ /* @__PURE__ */ jsxs(
2375
+ Tabs,
2062
2376
  {
2063
- priceId,
2064
- selectedToken,
2065
- onPaymentError: handlePaymentError,
2066
- onPaymentSuccess: handlePaymentSuccess
2377
+ value: activeTab,
2378
+ onValueChange: (value) => setTab(value),
2379
+ className: "w-full",
2380
+ children: [
2381
+ /* @__PURE__ */ jsxs(TabsList, { className: "grid w-full grid-cols-2 bg-muted/20", children: [
2382
+ /* @__PURE__ */ jsxs(TabsTrigger, { value: "wallet", disabled: !connected, children: [
2383
+ /* @__PURE__ */ jsx(Wallet, { className: "mr-2 h-4 w-4" }),
2384
+ " Pay with Wallet"
2385
+ ] }),
2386
+ /* @__PURE__ */ jsxs(TabsTrigger, { value: "qr", children: [
2387
+ /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
2388
+ " Scan QR Code"
2389
+ ] })
2390
+ ] }),
2391
+ /* @__PURE__ */ jsx(TabsContent, { value: "wallet", className: "mt-4", children: /* @__PURE__ */ jsx(
2392
+ DirectPayment,
2393
+ {
2394
+ priceId,
2395
+ tokenAmount,
2396
+ selectedToken,
2397
+ supportedTokens: tokens,
2398
+ onPaymentStart: handlePaymentStart,
2399
+ onPaymentConfirming: handlePaymentConfirming,
2400
+ onPaymentSuccess: handlePaymentSuccess,
2401
+ onPaymentError: handlePaymentError
2402
+ }
2403
+ ) }),
2404
+ /* @__PURE__ */ jsx(TabsContent, { value: "qr", className: "mt-4", children: /* @__PURE__ */ jsx(
2405
+ QRCodePayment,
2406
+ {
2407
+ priceId,
2408
+ selectedToken,
2409
+ onPaymentError: handlePaymentError,
2410
+ onPaymentSuccess: handlePaymentSuccess
2411
+ }
2412
+ ) })
2413
+ ]
2067
2414
  }
2068
- )
2069
- ] })
2415
+ ),
2416
+ !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." })
2417
+ ] }) });
2418
+ };
2419
+ return /* @__PURE__ */ jsx(Dialog, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-lg", children: [
2420
+ /* @__PURE__ */ jsxs(DialogHeader, { className: "space-y-1", children: [
2421
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Complete your payment" }),
2422
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Select a token and preferred method. We\u2019ll guide you through the rest." })
2423
+ ] }),
2424
+ renderBody()
2070
2425
  ] }) });
2071
2426
  };
2072
2427
  var PaymentExperience = ({
@@ -2129,81 +2484,74 @@ var PaymentExperience = ({
2129
2484
  failSavedPayment(message);
2130
2485
  }
2131
2486
  };
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"
2487
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
2488
+ /* @__PURE__ */ jsxs(Card, { className: "border-border/60 bg-card/95", children: [
2489
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
2490
+ /* @__PURE__ */ jsxs("div", { children: [
2491
+ /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-lg text-foreground", children: [
2492
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-5 w-5 text-primary" }),
2493
+ " Secure checkout"
2494
+ ] }),
2495
+ /* @__PURE__ */ jsxs(CardDescription, { children: [
2496
+ "Amount due: $",
2497
+ usdAmount.toFixed(2)
2498
+ ] })
2138
2499
  ] }),
2139
- /* @__PURE__ */ jsxs("p", { children: [
2140
- "Amount due: $",
2141
- usdAmount.toFixed(2)
2142
- ] })
2500
+ checkoutSummary && /* @__PURE__ */ jsx("div", { children: checkoutSummary })
2143
2501
  ] }),
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"
2502
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("div", { className: "grid gap-8 lg:grid-cols-2", children: [
2503
+ showStored && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2504
+ /* @__PURE__ */ jsx(
2505
+ StoredPaymentMethods,
2506
+ {
2507
+ selectedMethodId,
2508
+ onMethodSelect: handleMethodSelect,
2509
+ heading: "Saved cards",
2510
+ description: "Use or manage your saved payment methods."
2511
+ }
2512
+ ),
2513
+ onSavedMethodPayment && /* @__PURE__ */ jsx(
2514
+ Button,
2515
+ {
2516
+ className: "w-full",
2517
+ disabled: !selectedMethodId || savedStatus === "processing",
2518
+ onClick: handleSavedPayment,
2519
+ children: savedStatus === "processing" ? "Processing\u2026" : "Pay with selected card"
2520
+ }
2521
+ ),
2522
+ savedError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: savedError })
2523
+ ] }),
2524
+ 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: [
2525
+ /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-1", children: [
2526
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: [
2527
+ /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
2528
+ " Pay with a new card"
2529
+ ] }),
2530
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Card details are tokenized via Collect.js and never hit your server." })
2174
2531
  ] }),
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
- )
2532
+ /* @__PURE__ */ jsx(
2533
+ CardDetailsForm,
2534
+ {
2535
+ visible: true,
2536
+ submitLabel: "Pay now",
2537
+ submitting: newCardStatus === "processing",
2538
+ externalError: newCardError,
2539
+ onTokenize: handleNewCardTokenize
2540
+ }
2541
+ )
2542
+ ] }) })
2187
2543
  ] }) })
2188
2544
  ] }),
2189
- enableSolanaPay && /* @__PURE__ */ jsxs("div", { className: "payments-ui-solana-banner", children: [
2545
+ 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
2546
  /* @__PURE__ */ jsxs("div", { children: [
2191
- /* @__PURE__ */ jsxs("h3", { children: [
2192
- /* @__PURE__ */ jsx(Sparkles, { className: "payments-ui-icon" }),
2547
+ /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-base font-semibold text-primary", children: [
2548
+ /* @__PURE__ */ jsx(Sparkles, { className: "h-4 w-4" }),
2193
2549
  " Prefer Solana Pay?"
2194
2550
  ] }),
2195
- /* @__PURE__ */ jsx("p", { children: "Use a Solana wallet or QR code for instant settlement." })
2551
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-primary/80", children: "Use a Solana wallet or QR code for instant settlement." })
2196
2552
  ] }),
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
- ] }),
2553
+ /* @__PURE__ */ jsx(Button, { onClick: () => setSolanaModalOpen(true), children: "Open Solana Pay" })
2554
+ ] }) }),
2207
2555
  enableSolanaPay && /* @__PURE__ */ jsx(
2208
2556
  SolanaPaymentSelector,
2209
2557
  {