From 28ad6d12a7a718e48e6e5dfccfd4c2756aa0f0bc Mon Sep 17 00:00:00 2001 From: JSC Date: Sat, 12 Jul 2025 22:00:16 +0200 Subject: [PATCH] refactor: remove unused pages and components, streamline Admin and Dashboard functionality --- src/App.tsx | 28 --- src/components/sidebar/AppSidebar.tsx | 12 +- src/pages/ActivityPage.tsx | 274 --------------------- src/pages/AdminSoundsPage.tsx | 335 +------------------------- src/pages/AdminUsersPage.tsx | 153 ------------ src/pages/DashboardPage.tsx | 112 +-------- 6 files changed, 5 insertions(+), 909 deletions(-) delete mode 100644 src/pages/ActivityPage.tsx delete mode 100644 src/pages/AdminUsersPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 1b03b11..0bd1350 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,6 @@ import { AuthProvider } from '@/components/AuthProvider' import { SocketProvider } from '@/contexts/SocketContext' import { MusicPlayerProvider } from '@/contexts/MusicPlayerContext' import { AccountPage } from '@/pages/AccountPage' -import { ActivityPage } from '@/pages/ActivityPage' import { AdminUsersPage } from '@/pages/AdminUsersPage' import { AdminSoundsPage } from '@/pages/AdminSoundsPage' import { DashboardPage } from '@/pages/DashboardPage' @@ -42,19 +41,6 @@ function App() { } /> - - - - - - } - /> } /> - - Add User} - > - - - - } - /> ([]); - const [myStats, setMyStats] = useState(null); - const [popularSounds, setPopularSounds] = useState([]); - const [loading, setLoading] = useState(true); - const [activeTab, setActiveTab] = useState<'recent' | 'mystats' | 'popular'>('recent'); - - useEffect(() => { - fetchData(); - }, []); - - const fetchData = async () => { - try { - setLoading(true); - await Promise.all([ - fetchRecentPlays(), - fetchMyStats(), - fetchPopularSounds(), - ]); - } catch (err) { - console.error('Error fetching activity data:', err); - } finally { - setLoading(false); - } - }; - - const fetchRecentPlays = async () => { - try { - const response = await apiService.get('/api/soundboard/history?per_page=20'); - const data = await response.json(); - setRecentPlays(data.plays || []); - } catch (err) { - console.error('Error fetching recent plays:', err); - } - }; - - const fetchMyStats = async () => { - try { - const response = await apiService.get('/api/soundboard/my-stats'); - const data = await response.json(); - setMyStats(data); - } catch (err) { - console.error('Error fetching my stats:', err); - } - }; - - const fetchPopularSounds = async () => { - try { - const response = await apiService.get('/api/soundboard/popular?limit=10'); - const data = await response.json(); - setPopularSounds(data.popular_sounds || []); - } catch (err) { - console.error('Error fetching popular sounds:', err); - } - }; - - const formatRelativeTime = (dateString: string) => { - const date = new Date(dateString); - const now = new Date(); - const diff = now.getTime() - date.getTime(); - const minutes = Math.floor(diff / 60000); - const hours = Math.floor(diff / 3600000); - const days = Math.floor(diff / 86400000); - - if (minutes < 1) return 'Just now'; - if (minutes < 60) return `${minutes}m ago`; - if (hours < 24) return `${hours}h ago`; - return `${days}d ago`; - }; - - if (loading) { - return ( -
-
Loading activity...
-
- ); - } - - return ( -
- {/* Tab Navigation */} -
- - - -
- - {/* Recent Activity Tab */} - {activeTab === 'recent' && ( - - - - - Recent Activity - - - -
- {recentPlays.map((play) => ( -
-
- -
-
- {play.sound?.name || 'Unknown Sound'} -
-
- by {play.user?.name || 'Unknown User'} -
-
-
-
- {formatRelativeTime(play.played_at)} -
-
- ))} - {recentPlays.length === 0 && ( -
- No recent activity found. -
- )} -
-
-
- )} - - {/* My Statistics Tab */} - {activeTab === 'mystats' && myStats && ( -
- - - Total Plays - - - -
{myStats.total_plays}
-
-
- - - - Unique Sounds - - - -
{myStats.unique_sounds}
-
-
- - {myStats.favorite_sound && ( - - - Favorite Sound - - - -
{myStats.favorite_sound.sound.name}
-
- {myStats.favorite_sound.play_count} plays -
-
-
- )} -
- )} - - {/* Popular Sounds Tab */} - {activeTab === 'popular' && ( - - - - - Popular Sounds - - - -
- {popularSounds.map((item, index) => ( -
-
-
- {index + 1} -
-
-
{item.sound.name}
-
- {item.play_count} plays -
-
-
- {item.last_played && ( -
- Last: {formatRelativeTime(item.last_played)} -
- )} -
- ))} - {popularSounds.length === 0 && ( -
- No popular sounds found. -
- )} -
-
-
- )} -
- ); -} \ No newline at end of file diff --git a/src/pages/AdminSoundsPage.tsx b/src/pages/AdminSoundsPage.tsx index 253ff65..44711a7 100644 --- a/src/pages/AdminSoundsPage.tsx +++ b/src/pages/AdminSoundsPage.tsx @@ -1,129 +1,30 @@ -import { useState, useEffect } from 'react'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { RefreshCw, - Volume2, - Trash2, - CheckCircle, - XCircle, - AlertCircle, Database, Zap } from 'lucide-react'; import { toast } from 'sonner'; import { apiService } from '@/services/api'; -interface Sound { - id: number; - name: string; - filename: string; - type: string; - duration: number; - size: number; - play_count: number; - is_normalized: boolean; - normalized_filename?: string; - original_exists: boolean; - normalized_exists: boolean; - created_at: string; -} - -interface ScanStats { - total_sounds: number; - soundboard_sounds: number; - music_sounds: number; - total_size_bytes: number; - total_duration: number; - total_plays: number; -} - -interface NormalizationStats { - total_sounds: number; - normalized_count: number; - normalization_percentage: number; - total_original_size: number; - total_normalized_size: number; - size_difference: number; -} - export function AdminSoundsPage() { - const [sounds, setSounds] = useState([]); - const [scanStats, setScanStats] = useState(null); - const [normalizationStats, setNormalizationStats] = useState(null); - const [loading, setLoading] = useState(false); const [scanning, setScanning] = useState(false); const [normalizing, setNormalizing] = useState(false); - const [error, setError] = useState(null); - const [page, setPage] = useState(1); - const [totalPages, setTotalPages] = useState(1); - - useEffect(() => { - fetchData(); - }, [page]); - - const fetchData = async () => { - await Promise.all([ - fetchSounds(), - fetchScanStats(), - fetchNormalizationStats() - ]); - }; - - const fetchSounds = async () => { - try { - setLoading(true); - const response = await apiService.get(`/api/admin/sounds/list?page=${page}&per_page=20`); - const data = await response.json(); - setSounds(data.sounds || []); - setTotalPages(data.pagination?.pages || 1); - } catch (err) { - setError('Failed to load sounds'); - toast.error('Failed to load sounds'); - console.error('Error fetching sounds:', err); - } finally { - setLoading(false); - } - }; - - const fetchScanStats = async () => { - try { - const response = await apiService.get('/api/admin/sounds/scan/status'); - const data = await response.json(); - setScanStats(data); - } catch (err) { - console.error('Error fetching scan stats:', err); - } - }; - - const fetchNormalizationStats = async () => { - try { - const response = await apiService.get('/api/admin/sounds/normalize/status'); - const data = await response.json(); - setNormalizationStats(data); - } catch (err) { - console.error('Error fetching normalization stats:', err); - } - }; const handleScanSounds = async () => { try { setScanning(true); - setError(null); const response = await apiService.post('/api/admin/sounds/scan'); const data = await response.json(); if (response.ok) { toast.success(`Scan completed: ${data.files_added} new sounds added, ${data.files_skipped} skipped`); - await fetchData(); } else { - setError(data.error || 'Scan failed'); toast.error(data.error || 'Scan failed'); } - } catch (err) { - setError('Failed to scan sounds'); + } catch { toast.error('Failed to scan sounds'); - console.error('Error scanning sounds:', err); } finally { setScanning(false); } @@ -132,7 +33,6 @@ export function AdminSoundsPage() { const handleNormalizeAll = async () => { try { setNormalizing(true); - setError(null); const response = await apiService.post('/api/admin/sounds/normalize', { overwrite: false, two_pass: true @@ -141,89 +41,16 @@ export function AdminSoundsPage() { if (response.ok) { toast.success(`Normalization completed: ${data.successful} successful, ${data.failed} failed, ${data.skipped} skipped`); - await fetchData(); } else { - setError(data.error || 'Normalization failed'); toast.error(data.error || 'Normalization failed'); } - } catch (err) { - setError('Failed to normalize sounds'); + } catch { toast.error('Failed to normalize sounds'); - console.error('Error normalizing sounds:', err); } finally { setNormalizing(false); } }; - const handleNormalizeSound = async (soundId: number) => { - try { - const response = await apiService.post(`/api/admin/sounds/${soundId}/normalize`, { - overwrite: false, - two_pass: true - }); - const data = await response.json(); - - if (response.ok) { - toast.success('Sound normalized successfully'); - await fetchData(); - } else { - toast.error(`Normalization failed: ${data.error}`); - } - } catch (err) { - toast.error('Failed to normalize sound'); - console.error('Error normalizing sound:', err); - } - }; - - const handleDeleteSound = async (soundId: number, soundName: string) => { - const confirmDelete = () => { - toast.promise( - (async () => { - const response = await apiService.delete(`/api/admin/sounds/${soundId}`); - const data = await response.json(); - - if (response.ok) { - await fetchData(); - return `Sound "${soundName}" deleted successfully`; - } else { - throw new Error(data.error || 'Delete failed'); - } - })(), - { - loading: `Deleting "${soundName}"...`, - success: (message) => message, - error: (err) => `Failed to delete sound: ${err.message}`, - } - ); - }; - - toast(`Are you sure you want to delete "${soundName}"?`, { - action: { - label: 'Delete', - onClick: confirmDelete, - }, - cancel: { - label: 'Cancel', - onClick: () => {}, - }, - }); - }; - - const formatFileSize = (bytes: number) => { - if (bytes === 0) return '0 B'; - const k = 1024; - const sizes = ['B', 'KB', 'MB', 'GB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; - }; - - const formatDuration = (ms: number) => { - const seconds = Math.floor(ms / 1000); - const mins = Math.floor(seconds / 60); - const secs = seconds % 60; - return `${mins}:${secs.toString().padStart(2, '0')}`; - }; - return (
@@ -246,162 +73,6 @@ export function AdminSoundsPage() {
- - {error && ( -
- {error} -
- )} - - {/* Statistics Cards */} -
- {scanStats && ( - - - Total Sounds - - - -
{scanStats.total_sounds}
-

- {scanStats.soundboard_sounds} soundboard, {scanStats.music_sounds} music -

-
-
- )} - - {normalizationStats && ( - - - Normalized - - - -
{normalizationStats.normalized_count}
-

- {normalizationStats.normalization_percentage.toFixed(1)}% of total sounds -

-
-
- )} - - {scanStats && ( - - - Total Size - - - -
{formatFileSize(scanStats.total_size_bytes)}
-

- {scanStats.total_plays} total plays -

-
-
- )} -
- - {/* Sounds List */} - - - Sounds ({sounds.length}) - - - {loading ? ( -
- -
- ) : ( -
- {sounds.map((sound) => ( -
-
-
-

{sound.name}

-
- {sound.original_exists ? ( -
- -
- ) : ( -
- -
- )} - {sound.is_normalized ? ( - sound.normalized_exists ? ( -
- -
- ) : ( -
- -
- ) - ) : ( -
- -
- )} -
-
-
- {sound.filename} • {formatFileSize(sound.size)} • {formatDuration(sound.duration)} • {sound.play_count} plays -
-
-
- {!sound.is_normalized && ( - - )} - -
-
- ))} -
- )} - - {/* Pagination */} - {totalPages > 1 && ( -
- - - Page {page} of {totalPages} - - -
- )} -
-
); } \ No newline at end of file diff --git a/src/pages/AdminUsersPage.tsx b/src/pages/AdminUsersPage.tsx deleted file mode 100644 index a892258..0000000 --- a/src/pages/AdminUsersPage.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Button } from '@/components/ui/button' -import { useAuth } from '@/hooks/use-auth' - -export function AdminUsersPage() { - const { user } = useAuth() - - // Mock user data - in real app this would come from API - const users = [ - { - id: '1', - name: 'John Doe', - email: 'john@example.com', - role: 'admin', - is_active: true, - providers: ['password', 'google'], - created_at: '2024-01-15T10:30:00Z' - }, - { - id: '2', - name: 'Jane Smith', - email: 'jane@example.com', - role: 'user', - is_active: true, - providers: ['github'], - created_at: '2024-01-20T14:15:00Z' - }, - { - id: '3', - name: 'Bob Wilson', - email: 'bob@example.com', - role: 'user', - is_active: false, - providers: ['password'], - created_at: '2024-01-25T09:45:00Z' - } - ] - - if (user?.role !== 'admin') { - return ( -
- - - Access Denied - You don't have permission to access this page. - - -
- ) - } - - return ( -
- - - Users - All registered users in the system - - -
- {users.map((userData) => ( -
-
-
- - {userData.name.split(' ').map(n => n[0]).join('')} - -
- -
-
- {userData.name} - - {userData.role} - - {!userData.is_active && ( - - Disabled - - )} -
-

{userData.email}

-
- {userData.providers.map((provider) => ( - - {provider} - - ))} -
-
-
- -
- - -
-
- ))} -
-
-
- -
- - - Total Users - - -
{users.length}
-

Registered users

-
-
- - - - Active Users - - -
{users.filter(u => u.is_active).length}
-

Currently active

-
-
- - - - Admins - - -
{users.filter(u => u.role === 'admin').length}
-

Administrator accounts

-
-
-
-
- ) -} \ No newline at end of file diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 9f95d90..e850073 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -1,7 +1,4 @@ -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Button } from '@/components/ui/button' import { useAuth } from '@/hooks/use-auth' -import { Link } from 'react-router' export function DashboardPage() { const { user } = useAuth() @@ -9,113 +6,6 @@ export function DashboardPage() { if (!user) return null return ( -
-
- {/* User Profile Card */} - - - Profile Information - Your account details - - -
- {user.picture && ( - Profile - )} -
-

{user.name}

-

{user.email}

-
-
-
- - {user.role} - - {user.is_active && ( - - Active - - )} -
-
-
- - {/* Authentication Methods Card */} - - - Authentication Methods - How you can sign in - - -
- {user.providers.map((provider) => ( -
- {provider} - Connected -
- ))} -
-
-
- - {/* Quick Actions Card */} - - - Quick Actions - Common tasks and shortcuts - - - - - - - - - {user.role === 'admin' && ( - - - - )} - - -
- - {/* Admin Section */} - {user.role === 'admin' && ( - - - Admin Panel - Administrative functions and system overview - - -

- You have administrator privileges. You can manage users and system settings. -

-
- - - - - - -
-
-
- )} -
+
Dashboard
) } \ No newline at end of file