import React, { useState, useRef, useEffect } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faChevronLeft, faChevronDown, faTimes, faImage } from '@fortawesome/free-solid-svg-icons'; import { FileUploader } from 'react-drag-drop-files'; import Select from 'react-select' const Compare = () => { const BASE_URL = process.env.REACT_APP_BASE_URL const API_KEY = process.env.REACT_APP_API_KEY const [isSelectOpen, setIsSelectOpen] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [selectedImageName, setSelectedImageName] = useState(''); const [selectedCompareImageName, setSelectedCompareImageName] = useState(''); const fileInputRef = useRef(null); const fileCompareInputRef = useRef(null); const [showResult, setShowResult] = useState(false); const [applicationId, setApplicationId] = useState(''); const [selectedQuota, setSelectedQuota] = useState(0); const [thresholdId, setTresholdId] = useState(''); const [isLoading, setIsLoading] = useState(false); const [imageUrl, setImageUrl] = useState(''); const [imageCompareUrl, setImageCompareUrl] = useState(''); const [verified, setVerified] = useState(null); const fileTypes = ["JPG", "JPEG", "PNG"]; const [file, setFile] = useState(null); // For the first image const [compareFile, setCompareFile] = useState(null); // For the second imag const [applicationIds, setApplicationIds] = useState([]); const [inputValueApplication, setInputValueApplication] = useState(''); // Controlled input value for Application ID const thresholdIds = [ { id: 1, name: 'cosine', displayName: 'Basic' }, { id: 2, name: 'euclidean', displayName: 'Medium' }, { id: 3, name: 'euclidean_l2', displayName: 'High' }, ]; const [applicationError, setApplicationError] = useState(''); const [thresholdError, setThresholdError] = useState(''); const [uploadError, setUploadError] = useState(''); const [compareUploadError, setCompareUploadError] = useState(''); useEffect(() => { const fetchApplicationIds = async () => { try { setIsLoading(true) const url = `${BASE_URL}/application/list`; console.log('Fetching URL:', url); // Log the URL const response = await fetch(url, { method: 'GET', headers: { 'accept': 'application/json', 'x-api-key': `${API_KEY}`, }, }); const data = await response.json(); if (data.status_code === 200) { const ids = data.details.data.map(app => app.id); console.log('Application Id: ' + ids); // Log the IDs setApplicationIds(data.details.data); // Update state with the fetched data } else { console.error('Failed to fetch data:', data.details.message); } } catch (error) { console.error('Error fetching application IDs:', error); } finally { setIsLoading(false) } }; fetchApplicationIds(); }, []); const handleApplicationChange = (selectedOption) => { if (selectedOption) { const selectedId = selectedOption.value; const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId)); if (selectedApp) { setApplicationId(selectedId); setSelectedQuota(selectedApp.quota); // Set the selected quota } } }; const handleInputChangeApplication = (newInputValue) => { // Limit input to 15 characters for Application ID if (newInputValue.length <= 15) { setInputValueApplication(newInputValue); } }; const handleFocus = () => { setIsSelectOpen(true); }; const handleBlur = () => { setIsSelectOpen(false); }; const handleImageUpload = (file) => { if (file && fileTypes.includes(file.name.split('.').pop().toUpperCase())) { setSelectedImageName(file.name); setFile(file); // Store the file directly in state setUploadError(''); // Clear error if valid } }; const handleCompareImageUpload = (file) => { if (file && fileTypes.includes(file.name.split('.').pop().toUpperCase())) { setSelectedCompareImageName(file.name); setCompareFile(file); // Store the compare file directly in state setCompareUploadError(''); // Clear error if valid } }; const handleImageCancel = () => { setSelectedImageName(''); setImageUrl(''); if (fileInputRef.current) fileInputRef.current.value = ''; }; const handleCompareImageCancel = () => { setSelectedCompareImageName(''); setImageCompareUrl(''); if (fileCompareInputRef.current) fileCompareInputRef.current.value = ''; }; const handleCheckClick = async () => { // Reset error messages setApplicationError(''); setThresholdError(''); setUploadError(''); setCompareUploadError(''); setErrorMessage(''); // Initialize a flag to check for errors let hasError = false; // Validate Application ID if (!applicationId) { setApplicationError('Please select an Application ID before compare.'); hasError = true; } // Validate Threshold ID const selectedThreshold = thresholdIds.find(threshold => threshold.name === thresholdId)?.name; if (!selectedThreshold) { setThresholdError('Invalid threshold selected.'); hasError = true; } // Validate Image Uploads if (!selectedImageName) { setUploadError('Please upload a face photo before compare.'); hasError = true; } if (!selectedCompareImageName) { setCompareUploadError('Please upload a compare face photo before compare.'); hasError = true; } // If there are any errors, return early if (hasError) { return; } // Prepare FormData and log inputs const formData = new FormData(); formData.append('application_id', applicationId); formData.append('file1', file); // Use the state variable directly formData.append('file2', compareFile); // Use the state variable directly formData.append('threshold', selectedThreshold); // Log the inputs console.log('Inputs:', { applicationId, threshold: selectedThreshold, file1: selectedImageName, file2: selectedCompareImageName, }); setIsLoading(true); setErrorMessage(''); try { const response = await fetch(`${BASE_URL}/face_recognition/compare`, { method: 'POST', headers: { 'accept': 'application/json', 'x-api-key': `${API_KEY}`, }, body: formData, }); const data = await response.json(); if (response.ok) { // Fetch image URLs from response const imageUrl1 = data.details.data.result.image_url1; const imageUrl2 = data.details.data.result.image_url2; await fetchImage(imageUrl1, setImageUrl); await fetchImage(imageUrl2, setImageCompareUrl); setVerified(data.details.data.result.verified); setShowResult(true); console.log('Comparison successful:', data); } else { console.error('Error response:', data); const errorMessage = data.message || data.detail || data.details?.message || 'An unknown error occurred.'; setErrorMessage(errorMessage); } } catch (error) { console.error('Error:', error); setErrorMessage('An error occurred while making the request.'); } finally { setIsLoading(false); } }; const fetchImage = async (imageUrl, setImageUrl) => { setIsLoading(true); try { const response = await fetch(imageUrl, { method: 'GET', headers: { 'accept': 'application/json', 'x-api-key': `${API_KEY}`, // Ensure this is valid } }); if (!response.ok) { const errorDetails = await response.json(); console.error('Image fetch error details:', errorDetails); setErrorMessage('Failed to fetch image, please try again.'); return; } const imageBlob = await response.blob(); const imageData = URL.createObjectURL(imageBlob); console.log('Fetched image URL:', imageData); setImageUrl(imageData); // Set the state with the blob URL } catch (error) { console.error('Error fetching image:', error); setErrorMessage(error.message); } finally { setIsLoading(false); } }; const applicationOptions = applicationIds.map(app => ({ value: app.id, label: app.name })); const ResultsSection = ({ showResult, verified, imageUrl, selectedImageName, imageCompareUrl, selectedCompareImageName }) => ( showResult && (
Similarity | {verified !== null ? (verified ? 'True' : 'False') : 'N/A'} |
{selectedImageName}
{selectedCompareImageName}
Loading...
Remaining Quota
Drag and Drop Here
Or
BrowseRecommended size: 250x250 (Max File Size: 2MB)
Supported file types: JPG, JPEG
File: {selectedImageName}
{file && (Size: {formatFileSize(file.size)}
)}Drag and Drop Here
Or
BrowseRecommended size: 250x250 (Max File Size: 2MB)
Supported file types: JPG, JPEG
File: {selectedCompareImageName}
{compareFile && (Size: {formatFileSize(compareFile.size)}
)}