Adapt video card display for mobile devices with collapsed descriptions

Refactor the `VideoCard` component to conditionally render content for mobile devices, collapsing the video title and description with a "show more" option.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1/4DOsXkx
This commit is contained in:
sebastjanartic 2025-09-02 15:57:00 +00:00
parent b964b61f58
commit b1b7dae384

View File

@ -47,11 +47,15 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
const [isHovered, setIsHovered] = useState(false);
const [showPreview, setShowPreview] = useState(false);
const [isMuted, setIsMuted] = useState(true);
const [showMoreInfo, setShowMoreInfo] = useState(false);
const hoverTimeoutRef = useRef<NodeJS.Timeout>();
const videoRef = useRef<HTMLVideoElement>(null);
const hlsRef = useRef<Hls | null>(null);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
// Check if device is mobile
const isMobile = window.innerWidth < 768;
// Load mute preference on component mount
useEffect(() => {
@ -152,9 +156,9 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
return (
<div
data-testid={`card-video-${video.id}`}
className={`video-card transition-transform duration-200 hover:scale-[1.02] ${className}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className={`video-card transition-transform duration-200 ${isMobile ? '' : 'hover:scale-[1.02]'} ${className}`}
onMouseEnter={() => !isMobile && setIsHovered(true)}
onMouseLeave={() => !isMobile && setIsHovered(false)}
>
{/* Video preview container */}
<div
@ -269,8 +273,8 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
)}
{/* Modern gradient overlay with title */}
{!showPreview && !hideOverlay && (
{/* Desktop gradient overlay with title - hidden on mobile */}
{!showPreview && !hideOverlay && !isMobile && (
<div className="absolute inset-0 bg-gradient-to-t from-black/90 via-black/20 to-transparent z-10 flex items-end p-4 group-hover:from-black/95 transition-all duration-300">
<div className="w-full">
<h3 className="text-white font-extrabold text-xl leading-tight drop-shadow-2xl tracking-wide transform group-hover:scale-105 transition-transform duration-300 mb-1" style={{fontFamily: 'Poppins, Inter, sans-serif', textShadow: '2px 2px 8px rgba(0,0,0,0.8)'}}>
@ -280,13 +284,52 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
{video.title.split(' - ')[1] || video.title}
</p>
</div>
</div>
)}
</div>
{/* Mobile info section - below video */}
{isMobile && (
<div className="mt-3 px-1">
{/* Title */}
<h3 className="text-white font-bold text-base leading-tight mb-2 line-clamp-1" style={{fontFamily: 'Poppins, Inter, sans-serif'}}>
{video.title.split(' - ')[0] || 'go4.video'}
</h3>
{/* Duration and Views in one line */}
<div className="flex items-center justify-between text-white/70 text-sm mb-2">
<span>{formatViews(video.views || 0)}</span>
<span>{formatDate(video.createdAt)}</span>
</div>
{/* Show More / Show Less button */}
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setShowMoreInfo(!showMoreInfo);
}}
className="text-white/60 hover:text-white/80 text-sm transition-colors duration-200"
>
{showMoreInfo ? 'Pokaži manj' : 'Pokaži več'}
</button>
{/* Expandable info */}
{showMoreInfo && (
<div className="mt-2 text-white/70 text-sm space-y-1">
<p className="line-clamp-3">
{video.title.split(' - ')[1] || video.title}
</p>
{video.description && (
<p className="line-clamp-2 text-xs text-white/60">
{video.description}
</p>
)}
</div>
)}
</div>
)}
</div>
);
}