diff --git a/frontend/src/pages/Stats.jsx b/frontend/src/pages/Stats.jsx index 47d6b337..160ca132 100644 --- a/frontend/src/pages/Stats.jsx +++ b/frontend/src/pages/Stats.jsx @@ -23,6 +23,7 @@ import useChannelsStore from '../store/channels'; import useLogosStore from '../store/logos'; import logo from '../images/logo.png'; import { + ChevronDown, Gauge, HardDriveDownload, HardDriveUpload, @@ -86,6 +87,7 @@ const getStartDate = (uptime) => { const VODCard = ({ vodContent }) => { const [dateFormatSetting] = useLocalStorage('date-format', 'mdy'); const dateFormat = dateFormatSetting === 'mdy' ? 'MM/DD' : 'DD/MM'; + const [isClientExpanded, setIsClientExpanded] = useState(false); // Get metadata from the VOD content const metadata = vodContent.content_metadata || {}; @@ -101,7 +103,7 @@ const VODCard = ({ vodContent }) => { // Get poster/logo URL const posterUrl = metadata.logo_url || logo; - // Format duration + // Format duration for content length const formatDuration = (seconds) => { if (!seconds) return 'Unknown'; const hours = Math.floor(seconds / 3600); @@ -112,9 +114,7 @@ const VODCard = ({ vodContent }) => { // Get display title const getDisplayTitle = () => { if (isMovie) { - return metadata.year - ? `${vodContent.content_name} (${metadata.year})` - : vodContent.content_name; + return vodContent.content_name; } else if (isEpisode) { const season = metadata.season_number ? `S${metadata.season_number.toString().padStart(2, '0')}` @@ -132,12 +132,24 @@ const VODCard = ({ vodContent }) => { if (isMovie) { const parts = []; if (metadata.genre) parts.push(metadata.genre); - if (metadata.rating) parts.push(`Rated ${metadata.rating}`); - return parts.join(' • '); + // We'll handle rating separately as a badge now + return parts; } else if (isEpisode) { - return metadata.episode_name || 'Episode'; + return [metadata.episode_name || 'Episode']; } - return ''; + return []; + }; + + // Render subtitle + const renderSubtitle = () => { + const subtitleParts = getSubtitle(); + if (subtitleParts.length === 0) return null; + + return ( + + {subtitleParts.join(' • ')} + + ); }; // Calculate duration for connection @@ -229,12 +241,16 @@ const VODCard = ({ vodContent }) => { - -
- - {formatDuration(metadata.duration_secs)} -
-
+ {connection && ( + +
+ + {calculateConnectionDuration(connection)} +
+
+ )}
@@ -277,22 +293,14 @@ const VODCard = ({ vodContent }) => { )} {/* Subtitle/episode info */} - {getSubtitle() && ( + {getSubtitle().length > 0 && ( - - {getSubtitle()} - + {renderSubtitle()} )} - {/* Content information badges */} + {/* Content information badges - streamlined to avoid duplication */} - - - {contentType.toUpperCase()} - - - {metadata.year && ( @@ -301,99 +309,143 @@ const VODCard = ({ vodContent }) => { )} + {metadata.duration_secs && ( + + + {formatDuration(metadata.duration_secs)} + + + )} + {metadata.rating && ( - + - {metadata.rating} - - - )} - - {metadata.genre && ( - - - {metadata.genre} - - - )} - - {isEpisode && metadata.season_number && ( - - - Season {metadata.season_number} + {parseFloat(metadata.rating).toFixed(1)}/10 )} - {/* Individual client information */} + {/* Client information section - collapsible like channel cards */} {connection && ( - - - - Client IP: - - - {connection.client_ip || 'Unknown'} - - - - - - Duration: - - {calculateConnectionDuration(connection)} - - - )} - - {/* Additional client details */} - {connection && ( - - {connection.user_agent && connection.user_agent !== 'Unknown' && ( - - - User Agent: - - - {connection.user_agent.length > 80 - ? `${connection.user_agent.substring(0, 80)}...` - : connection.user_agent} - - - )} - - - - Client ID: - - - {connection.client_id || 'Unknown'} - - - - {connection.connected_at && ( + + {/* Client summary header - always visible */} + setIsClientExpanded(!isClientExpanded)} + > - - Connected: + + Client: + + + {connection.client_ip || 'Unknown IP'} - {getConnectionStartTime(connection)} + + + + {isClientExpanded ? 'Hide Details' : 'Show Details'} + + + + + + {/* Expanded client details */} + {isClientExpanded && ( + + {connection.user_agent && + connection.user_agent !== 'Unknown' && ( + + + User Agent: + + + {connection.user_agent.length > 100 + ? `${connection.user_agent.substring(0, 100)}...` + : connection.user_agent} + + + )} + + + + Client ID: + + + {connection.client_id || 'Unknown'} + + + + {connection.connected_at && ( + + + Connected: + + {getConnectionStartTime(connection)} + + )} + + {connection.duration && connection.duration > 0 && ( + + + Watch Duration: + + + {dayjs + .duration(connection.duration, 'seconds') + .humanize()} + + + )} + )} )}