This commit is contained in:
Linus Rath
2026-03-11 16:04:59 +01:00
9 changed files with 151 additions and 18 deletions
+97 -11
View File
@@ -3,7 +3,7 @@
import { useState, useEffect } from 'react';
import { useRouter } from '@/i18n/navigation';
import { useTranslations } from 'next-intl';
import { ArrowLeft, Settings as SettingsIcon } from 'lucide-react';
import { ArrowLeft, ChevronRight, Settings as SettingsIcon } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { AppearanceSettings } from '@/components/settings/appearance-settings';
import { EmailSettings } from '@/components/settings/email-settings';
@@ -16,6 +16,7 @@ import { TemplateSettings } from '@/components/settings/template-settings';
import { AdvancedSettings } from '@/components/settings/advanced-settings';
import { FolderSettings } from '@/components/settings/folder-settings';
import { useAuthStore } from '@/stores/auth-store';
import { useIsDesktop } from '@/hooks/use-media-query';
import { cn } from '@/lib/utils';
type Tab = 'appearance' | 'email' | 'account' | 'identities' | 'vacation' | 'calendar' | 'filters' | 'templates' | 'folders' | 'advanced';
@@ -25,6 +26,8 @@ export default function SettingsPage() {
const t = useTranslations('settings');
const { client, isAuthenticated } = useAuthStore();
const [activeTab, setActiveTab] = useState<Tab>('appearance');
const [mobileShowContent, setMobileShowContent] = useState(false);
const isDesktop = useIsDesktop();
useEffect(() => {
if (!isAuthenticated) {
@@ -53,6 +56,98 @@ export default function SettingsPage() {
{ id: 'advanced', label: t('tabs.advanced') },
];
const handleTabSelect = (tabId: Tab) => {
setActiveTab(tabId);
if (!isDesktop) {
setMobileShowContent(true);
}
};
const activeTabLabel = tabs.find((tab) => tab.id === activeTab)?.label ?? '';
const renderTabContent = () => (
<>
{activeTab === 'appearance' && <AppearanceSettings />}
{activeTab === 'email' && <EmailSettings />}
{activeTab === 'account' && <AccountSettings />}
{activeTab === 'identities' && <IdentitySettings />}
{activeTab === 'vacation' && <VacationSettings />}
{activeTab === 'calendar' && <CalendarSettings />}
{activeTab === 'filters' && <FilterSettings />}
{activeTab === 'templates' && <TemplateSettings />}
{activeTab === 'folders' && <FolderSettings />}
{activeTab === 'advanced' && <AdvancedSettings />}
</>
);
// Mobile layout
if (!isDesktop) {
// Mobile: show content view
if (mobileShowContent) {
return (
<div className="flex flex-col h-screen bg-background">
{/* Mobile content header */}
<div className="flex items-center gap-2 px-4 h-14 border-b border-border bg-background shrink-0">
<Button
variant="ghost"
size="icon"
onClick={() => setMobileShowContent(false)}
className="h-10 w-10"
>
<ArrowLeft className="w-5 h-5" />
</Button>
<h1 className="font-semibold text-lg truncate">{activeTabLabel}</h1>
</div>
{/* Content */}
<div className="flex-1 overflow-y-auto p-4">
<div className="bg-card border border-border rounded-lg p-4">
{renderTabContent()}
</div>
</div>
</div>
);
}
// Mobile: show tab list
return (
<div className="flex flex-col h-screen bg-background">
{/* Mobile header */}
<div className="flex items-center gap-2 px-4 h-14 border-b border-border bg-background shrink-0">
<Button
variant="ghost"
size="icon"
onClick={() => router.push('/')}
className="h-10 w-10"
>
<ArrowLeft className="w-5 h-5" />
</Button>
<div className="flex items-center gap-2">
<SettingsIcon className="w-5 h-5 text-muted-foreground" />
<h1 className="font-semibold text-lg">{t('title')}</h1>
</div>
</div>
{/* Tab list */}
<div className="flex-1 overflow-y-auto">
<div className="py-2">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => handleTabSelect(tab.id)}
className="w-full flex items-center justify-between px-5 py-3.5 text-sm text-foreground hover:bg-muted transition-colors duration-150"
>
<span>{tab.label}</span>
<ChevronRight className="w-4 h-4 text-muted-foreground" />
</button>
))}
</div>
</div>
</div>
);
}
// Desktop layout
return (
<div className="flex h-screen bg-background">
{/* Settings Sidebar */}
@@ -104,16 +199,7 @@ export default function SettingsPage() {
{/* Active Tab Content */}
<div className="bg-card border border-border rounded-lg p-6">
{activeTab === 'appearance' && <AppearanceSettings />}
{activeTab === 'email' && <EmailSettings />}
{activeTab === 'account' && <AccountSettings />}
{activeTab === 'identities' && <IdentitySettings />}
{activeTab === 'vacation' && <VacationSettings />}
{activeTab === 'calendar' && <CalendarSettings />}
{activeTab === 'filters' && <FilterSettings />}
{activeTab === 'templates' && <TemplateSettings />}
{activeTab === 'folders' && <FolderSettings />}
{activeTab === 'advanced' && <AdvancedSettings />}
{renderTabContent()}
</div>
</div>
</div>
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Erweitert",
"calendar": "Kalender",
"filters": "Filter",
"templates": "Vorlagen"
"templates": "Vorlagen",
"folders": "Ordner"
},
"tab_groups": {
"general": "Allgemein",
"account": "Konto",
"organization": "Organisation"
},
"appearance": {
"title": "Darstellung",
+5
View File
@@ -457,6 +457,11 @@
"templates": "Templates",
"folders": "Folders"
},
"tab_groups": {
"general": "General",
"account": "Account",
"organization": "Organization"
},
"appearance": {
"title": "Appearance",
"description": "Customize the look and feel of your webmail",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Avanzado",
"calendar": "Calendario",
"filters": "Filtros",
"templates": "Plantillas"
"templates": "Plantillas",
"folders": "Carpetas"
},
"tab_groups": {
"general": "General",
"account": "Cuenta",
"organization": "Organización"
},
"appearance": {
"title": "Apariencia",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Avancé",
"calendar": "Calendrier",
"filters": "Filtres",
"templates": "Modèles"
"templates": "Modèles",
"folders": "Dossiers"
},
"tab_groups": {
"general": "Général",
"account": "Compte",
"organization": "Organisation"
},
"appearance": {
"title": "Apparence",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Avanzate",
"calendar": "Calendario",
"filters": "Filtri",
"templates": "Modelli"
"templates": "Modelli",
"folders": "Cartelle"
},
"tab_groups": {
"general": "Generale",
"account": "Account",
"organization": "Organizzazione"
},
"appearance": {
"title": "Aspetto",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "詳細設定",
"calendar": "カレンダー",
"filters": "フィルター",
"templates": "テンプレート"
"templates": "テンプレート",
"folders": "フォルダー"
},
"tab_groups": {
"general": "一般",
"account": "アカウント",
"organization": "整理"
},
"appearance": {
"title": "外観",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Geavanceerd",
"calendar": "Agenda",
"filters": "Filters",
"templates": "Sjablonen"
"templates": "Sjablonen",
"folders": "Mappen"
},
"tab_groups": {
"general": "Algemeen",
"account": "Account",
"organization": "Organisatie"
},
"appearance": {
"title": "Uiterlijk",
+7 -1
View File
@@ -446,7 +446,13 @@
"advanced": "Avançado",
"calendar": "Calendário",
"filters": "Filtros",
"templates": "Modelos"
"templates": "Modelos",
"folders": "Pastas"
},
"tab_groups": {
"general": "Geral",
"account": "Conta",
"organization": "Organização"
},
"appearance": {
"title": "Aparência",