Skip to content

Commit

Permalink
Merge pull request #777 from trash-lobster/next
Browse files Browse the repository at this point in the history
  • Loading branch information
sphinxrave authored Aug 15, 2024
2 parents a584f06 + d8df1ec commit 3c3ea95
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 56 deletions.
69 changes: 48 additions & 21 deletions packages/react/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-collapsible": "^1.1.0",
"@radix-ui/react-context-menu": "^2.2.1",
Expand Down
36 changes: 1 addition & 35 deletions packages/react/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,8 @@ import { Link } from "react-router-dom";
import { SearchBar } from "./searchbar/components/SearchBar";
import clsx from "clsx";
import { Logo } from "./Logo";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/shadcn/ui/dropdown-menu";
import { useAuth } from "@/hooks/useAuth";
import { userAtom } from "@/store/auth";
import { useState } from "react";
import { UserMenu } from "./userMenu/components/UserMenu";
interface HeaderProps
extends React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
Expand Down Expand Up @@ -100,30 +93,3 @@ export function Header({ id }: HeaderProps) {
</header>
);
}
export function UserMenu() {
const { t } = useTranslation();
const user = useAtomValue(userAtom);
const { logout } = useAuth();

if (!user) {
return (
<Button asChild>
<Link to="/login">{t("component.mainNav.login")}</Link>
</Button>
);
}

return (
<DropdownMenu>
<DropdownMenuTrigger className="mx-2 w-8 shrink-0 overflow-hidden rounded-full">
<img
src={`https://api.dicebear.com/7.x/shapes/svg?seed=${user.id}`}
alt="User avatar"
/>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={() => logout()}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
103 changes: 103 additions & 0 deletions packages/react/src/components/header/userMenu/components/UserMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useAuth } from "@/hooks/useAuth";
import { userAtom } from "@/store/auth";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuSeparator,
} from "@radix-ui/react-dropdown-menu";
import { GearIcon, CalendarIcon, ExitIcon } from "@radix-ui/react-icons";
import { useAtomValue } from "jotai";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { UserMenuItem } from "./UserMenuItem";
import { Button } from "@/shadcn/ui/button";
import { DropdownMenuLabel } from "@/shadcn/ui/dropdown-menu";
import { Avatar, AvatarFallback, AvatarImage } from "@/shadcn/ui/avatar";

export function UserMenu() {
const { t } = useTranslation();
const user = useAtomValue(userAtom);
const { logout } = useAuth();

const mockUserMenuItems = [
{
key: "settings",
value: "Settings",
fn: () => console.log("settings"),
icon: <GearIcon />,
},
{
key: "iCalFeed",
value: "ICal Feed",
fn: () => console.log("iCalFeed"),
icon: <CalendarIcon />,
},
{ key: "logout", value: "Logout", fn: logout, icon: <ExitIcon /> },
];

if (!user) {
return (
<Button asChild>
<Link to="/login">{t("component.mainNav.login")}</Link>
</Button>
);
}

return (
<DropdownMenu>
<DropdownMenuTrigger className="z-30 mx-2 w-8 shrink-0 overflow-hidden rounded-full bg-base-2">
<img
src={`https://api.dicebear.com/7.x/shapes/svg?seed=${user.id}`}
alt="User avatar"
/>
</DropdownMenuTrigger>
<DropdownMenuContent className="relative right-8 z-30 bg-base-2">
{/* user profile */}
<div className="grid grid-cols-4 grid-rows-3 p-4">
<Avatar className="col-start-1 row-span-3 row-start-1 self-center justify-self-center">
<AvatarImage
src={`https://api.dicebear.com/7.x/shapes/svg?seed=${user.id}`}
alt="userIcon"
/>
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<div className="col-span-3 col-start-2 row-span-2 row-start-1">
<DropdownMenuLabel>{user.username}</DropdownMenuLabel>
<div className="flex flex-row gap-2 px-2 py-1.5 ">
<div
className={user.google_id ? "text-secondary-11" : "text-base"}
>
<div className="i-mdi:google p-1 text-xs" />
</div>
<div
className={user.discord_id ? "text-secondary-11" : "text-base"}
>
<div className="i-mdi:discord p-1 text-xs" />
</div>
<div
className={user.twitter_id ? "text-secondary-11" : "text-base"}
>
<div className="i-mdi:twitter p-1 text-xs" />
</div>
</div>
</div>
<DropdownMenuLabel className="col-span-3 col-start-2 row-start-3 capitalize text-base-11">
{user.role} : {user.contribution_count}
{t("component.mainNav.points")}
</DropdownMenuLabel>
</div>
<DropdownMenuSeparator className="border-base" />
{mockUserMenuItems.map((item) => {
return (
<UserMenuItem
key={item.key + item.value}
item={{ key: item.key, value: item.value, icon: item.icon }}
onClick={item.fn}
/>
);
})}
</DropdownMenuContent>
</DropdownMenu>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import { DropdownMenuItem } from "@/shadcn/ui/dropdown-menu";
// import { useTranslation } from "react-i18next";
import { MenuItem } from "../types";

interface UserMenuItemProps {
item: MenuItem;
onClick: () => void;
}

export function UserMenuItem({ item, onClick }: UserMenuItemProps) {
return (
<DropdownMenuItem
onClick={() => onClick()}
className="grid h-full w-full cursor-pointer grid-cols-4 p-4"
>
<div className="col-start-1 self-center justify-self-center">
{item.icon}
</div>
<div className="col-span-3 col-start-2 px-2">{item.value}</div>
</DropdownMenuItem>
);
}
5 changes: 5 additions & 0 deletions packages/react/src/components/header/userMenu/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type MenuItem = {
key: string;
value: string;
icon: React.JSX.Element;
};
48 changes: 48 additions & 0 deletions packages/react/src/shadcn/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"

import { cn } from "@/lib/utils"

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className
)}
{...props}
/>
))
Avatar.displayName = AvatarPrimitive.Root.displayName

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className
)}
{...props}
/>
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName

export { Avatar, AvatarImage, AvatarFallback }

0 comments on commit 3c3ea95

Please sign in to comment.