Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- 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.
114 lines
3.4 KiB
TypeScript
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>
|
|
)
|
|
}
|