refine button loading and order actions

This commit is contained in:
tedraykov 2024-07-03 13:49:13 +03:00
parent 37c603f64b
commit 5ef1972106
5 changed files with 30 additions and 17 deletions

View File

@ -4,7 +4,7 @@ import { VariantProps, tv } from 'tailwind-variants';
const loadingDots = tv({ const loadingDots = tv({
slots: { slots: {
root: 'mx-2 inline-flex items-center', root: 'mx-2 inline-flex items-center',
dots: 'bg-content inline-block animate-blink rounded-full' dots: 'bg-content inline-block animate-blink rounded-full'
}, },
variants: { variants: {
size: { size: {

View File

@ -15,6 +15,11 @@ const ActivateWarranty = ({ order }: ActivateWarrantyModalProps) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const isWarrantyActivated = order?.warrantyStatus?.value === WarrantyStatus.Activated; const isWarrantyActivated = order?.warrantyStatus?.value === WarrantyStatus.Activated;
const isPassDeadline = isBeforeToday(order?.warrantyActivationDeadline?.value); const isPassDeadline = isBeforeToday(order?.warrantyActivationDeadline?.value);
const isOrderConfirmed = order?.orderConfirmation?.value;
if (!isOrderConfirmed) {
return null;
}
if (isWarrantyActivated) { if (isWarrantyActivated) {
return <WarrantyActivatedBadge />; return <WarrantyActivatedBadge />;

View File

@ -189,10 +189,9 @@ export default function OrderConfirmationModal({
onClose: () => void; onClose: () => void;
}) { }) {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [submitting, setSubmitting] = useState(false);
const [orderConfirmationContent, setOrderConfirmationContent] = const [orderConfirmationContent, setOrderConfirmationContent] =
useState<OrderConfirmationContent>(); useState<OrderConfirmationContent>();
const [, startTransition] = useTransition(); const [submitting, startTransition] = useTransition();
const formRef = useRef<HTMLFormElement>(null); const formRef = useRef<HTMLFormElement>(null);
useEffect(() => { useEffect(() => {
@ -210,12 +209,11 @@ export default function OrderConfirmationModal({
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => { const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
event.preventDefault(); event.preventDefault();
setSubmitting(true);
const form = formRef.current; const form = formRef.current;
if (!form) return; if (!form) return;
const formData = new FormData(form);
startTransition(async () => { startTransition(async () => {
const formData = new FormData(form);
await confirmOrder({ await confirmOrder({
order, order,
content: orderConfirmationContent!, content: orderConfirmationContent!,
@ -269,6 +267,7 @@ export default function OrderConfirmationModal({
color="primary" color="primary"
disabled={submitting || loading} disabled={submitting || loading}
isLoading={submitting} isLoading={submitting}
loadingText="Submitting"
> >
Submit Submit
</Button> </Button>

View File

@ -22,11 +22,10 @@ function SignInButton({ message }: { message: string | null }) {
{message && <div className="my-5">{message}</div>} {message && <div className="my-5">{message}</div>}
<Button <Button
type="submit" type="submit"
aria-label="Log in" aria-label="Sign In"
aria-disabled={pending}
disabled={pending} disabled={pending}
isLoading={pending} isLoading={pending}
loadingText="Signing In..." loadingText="Signing In"
className="w-full" className="w-full"
> >
Sign In Sign In
@ -38,11 +37,18 @@ function SignInButton({ message }: { message: string | null }) {
const LogoutButton = () => { const LogoutButton = () => {
const { pending } = useFormStatus(); const { pending } = useFormStatus();
return ( return (
<Button disabled={pending} type="submit" variant="outlined" className="w-full"> <Button
{pending ? 'Logging Out...' : 'Log Out'} disabled={pending}
type="submit"
className="w-full"
isLoading={pending}
loadingText="Logging Out"
>
Log Out
</Button> </Button>
); );
}; };
const ProfilePopover = ({ menu }: ProfilePopoverProps) => { const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
const [message, action] = useFormState(doLogin, null); const [message, action] = useFormState(doLogin, null);
const [, logoutAction] = useFormState(doLogout, null); const [, logoutAction] = useFormState(doLogout, null);

View File

@ -19,7 +19,8 @@ const buttonVariants = tv({
'disabled:pointer-events-none disabled:shadow-none', 'disabled:pointer-events-none disabled:shadow-none',
focusInput focusInput
], ],
loading: 'pointer-events-none flex shrink-0 items-center justify-center gap-1.5' loading: 'pointer-events-none flex shrink-0 items-center justify-center gap-1.5',
loadingDots: ''
}, },
variants: { variants: {
size: { size: {
@ -39,13 +40,15 @@ const buttonVariants = tv({
}, },
variant: { variant: {
solid: { solid: {
root: 'border border-transparent shadow-sm' root: 'shadow-sm',
loadingDots: 'bg-white'
}, },
outlined: { outlined: {
root: 'border bg-white shadow-sm' root: 'bg-white shadow-sm ring-1 ring-inset ring-gray-300',
loadingDots: 'bg-content'
}, },
text: { text: {
root: 'border border-transparent' loadingDots: 'bg-content'
} }
} }
}, },
@ -161,7 +164,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
className, className,
disabled, disabled,
isLoading, isLoading,
loadingText = 'Loading', loadingText,
size, size,
color, color,
variant, variant,
@ -170,7 +173,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
}: ButtonProps, }: ButtonProps,
forwardedRef forwardedRef
) => { ) => {
const { loading, root } = buttonVariants({ variant, size, color }); const { loading, loadingDots, root } = buttonVariants({ variant, size, color });
const Component = as || 'button'; const Component = as || 'button';
return ( return (
@ -183,7 +186,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
> >
{isLoading ? ( {isLoading ? (
<span className={loading()}> <span className={loading()}>
<LoadingDots className="bg-white" /> <LoadingDots className={loadingDots()} />
<span className="sr-only">{loadingText}</span> <span className="sr-only">{loadingText}</span>
<span>{loadingText}</span> <span>{loadingText}</span>
</span> </span>