Adjust the site's logo design across the application to reflect updated branding guidelines. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d7424866-83d1-4486-a212-ac12b4c7becf Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/d7424866-83d1-4486-a212-ac12b4c7becf/rpyn1Rk
152 lines
5.2 KiB
TypeScript
152 lines
5.2 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { type Video } from "@shared/schema";
|
|
import SearchHeader from "@/components/search-header";
|
|
import VideoGrid from "@/components/video-grid";
|
|
|
|
|
|
interface VideosResponse {
|
|
videos: Video[];
|
|
total: number;
|
|
hasMore: boolean;
|
|
}
|
|
|
|
export default function Home() {
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
|
|
const [offset, setOffset] = useState(0);
|
|
const [allVideos, setAllVideos] = useState<Video[]>([]);
|
|
|
|
|
|
|
|
// Fetch videos
|
|
const { data: videosResponse, isLoading, refetch } = useQuery<VideosResponse>({
|
|
queryKey: ["/api/videos", {
|
|
limit: 20,
|
|
offset,
|
|
search: searchQuery || undefined
|
|
}],
|
|
queryFn: async ({ queryKey }) => {
|
|
const [, params] = queryKey as [string, any];
|
|
const searchParams = new URLSearchParams();
|
|
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
searchParams.append(key, String(value));
|
|
}
|
|
});
|
|
|
|
const response = await fetch(`/api/videos?${searchParams}`);
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch videos');
|
|
}
|
|
return response.json();
|
|
}
|
|
});
|
|
|
|
// Update videos when new data comes in
|
|
useEffect(() => {
|
|
if (videosResponse) {
|
|
if (offset === 0) {
|
|
setAllVideos(videosResponse.videos);
|
|
} else {
|
|
setAllVideos(prev => [...prev, ...videosResponse.videos]);
|
|
}
|
|
}
|
|
}, [videosResponse, offset]);
|
|
|
|
// Reset videos when search changes
|
|
const handleSearch = (query: string) => {
|
|
setSearchQuery(query);
|
|
setOffset(0);
|
|
setAllVideos([]);
|
|
};
|
|
|
|
const handleLoadMore = () => {
|
|
setOffset(prev => prev + 20);
|
|
};
|
|
|
|
// Force refetch when search changes
|
|
useEffect(() => {
|
|
refetch();
|
|
}, [searchQuery, offset, refetch]);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-bunny-dark">
|
|
<SearchHeader
|
|
onSearch={handleSearch}
|
|
onViewChange={setViewMode}
|
|
currentView={viewMode}
|
|
/>
|
|
|
|
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<VideoGrid
|
|
videos={allVideos}
|
|
isLoading={isLoading}
|
|
hasMore={videosResponse?.hasMore || false}
|
|
onLoadMore={handleLoadMore}
|
|
viewMode={viewMode}
|
|
/>
|
|
</main>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Footer */}
|
|
<footer className="bg-bunny-gray/50 border-t border-gray-700 mt-16">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
|
<div className="col-span-1 md:col-span-2">
|
|
<div className="flex items-center space-x-2 mb-4">
|
|
<div className="w-8 h-8 bg-bunny-blue rounded-lg flex items-center justify-center">
|
|
<div className="w-0 h-0 border-l-[5px] border-l-white border-y-[3px] border-y-transparent ml-0.5"></div>
|
|
</div>
|
|
<h3 className="text-xl font-bold text-bunny-light">go4.video</h3>
|
|
</div>
|
|
<p className="text-bunny-muted mb-4">
|
|
Fast, reliable, and globally distributed video streaming platform.
|
|
</p>
|
|
<div className="flex space-x-4">
|
|
<a href="#" className="text-bunny-muted hover:text-bunny-blue transition-colors">
|
|
Twitter
|
|
</a>
|
|
<a href="#" className="text-bunny-muted hover:text-bunny-blue transition-colors">
|
|
GitHub
|
|
</a>
|
|
<a href="#" className="text-bunny-muted hover:text-bunny-blue transition-colors">
|
|
LinkedIn
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 className="font-semibold mb-4 text-bunny-light">Platform</h4>
|
|
<ul className="space-y-2 text-bunny-muted">
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Upload</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Analytics</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">API Docs</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Support</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 className="font-semibold mb-4 text-bunny-light">Company</h4>
|
|
<ul className="space-y-2 text-bunny-muted">
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">About</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Privacy</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Terms</a></li>
|
|
<li><a href="#" className="hover:text-bunny-light transition-colors">Contact</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="border-t border-gray-700 mt-8 pt-8 text-center text-bunny-muted">
|
|
<p>© 2024 go4.video. All rights reserved.</p>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|