ultisuite-client/components/suite/header-account-actions.tsx
R3D347HR4Y ad1370ea7e
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: enhance configuration and add new demo layouts
- Introduced turbopack alias for canvas in next.config.mjs.
- Updated package.json scripts for development and branding tasks.
- Added new dependencies for Tiptap extensions.
- Implemented new demo layouts for agenda, contacts, drive, and mail applications.
- Enhanced globals.css for improved theming and splash screen animations.
- Added OAuth callback handling for drive mounts.
- Updated layout components to integrate new demo shells and improve structure.
2026-06-12 19:10:24 +02:00

114 lines
3.4 KiB
TypeScript

"use client"
import { useEffect, useRef, useState } from "react"
import Link from "next/link"
import { toast } from "sonner"
import { Icon } from "@iconify/react"
import { HelpCircle } from "lucide-react"
import { AccountAvatar } from "@/components/suite/account-avatar"
import { AccountSwitcherDropdown } from "@/components/suite/account-switcher-dropdown"
import { SuiteFavoritesMenu } from "@/components/suite/suite-favorites-menu"
import { Button } from "@/components/ui/button"
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
import { SUITE_ICON_BTN } from "@/lib/suite/suite-chrome-classes"
import { cn } from "@/lib/utils"
const HEADER_ICON_BTN_CLASS = cn(
"rounded-full",
SUITE_ICON_BTN,
"hover:text-accent-foreground",
)
interface HeaderAccountActionsProps {
className?: string
settingsHref?: string
onSettingsClick?: () => void
}
export function HeaderAccountActions({
className,
settingsHref,
onSettingsClick,
}: HeaderAccountActionsProps) {
const [accountMenuOpen, setAccountMenuOpen] = useState(false)
const accountMenuRef = useRef<HTMLDivElement>(null)
const identity = useChromeIdentity()
useEffect(() => {
const notice = sessionStorage.getItem("ulti_account_notice")
if (notice === "same") {
sessionStorage.removeItem("ulti_account_notice")
toast.message("Vous utilisez déjà ce compte Ulti.")
}
}, [])
return (
<div className={cn("flex shrink-0 items-center gap-1", className)}>
<Button
variant="ghost"
size="icon"
className={cn("hidden sm:inline-flex", HEADER_ICON_BTN_CLASS)}
aria-label="Aide"
>
<HelpCircle className="size-6 shrink-0" aria-hidden />
</Button>
<Button
variant="ghost"
size="icon"
className={HEADER_ICON_BTN_CLASS}
aria-label="Réglages"
{...(settingsHref
? { asChild: true }
: { onClick: onSettingsClick })}
>
{settingsHref ? (
<Link href={settingsHref}>
<Icon icon="mdi:cog-outline" className="size-6 shrink-0" aria-hidden />
</Link>
) : (
<Icon icon="mdi:cog-outline" className="size-6 shrink-0" aria-hidden />
)}
</Button>
<SuiteFavoritesMenu
iconButtonClass={HEADER_ICON_BTN_CLASS}
onOpen={() => setAccountMenuOpen(false)}
/>
<div className="relative ml-2" ref={accountMenuRef}>
<Button
variant="ghost"
size="icon-lg"
className="size-11 overflow-hidden rounded-full p-0"
aria-label={`Compte : ${identity?.email ?? "Utilisateur"}`}
aria-expanded={accountMenuOpen}
aria-haspopup="dialog"
onClick={() => {
setAccountMenuOpen(!accountMenuOpen)
}}
>
{identity ? (
<AccountAvatar
account={{
name: identity.name,
email: identity.email,
avatarUrl: identity.avatarUrl,
}}
size="md"
/>
) : (
<span className="flex size-10 items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground">
?
</span>
)}
</Button>
<AccountSwitcherDropdown
open={accountMenuOpen}
onOpenChange={setAccountMenuOpen}
containerRef={accountMenuRef}
/>
</div>
</div>
)
}