# Jukebox Project - Mobile App Exploration Report ## 📱 PROJECT OVERVIEW **Project Type**: React Native Mobile App + Web Admin Panel + Laravel API Backend **Current Date**: May 12, 2026 **Repository Location**: `/home/mathias/jukebox` --- ## 🏗️ ARCHITECTURE OVERVIEW ``` jukebox/ ├── jukebox/ # React Native Mobile App (Expo) │ ├── admin_panel/ # Web-based Admin Panel (React + Vite) │ └── src/ # Mobile app source code ├── www/api/ # Laravel REST API Backend (PHP) ├── db/ # Database schema and scripts ├── mocks/ # UI mockups and design files └── flyer/ # Marketing materials ``` --- ## 📲 MOBILE APP (REACT NATIVE / EXPO) ### Technology Stack - **Framework**: React Native 0.81.5 with Expo 54.0.33 - **Navigation**: React Navigation Native (Stack Navigator) - **State Management**: React Context API (LibraryProvider, PlayerProvider) - **UI Components**: React Native core components - **Icons**: Expo Vector Icons, React Native Vector Icons - **Animation**: React Native Reanimated - **Styling**: StyleSheet (React Native native styling) - **Special Libraries**: - `rn-inkpad` (UI components - buttons, sliders) - `expo-linear-gradient` (gradient backgrounds) - `react-native-safe-area-context` (safe area handling) ### Project Configuration ```json { "name": "jukebox", "version": "1.0.0", "platforms": ["iOS", "Android", "Web"], "orientation": "portrait", "newArchEnabled": true } ``` ### Scripts - `npm start` - Start Expo development server - `npm run android` - Run on Android emulator/device - `npm run ios` - Run on iOS simulator/device - `npm run web` - Run in web browser --- ## 🎯 MOBILE APP SCREENS ### 1. **HomeScreen** (`src/screens/HomeScreen.js`) - **Purpose**: Main landing page / music library browse - **Features**: - Header with navigation icons (Profile, Settings) - "Liked tracks" section (top 5 tracks with shortcut) - Albums grid (2 columns) - Tap on album to navigate to AlbumScreen - Tap on liked track to navigate to album - **Data Source**: Uses LibraryContext (mock data) - **Navigation**: `navigation.navigate("Album", { album })` ### 2. **AlbumScreen** (`src/screens/AlbumScreen.js`) - **Purpose**: Display album details and track list - **Features**: - Album cover image (140x140) - Album title, artist, release date, label, duration - FlatList of all tracks in album - Heart icon to like/unlike tracks - Back button to return to HomeScreen - **Data Source**: LibraryContext (albums state) - **Navigation**: Can navigate back to home ### 3. **LikedTracksScreen** (`src/screens/LikedTracksScreen.js`) - **Purpose**: View all liked tracks with search and filtering - **Features**: - Search input to filter by title/artist - Sort menu with 3 options: Date Added, Name, Length - Sort direction toggle (ASC/DESC) - FlatList of liked tracks - Can navigate to album from track - **Data Source**: LibraryContext (computed likedTracks) - **Navigation**: Back button, navigate to Album ### 4. **LoginScreen** (`src/screens/LoginScreen.js`) - **Purpose**: User authentication - **Features**: - Email input field - Password input field (secured) - "Log In" button - "Reset password" link - "Sign Up" link - **State**: Local component state (email, password) - **Action**: `onLogin()` - currently just logs to console - **Navigation**: Can navigate to PasswordReset, SignUp, back ### 5. **SignUpScreen** (`src/screens/SignUpScreen.js`) - **Purpose**: User registration - **Features**: - Email input - Password input - Confirm password input - "Sign Up" button - **State**: Local component state - **Action**: `onSignUp()` - currently just logs to console - **Navigation**: Back button ### 6. **PasswordResetScreen** (`src/screens/PasswordResetScreen.js`) - **Purpose**: Password recovery - **Features**: - Email input for account recovery - "Send email" button - **Action**: `onResetButtonPress()` - currently just logs to console - **Navigation**: Back button ### 7. **SettingsScreen** (`src/screens/SettingsScreen.js`) - **Purpose**: User preferences and account management - **Features**: - Toggle: Enable notifications (default: true) - Toggle: High quality streaming (default: false) - "Log out" button (red) - **State**: Local component state (notificationsEnabled, highQuality) - **Navigation**: Back button --- ## 🧩 COMPONENTS ### 1. **Header** (`src/components/Header.js`) - Displays screen title - Optional action icons (Profile, Settings) - Used on: HomeScreen, LikedTracksScreen, LoginScreen, SettingsScreen, etc. - Props: `title` (string), `showIcons` (boolean) ### 2. **TrackRow** (`src/components/TrackRow.js`) - Displays single track in a list item format - Shows: Cover image (46x46), title, artist, duration, heart icon - Props: `title`, `artist`, `duration`, `cover`, `liked`, `onToggleLike`, `onPress` - Used in: HomeScreen, AlbumScreen, LikedTracksScreen ### 3. **MediaPlayer** (`src/components/MediaPlayer.js`) - Floating player widget at bottom of screen - Shows: Track name/artist, progress bar with times, play/pause button - Uses: `rn-inkpad` Slider and Button components - Uses: `expo-linear-gradient` for dark gradient background - State: `isPlaying`, `progress` (local component state) - **Note**: Currently shows placeholder data, not connected to actual playback - Position: Absolute bottom-right, z-index: 999 ### 4. **DurationFormatter** (`src/components/DurationFormatter.js`) - Utility function to format seconds to MM:SS or HH:MM:SS format - Export: `durationFormatter(totalSeconds)` - Used in: TrackRow, AlbumScreen, LikedTracksScreen --- ## 🎵 DATA MANAGEMENT ### Data Flow Architecture ``` LibraryContext (Global State) ├── albums: Array of album objects ├── likedTracks: Computed memoized array ├── toggleLike(albumId, trackId): Function └── [Components access via useLibrary() hook] ``` ### LibraryContext (`src/contexts/LibraryContext.js`) - **State**: `albums` from `initialLibrary` (mock data) - **Methods**: - `toggleLike(albumId, trackId)` - Toggles liked status of a track - Computed `likedTracks` - Memoized array of all liked tracks across albums - **Usage**: `const { albums, likedTracks, toggleLike } = useLibrary()` ### Mock Data (`src/data/library.js`) **Currently Using STATIC MOCK DATA** - No API integration yet! Data structure: ```javascript [ { id: 'album1', title: 'Album Title', artist: 'Artist Name', date: 'YYYY-MM-DD', label: 'Label Name', duration: 8485 (in seconds), cover: require('../../assets/covers/cover.jpg'), tracks: [ { id: 'a1t1', title: 'Track Title', duration: 183, liked: false }, // ... more tracks ] }, // ... more albums ] ``` **Current Mock Data**: - 2 albums (Swans - "Soundtracks For The Blind", Daft Punk - "Discovery") - 26 + 14 = 40 total tracks - Some tracks pre-marked as liked --- ## 🎛️ STATE MANAGEMENT ### PlayerProvider Context (`App.js`) ```javascript { currentTrack: Track object or undefined, setCurrentTrack: Function, isPlaying: boolean, setIsPlaying: Function } ``` - Provides player state globally - Used by MediaPlayer component and navigation - **Status**: Provider setup exists, but MediaPlayer doesn't actually use currentTrack ### LibraryProvider Context - See above - manages album library and likes --- ## 📱 NAVIGATION STRUCTURE ### Stack Navigator Screens (in order) 1. Home 2. LikedTracks 3. Album 4. SignUp 5. Login 6. PasswordReset 7. Settings ### Navigation Type: React Navigation Native Stack - **Pattern**: Screen name → Component mapping - **Style**: Header hidden (`headerShown: false`) - **Safe Area**: Wrapped with SafeAreaProvider --- ## 🖼️ UI/UX DETAILS ### Color Scheme - **Primary Background**: `#000` (pure black) - **Secondary Background**: `#111827`, `#1f2937` (dark grays) - **Text Primary**: `#fff` (white) - **Text Secondary**: `#9ca3af` (light gray) - **Text Meta**: `#cfcfcf` (medium gray) - **Accent (Like)**: `#ff4d6d` (pink/red) - **Accent (Buttons)**: `#dbdbdb` (light gray) - **Warning/Danger**: `#e36d6d` (red) ### Layout - Portrait only orientation - Safe area respecting - Padding: typically 16px horizontal, 24px vertical - Border radius: typically 8-10px - Shadow/Elevation handling for media player (elevation: 10) --- ## 🌐 WEB ADMIN PANEL ### Technology Stack - **Framework**: React 19.2.0 - **Build Tool**: Vite 7.3.1 - **Routing**: React Router DOM 7.13.1 - **Styling**: Tailwind CSS 4.0.0 - **State Management**: React Context (AuthContext) ### Admin Panel Structure ``` admin_panel/ ├── src/ │ ├── App.jsx # Main router and layout │ ├── main.jsx # Entry point │ ├── pages/ │ │ ├── LoginPage.jsx # Admin login │ │ ├── AlbumsPage.jsx # Album management │ │ ├── AlbumTracksPage.jsx # Track management │ │ └── UsersPage.jsx # User management │ ├── contexts/ │ │ └── AuthContext.jsx # Authentication state │ └── services/ │ └── api.js # API client ├── vite.config.js ├── eslint.config.js └── package.json ``` ### Admin Pages #### LoginPage - Email/password form - Connects to `/api/login` - Stores token in localStorage - Redirects on success #### AlbumsPage - List all albums - Create, edit, delete albums - Upload album cover images - Navigate to AlbumTracksPage for track management #### AlbumTracksPage (`/albums/:albumId/tracks`) - Manage tracks within an album - Add, edit, delete tracks - Upload audio files - Reorder tracks #### UsersPage - List all users - View user details - Edit user roles - Delete users ### Admin API Integration (`services/api.js`) ```javascript const api = { // Albums getAlbums(), getAlbumById(id), addAlbum(data), updateAlbum(id, data), deleteAlbum(id), // Tracks addTrack(data), updateTrack(id, data), deleteTrack(id), reorderTracks(albumId, positions), // Artists getArtists(), addArtist(data), // Genres getGenres(), addGenre(data), // File uploads uploadImage(file), uploadAudio(file), // Users getUsers(), updateUser(id, data), deleteUser(id) } ``` --- ## 🔌 BACKEND API (LARAVEL) ### API Base URL - **Local Development**: `http://localhost/api` - **Environment Variable**: `VITE_API_URL` ### Authentication - **Method**: Laravel Sanctum (Bearer Token) - **Token Storage**: localStorage (`token` key) - **Expires On**: 401 Unauthorized → clears localStorage & redirects to /login ### Authentication Endpoints ``` POST /register - Create new user (user role) POST /login - Login & get token POST /logout - Logout & invalidate token GET /me - Get current user info ``` ### Database Models (from API_QUICK_REFERENCE.md) ``` Users ├─ has_many: Tracks (likes table) ├─ belongs_to: Role Albums ├─ belongs_to: Label ├─ has_many: Tracks Tracks ├─ belongs_to: Album ├─ belongs_to_many: Artists (artist_track) ├─ belongs_to_many: Genres (track_genre) ├─ belongs_to_many: Users (likes) Artists ├─ belongs_to: Label ├─ belongs_to_many: Tracks Genres └─ belongs_to_many: Tracks Labels ├─ has_many: Artists └─ has_many: Albums Roles └─ has_many: Users ``` ### Key API Endpoints (for mobile) ``` GET /albums - Get all albums GET /albums/{id} - Get album with tracks GET /tracks - Get all tracks GET /tracks/{id} - Get track details POST /tracks/{id}/like - Like a track DELETE /tracks/{id}/like - Unlike a track GET /me/likes - Get liked tracks GET /artists - Get artists GET /genres - Get genres ``` ### Admin-Only Endpoints ``` POST/PUT/DELETE /albums POST/PUT/DELETE /tracks POST/PUT/DELETE /artists POST/PUT/DELETE /genres POST/PUT/DELETE /labels POST/PUT/DELETE /users ``` --- ## 🚨 CURRENT STATE & LIMITATIONS ### ✅ What's Implemented 1. ✅ Complete navigation structure (all screens) 2. ✅ Mock data with 2 sample albums 3. ✅ Like/unlike functionality (local state) 4. ✅ Search and sort in LikedTracksScreen 5. ✅ MediaPlayer UI component (visual only) 6. ✅ Context API setup for global state 7. ✅ SafeAreaProvider for device compatibility 8. ✅ Admin panel basic UI structure 9. ✅ API client with authentication headers 10. ✅ Tailwind CSS styling in admin ### ❌ What's NOT Implemented 1. ❌ **No API Integration** - Mobile app still uses mock data 2. ❌ **No Real Authentication** - Login/SignUp don't call API 3. ❌ **No Audio Playback** - MediaPlayer is UI-only, no actual playback 4. ❌ **No Real Settings** - Settings switches don't persist or affect app 5. ❌ **No Password Reset** - Password reset logic not implemented 6. ❌ **No Data Persistence** - App state lost on refresh 7. ❌ **No Image Assets** - Need to verify album covers exist 8. ❌ **No Admin Page Implementations** - AlbumsPage, UsersPage, etc. are stubs 9. ❌ **No File Upload** - Upload endpoints not integrated in admin 10. ❌ **No Error Handling** - Limited error boundaries or error messages 11. ❌ **No Loading States** - No spinners or loading indicators 12. ❌ **No Pagination** - API has no pagination, all records returned ### 🔄 Backend API Status - ✅ Built with Laravel - ✅ Authentication system ready (Sanctum) - ✅ Database schema designed - ✅ Most controllers implemented - ⚠️ Limited test coverage - ⚠️ No CORS configuration file - ⚠️ No pagination or filtering - ⚠️ No API documentation (though quick reference exists) --- ## 📊 DATA FLOW SUMMARY ### Current Flow (Mock Data) ``` App.js ├── PlayerProvider │ └── LibraryProvider │ ├── initialLibrary (mock data) │ └── [All Screens] │ ├── HomeScreen │ ├── AlbumScreen │ ├── LikedTracksScreen │ └── LoginScreen (not connected) ``` ### Expected Future Flow (With API) ``` API (Laravel) ├── /albums ├── /tracks ├── /users/me/likes └── /login ↓ LibraryContext (should fetch from API) ├── albums ├── likedTracks └── currentUser ↓ All Screens display live API data ``` --- ## 🛠️ NEXT STEPS FOR INTEGRATION 1. **Connect Mobile App to API** - Replace `initialLibrary` with API calls in LibraryProvider - Implement login/logout with real authentication - Add data persistence (localStorage or AsyncStorage) 2. **Implement Audio Playback** - Use `expo-av` for audio playback - Connect MediaPlayer to PlayerProvider - Stream tracks from API 3. **Build Admin Panel Pages** - Implement AlbumsPage.jsx - Implement UsersPage.jsx - Implement AlbumTracksPage.jsx 4. **Add Error Handling** - API error boundaries - User feedback (toasts/alerts) - Retry logic 5. **Performance Optimizations** - Add pagination to API - Implement image caching - Add loading states - Memoize expensive computations --- ## 📁 FILE SUMMARY ``` /home/mathias/jukebox/jukebox/ ├── App.js (100 lines) - Root component, navigation, contexts ├── index.js (9 lines) - Expo entry point ├── app.json - Expo configuration ├── package.json - Dependencies ├── src/ │ ├── screens/ (6 files, ~100-150 lines each) │ │ ├── HomeScreen.js │ │ ├── AlbumScreen.js │ │ ├── LikedTracksScreen.js │ │ ├── LoginScreen.js │ │ ├── SignUpScreen.js │ │ ├── PasswordResetScreen.js │ │ └── SettingsScreen.js │ ├── components/ (4 files) │ │ ├── Header.js │ │ ├── TrackRow.js │ │ ├── MediaPlayer.js │ │ └── DurationFormatter.js │ ├── contexts/ (1 file) │ │ └── LibraryContext.js │ ├── data/ (1 file) │ │ └── library.js (mock data) │ └── .expo/ ├── assets/ │ ├── covers/ (album cover images) │ ├── icon.png │ ├── splash-icon.png │ ├── adaptive-icon.png │ └── favicon.png └── admin_panel/ ├── src/ (7 files) └── package.json /home/mathias/jukebox/www/api/ (Laravel) ├── app/ │ ├── Http/Controllers/ │ ├── Models/ │ └── Providers/ ├── routes/api.php ├── database/ │ ├── migrations/ │ └── seeders/ └── config/ Total: ~1000+ lines of React Native code ~500+ lines of React admin code ~2000+ lines of Laravel PHP code ``` --- ## 🎯 KEY FINDINGS 1. **Mobile App**: Well-structured React Native project using Expo with clear separation of concerns (screens, components, contexts) 2. **State Management**: Uses React Context API - simple but sufficient for current size; could upgrade to Redux/Zustand if needed 3. **Design Consistency**: Dark theme throughout with consistent color palette and spacing 4. **Backend Ready**: Laravel API is built but mobile app hasn't been connected yet 5. **No Real Data Persistence**: Everything is in-memory state; needs localStorage/AsyncStorage or API integration 6. **Admin Panel**: Basic structure exists but needs implementation of actual pages 7. **Authentication Flow**: Designed but not implemented end-to-end --- **Report Generated**: May 12, 2026 **Explorer**: Claude Code **Status**: Ready for development phase