LiveDisplayX / src / app / admin / twitch / page.tsx
page.tsx
Raw
"use client";

import { useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { Monitor, RefreshCcw, Maximize2, Minimize2, TwitchIcon, Eye } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import useSWR from "swr";
import Image from "next/image";

interface TwitchStream {
  id: string;
  user_name: string;
  game_name: string;
  title: string;
  viewer_count: number;
  thumbnail_url: string;
}

interface Screen {
  id: string;
  name: string;
  type: string;
  status: 'online' | 'offline';
}

export default function TwitchPage() {
  const [selectedScreens, setSelectedScreens] = useState<string[]>([]);
  const [twitchChannel, setTwitchChannel] = useState("");

  const { data: popularStreams, error } = useSWR<TwitchStream[]>(
    '/api/twitch/popular',
    async () => {
      // Implement your Twitch API fetch logic here
      return [];
    }
  );

  const screens: Screen[] = [
    { id: "1", name: "Main Stage", type: "twitch", status: "online" },
    { id: "2", name: "Secondary Stage", type: "twitch", status: "online" },
    { id: "3", name: "Entrance Display", type: "event", status: "offline" },
  ];

  const handleScreenSelect = (screenId: string) => {
    setSelectedScreens(prev => 
      prev.includes(screenId) 
        ? prev.filter(id => id !== screenId)
        : [...prev, screenId]
    );
  };

  const handleStreamSelect = (streamName: string) => {
    setTwitchChannel(streamName);
  };

  return (
    <div className="min-h-screen bg-gradient-to-b from-violet-50 via-white to-sky-50">
      <div className="max-w-[1400px] mx-auto space-y-8 p-8">
        <div>
          <h1 className="text-4xl font-bold tracking-tight bg-gradient-to-r from-purple-600 via-pink-500 to-blue-500 bg-clip-text text-transparent">
            Twitch Management
          </h1>
          <p className="mt-2 text-gray-600">
            Configure and control Twitch streams across your displays
          </p>
        </div>

        <div className="grid grid-cols-12 gap-6">
          <div className="col-span-12 lg:col-span-4 space-y-6">
            <Card className="rounded-2xl border-2 border-purple-100/50 hover:border-purple-200 transition-all duration-300 bg-white/70 backdrop-blur-sm">
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <TwitchIcon className="h-5 w-5 text-purple-500" />
                  Update Streams
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-6">
                <div className="space-y-4">
                  <Label className="text-base font-semibold">Select Screens</Label>
                  <div className="grid grid-cols-1 gap-3">
                    {screens.map(screen => (
                      <div key={screen.id} className="flex items-center space-x-3 rounded-xl bg-purple-50/50 p-3 border border-purple-100">
                        <Checkbox
                          id={screen.id}
                          checked={selectedScreens.includes(screen.id)}
                          onCheckedChange={() => handleScreenSelect(screen.id)}
                          className="rounded-lg data-[state=checked]:bg-purple-600 data-[state=checked]:border-purple-600"
                        />
                        <div className="flex flex-1 items-center justify-between">
                          <Label htmlFor={screen.id} className="font-medium cursor-pointer">
                            {screen.name}
                          </Label>
                          <Badge 
                            className={`${
                              screen.status === 'online' 
                                ? 'bg-purple-500/10 text-purple-600' 
                                : 'bg-pink-500/10 text-pink-600'
                            }`}
                          >
                            {screen.status}
                          </Badge>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>

                <div className="space-y-2">
                  <Label className="text-base font-semibold">Twitch Channel</Label>
                  <div className="flex gap-2">
                    <Input
                      placeholder="Enter channel name"
                      value={twitchChannel}
                      onChange={(e) => setTwitchChannel(e.target.value)}
                      className="rounded-xl border-gray-200 focus:ring-purple-500"
                    />
                    <Button className="bg-purple-600 hover:bg-purple-700 text-white rounded-xl">
                      Update
                    </Button>
                  </div>
                </div>
              </CardContent>
            </Card>

            <Card className="rounded-2xl border-2 border-pink-100/50 hover:border-pink-200 transition-all duration-300 bg-white/70 backdrop-blur-sm">
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <Monitor className="h-5 w-5 text-pink-500" />
                  Active Displays
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                {screens.filter(s => s.type === 'twitch').map(screen => (
                  <div key={screen.id} className="flex items-center justify-between p-3 rounded-xl bg-pink-50/50 border border-pink-100">
                    <div>
                      <p className="font-medium">{screen.name}</p>
                      <p className="text-sm text-gray-500">Currently: esl_csgo</p>
                    </div>
                    <div className="flex gap-2">
                      <Button 
                        variant="outline"
                        size="sm"
                        className="rounded-xl border-pink-200 hover:bg-pink-50 hover:text-pink-600"
                      >
                        <RefreshCcw className="h-4 w-4" />
                      </Button>
                      <Button 
                        variant="outline"
                        size="sm"
                        className="rounded-xl border-pink-200 hover:bg-pink-50 hover:text-pink-600"
                      >
                        <Maximize2 className="h-4 w-4" />
                      </Button>
                      <Button 
                        variant="outline"
                        size="sm"
                        className="rounded-xl border-pink-200 hover:bg-pink-50 hover:text-pink-600"
                      >
                        <Minimize2 className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          </div>

          <div className="col-span-12 lg:col-span-8">
            <Card className="rounded-2xl border-2 border-blue-100/50 hover:border-blue-200 transition-all duration-300 bg-white/70 backdrop-blur-sm">
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <TwitchIcon className="h-5 w-5 text-blue-500" />
                  Popular Streams
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
                  {[1, 2, 3, 4, 5, 6].map((i) => (
                    <Card 
                      key={i}
                      className="overflow-hidden rounded-xl border border-gray-100 hover:border-blue-200 transition-all duration-300 cursor-pointer group"
                      onClick={() => handleStreamSelect(`stream${i}`)}
                    >
                      <CardContent className="p-0">
                        <div className="aspect-video relative">
                          <Image
                            src={`https://picsum.photos/seed/${i}/400/225`}
                            alt="Stream thumbnail"
                            layout="fill"
                            objectFit="cover"
                          />
                          <div className="absolute bottom-2 right-2 bg-red-500 text-white text-sm px-2 py-0.5 rounded-lg">
                            LIVE
                          </div>
                        </div>
                        <div className="p-3 space-y-2">
                          <div className="flex items-start justify-between">
                            <div>
                              <h3 className="font-semibold text-sm">ESL_CSGO</h3>
                              <p className="text-sm text-gray-500">CS2 - ESL Pro League</p>
                            </div>
                            <Badge variant="secondary" className="rounded-lg">
                              <Eye className="h-3 w-3 mr-1" />
                              125K
                            </Badge>
                          </div>
                          <div className="flex gap-2">
                            <Button 
                              size="sm" 
                              variant="outline" 
                              className="flex-1 rounded-lg border-blue-200 hover:bg-blue-50 hover:text-blue-600 group-hover:border-blue-300"
                            >
                              Select
                            </Button>
                            <Button 
                              size="sm" 
                              variant="outline"
                              className="rounded-lg border-blue-200 hover:bg-blue-50 hover:text-blue-600 group-hover:border-blue-300"
                              onClick={(e) => {
                                e.stopPropagation();
                                window.open(`https://twitch.tv/esl_csgo`, '_blank');
                              }}
                            >
                              Watch
                            </Button>
                          </div>
                        </div>
                      </CardContent>
                    </Card>
                  ))}
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      </div>
    </div>
  );
}