Files
vibe-kanban/frontend/src/pages/settings/SettingsLayout.tsx
Alex Netsch 1dc46d869b Close settings X (vibe-kanban) (#1012)
* Excellent! All changes have been successfully implemented. Here's a summary of what was done:

## Changes Made

### 1. **Updated SettingsLayout.tsx** (`frontend/src/pages/settings/SettingsLayout.tsx:33-46`)
   - Changed import from `ArrowLeft` to `X` icon from lucide-react
   - Moved the close button from the left side to the right side within a flex container
   - Replaced the "Back to app" button with an icon-only X button
   - Applied consistent styling matching the dialog component pattern (opacity, hover effects, focus ring)
   - Added screen reader text "Close" for accessibility

### 2. **Removed unused translation keys** from all locale files:
   - `frontend/src/i18n/locales/en/settings.json`
   - `frontend/src/i18n/locales/es/settings.json`
   - `frontend/src/i18n/locales/ja/settings.json`
   - `frontend/src/i18n/locales/ko/settings.json`

   Removed the `"backToApp"` key since it's no longer needed.

The settings page now has an X button in the top right corner (next to the "Settings" title) instead of a "Back to app" button in the top left, matching the standard UX pattern used throughout the application.

* Perfect! I've successfully moved the X button to the absolute top right of the settings page. Here's what changed:

## Changes Made

**Updated SettingsLayout.tsx** (`frontend/src/pages/settings/SettingsLayout.tsx:28-44`)

1. Added `relative` positioning to the main container div
2. Moved the X button outside of the sidebar, placing it as an absolutely positioned element at `top-4 right-4`
3. Simplified the sidebar header - the "Settings" title now stands alone without the flex container
4. The X button now appears in the top right corner of the entire settings page, independent of the sidebar layout

The X button is now positioned at the absolute top right of the settings page container, exactly where you'd expect a close button to be in most applications!

* Perfect! I've made the adjustment to move the X button to the absolute top right of the settings page. Here's what I changed:

## Changes Made

**Updated SettingsLayout.tsx** (`frontend/src/pages/settings/SettingsLayout.tsx:29-37`)

1. Changed `top-4` to `top-0` - This positions the button at the very top edge of the container, right below the navbar
2. Added `z-10` - Ensures the button appears above other content and doesn't get hidden

The X button is now positioned at the absolute top right corner of the settings page container (just below the navbar), which should provide better visual separation from the hamburger menu and look cleaner overall. The button will be at the top edge of the settings content area without the extra spacing that was causing the cramped appearance.

* I've adjusted the X button positioning from `top-0` to `top-2`, which adds 0.5rem (8px) of spacing. This should create a bit more breathing room between the navbar hamburger menu and the X button.

However, looking at the screenshot you shared, it seems like we may need even more spacing. If this still looks too cramped, we could increase it to `top-4` (16px), `top-6` (24px), or even `top-8` (32px) to match the vertical padding of the container.

Could you check if this looks better? If it still needs more spacing, let me know and I can adjust it further.

* Revert "I've adjusted the X button positioning from `top-0` to `top-2`, which adds 0.5rem (8px) of spacing. This should create a bit more breathing room between the navbar hamburger menu and the X button."

This reverts commit e2d5617562e23edbfb25d7514f5a8758ba501eb1.

* Perfect! I've adjusted the X button positioning from `right-4` to `right-3` to match the navbar's `px-3` padding.

## Changes Made

**Updated SettingsLayout.tsx** (`frontend/src/pages/settings/SettingsLayout.tsx:33`)

Changed the X button's horizontal positioning from `right-4` (16px) to `right-3` (12px) to match the navbar's padding, ensuring the X button is now vertically aligned with the hamburger menu icon above it.

The X button should now be perfectly aligned with the hamburger menu in the navbar! Both icons are now 12px from the right edge of their respective containers.

* Perfect! I've successfully fixed the i18n regression. Here's a summary of what was done:

## Changes Made

### 1. Added "close" translation to all locale files

**en/common.json**: Added `"close": "Close"`
**es/common.json**: Added `"close": "Cerrar"`
**ja/common.json**: Added `"close": "閉じる"`
**ko/common.json**: Added `"close": "닫기"`

All added to the `buttons` section to maintain consistency with other button translations.

### 2. Updated SettingsLayout.tsx (`frontend/src/pages/settings/SettingsLayout.tsx:25,37`)

- Added a second translation hook: `const { t: tCommon } = useTranslation('common');`
- Changed the hardcoded text from `<span className="sr-only">Close</span>` to `<span className="sr-only">{tCommon('buttons.close')}</span>`

Now the close button's accessibility label will be properly translated based on the user's language preference, maintaining consistency with the rest of the application's i18n implementation!

* new settings close button (vibe-kanban) (#1018)

adds an esc button to settings in a new sticky header

* Lint

---------

Co-authored-by: Britannio Jarrett <britanniojarrett@gmail.com>
Co-authored-by: Britannio Jarrett <33752528+britannio@users.noreply.github.com>
2025-10-15 17:27:25 +01:00

103 lines
3.4 KiB
TypeScript

import { NavLink, Outlet } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Settings, Cpu, Server, X } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { usePreviousPath } from '@/hooks/usePreviousPath';
import { useEffect } from 'react';
import { useHotkeysContext } from 'react-hotkeys-hook';
import { useKeyExit } from '@/keyboard/hooks';
import { Scope } from '@/keyboard/registry';
const settingsNavigation = [
{
path: 'general',
icon: Settings,
},
{
path: 'agents',
icon: Cpu,
},
{
path: 'mcp',
icon: Server,
},
];
export function SettingsLayout() {
const { t } = useTranslation('settings');
const goToPreviousPath = usePreviousPath();
const { enableScope, disableScope } = useHotkeysContext();
// Enable SETTINGS scope when component mounts
useEffect(() => {
enableScope(Scope.SETTINGS);
return () => {
disableScope(Scope.SETTINGS);
};
}, [enableScope, disableScope]);
// Register ESC keyboard shortcut
useKeyExit(goToPreviousPath, { scope: Scope.SETTINGS });
return (
<div className="container mx-auto">
{/* Header with title and close button */}
<div className="flex items-center justify-between sticky top-0 bg-background z-10 py-4 -mx-4 px-4">
<h1 className="text-2xl font-semibold">
{t('settings.layout.nav.title')}
</h1>
<Button
variant="ghost"
onClick={goToPreviousPath}
className="h-8 px-2 rounded-none border border-foreground/20 hover:border-foreground/30 transition-all hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 flex items-center gap-1.5"
>
<X className="h-4 w-4" />
<span className="text-xs font-medium">ESC</span>
</Button>
</div>
<div className="flex flex-col lg:flex-row gap-8">
{/* Sidebar Navigation */}
<aside className="w-full lg:w-64 lg:shrink-0 lg:sticky lg:top-24 lg:h-fit lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto">
<div className="space-y-1">
<nav className="space-y-1">
{settingsNavigation.map((item) => {
const Icon = item.icon;
return (
<NavLink
key={item.path}
to={item.path}
end
className={({ isActive }) =>
cn(
'flex items-start gap-3 px-3 py-2 text-sm transition-colors',
'hover:text-accent-foreground',
isActive
? 'text-primary-foreground'
: 'text-secondary-foreground'
)
}
>
<Icon className="h-4 w-4 mt-0.5 shrink-0" />
<div className="flex-1 min-w-0">
<div className="font-medium">
{t(`settings.layout.nav.${item.path}`)}
</div>
<div>{t(`settings.layout.nav.${item.path}Desc`)}</div>
</div>
</NavLink>
);
})}
</nav>
</div>
</aside>
{/* Main Content */}
<main className="flex-1 min-w-0">
<Outlet />
</main>
</div>
</div>
);
}