Improve zap-pay-request

environments/review-upgrade-ui-x91kq0/deployments/4803
danidfra 2024-09-11 16:45:40 -03:00
rodzic cfaaa43e04
commit 07fec136be
2 zmienionych plików z 41 dodań i 18 usunięć

Wyświetl plik

@ -1,48 +1,64 @@
import clsx from 'clsx'; import clsx from 'clsx';
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom';
import { themes } from './useZapButtonStyles'; import { shortNumberFormat } from 'soapbox/utils/numbers';
interface IZapButton { interface IButton {
/** Whether this button expands the width of its container. */
block?: boolean;
/** Elements inside the <button> */
children?: React.ReactNode;
/** Extra class names for the button. */ /** Extra class names for the button. */
className?: string; className?: string;
/** Prevent the button from being clicked. */
disabled?: boolean;
/** Specifies the icon element as 'svg' or 'img'. */
iconElement?: 'svg' | 'img';
/** URL to an SVG icon to render inside the button. */ /** URL to an SVG icon to render inside the button. */
icon?: string; icon?: string;
/** Action when the button is clicked. */ /** Action when the button is clicked. */
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void; onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
/** Text inside the button. Takes precedence over `children`. */ /** Amount of sats. */
text?: React.ReactNode; amount?: number;
/** Styles the button visually with a predefined theme. */ /** Makes the button into a navlink, if provided. */
theme?: keyof typeof themes; to?: string;
/** Change the button style if it is selected. */
selected: boolean;
/** Whether this button should submit a form by default. */ /** Whether this button should submit a form by default. */
type?: 'button' | 'submit'; type?: 'button' | 'submit';
} }
/** Customizable button element with various themes. */ /** Customizable button element. */
const ZapButton = React.forwardRef<HTMLButtonElement, IZapButton>((props, ref): JSX.Element => { const ZapButton = React.forwardRef<HTMLButtonElement, IButton>((props, ref): JSX.Element => {
const { const {
disabled = false,
icon, icon,
onClick, onClick,
theme = 'secondary', selected,
text, to,
amount,
type = 'button', type = 'button',
className, className,
} = props; } = props;
const renderButton = () => ( const renderButton = () => (
<button <button
disabled={disabled}
onClick={onClick} onClick={onClick}
ref={ref} ref={ref}
type={type} type={type}
data-testid='button' data-testid='button'
> >
<div className={clsx(className, { 'flex flex-col items-center w-12 !box-border place-content-center border font-medium p-2 rounded-xl focus:outline-none focus:ring-2 focus:ring-offset-2 appearance-none transition-all sm:w-20 sm:p-4': true, <div className={clsx(className, { 'flex flex-col items-center w-14 !box-border place-content-center border font-medium p-2 rounded-xl focus:outline-none focus:ring-2 focus:ring-offset-2 appearance-none transition-all sm:p-4 sm:w-20': true,
[`${themes[theme]}`]: true })} 'select-none disabled:opacity-75 disabled:cursor-default': disabled,
'bg-primary-500 hover:bg-primary-400 dark:hover:bg-primary-600 border-transparent focus:bg-primary-500 text-gray-100 focus:ring-primary-300': selected,
'border border-solid bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500': !selected })}
> >
<img className='w-16' src={icon} alt='stack coin' /> <img className='w-16' src={icon} alt='stack coin' />
<span className='text-base sm:text-2xl'> <span className='text-base sm:text-2xl'>
<p> <p>
{text} {shortNumberFormat(amount)}
</p> </p>
</span> </span>
@ -50,6 +66,14 @@ const ZapButton = React.forwardRef<HTMLButtonElement, IZapButton>((props, ref):
</button> </button>
); );
if (to) {
return (
<Link to={to} tabIndex={-1} className='inline-flex'>
{renderButton()}
</Link>
);
}
return renderButton(); return renderButton();
}); });

Wyświetl plik

@ -37,6 +37,9 @@ const ZapPayRequestForm = ({ account, status, onClose }: IZapPayRequestForm) =>
const [zapComment, setZapComment] = useState(''); const [zapComment, setZapComment] = useState('');
// amount in millisatoshi // amount in millisatoshi
const [zapAmount, setZapAmount] = useState(50); const [zapAmount, setZapAmount] = useState(50);
const ZAP_AMOUNTS = [50, 200, 1_000, 3_000, 5_000];
const ZAP_ICONS = [coinIcon, coinStack, pileCoin, moneyBag, chestIcon];
const handleSubmit = async (e?: React.FormEvent<Element>) => { const handleSubmit = async (e?: React.FormEvent<Element>) => {
e?.preventDefault(); e?.preventDefault();
@ -81,11 +84,7 @@ const ZapPayRequestForm = ({ account, status, onClose }: IZapPayRequestForm) =>
</Stack> </Stack>
<div className='flex justify-center '> <div className='flex justify-center '>
<ZapButton onClick={() => setZapAmount(50)} className='m-1' theme={zapAmount === 50 ? 'primary' : 'muted'} icon={coinIcon} text='50' /> {ZAP_AMOUNTS.map((amount, i) => <ZapButton onClick={() => setZapAmount(amount)} className='m-0.5 sm:m-1' selected={zapAmount === amount} icon={ZAP_ICONS[i]} amount={amount} />)}
<ZapButton onClick={() => setZapAmount(200)} className='m-1' theme={zapAmount === 200 ? 'primary' : 'muted'} icon={coinStack} text='200' />
<ZapButton onClick={() => setZapAmount(1_000)} className='m-1' theme={zapAmount === 1_000 ? 'primary' : 'muted'} icon={pileCoin} text='1K' />
<ZapButton onClick={() => setZapAmount(3_000)} className='m-1' theme={zapAmount === 3_000 ? 'primary' : 'muted'} icon={moneyBag} text='3K' />
<ZapButton onClick={() => setZapAmount(5_000)} className='m-1' theme={zapAmount === 5_000 ? 'primary' : 'muted'} icon={chestIcon} text='5K' />
</div> </div>
<Stack space={2}> <Stack space={2}>