LiveDisplayX / src / app / admin / playlists / 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 { Badge } from "@/components/ui/badge";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import { 
  BatteryWarning as PlaylistIcon, 
  Plus, 
  Search, 
  Tag,
  Image as ImageIcon,
  Clock,
  Edit,
  Trash2,
  Eye,
  ArrowUpRight,
  Timer,
  Calendar
} from "lucide-react";

interface Playlist {
  id: string;
  title: string;
  description: string;
  tags: string[];
  duration: number;
  imageCount: number;
  schedule: {
    start: string;
    end: string;
  };
  lastModified: string;
  thumbnail: string;
}

export default function PlaylistsPage() {
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [activeFilter, setActiveFilter] = useState<string>("all");

  const playlists: Playlist[] = [
    {
      id: "1",
      title: "Standard",
      description: "Standard playlist",
      tags: ["standard", "campaign", "rizz"],
      duration: 300,
      imageCount: 12,
      schedule: {
        start: "2024-06-01",
        end: "2024-08-31"
      },
      lastModified: "2024-03-20T14:30:00",
      thumbnail: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=800&h=400&fit=crop"
    },
    {
      id: "2",
      title: "Event",
      description: "event playlist",
      tags: ["event", "spilling", "folk"],
      duration: 180,
      imageCount: 8,
      schedule: {
        start: "2024-01-01",
        end: "2024-12-31"
      },
      lastModified: "2024-03-19T09:15:00",
      thumbnail: "https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=800&h=400&fit=crop"
    },
    {
      id: "3",
      title: "Gaming Tournament Highlights",
      description: "Best moments from our recent tournaments",
      tags: ["gaming", "tournaments", "highlights"],
      duration: 240,
      imageCount: 15,
      schedule: {
        start: "2024-03-01",
        end: "2024-04-30"
      },
      lastModified: "2024-03-18T16:45:00",
      thumbnail: "https://images.unsplash.com/photo-1542751371-adc38448a05e?w=800&h=400&fit=crop"
    },
    {
      id: "4",
      title: "Kurs ",
      description: "Featured food and drink items",
      tags: ["menu", "food", "drinks"],
      duration: 120,
      imageCount: 6,
      schedule: {
        start: "2024-04-01",
        end: "2024-05-31"
      },
      lastModified: "2024-03-17T11:20:00",
      thumbnail: "https://images.unsplash.com/photo-1504674900247-0877df9cc836?w=800&h=400&fit=crop"
    }
  ];

  const allTags = Array.from(
    new Set(playlists.flatMap(playlist => playlist.tags))
  );

  const filteredPlaylists = playlists.filter(playlist => {
    const matchesSearch = playlist.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
                         playlist.description.toLowerCase().includes(searchQuery.toLowerCase()) ||
                         playlist.tags.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase()));
    
    const matchesFilter = activeFilter === "all" || playlist.tags.includes(activeFilter);
    
    return matchesSearch && matchesFilter;
  });

  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 className="flex items-center justify-between">
          <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">
              Playlist Management
            </h1>
            <p className="mt-2 text-gray-600">
              Create and manage content playlists for your displays
            </p>
          </div>
          <Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
            <DialogTrigger asChild>
              <Button className="bg-purple-600 hover:bg-purple-700 text-white rounded-xl flex items-center gap-2">
                <Plus className="h-5 w-5" />
                Create Playlist
              </Button>
            </DialogTrigger>
            <DialogContent className="sm:max-w-[600px] rounded-2xl">
              <DialogHeader>
                <DialogTitle>Create New Playlist</DialogTitle>
              </DialogHeader>
              <div className="space-y-6 py-4">
                <div className="space-y-2">
                  <Label>Playlist Title</Label>
                  <Input className="rounded-xl" placeholder="Enter playlist title" />
                </div>
                <div className="space-y-2">
                  <Label>Description</Label>
                  <Input className="rounded-xl" placeholder="Enter playlist description" />
                </div>
                <div className="space-y-2">
                  <Label>Tags</Label>
                  <Input className="rounded-xl" placeholder="Add tags (comma separated)" />
                </div>
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label>Start Date</Label>
                    <Input type="date" className="rounded-xl" />
                  </div>
                  <div className="space-y-2">
                    <Label>End Date</Label>
                    <Input type="date" className="rounded-xl" />
                  </div>
                </div>
                <div className="flex justify-end gap-2">
                  <Button 
                    variant="outline" 
                    onClick={() => setIsCreateOpen(false)}
                    className="rounded-xl"
                  >
                    Cancel
                  </Button>
                  <Button className="bg-purple-600 hover:bg-purple-700 text-white rounded-xl">
                    Create Playlist
                  </Button>
                </div>
              </div>
            </DialogContent>
          </Dialog>
        </div>

        <div className="grid grid-cols-12 gap-6">
          <div className="col-span-12 lg:col-span-3 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">
                  <Search className="h-5 w-5 text-purple-500" />
                  Search & Filter
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <Input 
                  placeholder="Search playlists..."
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  className="rounded-xl border-gray-200 focus:ring-purple-500"
                />
                <div className="space-y-2">
                  <Label className="text-sm font-medium">Filter by Tag</Label>
                  <ScrollArea className="h-[200px] rounded-xl border border-gray-200 p-2">
                    <div className="space-y-2">
                      <Button
                        variant="ghost"
                        className={`w-full justify-start rounded-lg ${
                          activeFilter === "all"
                            ? "bg-purple-50 text-purple-600"
                            : ""
                        }`}
                        onClick={() => setActiveFilter("all")}
                      >
                        <Tag className="h-4 w-4 mr-2" />
                        All Playlists
                      </Button>
                      {allTags.map((tag) => (
                        <Button
                          key={tag}
                          variant="ghost"
                          className={`w-full justify-start rounded-lg ${
                            activeFilter === tag
                              ? "bg-purple-50 text-purple-600"
                              : ""
                          }`}
                          onClick={() => setActiveFilter(tag)}
                        >
                          <Tag className="h-4 w-4 mr-2" />
                          {tag}
                        </Button>
                      ))}
                    </div>
                  </ScrollArea>
                </div>
              </CardContent>
            </Card>

            <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">
                  <PlaylistIcon className="h-5 w-5 text-purple-500" />
                  Quick Stats
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="grid grid-cols-2 gap-4">
                  <div className="bg-purple-50/50 p-4 rounded-xl border border-purple-100">
                    <p className="text-sm text-gray-500">Total Playlists</p>
                    <p className="text-2xl font-semibold text-purple-600">{playlists.length}</p>
                  </div>
                  <div className="bg-pink-50/50 p-4 rounded-xl border border-pink-100">
                    <p className="text-sm text-gray-500">Active</p>
                    <p className="text-2xl font-semibold text-pink-600">3</p>
                  </div>
                </div>
              </CardContent>
            </Card>
          </div>

          <div className="col-span-12 lg:col-span-9">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              {filteredPlaylists.map((playlist) => (
                <Card 
                  key={playlist.id}
                  className="rounded-2xl border-2 border-purple-100/50 hover:border-purple-200 transition-all duration-300 bg-white/70 backdrop-blur-sm overflow-hidden group"
                >
                  <div className="aspect-video relative">
                    <img
                      src={playlist.thumbnail}
                      alt={playlist.title}
                      className="absolute inset-0 w-full h-full object-cover"
                    />
                    <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
                    <div className="absolute bottom-4 left-4 right-4">
                      <h3 className="text-xl font-semibold text-white mb-1">{playlist.title}</h3>
                      <p className="text-sm text-gray-200 line-clamp-2">{playlist.description}</p>
                    </div>
                  </div>
                  <CardContent className="p-4">
                    <div className="flex flex-wrap gap-2 mb-4">
                      {playlist.tags.map((tag, index) => (
                        <Badge 
                          key={index}
                          variant="secondary"
                          className="rounded-full bg-purple-50 text-purple-600 hover:bg-purple-100"
                        >
                          {tag}
                        </Badge>
                      ))}
                    </div>
                    <div className="grid grid-cols-2 gap-4 mb-4">
                      <div className="flex items-center gap-2 text-sm text-gray-600">
                        <ImageIcon className="h-4 w-4" />
                        <span>{playlist.imageCount} images</span>
                      </div>
                      <div className="flex items-center gap-2 text-sm text-gray-600">
                        <Timer className="h-4 w-4" />
                        <span>{playlist.duration}s duration</span>
                      </div>
                      <div className="flex items-center gap-2 text-sm text-gray-600">
                        <Calendar className="h-4 w-4" />
                        <span>{new Date(playlist.schedule.start).toLocaleDateString()}</span>
                      </div>
                      <div className="flex items-center gap-2 text-sm text-gray-600">
                        <Clock className="h-4 w-4" />
                        <span>Last modified {new Date(playlist.lastModified).toLocaleDateString()}</span>
                      </div>
                    </div>
                    <div className="flex items-center justify-between">
                      <Button 
                        variant="outline"
                        size="sm"
                        className="rounded-xl border-purple-200 hover:bg-purple-50 hover:text-purple-600"
                      >
                        <Eye className="h-4 w-4 mr-2" />
                        Preview
                      </Button>
                      <div className="flex gap-2">
                        <Button 
                          variant="outline"
                          size="sm"
                          className="rounded-xl border-purple-200 hover:bg-purple-50 hover:text-purple-600"
                        >
                          <Edit className="h-4 w-4" />
                        </Button>
                        <Button 
                          variant="outline"
                          size="sm"
                          className="rounded-xl border-red-200 hover:bg-red-50 hover:text-red-600"
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    </div>
                  </CardContent>
                </Card>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}