videofolxtv/client/src/pages/PlayerPage.tsx
sebastjanartic 120fd478e8 Improve page titles and meta descriptions for better search engine visibility
Updates titles, meta descriptions, and Open Graph tags across various pages and API responses for improved SEO and language consistency.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 401e2ec0-e00d-4f10-9d0e-60f3d479f9a5
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: b39b5688-81f4-4af3-b05c-9c9e8c4350ff
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/401e2ec0-e00d-4f10-9d0e-60f3d479f9a5/qFrskyV
2026-02-13 17:39:39 +00:00

223 lines
8.8 KiB
TypeScript

import { useState, useEffect } from 'react';
import { ChevronLeft, Menu, X, Search, Tv } from 'lucide-react';
import { Link } from 'wouter';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useQuery } from '@tanstack/react-query';
import VideoCard from '@/components/video-card';
import HeaderAd from '@/components/HeaderAd';
export default function PlayerPage() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const { data: videosData } = useQuery({
queryKey: ['/api/videos'],
staleTime: 5 * 60 * 1000,
});
const videos = (videosData && Array.isArray((videosData as any).videos)) ? (videosData as any).videos : [];
useEffect(() => {
document.title = 'Professional Player | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'Professioneller Video Player mit Overlay Graphics und Streaming-Funktionen. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
}
}, []);
const handleSearch = (e: React.FormEvent) => {
e.preventDefault();
if (searchQuery.trim()) {
window.location.href = `/?search=${encodeURIComponent(searchQuery)}`;
}
};
return (
<div className="min-h-screen bg-gradient-to-b from-[#0f0f14] to-[#1a1a24]">
<header className="sticky top-0 z-50 bg-[#0f0f14]/95 backdrop-blur-sm border-b border-gray-800/50">
<div className="max-w-7xl mx-auto px-4 py-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Link href="/">
<Button variant="ghost" size="icon" className="text-gray-400 hover:text-white">
<ChevronLeft className="h-5 w-5" />
</Button>
</Link>
<Link href="/">
<img
src="https://folx.tv/images/logo.svg"
alt="FOLX.TV"
className="h-8 cursor-pointer hover:opacity-80 transition-opacity"
/>
</Link>
</div>
<nav className="hidden md:flex items-center gap-6">
<Link href="/" className="text-gray-300 hover:text-white transition-colors text-sm font-medium">
Videos
</Link>
<Link href="/live" className="text-gray-300 hover:text-white transition-colors text-sm font-medium">
LIVE
</Link>
<Link href="/player" className="text-pink-500 transition-colors text-sm font-medium flex items-center gap-1">
<Tv className="h-4 w-4" />
Player
</Link>
</nav>
<div className="flex items-center gap-3">
<form onSubmit={handleSearch} className="hidden md:flex relative">
<Input
type="text"
placeholder="Suchen..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-64 bg-gray-800/50 border-gray-700 text-white placeholder:text-gray-500 pr-10"
/>
<Button
type="submit"
size="icon"
variant="ghost"
className="absolute right-0 top-0 h-full text-gray-400 hover:text-white"
>
<Search className="h-4 w-4" />
</Button>
</form>
<Button
variant="ghost"
size="icon"
className="md:hidden text-gray-400 hover:text-white"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
>
{isMobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
</Button>
</div>
</div>
{isMobileMenuOpen && (
<div className="md:hidden mt-4 pb-4 border-t border-gray-800 pt-4">
<nav className="flex flex-col gap-3">
<Link href="/" className="text-gray-300 hover:text-white transition-colors text-sm font-medium py-2">
Videos
</Link>
<Link href="/live" className="text-gray-300 hover:text-white transition-colors text-sm font-medium py-2">
LIVE
</Link>
<Link href="/player" className="text-pink-500 transition-colors text-sm font-medium py-2 flex items-center gap-2">
<Tv className="h-4 w-4" />
Player
</Link>
</nav>
<form onSubmit={handleSearch} className="mt-4 relative">
<Input
type="text"
placeholder="Suchen..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full bg-gray-800/50 border-gray-700 text-white placeholder:text-gray-500 pr-10"
/>
<Button
type="submit"
size="icon"
variant="ghost"
className="absolute right-0 top-0 h-full text-gray-400 hover:text-white"
>
<Search className="h-4 w-4" />
</Button>
</form>
</div>
)}
</div>
</header>
<HeaderAd />
<main className="max-w-7xl mx-auto px-4 py-6">
<div className="flex items-center gap-3 mb-6">
<div className="bg-gradient-to-r from-pink-500 to-purple-600 p-2 rounded-lg">
<Tv className="h-6 w-6 text-white" />
</div>
<div>
<h1 className="text-2xl md:text-3xl font-bold text-white">Professional Player</h1>
<p className="text-gray-400 text-sm">MTV-Style Overlay Graphics & Streaming</p>
</div>
</div>
<div className="bg-black rounded-xl overflow-hidden shadow-2xl mb-8">
<div style={{ position: 'relative', paddingBottom: '56.25%', height: 0, overflow: 'hidden' }}>
<iframe
src="https://player-one-sebastjanartic.replit.app/professional-player"
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
border: 'none'
}}
allowFullScreen
allow="autoplay; fullscreen"
title="Professional Video Player"
/>
</div>
</div>
<div className="bg-gray-800/30 rounded-xl p-6 mb-8">
<h2 className="text-xl font-semibold text-white mb-4">Embed Code</h2>
<p className="text-gray-400 text-sm mb-4">Kopieren Sie diesen Code, um den Player auf Ihrer Website einzubetten:</p>
<div className="bg-gray-900 rounded-lg p-4 overflow-x-auto">
<code className="text-green-400 text-sm whitespace-pre-wrap break-all">
{`<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe
src="https://player-one-sebastjanartic.replit.app/professional-player"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
allowfullscreen
allow="autoplay; fullscreen">
</iframe>
</div>`}
</code>
</div>
<Button
className="mt-4 bg-pink-600 hover:bg-pink-700"
onClick={() => {
navigator.clipboard.writeText(`<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe
src="https://player-one-sebastjanartic.replit.app/professional-player"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
allowfullscreen
allow="autoplay; fullscreen">
</iframe>
</div>`);
alert('Code kopiert!');
}}
>
Code kopieren
</Button>
</div>
{videos.length > 0 && (
<section>
<h2 className="text-xl font-semibold text-white mb-4">Empfohlene Videos</h2>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
{videos.slice(0, 10).map((video: any) => (
<VideoCard key={video.id} video={video} onClick={() => window.location.href = `/video/${video.id.replace(/-/g, '').substring(0, 8)}`} />
))}
</div>
</section>
)}
</main>
<footer className="bg-[#0a0a0f] border-t border-gray-800 py-8 mt-12">
<div className="max-w-7xl mx-auto px-4 text-center">
<p className="text-gray-500 text-sm">
© 2025 FOLX.TV - Alle Rechte vorbehalten
</p>
</div>
</footer>
</div>
);
}