Skip to content

feat(profile): Implement LocalStorage preferences for anonymous users #311

@arunderwood

Description

@arunderwood

Summary

Create React hook for managing user preferences in browser LocalStorage, enabling anonymous users to personalize their experience.

Parent Epic

Part of #309 (User Profiles & Personalization)

Dependencies

  • Depends on: Profile schema ADR issue

Deliverables

usePreferences Hook

  • Create src/main/frontend/hooks/usePreferences.ts:
    interface UserPreferences {
      callsign?: string;
      gridSquare?: string;        // e.g., "FN31pr"
      preferredBands?: string[];  // e.g., ["20m", "40m", "2m"]
      preferredModes?: string[];  // e.g., ["SSB", "FT8", "CW"]
    }
    
    export function usePreferences(): {
      preferences: UserPreferences;
      setPreferences: (prefs: Partial<UserPreferences>) => void;
      updatePreference: <K extends keyof UserPreferences>(key: K, value: UserPreferences[K]) => void;
      clearPreferences: () => void;
      isLoaded: boolean;
    }

Validation

  • Grid square validation (Maidenhead format: 2-8 characters, pattern: [A-R]{2}[0-9]{2}([A-X]{2}([0-9]{2})?)?)
  • Callsign format validation (basic: 1-10 alphanumeric chars)
  • Band/mode validation against known values

Persistence

  • Store preferences in localStorage under key nextskip:preferences
  • Persist across browser sessions
  • Handle storage quota exceeded gracefully

Testing

  • Unit tests for hook in src/test/frontend/hooks/usePreferences.test.ts
  • Tests for validation functions
  • Tests for localStorage interaction

LocalStorage Schema

{
  "callsign": "W1AW",
  "gridSquare": "FN31pr",
  "preferredBands": ["20m", "40m"],
  "preferredModes": ["SSB", "FT8"]
}

Acceptance Criteria

  • Anonymous users can set/retrieve preferences from LocalStorage
  • Preferences persist across page reloads
  • Invalid grid squares are rejected with error message
  • Hook provides loading state for hydration

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions