'use client';
import { useCallback, useMemo } from 'react';
import { cn, pressable, text, prefixClassName } from '../../styles/theme';
import { useAccount } from 'wagmi';
import { useAnalytics } from '../../core/analytics/hooks/useAnalytics';
import { FundEvent } from '../../core/analytics/types';
import { usePopupMonitor } from '@/buy/hooks/usePopupMonitor';
import { ErrorSvg } from '@/internal/svg/errorSvg';
import { openPopup } from '@/internal/utils/openPopup';
import { Spinner } from '../../internal/components/Spinner';
import { AddSvg } from '../../internal/svg/addSvg';
import { SuccessSvg } from '../../internal/svg/successSvg';
import { ConnectWallet } from '../../wallet/components/ConnectWallet';
import { useGetFundingUrl } from '../hooks/useGetFundingUrl';
import type { FundButtonProps } from '../types';
import { getFundingPopupSize } from '../utils/getFundingPopupSize';
export function FundButton({
className,
children,
disabled = false,
fundingUrl,
openIn = 'popup',
popupSize = 'md',
target,
state: buttonState = 'default',
fiatCurrency = 'USD',
onPopupClose,
onClick,
render,
sessionToken,
}: FundButtonProps) {
// If the fundingUrl prop is undefined, fallback to our recommended funding URL based on the wallet type
const fallbackFundingUrl = useGetFundingUrl({
fiatCurrency,
originComponentName: 'FundButton',
sessionToken,
});
const { address } = useAccount();
const fundingUrlToRender = fundingUrl ?? fallbackFundingUrl;
const isDisabled = disabled || !fundingUrlToRender;
const { startPopupMonitor } = usePopupMonitor(onPopupClose);
const { sendAnalytics } = useAnalytics();
const handleAnalyticsInitiated = useCallback(() => {
sendAnalytics(FundEvent.FundInitiated, {
currency: fiatCurrency,
});
}, [sendAnalytics, fiatCurrency]);
const handleAnalyticsFailure = useCallback(
(error: string) => {
sendAnalytics(FundEvent.FundFailure, {
error,
metadata: { currency: fiatCurrency },
});
},
[sendAnalytics, fiatCurrency],
);
const handleClick = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
if (fundingUrlToRender && openIn === 'tab') {
handleAnalyticsInitiated();
onClick?.();
window.open(fundingUrlToRender, '_blank');
return;
}
if (fundingUrlToRender) {
handleAnalyticsInitiated();
onClick?.();
const { height, width } = getFundingPopupSize(
popupSize,
fundingUrlToRender,
);
const popupWindow = openPopup({
url: fundingUrlToRender,
height,
width,
target,
});
if (popupWindow) {
startPopupMonitor(popupWindow);
} else {
handleAnalyticsFailure('Failed to open funding popup');
}
}
},
[
fundingUrlToRender,
openIn,
handleAnalyticsInitiated,
onClick,
popupSize,
target,
startPopupMonitor,
handleAnalyticsFailure,
],
);
const buttonColorClass = useMemo(() => {
if (buttonState === 'error') {
return prefixClassName('bg-ock-error');
}
return pressable.primary;
}, [buttonState]);
const classNames = cn(
buttonColorClass,
'rounded-ock-default px-4 py-3 inline-flex items-center justify-center space-x-2',
{
[pressable.disabled]: isDisabled,
},
text.headline,
'text-ock-foreground-inverse',
className,
);
const buttonIcon = useMemo(() => {
switch (buttonState) {
case 'loading':
return '';
case 'success':
return ;
case 'error':
return ;
default:
return ;
}
}, [buttonState]);
const buttonTextContent = useMemo(() => {
switch (buttonState) {
case 'loading':
return '';
case 'success':
return 'Success';
case 'error':
return 'Something went wrong';
default:
return 'Fund';
}
}, [buttonState]);
const buttonContent = useMemo(() => {
if (buttonState === 'loading') {
return ;
}
return (
<>
{buttonIcon && (
{buttonIcon}
)}
{buttonTextContent}
>
);
}, [buttonState, buttonIcon, buttonTextContent]);
if (!address) {
return ;
}
if (render) {
return render({
status: buttonState,
onClick: handleClick,
isDisabled,
});
}
return (
);
}