mirror of
https://github.com/vercel/commerce.git
synced 2025-05-13 05:07:51 +00:00
add logout button
This commit is contained in:
parent
aa29b3071d
commit
5517ccbd07
@ -31,8 +31,23 @@ const buttonVariants = tv({
|
|||||||
root: 'text-base px-4 py-2.5'
|
root: 'text-base px-4 py-2.5'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
color: {
|
||||||
|
primary: {},
|
||||||
|
content: {}
|
||||||
|
},
|
||||||
variant: {
|
variant: {
|
||||||
primary: {
|
solid: {},
|
||||||
|
outlined: {
|
||||||
|
root: 'border bg-white'
|
||||||
|
},
|
||||||
|
text: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
color: 'primary',
|
||||||
|
variant: 'solid',
|
||||||
|
class: {
|
||||||
root: [
|
root: [
|
||||||
// border
|
// border
|
||||||
'border-transparent',
|
'border-transparent',
|
||||||
@ -44,48 +59,41 @@ const buttonVariants = tv({
|
|||||||
'hover:bg-primary-empahsis',
|
'hover:bg-primary-empahsis',
|
||||||
// disabled
|
// disabled
|
||||||
'disabled:bg-primary-muted',
|
'disabled:bg-primary-muted',
|
||||||
'hover:bg-primary-emphasis',
|
|
||||||
'pressed:bg-primary-emphasis/80'
|
'pressed:bg-primary-emphasis/80'
|
||||||
]
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
secondary: {
|
{
|
||||||
|
color: 'primary',
|
||||||
|
variant: 'outlined',
|
||||||
|
class: {
|
||||||
root: [
|
root: [
|
||||||
// border
|
// border
|
||||||
'border-gray-300',
|
'border-primary',
|
||||||
// text color
|
// text color
|
||||||
'text-gray-900',
|
'text-primary',
|
||||||
// background color
|
// background color
|
||||||
'bg-white',
|
'bg-white',
|
||||||
// hover color
|
// hover color
|
||||||
'hover:bg-gray-50',
|
'hover:bg-primary/10',
|
||||||
// disabled
|
// disabled
|
||||||
'disabled:text-gray-400'
|
'disabled:border-primary-muted disabled:text-primary-muted'
|
||||||
]
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
root: [
|
|
||||||
// border
|
|
||||||
'border-transparent',
|
|
||||||
// text color
|
|
||||||
'text-tremor-brand',
|
|
||||||
// background color
|
|
||||||
'bg-transparent',
|
|
||||||
// hover color
|
|
||||||
'disabled:text-gray-400'
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: 'primary',
|
variant: 'solid',
|
||||||
|
color: 'primary',
|
||||||
size: 'md'
|
size: 'md'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ButtonProps extends ButtonBaseProps, VariantProps<typeof buttonVariants> {
|
interface ButtonProps extends Omit<ButtonBaseProps, 'color'>, VariantProps<typeof buttonVariants> {
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
loadingText?: string;
|
loadingText?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
|
@ -14,12 +14,15 @@ import CloseCart from './close-cart';
|
|||||||
import LineItem from './line-item';
|
import LineItem from './line-item';
|
||||||
import OpenCart from './open-cart';
|
import OpenCart from './open-cart';
|
||||||
import VehicleDetails, { VehicleFormSchema, vehicleFormSchema } from './vehicle-details';
|
import VehicleDetails, { VehicleFormSchema, vehicleFormSchema } from './vehicle-details';
|
||||||
|
import useAuth from 'hooks/use-auth';
|
||||||
|
|
||||||
export default function CartModal({ cart }: { cart: Cart | undefined }) {
|
export default function CartModal({ cart }: { cart: Cart | undefined }) {
|
||||||
|
const { isAuthenticated } = useAuth();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const quantityRef = useRef(cart?.totalQuantity);
|
const quantityRef = useRef(cart?.totalQuantity);
|
||||||
const openCart = () => setIsOpen(true);
|
const openCart = () => setIsOpen(true);
|
||||||
const closeCart = () => setIsOpen(false);
|
const closeCart = () => setIsOpen(false);
|
||||||
|
const [checkoutUrl, setCheckoutUrl] = useState<string | undefined>(cart?.checkoutUrl);
|
||||||
const { control, handleSubmit } = useForm<VehicleFormSchema>({
|
const { control, handleSubmit } = useForm<VehicleFormSchema>({
|
||||||
resolver: zodResolver(vehicleFormSchema),
|
resolver: zodResolver(vehicleFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -45,6 +48,20 @@ export default function CartModal({ cart }: { cart: Cart | undefined }) {
|
|||||||
}
|
}
|
||||||
}, [isOpen, cart?.totalQuantity, quantityRef]);
|
}, [isOpen, cart?.totalQuantity, quantityRef]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!cart) return;
|
||||||
|
if (isAuthenticated) {
|
||||||
|
const newCheckoutUrl = new URL(cart.checkoutUrl);
|
||||||
|
newCheckoutUrl.searchParams.append('logged_in', 'true');
|
||||||
|
|
||||||
|
return setCheckoutUrl(newCheckoutUrl.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkoutUrl !== cart.checkoutUrl) {
|
||||||
|
setCheckoutUrl(cart.checkoutUrl);
|
||||||
|
}
|
||||||
|
}, [cart, isAuthenticated, checkoutUrl]);
|
||||||
|
|
||||||
const onSubmit = async (data: VehicleFormSchema) => {
|
const onSubmit = async (data: VehicleFormSchema) => {
|
||||||
if (!cart) return;
|
if (!cart) return;
|
||||||
|
|
||||||
@ -136,7 +153,7 @@ export default function CartModal({ cart }: { cart: Cart | undefined }) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a href={cart.checkoutUrl} ref={linkRef} className="hidden">
|
<a href={checkoutUrl} ref={linkRef} className="hidden">
|
||||||
Proceed to Checkout
|
Proceed to Checkout
|
||||||
</a>
|
</a>
|
||||||
<button
|
<button
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
import { CloseButton, Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react';
|
import { CloseButton, Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react';
|
||||||
import { ArrowRightIcon } from '@heroicons/react/16/solid';
|
import { ArrowRightIcon } from '@heroicons/react/16/solid';
|
||||||
import { Menu } from 'lib/shopify/types';
|
import { Menu } from 'lib/shopify/types';
|
||||||
import { Fragment } from 'react';
|
import { Fragment, useState } from 'react';
|
||||||
import OpenProfile from './open-profile';
|
import OpenProfile from './open-profile';
|
||||||
import { useFormState, useFormStatus } from 'react-dom';
|
import { useFormState, useFormStatus } from 'react-dom';
|
||||||
import { doLogin } from 'components/auth/actions';
|
import { doLogin } from 'components/auth/actions';
|
||||||
import { Button } from 'components/button';
|
import { Button } from 'components/button';
|
||||||
import useAuth from 'hooks/use-auth';
|
import useAuth from 'hooks/use-auth';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
type ProfilePopoverProps = {
|
type ProfilePopoverProps = {
|
||||||
menu: Menu[];
|
menu: Menu[];
|
||||||
@ -35,8 +36,10 @@ function SubmitButton(props: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
||||||
const [message] = useFormState(doLogin, null);
|
const [message, action] = useFormState(doLogin, null);
|
||||||
const { isAuthenticated, loading } = useAuth();
|
const { isAuthenticated, loading } = useAuth();
|
||||||
|
const [loggingOut, setLoggingOut] = useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover className="relative">
|
<Popover className="relative">
|
||||||
@ -55,7 +58,11 @@ const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
|||||||
<PopoverPanel className="absolute -right-10 z-50 mt-2 w-72 max-w-lg px-4 sm:px-0 lg:right-0">
|
<PopoverPanel className="absolute -right-10 z-50 mt-2 w-72 max-w-lg px-4 sm:px-0 lg:right-0">
|
||||||
<div className="flex flex-col gap-2 overflow-hidden rounded-md bg-white px-4 py-3 text-black shadow-xl ring-1 ring-black/5">
|
<div className="flex flex-col gap-2 overflow-hidden rounded-md bg-white px-4 py-3 text-black shadow-xl ring-1 ring-black/5">
|
||||||
<span className="text-sm font-medium">My Account</span>
|
<span className="text-sm font-medium">My Account</span>
|
||||||
{!isAuthenticated && !loading && <SubmitButton message={message} />}
|
{!isAuthenticated && !loading && (
|
||||||
|
<form action={action}>
|
||||||
|
<SubmitButton message={message} />
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
{menu.length ? (
|
{menu.length ? (
|
||||||
<ul className="flex w-full flex-col divide-y text-sm">
|
<ul className="flex w-full flex-col divide-y text-sm">
|
||||||
{isAuthenticated && (
|
{isAuthenticated && (
|
||||||
@ -82,6 +89,18 @@ const ProfilePopover = ({ menu }: ProfilePopoverProps) => {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
) : null}
|
) : null}
|
||||||
|
{isAuthenticated && !loading && (
|
||||||
|
<Button
|
||||||
|
disabled={loggingOut}
|
||||||
|
onClick={() => {
|
||||||
|
setLoggingOut(true);
|
||||||
|
router.push('/logout');
|
||||||
|
}}
|
||||||
|
variant="outlined"
|
||||||
|
>
|
||||||
|
{loggingOut ? 'Logging Out...' : 'Log Out'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</PopoverPanel>
|
</PopoverPanel>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
@ -493,7 +493,7 @@ export async function logout(request: NextRequest, origin: string) {
|
|||||||
//if there is no idToken, then sending to logout url will redirect shopify, so just
|
//if there is no idToken, then sending to logout url will redirect shopify, so just
|
||||||
//redirect to login here and delete cookies (presumably they don't even exist)
|
//redirect to login here and delete cookies (presumably they don't even exist)
|
||||||
if (!idTokenValue) {
|
if (!idTokenValue) {
|
||||||
const logoutUrl = new URL(`${origin}/login`);
|
const logoutUrl = new URL(`${origin}`);
|
||||||
const response = NextResponse.redirect(`${logoutUrl}`);
|
const response = NextResponse.redirect(`${logoutUrl}`);
|
||||||
return removeAllCookies(response);
|
return removeAllCookies(response);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user