feat: redesign admin settings with tree navigation and compact layout

- Replace flat sidebar with collapsible tree groups (7 groups, 52 sub-items)
- Map all 61 backend category keys to sidebar navigation
- Add QuickToggles panel for boolean settings
- Replace card-style SettingRow with compact SettingsTableRow
- Add breadcrumb navigation for tree sub-items
- Add source badges (modified/DB/ENV) on settings
- Implement two-level mobile navigation with group chips
- Add i18n translations for all new keys (en, ru, zh, fa)
This commit is contained in:
Fringg
2026-03-29 02:38:52 +03:00
parent 88c93e2b5f
commit 21813ef82e
13 changed files with 1334 additions and 344 deletions

View File

@@ -1,111 +1,160 @@
import { ThemeColors, DEFAULT_THEME_COLORS } from '../../types/theme';
// Menu item types
export interface MenuItem {
// Tree sidebar types
export interface TreeSubItem {
id: string;
categories: string[];
}
export interface TreeGroup {
id: string;
icon: string;
children: TreeSubItem[];
}
export interface SpecialItem {
id: string;
icon?: string;
iconType?: 'star' | null;
categories?: string[];
}
export interface MenuSection {
id: string;
items: MenuItem[];
export interface SettingsTreeConfig {
specialItems: SpecialItem[];
groups: TreeGroup[];
}
// Sidebar menu configuration
export const MENU_SECTIONS: MenuSection[] = [
{
id: 'main',
items: [
{ id: 'favorites', iconType: 'star' },
{ id: 'branding', iconType: null },
{ id: 'theme', iconType: null },
{ id: 'analytics', iconType: null },
{ id: 'buttons', iconType: null },
],
},
{
id: 'settings',
items: [
{
id: 'payments',
iconType: null,
categories: [
'PAYMENT',
'PAYMENT_VERIFICATION',
'YOOKASSA',
'CRYPTOBOT',
'HELEKET',
'PLATEGA',
'TRIBUTE',
'MULENPAY',
'PAL24',
'WATA',
'TELEGRAM',
],
},
{
id: 'subscriptions',
iconType: null,
categories: [
'SUBSCRIPTIONS_CORE',
'SIMPLE_SUBSCRIPTION',
'PERIODS',
'SUBSCRIPTION_PRICES',
'TRAFFIC',
'TRAFFIC_PACKAGES',
'TRIAL',
'AUTOPAY',
],
},
{
id: 'interface',
iconType: null,
categories: [
'INTERFACE',
'INTERFACE_BRANDING',
'INTERFACE_SUBSCRIPTION',
'CONNECT_BUTTON',
'MINIAPP',
'TELEGRAM_WIDGET',
'TELEGRAM_OIDC',
'HAPP',
'SKIP',
'ADDITIONAL',
],
},
{
id: 'notifications',
iconType: null,
categories: ['NOTIFICATIONS', 'ADMIN_NOTIFICATIONS', 'ADMIN_REPORTS'],
},
{ id: 'database', iconType: null, categories: ['DATABASE', 'POSTGRES', 'SQLITE', 'REDIS'] },
{
id: 'system',
iconType: null,
categories: [
'CORE',
'REMNAWAVE',
'SERVER_STATUS',
'MONITORING',
'MAINTENANCE',
'BACKUP',
'VERSION',
'WEB_API',
'WEBHOOK',
'LOG',
'DEBUG',
'EXTERNAL_ADMIN',
],
},
{
id: 'users',
iconType: null,
categories: ['SUPPORT', 'LOCALIZATION', 'CHANNEL', 'TIMEZONE', 'REFERRAL', 'MODERATION'],
},
],
},
];
// Hierarchical settings tree — all 61 backend category keys mapped into 7 groups
export const SETTINGS_TREE: SettingsTreeConfig = {
specialItems: [
{ id: 'favorites', iconType: 'star' },
{ id: 'branding', icon: '🎨' },
{ id: 'theme', icon: '🌈' },
{ id: 'analytics', icon: '📊' },
{ id: 'buttons', icon: '📱' },
],
groups: [
{
id: 'payments',
icon: '💳',
children: [
{ id: 'payments_general', categories: ['PAYMENT', 'PAYMENT_VERIFICATION'] },
{ id: 'payments_stars', categories: ['TELEGRAM'] },
{ id: 'payments_yookassa', categories: ['YOOKASSA'] },
{ id: 'payments_cryptobot', categories: ['CRYPTOBOT'] },
{ id: 'payments_cloudpayments', categories: ['CLOUDPAYMENTS'] },
{ id: 'payments_freekassa', categories: ['FREEKASSA'] },
{ id: 'payments_kassa_ai', categories: ['KASSA_AI'] },
{ id: 'payments_platega', categories: ['PLATEGA'] },
{ id: 'payments_pal24', categories: ['PAL24'] },
{ id: 'payments_heleket', categories: ['HELEKET'] },
{ id: 'payments_mulenpay', categories: ['MULENPAY'] },
{ id: 'payments_tribute', categories: ['TRIBUTE'] },
{ id: 'payments_wata', categories: ['WATA'] },
{ id: 'payments_riopay', categories: ['RIOPAY'] },
{ id: 'payments_severpay', categories: ['SEVERPAY'] },
],
},
{
id: 'subscriptions',
icon: '📦',
children: [
{ id: 'subs_core', categories: ['SUBSCRIPTIONS_CORE'] },
{ id: 'subs_trial', categories: ['TRIAL'] },
{ id: 'subs_pricing', categories: ['SUBSCRIPTION_PRICES'] },
{ id: 'subs_periods', categories: ['PERIODS'] },
{ id: 'subs_traffic', categories: ['TRAFFIC', 'TRAFFIC_PACKAGES'] },
{ id: 'subs_simple', categories: ['SIMPLE_SUBSCRIPTION'] },
{ id: 'subs_autopay', categories: ['AUTOPAY'] },
],
},
{
id: 'interface',
icon: '🖥️',
children: [
{
id: 'iface_general',
categories: ['INTERFACE', 'INTERFACE_BRANDING', 'INTERFACE_SUBSCRIPTION'],
},
{ id: 'iface_connect', categories: ['CONNECT_BUTTON'] },
{ id: 'iface_miniapp', categories: ['MINIAPP'] },
{ id: 'iface_happ', categories: ['HAPP'] },
{ id: 'iface_widget', categories: ['TELEGRAM_WIDGET'] },
{ id: 'iface_oidc', categories: ['TELEGRAM_OIDC'] },
{ id: 'iface_skip', categories: ['SKIP'] },
{ id: 'iface_additional', categories: ['ADDITIONAL'] },
],
},
{
id: 'users',
icon: '👥',
children: [
{ id: 'users_support', categories: ['SUPPORT'] },
{ id: 'users_referral', categories: ['REFERRAL'] },
{ id: 'users_channel', categories: ['CHANNEL'] },
{ id: 'users_localization', categories: ['LOCALIZATION', 'TIMEZONE'] },
{ id: 'users_moderation', categories: ['MODERATION', 'BAN_NOTIFICATIONS'] },
],
},
{
id: 'notifications',
icon: '🔔',
children: [
{ id: 'notif_user', categories: ['NOTIFICATIONS', 'WEBHOOK_NOTIFICATIONS'] },
{ id: 'notif_admin', categories: ['ADMIN_NOTIFICATIONS'] },
{ id: 'notif_reports', categories: ['ADMIN_REPORTS'] },
],
},
{
id: 'database',
icon: '🗄️',
children: [
{ id: 'db_general', categories: ['DATABASE'] },
{ id: 'db_postgres', categories: ['POSTGRES'] },
{ id: 'db_sqlite', categories: ['SQLITE'] },
{ id: 'db_redis', categories: ['REDIS'] },
],
},
{
id: 'system',
icon: '⚙️',
children: [
{ id: 'sys_core', categories: ['CORE', 'DEBUG'] },
{ id: 'sys_remnawave', categories: ['REMNAWAVE'] },
{ id: 'sys_webapi', categories: ['WEB_API', 'EXTERNAL_ADMIN'] },
{ id: 'sys_webhook', categories: ['WEBHOOK'] },
{ id: 'sys_server', categories: ['SERVER_STATUS'] },
{ id: 'sys_monitoring', categories: ['MONITORING'] },
{ id: 'sys_maintenance', categories: ['MAINTENANCE'] },
{ id: 'sys_backup', categories: ['BACKUP'] },
{ id: 'sys_version', categories: ['VERSION'] },
{ id: 'sys_logging', categories: ['LOG'] },
],
},
],
};
// Helper: find which group and sub-item a backend category key belongs to
export function findTreeLocation(
categoryKey: string,
): { groupId: string; subItemId: string } | null {
for (const group of SETTINGS_TREE.groups) {
for (const child of group.children) {
if (child.categories.includes(categoryKey)) {
return { groupId: group.id, subItemId: child.id };
}
}
}
return null;
}
// Helper: get all backend category keys for a given sub-item id
export function getCategoriesForSubItem(subItemId: string): string[] {
for (const group of SETTINGS_TREE.groups) {
const child = group.children.find((c) => c.id === subItemId);
if (child) return child.categories;
}
return [];
}
// Theme preset type
export interface ThemePreset {