Skip to content

Commit

Permalink
add user menu to the navbar (#1014)
Browse files Browse the repository at this point in the history
Co-authored-by: Michał Miszczyszyn <[email protected]>
  • Loading branch information
grzegorzpokorski and typeofweb authored Nov 13, 2023
1 parent 834feee commit 1d13c57
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 104 deletions.
31 changes: 7 additions & 24 deletions src/app/(main)/login/LoginComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
"use client";

import { useQuery } from "urql";
import { useSaleorAuthContext } from "@saleor/auth-sdk/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { CurrentUserDocument, type CurrentUserQuery } from "@/gql/graphql";
import { LoginForm } from "@/ui/components/LoginForm";
import { UserCard } from "@/ui/components/UserCard";

export const LoginComponent = () => {
const { signOut } = useSaleorAuthContext();

const router = useRouter();
const [{ data }] = useQuery<CurrentUserQuery>({
query: CurrentUserDocument.toString(),
});

return data?.me ? (
<>
<UserCard user={data.me} />
<div className="mt-4 flex space-x-2">
<Link href="/orders" className="h-full rounded bg-neutral-100 px-4 py-2 hover:bg-neutral-200">
My orders
</Link>
<button
onClick={() => signOut()}
className="rounded bg-neutral-800 px-4 py-2 text-neutral-200 hover:bg-neutral-700"
type="button"
>
Log Out
</button>
</div>
</>
) : (
<LoginForm />
);
if (data?.me) {
router.push("/");
}

return <LoginForm />;
};
9 changes: 1 addition & 8 deletions src/graphql/CurrentUser.graphql
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
query CurrentUser {
me {
id
email
firstName
lastName
avatar {
url
alt
}
...UserDetails
}
}
9 changes: 1 addition & 8 deletions src/graphql/CurrentUserOrderList.graphql
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
query CurrentUserOrderList {
me {
id
email
firstName
lastName
avatar {
url
alt
}
...UserDetails
orders(first: 10) {
edges {
node {
Expand Down
10 changes: 10 additions & 0 deletions src/graphql/UserDetailsFragment.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fragment UserDetails on User {
id
email
firstName
lastName
avatar {
url
alt
}
}
7 changes: 6 additions & 1 deletion src/ui/components/OrderList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"use client";
import { useQuery } from "urql";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { CurrentUserOrderListDocument, type CurrentUserOrderListQuery } from "@/gql/graphql";
import { formatMoney } from "@/lib/graphql";
import { formatDate } from "@/lib/date";

export function OrderList() {
const router = useRouter();
const [{ data, fetching }] = useQuery<CurrentUserOrderListQuery>({
query: CurrentUserOrderListDocument.toString(),
});
Expand All @@ -18,14 +20,17 @@ export function OrderList() {
const email = user?.email;

if (!email) {
router.push("/");
return <div>User does not have email</div>;
}

const orders = user.orders?.edges || [];

return (
<div className="mx-auto max-w-7xl p-8">
<h1 className="text-2xl font-bold tracking-tight text-neutral-900">{user.firstName}&rsquo;s Orders</h1>
<h1 className="text-2xl font-bold tracking-tight text-neutral-900">
{user.firstName ? user.firstName : user.email}&rsquo;s orders
</h1>

{orders.length === 0 ? (
<div className="mt-8">
Expand Down
22 changes: 0 additions & 22 deletions src/ui/components/UserCard.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/ui/components/nav/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Suspense } from "react";
import { AccountLink } from "./components/AccountLink";
import { UserMenu } from "./components/UserMenu/UserMenu";
import { CartNavItem } from "./components/CartNavItem";
import { NavLinks } from "./components/NavLinks";
import { MobileMenu } from "./components/MobileMenu";
Expand All @@ -12,7 +12,7 @@ export const Nav = () => {
</ul>
<div className="ml-auto flex items-center justify-center whitespace-nowrap">
<Suspense fallback={<div className="w-6" />}>
<AccountLink />
<UserMenu />
</Suspense>
</div>
<div className="flex items-center">
Expand Down
39 changes: 0 additions & 39 deletions src/ui/components/nav/components/AccountLink.tsx

This file was deleted.

81 changes: 81 additions & 0 deletions src/ui/components/nav/components/UserMenu/UserMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client";

import { Fragment } from "react";
import Link from "next/link";
import clsx from "clsx";
import { useQuery } from "urql";
import { UserIcon } from "lucide-react";
import { Menu, Transition } from "@headlessui/react";
import { useSaleorAuthContext } from "@saleor/auth-sdk/react";
import { UserAvatar } from "./components/UserAvatar";
import { UserInfo } from "./components/UserInfo";
import { CurrentUserDocument, type CurrentUserQuery } from "@/gql/graphql";

export function UserMenu() {
const { signOut } = useSaleorAuthContext();
const [{ data }] = useQuery<CurrentUserQuery>({
query: CurrentUserDocument.toString(),
});

if (data?.me) {
return (
<Menu as="div" className="relative ml-3">
<Menu.Button className="relative flex rounded-full bg-neutral-200 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-neutral-800">
<span className="sr-only">Open user menu</span>
<UserAvatar user={data.me} />
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right divide-y divide-neutral-200 bg-white py-1 text-start shadow ring-1 ring-neutral-200 ring-opacity-5 focus:outline-none">
<UserInfo user={data.me} />
<div className="flex flex-col px-1 py-1">
<Menu.Item>
{({ active }) => (
<Link
href="/orders"
className={clsx(
active && "bg-neutral-100",
"block px-4 py-2 text-sm text-sm font-medium text-neutral-500 hover:text-neutral-700",
)}
>
My orders
</Link>
)}
</Menu.Item>
</div>
<div className="flex flex-col px-1 py-1">
<Menu.Item>
{({ active }) => (
<button
type="button"
onClick={() => signOut()}
className={clsx(
active && "bg-neutral-100",
"block px-4 py-2 text-start text-sm text-sm font-medium text-neutral-500 hover:text-neutral-700",
)}
>
Log Out
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</Menu>
);
} else {
return (
<Link href="/login" className="h-6 w-6 flex-shrink-0">
<UserIcon className="h-6 w-6 shrink-0" aria-hidden="true" />
<span className="sr-only">Log in</span>
</Link>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Image from "next/image";
import { type UserDetailsFragment } from "@/gql/graphql";

type Props = {
user: UserDetailsFragment;
};

export const UserAvatar = ({ user }: Props) => {
const label =
user.firstName && user.lastName
? `${user.firstName.slice(0, 1)}${user.lastName.slice(0, 1)}`
: user.email.slice(0, 2);

if (user.avatar) {
return (
<Image
className="h-8 w-8 rounded-full border"
aria-hidden="true"
src={user.avatar.url}
width={24}
height={24}
alt=""
/>
);
}

return (
<span
className="flex h-8 w-8 items-center justify-center rounded-full border bg-white text-center text-xs font-bold uppercase"
aria-hidden="true"
>
{label}
</span>
);
};
16 changes: 16 additions & 0 deletions src/ui/components/nav/components/UserMenu/components/UserInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { type UserDetailsFragment } from "@/gql/graphql";

type Props = {
user: UserDetailsFragment;
};

export const UserInfo = ({ user }: Props) => {
const userName = user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : null;

return (
<p className="truncate px-5 py-2 text-xs text-neutral-700">
{userName && <span className="mb-0.5 block truncate font-bold">{userName}</span>}
{user.email}
</p>
);
};

0 comments on commit 1d13c57

Please sign in to comment.