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:
R3D347HR4Y 2026-06-16 11:32:58 +02:00
parent 2a0958b70d
commit b95948f980
29 changed files with 174 additions and 86 deletions

View File

@ -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[] }>

View File

@ -7,7 +7,7 @@ export const metadata: Metadata = suitePageMetadata({
app: "compte",
})
export default function CompteRootLayout({
export default function AccountRootLayout({
children,
}: {
children: React.ReactNode

View File

@ -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 />

View File

@ -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>
}

View File

@ -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
View 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>
)
}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>
)

View File

@ -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:

View File

@ -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>
)

View File

@ -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>

View File

@ -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>

View File

@ -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>
)

View File

@ -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>

View File

@ -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 (

View File

@ -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])

View 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>
)
}

View File

@ -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.
*/

View File

@ -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>

View File

@ -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}/`))

View File

@ -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) &&

View File

@ -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 {

View File

@ -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
View File

@ -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.

View File

@ -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