@splito/sdk
Version:
Official JavaScript/TypeScript SDK for Splito - Split payments across multiple recipients
1,065 lines (1,052 loc) • 57.1 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/lib/utils.ts
function cn(...inputs) {
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
}
var import_clsx, import_tailwind_merge;
var init_utils = __esm({
"src/lib/utils.ts"() {
import_clsx = require("clsx");
import_tailwind_merge = require("tailwind-merge");
}
});
// src/components/ui/button.tsx
var React, import_react_slot, import_class_variance_authority, import_jsx_runtime, buttonVariants, Button;
var init_button = __esm({
"src/components/ui/button.tsx"() {
React = __toESM(require("react"));
import_react_slot = require("@radix-ui/react-slot");
import_class_variance_authority = require("class-variance-authority");
init_utils();
import_jsx_runtime = require("react/jsx-runtime");
buttonVariants = (0, import_class_variance_authority.cva)(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline"
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10"
}
},
defaultVariants: {
variant: "default",
size: "default"
}
}
);
Button = React.forwardRef(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? import_react_slot.Slot : "button";
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
}
);
Button.displayName = "Button";
}
});
// src/components/ui/card.tsx
var React2, import_jsx_runtime2, Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter;
var init_card = __esm({
"src/components/ui/card.tsx"() {
React2 = __toESM(require("react"));
init_utils();
import_jsx_runtime2 = require("react/jsx-runtime");
Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props }));
Card.displayName = "Card";
CardHeader = React2.forwardRef(
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
);
CardHeader.displayName = "CardHeader";
CardTitle = React2.forwardRef(
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
);
CardTitle.displayName = "CardTitle";
CardDescription = React2.forwardRef(
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
);
CardDescription.displayName = "CardDescription";
CardContent = React2.forwardRef(
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("p-6 pt-0", className), ...props })
);
CardContent.displayName = "CardContent";
CardFooter = React2.forwardRef(
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
);
CardFooter.displayName = "CardFooter";
}
});
// src/components/ui/input.tsx
var React3, import_jsx_runtime3, Input;
var init_input = __esm({
"src/components/ui/input.tsx"() {
React3 = __toESM(require("react"));
init_utils();
import_jsx_runtime3 = require("react/jsx-runtime");
Input = React3.forwardRef(
({ className, type, ...props }, ref) => {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"input",
{
type,
className: cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground 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 md:text-sm",
className
),
ref,
...props
}
);
}
);
Input.displayName = "Input";
}
});
// src/components/ui/label.tsx
var React4, LabelPrimitive, import_class_variance_authority2, import_jsx_runtime4, labelVariants, Label;
var init_label = __esm({
"src/components/ui/label.tsx"() {
React4 = __toESM(require("react"));
LabelPrimitive = __toESM(require("@radix-ui/react-label"));
import_class_variance_authority2 = require("class-variance-authority");
init_utils();
import_jsx_runtime4 = require("react/jsx-runtime");
labelVariants = (0, import_class_variance_authority2.cva)("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
Label = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LabelPrimitive.Root, { ref, className: cn(labelVariants(), className), ...props }));
Label.displayName = LabelPrimitive.Root.displayName;
}
});
// src/components/ui/badge.tsx
function Badge({ className, variant, ...props }) {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
}
var import_class_variance_authority3, import_jsx_runtime5, badgeVariants;
var init_badge = __esm({
"src/components/ui/badge.tsx"() {
import_class_variance_authority3 = require("class-variance-authority");
init_utils();
import_jsx_runtime5 = require("react/jsx-runtime");
badgeVariants = (0, import_class_variance_authority3.cva)(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground",
success: "border-transparent bg-success/10 text-success hover:bg-success/20",
warning: "border-transparent bg-warning/10 text-warning hover:bg-warning/20",
error: "border-transparent bg-destructive/10 text-destructive hover:bg-destructive/20"
}
},
defaultVariants: {
variant: "default"
}
}
);
}
});
// src/components/ui/dialog.tsx
var React5, DialogPrimitive, import_lucide_react, import_jsx_runtime6, Dialog, DialogPortal, DialogOverlay, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription;
var init_dialog = __esm({
"src/components/ui/dialog.tsx"() {
React5 = __toESM(require("react"));
DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
import_lucide_react = require("lucide-react");
init_utils();
import_jsx_runtime6 = require("react/jsx-runtime");
Dialog = DialogPrimitive.Root;
DialogPortal = DialogPrimitive.Portal;
DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
DialogPrimitive.Overlay,
{
ref,
className: cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
),
...props
}
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
DialogContent = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { children: [
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, {}),
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
DialogPrimitive.Content,
{
ref,
className: cn(
"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%] sm:rounded-lg",
className
),
...props,
children: [
children,
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.X, { className: "h-4 w-4" }),
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Close" })
] })
]
}
)
] }));
DialogContent.displayName = DialogPrimitive.Content.displayName;
DialogHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
DialogHeader.displayName = "DialogHeader";
DialogFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
DialogFooter.displayName = "DialogFooter";
DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
DialogPrimitive.Title,
{
ref,
className: cn("text-lg font-semibold leading-none tracking-tight", className),
...props
}
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;
DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
}
});
// src/components/ui/drawer.tsx
var React6, import_vaul, import_jsx_runtime7, Drawer, DrawerTrigger, DrawerPortal, DrawerClose, DrawerOverlay, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription;
var init_drawer = __esm({
"src/components/ui/drawer.tsx"() {
React6 = __toESM(require("react"));
import_vaul = require("vaul");
init_utils();
import_jsx_runtime7 = require("react/jsx-runtime");
Drawer = ({ shouldScaleBackground = true, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_vaul.Drawer.Root, { shouldScaleBackground, ...props });
Drawer.displayName = "Drawer";
DrawerTrigger = import_vaul.Drawer.Trigger;
DrawerPortal = import_vaul.Drawer.Portal;
DrawerClose = import_vaul.Drawer.Close;
DrawerOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_vaul.Drawer.Overlay, { ref, className: cn("fixed inset-0 z-50 bg-black/80", className), ...props }));
DrawerOverlay.displayName = import_vaul.Drawer.Overlay.displayName;
DrawerContent = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DrawerPortal, { children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DrawerOverlay, {}),
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
import_vaul.Drawer.Content,
{
ref,
className: cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className
),
...props,
children: [
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" }),
children
]
}
)
] }));
DrawerContent.displayName = "DrawerContent";
DrawerHeader = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cn("grid gap-1.5 p-4 text-center sm:text-left", className), ...props });
DrawerHeader.displayName = "DrawerHeader";
DrawerFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cn("mt-auto flex flex-col gap-2 p-4", className), ...props });
DrawerFooter.displayName = "DrawerFooter";
DrawerTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
import_vaul.Drawer.Title,
{
ref,
className: cn("text-lg font-semibold leading-none tracking-tight", className),
...props
}
));
DrawerTitle.displayName = import_vaul.Drawer.Title.displayName;
DrawerDescription = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_vaul.Drawer.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
DrawerDescription.displayName = import_vaul.Drawer.Description.displayName;
}
});
// src/hooks/use-toast.ts
function genId() {
count = (count + 1) % Number.MAX_SAFE_INTEGER;
return count.toString();
}
function dispatch(action) {
memoryState = reducer(memoryState, action);
listeners.forEach((listener) => {
listener(memoryState);
});
}
function toast({ ...props }) {
const id = genId();
const update = (props2) => dispatch({
type: "UPDATE_TOAST",
toast: { ...props2, id }
});
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
dispatch({
type: "ADD_TOAST",
toast: {
...props,
id,
open: true,
onOpenChange: (open) => {
if (!open) dismiss();
}
}
});
return {
id,
dismiss,
update
};
}
function useToast() {
const [state, setState] = React7.useState(memoryState);
React7.useEffect(() => {
listeners.push(setState);
return () => {
const index = listeners.indexOf(setState);
if (index > -1) {
listeners.splice(index, 1);
}
};
}, [state]);
return {
...state,
toast,
dismiss: (toastId) => dispatch({ type: "DISMISS_TOAST", toastId })
};
}
var React7, TOAST_LIMIT, TOAST_REMOVE_DELAY, count, toastTimeouts, addToRemoveQueue, reducer, listeners, memoryState;
var init_use_toast = __esm({
"src/hooks/use-toast.ts"() {
React7 = __toESM(require("react"));
TOAST_LIMIT = 1;
TOAST_REMOVE_DELAY = 1e6;
count = 0;
toastTimeouts = /* @__PURE__ */ new Map();
addToRemoveQueue = (toastId) => {
if (toastTimeouts.has(toastId)) {
return;
}
const timeout = setTimeout(() => {
toastTimeouts.delete(toastId);
dispatch({
type: "REMOVE_TOAST",
toastId
});
}, TOAST_REMOVE_DELAY);
toastTimeouts.set(toastId, timeout);
};
reducer = (state, action) => {
switch (action.type) {
case "ADD_TOAST":
return {
...state,
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
};
case "UPDATE_TOAST":
return {
...state,
toasts: state.toasts.map((t) => t.id === action.toast.id ? { ...t, ...action.toast } : t)
};
case "DISMISS_TOAST": {
const { toastId } = action;
if (toastId) {
addToRemoveQueue(toastId);
} else {
state.toasts.forEach((toast2) => {
addToRemoveQueue(toast2.id);
});
}
return {
...state,
toasts: state.toasts.map(
(t) => t.id === toastId || toastId === void 0 ? {
...t,
open: false
} : t
)
};
}
case "REMOVE_TOAST":
if (action.toastId === void 0) {
return {
...state,
toasts: []
};
}
return {
...state,
toasts: state.toasts.filter((t) => t.id !== action.toastId)
};
}
};
listeners = [];
memoryState = { toasts: [] };
}
});
// src/integrations/supabase/client.ts
var import_supabase_js, SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, supabase;
var init_client = __esm({
"src/integrations/supabase/client.ts"() {
import_supabase_js = require("@supabase/supabase-js");
SUPABASE_URL = "https://mhskwcysroougxpjacdz.supabase.co";
SUPABASE_PUBLISHABLE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1oc2t3Y3lzcm9vdWd4cGphY2R6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTg1OTQ4NjMsImV4cCI6MjA3NDE3MDg2M30.7R5jmf1okIVMQo10w-H0pfqkukfq90vXLJEkN7IvzBY";
supabase = (0, import_supabase_js.createClient)(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
auth: {
storage: localStorage,
persistSession: true,
autoRefreshToken: true
}
});
}
});
// src/sdk/SplitModal.tsx
function SplitModalContent({ token, baseUrl }) {
const { toast: toast2 } = useToast();
const [paymentIntent, setPaymentIntent] = (0, import_react.useState)(null);
const [recipients, setRecipients] = (0, import_react.useState)([]);
const [loading, setLoading] = (0, import_react.useState)(true);
const [paymentForm, setPaymentForm] = (0, import_react.useState)({
name: "",
email: "",
amount: 0
});
const [selectedAmount, setSelectedAmount] = (0, import_react.useState)(null);
const [selectedPaymentMethod, setSelectedPaymentMethod] = (0, import_react.useState)("stripe");
const [inviteForm, setInviteForm] = (0, import_react.useState)({
name: "",
email: ""
});
const [isInviting, setIsInviting] = (0, import_react.useState)(false);
const [showInviteForm, setShowInviteForm] = (0, import_react.useState)(false);
const [isGeneratingQR, setIsGeneratingQR] = (0, import_react.useState)(false);
const [showQRInvitation, setShowQRInvitation] = (0, import_react.useState)(false);
const [qrCodeData, setQrCodeData] = (0, import_react.useState)(null);
const [invitationUrl, setInvitationUrl] = (0, import_react.useState)(null);
const [isProcessingPayment, setIsProcessingPayment] = (0, import_react.useState)(false);
(0, import_react.useEffect)(() => {
if (token) {
fetchPaymentDetails();
}
}, [token]);
(0, import_react.useEffect)(() => {
if (recipients.length > 0 && !paymentForm.name) {
const urlParams = new URLSearchParams(window.location.search);
const inviteeEmail = urlParams.get("invitee");
if (inviteeEmail) {
const matchingRecipient = recipients.find(
(r) => r.email.toLowerCase() === decodeURIComponent(inviteeEmail).toLowerCase()
);
if (matchingRecipient) {
setPaymentForm((prev) => ({
...prev,
name: matchingRecipient.name,
email: matchingRecipient.email
}));
toast2({
title: "Welcome!",
description: `Hi ${matchingRecipient.name}, we've pre-filled your details.`
});
}
}
}
}, [recipients]);
const fetchPaymentDetails = async () => {
try {
const response = await fetch(`${baseUrl}/functions/v1/get-splitting-link`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ token })
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `HTTP ${response.status}`);
}
const data = await response.json();
if (!data) {
throw new Error("No data received");
}
setPaymentIntent(data);
setRecipients(data.recipients || []);
} catch (error) {
console.error("Error fetching payment details:", error);
toast2({
title: "Error",
description: error instanceof Error ? error.message : "Failed to load payment details",
variant: "destructive"
});
} finally {
setLoading(false);
}
};
const processPayment = async () => {
if (!paymentForm.name || !paymentForm.email || !selectedAmount) {
toast2({
title: "Error",
description: "Please fill in all required fields",
variant: "destructive"
});
return;
}
setIsProcessingPayment(true);
try {
if (selectedPaymentMethod === "stripe") {
const { data, error } = await supabase.functions.invoke("process-connected-payment", {
body: {
payment_intent_id: paymentIntent?.id,
payer_name: paymentForm.name,
payer_email: paymentForm.email,
amount_cents: selectedAmount
}
});
if (error) throw error;
if (data?.checkout_url) {
toast2({
title: "Redirecting to Payment",
description: "You'll be redirected to complete your payment securely."
});
await new Promise((resolve) => setTimeout(resolve, 500));
window.open(data.checkout_url, "_blank");
}
} else if (selectedPaymentMethod === "paypal") {
const { data, error } = await supabase.functions.invoke("create-paypal-payment", {
body: {
payment_intent_id: paymentIntent?.id,
payer_name: paymentForm.name,
payer_email: paymentForm.email,
amount_cents: selectedAmount
}
});
if (error) throw error;
if (data?.approval_url) {
toast2({
title: "Redirecting to PayPal",
description: "You'll be redirected to PayPal to complete your payment."
});
await new Promise((resolve) => setTimeout(resolve, 500));
window.open(data.approval_url, "_blank");
}
}
} catch (error) {
toast2({
title: "Payment Error",
description: error.message || "Failed to process payment",
variant: "destructive"
});
} finally {
setIsProcessingPayment(false);
}
};
const generateQRInvitation = async () => {
if (showQRInvitation) {
setShowQRInvitation(false);
return;
}
setIsGeneratingQR(true);
try {
const url = `${window.location.origin}/split/${token}`;
const qrData = await import_qrcode.default.toDataURL(url, {
width: 300,
margin: 2,
color: {
dark: "#000000",
light: "#FFFFFF"
}
});
setQrCodeData(qrData);
setInvitationUrl(url);
setShowQRInvitation(true);
} catch (error) {
toast2({
title: "Error",
description: "Failed to generate QR code",
variant: "destructive"
});
} finally {
setIsGeneratingQR(false);
}
};
const copyInvitationUrl = () => {
if (invitationUrl) {
navigator.clipboard.writeText(invitationUrl);
toast2({
title: "Copied!",
description: "Invitation link copied to clipboard"
});
}
};
const shareInvitation = async () => {
if (navigator.share && invitationUrl) {
try {
await navigator.share({
title: "Split Payment Invitation",
text: "Join me in splitting this payment",
url: invitationUrl
});
} catch (error) {
copyInvitationUrl();
}
} else {
copyInvitationUrl();
}
};
const sendInvitation = async () => {
if (!inviteForm.name || !inviteForm.email) {
toast2({
title: "Error",
description: "Please fill in all invitation fields",
variant: "destructive"
});
return;
}
if (!paymentIntent || !token) return;
setIsInviting(true);
try {
const { data, error } = await supabase.functions.invoke("send-invitation", {
body: {
paymentIntentId: paymentIntent.id,
inviteeEmail: inviteForm.email,
inviteeName: inviteForm.name,
inviterName: "Anonymous",
inviterEmail: "noreply@splito.com",
splittingToken: token
}
});
if (error) throw error;
const newRecipient = {
id: crypto.randomUUID(),
name: inviteForm.name,
email: inviteForm.email,
amount_cents: 0,
status: "pending",
payment_completed_at: null
};
setRecipients((prev) => [newRecipient, ...prev]);
toast2({
title: "Invitation Sent!",
description: `${inviteForm.name} has been invited and added to participants.`
});
setInviteForm({ name: "", email: "" });
setShowInviteForm(false);
fetchPaymentDetails();
} catch (error) {
console.error("Error sending invitation:", error);
toast2({
title: "Error",
description: error.message || "Failed to send invitation",
variant: "destructive"
});
} finally {
setIsInviting(false);
}
};
if (loading) {
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Loader2, { className: "w-8 h-8 animate-spin text-primary" }) });
}
if (!paymentIntent) {
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "p-6 text-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.AlertTriangle, { className: "w-12 h-12 text-warning mx-auto mb-4" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "text-xl font-semibold mb-2", children: "Splitting Link Not Found" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-muted-foreground", children: "This splitting link is invalid or has expired." })
] });
}
const totalPaid = recipients.filter((r) => r.status === "completed").reduce((sum, r) => sum + r.amount_cents, 0);
const remainingAmount = paymentIntent.amount_cents - totalPaid;
const progressPercentage = totalPaid / paymentIntent.amount_cents * 100;
const quickAmounts = [
{ label: "Equal Split", value: Math.ceil(remainingAmount / Math.max(1, (paymentIntent.max_participants || 10) - recipients.length)) },
{ label: "25%", value: Math.ceil(paymentIntent.amount_cents * 0.25) },
{ label: "50%", value: Math.ceil(paymentIntent.amount_cents * 0.5) },
{ label: "Full Amount", value: remainingAmount }
].filter((amount) => amount.value <= remainingAmount && amount.value > 0);
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-6 max-h-[80vh] overflow-y-auto px-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "text-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-center gap-4 mb-4", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col items-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "w-12 h-12 rounded-xl flex items-center justify-center mb-1 overflow-hidden", children: paymentIntent?.business?.logo_url ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"img",
{
src: paymentIntent.business.logo_url,
alt: `${paymentIntent.business.name} logo`,
className: "w-full h-full object-cover rounded-xl"
}
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "w-12 h-12 bg-gradient-to-br from-primary to-primary-hover rounded-xl flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Building2, { className: "w-6 h-6 text-white" }) }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: paymentIntent?.business?.name || "Business" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.RefreshCw, { className: "w-4 h-4 text-muted-foreground" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col items-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "w-12 h-12 rounded-xl flex items-center justify-center mb-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"img",
{
src: "/logo.png",
alt: "Splito",
className: "w-10 h-10 rounded object-cover"
}
) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-xs font-medium", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "bg-gradient-to-r from-primary to-primary/80 bg-clip-text text-transparent font-bold", children: "Splito" }) })
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "text-xl font-bold mb-1", children: "Split Payment Request" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-muted-foreground", children: "Join others in splitting this payment" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Card, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardHeader, { className: "pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardTitle, { className: "flex items-center gap-2 text-lg", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.DollarSign, { className: "w-5 h-5" }),
paymentIntent.products?.name || "Payment Request"
] }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardContent, { className: "space-y-3", children: [
paymentIntent.products?.description && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-muted-foreground", children: paymentIntent.products.description }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-3 text-sm", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "font-medium", children: "Total Amount" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "text-lg font-bold text-primary", children: [
"$",
(paymentIntent.amount_cents / 100).toFixed(2),
" ",
paymentIntent.currency
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "font-medium", children: "Remaining" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "text-lg font-bold text-success", children: [
"$",
(remainingAmount / 100).toFixed(2)
] })
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex justify-between text-xs", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-muted-foreground", children: "Progress" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "font-medium", children: [
progressPercentage.toFixed(0),
"%"
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "h-2 bg-secondary rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
"div",
{
className: "h-full bg-gradient-to-r from-primary to-primary/80 transition-all duration-500",
style: { width: `${progressPercentage}%` }
}
) })
] })
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Card, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardHeader, { className: "pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardTitle, { className: "flex items-center gap-2 text-base", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Users, { className: "w-4 h-4" }),
"Participants (",
recipients.length,
"/",
paymentIntent.max_participants || 10,
")"
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
variant: showQRInvitation ? "default" : "outline",
size: "sm",
onClick: generateQRInvitation,
disabled: isGeneratingQR,
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.QrCode, { className: "w-3 h-3" })
}
),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
variant: showInviteForm ? "default" : "outline",
size: "sm",
onClick: () => setShowInviteForm(!showInviteForm),
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.UserPlus, { className: "w-3 h-3" })
}
)
] })
] }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardContent, { className: "space-y-3", children: [
showQRInvitation && qrCodeData && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { className: "bg-gradient-to-r from-primary/5 to-secondary/5", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardContent, { className: "pt-4 text-center space-y-3", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: qrCodeData, alt: "QR Code", className: "mx-auto w-48 h-48" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-muted-foreground", children: "Scan to join the split" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex gap-2 justify-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { variant: "outline", size: "sm", onClick: copyInvitationUrl, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Copy, { className: "w-3 h-3" }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { variant: "outline", size: "sm", onClick: shareInvitation, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Share2, { className: "w-3 h-3" }) })
] })
] }) }),
showInviteForm && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { className: "bg-gradient-to-r from-primary/5 to-secondary/5 border-primary/20", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardContent, { className: "pt-3 space-y-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2 mb-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Mail, { className: "w-3 h-3 text-primary" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { className: "text-sm font-medium", children: "Invite someone to contribute" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-1 gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Label, { htmlFor: "inviteName", className: "text-xs", children: "Name" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Input,
{
id: "inviteName",
placeholder: "Friend's name",
value: inviteForm.name,
onChange: (e) => setInviteForm((prev) => ({ ...prev, name: e.target.value })),
className: "h-8 text-sm"
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Label, { htmlFor: "inviteEmail", className: "text-xs", children: "Email" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Input,
{
id: "inviteEmail",
type: "email",
placeholder: "friend@email.com",
value: inviteForm.email,
onChange: (e) => setInviteForm((prev) => ({ ...prev, email: e.target.value })),
className: "h-8 text-sm"
}
)
] })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex gap-2 pt-1", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
onClick: sendInvitation,
disabled: isInviting || !inviteForm.name || !inviteForm.email,
size: "sm",
className: "text-xs h-8",
children: isInviting ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Clock, { className: "w-3 h-3 animate-spin" }),
"Sending..."
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Send, { className: "w-3 h-3" }),
"Send Invitation"
] })
}
),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
variant: "outline",
size: "sm",
className: "text-xs h-8",
onClick: () => {
setShowInviteForm(false);
setInviteForm({ name: "", email: "" });
},
children: "Cancel"
}
)
] })
] }) }),
recipients.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "space-y-2", children: recipients.map((recipient) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between p-2 border rounded-lg text-sm", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "font-medium text-sm", children: recipient.name }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-muted-foreground", children: recipient.email })
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Badge, { variant: recipient.status === "completed" ? "success" : "secondary", className: "text-xs", children: [
"$",
(recipient.amount_cents / 100).toFixed(2)
] }),
recipient.status === "completed" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.CheckCircle, { className: "w-3 h-3 text-success" })
] })
] }, recipient.id)) })
] })
] }),
remainingAmount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Card, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CardHeader, { className: "pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardTitle, { className: "flex items-center gap-2 text-base", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.CreditCard, { className: "w-4 h-4" }),
"Choose Your Contribution"
] }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CardContent, { className: "space-y-3", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "grid grid-cols-2 gap-2", children: quickAmounts.map((amount) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
variant: selectedAmount === amount.value ? "default" : "outline",
onClick: () => setSelectedAmount(amount.value),
className: "text-xs h-9",
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "text-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "font-semibold", children: amount.label }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "text-xs opacity-80", children: [
"$",
(amount.value / 100).toFixed(2)
] })
] })
},
amount.label
)) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Label, { htmlFor: "customAmount", className: "text-xs", children: "Custom Amount" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Input,
{
id: "customAmount",
type: "number",
placeholder: "Enter custom amount",
value: selectedAmount ? (selectedAmount / 100).toString() : "",
onChange: (e) => setSelectedAmount(Math.round(parseFloat(e.target.value || "0") * 100)),
min: "0.01",
max: (remainingAmount / 100).toFixed(2),
step: "0.01",
className: "h-8 text-sm"
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-2", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Label, { className: "text-xs", children: "Your Details" }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Input,
{
placeholder: "Your name",
value: paymentForm.name,
onChange: (e) => setPaymentForm({ ...paymentForm, name: e.target.value }),
className: "h-8 text-sm"
}
),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Input,
{
type: "email",
placeholder: "your.email@example.com",
value: paymentForm.email,
onChange: (e) => setPaymentForm({ ...paymentForm, email: e.target.value }),
className: "h-8 text-sm"
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
Button,
{
onClick: processPayment,
disabled: !selectedAmount || !paymentForm.name || !paymentForm.email || isProcessingPayment,
className: "w-full",
size: "sm",
children: isProcessingPayment ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Loader2, { className: "w-4 h-4 mr-2 animate-spin" }),
"Processing..."
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.CreditCard, { className: "w-4 h-4 mr-2" }),
"Pay $",
selectedAmount ? (selectedAmount / 100).toFixed(2) : "0.00"
] })
}
)
] })
] })
] });
}
function SplitModal({ open, onClose, token, baseUrl, isMobile }) {
if (isMobile) {
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Drawer, { open, onOpenChange: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DrawerContent, { className: "max-h-[95vh]", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DrawerHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DrawerTitle, { children: "Split Payment" }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "px-4 pb-6 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SplitModalContent, { token, baseUrl }) })
] }) });
}
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dialog, { open, onOpenChange: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogContent, { className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DialogTitle, { children: "Split Payment" }) }),
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SplitModalContent, { token, baseUrl })
] }) });
}
var import_react, import_lucide_react2, import_qrcode, import_jsx_runtime8;
var init_SplitModal = __esm({
"src/sdk/SplitModal.tsx"() {
import_react = require("react");
import_lucide_react2 = require("lucide-react");
init_button();
init_card();
init_input();
init_label();
init_badge();
init_dialog();
init_drawer();
init_use_toast();
init_client();
import_qrcode = __toESM(require("qrcode"));
import_jsx_runtime8 = require("react/jsx-runtime");
}
});
// src/sdk/modal-initializer.tsx
var modal_initializer_exports = {};
__export(modal_initializer_exports, {
openSplitModal: () => openSplitModal
});
function openSplitModal(token, baseUrl) {
const isMobile = window.innerWidth < 768;
const apiBaseUrl = baseUrl || window.location.origin;
const container = document.createElement("div");
container.id = "splito-modal-root";
container.style.position = "fixed";
container.style.top = "0";
container.style.left = "0";
container.style.width = "100%";
container.style.height = "100%";
container.style.zIndex = "9999";
document.body.appendChild(container);
const root = (0, import_client2.createRoot)(container);
const handleClose = () => {
root.unmount();
document.body.removeChild(container);
};
root.render(
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
SplitModal,
{
open: true,
onClose: handleClose,
token,
baseUrl: apiBaseUrl,
isMobile
}
)
);
}
var import_client2, import_jsx_runtime9;
var init_modal_initializer = __esm({
"src/sdk/modal-initializer.tsx"() {
import_client2 = require("react-dom/client");
init_SplitModal();
import_jsx_runtime9 = require("react/jsx-runtime");
}
});
// src/sdk/index.ts
var index_exports = {};
__export(index_exports, {
Splito: () => Splito,
default: () => in