diff --git a/src/locales/ar.json b/src/locales/ar.json
index 0f6a2020..bb568c1f 100644
--- a/src/locales/ar.json
+++ b/src/locales/ar.json
@@ -913,6 +913,11 @@
"title": "الإعدادات",
"description": "إدارة إعدادات {{appName}} الخاصة بك",
"deleteAccount": "حذف الحساب",
+ "groups": {
+ "account": "الحساب",
+ "app": "التطبيق",
+ "system": "النظام"
+ },
"sections": {
"profile": "الملف الشخصي",
"profileDesc": "اسم العرض والسيرة الذاتية والصورة الرمزية والتحقق.",
diff --git a/src/locales/en.json b/src/locales/en.json
index 13af3ab7..f68c3bd5 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1376,6 +1376,11 @@
"title": "Settings",
"description": "Manage your {{appName}} settings",
"deleteAccount": "Delete account",
+ "groups": {
+ "account": "Account",
+ "app": "App",
+ "system": "System"
+ },
"sections": {
"profile": "Profile",
"profileDesc": "Display name, bio, avatar, and verification.",
diff --git a/src/locales/es.json b/src/locales/es.json
index 6f7cbd5e..9ab8bfdd 100644
--- a/src/locales/es.json
+++ b/src/locales/es.json
@@ -923,6 +923,11 @@
"title": "Ajustes",
"description": "Administra tus ajustes de {{appName}}",
"deleteAccount": "Eliminar cuenta",
+ "groups": {
+ "account": "Cuenta",
+ "app": "Aplicación",
+ "system": "Sistema"
+ },
"sections": {
"profile": "Perfil",
"profileDesc": "Nombre, biografía, avatar y verificación.",
diff --git a/src/locales/fa.json b/src/locales/fa.json
index a75e7309..a4224927 100644
--- a/src/locales/fa.json
+++ b/src/locales/fa.json
@@ -923,6 +923,11 @@
"title": "تنظیمات",
"description": "مدیریت تنظیمات {{appName}} شما",
"deleteAccount": "حذف حساب",
+ "groups": {
+ "account": "حساب",
+ "app": "برنامه",
+ "system": "سیستم"
+ },
"sections": {
"profile": "نمایه",
"profileDesc": "نام نمایشی، بیوگرافی، آواتار و تأیید هویت.",
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 971f96cd..287cabe4 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -1362,6 +1362,11 @@
"title": "Paramètres",
"description": "Gérez vos paramètres {{appName}}",
"deleteAccount": "Supprimer le compte",
+ "groups": {
+ "account": "Compte",
+ "app": "Application",
+ "system": "Système"
+ },
"sections": {
"profile": "Profil",
"profileDesc": "Nom d'affichage, biographie, avatar et vérification.",
diff --git a/src/locales/hi.json b/src/locales/hi.json
index 99ac3918..57de7480 100644
--- a/src/locales/hi.json
+++ b/src/locales/hi.json
@@ -1365,6 +1365,11 @@
"title": "सेटिंग्स",
"description": "अपनी {{appName}} सेटिंग्स प्रबंधित करें",
"deleteAccount": "अकाउंट डिलीट करें",
+ "groups": {
+ "account": "खाता",
+ "app": "ऐप",
+ "system": "सिस्टम"
+ },
"sections": {
"profile": "प्रोफ़ाइल",
"profileDesc": "डिस्प्ले नाम, बायो, अवतार, और सत्यापन।",
diff --git a/src/locales/id.json b/src/locales/id.json
index 31cfc808..ed02bc4f 100644
--- a/src/locales/id.json
+++ b/src/locales/id.json
@@ -1365,6 +1365,11 @@
"title": "Pengaturan",
"description": "Kelola pengaturan {{appName}} Anda",
"deleteAccount": "Hapus akun",
+ "groups": {
+ "account": "Akun",
+ "app": "Aplikasi",
+ "system": "Sistem"
+ },
"sections": {
"profile": "Profil",
"profileDesc": "Nama tampilan, bio, avatar, dan verifikasi.",
diff --git a/src/locales/km.json b/src/locales/km.json
index d1637420..c464d16d 100644
--- a/src/locales/km.json
+++ b/src/locales/km.json
@@ -923,6 +923,11 @@
"title": "ការកំណត់",
"description": "គ្រប់គ្រងការកំណត់ {{appName}} របស់អ្នក",
"deleteAccount": "លុបគណនី",
+ "groups": {
+ "account": "គណនី",
+ "app": "កម្មវិធី",
+ "system": "ប្រព័ន្ធ"
+ },
"sections": {
"profile": "ប្រវត្តិរូប",
"profileDesc": "ឈ្មោះបង្ហាញ ប្រវត្តិរូបសង្ខេប រូបតំណាង និងការផ្ទៀងផ្ទាត់។",
diff --git a/src/locales/ps.json b/src/locales/ps.json
index f4cdd4bd..3c06453c 100644
--- a/src/locales/ps.json
+++ b/src/locales/ps.json
@@ -925,6 +925,11 @@
"title": "تنظیمات",
"description": "د {{appName}} تنظیماتو اداره کول",
"deleteAccount": "حساب ړنګول",
+ "groups": {
+ "account": "حساب",
+ "app": "اپلیکیشن",
+ "system": "سیسټم"
+ },
"sections": {
"profile": "پروفایل",
"profileDesc": "د ښودنې نوم، بیوګرافي، اواتار، او تصدیق.",
diff --git a/src/locales/pt.json b/src/locales/pt.json
index 32688dcb..df63f018 100644
--- a/src/locales/pt.json
+++ b/src/locales/pt.json
@@ -1367,6 +1367,11 @@
"title": "Configurações",
"description": "Gerencie suas configurações do {{appName}}",
"deleteAccount": "Excluir conta",
+ "groups": {
+ "account": "Conta",
+ "app": "Aplicativo",
+ "system": "Sistema"
+ },
"sections": {
"profile": "Perfil",
"profileDesc": "Nome de exibição, biografia, avatar e verificação.",
diff --git a/src/locales/ru.json b/src/locales/ru.json
index ab13f5da..ba04b467 100644
--- a/src/locales/ru.json
+++ b/src/locales/ru.json
@@ -1367,6 +1367,11 @@
"title": "Настройки",
"description": "Управляйте настройками {{appName}}",
"deleteAccount": "Удалить аккаунт",
+ "groups": {
+ "account": "Аккаунт",
+ "app": "Приложение",
+ "system": "Система"
+ },
"sections": {
"profile": "Профиль",
"profileDesc": "Имя для отображения, биография, аватар и верификация.",
diff --git a/src/locales/sn.json b/src/locales/sn.json
index 9bcdaba5..4a7b05b1 100644
--- a/src/locales/sn.json
+++ b/src/locales/sn.json
@@ -925,6 +925,11 @@
"title": "Marongero",
"description": "Tarisira marongero ako e{{appName}}",
"deleteAccount": "Bvisa akaunti",
+ "groups": {
+ "account": "Akaundi",
+ "app": "Puroguramu",
+ "system": "Sisitimu"
+ },
"sections": {
"profile": "Profile",
"profileDesc": "Zita rinoratidzwa, nhoroondo, mufananidzo, nokutsigirwa.",
diff --git a/src/locales/sw.json b/src/locales/sw.json
index f02196e9..0c8eaec8 100644
--- a/src/locales/sw.json
+++ b/src/locales/sw.json
@@ -1364,6 +1364,11 @@
"title": "Mipangilio",
"description": "Simamia mipangilio yako ya {{appName}}",
"deleteAccount": "Futa akaunti",
+ "groups": {
+ "account": "Akaunti",
+ "app": "Programu",
+ "system": "Mfumo"
+ },
"sections": {
"profile": "Wasifu",
"profileDesc": "Jina la kuonyesha, wasifu, picha, na uthibitisho.",
diff --git a/src/locales/tr.json b/src/locales/tr.json
index 8fd3aa79..da61c295 100644
--- a/src/locales/tr.json
+++ b/src/locales/tr.json
@@ -1366,6 +1366,11 @@
"title": "Ayarlar",
"description": "{{appName}} ayarlarınızı yönetin",
"deleteAccount": "Hesabı sil",
+ "groups": {
+ "account": "Hesap",
+ "app": "Uygulama",
+ "system": "Sistem"
+ },
"sections": {
"profile": "Profil",
"profileDesc": "Görünen ad, biyografi, avatar ve doğrulama.",
diff --git a/src/locales/zh-Hant.json b/src/locales/zh-Hant.json
index 4125f16b..962664b0 100644
--- a/src/locales/zh-Hant.json
+++ b/src/locales/zh-Hant.json
@@ -925,6 +925,11 @@
"title": "設定",
"description": "管理你的 {{appName}} 設定",
"deleteAccount": "刪除賬戶",
+ "groups": {
+ "account": "帳戶",
+ "app": "應用程式",
+ "system": "系統"
+ },
"sections": {
"profile": "個人資料",
"profileDesc": "顯示名稱、簡介、頭像和驗證。",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index c41e2d98..00708869 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -925,6 +925,11 @@
"title": "设置",
"description": "管理你的 {{appName}} 设置",
"deleteAccount": "删除账户",
+ "groups": {
+ "account": "账户",
+ "app": "应用",
+ "system": "系统"
+ },
"sections": {
"profile": "个人资料",
"profileDesc": "显示名称、简介、头像和验证。",
diff --git a/src/pages/AdvancedSettingsPage.tsx b/src/pages/AdvancedSettingsPage.tsx
index 0c663e68..ced4b46a 100644
--- a/src/pages/AdvancedSettingsPage.tsx
+++ b/src/pages/AdvancedSettingsPage.tsx
@@ -37,11 +37,11 @@ export function AdvancedSettingsPage() {
}
/>
-
+
{/* Intro */}
-
-
{t('settings.advanced.powerUserHeading')}
-
+
+
{t('settings.advanced.powerUserHeading')}
+
{t('settings.advanced.intro')}
diff --git a/src/pages/AppearanceSettingsPage.tsx b/src/pages/AppearanceSettingsPage.tsx
index 7cbb1343..b3a1744b 100644
--- a/src/pages/AppearanceSettingsPage.tsx
+++ b/src/pages/AppearanceSettingsPage.tsx
@@ -1,5 +1,5 @@
import { useSeoMeta } from '@unhead/react';
-import { Monitor, Moon, Sun } from 'lucide-react';
+import { Check, Monitor, Moon, Sun } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { PageHeader } from '@/components/PageHeader';
import { useAppContext } from '@/hooks/useAppContext';
@@ -60,52 +60,47 @@ export function AppearanceSettingsPage() {
}
/>
-
+
{/* Intro */}
-
-
{t('settings.appearance.colorMode')}
-
+
+
{t('settings.appearance.colorMode')}
+
{t('settings.appearance.intro')}
{/* Theme options */}
-
+
{themeOptions.map((option) => (
))}
diff --git a/src/pages/LanguageSettingsPage.tsx b/src/pages/LanguageSettingsPage.tsx
index c60c1b52..a046ed78 100644
--- a/src/pages/LanguageSettingsPage.tsx
+++ b/src/pages/LanguageSettingsPage.tsx
@@ -63,14 +63,18 @@ export function LanguageSettingsPage() {
}
/>
-
-
-
+
+
-
+
{SUPPORTED_LANGUAGES.map((language) => {
const selected = language.code === currentLng;
const rtl = isRTLLanguage(language.code);
@@ -82,34 +86,25 @@ export function LanguageSettingsPage() {
aria-checked={selected}
onClick={() => handleSelect(language.code)}
className={cn(
- 'w-full flex items-center gap-4 px-4 py-3.5 rounded-xl border-2 transition-all duration-200',
- 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
- selected
- ? 'border-primary bg-primary/5 shadow-sm'
- : 'border-border/50 hover:border-primary/40 hover:bg-muted/30',
+ 'w-full flex items-center gap-4 px-3.5 py-3 transition-colors',
+ 'hover:bg-muted/50 active:bg-muted/70',
+ 'focus-visible:outline-none focus-visible:bg-muted/50',
)}
>
-
+
{language.nativeName}
-
+
{language.code}
{selected && (
-
+
)}
@@ -117,7 +112,7 @@ export function LanguageSettingsPage() {
})}
-
+
{t('language.translationNote')}
diff --git a/src/pages/NetworkSettingsPage.tsx b/src/pages/NetworkSettingsPage.tsx
index 359584e7..7dcebb47 100644
--- a/src/pages/NetworkSettingsPage.tsx
+++ b/src/pages/NetworkSettingsPage.tsx
@@ -50,28 +50,25 @@ export function NetworkSettingsPage() {
}
/>
-
+
{/* Intro */}
-
-
{t('settings.network.connectionsHeading')}
-
+
+
{t('settings.network.connectionsHeading')}
+
{t('settings.network.connectionsIntro')}
{/* Low-Bandwidth Mode */}
-
-
-
{t('settings.network.lowBandwidthHeading')}
-
-
-
+
+ {t('settings.network.lowBandwidthHeading')}
+
-
@@ -86,13 +83,13 @@ export function NetworkSettingsPage() {
{/* Image Proxy — independent of Low-Bandwidth. Controls whether
images are fetched from a downsizing proxy. */}
-
+
-
+
{t('settings.network.useImageProxy')}
-
+
{t('settings.network.useImageProxyDesc')}
@@ -156,40 +153,27 @@ export function NetworkSettingsPage() {
)}
-
+
{/* Relays */}
-
-
-
{t('settings.network.relays')}
-
-
-
-
-
-
+
+ {t('settings.network.relays')}
+
+
{/* Blossom Servers */}
-
-
-
{t('settings.network.blossomServers')}
-
-
-
-
-
-
+
+ {t('settings.network.blossomServers')}
+
+
{/* Image Upload Quality */}
-
-
-
{t('settings.network.imageUploads')}
-
-
-
+
+ {t('settings.network.imageUploads')}
+
-
{t('settings.network.uploadQuality')}
-
+ {t('settings.network.uploadQuality')}
+
{t('settings.network.uploadQualityDesc')}
@@ -210,7 +194,7 @@ export function NetworkSettingsPage() {
))}
-
+
);
diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx
index aefdddc9..f434e0f3 100644
--- a/src/pages/SettingsPage.tsx
+++ b/src/pages/SettingsPage.tsx
@@ -1,12 +1,24 @@
import { useSeoMeta } from '@unhead/react';
import { lazy, Suspense, useState } from 'react';
-import { ChevronRight, Settings } from 'lucide-react';
+import {
+ ChevronRight,
+ Settings,
+ User,
+ BadgeCheck,
+ Palette,
+ Languages,
+ Wifi,
+ Bell,
+ SlidersHorizontal,
+ ShieldCheck,
+} from 'lucide-react';
import { Link, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { PageHeader } from '@/components/PageHeader';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useAppContext } from '@/hooks/useAppContext';
import { isAdmin } from '@/lib/admins';
+import { cn } from '@/lib/utils';
const RequestToVanishDialog = lazy(() => import('@/components/RequestToVanishDialog').then(m => ({ default: m.RequestToVanishDialog })));
@@ -17,6 +29,12 @@ interface SettingsSection {
/** i18n key under `settings.sections.*` for the row description. */
descriptionKey: string;
path: string;
+ /** Icon rendered in the colored leading tile. */
+ icon: React.ReactNode;
+ /** Tailwind classes for the icon tile background gradient. */
+ tile: string;
+ /** Which visual group this row belongs to. */
+ group: 'account' | 'app' | 'system';
requiresAuth?: boolean;
/** When true, only shown to platform admins (see `isAdmin` in `@/lib/admins`). */
requiresAdmin?: boolean;
@@ -28,6 +46,9 @@ const settingsSections: SettingsSection[] = [
labelKey: 'settings.sections.profile',
descriptionKey: 'settings.sections.profileDesc',
path: '/settings/profile',
+ icon:
,
+ tile: 'bg-gradient-to-b from-blue-400 to-blue-600',
+ group: 'account',
requiresAuth: true,
},
{
@@ -35,6 +56,9 @@ const settingsSections: SettingsSection[] = [
labelKey: 'settings.sections.verifier',
descriptionKey: 'settings.sections.verifierDesc',
path: '/settings/verifier',
+ icon:
,
+ tile: 'bg-gradient-to-b from-emerald-400 to-emerald-600',
+ group: 'account',
requiresAuth: true,
},
{
@@ -42,25 +66,37 @@ const settingsSections: SettingsSection[] = [
labelKey: 'settings.sections.appearance',
descriptionKey: 'settings.sections.appearanceDesc',
path: '/settings/appearance',
+ icon:
,
+ tile: 'bg-gradient-to-b from-violet-400 to-violet-600',
+ group: 'app',
},
{
id: 'language',
labelKey: 'settings.sections.language',
descriptionKey: 'settings.sections.languageDesc',
path: '/settings/language',
- },
- {
- id: 'network',
- labelKey: 'settings.sections.network',
- descriptionKey: 'settings.sections.networkDesc',
- path: '/settings/network',
- requiresAuth: true,
+ icon:
,
+ tile: 'bg-gradient-to-b from-sky-400 to-sky-600',
+ group: 'app',
},
{
id: 'notifications',
labelKey: 'settings.sections.notifications',
descriptionKey: 'settings.sections.notificationsDesc',
path: '/settings/notifications',
+ icon:
,
+ tile: 'bg-gradient-to-b from-rose-400 to-rose-600',
+ group: 'app',
+ requiresAuth: true,
+ },
+ {
+ id: 'network',
+ labelKey: 'settings.sections.network',
+ descriptionKey: 'settings.sections.networkDesc',
+ path: '/settings/network',
+ icon:
,
+ tile: 'bg-gradient-to-b from-amber-400 to-amber-600',
+ group: 'system',
requiresAuth: true,
},
{
@@ -68,17 +104,25 @@ const settingsSections: SettingsSection[] = [
labelKey: 'settings.sections.advanced',
descriptionKey: 'settings.sections.advancedDesc',
path: '/settings/advanced',
+ icon:
,
+ tile: 'bg-gradient-to-b from-slate-400 to-slate-600',
+ group: 'system',
},
{
id: 'organizers',
labelKey: 'settings.sections.organizers',
descriptionKey: 'settings.sections.organizersDesc',
path: '/organizers',
+ icon:
,
+ tile: 'bg-gradient-to-b from-teal-400 to-teal-600',
+ group: 'system',
requiresAuth: true,
requiresAdmin: true,
},
];
+const GROUP_ORDER: Array
= ['account', 'app', 'system'];
+
export function SettingsPage() {
const { t } = useTranslation();
const { user } = useCurrentUser();
@@ -86,7 +130,6 @@ export function SettingsPage() {
const navigate = useNavigate();
const [deleteAccountOpen, setDeleteAccountOpen] = useState(false);
-
useSeoMeta({
title: `${t('settings.title')} | ${config.appName}`,
description: t('settings.description', { appName: config.appName }),
@@ -98,31 +141,60 @@ export function SettingsPage() {
return true;
});
+ const groups = GROUP_ORDER
+ .map((group) => ({ group, items: visibleSections.filter((s) => s.group === group) }))
+ .filter((g) => g.items.length > 0);
+
return (
} backTo="/" />
- {/* Settings list */}
-