mirror of
https://github.com/vercel/commerce.git
synced 2025-05-12 12:47:50 +00:00
refine button loading and order actions
This commit is contained in:
parent
37c603f64b
commit
5ef1972106
@ -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: {
|
||||||
|
@ -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 />;
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user