live / dashboard /components /SceneControl.tsx
ayush77uh's picture
fff
41ffa03
Raw
History Blame Contribute Delete
6.2 kB
'use client'
import { motion } from 'framer-motion'
import {
Coffee,
Image as ImageIcon,
Type,
AlertTriangle,
Zap,
StopCircle
} from 'lucide-react'
interface Scene {
brb_active: boolean
logo_active: boolean
overlay_text: string
}
interface SceneControlProps {
scene?: Scene
onToggleBRB: () => void
onToggleLogo: () => void
}
export default function SceneControl({ scene, onToggleBRB, onToggleLogo }: SceneControlProps) {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="glass rounded-xl p-6"
>
<h2 className="text-lg font-semibold flex items-center gap-2 mb-4">
<Zap className="w-5 h-5 text-yellow-400" />
Scene Controls
</h2>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
{/* BRB Toggle */}
<button
onClick={onToggleBRB}
className={`relative p-4 rounded-xl border-2 transition-all duration-300 ${
scene?.brb_active
? 'bg-yellow-500/20 border-yellow-500 shadow-lg shadow-yellow-500/20'
: 'bg-white/5 border-white/10 hover:border-white/30'
}`}
>
<div className="flex flex-col items-center gap-2">
<div className={`p-3 rounded-full ${
scene?.brb_active ? 'bg-yellow-500/30' : 'bg-white/10'
}`}>
<Coffee className={`w-6 h-6 ${
scene?.brb_active ? 'text-yellow-400' : 'text-gray-400'
}`} />
</div>
<span className={`font-medium ${
scene?.brb_active ? 'text-yellow-400' : 'text-gray-300'
}`}>
BRB
</span>
<span className="text-xs text-gray-500">
{scene?.brb_active ? 'ACTIVE' : 'OFF'}
</span>
</div>
{scene?.brb_active && (
<motion.div
layoutId="active-indicator"
className="absolute inset-0 border-2 border-yellow-500 rounded-xl"
initial={false}
transition={{ type: "spring", stiffness: 500, damping: 30 }}
/>
)}
</button>
{/* Logo Toggle */}
<button
onClick={onToggleLogo}
className={`relative p-4 rounded-xl border-2 transition-all duration-300 ${
scene?.logo_active
? 'bg-cyan-500/20 border-cyan-500 shadow-lg shadow-cyan-500/20'
: 'bg-white/5 border-white/10 hover:border-white/30'
}`}
>
<div className="flex flex-col items-center gap-2">
<div className={`p-3 rounded-full ${
scene?.logo_active ? 'bg-cyan-500/30' : 'bg-white/10'
}`}>
<ImageIcon className={`w-6 h-6 ${
scene?.logo_active ? 'text-cyan-400' : 'text-gray-400'
}`} />
</div>
<span className={`font-medium ${
scene?.logo_active ? 'text-cyan-400' : 'text-gray-300'
}`}>
LIVE Badge
</span>
<span className="text-xs text-gray-500">
{scene?.logo_active ? 'ACTIVE' : 'OFF'}
</span>
</div>
</button>
{/* Emergency Stop */}
<button
onClick={() => {
if (confirm('Stop stream immediately?')) {
fetch('/api/stop', { method: 'POST' })
}
}}
className="relative p-4 rounded-xl border-2 bg-red-500/10 border-red-500/50
hover:bg-red-500/20 transition-all duration-300 group"
>
<div className="flex flex-col items-center gap-2">
<div className="p-3 rounded-full bg-red-500/30 group-hover:bg-red-500/50 transition-colors">
<StopCircle className="w-6 h-6 text-red-400" />
</div>
<span className="font-medium text-red-400">
EMERGENCY STOP
</span>
<span className="text-xs text-gray-500">
Click to stop
</span>
</div>
</button>
</div>
{/* Overlay Text Input */}
<div className="mt-4 p-4 bg-white/5 rounded-lg">
<div className="flex items-center gap-2 mb-2">
<Type className="w-4 h-4 text-gray-400" />
<span className="text-sm text-gray-400">Custom Overlay Text</span>
</div>
<div className="flex gap-2">
<input
type="text"
placeholder="Short overlay text..."
className="flex-1 bg-white/10 border border-white/20 rounded-lg px-3 py-2
text-sm text-white placeholder-gray-500 focus:outline-none
focus:border-cyan-500/50"
onKeyDown={(e) => {
if (e.key === 'Enter') {
fetch('/api/scene/overlay?text=' + encodeURIComponent(e.currentTarget.value), {
method: 'POST'
})
e.currentTarget.value = ''
}
}}
/>
<button
onClick={(e) => {
const input = e.currentTarget.previousElementSibling as HTMLInputElement
if (input.value) {
fetch('/api/scene/overlay?text=' + encodeURIComponent(input.value), {
method: 'POST'
})
input.value = ''
}
}}
className="px-4 py-2 bg-cyan-500/20 hover:bg-cyan-500/30 text-cyan-400
rounded-lg text-sm transition-colors"
>
Set
</button>
</div>
{scene?.overlay_text && (
<p className="mt-2 text-sm text-cyan-400">
Current: {scene.overlay_text}
</p>
)}
</div>
{/* Warning */}
<div className="mt-4 flex items-start gap-2 p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<AlertTriangle className="w-5 h-5 text-yellow-400 flex-shrink-0 mt-0.5" />
<p className="text-sm text-yellow-200">
Scene changes restart FFmpeg briefly. Keep overlay text short.
</p>
</div>
</motion.div>
)
}