From 7651f730fdb5ae653f688b0811e04f9e693190f2 Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Mon, 1 Sep 2025 18:14:46 +0000 Subject: [PATCH] Organize videos into categories with improved navigation and search functionality Introduces video categorization on the home page, including "Meist Angesehen", "FOLX STADL Shows", "Neue Videos", and "Alle Videos". Adds pagination buttons (ChevronLeft, ChevronRight) and updates placeholder text to Slovenian ("Videos suchen...", "Suchen..."). Refactors the header background and gradient for the main content. Replaces skeleton loading with a grid layout for fetched videos. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 890577b1-c154-40a4-a177-a0c6d55320c3 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/890577b1-c154-40a4-a177-a0c6d55320c3/aC8PHqS --- client/src/pages/home.tsx | 159 +++++++++++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 21 deletions(-) diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index a619322..3f8ad41 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -1,10 +1,11 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { useQuery } from "@tanstack/react-query"; import { type Video } from "@shared/schema"; import VideoCard from "@/components/video-card"; import { Link } from "wouter"; import { Input } from "@/components/ui/input"; -import { Search, Menu, X } from "lucide-react"; +import { Search, Menu, X, ChevronLeft, ChevronRight } from "lucide-react"; +import { Button } from "@/components/ui/button"; interface VideosResponse { videos: Video[]; @@ -12,6 +13,11 @@ interface VideosResponse { hasMore: boolean; } +interface VideoCategory { + title: string; + videos: Video[]; +} + export default function Home() { const [searchQuery, setSearchQuery] = useState(""); const [allVideos, setAllVideos] = useState([]); @@ -57,10 +63,47 @@ export default function Home() { window.location.href = `/video/${video.id}`; }; + // Organize videos into categories like ZDF + const getCategories = (): VideoCategory[] => { + if (!allVideos.length) return []; + + // Sort by views for popular content + const sortedByViews = [...allVideos].sort((a, b) => (b.views || 0) - (a.views || 0)); + + // Sort by date for recently added + const sortedByDate = [...allVideos].sort((a, b) => + new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + ); + + // FOLX STADL videos + const folxStadlVideos = allVideos.filter(video => + video.title.includes("FOLX STADL") || video.title.includes("FOLXSTADL") + ); + + return [ + { + title: "Meist Angesehen", + videos: sortedByViews.slice(0, 12) + }, + ...(folxStadlVideos.length > 0 ? [{ + title: "FOLX STADL Shows", + videos: folxStadlVideos.slice(0, 12) + }] : []), + { + title: "Neue Videos", + videos: sortedByDate.slice(0, 12) + }, + { + title: "Alle Videos", + videos: allVideos.slice(0, 15) + } + ]; + }; + return ( -
+
{/* Header */} -
+
{/* Logo */} @@ -87,7 +130,7 @@ export default function Home() {
setSearchQuery(e.target.value)} className="bg-white/10 border-white/20 text-white placeholder-white/50 w-64" @@ -116,7 +159,7 @@ export default function Home() {
setSearchQuery(e.target.value)} className="bg-white/10 border-white/20 text-white placeholder-white/50 w-full" @@ -131,25 +174,31 @@ export default function Home() { {/* Main Content */}
{isLoading ? ( -
- {Array.from({ length: 15 }).map((_, index) => ( -
-
-
-
-
+
+ {Array.from({ length: 3 }).map((_, categoryIndex) => ( +
+
+
+ {Array.from({ length: 6 }).map((_, index) => ( +
+
+
+
+
+
+
+ ))}
))}
) : ( -
- {allVideos.map((video) => ( - + {getCategories().map((category, categoryIndex) => ( + ))}
@@ -157,10 +206,78 @@ export default function Home() { {allVideos.length === 0 && !isLoading && (
-
No videos found
+
Keine Videos gefunden
)}
); +} + +interface CategorySectionProps { + category: VideoCategory; + onVideoClick: (video: Video) => void; +} + +function CategorySection({ category, onVideoClick }: CategorySectionProps) { + const scrollRef = useRef(null); + + const scroll = (direction: 'left' | 'right') => { + if (scrollRef.current) { + const scrollAmount = 320; // Width of one card + gap + const newScrollLeft = scrollRef.current.scrollLeft + (direction === 'right' ? scrollAmount : -scrollAmount); + scrollRef.current.scrollTo({ + left: newScrollLeft, + behavior: 'smooth' + }); + } + }; + + return ( +
+

+ {category.title} +

+ +
+ {/* Left scroll button */} + + + {/* Right scroll button */} + + + {/* Scrollable video row */} +
+ {category.videos.map((video) => ( +
+ +
+ ))} +
+
+
+ ); } \ No newline at end of file