Improve Navigation + ThemeSwitcher

This commit is contained in:
Arthur Belleville 2025-04-06 21:36:55 +02:00
parent daece4521b
commit 9235117aee
No known key found for this signature in database
2 changed files with 29 additions and 23 deletions

View file

@ -5,7 +5,6 @@ import {
HelpCircleIcon,
SendIcon,
ChevronRightIcon,
Settings,
ConstructionIcon,
PlusIcon,
MinusIcon,
@ -40,6 +39,7 @@ import {
import { useState, useRef } from "react";
import logo from "../assets/icon.jpg";
import { ThemeSwitcher } from "./ThemeSwitcher";
import { useSession } from "../contexts/SessionContext";
type NavLinkItem = {
isActive?: boolean;
@ -97,37 +97,39 @@ function NavLink(props: NavLinkProps) {
);
}
export function ControlledOpenState({ isCollapsed }: { isCollapsed: boolean }) {
const [isOpen, setIsOpen] = useState(false);
export function UserMenuPopover({ isCollapsed }: { isCollapsed: boolean }) {
const { session } = useSession();
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const ref = useRef(null);
return (
<>
<Button
aria-label="Settings"
onPress={() => setIsOpen(true)}
aria-label="User menu"
variant="plain"
onPress={() => setIsPopoverOpen(!isPopoverOpen)}
ref={ref}
className={twMerge(
"flex items-center gap-2",
isCollapsed && "justify-center"
)}
isIconOnly={isCollapsed}
className={twMerge("flex items-center w-90 justify-start")}
>
<Icon>
<Settings />
</Icon>
<Avatar
className="rounded-full"
src={session?.user?.user_metadata?.avatar_url}
alt="Avatar"
/>
<span
className={twMerge(
"transition-all duration-300",
isCollapsed ? "opacity-0 w-0" : "opacity-100"
)}
>
Settings
{session?.user?.user_metadata?.first_name}
</span>
</Button>
<Popover
className="min-w-56 rounded-xl"
isOpen={isOpen}
onOpenChange={setIsOpen}
isOpen={isPopoverOpen}
onOpenChange={setIsPopoverOpen}
triggerRef={ref}
>
<Dialog aria-label="Settings">
@ -209,14 +211,14 @@ export const SideNavigation = ({
}) => {
const isCollapsable = !isMobileMenuOpen;
const [isCollapsed, setIsCollapsed] = useState(isCollapsable ? true : false);
const [isCollapsed, setIsCollapsed] = useState(isCollapsable ? false : true);
return (
<div
className={twMerge(
"group isolate flex flex-col overflow-y-auto bg-gray-200 dark:bg-gray-900 transition-all duration-300",
"fixed md:relative h-screen z-50",
isCollapsed ? "w-14" : "w-52",
isCollapsed ? "w-20" : "w-52",
"md:flex",
"transform md:transform-none",
isMobileMenuOpen
@ -267,9 +269,9 @@ export const SideNavigation = ({
)}
</div>
<MainNavigation isCollapsed={isCollapsed} />
<ThemeSwitcher />
<div className="bg-gray-200 dark:bg-gray-900 sticky bottom-0 left-0 flex px-2 py-3">
<ControlledOpenState isCollapsed={isCollapsed} />
{!isCollapsed ? <ThemeSwitcher /> : null}
<div className="bg-gray-200 dark:bg-gray-900 sticky bottom-0 left-0 flex mx-3 py-2">
<UserMenuPopover isCollapsed={isCollapsed} />
</div>
</div>
);
@ -327,7 +329,7 @@ export function MainNavigation({ isCollapsed }: { isCollapsed: boolean }) {
</li>
))}
</ul>
<ul className="mt-auto grid gap-y-0.5 px-2 py-3">
<ul className="mt-auto grid gap-y-0.5 px-2 py-2">
<li>
<NavLink>
<RouterLink to="/">

View file

@ -10,7 +10,7 @@ export function ThemeSwitcher() {
isSelected={theme === "dark"}
onChange={() => setTheme(theme === "dark" ? "light" : "dark")}
className={twMerge(
"p-2 rounded-full",
"py-2 px-2 mx-4 rounded-full",
"bg-slate-100 dark:bg-slate-800",
"border border-slate-200 dark:border-slate-700",
"hover:bg-slate-200 dark:hover:bg-slate-700",
@ -47,7 +47,11 @@ export function ThemeSwitcher() {
/>
</svg>
)}
<span className="text-sm text-slate-600 dark:text-slate-400">
<span
className={twMerge(
"hidden sm:inline text-sm text-slate-600 dark:text-slate-400"
)}
>
{theme === "dark"
? "Mode sombre"
: theme === "light"