videofolxtv/client/src/pages/home.tsx
sebastjanartic 1a996d1009 Make video grid sections extend fully to the screen edges
Adjust padding and margins in the Netflix grid component and home page layout to ensure video sections display edge-to-edge.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 074b0e4c-6171-43bd-aa98-f9e04623ca14
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/074b0e4c-6171-43bd-aa98-f9e04623ca14/DVZN4Rp
2025-08-30 14:29:27 +00:00

168 lines
6.6 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";
import NetflixGrid from "@/components/netflix-grid";
import go4LogoPath from "@assets/go4_1756394900352.png";
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 with aggressive caching for speed
const { data: videosResponse, isLoading, refetch } = useQuery<VideosResponse>({
queryKey: ["/api/videos", {
limit: 1000, // Naloži vse videje naenkrat
offset: 0,
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();
},
staleTime: 5 * 60 * 1000, // 5 minutes cache - much faster
gcTime: 10 * 60 * 1000, // 10 minutes retention
refetchOnWindowFocus: false, // Don't refetch on focus
refetchOnReconnect: false // Don't refetch on reconnect
});
// Update videos when new data comes in
useEffect(() => {
if (videosResponse) {
setAllVideos(videosResponse.videos);
}
}, [videosResponse]);
// Reset videos when search changes
const handleSearch = (query: string) => {
setSearchQuery(query);
setAllVideos([]);
};
// Only refetch when search changes, not offset (for speed)
useEffect(() => {
if (searchQuery !== undefined) {
refetch();
}
}, [searchQuery, refetch]);
return (
<div className="min-h-screen bunny-dark static-triangles">
<SearchHeader
onSearch={handleSearch}
onViewChange={setViewMode}
currentView={viewMode}
/>
<main className="w-full pt-0 pb-8 relative">
{/* Trikotniki na robovih - ne prekrivajo video kartic */}
<div className="absolute top-10 right-2 w-0 h-0 border-l-[70px] border-l-transparent border-r-[70px] border-r-transparent border-b-[100px] border-b-blue-400/8 rotate-12 z-0"></div>
<div className="absolute top-1/2 left-2 w-0 h-0 border-l-[60px] border-l-transparent border-r-[60px] border-r-transparent border-b-[85px] border-b-purple-400/8 -rotate-12 z-0"></div>
<div className="absolute bottom-1/4 right-2 w-0 h-0 border-l-[50px] border-l-transparent border-r-[50px] border-r-transparent border-b-[70px] border-b-cyan-400/8 rotate-45 z-0"></div>
{viewMode === "grid" ? (
<NetflixGrid
videos={allVideos}
isLoading={isLoading}
/>
) : (
<VideoGrid
videos={allVideos}
isLoading={isLoading}
hasMore={false}
onLoadMore={() => {}}
viewMode={viewMode}
/>
)}
</main>
{/* Footer with large triangle design */}
<footer className="bunny-gray border-t border-white/20 mt-16 relative overflow-hidden">
{/* Trikotniki v footerju - manjši in bolje pozicionirani */}
<div className="absolute top-0 right-0 w-0 h-0 border-l-[80px] border-l-transparent border-b-[50px] border-b-blue-500/4 z-0"></div>
<div className="absolute bottom-0 left-0 w-0 h-0 border-r-[70px] border-r-transparent border-t-[45px] border-t-purple-500/4 z-0"></div>
<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 gradient-primary rounded-lg flex items-center justify-center shadow-lg">
<div className="w-0 h-0 border-l-[8px] border-l-white border-y-[5px] border-y-transparent ml-1"></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>&copy; 2024 go4.video. All rights reserved.</p>
</div>
</div>
</footer>
</div>
);
}