summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/media-panel.tsx
blob: 1e5aa465d270898646e7a468e0b768a4344050ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"use client";

import { Button } from "../ui/button";
import { AspectRatio } from "../ui/aspect-ratio";
import { useMediaStore } from "@/stores/media-store";
import { Plus, Image, Video, Music, Upload } from "lucide-react";
import { useState, useRef } from "react";

export function MediaPanel() {
  const { mediaItems, addMediaItem } = useMediaStore();
  const [isDragOver, setIsDragOver] = useState(false);
  const dragCounterRef = useRef(0);

  const handleAddSampleMedia = () => {
    // Just for testing - add a sample media item
    addMediaItem({
      name: `Sample ${mediaItems.length + 1}`,
      type: "image",
    });
  };

  const getMediaIcon = (type: string) => {
    switch (type) {
      case "video":
        return <Video className="h-4 w-4" />;
      case "audio":
        return <Music className="h-4 w-4" />;
      default:
        return <Image className="h-4 w-4" />;
    }
  };

  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault();
    dragCounterRef.current += 1;
    if (!isDragOver) {
      setIsDragOver(true);
    }
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
  };

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    dragCounterRef.current -= 1;
    if (dragCounterRef.current === 0) {
      setIsDragOver(false);
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(false);
    dragCounterRef.current = 0;
    // TODO: Handle file drop functionality
  };

  return (
    <div
      className={`h-full overflow-y-auto transition-colors duration-200 relative ${
        isDragOver ? "bg-accent/30 border-accent" : ""
      }`}
      onDragEnter={handleDragEnter}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
    >
      {/* Drag Overlay */}
      {isDragOver && (
        <div className="absolute inset-0 bg-accent/20 backdrop-blur-lg border-2 border-dashed border-accent rounded-lg flex items-center justify-center z-10 pointer-events-none">
          <div className="text-center">
            <Upload className="h-8 w-8 text-accent mx-auto mb-2" />
            <p className="text-sm font-medium text-accent">Drop files here</p>
            <p className="text-xs text-muted-foreground">
              Images, videos, and audio files
            </p>
          </div>
        </div>
      )}

      <div className="space-y-4 p-2 h-full">
        {/* Media Grid */}
        {mediaItems.length === 0 ? (
          <EmptyMedia onAddSample={handleAddSampleMedia} />
        ) : (
          <div className="grid grid-cols-2 gap-2">
            {mediaItems.map((item) => (
              <Button
                key={item.id}
                variant="outline"
                className="flex flex-col gap-2 p-2 h-auto overflow-hidden"
              >
                <AspectRatio ratio={16 / 9} className="w-full">
                  <div className="w-full h-full bg-muted/30 flex flex-col items-center justify-center text-muted-foreground">
                    {getMediaIcon(item.type)}
                    <span className="text-xs mt-1 truncate max-w-full px-1">
                      {item.name}
                    </span>
                  </div>
                </AspectRatio>
              </Button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function EmptyMedia({ onAddSample }: { onAddSample: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center py-8 text-center h-full">
      <div className="w-16 h-16 rounded-full bg-muted/30 flex items-center justify-center mb-4">
        <Image className="h-8 w-8 text-muted-foreground" />
      </div>
      <p className="text-sm text-muted-foreground">No media in project</p>
      <p className="text-xs text-muted-foreground/70 mt-1">
        Drag files or click to add media
      </p>
      <Button
        variant="outline"
        size="sm"
        className="mt-4"
        onClick={onAddSample}
      >
        <Plus className="h-4 w-4 mr-2" />
        Add Sample
      </Button>
    </div>
  );
}