mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-05 06:50:10 +00:00
feat(settings): move device management into settings
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { ArrowUpDown, Check, ChevronDown, Clock3, Cloud, FileClock, Folder as FolderIcon, Globe2, KeyRound, Lock, LogOut, MonitorSmartphone, Send as SendIcon, Settings as SettingsIcon, ShieldUser, SlidersHorizontal, Users } from 'lucide-preact';
|
import { ArrowUpDown, Check, ChevronDown, Clock3, Cloud, FileClock, Folder as FolderIcon, KeyRound, Lock, LogOut, MonitorSmartphone, Send as SendIcon, Settings as SettingsIcon, ShieldUser, SlidersHorizontal, Users } from 'lucide-preact';
|
||||||
import type { ComponentChildren } from 'preact';
|
import type { ComponentChildren } from 'preact';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { Link } from 'wouter';
|
import { Link } from 'wouter';
|
||||||
@@ -57,7 +57,8 @@ export default function AppAuthenticatedShell(props: AppAuthenticatedShellProps)
|
|||||||
const isAdmin = isAdminProfile(props.profile);
|
const isAdmin = isAdminProfile(props.profile);
|
||||||
const vaultActive = props.location === '/vault' || props.location === '/vault/totp';
|
const vaultActive = props.location === '/vault' || props.location === '/vault/totp';
|
||||||
const deviceManagementActive = props.location === DEVICE_MANAGEMENT_ROUTE || props.location === LEGACY_DEVICE_MANAGEMENT_ROUTE;
|
const deviceManagementActive = props.location === DEVICE_MANAGEMENT_ROUTE || props.location === LEGACY_DEVICE_MANAGEMENT_ROUTE;
|
||||||
const settingsActive = props.location === props.settingsAccountRoute || props.location === '/settings/domain-rules' || deviceManagementActive;
|
const settingsActive = props.location === '/settings' || props.location === props.settingsAccountRoute || props.location === '/settings/domain-rules' || deviceManagementActive;
|
||||||
|
const flatSettingsActive = settingsActive && !deviceManagementActive;
|
||||||
const dataActive = props.location === '/backup' || props.isImportRoute;
|
const dataActive = props.location === '/backup' || props.isImportRoute;
|
||||||
const managementActive = props.location === '/admin' || props.location === '/logs';
|
const managementActive = props.location === '/admin' || props.location === '/logs';
|
||||||
const [navLayoutMode, setNavLayoutMode] = useState<NavLayoutMode>(readNavLayoutMode);
|
const [navLayoutMode, setNavLayoutMode] = useState<NavLayoutMode>(readNavLayoutMode);
|
||||||
@@ -175,8 +176,7 @@ export default function AppAuthenticatedShell(props: AppAuthenticatedShellProps)
|
|||||||
{renderSideLink('/vault', props.location === '/vault', <KeyRound size={16} />, t('nav_vault_items'))}
|
{renderSideLink('/vault', props.location === '/vault', <KeyRound size={16} />, t('nav_vault_items'))}
|
||||||
{renderSideLink('/vault/totp', props.location === '/vault/totp', <Clock3 size={16} />, t('txt_verification_code'))}
|
{renderSideLink('/vault/totp', props.location === '/vault/totp', <Clock3 size={16} />, t('txt_verification_code'))}
|
||||||
{renderSideLink('/sends', props.location === '/sends', <SendIcon size={16} />, t('nav_sends'))}
|
{renderSideLink('/sends', props.location === '/sends', <SendIcon size={16} />, t('nav_sends'))}
|
||||||
{renderSideLink(props.settingsAccountRoute, props.location === props.settingsAccountRoute, <SettingsIcon size={16} />, t('nav_account_settings'))}
|
{renderSideLink('/settings', flatSettingsActive, <SettingsIcon size={16} />, t('txt_settings'))}
|
||||||
{renderSideLink('/settings/domain-rules', props.location === '/settings/domain-rules', <Globe2 size={16} />, t('nav_domain_rules'))}
|
|
||||||
{renderSideLink(DEVICE_MANAGEMENT_ROUTE, deviceManagementActive, <MonitorSmartphone size={16} />, t('nav_device_management'))}
|
{renderSideLink(DEVICE_MANAGEMENT_ROUTE, deviceManagementActive, <MonitorSmartphone size={16} />, t('nav_device_management'))}
|
||||||
{isAdmin && renderSideLink('/backup', props.location === '/backup', <Cloud size={16} />, t('nav_backup_strategy'))}
|
{isAdmin && renderSideLink('/backup', props.location === '/backup', <Cloud size={16} />, t('nav_backup_strategy'))}
|
||||||
{renderSideLink(props.importRoute, props.isImportRoute, <ArrowUpDown size={16} />, t('nav_import_export'))}
|
{renderSideLink(props.importRoute, props.isImportRoute, <ArrowUpDown size={16} />, t('nav_import_export'))}
|
||||||
|
|||||||
@@ -320,43 +320,55 @@ export default function AppMainRoutes(props: AppMainRoutesProps) {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route path="/settings">
|
<Route path="/settings">
|
||||||
{props.profile ? (
|
{props.profile ? (
|
||||||
<section className="card mobile-settings-card">
|
<section className="card mobile-settings-card settings-home-card">
|
||||||
<div className="mobile-settings-links">
|
<div className="settings-home-section">
|
||||||
<Link href={props.settingsAccountRoute} className="mobile-settings-link">
|
<h3>{t('txt_settings')}</h3>
|
||||||
<SettingsIcon size={18} />
|
<div className="mobile-settings-links">
|
||||||
<span>{t('nav_account_settings')}</span>
|
<Link href={props.settingsAccountRoute} className="mobile-settings-link">
|
||||||
</Link>
|
<SettingsIcon size={18} />
|
||||||
<Link href="/settings/security/device-management" className="mobile-settings-link">
|
<span>{t('nav_account_settings')}</span>
|
||||||
<Shield size={18} />
|
|
||||||
<span>{t('nav_device_management')}</span>
|
|
||||||
</Link>
|
|
||||||
<Link href="/settings/domain-rules" className="mobile-settings-link">
|
|
||||||
<Globe2 size={18} />
|
|
||||||
<span>{t('nav_domain_rules')}</span>
|
|
||||||
</Link>
|
|
||||||
<Link href={props.importRoute} className="mobile-settings-link">
|
|
||||||
<ArrowUpDown size={18} />
|
|
||||||
<span>{t('nav_import_export')}</span>
|
|
||||||
</Link>
|
|
||||||
{isAdmin && (
|
|
||||||
<Link href="/admin" className="mobile-settings-link">
|
|
||||||
<ShieldUser size={18} />
|
|
||||||
<span>{t('nav_admin_panel')}</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
<Link href="/settings/security/device-management" className="mobile-settings-link">
|
||||||
{isAdmin && (
|
<Shield size={18} />
|
||||||
<Link href="/logs" className="mobile-settings-link">
|
<span>{t('nav_device_management')}</span>
|
||||||
<FileClock size={18} />
|
|
||||||
<span>{t('nav_log_center')}</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
<Link href="/settings/domain-rules" className="mobile-settings-link">
|
||||||
{isAdmin && (
|
<Globe2 size={18} />
|
||||||
<Link href="/backup" className="mobile-settings-link">
|
<span>{t('nav_domain_rules')}</span>
|
||||||
<Cloud size={18} />
|
|
||||||
<span>{t('nav_backup_strategy')}</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="settings-home-section">
|
||||||
|
<h3>{t('nav_group_data_backup')}</h3>
|
||||||
|
<div className="mobile-settings-links">
|
||||||
|
<Link href={props.importRoute} className="mobile-settings-link">
|
||||||
|
<ArrowUpDown size={18} />
|
||||||
|
<span>{t('nav_import_export')}</span>
|
||||||
|
</Link>
|
||||||
|
{isAdmin && (
|
||||||
|
<Link href="/backup" className="mobile-settings-link">
|
||||||
|
<Cloud size={18} />
|
||||||
|
<span>{t('nav_backup_strategy')}</span>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isAdmin && (
|
||||||
|
<div className="settings-home-section">
|
||||||
|
<h3>{t('nav_group_management')}</h3>
|
||||||
|
<div className="mobile-settings-links">
|
||||||
|
<Link href="/admin" className="mobile-settings-link">
|
||||||
|
<ShieldUser size={18} />
|
||||||
|
<span>{t('nav_admin_panel')}</span>
|
||||||
|
</Link>
|
||||||
|
<Link href="/logs" className="mobile-settings-link">
|
||||||
|
<FileClock size={18} />
|
||||||
|
<span>{t('nav_log_center')}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="settings-home-spacer" />
|
||||||
<button type="button" className="btn btn-secondary mobile-settings-logout" onClick={props.onLogout}>
|
<button type="button" className="btn btn-secondary mobile-settings-logout" onClick={props.onLogout}>
|
||||||
<LogOut size={14} className="btn-icon" />
|
<LogOut size={14} className="btn-icon" />
|
||||||
{t('txt_sign_out')}
|
{t('txt_sign_out')}
|
||||||
|
|||||||
@@ -424,6 +424,48 @@ h4 {
|
|||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-home-card {
|
||||||
|
min-height: min(640px, calc(100dvh - 180px));
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-home-section {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-home-section h3 {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text);
|
||||||
|
font-size: var(--font-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-home-spacer {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-settings-links {
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-settings-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
min-height: 46px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
color: var(--text);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
.auth-card h1,
|
.auth-card h1,
|
||||||
.standalone-title {
|
.standalone-title {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
|
|||||||
Reference in New Issue
Block a user