File size: 4,671 Bytes
0b5c6fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from "react";
import {Camera, Upload} from "lucide-react";
import {Button} from "@/components/ui/button";

interface ImageUploadProps {
    onImageUpload: (file: File) => void;
    sideEffect: (text: string | null) => void;
}

export default function ImageUpload({onImageUpload, sideEffect}: ImageUploadProps) {
    const [isDragging, setIsDragging] = React.useState(false);
    const fileInputRef = React.useRef<HTMLInputElement>(null);
    const videoRef = React.useRef<HTMLVideoElement>(null);
    const [isCameraActive, setIsCameraActive] = React.useState(false);

    const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
        e.preventDefault();
        setIsDragging(true);
    };

    const handleDragLeave = () => {
        setIsDragging(false);
    };

    const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
        e.preventDefault();
        setIsDragging(false);
        const file = e.dataTransfer.files[0];
        if (file) {
            onImageUpload(file);
        }
    };

    const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            onImageUpload(file);
        }
    };

    const activateCamera = async () => {
        try {
            const stream = await navigator.mediaDevices.getUserMedia({video: true});
            if (videoRef.current) {
                videoRef.current.srcObject = stream;
                setIsCameraActive(true);
            }
        } catch (error) {
            console.error("Error accessing camera:", error);
        }
    };

    const capturePhoto = () => {
        if (videoRef.current) {
            const canvas = document.createElement("canvas");
            canvas.width = videoRef.current.videoWidth;
            canvas.height = videoRef.current.videoHeight;
            canvas.getContext("2d")?.drawImage(videoRef.current, 0, 0);
            canvas.toBlob((blob) => {
                if (blob) {
                    const file = new File([blob], "camera-photo.jpg", {
                        type: "image/jpeg",
                    });
                    onImageUpload(file);
                }
            }, "image/jpeg");
            setIsCameraActive(false);
        }
    };

    return (
        <div
            className={`border-2 border-dashed rounded-lg p-8 text-center transition-all duration-300 ${
                isDragging
                    ? "border-blue-500 bg-blue-50"
                    : "border-gray-300 hover:border-blue-300 hover:bg-blue-50"
            }`}
            onDragOver={handleDragOver}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
        >
            {isCameraActive ? (
                <div className="space-y-4">
                    <video
                        ref={videoRef}
                        autoPlay
                        className="mx-auto mb-4 rounded-lg shadow-md"
                    />
                    <Button onClick={capturePhoto} variant="default">
                        Capture Photo
                    </Button>
                </div>
            ) : (
                <>
                    <form
                        onSubmit={(event) => event.preventDefault()}
                        encType="multipart/form-data"
                    >
                        <p className="mb-4 text-gray-600">
                            Drag and drop an image here, or click to select a file
                        </p>
                        <input
                            type="file"
                            accept="image/*"
                            onChange={(event) => {
                                handleFileInput(event);
                                sideEffect(null)
                            }}
                            className="hidden"
                            ref={fileInputRef}
                        />
                        <div className="space-x-4">
                            <Button
                                onClick={() => fileInputRef.current?.click()}
                                variant="outline"
                            >
                                <Upload className="w-4 h-4 mr-2"/>
                                Select Image
                            </Button>
                            <Button onClick={activateCamera} variant="outline">
                                <Camera className="w-4 h-4 mr-2"/>
                                Use Camera
                            </Button>
                        </div>
                    </form>
                </>
            )}
        </div>
    );
}