# Web Platform Implementation Guide > **Platform:** Web (React + Ionic + TypeScript) > **Core Business Logic:** See `../../PRD.md` for platform-agnostic requirements This document contains **web-specific implementation details** for the Karaoke App. All business logic, data models, and core requirements are defined in the main PRD. --- ## Quick Reference | Section | Purpose | |---------|---------| | [UI/UX Behavior](#uiux-behavior) | Web-specific UI patterns and interactions | | [Refactored Architecture](#refactored-architecture) | Latest architecture improvements and patterns | | [Component Architecture](#component-architecture) | React/Ionic component structure | | [State Management](#state-management) | Redux Toolkit implementation | | [Performance Optimizations](#performance-optimizations) | Web-specific performance strategies | | [Development Setup](#development-setup) | Web project configuration | | [Design Assets](#design-assets) | Web-specific visual references | | [Toolset Choices](#toolset-choices) | Web technology rationale | --- ## Refactored Architecture ### **Overview** The web implementation has been completely refactored to improve maintainability, performance, and developer experience. This section documents the latest architecture patterns and implementation details. ### **Key Architectural Improvements** #### **1. Domain-Specific Redux Slices** Replaced the monolithic `controllerSlice` with focused, domain-specific slices: ```typescript // Before: Monolithic controllerSlice src/redux/controllerSlice.ts (1000+ lines) // After: Domain-specific slices src/redux/songsSlice.ts // Song catalog management src/redux/queueSlice.ts // Queue operations and state src/redux/favoritesSlice.ts // Favorites management src/redux/historySlice.ts // History tracking ``` **Benefits:** - **Better Performance** - Smaller slices mean faster state updates - **Easier Testing** - Isolated business logic for each domain - **Improved Maintainability** - Clear separation of concerns - **Reduced Bundle Size** - Only load necessary slice logic #### **2. Composable Hooks** Extracted common patterns into reusable, composable hooks: ```typescript // Reusable filtering logic useFilteredSongs(songs, searchTerm, disabledSongs) // Generic pagination with search usePaginatedData(data, pageSize, searchTerm) // Centralized error handling useErrorHandler(operation, fallbackMessage) // Performance monitoring usePerformanceMonitor(componentName, props) ``` **Benefits:** - **Code Reuse** - Common patterns shared across features - **Performance Optimized** - Each hook can be optimized independently - **Type Safety** - Full TypeScript support with proper typing - **Easier Testing** - Isolated business logic #### **3. Optimized Components** Enhanced components with performance optimizations: ```typescript // Memoized SongItem with optimized rendering const SongItem = React.memo(({ song, context, ...props }) => { const isInQueue = useMemo(() => /* expensive computation */, [queue, song.path]); const handleAddToQueue = useCallback(() => /* action */, [handleAddToQueue, song]); return ...; }); // Generic ListItem for any data type const ListItem = React.memo(({ primaryText, secondaryText, onClick, ...props }) => { return ...; }); // High-performance virtualized list const VirtualizedList = ({ items, renderItem, itemHeight, ...props }: VirtualizedListProps) => { // Only renders visible items return
...
; }; ``` **Benefits:** - **React.memo** - Prevents unnecessary re-renders - **Generic Components** - Reusable across different data types - **Virtualized Rendering** - Handles large datasets efficiently - **Performance Monitoring** - Built-in tracking capabilities ### **Implementation Patterns** #### **State Management Pattern** ```typescript // Domain-specific slice export const songsSlice = createSlice({ name: 'songs', initialState, reducers: { /* domain-specific actions */ }, extraReducers: (builder) => { builder.addCase(fetchSongs.fulfilled, (state, action) => { // Handle async operations }); }, }); // Composable hook using the slice export const useSongs = () => { const dispatch = useAppDispatch(); const songs = useAppSelector(selectSongs); const fetchSongs = useCallback(async () => { try { await dispatch(fetchSongsThunk()); } catch (error) { // Error handling } }, [dispatch]); return { songs, fetchSongs }; }; ``` #### **Component Pattern** ```typescript // Feature component using composable hooks const Search: React.FC = () => { const { songs, loading, error } = useSongs(); const { filteredSongs, searchTerm, setSearchTerm } = useFilteredSongs(songs); const { paginatedData, hasMore, loadMore } = usePaginatedData(filteredSongs); return (
} hasMore={hasMore} onLoadMore={loadMore} />
); }; ``` ### **Performance Optimizations** #### **Component-Level Optimizations** - **React.memo** - Prevents re-renders when props haven't changed - **useMemo** - Memoizes expensive computations - **useCallback** - Memoizes event handlers and functions - **Virtualized Lists** - Only renders visible items for large datasets #### **State Management Optimizations** - **Domain-Specific Slices** - Smaller, focused state management - **Memoized Selectors** - Efficient state access with reselect - **Lazy Loading** - Load components and data only when needed - **Incremental Updates** - Target specific Firebase nodes for efficiency #### **Data Handling Optimizations** - **Pagination** - Load data in chunks to prevent UI blocking - **Search Debouncing** - Reduce unnecessary API calls during typing - **Filtering Optimization** - Efficient algorithms for large datasets - **Memory Management** - Proper cleanup of listeners and subscriptions ### **Development Guidelines** #### **Adding New Features** 1. **Create domain-specific slice** if needed 2. **Implement composable hooks** for business logic 3. **Build optimized components** with React.memo and useCallback 4. **Add TypeScript types** for type safety 5. **Implement error handling** using useErrorHandler #### **Performance Best Practices** - **Use React.memo** for expensive components - **Implement useMemo/useCallback** for expensive operations - **Leverage virtualized lists** for large datasets - **Optimize Redux selectors** with memoization - **Monitor performance** with usePerformanceMonitor #### **Code Organization** - **Domain-specific slices** in `/redux/` - **Composable hooks** in `/hooks/` - **Generic components** in `/components/common/` - **Feature components** in `/features/` - **TypeScript types** in `/types/` --- ## UI/UX Behavior ### **Web-Specific Requirements:** #### **Responsive Design:** - **Mobile-first approach** with touch-friendly interface - **Progressive Web App (PWA)** capabilities for app-like experience - **Responsive breakpoints** for tablet and desktop views - **Touch gestures** for queue reordering and navigation #### **Ionic React Components:** - **IonApp** as root container with proper theming - **IonRouterOutlet** for navigation between pages - **IonList** and **IonItem** for song and queue displays - **IonButton** with proper touch targets (44px minimum) - **IonSearchbar** for song search with debounced input - **IonModal** for singer selection and settings - **IonToast** for user feedback and notifications #### **Navigation Patterns:** - **Tab-based navigation** for main sections (Queue, Search, History, etc.) - **Stack navigation** for detail views (song info, artist pages) - **Modal overlays** for quick actions (singer selection, settings) - **Deep linking** support for direct page access #### **Real-time Updates:** - **Live queue updates** with visual indicators for changes - **Playback state synchronization** across all connected devices - **User presence indicators** showing who's currently active - **Optimistic UI updates** with rollback on errors --- ## Codebase Organization & File Structure ### **Refactored Web Project Structure (Latest):** ``` src/ ├── components/ # Reusable UI components │ ├── Auth/ # Authentication components │ ├── common/ # Shared components (SongItem, ActionButton, etc.) │ ├── Layout/ # Layout and navigation components │ └── Navigation/ # Navigation components ├── features/ # Feature-specific components │ ├── Artists/ # Artist browsing feature │ ├── Favorites/ # Favorites management │ ├── History/ # Play history │ ├── NewSongs/ # New songs feature │ ├── Queue/ # Queue management │ ├── Search/ # Song search │ ├── Settings/ # Settings and admin features │ ├── Singers/ # Singer management │ ├── SongLists/ # Song lists feature │ └── TopPlayed/ # Top played songs ├── firebase/ # Firebase configuration and services │ ├── config.ts # Firebase configuration │ ├── services.ts # Firebase service layer │ └── useFirebase.ts # Firebase hooks ├── hooks/ # Custom React hooks (refactored) │ ├── useFilteredSongs.ts # Reusable song filtering logic │ ├── usePaginatedData.ts # Generic pagination with search │ ├── useErrorHandler.ts # Centralized error handling │ ├── usePerformanceMonitor.ts # Performance tracking │ ├── useQueue.ts # Queue management hooks │ ├── useSearch.ts # Search functionality hooks │ ├── useFavorites.ts # Favorites management hooks │ └── ... # Other feature hooks ├── redux/ # State management (domain-specific slices) │ ├── store.ts # Redux store configuration │ ├── songsSlice.ts # Song catalog management │ ├── queueSlice.ts # Queue operations and state │ ├── favoritesSlice.ts # Favorites management │ ├── historySlice.ts # History tracking │ ├── selectors.ts # Memoized selectors │ └── hooks.ts # Redux hooks ├── types/ # TypeScript type definitions └── utils/ # Utility functions ``` ### **Refactored Architecture Benefits:** #### **Domain-Specific Redux Slices:** - **Modular Design** - Each slice handles a specific domain (songs, queue, favorites, history) - **Better Performance** - Smaller slices mean faster state updates and re-renders - **Easier Testing** - Isolated business logic for each domain - **Improved Maintainability** - Clear separation of concerns #### **Composable Hooks:** - **Reusable Logic** - Common patterns extracted into reusable hooks - **Performance Optimized** - Each hook can be optimized independently - **Type Safety** - Full TypeScript support with proper typing - **Error Handling** - Centralized error management across the app #### **Optimized Components:** - **React.memo** - Prevents unnecessary re-renders for expensive components - **Generic Components** - Reusable across different data types (ListItem, VirtualizedList) - **Performance Monitoring** - Built-in performance tracking - **Error Boundaries** - Graceful error handling and recovery ### **File Organization Rules:** | Folder | Purpose | Key Files | Import Pattern | |--------|---------|-----------|----------------| | `/components` | Reusable UI components | `SongItem.tsx`, `ActionButton.tsx`, `ListItem.tsx` | `import { SongItem } from '../components/common'` | | `/features` | Feature-specific pages | `Queue.tsx`, `Search.tsx` | `import { Queue } from '../features/Queue'` | | `/firebase` | Firebase integration | `services.ts`, `config.ts` | `import { queueService } from '../firebase/services'` | | `/hooks` | Composable business logic | `useFilteredSongs.ts`, `usePaginatedData.ts` | `import { useFilteredSongs } from '../hooks'` | | `/redux` | Domain-specific state | `songsSlice.ts`, `queueSlice.ts` | `import { songsSlice } from '../redux'` | | `/types` | TypeScript definitions | `index.ts` (extends docs/types.ts) | `import type { Song, QueueItem } from '../types'` | ### **Import Patterns:** #### **1. Redux Imports:** ```typescript // Always import from the main redux index import { useAppDispatch, useAppSelector } from '../redux'; import { selectQueue, selectSongs } from '../redux'; import { setController, updateQueue } from '../redux'; // ❌ Don't import directly from slice files // ❌ import { selectQueue } from '../redux/controllerSlice'; // ✅ Always use the main redux index // ✅ import { selectQueue } from '../redux'; ``` #### **2. Firebase Service Imports:** ```typescript // Import services from the main services file import { queueService, searchService } from '../firebase/services'; // ❌ Don't import directly from individual service files // ❌ import { addToQueue } from '../firebase/queueService'; // ✅ Always use the main services file // ✅ import { queueService } from '../firebase/services'; ``` #### **3. Type Imports:** ```typescript // Always use type imports for TypeScript interfaces import type { Song, QueueItem, Singer } from '../types'; // ❌ Don't import types from individual files // ❌ import { Song } from '../types/Song'; // ✅ Always use the main types index // ✅ import type { Song } from '../types'; ``` #### **4. Hook Imports:** ```typescript // Import hooks from their specific files import { useQueue } from '../hooks/useQueue'; import { useSearch } from '../hooks/useSearch'; import { useFavorites } from '../hooks/useFavorites'; // ❌ Don't import from a general hooks index // ❌ import { useQueue } from '../hooks'; // ✅ Import from specific hook files // ✅ import { useQueue } from '../hooks/useQueue'; ``` #### **5. Component Imports:** ```typescript // Import components from their specific folders import { SongItem } from '../components/common/SongItem'; import { ActionButton } from '../components/common/ActionButton'; import { Layout } from '../components/Layout/Layout'; // ❌ Don't import from general component indices // ❌ import { SongItem } from '../components'; // ✅ Import from specific component files // ✅ import { SongItem } from '../components/common/SongItem'; ``` ### **Architecture Flow:** ``` UI Components → Custom Hooks → Redux State → Firebase Services → Firebase Database ``` ### **Separation of Concerns:** - **Components:** Only handle UI presentation and user interactions - **Hooks:** Contain business logic and data management - **Redux:** Manage global application state - **Services:** Handle Firebase operations and data persistence - **Types:** Define data structures and interfaces ## Component Architecture ### **React Component Structure:** #### **Page Components:** ```typescript // src/features/Queue/Queue.tsx interface QueueProps { // Props interface } const Queue: React.FC = () => { // Component implementation } ``` #### **Common Components:** ```typescript // src/components/common/SongItem.tsx interface SongItemProps { song: Song; onAddToQueue: (song: Song) => void; onAddToFavorites: (song: Song) => void; showAddButton?: boolean; showFavoriteButton?: boolean; } ``` #### **Layout Components:** ```typescript // src/components/Layout/Layout.tsx interface LayoutProps { children: React.ReactNode; title?: string; showBackButton?: boolean; } ``` ### **Ionic Integration:** - **IonPage** wrapper for all page components - **IonHeader** with dynamic titles and action buttons - **IonContent** with proper scrolling behavior - **IonFooter** for player controls and queue management - **IonLoading** for async operations and data fetching --- ## State Management ### **Redux Architecture Pattern:** The web implementation uses Redux Toolkit for predictable state management with excellent TypeScript support. #### **Store Structure:** ```typescript // src/redux/store.ts export const store = configureStore({ reducer: { auth: authSlice, player: playerSlice, queue: queueSlice, controller: controllerSlice, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: ['persist/PERSIST'], }, }), }); ``` #### **Slice Patterns:** ```typescript // src/redux/controllerSlice.ts const controllerSlice = createSlice({ name: 'controller', initialState, reducers: { setController: (state, action) => { state.data = action.payload; }, updateQueue: (state, action) => { state.data.player.queue = action.payload; }, }, }); ``` #### **Selectors:** ```typescript // src/redux/selectors.ts export const selectQueue = (state: RootState) => state.controller.data?.player?.queue || {}; export const selectQueueLength = createSelector( [selectQueue], (queue) => Object.keys(queue).length ); ``` ### **Redux Toolkit Implementation:** #### **Store Structure:** ```typescript // src/redux/store.ts export const store = configureStore({ reducer: { auth: authSlice, player: playerSlice, queue: queueSlice, controller: controllerSlice, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: ['persist/PERSIST'], }, }), }); ``` #### **Slice Patterns:** ```typescript // src/redux/queueSlice.ts const queueSlice = createSlice({ name: 'queue', initialState, reducers: { addToQueue: (state, action) => { // Implementation }, removeFromQueue: (state, action) => { // Implementation }, }, }); ``` #### **Selectors:** ```typescript // src/redux/selectors.ts export const selectQueue = (state: RootState) => state.queue.items; export const selectQueueLength = createSelector( [selectQueue], (queue) => queue.length ); ``` --- ## Development Setup ### **Project Configuration:** #### **Package.json Dependencies:** ```json { "dependencies": { "@ionic/react": "^7.0.0", "@reduxjs/toolkit": "^1.9.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.0", "firebase": "^9.0.0" }, "devDependencies": { "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "typescript": "^4.9.0", "vite": "^4.0.0" } } ``` #### **Vite Configuration:** ```typescript // vite.config.ts export default defineConfig({ plugins: [react()], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, build: { outDir: 'dist', sourcemap: true, }, }); ``` #### **TypeScript Configuration:** ```json // tsconfig.json { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true } } ``` ### **Environment Setup:** ```bash # .env.local VITE_FIREBASE_API_KEY=your_api_key VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com VITE_FIREBASE_PROJECT_ID=your_project_id VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id VITE_FIREBASE_APP_ID=your_app_id VITE_FIREBASE_DATABASE_URL=https://your_project-default-rtdb.firebaseio.com ``` --- ## Design Assets ### **Web-Specific Mockups:** Located in `design/` with 30+ mockups covering all features: #### **Core Navigation & Layout:** - `00-web-layout.JPG` - Overall web layout structure - `01-Login.png` - Login screen design - `02-menu.jpeg`, `02a-menu.jpeg`, `02b-menu.png`, `02c-menu.jpeg` - Navigation menu variations #### **Queue Management:** - `02-queue.png` - Main queue view - `02-queue-delete.png` - Queue with delete functionality - `02-queue-drag.png` - Queue reordering with drag and drop - `02-queue-sorting.png` - Queue sorting interface #### **Search & Discovery:** - `04-search.png` - Main search interface - `04-search typing .png` - Search with typing interaction - `04-search-song info.png` - Search results with song information #### **User Management:** - `05-singers.png` - Singer list view - `05-singers add.png` - Singer management interface #### **Content Browsing:** - `06-artists .png` - Artist browse interface - `06-artists (not admin).png` - Non-admin artist view - `06-artists search.png` - Artist search functionality - `06-artists songs.png` - Artist songs list #### **User Features:** - `07-favorites.png` - Favorites management - `08-history.png` - Play history view - `09-songs list.png` - Main song lists view - `09-song lists - songs.png` - Song lists with song details - `09- song lists songs expand.png` - Song lists with expandable sections #### **Admin Features:** - `10-Settings.png` - Settings interface - `11-top 100.png` - Top played songs - `12-favorites .png` - Favorites view - `12-favorite lists.png` - Favorite lists management #### **Menu States:** - `03-menu.png` - General menu layout - `03-menu current page and non-admin.png` - Navigation with current page indicators - `03-menu playing (admin).png` - Admin view during playback ### **Design System:** - **Ionic Design System** for consistent UI components - **Custom CSS variables** for theming and branding - **Responsive grid system** for layout consistency - **Touch-friendly spacing** and sizing guidelines --- ## Toolset Choices ### **Current Web Implementation Toolset:** #### **Core Framework: React 18 + TypeScript** - **Why:** Chosen for its component-based architecture, strong ecosystem, and excellent TypeScript support - **Migration Note:** Can be replaced with any other component-based framework (e.g., Vue, Svelte) #### **State Management: Redux Toolkit** - **Why:** Provides predictable state management with excellent TypeScript support and dev tools - **Migration Note:** Can be replaced with Context API, Zustand, or other state management solutions #### **UI Framework: Ionic React** - **Why:** Provides mobile-first UI components with excellent touch support and PWA capabilities - **Migration Note:** Can be replaced with Material-UI, Chakra UI, or custom components #### **Build Tool: Vite** - **Why:** Fast development server and optimized builds with excellent TypeScript support - **Migration Note:** Can be replaced with Webpack, Parcel, or other build tools #### **Backend: Firebase Realtime Database** - **Why:** Real-time synchronization, simple setup, and excellent React integration - **Migration Note:** Can be replaced with any real-time database (Supabase, AWS AppSync, etc.) ### **Development Tools:** - **TypeScript:** Type safety and better developer experience - **ESLint:** Code quality and consistency - **Prettier:** Code formatting - **React DevTools:** Component debugging - **Redux DevTools:** State management debugging --- ## Web-Specific Implementation Details ### **Authentication & Session Management:** - **Admin Access:** Triggered by URL parameter (`?admin=true`), removed after login - **Session Persistence:** Lost on browser reload (no persistent storage) - **Admin Mode:** Pre-fills singer name as "Admin" for convenience - **URL Handling:** Admin parameter automatically removed from URL after authentication ### **Search Implementation:** - **Pagination:** Uses Ionic InfiniteScrollList component for efficient loading - **Debouncing:** Search input debounced to prevent excessive API calls - **Real-time Results:** Instant search results as user types - **Context Actions:** Add to queue, favorite, and other actions available per song ### **Queue Management:** - **UI Controls:** Reordering and deletion exposed via UI controls only visible to admins - **Drag & Drop:** Uses Ionic drag handles and swipe actions for reordering - **Visual Feedback:** Clear indicators for admin-only actions - **State Synchronization:** Real-time updates across all connected clients ### **Favorites Implementation:** - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Real-time Sync:** Shared favorites list synchronized across all clients - **Duplicate Prevention:** Prevents duplicates using song path field - **User Actions:** Anyone can add/remove favorites ### **New Songs Implementation:** - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Real-time Updates:** Shows recently added songs from newSongs node - **Automatic Loading:** Progressive loading as user scrolls ### **Artists Implementation:** - **Modal Views:** Uses Ionic modals for artist song lists - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Search Integration:** Artist search functionality included - **Song Counts:** Displays song count per artist ### **Song Lists Implementation:** - **Modal Interface:** Uses Ionic modals for viewing list contents - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Expandable Views:** Available versions shown with expandable sections - **Availability Status:** Shows which songs are available in catalog ### **History Implementation:** - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Automatic Tracking:** Songs automatically added when played - **Timestamp Display:** Shows when each song was last played - **Append-only:** History is append-only, shared across all clients ### **Top Played Implementation:** - **Infinite Scroll:** Uses Ionic InfiniteScrollList for pagination - **Play Count Display:** Shows play count for each song - **Real-time Updates:** Popular songs generated by backend - **Backend Integration:** Based on history data ### **Singer Management:** - **Admin-only UI:** Singer management available only to admins via settings page - **Unique Names:** Singer names must be unique and non-empty - **Auto-addition:** Singers automatically added when they join - **Last Join Tracking:** Tracks when each singer last joined ### **Playback Control:** - **Admin-only Controls:** Player controls only rendered for admins - **State-based UI:** Play/pause/stop buttons shown/hidden based on current state - **Queue Validation:** Play button disabled when queue is empty - **Real-time Sync:** Playback state synchronized across all clients ### **Error Handling & Sync:** - **Toast Notifications:** Uses web-specific toast notifications for user feedback - **Error Boundaries:** React error boundaries for component-level error handling - **Retry Patterns:** Automatic retry for failed Firebase operations - **Connection Monitoring:** Real-time connection status tracking ### **Disabled Songs:** - **Modal Management:** Disabled songs managed via modal dialog - **Search & Filter:** Search and filter capabilities in management interface - **Hash Storage:** Disabled songs stored using hash of song path - **Admin-only Access:** Only admins can disable or enable songs ### **Settings Implementation:** - **Debug Logging:** Web-only feature, toggled via settings page - **Admin-only Access:** Only admins can change player settings - **Real-time Updates:** Settings changes synchronized across all clients - **UI Controls:** Settings interface with toggle switches and controls ### **Navigation Implementation:** - **Admin-based Navigation:** Navigation adapts based on admin status - **Hidden Pages:** Settings page only visible to admins - **Role-based UI:** Different navigation options for different user roles - **Dynamic Menus:** Menu items shown/hidden based on permissions ### **UI/UX Implementation:** - **Ionic React:** Uses Ionic React and Tailwind CSS for UI - **Component Library:** Infinite scroll, swipe actions, modals, and toasts using Ionic components - **Responsive Design:** Mobile-first approach with touch-friendly interface - **Theme Support:** Light/dark mode support with consistent styling ## Implementation Notes ### **Critical Web-Specific Patterns:** #### **Firebase Integration:** ```typescript // src/firebase/services.ts export const queueService = { addToQueue: async (song: Song, singerId: string) => { const newKey = await getNextKey('queue'); await set(ref(database, `queue/${newKey}`), { songId: song.id, singerId, timestamp: Date.now(), key: newKey, }); }, }; ``` #### **Real-time Listeners:** ```typescript // src/hooks/useQueue.ts useEffect(() => { const queueRef = ref(database, 'queue'); const unsubscribe = onValue(queueRef, (snapshot) => { const data = snapshot.val(); if (data) { const queueItems = Object.values(data) as QueueItem[]; dispatch(setQueue(queueItems)); } }); return () => unsubscribe(); }, [dispatch]); ``` #### **Error Handling:** ```typescript // src/hooks/useFirebaseSync.ts const retryOperation = async (operation: () => Promise, maxRetries = 3) => { for (let i = 0; i < maxRetries; i++) { try { await operation(); return; } catch (error) { if (i === maxRetries - 1) throw error; await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } } }; ``` ### **Hook Implementation Patterns:** #### **Custom Hook Structure:** ```typescript // src/hooks/useQueue.ts export const useQueue = () => { const dispatch = useAppDispatch(); const queue = useAppSelector(selectQueue); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const addToQueue = useCallback(async (song: Song, singerId: string) => { try { setLoading(true); setError(null); await queueService.addToQueue(song, singerId); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to add to queue'); } finally { setLoading(false); } }, []); return { queue, loading, error, addToQueue, }; }; ``` #### **Hook Dependencies:** - **Hooks depend on Redux state** and services - **Business logic** implemented in hooks, not components - **Error handling** and loading states managed in hooks - **Memoization** used for expensive operations #### **Hook Usage in Components:** ```typescript // src/features/Queue/Queue.tsx const Queue: React.FC = () => { const { queue, loading, error, addToQueue } = useQueue(); const { songs } = useSongs(); const handleAddToQueue = useCallback((song: Song) => { addToQueue(song, currentSingerId); }, [addToQueue, currentSingerId]); if (loading) return ; if (error) return ; return ( {Object.values(queue).map((item) => ( ))} ); }; ``` ### **Performance Optimizations:** #### **Component-Level Optimizations:** - **React.memo** - Prevents unnecessary re-renders for expensive components like `SongItem` - **useMemo/useCallback** - Memoizes expensive computations and event handlers - **Virtualized Lists** - `VirtualizedList` component renders only visible items for large datasets - **Generic Components** - `ListItem` component works with any data type for reusability #### **State Management Optimizations:** - **Domain-Specific Slices** - Smaller, focused Redux slices (songs, queue, favorites, history) - **Composable Hooks** - Reusable logic (`useFilteredSongs`, `usePaginatedData`, `useErrorHandler`) - **Optimized Selectors** - Memoized Redux selectors for efficient state access - **Lazy Loading** - Components and data loaded only when needed #### **Data Handling Optimizations:** - **Pagination** - `usePaginatedData` hook loads data in chunks to prevent UI blocking - **Search Debouncing** - Reduces unnecessary API calls during typing - **Filtering Optimization** - `useFilteredSongs` hook provides efficient filtering algorithms - **Memory Management** - Proper cleanup of listeners and subscriptions #### **Performance Monitoring:** - **Built-in Performance Hooks** - `usePerformanceMonitor` tracks component render times - **Error Tracking** - Centralized error handling with performance impact monitoring - **Bundle Analysis** - Optimized bundle size with code splitting #### **Specific Optimizations:** - **SongItem Component** - Fully memoized with React.memo, useMemo, and useCallback - **ListItem Component** - Generic component supporting multiple data types - **VirtualizedList Component** - High-performance list rendering with windowing - **ActionButton Component** - Reusable buttons with consistent styling and behavior ### **Refactoring Benefits & Migration Notes:** #### **Architecture Improvements:** - **Modular Redux Slices** - Replaced monolithic `controllerSlice` with domain-specific slices - **Composable Hooks** - Extracted common patterns into reusable hooks - **Performance Optimizations** - Added React.memo, useMemo, useCallback throughout - **Type Safety** - Enhanced TypeScript support with strict typing #### **Component Enhancements:** - **Generic ListItem** - Replaced song-specific component with generic, reusable component - **VirtualizedList** - Added high-performance list rendering for large datasets - **Performance Monitoring** - Built-in performance tracking with `usePerformanceMonitor` - **Error Boundaries** - Centralized error handling across the application #### **Development Experience:** - **Better Maintainability** - Clear separation of concerns with domain-specific slices - **Easier Testing** - Isolated business logic for each domain - **Improved Performance** - Optimized rendering and state management - **Enhanced Type Safety** - Full TypeScript coverage with proper typing ### **Critical Implementation Rules:** - **Never import directly from slice files** - always use the main redux index - **Always use type imports** for TypeScript interfaces - **Implement business logic in hooks**, not components - **Use memoization** for expensive operations - **Handle loading and error states** in all async operations - **Use React.memo** for performance-critical components - **Leverage composable hooks** for reusable business logic --- ## Migration Guide ### **To Other Web Frameworks:** #### **Vue.js Migration:** - Replace React components with Vue components - Replace Redux with Pinia or Vuex - Replace Ionic React with Ionic Vue - Keep all business logic and Firebase integration #### **Svelte Migration:** - Replace React components with Svelte components - Replace Redux with Svelte stores - Replace Ionic React with Ionic Svelte - Keep all business logic and Firebase integration ### **To Mobile Platforms:** #### **React Native Migration:** - Replace Ionic components with React Native components - Replace web-specific APIs with React Native APIs - Keep Redux state management - Keep all business logic and Firebase integration #### **Native iOS/Android Migration:** - Replace React components with native UI components - Replace Redux with native state management - Keep all business logic and Firebase integration - Adapt UI patterns to platform conventions --- _This document contains web-specific implementation details. For core business logic and platform-agnostic requirements, see the main `../../PRD.md`._