304 lines
10 KiB
TypeScript
304 lines
10 KiB
TypeScript
"use client"
|
||
|
||
import { ChevronDown, Plus, Bot } from "lucide-react"
|
||
import { cn } from "@/lib/utils"
|
||
import { Icon } from "@iconify/react"
|
||
import { FOLDER_SECTION_ICON } from "@/lib/folder-nav-icons"
|
||
import {
|
||
CATEGORY_IDS_IN_PLUS_ONLY,
|
||
MAIL_SIDEBAR_DOSSIERS_SECTION_STICKY_Z,
|
||
hasPlusOnlyExtras,
|
||
sidebarSecondaryActions,
|
||
} from "@/components/gmail/sidebar/sidebar-nav-constants"
|
||
import { navRowRoundedWhenActive } from "@/components/gmail/sidebar/sidebar-nav-primitives"
|
||
import { CategoryNavRow } from "@/components/gmail/sidebar/category-nav-row"
|
||
import { SidebarNavItem } from "@/components/gmail/sidebar/sidebar-nav-item"
|
||
import { SidebarLabelItemRow } from "@/components/gmail/sidebar/sidebar-label-item-row"
|
||
import {
|
||
renderCollapsedFolderList,
|
||
renderExpandedFolderSubtree,
|
||
} from "@/components/gmail/sidebar/sidebar-folder-tree"
|
||
import { MAIL_SIDEBAR_BLUR_SURFACE_CLASS } from "@/lib/mail-chrome-classes"
|
||
import type { useSidebarState } from "@/components/gmail/sidebar/use-sidebar-state"
|
||
|
||
type SidebarState = ReturnType<typeof useSidebarState>
|
||
|
||
export function SidebarNavPanel({
|
||
selectedFolder,
|
||
onSelectFolder,
|
||
folderUnreadCounts,
|
||
splitView = false,
|
||
state,
|
||
}: {
|
||
selectedFolder: string
|
||
onSelectFolder: (folder: string) => void
|
||
folderUnreadCounts: Record<string, number>
|
||
splitView?: boolean
|
||
state: SidebarState
|
||
}) {
|
||
const {
|
||
isExpanded,
|
||
navRailInset,
|
||
touchNav,
|
||
visibleMainItems,
|
||
primaryVisibleCategories,
|
||
plusOnlyVisibleCategories,
|
||
disabledSystemNavItems,
|
||
navMoreOpen,
|
||
setNavMoreOpen,
|
||
setLabelRowEnabled,
|
||
folderTree,
|
||
folderRowProps,
|
||
collapsedFolderOpts,
|
||
visibleNavLabelRows,
|
||
labelRowProps,
|
||
setNewFolderParent,
|
||
setNewFolderName,
|
||
setFolderDialogOpen,
|
||
setNewLabelName,
|
||
setLabelDialogOpen,
|
||
} = state
|
||
|
||
return (
|
||
<div
|
||
className={cn(
|
||
"min-h-0 flex-1 overflow-y-auto overflow-x-hidden",
|
||
"[scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
|
||
)}
|
||
>
|
||
<nav
|
||
className={cn(
|
||
"flex min-h-full flex-col",
|
||
navRailInset,
|
||
!splitView && "sm:pt-3"
|
||
)}
|
||
>
|
||
{visibleMainItems.map((item) => (
|
||
<SidebarNavItem
|
||
key={item.id}
|
||
item={item}
|
||
isSelected={selectedFolder === item.id}
|
||
unreadCount={folderUnreadCounts[item.id] ?? 0}
|
||
isExpanded={isExpanded}
|
||
onSelectFolder={onSelectFolder}
|
||
/>
|
||
))}
|
||
{primaryVisibleCategories.map((item) => (
|
||
<CategoryNavRow
|
||
key={item.id}
|
||
item={item}
|
||
isSelected={selectedFolder === item.id}
|
||
isExpanded={isExpanded}
|
||
unreadCount={folderUnreadCounts[item.id] ?? 0}
|
||
onSelectFolder={onSelectFolder}
|
||
touchNav={touchNav}
|
||
onDisableNavLabel={(id) => setLabelRowEnabled(id, false)}
|
||
onEnableNavLabel={(id) => setLabelRowEnabled(id, true)}
|
||
/>
|
||
))}
|
||
|
||
{hasPlusOnlyExtras && (
|
||
<button
|
||
type="button"
|
||
title={!isExpanded ? (navMoreOpen ? "Moins" : "Plus") : undefined}
|
||
aria-expanded={navMoreOpen}
|
||
aria-label={
|
||
!isExpanded
|
||
? navMoreOpen
|
||
? "Moins d’entrées"
|
||
: "Plus d’entrées"
|
||
: undefined
|
||
}
|
||
onClick={() =>
|
||
setNavMoreOpen((wasOpen) => {
|
||
if (!wasOpen) return true
|
||
if (CATEGORY_IDS_IN_PLUS_ONLY.has(selectedFolder)) {
|
||
onSelectFolder("inbox")
|
||
return false
|
||
}
|
||
return false
|
||
})
|
||
}
|
||
className={cn(
|
||
"flex h-8 w-full shrink-0 cursor-pointer items-center gap-4 pl-6 pr-3 text-gray-700 transition-colors hover:bg-mail-nav-hover",
|
||
navRowRoundedWhenActive(false)
|
||
)}
|
||
>
|
||
<ChevronDown
|
||
className={cn(
|
||
"h-5 w-5 shrink-0 transition-transform duration-200",
|
||
navMoreOpen && "rotate-180"
|
||
)}
|
||
/>
|
||
{isExpanded && (
|
||
<span className="text-sm">{navMoreOpen ? "Moins" : "Plus"}</span>
|
||
)}
|
||
</button>
|
||
)}
|
||
|
||
{navMoreOpen && (
|
||
<>
|
||
{plusOnlyVisibleCategories.map((item) => (
|
||
<CategoryNavRow
|
||
key={item.id}
|
||
item={item}
|
||
isSelected={selectedFolder === item.id}
|
||
isExpanded={isExpanded}
|
||
unreadCount={folderUnreadCounts[item.id] ?? 0}
|
||
onSelectFolder={onSelectFolder}
|
||
touchNav={touchNav}
|
||
onDisableNavLabel={(id) => setLabelRowEnabled(id, false)}
|
||
onEnableNavLabel={(id) => setLabelRowEnabled(id, true)}
|
||
/>
|
||
))}
|
||
{isExpanded && (
|
||
<div className="mt-1 flex flex-col gap-px">
|
||
{sidebarSecondaryActions.map((a) => {
|
||
const ActionIcon = a.icon
|
||
return (
|
||
<button
|
||
key={a.id}
|
||
type="button"
|
||
className="flex min-h-8 w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pl-6 pr-3 text-left text-xs text-gray-600 transition-colors hover:bg-gray-50 hover:text-gray-800"
|
||
>
|
||
<ActionIcon className="h-3.5 w-3.5 shrink-0 opacity-70" aria-hidden />
|
||
<span className="min-w-0 leading-snug">{a.label}</span>
|
||
</button>
|
||
)
|
||
})}
|
||
</div>
|
||
)}
|
||
{isExpanded && disabledSystemNavItems.length > 0 && (
|
||
<div className="mt-2 pt-2">
|
||
<div className="mb-1 pl-6 pr-3 text-[11px] font-medium uppercase tracking-wide text-gray-500">
|
||
Désactivées
|
||
</div>
|
||
{disabledSystemNavItems.map((item) => (
|
||
<CategoryNavRow
|
||
key={item.id}
|
||
item={item}
|
||
isSelected={false}
|
||
isExpanded={isExpanded}
|
||
unreadCount={folderUnreadCounts[item.id] ?? 0}
|
||
onSelectFolder={onSelectFolder}
|
||
touchNav={touchNav}
|
||
onDisableNavLabel={(id) => setLabelRowEnabled(id, false)}
|
||
onEnableNavLabel={(id) => setLabelRowEnabled(id, true)}
|
||
variant="hidden"
|
||
/>
|
||
))}
|
||
</div>
|
||
)}
|
||
</>
|
||
)}
|
||
|
||
<div className="mt-3 pt-1">
|
||
<div
|
||
className={cn(
|
||
"sticky top-0 flex h-8 w-full min-w-0 shrink-0 items-center gap-2 pl-6 pr-3",
|
||
MAIL_SIDEBAR_BLUR_SURFACE_CLASS
|
||
)}
|
||
style={{ zIndex: MAIL_SIDEBAR_DOSSIERS_SECTION_STICKY_Z }}
|
||
title={!isExpanded ? "Dossiers" : undefined}
|
||
>
|
||
<Icon
|
||
icon={FOLDER_SECTION_ICON}
|
||
className="h-5 w-5 shrink-0 text-gray-600"
|
||
aria-hidden
|
||
/>
|
||
{isExpanded && (
|
||
<span className="min-w-0 flex-1 truncate text-left text-sm font-medium text-gray-700">
|
||
Dossiers
|
||
</span>
|
||
)}
|
||
{isExpanded && (
|
||
<button
|
||
type="button"
|
||
className="flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded-full text-gray-500 hover:bg-mail-nav-hover hover:text-gray-700"
|
||
aria-label="Ajouter un dossier"
|
||
title="Ajouter un dossier"
|
||
onClick={() => {
|
||
setNewFolderParent("__root__")
|
||
setNewFolderName("")
|
||
setFolderDialogOpen(true)
|
||
}}
|
||
>
|
||
<Plus className="h-5 w-5 shrink-0" />
|
||
</button>
|
||
)}
|
||
</div>
|
||
|
||
{isExpanded
|
||
? renderExpandedFolderSubtree(folderTree, 0, folderRowProps)
|
||
: renderCollapsedFolderList(folderTree, collapsedFolderOpts)}
|
||
</div>
|
||
|
||
<div className="mt-3 pt-1">
|
||
<div
|
||
className={cn(
|
||
"sticky top-0 z-30 flex h-8 w-full min-w-0 shrink-0 items-center gap-2 pl-6 pr-3",
|
||
MAIL_SIDEBAR_BLUR_SURFACE_CLASS
|
||
)}
|
||
title={!isExpanded ? "Libellés" : undefined}
|
||
>
|
||
<Icon
|
||
icon="mdi:label-outline"
|
||
className="h-5 w-5 shrink-0 text-gray-600"
|
||
aria-hidden
|
||
/>
|
||
{isExpanded && (
|
||
<span className="min-w-0 flex-1 truncate text-left text-sm font-medium text-gray-700">
|
||
Libellés
|
||
</span>
|
||
)}
|
||
{isExpanded && (
|
||
<button
|
||
type="button"
|
||
className="flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded-full text-gray-500 hover:bg-mail-nav-hover hover:text-gray-700"
|
||
aria-label="Ajouter un libellé"
|
||
title="Ajouter un libellé"
|
||
onClick={() => {
|
||
setNewLabelName("")
|
||
setLabelDialogOpen(true)
|
||
}}
|
||
>
|
||
<Plus className="h-5 w-5 shrink-0" />
|
||
</button>
|
||
)}
|
||
</div>
|
||
|
||
{visibleNavLabelRows.map((item) => (
|
||
<SidebarLabelItemRow
|
||
key={item.id}
|
||
item={item}
|
||
unreadCount={folderUnreadCounts[item.id] ?? 0}
|
||
isExpanded={isExpanded}
|
||
{...labelRowProps}
|
||
/>
|
||
))}
|
||
</div>
|
||
|
||
<div
|
||
className={cn(
|
||
"relative z-[41] mt-auto pt-2",
|
||
MAIL_SIDEBAR_BLUR_SURFACE_CLASS,
|
||
"max-sm:pb-16 sm:-mr-3.5 sm:w-[calc(100%+0.875rem)] sm:sticky sm:bottom-0 sm:border-t sm:border-gray-200 sm:pb-3"
|
||
)}
|
||
>
|
||
<button
|
||
type="button"
|
||
title={!isExpanded ? "Sortbot" : undefined}
|
||
className={cn(
|
||
"flex h-8 w-full shrink-0 cursor-pointer items-center gap-4 pl-6 pr-3 text-sm text-gray-700 transition-colors hover:bg-mail-nav-hover",
|
||
navRowRoundedWhenActive(false)
|
||
)}
|
||
>
|
||
<Bot className="h-5 w-5 shrink-0 text-gray-600" aria-hidden />
|
||
{isExpanded && <span>Sortbot</span>}
|
||
</button>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
)
|
||
}
|