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>
);
}
|