fix: admin UI spacing - reduce container/padding, increase typography

Phase 1: High-impact spacing reductions

- DatabaseManager: space-y-4 md:space-y-5, p-8→p-6, text-xs→text-sm labels
- LdapManager: space-y-3, p-6, py-2→py-1.5 inputs, button heights reduced
- IdentityManager: p-6, space-y-1 user list, modal input py-1.5
- All panels: mb-3 instead of mb-4, gap-3 instead of gap-4
- Button heights: py-4→py-2.5 (Export), py-3→py-2 (LDAP buttons)
- Input padding: py-2→py-1.5, py-3→py-1.5 for better density

Tests: 291/291 passing, Build: success, zero TypeScript errors
Estimated ~80-100px vertical savings across admin dashboard
This commit is contained in:
2026-04-19 18:55:20 +03:00
parent 7eafd45ab1
commit c4c36dc6b6
5 changed files with 368 additions and 44 deletions

View File

@@ -34,9 +34,9 @@ export default function DatabaseManager({
};
return (
<div className="space-y-4 md:space-y-5 h-full">
<div className="space-y-3 md:space-y-4 h-full">
<div data-testid="database-info" className="bg-surface/50 border border-slate-800/50 rounded-[2.5rem] p-4 md:p-6 shadow-2xl overflow-hidden relative group transition-all">
<div className="flex items-center gap-4 mb-4">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary border border-primary/20">
<Database size={20} />
</div>
@@ -70,9 +70,9 @@ export default function DatabaseManager({
</div>
</div>
<div className="bg-surface/50 border border-slate-800/50 rounded-[2.5rem] p-4 md:p-6 shadow-2xl space-y-5">
<div className="space-y-4">
<div className="flex items-center gap-4">
<div className="bg-surface/50 border border-slate-800/50 rounded-[2.5rem] p-4 md:p-6 shadow-2xl space-y-4">
<div className="space-y-3">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary border border-primary/20">
<History size={20} />
</div>
@@ -83,19 +83,19 @@ export default function DatabaseManager({
</div>
<div className="grid sm:grid-cols-3 gap-3">
<div className="space-y-1.5">
<label className="text-xs font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<div className="space-y-1">
<label className="text-sm font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<History size={10} /> Max Backups
</label>
<input
type="number"
value={dbSettings.retention_count}
onChange={(e) => onUpdateDbSettings({...dbSettings, retention_count: parseInt(e.target.value)})}
className="w-full bg-background/80 border border-slate-800 rounded-xl py-2 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
className="w-full bg-background/80 border border-slate-800 rounded-xl py-1.5 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<div className="space-y-1">
<label className="text-sm font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<Clock size={10} /> Schedule (Hour)
</label>
<input
@@ -103,11 +103,11 @@ export default function DatabaseManager({
min="0" max="23"
value={dbSettings.schedule_hour}
onChange={(e) => onUpdateDbSettings({...dbSettings, schedule_hour: parseInt(e.target.value)})}
className="w-full bg-background/80 border border-slate-800 rounded-xl py-2 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
className="w-full bg-background/80 border border-slate-800 rounded-xl py-1.5 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
/>
</div>
<div className="space-y-2">
<label className="text-xs font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<div className="space-y-1">
<label className="text-sm font-normal text-muted tracking-tight ml-1 flex items-center gap-2">
<Zap size={10} /> Frequency (Days)
</label>
<input
@@ -115,23 +115,23 @@ export default function DatabaseManager({
min="1"
value={dbSettings.schedule_freq_days}
onChange={(e) => onUpdateDbSettings({...dbSettings, schedule_freq_days: parseInt(e.target.value)})}
className="w-full bg-background/80 border border-slate-800 rounded-xl py-2 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
className="w-full bg-background/80 border border-slate-800 rounded-xl py-1.5 px-4 text-xs font-normal text-white outline-none focus:border-primary/50 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none transition-all tabular-nums"
/>
</div>
</div>
</div>
<div className="space-y-3">
<div className="space-y-2">
<div className="flex items-center justify-between px-1">
<label className="text-xs font-normal text-muted tracking-tight">Recovery Points</label>
<label className="text-sm font-normal text-muted tracking-tight">Recovery Points</label>
<div className="text-xs font-normal text-primary tracking-tight bg-primary/5 px-3 py-1 rounded-full border border-primary/10">
{formatSize(dbStats.total_size_bytes)} Used
</div>
</div>
<div className="space-y-1.5 pr-2 overflow-y-auto max-h-[300px] scrollbar-thin scrollbar-thumb-slate-800 scrollbar-track-transparent">
<div className="space-y-1 pr-2 overflow-y-auto max-h-[300px] scrollbar-thin scrollbar-thumb-slate-800 scrollbar-track-transparent">
{backups.map((bak: any) => (
<div key={bak.filename} className="flex items-center justify-between p-3.5 bg-background/40 border border-slate-800/40 rounded-2xl group/item hover:border-primary/30 transition-all">
<div key={bak.filename} className="flex items-center justify-between p-3 bg-background/40 border border-slate-800/40 rounded-2xl group/item hover:border-primary/30 transition-all">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-lg bg-slate-800 flex items-center justify-center text-muted">
<Database size={14} />
@@ -155,23 +155,23 @@ export default function DatabaseManager({
</div>
</div>
<div className="grid grid-cols-2 gap-4 pt-2">
<div className="grid grid-cols-2 gap-3 pt-1">
<button
onClick={onExport}
className="flex items-center justify-center gap-2 py-3 bg-background border border-slate-800 hover:border-primary/50 text-primary rounded-2xl text-sm font-normal transition-all active:scale-95 tracking-tight shadow-xl shadow-black/20 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none"
className="flex items-center justify-center gap-2 py-2.5 bg-background border border-slate-800 hover:border-primary/50 text-primary rounded-2xl text-sm font-normal transition-all active:scale-95 tracking-tight shadow-xl shadow-black/20 focus-visible:ring-2 focus-visible:ring-primary focus-visible:outline-none"
aria-label="Export database"
>
<Download size={14} /> Export Database
</button>
<div className="relative">
<input
type="file"
<input
type="file"
accept=".db"
onChange={onImport}
className="absolute inset-0 opacity-0 cursor-pointer z-10"
/>
<button
className="w-full flex items-center justify-center gap-2 py-4 bg-background border border-slate-800 hover:border-rose-500/50 text-rose-500 rounded-2xl text-sm font-normal transition-all tracking-tight shadow-xl shadow-black/20 focus-visible:ring-2 focus-visible:ring-rose-500 focus-visible:outline-none"
className="w-full flex items-center justify-center gap-2 py-2.5 bg-background border border-slate-800 hover:border-rose-500/50 text-rose-500 rounded-2xl text-sm font-normal transition-all tracking-tight shadow-xl shadow-black/20 focus-visible:ring-2 focus-visible:ring-rose-500 focus-visible:outline-none"
aria-label="Import database"
>
<Upload size={14} /> Import Database