2025-02-05 18:52:03 +05:30

195 lines
5.3 KiB
TypeScript

"use client";
import React, { useRef, useState, useEffect } from "react";
import "./Register.css"; // Import CSS for styling
import { toast } from "@/hooks/use-toast";
import { Button } from "../ui/button";
const Register: React.FC = () => {
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [name, setName] = useState<string>("");
const [error, setError] = useState<string>(""); // State for error message
const [selectedFile, setSelectedFile] = useState<File | null>(null); // State for uploaded image
// Automatically open the camera when the component mounts
useEffect(() => {
const openCamera = async () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
});
if (videoRef.current) {
videoRef.current.srcObject = stream;
}
} catch (err) {
console.error("Error accessing the camera", err);
}
};
openCamera();
}, []);
// Capture image from video stream
const captureImage = () => {
if (!name.trim()) {
setError("Name is required"); // Set error message if name is empty
return;
}
const video = videoRef.current;
const canvas = canvasRef.current;
if (video && canvas) {
const context = canvas.getContext("2d");
if (context) {
// Draw the current frame from the video on the canvas
context.drawImage(video, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
if (blob) {
const file = new File([blob], "captured-image.png", {
type: "image/png",
});
callApi(name, file);
}
}, "image/png");
}
}
};
// Handle file upload
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0] || null;
setSelectedFile(file);
};
// Submit uploaded file
const submitUploadedFile = () => {
if (!name.trim()) {
setError("Name is required");
return;
}
if (!selectedFile) {
setError("Please upload an image file.");
return;
}
callApi(name, selectedFile);
};
// Call API with name and image file
const callApi = async (name: string, file: File) => {
const formData = new FormData();
formData.append("name", name);
formData.append("image", file);
try {
const startTime = performance.now();
const response = await fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/register`,
{
method: "POST",
body: formData,
}
);
// End measuring time
const endTime = performance.now();
const totalTime = (endTime - startTime) / 1000; // Convert milliseconds to seconds
if (response.ok) {
const data = await response.json();
console.log("API call successful", totalTime);
toast({
title: data.message,
description: `Name: ${data?.name} `,
});
setError("");
} else {
console.error("API call failed");
setError("Failed to register. Please try again.");
}
} catch (error) {
console.error("Error calling API", error);
setError("An error occurred. Please try again.");
}
};
return (
<div className="container">
<h1 className="title">Face Capture & Upload Form</h1>
<form className="form">
<div className="form-group">
<label htmlFor="name" className="label">
Name:
</label>
<input
id="name"
type="text"
value={name}
onChange={(e) => {
setName(e.target.value);
setError(""); // Clearing error message when user starts typing
}}
className="input"
placeholder="Enter your name"
required
/>
{error && !name.trim() && (
<p className="error-message">{error}</p> // Displaying error message if name is empty
)}
</div>
<div className="mb-5">
<video
ref={videoRef}
autoPlay
playsInline
className="w-full max-w-[500px] rounded-lg shadow-md scale-x-[-1]"
/>
<Button
type="button"
onClick={captureImage}
className="capture-button"
>
Capture Image
</Button>
</div>
<div>Or</div>
<div className="file-upload-container">
<label htmlFor="file-upload" className="label">
Upload Image:
</label>
<input
id="file-upload"
type="file"
accept="image/*"
onChange={handleFileUpload}
className="file-input"
/>
<button
type="button"
onClick={submitUploadedFile}
// className="upload-button"
className="capture-button"
>
Submit Uploaded Image
</button>
</div>
<canvas
ref={canvasRef}
style={{ display: "none" }}
width="640"
height="480"
/>
{error && <p className="error-message">{error}</p>}
</form>
</div>
);
};
export default Register;