mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
fix: mobile layout and touch target improvements for admin settings
- SettingsTableRow: stack name above controls on mobile, show action buttons without hover (max-lg:opacity-100) - SettingsMobileTabs: increase touch targets to 44px, add scroll spacers - QuickToggles: increase chip touch targets - SettingInput: increase display button touch target - AdminSettings: add bottom padding buffer to mobile layout
This commit is contained in:
@@ -39,7 +39,7 @@ export function QuickToggles({ settings, onUpdate, disabled, className }: QuickT
|
|||||||
onClick={() => onUpdate(setting.key, isOn ? 'false' : 'true')}
|
onClick={() => onUpdate(setting.key, isOn ? 'false' : 'true')}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex items-center gap-2 rounded-lg border px-2.5 py-1.5 text-xs font-medium transition-all',
|
'flex items-center gap-2 rounded-lg border px-2.5 py-2.5 text-xs font-medium transition-all',
|
||||||
isOn
|
isOn
|
||||||
? 'border-success-500/20 bg-success-500/[0.08] text-dark-100'
|
? 'border-success-500/20 bg-success-500/[0.08] text-dark-100'
|
||||||
: 'border-dark-600/50 bg-dark-700/20 text-dark-400',
|
: 'border-dark-600/50 bg-dark-700/20 text-dark-400',
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ export function SettingInput({ setting, onUpdate, disabled }: SettingInputProps)
|
|||||||
<button
|
<button
|
||||||
onClick={handleStart}
|
onClick={handleStart}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
className="group flex min-w-[100px] max-w-[200px] items-center gap-2 truncate rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-left font-mono text-sm text-dark-200 transition-colors hover:border-dark-500 hover:bg-dark-600 disabled:opacity-50"
|
className="group flex min-w-[100px] max-w-[200px] items-center gap-2 truncate rounded-lg border border-dark-600 bg-dark-700 px-3 py-2.5 text-left font-mono text-sm text-dark-200 transition-colors hover:border-dark-500 hover:bg-dark-600 disabled:opacity-50"
|
||||||
>
|
>
|
||||||
<span className="flex-1 truncate">{currentValue || '-'}</span>
|
<span className="flex-1 truncate">{currentValue || '-'}</span>
|
||||||
<span className="text-dark-500 opacity-0 transition-colors group-hover:text-accent-400 group-hover:opacity-100">
|
<span className="text-dark-500 opacity-0 transition-colors group-hover:text-accent-400 group-hover:opacity-100">
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export function SettingsMobileTabs({
|
|||||||
setActiveSection('favorites');
|
setActiveSection('favorites');
|
||||||
setExpandedGroup(null);
|
setExpandedGroup(null);
|
||||||
}}
|
}}
|
||||||
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${
|
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-3 text-sm font-medium transition-all ${
|
||||||
isFavoritesActive
|
isFavoritesActive
|
||||||
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
||||||
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
||||||
@@ -116,7 +116,7 @@ export function SettingsMobileTabs({
|
|||||||
setActiveSection(item.id);
|
setActiveSection(item.id);
|
||||||
setExpandedGroup(null);
|
setExpandedGroup(null);
|
||||||
}}
|
}}
|
||||||
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${
|
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-3 text-sm font-medium transition-all ${
|
||||||
isActive
|
isActive
|
||||||
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
||||||
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
||||||
@@ -137,7 +137,7 @@ export function SettingsMobileTabs({
|
|||||||
key={group.id}
|
key={group.id}
|
||||||
ref={hasActiveChild ? activeRef : null}
|
ref={hasActiveChild ? activeRef : null}
|
||||||
onClick={() => handleGroupTap(group.id)}
|
onClick={() => handleGroupTap(group.id)}
|
||||||
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${
|
className={`flex shrink-0 items-center gap-2 rounded-xl px-4 py-3 text-sm font-medium transition-all ${
|
||||||
hasActiveChild || isExpanded
|
hasActiveChild || isExpanded
|
||||||
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
? 'bg-accent-500/15 text-accent-400 ring-1 ring-accent-500/30'
|
||||||
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
||||||
@@ -148,6 +148,7 @@ export function SettingsMobileTabs({
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
<div className="w-3 shrink-0" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Level 2: Sub-item chips (shown when a group is expanded) */}
|
{/* Level 2: Sub-item chips (shown when a group is expanded) */}
|
||||||
@@ -164,7 +165,7 @@ export function SettingsMobileTabs({
|
|||||||
<button
|
<button
|
||||||
key={child.id}
|
key={child.id}
|
||||||
onClick={() => setActiveSection(child.id)}
|
onClick={() => setActiveSection(child.id)}
|
||||||
className={`shrink-0 rounded-lg px-3 py-1.5 text-xs font-medium transition-all ${
|
className={`shrink-0 rounded-lg px-3 py-2.5 text-sm font-medium transition-all ${
|
||||||
isActive
|
isActive
|
||||||
? 'bg-accent-500/10 text-accent-400 ring-1 ring-accent-500/20'
|
? 'bg-accent-500/10 text-accent-400 ring-1 ring-accent-500/20'
|
||||||
: 'bg-dark-800/30 text-dark-500 active:bg-dark-700'
|
: 'bg-dark-800/30 text-dark-500 active:bg-dark-700'
|
||||||
@@ -174,6 +175,7 @@ export function SettingsMobileTabs({
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
<div className="w-3 shrink-0" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,9 +67,13 @@ export function SettingsTableRow({
|
|||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={cn(isLongValue ? 'space-y-3' : 'flex items-center gap-4')}>
|
<div
|
||||||
|
className={cn(
|
||||||
|
isLongValue ? 'space-y-3' : 'flex flex-col gap-2 lg:flex-row lg:items-center lg:gap-4',
|
||||||
|
)}
|
||||||
|
>
|
||||||
{/* Left side: name, badges, key */}
|
{/* Left side: name, badges, key */}
|
||||||
<div className={cn('min-w-0', !isLongValue && 'flex-1')}>
|
<div className={cn('min-w-0', !isLongValue && 'lg:flex-1')}>
|
||||||
{/* Name + badges row */}
|
{/* Name + badges row */}
|
||||||
<div className="flex flex-wrap items-center gap-1.5">
|
<div className="flex flex-wrap items-center gap-1.5">
|
||||||
<span className="text-[13px] font-medium text-dark-100">{displayName}</span>
|
<span className="text-[13px] font-medium text-dark-100">{displayName}</span>
|
||||||
@@ -106,7 +110,12 @@ export function SettingsTableRow({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right side: control + action buttons */}
|
{/* Right side: control + action buttons */}
|
||||||
<div className={cn('flex items-center gap-2', isLongValue ? 'w-full' : 'flex-shrink-0')}>
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex items-center gap-2',
|
||||||
|
isLongValue ? 'w-full' : 'self-end lg:flex-shrink-0',
|
||||||
|
)}
|
||||||
|
>
|
||||||
{setting.read_only ? (
|
{setting.read_only ? (
|
||||||
<span className="max-w-[240px] truncate rounded bg-dark-700/30 px-3 py-1.5 font-mono text-xs text-dark-400">
|
<span className="max-w-[240px] truncate rounded bg-dark-700/30 px-3 py-1.5 font-mono text-xs text-dark-400">
|
||||||
{isBool
|
{isBool
|
||||||
@@ -133,7 +142,7 @@ export function SettingsTableRow({
|
|||||||
<button
|
<button
|
||||||
onClick={onReset}
|
onClick={onReset}
|
||||||
disabled={isResetting}
|
disabled={isResetting}
|
||||||
className="flex-shrink-0 rounded-lg p-1.5 text-dark-500 opacity-0 transition-all hover:bg-dark-700 hover:text-dark-200 disabled:opacity-50 group-hover:opacity-100"
|
className="flex-shrink-0 rounded-lg p-1.5 text-dark-500 opacity-0 transition-all hover:bg-dark-700 hover:text-dark-200 disabled:opacity-50 group-hover:opacity-100 max-lg:opacity-100"
|
||||||
title={t('admin.settings.reset')}
|
title={t('admin.settings.reset')}
|
||||||
aria-label={t('admin.settings.reset')}
|
aria-label={t('admin.settings.reset')}
|
||||||
>
|
>
|
||||||
@@ -148,7 +157,7 @@ export function SettingsTableRow({
|
|||||||
'flex-shrink-0 rounded-lg p-1.5 transition-all',
|
'flex-shrink-0 rounded-lg p-1.5 transition-all',
|
||||||
isFavorite
|
isFavorite
|
||||||
? 'text-warning-400 hover:bg-warning-500/15'
|
? 'text-warning-400 hover:bg-warning-500/15'
|
||||||
: 'text-dark-500 opacity-0 hover:bg-dark-700/50 hover:text-warning-400 group-hover:opacity-100',
|
: 'text-dark-500 opacity-0 hover:bg-dark-700/50 hover:text-warning-400 group-hover:opacity-100 max-lg:opacity-100',
|
||||||
)}
|
)}
|
||||||
title={
|
title={
|
||||||
isFavorite
|
isFavorite
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export default function AdminSettings() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Mobile Layout */}
|
{/* Mobile Layout */}
|
||||||
<div className="space-y-4 lg:hidden">
|
<div className="space-y-4 pb-4 lg:hidden">
|
||||||
<SettingsMobileTabs
|
<SettingsMobileTabs
|
||||||
activeSection={activeSection}
|
activeSection={activeSection}
|
||||||
setActiveSection={setActiveSection}
|
setActiveSection={setActiveSection}
|
||||||
|
|||||||
Reference in New Issue
Block a user