194 lines
10 KiB
TypeScript
194 lines
10 KiB
TypeScript
"use client";
|
|
|
|
import React from 'react';
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
|
|
interface LiveStreamProps {
|
|
id: string;
|
|
}
|
|
|
|
// Define burrowing owl info based on stream ID
|
|
const getStreamInfo = (id: string) => {
|
|
switch (id) {
|
|
case "1":
|
|
return {
|
|
title: "Cape Coral Burrowing Owl",
|
|
location: "Cape Coral, FL",
|
|
fact: "The burrowing owl is the official city bird of Cape Coral. These unique owls nest underground and are active during the day."
|
|
};
|
|
case "2":
|
|
return {
|
|
title: "Burrowing Owl Habitat",
|
|
location: "Cape Coral, FL",
|
|
fact: "Burrowing owls prefer open areas with low vegetation and create underground burrows that provide shelter for many wildlife species."
|
|
};
|
|
case "3":
|
|
return {
|
|
title: "Owl Burrow Monitoring",
|
|
location: "Cape Coral, FL",
|
|
fact: "CCFW volunteers maintain over 2,500 burrows throughout Cape Coral to protect these threatened ground-dwelling owls."
|
|
};
|
|
default:
|
|
return {
|
|
title: `Burrowing Owl Cam ${id}`,
|
|
location: "Cape Coral, FL",
|
|
fact: "Burrowing owls are Florida's smallest owl species and are known for their distinctive long legs and daytime activity."
|
|
};
|
|
}
|
|
};
|
|
|
|
// Client-side component for dynamic time to avoid hydration errors
|
|
const ClientTimeDisplay: React.FC = () => {
|
|
const [currentTime, setCurrentTime] = React.useState<string>('');
|
|
|
|
React.useEffect(() => {
|
|
setCurrentTime(new Date().toLocaleDateString() + ' • ' + new Date().toLocaleTimeString());
|
|
}, []);
|
|
|
|
return <span className="bg-ccfw-beige/50 py-1 px-2 rounded">{currentTime}</span>;
|
|
};
|
|
|
|
const LiveStream: React.FC<LiveStreamProps> = ({ id }) => {
|
|
// This would be determined by your backend in a real app
|
|
const isLive = id !== "3"; // Let's assume stream #3 is offline for testing
|
|
|
|
const streamInfo = getStreamInfo(id);
|
|
// Use a fixed viewer count to avoid hydration errors
|
|
const viewerCount = isLive ? (id === "1" ? 128 : id === "2" ? 86 : 75) : 0;
|
|
|
|
return (
|
|
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm">
|
|
<CardHeader className="pb-2 border-b border-ccfw-teal/20">
|
|
<div className="flex justify-between items-center">
|
|
<CardTitle className="text-ccfw-teal">{streamInfo.title}</CardTitle>
|
|
<div className="flex items-center gap-2">
|
|
<div className={`h-3 w-3 rounded-full ${isLive ? 'bg-ccfw-coral animate-pulse' : 'bg-gray-500'}`}></div>
|
|
<span className="text-sm font-medium text-ccfw-maroon font-semibold">{isLive ? 'LIVE' : 'OFFLINE'}</span>
|
|
</div>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="pt-4">
|
|
<div className="bg-black aspect-video flex flex-col items-center justify-center rounded-md border border-ccfw-teal/30 relative overflow-hidden">
|
|
{isLive ? (
|
|
<>
|
|
<div className="absolute inset-0 bg-gradient-to-b from-ccfw-teal/5 to-transparent"></div>
|
|
|
|
{/* Overlay for wildlife stream info */}
|
|
<div className="absolute top-0 left-0 w-full bg-black/50 p-2 flex justify-between items-center">
|
|
<div className="flex items-center">
|
|
<div className="h-2 w-2 rounded-full bg-ccfw-coral animate-pulse mr-2"></div>
|
|
<span className="text-xs text-white">CCFW Wildlife Stream</span>
|
|
</div>
|
|
<div className="text-xs text-white bg-ccfw-teal/80 px-2 py-1 rounded">
|
|
HD
|
|
</div>
|
|
</div>
|
|
|
|
<div className="z-10 flex flex-col items-center">
|
|
<div className="bg-black/60 px-4 py-2 rounded-lg border border-ccfw-teal/30">
|
|
<p className="text-white font-medium">{streamInfo.location} • Cape Coral Friends of Wildlife</p>
|
|
<p className="text-xs text-white mt-2">HD Video • Live from Florida</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="absolute bottom-4 right-4 bg-black/70 text-white text-xs px-2 py-1 rounded flex items-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-3 w-3 mr-1 text-ccfw-coral" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
|
</svg>
|
|
{viewerCount}
|
|
</div>
|
|
|
|
{/* Stream controls overlay */}
|
|
<div className="absolute bottom-0 left-0 w-full bg-gradient-to-t from-black to-transparent pt-8 pb-2 px-4">
|
|
<div className="flex justify-between items-center">
|
|
<div className="flex space-x-3">
|
|
<button className="text-white hover:text-ccfw-coral transition-colors">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15.536a5 5 0 001.414-7.071m-2.829 9.9a9 9 0 010-12.728" />
|
|
</svg>
|
|
</button>
|
|
<button className="text-white hover:text-ccfw-coral transition-colors">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div className="text-xs text-white">
|
|
Powered by CCFW
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<div className="flex flex-col items-center">
|
|
<div className="bg-black/60 p-4 rounded-lg border border-ccfw-teal/30">
|
|
<div className="flex items-center mb-3">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-10 w-10 text-gray-600 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<div>
|
|
<p className="text-white font-medium">Stream currently offline</p>
|
|
<p className="text-xs text-white/80">Will return soon. Check back later.</p>
|
|
</div>
|
|
</div>
|
|
<div className="text-xs text-white text-center">
|
|
<a
|
|
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="hover:text-ccfw-coral transition-colors"
|
|
>
|
|
View upcoming livestream schedule
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="mt-4 flex justify-between items-center">
|
|
<div className="text-xs text-ccfw-maroon/70">
|
|
<ClientTimeDisplay />
|
|
</div>
|
|
<div className="flex gap-3">
|
|
<button className="text-ccfw-teal hover:text-ccfw-coral transition-colors">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
|
</svg>
|
|
</button>
|
|
<button className="text-ccfw-teal hover:text-ccfw-coral transition-colors">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
|
</svg>
|
|
</button>
|
|
<a
|
|
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
|
target="_blank"
|
|
className="text-ccfw-teal hover:text-ccfw-coral transition-colors"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Wildlife fact */}
|
|
<div className="mt-3 bg-ccfw-beige/10 p-3 rounded-md border border-ccfw-teal/20">
|
|
<div className="flex items-start gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-ccfw-gold flex-shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<p className="text-sm text-ccfw-maroon font-medium leading-relaxed">
|
|
<span className="font-semibold text-ccfw-teal">Wildlife Fact:</span> {streamInfo.fact}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default LiveStream;
|