feat: refactor mail and account settings structure for improved navigation and layout
- Updated routing for mail settings to redirect to the new settings layout. - Introduced new account layout and section components for better organization. - Replaced hardcoded paths with constants for account and mail settings to enhance maintainability. - Removed deprecated mail settings layout and integrated it into the new settings structure. - Enhanced user experience by streamlining navigation between account and mail settings.
This commit is contained in:
parent
2a0958b70d
commit
b95948f980
@ -1,6 +1,6 @@
|
||||
import { CompteSettingsSectionFromSegments } from "@/components/compte/compte-settings-section-view"
|
||||
|
||||
export default async function CompteSectionPage({
|
||||
export default async function AccountSectionPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ section?: string[] }>
|
||||
@ -7,7 +7,7 @@ export const metadata: Metadata = suitePageMetadata({
|
||||
app: "compte",
|
||||
})
|
||||
|
||||
export default function CompteRootLayout({
|
||||
export default function AccountRootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
@ -7,7 +7,6 @@ import {
|
||||
useLayoutEffect,
|
||||
useState,
|
||||
} from "react"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { useIsXs } from "@/hooks/use-xs"
|
||||
import { readTouchNavMatches, useTouchNav } from "@/hooks/use-touch-nav"
|
||||
import { useMailSplitView } from "@/hooks/use-mail-split-view"
|
||||
@ -44,16 +43,9 @@ import { ComposeIdentitiesSync } from "@/components/gmail/compose-identities-syn
|
||||
import { MailSignaturesSync } from "@/components/gmail/mail-signatures-sync"
|
||||
import { MailNotificationsBridge } from "@/components/gmail/mail-notifications-bridge"
|
||||
import { useWebSocket } from "@/lib/api/ws"
|
||||
import { useMailSettingsStore } from "@/lib/stores/mail-settings-store"
|
||||
import { FilePreviewDialog } from "@/components/drive/file-preview-dialog"
|
||||
import { AiChatPanel } from "@/components/ai/ai-chat-panel"
|
||||
|
||||
const MAIL_SETTINGS_PATH = "/mail/settings"
|
||||
|
||||
function isMailSettingsPath(pathname: string | null): boolean {
|
||||
return pathname === MAIL_SETTINGS_PATH || pathname?.startsWith(`${MAIL_SETTINGS_PATH}/`) === true
|
||||
}
|
||||
|
||||
function MailAppInner() {
|
||||
const { route, navigateRoute, searchParams: currentSearchParams } =
|
||||
useMailRoute()
|
||||
@ -224,20 +216,12 @@ function MailAppInner() {
|
||||
}
|
||||
|
||||
export function MailAppShell({
|
||||
children: routeOutlet,
|
||||
children: _routeOutlet,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const pathname = usePathname()
|
||||
const showSettingsPage = isMailSettingsPath(pathname)
|
||||
useWebSocket()
|
||||
|
||||
useEffect(() => {
|
||||
if (showSettingsPage) {
|
||||
useMailSettingsStore.getState().setQuickSettingsOpen(false)
|
||||
}
|
||||
}, [showSettingsPage])
|
||||
|
||||
useEffect(() => {
|
||||
const blockPinch = (event: Event) => event.preventDefault()
|
||||
document.addEventListener("gesturestart", blockPinch, { passive: false })
|
||||
@ -263,11 +247,7 @@ export function MailAppShell({
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{showSettingsPage ? (
|
||||
<SidebarNavProvider>{routeOutlet}</SidebarNavProvider>
|
||||
) : (
|
||||
<MailAppInner />
|
||||
)}
|
||||
<MailAppInner />
|
||||
</Suspense>
|
||||
<MailThemeApplier />
|
||||
<MailSettingsSync />
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
import { MailSettingsLayout } from "@/components/gmail/settings/mail-settings-layout"
|
||||
import type { Metadata } from "next"
|
||||
import { suitePageMetadata } from "@/lib/suite/page-metadata"
|
||||
|
||||
export const metadata: Metadata = suitePageMetadata({
|
||||
app: "mail",
|
||||
title: "Réglages",
|
||||
})
|
||||
|
||||
export default function MailSettingsRootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return <MailSettingsLayout>{children}</MailSettingsLayout>
|
||||
}
|
||||
@ -1,14 +1,15 @@
|
||||
import { redirect } from "next/navigation"
|
||||
import { MailSettingsSectionFromSegments } from "@/components/gmail/settings/mail-settings-section-view"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
export default async function MailSettingsSectionPage({
|
||||
export default async function SettingsSectionPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ section?: string[] }>
|
||||
}) {
|
||||
const { section } = await params
|
||||
if (section?.[0] === "signatures") {
|
||||
redirect("/mail/settings/accounts")
|
||||
redirect(`${MAIL_SETTINGS_BASE_PATH}/accounts`)
|
||||
}
|
||||
return <MailSettingsSectionFromSegments segments={section} />
|
||||
}
|
||||
24
app/settings/layout.tsx
Normal file
24
app/settings/layout.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import { MailSettingsLayout } from "@/components/gmail/settings/mail-settings-layout"
|
||||
import { SettingsAppShell } from "@/components/gmail/settings/settings-app-shell"
|
||||
import { SuiteThemeShell } from "@/components/suite/suite-theme-shell"
|
||||
import type { Metadata } from "next"
|
||||
import { suitePageMetadata } from "@/lib/suite/page-metadata"
|
||||
|
||||
export const metadata: Metadata = suitePageMetadata({
|
||||
app: "mail",
|
||||
title: "Réglages",
|
||||
})
|
||||
|
||||
export default function SettingsRootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<SuiteThemeShell>
|
||||
<SettingsAppShell>
|
||||
<MailSettingsLayout>{children}</MailSettingsLayout>
|
||||
</SettingsAppShell>
|
||||
</SuiteThemeShell>
|
||||
)
|
||||
}
|
||||
@ -6,6 +6,7 @@ import {
|
||||
toggleUltiAiToolGroup,
|
||||
ULTIAI_TOOL_GROUPS,
|
||||
} from "@/lib/ai/ultiai-tool-groups"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
type UltiAiToolsCardProps = {
|
||||
enabledTools: string[]
|
||||
@ -16,7 +17,7 @@ type UltiAiToolsCardProps = {
|
||||
export function UltiAiToolsCard({
|
||||
enabledTools,
|
||||
onChange,
|
||||
webSearchSettingsHref = "/mail/settings/automation",
|
||||
webSearchSettingsHref = `${MAIL_SETTINGS_BASE_PATH}/automation`,
|
||||
}: UltiAiToolsCardProps) {
|
||||
return (
|
||||
<SettingsCard
|
||||
|
||||
@ -31,6 +31,7 @@ import { useMergedAgendaCalendars } from "@/lib/agenda/use-visible-agenda-calend
|
||||
import { useLabels } from "@/lib/api/hooks/use-folder-label-queries"
|
||||
import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries"
|
||||
import { MAIL_SETTINGS_PAGE_MASONRY_SECTION_CLASS } from "@/lib/mail-chrome-classes"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function CalendarCheckboxRow({
|
||||
@ -405,7 +406,7 @@ export function AgendaCalendarsSettingsFields({
|
||||
{accounts.length === 0 ? (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Aucun compte mail connecté.{" "}
|
||||
<a href="/mail/settings/accounts" className="text-[#1a73e8] hover:underline">
|
||||
<a href={`${MAIL_SETTINGS_BASE_PATH}/accounts`} className="text-[#1a73e8] hover:underline">
|
||||
Ajouter un compte
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -8,6 +8,7 @@ import { AgendaSettingsFields } from "@/components/agenda/agenda-settings-fields
|
||||
import { ThemeSettingsDialog } from "@/components/gmail/quick-settings/theme-settings-dialog"
|
||||
import { useAgendaSettingsStore } from "@/lib/agenda/agenda-store"
|
||||
import { useMailSettingsStore } from "@/lib/stores/mail-settings-store"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function AgendaQuickSettingsPanel() {
|
||||
@ -55,7 +56,7 @@ export function AgendaQuickSettingsPanel() {
|
||||
className="h-10 w-full rounded-full border-[#1a73e8] text-[#1a73e8] hover:bg-[#e8f0fe]/50 dark:border-[#9aa0a6] dark:text-white dark:hover:bg-[#3c4043]/50"
|
||||
asChild
|
||||
>
|
||||
<Link href="/mail/settings/agenda" onClick={() => setOpen(false)}>
|
||||
<Link href={`${MAIL_SETTINGS_BASE_PATH}/agenda`} onClick={() => setOpen(false)}>
|
||||
Voir tous les paramètres
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
formatAiCostEUR,
|
||||
type AiQuota,
|
||||
} from "@/lib/api/hooks/use-ai-queries"
|
||||
import { ACCOUNT_SETTINGS_BASE_PATH } from "@/lib/compte-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function AiSpendBar({
|
||||
@ -73,7 +74,7 @@ export function AiSpendBar({
|
||||
) : null}
|
||||
{!compact ? (
|
||||
<Link
|
||||
href="/compte/usage-ia"
|
||||
href={`${ACCOUNT_SETTINGS_BASE_PATH}/usage-ia`}
|
||||
className="text-[10px] text-muted-foreground underline-offset-2 hover:underline"
|
||||
>
|
||||
Détail de consommation
|
||||
|
||||
@ -11,7 +11,9 @@ import {
|
||||
} from "@/lib/suite/suite-chrome-classes"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const COMPTE_HREF = "/compte"
|
||||
import { ACCOUNT_SETTINGS_BASE_PATH } from "@/lib/compte-settings/settings-nav"
|
||||
|
||||
const ACCOUNT_HREF = ACCOUNT_SETTINGS_BASE_PATH
|
||||
|
||||
export function CompteSettingsHeader() {
|
||||
return (
|
||||
@ -20,7 +22,7 @@ export function CompteSettingsHeader() {
|
||||
className="flex h-16 w-full shrink-0 items-center gap-0 bg-app-canvas pr-4 sm:gap-2"
|
||||
>
|
||||
<div className="hidden h-full w-64 shrink-0 items-center gap-2 pl-4 md:flex lg:w-72">
|
||||
<Link href={COMPTE_HREF} className={cn("inline-flex", SUITE_APP_LOGO_LOCKUP_CLASS)}>
|
||||
<Link href={ACCOUNT_HREF} className={cn("inline-flex", SUITE_APP_LOGO_LOCKUP_CLASS)}>
|
||||
<Image
|
||||
src={suitePublicAsset("/compte-mark.svg")}
|
||||
alt=""
|
||||
@ -34,7 +36,7 @@ export function CompteSettingsHeader() {
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center pl-2 md:hidden">
|
||||
<Link href={COMPTE_HREF} className="inline-flex shrink-0 items-center">
|
||||
<Link href={ACCOUNT_HREF} className="inline-flex shrink-0 items-center">
|
||||
<Image
|
||||
src={suitePublicAsset("/compte-mark.svg")}
|
||||
alt="Compte Ulti"
|
||||
@ -50,7 +52,7 @@ export function CompteSettingsHeader() {
|
||||
|
||||
<HeaderAccountActions
|
||||
className="ml-auto shrink-0 pl-2 sm:pl-4"
|
||||
settingsHref={COMPTE_HREF}
|
||||
settingsHref={ACCOUNT_HREF}
|
||||
/>
|
||||
</header>
|
||||
)
|
||||
|
||||
@ -5,18 +5,19 @@ import { ChevronRight, ShieldCheck, UserRound } from "lucide-react"
|
||||
import { AccountAvatar } from "@/components/suite/account-avatar"
|
||||
import { CompteSettingsCard } from "@/components/compte/compte-settings-card"
|
||||
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
|
||||
import { ACCOUNT_SETTINGS_BASE_PATH } from "@/lib/compte-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const CARDS = [
|
||||
{
|
||||
href: "/compte/informations",
|
||||
href: `${ACCOUNT_SETTINGS_BASE_PATH}/informations`,
|
||||
icon: UserRound,
|
||||
title: "Informations personnelles",
|
||||
description:
|
||||
"Consultez votre nom, votre adresse e-mail et votre identifiant Ulti.",
|
||||
},
|
||||
{
|
||||
href: "/compte/securite",
|
||||
href: `${ACCOUNT_SETTINGS_BASE_PATH}/securite`,
|
||||
icon: ShieldCheck,
|
||||
title: "Sécurité",
|
||||
description:
|
||||
|
||||
@ -11,6 +11,7 @@ import { useIsXs } from "@/hooks/use-xs"
|
||||
import { useDriveUIStore } from "@/lib/stores/drive-ui-store"
|
||||
import { Menu } from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
export function DriveHeader({
|
||||
search,
|
||||
@ -67,7 +68,7 @@ export function DriveHeader({
|
||||
</div>
|
||||
<HeaderAccountActions
|
||||
className="ml-auto shrink-0 pl-4"
|
||||
settingsHref="/mail/settings"
|
||||
settingsHref={MAIL_SETTINGS_BASE_PATH}
|
||||
/>
|
||||
</header>
|
||||
)
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
DRIVE_SIDEBAR_ROW_CLASS,
|
||||
} from "@/lib/drive/drive-chrome-classes"
|
||||
import { mailNavRowClass } from "@/lib/mail-chrome-classes"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
import { DriveQuotaBar } from "@/components/drive/quota-bar"
|
||||
import { DriveNewMenu } from "@/components/drive/new-menu"
|
||||
import { DriveSidebarFolderTree } from "@/components/drive/sidebar-folder-tree"
|
||||
@ -97,7 +98,7 @@ export function DriveSidebar({
|
||||
aria-label="Réglages"
|
||||
asChild
|
||||
>
|
||||
<Link href="/mail/settings">
|
||||
<Link href={MAIL_SETTINGS_BASE_PATH}>
|
||||
<Icon icon="mdi:cog" className="size-5 shrink-0" aria-hidden />
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
@ -10,6 +10,7 @@ import type { ApiMailAccount } from "@/lib/api/types"
|
||||
import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries"
|
||||
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
|
||||
import { buildOidcLoginUrl } from "@/lib/auth/login-url"
|
||||
import { ACCOUNT_SETTINGS_BASE_PATH } from "@/lib/compte-settings/settings-nav"
|
||||
import {
|
||||
useAccountStore,
|
||||
useSignOutAll,
|
||||
@ -144,7 +145,7 @@ export function AccountSwitcherDropdown({
|
||||
className="mt-4 h-9 rounded-full border-border bg-transparent px-5 text-sm font-medium text-primary hover:bg-accent hover:text-primary"
|
||||
asChild
|
||||
>
|
||||
<Link href="/compte" onClick={() => onOpenChange(false)}>
|
||||
<Link href={ACCOUNT_SETTINGS_BASE_PATH} onClick={() => onOpenChange(false)}>
|
||||
Gérer votre compte
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
CONTACTS_SEARCH_BAR_CLASS,
|
||||
CONTACTS_SEARCH_INPUT_CLASS,
|
||||
} from "@/lib/contacts-chrome-classes"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
interface ContactsHeaderProps {
|
||||
@ -63,7 +64,7 @@ export function ContactsHeader({
|
||||
|
||||
<HeaderAccountActions
|
||||
className="shrink-0 pl-1 sm:pl-4"
|
||||
settingsHref="/mail/settings/accounts"
|
||||
settingsHref={`${MAIL_SETTINGS_BASE_PATH}/accounts`}
|
||||
/>
|
||||
</header>
|
||||
)
|
||||
|
||||
@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button"
|
||||
import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet"
|
||||
import { MailSettingsFields } from "@/components/gmail/mail-settings-fields"
|
||||
import { useMailSettingsStore } from "@/lib/stores/mail-settings-store"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function QuickSettingsPanel() {
|
||||
@ -53,7 +54,7 @@ export function QuickSettingsPanel() {
|
||||
className="h-10 w-full rounded-full border-[#1a73e8] text-[#1a73e8] hover:bg-[#e8f0fe]/50 dark:border-[#9aa0a6] dark:text-white dark:hover:bg-[#3c4043]/50"
|
||||
asChild
|
||||
>
|
||||
<Link href="/mail/settings" onClick={() => setOpen(false)}>
|
||||
<Link href={MAIL_SETTINGS_BASE_PATH} onClick={() => setOpen(false)}>
|
||||
Voir tous les paramètres
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
@ -4,7 +4,9 @@ import { UltiMailLogo } from "@/components/ultimail-logo"
|
||||
import { MailSettingsSearchBar } from "@/components/gmail/settings/mail-settings-search-bar"
|
||||
import { HeaderAccountActions } from "@/components/suite/header-account-actions"
|
||||
|
||||
const SETTINGS_HREF = "/mail/settings"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
const SETTINGS_HREF = MAIL_SETTINGS_BASE_PATH
|
||||
|
||||
export function MailSettingsHeader() {
|
||||
return (
|
||||
|
||||
@ -48,6 +48,7 @@ import { SettingsSectionHeader } from "@/components/gmail/settings/settings-sect
|
||||
import { SettingsSyncBanner } from "@/components/gmail/settings/settings-sync-banner"
|
||||
import { useAuthReady } from "@/lib/api/use-auth-ready"
|
||||
import type { ApiMailAccount, ApiMailSignature } from "@/lib/api/types"
|
||||
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
const NONE_SIGNATURE = "__none__"
|
||||
|
||||
@ -72,7 +73,7 @@ export function AccountsSettingsSection() {
|
||||
useEffect(() => {
|
||||
if (oauthStatus === "success") {
|
||||
void refetch()
|
||||
router.replace("/mail/settings/accounts")
|
||||
router.replace(`${MAIL_SETTINGS_BASE_PATH}/accounts`)
|
||||
}
|
||||
}, [oauthStatus, refetch, router])
|
||||
|
||||
|
||||
42
components/gmail/settings/settings-app-shell.tsx
Normal file
42
components/gmail/settings/settings-app-shell.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect } from "react"
|
||||
import { SidebarNavProvider } from "@/lib/sidebar-nav-context"
|
||||
import { MailSettingsSync } from "@/components/gmail/mail-settings-sync"
|
||||
import { MailNavSync } from "@/components/gmail/mail-nav-sync"
|
||||
import { ComposeIdentitiesSync } from "@/components/gmail/compose-identities-sync"
|
||||
import { MailSignaturesSync } from "@/components/gmail/mail-signatures-sync"
|
||||
import { MailNotificationsBridge } from "@/components/gmail/mail-notifications-bridge"
|
||||
import { useWebSocket } from "@/lib/api/ws"
|
||||
import { useMailSettingsStore } from "@/lib/stores/mail-settings-store"
|
||||
|
||||
export function SettingsAppShell({ children }: { children: React.ReactNode }) {
|
||||
useWebSocket()
|
||||
|
||||
useEffect(() => {
|
||||
useMailSettingsStore.getState().setQuickSettingsOpen(false)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const blockPinch = (event: Event) => event.preventDefault()
|
||||
document.addEventListener("gesturestart", blockPinch, { passive: false })
|
||||
document.addEventListener("gesturechange", blockPinch, { passive: false })
|
||||
document.addEventListener("gestureend", blockPinch, { passive: false })
|
||||
return () => {
|
||||
document.removeEventListener("gesturestart", blockPinch)
|
||||
document.removeEventListener("gesturechange", blockPinch)
|
||||
document.removeEventListener("gestureend", blockPinch)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<SidebarNavProvider>
|
||||
{children}
|
||||
<MailSettingsSync />
|
||||
<MailNavSync />
|
||||
<ComposeIdentitiesSync />
|
||||
<MailSignaturesSync />
|
||||
<MailNotificationsBridge />
|
||||
</SidebarNavProvider>
|
||||
)
|
||||
}
|
||||
@ -8,7 +8,7 @@ import { cn } from "@/lib/utils"
|
||||
|
||||
/**
|
||||
* Settings UI kit — composants unifiés pour les interfaces de réglages
|
||||
* (/admin/* et /mail/settings). Centralise cards, champs, lignes à bascule,
|
||||
* (/admin/* et /settings). Centralise cards, champs, lignes à bascule,
|
||||
* grilles et hints afin d'homogénéiser typographies, paddings et alignements.
|
||||
*/
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button"
|
||||
import { useAuthLogout } from "@/components/auth/auth-provider"
|
||||
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
|
||||
import { buildOidcLoginUrl } from "@/lib/auth/login-url"
|
||||
import { ACCOUNT_SETTINGS_BASE_PATH } from "@/lib/compte-settings/settings-nav"
|
||||
|
||||
export function AccountSwitcherPanel({ onClose }: { onClose: () => void }) {
|
||||
const pathname = usePathname()
|
||||
@ -67,7 +68,7 @@ export function AccountSwitcherPanel({ onClose }: { onClose: () => void }) {
|
||||
className="mt-4 h-9 rounded-full border-border bg-transparent px-5 text-sm font-medium text-primary hover:bg-accent hover:text-primary"
|
||||
asChild
|
||||
>
|
||||
<Link href="/compte" onClick={onClose}>
|
||||
<Link href={ACCOUNT_SETTINGS_BASE_PATH} onClick={onClose}>
|
||||
Gérer votre compte
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
@ -3,6 +3,8 @@ import { Home, ShieldCheck, Sparkles, UserRound } from "lucide-react"
|
||||
|
||||
export type CompteSettingsSectionId = "home" | "personal-info" | "security" | "usage-ia"
|
||||
|
||||
export const ACCOUNT_SETTINGS_BASE_PATH = "/account"
|
||||
|
||||
export type CompteSettingsNavItem = {
|
||||
id: CompteSettingsSectionId
|
||||
label: string
|
||||
@ -16,38 +18,48 @@ export const COMPTE_SETTINGS_NAV: CompteSettingsNavItem[] = [
|
||||
id: "home",
|
||||
label: "Accueil",
|
||||
description: "Vue d'ensemble de votre compte Ulti",
|
||||
href: "/compte",
|
||||
href: ACCOUNT_SETTINGS_BASE_PATH,
|
||||
icon: Home,
|
||||
},
|
||||
{
|
||||
id: "personal-info",
|
||||
label: "Informations personnelles",
|
||||
description: "Nom, adresse e-mail et identifiant",
|
||||
href: "/compte/informations",
|
||||
href: `${ACCOUNT_SETTINGS_BASE_PATH}/informations`,
|
||||
icon: UserRound,
|
||||
},
|
||||
{
|
||||
id: "usage-ia",
|
||||
label: "Usage IA",
|
||||
description: "Consommation LLM et clés API personnelles",
|
||||
href: "/compte/usage-ia",
|
||||
href: `${ACCOUNT_SETTINGS_BASE_PATH}/usage-ia`,
|
||||
icon: Sparkles,
|
||||
},
|
||||
{
|
||||
id: "security",
|
||||
label: "Sécurité",
|
||||
description: "Mot de passe, sessions et appareils",
|
||||
href: "/compte/securite",
|
||||
href: `${ACCOUNT_SETTINGS_BASE_PATH}/securite`,
|
||||
icon: ShieldCheck,
|
||||
},
|
||||
]
|
||||
|
||||
export function isAccountSettingsPath(pathname: string | null): boolean {
|
||||
return (
|
||||
pathname === ACCOUNT_SETTINGS_BASE_PATH ||
|
||||
pathname?.startsWith(`${ACCOUNT_SETTINGS_BASE_PATH}/`) === true
|
||||
)
|
||||
}
|
||||
|
||||
export function isCompteSettingsNavActive(
|
||||
pathname: string | null,
|
||||
item: CompteSettingsNavItem
|
||||
): boolean {
|
||||
if (item.href === "/compte") {
|
||||
return pathname === "/compte" || pathname === "/compte/accueil"
|
||||
if (item.href === ACCOUNT_SETTINGS_BASE_PATH) {
|
||||
return (
|
||||
pathname === ACCOUNT_SETTINGS_BASE_PATH ||
|
||||
pathname === `${ACCOUNT_SETTINGS_BASE_PATH}/accueil`
|
||||
)
|
||||
}
|
||||
return (
|
||||
pathname === item.href || Boolean(pathname?.startsWith(`${item.href}/`))
|
||||
|
||||
@ -17,6 +17,8 @@ export type MailSettingsSectionId =
|
||||
| "automation"
|
||||
| "agenda"
|
||||
|
||||
export const MAIL_SETTINGS_BASE_PATH = "/settings"
|
||||
|
||||
export type MailSettingsNavItem = {
|
||||
id: MailSettingsSectionId
|
||||
label: string
|
||||
@ -30,53 +32,61 @@ export const MAIL_SETTINGS_NAV: MailSettingsNavItem[] = [
|
||||
id: "display",
|
||||
label: "Affichage",
|
||||
description: "Densité, thème, boîte de réception, volet de lecture",
|
||||
href: "/mail/settings",
|
||||
href: MAIL_SETTINGS_BASE_PATH,
|
||||
icon: Monitor,
|
||||
},
|
||||
{
|
||||
id: "accounts",
|
||||
label: "Comptes mail",
|
||||
description: "IMAP, SMTP, identités d'envoi et signatures",
|
||||
href: "/mail/settings/accounts",
|
||||
href: `${MAIL_SETTINGS_BASE_PATH}/accounts`,
|
||||
icon: Users,
|
||||
},
|
||||
{
|
||||
id: "labels",
|
||||
label: "Libellés et dossiers",
|
||||
description: "Organisation unifiée cross-comptes",
|
||||
href: "/mail/settings/labels",
|
||||
href: `${MAIL_SETTINGS_BASE_PATH}/labels`,
|
||||
icon: FolderKanban,
|
||||
},
|
||||
{
|
||||
id: "notifications",
|
||||
label: "Notifications",
|
||||
description: "Alertes desktop, mobile et e-mail",
|
||||
href: "/mail/settings/notifications",
|
||||
href: `${MAIL_SETTINGS_BASE_PATH}/notifications`,
|
||||
icon: Bell,
|
||||
},
|
||||
{
|
||||
id: "automation",
|
||||
label: "Automatisations",
|
||||
description: "Règles, webhooks, LLM, recherche web, tokens API",
|
||||
href: "/mail/settings/automation",
|
||||
href: `${MAIL_SETTINGS_BASE_PATH}/automation`,
|
||||
icon: Bot,
|
||||
},
|
||||
{
|
||||
id: "agenda",
|
||||
label: ULTICAL_APP_NAME,
|
||||
description: "Affichage, visio, invitations, agendas et vues",
|
||||
href: "/mail/settings/agenda",
|
||||
href: `${MAIL_SETTINGS_BASE_PATH}/agenda`,
|
||||
icon: CalendarDays,
|
||||
},
|
||||
]
|
||||
|
||||
export function isMailSettingsPath(pathname: string | null): boolean {
|
||||
return (
|
||||
pathname === MAIL_SETTINGS_BASE_PATH ||
|
||||
pathname?.startsWith(`${MAIL_SETTINGS_BASE_PATH}/`) === true
|
||||
)
|
||||
}
|
||||
|
||||
export function isMailSettingsNavActive(
|
||||
pathname: string | null,
|
||||
item: MailSettingsNavItem
|
||||
): boolean {
|
||||
if (item.href === "/mail/settings") {
|
||||
if (item.href === MAIL_SETTINGS_BASE_PATH) {
|
||||
return (
|
||||
pathname === "/mail/settings" || pathname === "/mail/settings/display"
|
||||
pathname === MAIL_SETTINGS_BASE_PATH ||
|
||||
pathname === `${MAIL_SETTINGS_BASE_PATH}/display`
|
||||
)
|
||||
}
|
||||
return (
|
||||
@ -104,7 +114,7 @@ const MAIL_SETTINGS_WIDE_LAYOUT_SECTIONS: MailSettingsSectionId[] = [
|
||||
const MAIL_SETTINGS_LEFT_ALIGNED_SECTIONS: MailSettingsSectionId[] = ["accounts"]
|
||||
|
||||
export function isMailSettingsWideLayoutPath(pathname: string | null): boolean {
|
||||
if (!pathname?.startsWith("/mail/settings")) return false
|
||||
if (!isMailSettingsPath(pathname)) return false
|
||||
return MAIL_SETTINGS_NAV.some(
|
||||
(item) =>
|
||||
MAIL_SETTINGS_WIDE_LAYOUT_SECTIONS.includes(item.id) &&
|
||||
@ -113,7 +123,7 @@ export function isMailSettingsWideLayoutPath(pathname: string | null): boolean {
|
||||
}
|
||||
|
||||
export function isMailSettingsLeftAlignedPath(pathname: string | null): boolean {
|
||||
if (!pathname?.startsWith("/mail/settings")) return false
|
||||
if (!isMailSettingsPath(pathname)) return false
|
||||
return MAIL_SETTINGS_NAV.some(
|
||||
(item) =>
|
||||
MAIL_SETTINGS_LEFT_ALIGNED_SECTIONS.includes(item.id) &&
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { MAIL_SETTINGS_NAV, type MailSettingsSectionId } from "@/lib/mail-settings/settings-nav"
|
||||
import { MAIL_SETTINGS_BASE_PATH, MAIL_SETTINGS_NAV, type MailSettingsSectionId } from "@/lib/mail-settings/settings-nav"
|
||||
|
||||
export type MailSettingsSearchEntry = {
|
||||
id: string
|
||||
@ -11,7 +11,7 @@ export type MailSettingsSearchEntry = {
|
||||
}
|
||||
|
||||
function sectionHref(sectionId: MailSettingsSectionId): string {
|
||||
return MAIL_SETTINGS_NAV.find((item) => item.id === sectionId)?.href ?? "/mail/settings"
|
||||
return MAIL_SETTINGS_NAV.find((item) => item.id === sectionId)?.href ?? MAIL_SETTINGS_BASE_PATH
|
||||
}
|
||||
|
||||
function sectionLabel(sectionId: MailSettingsSectionId): string {
|
||||
|
||||
@ -14,11 +14,6 @@ export type FavoriteApp = {
|
||||
}
|
||||
|
||||
export const SUITE_FAVORITE_APPS: FavoriteApp[] = [
|
||||
{
|
||||
name: "Compte",
|
||||
icon: suitePublicAsset("/compte-mark.svg"),
|
||||
href: "/compte",
|
||||
},
|
||||
{
|
||||
name: ULTICAL_APP_NAME,
|
||||
icon: suitePublicAsset("/agenda-mark.svg"),
|
||||
|
||||
2
next-env.d.ts
vendored
2
next-env.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/types/routes.d.ts";
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
@ -16,6 +16,30 @@ const nextConfig = {
|
||||
// breaks Tailwind @import resolution (resolves from parent /Users/red/workdev).
|
||||
outputFileTracingRoot: projectRoot,
|
||||
allowedDevOrigins: ['192.168.0.20', '127.0.0.1', 'localhost', '100.120.4.66'],
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
source: "/mail/settings",
|
||||
destination: "/settings",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/mail/settings/:section*",
|
||||
destination: "/settings/:section*",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/compte",
|
||||
destination: "/account",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/compte/:section*",
|
||||
destination: "/account/:section*",
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user