veza/apps/web/src/components/views/LiveView.tsx

157 lines
8.7 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import { Card } from '../ui/card';
import { Button } from '../ui/button';
import { Badge } from '../ui/badge';
2026-01-07 18:39:21 +00:00
import { Users, Heart, Share2, DollarSign, MessageSquare, Send, Radio, Settings, Maximize2 } from 'lucide-react';
import { LiveStream } from '../../types';
import { useToast } from '../../context/ToastContext';
const featuredStream: LiveStream = {
2026-01-07 18:39:21 +00:00
id: '1',
title: 'Late Night DnB Production 🎧 | Feedback Session',
streamer: 'Neuro_Glitch',
viewers: 1240,
thumbnailUrl: 'https://picsum.photos/id/140/800/450',
tags: ['Production', 'Ableton', 'DnB'],
isLive: true,
category: 'Production'
};
const chatMessages = [
2026-01-07 18:39:21 +00:00
{ user: 'BassHead99', text: 'That Reese bass is filthy! 🤮🔥', color: 'text-kodo-cyan' },
{ user: 'Studio_Rat', text: 'What VST is that?', color: 'text-gray-400' },
{ user: 'Neuro_Glitch', text: 'It\'s Phase Plant, just initializing now.', color: 'text-kodo-gold font-bold' },
{ user: 'VocalChops', text: 'Sent a $5 dono! Check my track?', color: 'text-kodo-lime' },
];
export const LiveView: React.FC = () => {
2026-01-07 18:39:21 +00:00
const { addToast } = useToast();
const [msgInput, setMsgInput] = useState('');
2026-01-07 18:39:21 +00:00
const handleSend = () => {
if (!msgInput) return;
addToast("Message sent to chat", "success");
setMsgInput('');
2026-01-07 18:39:21 +00:00
};
2026-01-07 18:39:21 +00:00
return (
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6 h-[calc(100vh-120px)] animate-fadeIn">
2026-01-07 18:39:21 +00:00
{/* Main Stream Area */}
<div className="lg:col-span-9 flex flex-col gap-4">
<div className="relative aspect-video bg-black rounded-xl overflow-hidden shadow-2xl border border-kodo-steel group">
{/* Mock Video Feed */}
<img src={featuredStream.thumbnailUrl} className="w-full h-full object-cover opacity-80" />
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent to-transparent"></div>
{/* Live Indicator */}
<div className="absolute top-4 left-4 flex gap-2">
<span className="bg-kodo-red text-white px-2 py-1 text-xs font-bold rounded flex items-center gap-1 animate-pulse">
<Radio className="w-3 h-3" /> LIVE
</span>
<span className="bg-black/50 backdrop-blur text-white px-2 py-1 text-xs font-mono rounded flex items-center gap-1">
<Users className="w-3 h-3" /> {featuredStream.viewers}
</span>
</div>
2026-01-07 18:39:21 +00:00
{/* Stream Controls Overlay */}
<div className="absolute bottom-0 left-0 right-0 p-4 flex justify-between items-end opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<div className="flex gap-4">
<Button variant="ghost" size="sm" className="text-white hover:bg-white/10" onClick={() => addToast("Chat hidden")}><MessageSquare className="w-5 h-5" /></Button>
<Button variant="ghost" size="sm" className="text-white hover:bg-white/10" onClick={() => addToast("Stream Settings")}><Settings className="w-5 h-5" /></Button>
</div>
<div className="flex gap-4">
<Button variant="ghost" size="sm" className="text-white hover:bg-white/10" onClick={() => addToast("Entering Fullscreen")}><Maximize2 className="w-5 h-5" /></Button>
</div>
</div>
</div>
2026-01-07 18:39:21 +00:00
{/* Stream Info */}
<div className="flex justify-between items-start">
<div className="flex gap-4">
<div className="w-12 h-12 rounded-full bg-gradient-neon p-0.5">
<img src="https://picsum.photos/100/100" className="w-full h-full rounded-full object-cover border-2 border-kodo-void" />
</div>
<div>
<h1 className="text-2xl font-bold text-white">{featuredStream.title}</h1>
<p className="text-kodo-cyan font-medium cursor-pointer hover:underline" onClick={() => addToast("Opening Streamer Profile")}>{featuredStream.streamer}</p>
<div className="flex gap-2 mt-2">
{featuredStream.tags.map(tag => (
<Badge key={tag} label={tag} variant="terminal" />
))}
</div>
</div>
</div>
2026-01-07 18:39:21 +00:00
<div className="flex gap-3">
<Button variant="secondary" icon={<Heart className="w-4 h-4" />} onClick={() => addToast("Followed Streamer", "success")}>FOLLOW</Button>
<Button variant="primary" icon={<DollarSign className="w-4 h-4" />} onClick={() => addToast("Donation modal opening...", "info")}>DONATE</Button>
<Button variant="ghost" icon={<Share2 className="w-4 h-4" />} onClick={() => addToast("Stream link copied!")}>SHARE</Button>
</div>
</div>
2026-01-07 18:39:21 +00:00
{/* Suggested Streams */}
<div className="mt-4">
<h3 className="font-bold text-gray-400 mb-4 uppercase text-sm tracking-wider">Recommended Channels</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{[1, 2, 3].map(i => (
<Card key={i} variant="default" className="p-0 overflow-hidden group cursor-pointer" onClick={() => addToast("Switching stream...")}>
<div className="aspect-video relative">
<img src={`https://picsum.photos/300/200?random=${i}`} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
<div className="absolute bottom-2 left-2 bg-kodo-void/80 px-2 py-0.5 rounded text-[10px] text-white">DJ Set</div>
</div>
2026-01-07 18:39:21 +00:00
<div className="p-3 flex gap-2">
<div className="w-8 h-8 rounded-full bg-gray-700"></div>
<div>
<div className="font-bold text-sm text-white truncate">Techno Bunker 24/7</div>
<div className="text-xs text-gray-500">Underground_Radio</div>
</div>
</div>
</Card>
))}
</div>
</div>
</div>
2026-01-07 18:39:21 +00:00
{/* Live Chat */}
<Card variant="gaming" className="lg:col-span-3 flex flex-col p-0 overflow-hidden h-full max-h-[calc(100vh-120px)]">
<div className="p-3 border-b border-kodo-steel/50 flex justify-between items-center bg-kodo-ink">
<span className="font-mono text-sm font-bold text-white">STREAM CHAT</span>
<div className="w-2 h-2 bg-kodo-lime rounded-full animate-pulse"></div>
</div>
2026-01-07 18:39:21 +00:00
<div className="flex-1 overflow-y-auto p-4 space-y-3 font-mono text-sm">
{chatMessages.map((msg, i) => (
<div key={i} className="break-words">
<span className={`font-bold ${msg.color} mr-2 cursor-pointer hover:underline`}>{msg.user}:</span>
<span className="text-gray-300">{msg.text}</span>
</div>
))}
<div className="text-center py-2">
<span className="text-[10px] text-gray-500 bg-kodo-slate px-2 py-1 rounded-full">Welcome to the chat room!</span>
</div>
</div>
2026-01-07 18:39:21 +00:00
<div className="p-3 bg-kodo-slate border-t border-kodo-steel">
<div className="flex gap-2">
<div className="relative flex-1">
<input
value={msgInput}
onChange={(e) => setMsgInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
className="w-full bg-kodo-ink border border-kodo-steel rounded px-3 py-2 text-sm text-white focus:border-kodo-cyan outline-none"
placeholder="Say something..."
/>
<DollarSign className="absolute right-2 top-1/2 -translate-y-1/2 w-4 h-4 text-kodo-gold cursor-pointer hover:scale-110 transition-transform" />
</div>
<Button variant="primary" size="sm" className="px-3" onClick={handleSend}><Send className="w-4 h-4" /></Button>
</div>
<div className="flex justify-between mt-2 px-1">
<span className="text-[10px] text-gray-500">Balance: 420 $VEZA</span>
<span className="text-[10px] text-kodo-cyan cursor-pointer" onClick={() => addToast("Opening Wallet...")}>Get Coins</span>
</div>
</div>
2026-01-07 18:39:21 +00:00
</Card>
2026-01-07 18:39:21 +00:00
</div>
);
};