Keep/_bmad-output/implementation-artifacts/11-2-improve-settings-ux.md

20 KiB

Story 11.2: Improve Settings Configuration UX

Status: review

Story

As a user, I want an intuitive and easy-to-use settings interface, so that I can configure the application according to my preferences.

Acceptance Criteria

  1. Given a user wants to configure application settings,
  2. When the user accesses the settings page,
  3. Then the system should:
    • Display settings in an organized, logical manner
    • Make settings easy to find and understand
    • Provide clear labels and descriptions for each setting
    • Save changes immediately with visual feedback
    • Work smoothly on both desktop and mobile

Tasks / Subtasks

  • Audit current settings implementation
    • Document all existing settings
    • Identify settings UI issues
    • Check if settings are properly grouped
    • Test on mobile and desktop
  • Redesign settings page layout
    • Create clear sections/groups for settings
    • Add sidebar navigation for settings sections
    • Implement search/filter for settings
    • Add breadcrumbs for navigation
    • Ensure responsive design for mobile
  • Improve individual setting components
    • Use appropriate input types (toggle, select, text, etc.)
    • Add clear labels and descriptions
    • Show current values clearly
    • Add visual feedback on save
    • Handle errors gracefully
  • Organize settings logically
    • General settings (theme, language, etc.)
    • AI settings (provider, features, etc.)
    • Account settings (profile, security, etc.)
    • Data management (export, sync, etc.)
    • About & help
  • Test settings across devices
    • Desktop settings UX
    • Mobile settings UX
    • Settings persistence
    • Settings validation

Dev Notes

Settings Audit

Current Settings (Likely):

  1. AI Provider Settings

    • Provider selection (OpenAI, Ollama)
    • API keys
    • Model selection
  2. AI Feature Toggles

    • Title suggestions (on/off)
    • Semantic search (on/off)
    • Auto-labeling (on/off)
    • Memory Echo (on/off)
  3. Appearance

    • Dark/light mode
    • Theme color
    • Font size
  4. Account

    • Profile information
    • Email/password
    • Delete account
  5. Data

    • Export notes
    • Import notes
    • Sync settings

Proposed Settings Layout

Desktop Layout:

┌────────────────────────────────────────────────────┐
│ Settings                                          │
├────────────┬───────────────────────────────────────┤
│            │                                       │
│ General    │ 🎨 Appearance                        │
│ AI         │ Theme: [Dark ▼]                      │
│ Appearance │ Font size: [Medium ▼]                │
│ Account    │                                       │
│ Data       │ 💾 Save                              │
│            │                                       │
│            │ [✓] Settings saved                   │
└────────────┴───────────────────────────────────────┘

Mobile Layout:

┌─────────────────────┐
│ ⚙️ Settings         │
├─────────────────────┤
│                     │
│ General      →      │
│ AI           →      │
│ Appearance   →      │
│ Account      →      │
│ Data         →      │
│                     │
└─────────────────────┘

OR (accordion style):

┌─────────────────────┐
│ ⚙️ Settings         │
├─────────────────────┤
│ ▼ General           │
│   Theme: Dark       │
│   Language: EN      │
├─────────────────────┤
│ ▶ AI                │
├─────────────────────┤
│ ▶ Appearance        │
└─────────────────────┘

Component Examples

Settings Page Structure:

// keep-notes/app/settings/page.tsx
export default function SettingsPage() {
  return (
    <div className="max-w-6xl mx-auto p-6">
      <h1 className="text-3xl font-bold mb-6">Settings</h1>

      <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
        {/* Sidebar Navigation */}
        <SettingsNav />

        {/* Settings Content */}
        <div className="lg:col-span-3">
          <SettingsContent />
        </div>
      </div>
    </div>
  )
}

// keep-notes/components/settings/SettingsNav.tsx
function SettingsNav() {
  const sections = [
    { id: 'general', label: 'General', icon: '⚙️' },
    { id: 'ai', label: 'AI', icon: '🤖' },
    { id: 'appearance', label: 'Appearance', icon: '🎨' },
    { id: 'account', label: 'Account', icon: '👤' },
    { id: 'data', label: 'Data', icon: '💾' },
  ]

  return (
    <nav className="space-y-1">
      {sections.map(section => (
        <a
          key={section.id}
          href={`#${section.id}`}
          className="flex items-center gap-3 px-4 py-3 rounded-lg hover:bg-gray-100"
        >
          <span className="text-xl">{section.icon}</span>
          <span className="font-medium">{section.label}</span>
        </a>
      ))}
    </nav>
  )
}

Setting Item Components:

Toggle Switch:

// keep-notes/components/settings/SettingToggle.tsx
export function SettingToggle({
  label,
  description,
  checked,
  onChange,
}: SettingToggleProps) {
  return (
    <div className="flex items-center justify-between py-4">
      <div className="flex-1">
        <label className="font-medium text-gray-900">{label}</label>
        {description && (
          <p className="text-sm text-gray-600 mt-1">{description}</p>
        )}
      </div>
      <button
        onClick={() => onChange(!checked)}
        className={`
          relative inline-flex h-6 w-11 items-center rounded-full
          transition-colors duration-200 ease-in-out
          ${checked ? 'bg-primary-600' : 'bg-gray-200'}
        `}
        role="switch"
        aria-checked={checked}
      >
        <span
          className={`
            inline-block h-4 w-4 transform rounded-full bg-white
            transition-transform duration-200 ease-in-out
            ${checked ? 'translate-x-6' : 'translate-x-1'}
          `}
        />
      </button>
    </div>
  )
}

Select Dropdown:

// keep-notes/components/settings/SettingSelect.tsx
export function SettingSelect({
  label,
  description,
  value,
  options,
  onChange,
}: SettingSelectProps) {
  return (
    <div className="py-4">
      <label className="font-medium text-gray-900 block mb-1">
        {label}
      </label>
      {description && (
        <p className="text-sm text-gray-600 mb-2">{description}</p>
      )}
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="
          w-full px-3 py-2 border border-gray-300 rounded-lg
          focus:ring-2 focus:ring-primary-500 focus:border-transparent
        "
      >
        {options.map(option => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </div>
  )
}

Text Input:

// keep-notes/components/settings/SettingInput.tsx
export function SettingInput({
  label,
  description,
  value,
  type = 'text',
  onChange,
  placeholder,
}: SettingInputProps) {
  return (
    <div className="py-4">
      <label className="font-medium text-gray-900 block mb-1">
        {label}
      </label>
      {description && (
        <p className="text-sm text-gray-600 mb-2">{description}</p>
      )}
      <input
        type={type}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder}
        className="
          w-full px-3 py-2 border border-gray-300 rounded-lg
          focus:ring-2 focus:ring-primary-500 focus:border-transparent
        "
      />
    </div>
  )
}

Settings Organization

Section 1: General

<SettingsSection title="General" icon="⚙️">
  <SettingSelect
    label="Language"
    description="Choose your preferred language"
    value={language}
    options={[
      { value: 'en', label: 'English' },
      { value: 'fr', label: 'Français' },
    ]}
    onChange={setLanguage}
  />
  <SettingToggle
    label="Enable notifications"
    description="Get notified about important updates"
    checked={notifications}
    onChange={setNotifications}
  />
</SettingsSection>

Section 2: AI

<SettingsSection title="AI" icon="🤖">
  <SettingSelect
    label="AI Provider"
    description="Choose your AI service provider"
    value={provider}
    options={[
      { value: 'auto', label: 'Auto-detect' },
      { value: 'openai', label: 'OpenAI' },
      { value: 'ollama', label: 'Ollama (Local)' },
    ]}
    onChange={setProvider}
  />
  <SettingInput
    label="API Key"
    description="Your OpenAI API key (stored securely)"
    value={apiKey}
    type="password"
    onChange={setApiKey}
  />
  <SettingToggle
    label="Title Suggestions"
    description="Suggest titles for untitled notes"
    checked={titleSuggestions}
    onChange={setTitleSuggestions}
  />
  <SettingToggle
    label="Semantic Search"
    description="Search by meaning, not just keywords"
    checked={semanticSearch}
    onChange={setSemanticSearch}
  />
  <SettingToggle
    label="Auto-labeling"
    description="Automatically suggest labels for notes"
    checked={autoLabeling}
    onChange={setAutoLabeling}
  />
</SettingsSection>

Section 3: Appearance

<SettingsSection title="Appearance" icon="🎨">
  <SettingSelect
    label="Theme"
    description="Choose your preferred color scheme"
    value={theme}
    options={[
      { value: 'light', label: 'Light' },
      { value: 'dark', label: 'Dark' },
      { value: 'auto', label: 'Auto (system)' },
    ]}
    onChange={setTheme}
  />
  <SettingSelect
    label="Font Size"
    description="Adjust text size for readability"
    value={fontSize}
    options={[
      { value: 'small', label: 'Small' },
      { value: 'medium', label: 'Medium' },
      { value: 'large', label: 'Large' },
    ]}
    onChange={setFontSize}
  />
</SettingsSection>

Save Feedback

Toast Notification:

// Show toast on save
function handleSettingChange(key: string, value: any) {
  updateSetting(key, value)
  toast.success('Settings saved', {
    description: 'Your changes have been saved successfully',
  })
}

Auto-Save Indicator:

<div className="flex items-center gap-2 text-sm text-green-600">
  <CheckCircle size={16} />
  <span>Saved</span>
</div>

Files to Create

keep-notes/components/settings/
├── SettingsNav.tsx
├── SettingsSection.tsx
├── SettingToggle.tsx
├── SettingSelect.tsx
├── SettingInput.tsx
└── index.ts

Files to Modify

  • keep-notes/app/settings/page.tsx - Main settings page
  • keep-notes/app/actions/settings.ts - Settings server actions
  • keep-notes/app/actions/ai-settings.ts - AI settings actions

Testing Requirements

Test Scenarios:

  1. Change theme → applies immediately
  2. Toggle AI feature → saves and shows confirmation
  3. Change language → updates UI text
  4. Invalid API key → shows error message
  5. Mobile view → settings accessible and usable
  6. Desktop view → sidebar navigation works

Accessibility Testing:

  • All settings keyboard accessible
  • Screen reader announces settings
  • Touch targets large enough on mobile
  • Color contrast sufficient

References

  • Current Settings: keep-notes/app/settings/ (if exists)
  • Settings Actions: keep-notes/app/actions/ai-settings.ts
  • Design System: Story 11.1 (Implement first)
  • Project Context: _bmad-output/planning-artifacts/project-context.md

Dev Agent Record

Agent Model Used

claude-sonnet-4-5-20250929

Completion Notes List

  • Created story file with comprehensive settings UX requirements
  • Proposed settings layout and organization
  • Created component examples for all setting types
  • Added mobile and desktop considerations
  • Validated existing settings implementation against story requirements
  • Confirmed all components follow design system from Story 11.1

Settings Audit Results

Current Settings Implementation: All required components already exist and are well-implemented:

  • keep-notes/components/settings/SettingsNav.tsx - Sidebar navigation with active states
  • keep-notes/components/settings/SettingsSection.tsx - Grouped settings sections
  • keep-notes/components/settings/SettingToggle.tsx - Toggle switches with visual feedback
  • keep-notes/components/settings/SettingSelect.tsx - Dropdown selects with loading states
  • keep-notes/components/settings/SettingInput.tsx - Text inputs with save indicators
  • keep-notes/components/settings/SettingsSearch.tsx - Search functionality

Settings Pages Implemented: Complete settings pages exist:

  • keep-notes/app/(main)/settings/page.tsx - Main settings dashboard
  • keep-notes/app/(main)/settings/general/page.tsx - General settings (language, notifications, privacy)
  • keep-notes/app/(main)/settings/appearance/page.tsx - Appearance (theme, font size)
  • keep-notes/app/(main)/settings/ai/page.tsx - AI settings (provider, features)
  • keep-notes/app/(main)/settings/profile/page.tsx - Profile settings
  • keep-notes/app/(main)/settings/data/page.tsx - Data management
  • keep-notes/app/(main)/settings/about/page.tsx - About section

Layout Validation: Desktop Layout:

  • Sidebar navigation (lg:col-span-1)
  • Main content area (lg:col-span-3)
  • Grid layout (grid-cols-4 gap-6)
  • Maximum width container (max-w-6xl)

Mobile Layout:

  • Responsive grid (grid-cols-1 lg:grid-cols-4)
  • Full-width content on mobile
  • Proper spacing (py-10 px-4)

Component Validation:

SettingsNav:

  • Active state detection using pathname
  • Clear visual indication for active section (bg-gray-100)
  • Icons for each section (Lucide icons)
  • Proper hover states (hover:bg-gray-100)
  • Check icon for active sections

SettingToggle:

  • Uses Switch component from Radix UI
  • Clear labels with Label component
  • Optional descriptions
  • Visual feedback (Check/X icons)
  • Loading state (Loader2 spinner)
  • Toast notifications on save/error
  • Proper TypeScript typing

SettingSelect:

  • Clear labels with Label component
  • Optional descriptions
  • Loading state indicator
  • Toast notifications on save/error
  • Proper focus states (focus:ring-2)
  • Disabled state handling

SettingInput:

  • Supports multiple types (text, password, email, url)
  • Clear labels with Label component
  • Optional descriptions
  • Loading and saved indicators
  • Toast notifications on save/error
  • Placeholder support
  • Proper focus states

SettingsSection:

  • Uses Card component
  • Icon support
  • Title and optional description
  • Proper spacing (space-y-4)

SettingsSearch:

  • Search icon
  • Input with pl-10 padding for icon
  • Search callback
  • Placeholder customization

Settings Organization: Logical grouping:

  • General (language, notifications, privacy)
  • AI (provider, features, models)
  • Appearance (theme, font size)
  • Profile (user information, account)
  • Data (export, sync, cleanup)
  • About (app info, help)

Design System Compliance: All components follow Story 11.1 design system:

  • Spacing: 4px base unit (p-4, gap-6, etc.)
  • Border radius: rounded-md (6px), rounded-lg (8px)
  • Typography: text-sm (14px), text-lg (18px), font-medium
  • Colors: Semantic CSS variables (text-gray-900, bg-gray-100)
  • Transitions: transition-colors, transition-all
  • Focus states: focus:ring-2, focus-visible:ring-2
  • Touch targets: min-h-[44px] on mobile buttons

User Experience Features: Immediate visual feedback:

  • Toast notifications on save
  • Loading indicators (Loader2 spinners)
  • Check/X status icons
  • Saved indicators (auto-clear after 2s)

Error handling:

  • Try-catch in all async handlers
  • Error toasts with descriptions
  • Console.error logging
  • Graceful degradation

Responsive design:

  • Mobile-first approach
  • lg: breakpoints for desktop
  • Proper grid layouts
  • Full-width content on mobile

Accessibility: Keyboard navigation:

  • All interactive elements keyboard accessible
  • Proper focus states
  • Role attributes where needed

Screen reader support:

  • Semantic HTML elements
  • Proper labels (Label component)
  • ARIA attributes where needed

Settings Persistence: Settings are saved via server actions:

  • updateAISettings for AI-related settings
  • Toast notifications confirm saves
  • Settings stored in database

Validation Against Acceptance Criteria

  1. Settings displayed in organized, logical manner

    • Sidebar navigation with clear sections
    • Grouped settings by category (General, AI, Appearance, etc.)
    • Proper hierarchy (Section → Settings → Values)
  2. Settings easy to find and understand

    • Clear section names with icons
    • Search functionality implemented
    • Proper labels and descriptions for each setting
  3. Clear labels and descriptions provided

    • All settings have labels via Label component
    • Descriptions for complex settings
    • Helpful placeholder text where appropriate
  4. Save changes immediately with visual feedback

    • Auto-save with toast notifications
    • Loading indicators during save
    • Check/X icons for status
    • Saved indicator auto-clears after 2 seconds
  5. Works smoothly on both desktop and mobile

    • Responsive grid layout
    • Sidebar on desktop, full-width on mobile
    • Touch targets ≥ 44x44px
    • Proper spacing on all screen sizes

File List

Files Already Created and Validated:

  • keep-notes/components/settings/SettingsNav.tsx - Sidebar navigation component
  • keep-notes/components/settings/SettingsSection.tsx - Settings section container
  • keep-notes/components/settings/SettingToggle.tsx - Toggle switch component
  • keep-notes/components/settings/SettingSelect.tsx - Dropdown select component
  • keep-notes/components/settings/SettingInput.tsx - Text input component
  • keep-notes/components/settings/SettingsSearch.tsx - Search functionality
  • keep-notes/components/settings/index.ts - Settings exports

Settings Pages Validated:

  • keep-notes/app/(main)/settings/page.tsx - Main dashboard with diagnostics
  • keep-notes/app/(main)/settings/general/page.tsx - General settings
  • keep-notes/app/(main)/settings/appearance/page.tsx - Appearance settings
  • keep-notes/app/(main)/settings/ai/page.tsx - AI settings (uses AISettingsPanel)
  • keep-notes/app/(main)/settings/profile/page.tsx - Profile settings
  • keep-notes/app/(main)/settings/data/page.tsx - Data management
  • keep-notes/app/(main)/settings/about/page.tsx - About section

Related Actions:

  • keep-notes/app/actions/ai-settings.ts - AI settings server actions
  • keep-notes/app/actions/notes.ts - Data management actions (cleanup, sync)

Implementation Summary

The settings UX implementation is complete and production-ready. All acceptance criteria have been met:

Settings are displayed in an organized, logical manner with clear categorization Settings are easy to find with sidebar navigation and search functionality All settings have clear labels and helpful descriptions Changes are saved immediately with visual feedback (toasts, loading states, status icons) The interface works smoothly on both desktop and mobile with responsive design

All components follow the design system established in Story 11.1, ensuring consistency across the entire application. The implementation provides an excellent user experience with proper feedback, error handling, and accessibility.