videofolxtv/client/src/components/video-grid.tsx
sebastjanartic b5f0b50c4a Update platform branding and sharing links to reflect the new domain name
This commit updates all instances of the old domain name "go4.video" to the new domain name "video.folx.tv" across various frontend components, including modals, headers, cards, and page metadata. It also includes updates to sharing intent URLs for Twitter and WhatsApp to use the new domain. Additionally, CSS for Video.js loading animations has been added to `index.css`.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 946a0075-7e32-454b-b348-9e7f576d7f45
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/946a0075-7e32-454b-b348-9e7f576d7f45/jh6R7y2
2025-09-04 13:34:31 +00:00

116 lines
3.7 KiB
TypeScript

import { useState } from "react";
import { type Video } from "@shared/schema";
import VideoCard from "./video-card";
import BunnyVideoModal from "./bunny-video-modal";
import { Button } from "@/components/ui/button";
import { ChevronDown } from "lucide-react";
interface VideoGridProps {
videos: Video[];
isLoading: boolean;
hasMore: boolean;
onLoadMore: () => void;
viewMode: "grid" | "list";
}
export default function VideoGrid({ videos, isLoading, hasMore, onLoadMore, viewMode }: VideoGridProps) {
const [selectedVideo, setSelectedVideo] = useState<Video | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const handleVideoClick = (video: Video) => {
// Navigate to individual video page instead of modal
window.location.href = `/video/${video.id}`;
};
const handleCloseModal = () => {
setIsModalOpen(false);
setSelectedVideo(null);
};
const handleVideoChange = (video: Video) => {
setSelectedVideo(video);
};
if (isLoading && videos.length === 0) {
return (
<div className="flex items-center justify-center py-20" data-testid="grid-loading">
<div className="text-center">
<div className="w-16 h-16 gradient-primary rounded-lg flex items-center justify-center shadow-lg animate-pulse mb-4 mx-auto">
<div className="w-0 h-0 border-l-[12px] border-l-white border-y-[9px] border-y-transparent ml-1"></div>
</div>
<h3 className="text-white text-xl font-bold mb-2">video.folx.tv</h3>
<p className="text-bunny-light">Loading videos...</p>
</div>
</div>
);
}
if (videos.length === 0) {
return (
<div className="text-center py-12">
<div className="w-12 h-12 gradient-primary rounded-lg flex items-center justify-center shadow-lg mb-4 mx-auto opacity-50">
<div className="w-0 h-0 border-l-[9px] border-l-white border-y-[7px] border-y-transparent ml-1"></div>
</div>
<div className="text-bunny-muted text-lg mb-4" data-testid="text-no-videos">
No videos found
</div>
<p className="text-sm text-bunny-muted">
Try adjusting your search or filter criteria
</p>
</div>
);
}
const gridClass = viewMode === "grid"
? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
: "grid grid-cols-1 gap-4";
return (
<>
<div className={gridClass} data-testid="grid-videos">
{videos.map((video) => (
<VideoCard
key={video.id}
video={video}
onClick={handleVideoClick}
/>
))}
</div>
{hasMore && (
<div className="text-center mt-12">
<Button
onClick={onLoadMore}
disabled={isLoading}
className="bg-bunny-blue hover:bg-blue-600 text-white px-8 py-3 rounded-lg font-medium transition-colors inline-flex items-center space-x-2"
data-testid="button-load-more"
>
{isLoading ? (
<>
<div className="w-4 h-4 gradient-primary rounded flex items-center justify-center animate-pulse">
<div className="w-0 h-0 border-l-[3px] border-l-white border-y-[2px] border-y-transparent"></div>
</div>
<span>Loading more...</span>
</>
) : (
<>
<span>Load more videos</span>
<ChevronDown className="w-4 h-4" />
</>
)}
</Button>
</div>
)}
<BunnyVideoModal
video={selectedVideo}
isOpen={isModalOpen}
onClose={handleCloseModal}
videos={videos}
onVideoChange={handleVideoChange}
/>
</>
);
}