From 68878187e213df5fa8e461630f6b604511a49f95 Mon Sep 17 00:00:00 2001 From: Rizqika Date: Mon, 11 Nov 2024 18:45:07 +0700 Subject: [PATCH] OCR KTP --- .../FaceRecognition/Section/Enroll.jsx | 627 ++++++++-------- src/screens/Biometric/OcrKtp/Verify.jsx | 674 ++++++++---------- 2 files changed, 624 insertions(+), 677 deletions(-) diff --git a/src/screens/Biometric/FaceRecognition/Section/Enroll.jsx b/src/screens/Biometric/FaceRecognition/Section/Enroll.jsx index 735d492..6456a6b 100644 --- a/src/screens/Biometric/FaceRecognition/Section/Enroll.jsx +++ b/src/screens/Biometric/FaceRecognition/Section/Enroll.jsx @@ -33,320 +33,6 @@ const Enroll = () => { const [options, setOptions] = useState([]); const [isMobile, setIsMobile] = useState(false); - const styles = { - // Existing styles - formGroup: { - marginTop: '-45px', - }, - selectWrapper: { - position: 'relative', - marginTop: '0', - }, - select: { - width: '100%', - paddingRight: '30px', - }, - chevronIcon: { - position: 'absolute', - right: '10px', - top: '50%', - transform: 'translateY(-50%)', - pointerEvents: 'none', - }, - remainingQuota: { - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - marginTop: '4px', - }, - quotaText: { - fontSize: '40px', - color: '#0542cc', - fontWeight: '600', - }, - timesText: { - marginLeft: '8px', - verticalAlign: 'super', - fontSize: '20px', - }, - uploadArea: { - backgroundColor: '#e6f2ff', - height: '250px', // Default height for non-mobile devices - cursor: 'pointer', - marginTop: '1rem', - paddingTop: '22px', - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - border: '1px solid #ced4da', - borderRadius: '0.25rem', - }, - - // Mobile responsive styles for upload area - uploadAreaMobile: { - backgroundColor: '#e6f2ff', - height: '50svh', // Reduced height for mobile - cursor: 'pointer', - marginTop: '1rem', - paddingTop: '18px', // Adjusted padding for mobile - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - border: '1px solid #ced4da', - borderRadius: '0.25rem', - padding: '20px' - }, - uploadIcon: { - fontSize: '40px', - color: '#0542cc', - marginBottom: '7px', - }, - uploadText: { - color: '#1f2d3d', - fontWeight: '400', - fontSize: '16px', - lineHeight: '13px', - }, - wrapper: { - border: '1px solid #ddd', - borderRadius: '6px', - padding: '18px 10px 0 8px', // Padding lebih seragam - height: '13svh', // Tinggi lebih kecil untuk menyesuaikan tampilan - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - backgroundColor: '#f9f9f9', - overflow: 'hidden', - }, - fileWrapper: { - display: 'flex', - alignItems: 'center', - flex: '1', - }, - textContainer: { - flex: '1', - fontSize: '16px', // Ukuran font lebih kecil - marginLeft: '6px', - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - marginTop: '1rem' - }, - fileSize: { - fontSize: '12px', - color: '#555', - marginBottom: '2rem', - }, - closeButtonContainer: { - display: 'flex', - alignItems: 'center', - marginLeft: 'auto', - }, - closeButton: { - background: 'transparent', - border: 'none', - cursor: 'pointer', - padding: '0', - }, - imageIcon: { - color: '#0542cc', - fontSize: '18px', // Ukuran ikon sedikit lebih kecil - marginRight: '6px', - }, - closeIcon: { - color: 'red', - fontSize: '18px', - }, - submitButton: { - marginLeft: 'auto', - marginTop: '4rem', - textAlign: 'start', - position: 'relative', - zIndex: 1, - }, - uploadError: { - color: 'red', - fontSize: '12px', - marginTop: '5px', - }, - - // New styles added and merged - containerResultStyle: { - padding: '20px', - border: '1px solid #0053b3', - borderRadius: '5px', - width: '100%', - margin: '20px auto', - }, - resultContainer: { - display: 'flex', - justifyContent: 'space-between', // Horizontal alignment - alignItems: 'flex-start', // Align items at the top - flexDirection: isMobile ? 'column' : 'row', // Stack vertically on mobile - width: '100%', - }, - resultsTable: { - width: '60%', - borderCollapse: 'collapse', - }, - resultsTableMobile: { - width: '100%', - borderCollapse: 'collapse', - }, - resultsCell: { - padding: '8px', - width: '30%', - fontSize: isMobile ? '14px' : '16px', - }, - resultsValueCell: { - padding: '8px', - width: '70%', - fontSize: isMobile ? '14px' : '16px', - color: 'red', - }, - resultsTrueValue: { - color: 'inherit', - }, - imageContainer: { - display: 'flex', - flexDirection: 'column', - alignItems: isMobile ? 'center' : 'flex-start', // Center image on mobile - width: '100%', - marginTop: isMobile ? '10px' : '0', // Add margin for spacing on mobile - }, - imageStyle: { - width: '300px', - height: '300px', - borderRadius: '5px', - }, - imageStyleMobile: { - width: '100%', // Make image responsive on mobile - height: 'auto', - borderRadius: '5px', - }, - imageDetails: { - marginTop: '10px', - fontSize: isMobile ? '14px' : '16px', // Adjust font size on mobile - color: '#1f2d3d', - }, - loadingOverlay: { - position: 'fixed', - top: 0, - left: 0, - right: 0, - bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.2)', - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - zIndex: 1000, - }, - spinner: { - border: '4px solid rgba(0, 0, 0, 0.1)', - borderLeftColor: '#0542cc', - borderRadius: '50%', - width: '90px', - height: '90px', - animation: 'spin 1s ease-in-out infinite', - }, - loadingText: { - marginTop: '10px', - fontSize: '1.2rem', - color: '#fff', - textAlign: 'center', - }, - uploadedFileWrapper: { - backgroundColor: '#fff', - border: '0.2px solid gray', - padding: '15px 0 0 17px', - borderRadius: '5px', - display: 'flex', - alignItems: 'center', - gap: '10px', - justifyContent: 'space-between', - }, - uploadedFileInfo: { - marginRight: '18rem', - marginTop: '0.2rem', - }, - uploadedFileText: { - fontSize: '16px', - color: '#1f2d3d', - }, - resultsTable: { - width: '60%', - borderCollapse: 'collapse', - }, - resultsRow: { - border: '0.1px solid gray', - padding: '8px', - }, - resultsCell: { - padding: '8px', - width: '30%', - }, - resultsValueCell: { - padding: '8px', - width: '70%', - color: 'red', - }, - resultsTrueValue: { - color: 'inherit', - }, - customLabel: { - fontWeight: 600, fontSize: '14px', color: '#212529' - }, - - // Mobile responsiveness adjustments (if necessary) - responsiveImageStyle: { - width: '100%', - maxHeight: '250px', - objectFit: 'cover', - marginTop: '20px', - }, - responsiveResultContainer: { - padding: '1rem', - border: '1px solid #ccc', - borderRadius: '8px', - marginTop: '20px', - }, - responsiveImageContainer: { - marginTop: '20px', - textAlign: 'center', - }, - responsiveSubmitButton: { - marginTop: '1rem', - }, - responsiveLoadingOverlay: { - position: 'absolute', - top: '0', - left: '0', - width: '100%', - height: '100%', - backgroundColor: 'rgba(0,0,0,0.5)', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - zIndex: '10', - }, - responsiveSpinner: { - border: '4px solid #f3f3f3', - borderTop: '4px solid #3498db', - borderRadius: '50%', - width: '50px', - height: '50px', - animation: 'spin 2s linear infinite', - }, - responsiveLoadingText: { - color: 'white', - marginTop: '10px', - }, - } - - useEffect(() => { const fetchApplicationIds = async () => { setIsLoading(true); @@ -646,6 +332,319 @@ const Enroll = () => { return `${(sizeInBytes / 1048576).toFixed(2)} MB`; // Jika ukuran lebih besar dari 1 MB } }; + + const styles = { + // Existing styles + formGroup: { + marginTop: '-45px', + }, + selectWrapper: { + position: 'relative', + marginTop: '0', + }, + select: { + width: '100%', + paddingRight: '30px', + }, + chevronIcon: { + position: 'absolute', + right: '10px', + top: '50%', + transform: 'translateY(-50%)', + pointerEvents: 'none', + }, + remainingQuota: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + marginTop: '4px', + }, + quotaText: { + fontSize: '40px', + color: '#0542cc', + fontWeight: '600', + }, + timesText: { + marginLeft: '8px', + verticalAlign: 'super', + fontSize: '20px', + }, + uploadArea: { + backgroundColor: '#e6f2ff', + height: '250px', // Default height for non-mobile devices + cursor: 'pointer', + marginTop: '1rem', + paddingTop: '22px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + border: '1px solid #ced4da', + borderRadius: '0.25rem', + }, + + // Mobile responsive styles for upload area + uploadAreaMobile: { + backgroundColor: '#e6f2ff', + height: '50svh', // Reduced height for mobile + cursor: 'pointer', + marginTop: '1rem', + paddingTop: '18px', // Adjusted padding for mobile + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + border: '1px solid #ced4da', + borderRadius: '0.25rem', + padding: '20px' + }, + uploadIcon: { + fontSize: '40px', + color: '#0542cc', + marginBottom: '7px', + }, + uploadText: { + color: '#1f2d3d', + fontWeight: '400', + fontSize: '16px', + lineHeight: '13px', + }, + wrapper: { + border: '1px solid #ddd', + borderRadius: '6px', + padding: '18px 10px 0 8px', // Padding lebih seragam + height: '13svh', // Tinggi lebih kecil untuk menyesuaikan tampilan + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + backgroundColor: '#f9f9f9', + overflow: 'hidden', + }, + fileWrapper: { + display: 'flex', + alignItems: 'center', + flex: '1', + }, + textContainer: { + flex: '1', + fontSize: '16px', // Ukuran font lebih kecil + marginLeft: '6px', + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + marginTop: '1rem' + }, + fileSize: { + fontSize: '12px', + color: '#555', + marginBottom: '2rem', + }, + closeButtonContainer: { + display: 'flex', + alignItems: 'center', + marginLeft: 'auto', + }, + closeButton: { + background: 'transparent', + border: 'none', + cursor: 'pointer', + padding: '0', + }, + imageIcon: { + color: '#0542cc', + fontSize: '18px', // Ukuran ikon sedikit lebih kecil + marginRight: '6px', + }, + closeIcon: { + color: 'red', + fontSize: '18px', + }, + submitButton: { + marginLeft: 'auto', + marginTop: '4rem', + textAlign: 'start', + position: 'relative', + zIndex: 1, + }, + uploadError: { + color: 'red', + fontSize: '12px', + marginTop: '5px', + }, + + // New styles added and merged + containerResultStyle: { + padding: '20px', + border: '1px solid #0053b3', + borderRadius: '5px', + width: '100%', + margin: '20px auto', + }, + resultContainer: { + display: 'flex', + justifyContent: 'space-between', // Horizontal alignment + alignItems: 'flex-start', // Align items at the top + flexDirection: isMobile ? 'column' : 'row', // Stack vertically on mobile + width: '100%', + }, + resultsTable: { + width: '60%', + borderCollapse: 'collapse', + }, + resultsTableMobile: { + width: '100%', + borderCollapse: 'collapse', + }, + resultsCell: { + padding: '8px', + width: '30%', + fontSize: isMobile ? '14px' : '16px', + }, + resultsValueCell: { + padding: '8px', + width: '70%', + fontSize: isMobile ? '14px' : '16px', + color: 'red', + }, + resultsTrueValue: { + color: 'inherit', + }, + imageContainer: { + display: 'flex', + flexDirection: 'column', + alignItems: isMobile ? 'center' : 'flex-start', // Center image on mobile + width: '100%', + marginTop: isMobile ? '10px' : '0', // Add margin for spacing on mobile + }, + imageStyle: { + width: '300px', + height: '300px', + borderRadius: '5px', + }, + imageStyleMobile: { + width: '100%', // Make image responsive on mobile + height: 'auto', + borderRadius: '5px', + }, + imageDetails: { + marginTop: '10px', + fontSize: isMobile ? '14px' : '16px', // Adjust font size on mobile + color: '#1f2d3d', + }, + loadingOverlay: { + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0, 0, 0, 0.2)', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + zIndex: 1000, + }, + spinner: { + border: '4px solid rgba(0, 0, 0, 0.1)', + borderLeftColor: '#0542cc', + borderRadius: '50%', + width: '90px', + height: '90px', + animation: 'spin 1s ease-in-out infinite', + }, + loadingText: { + marginTop: '10px', + fontSize: '1.2rem', + color: '#fff', + textAlign: 'center', + }, + uploadedFileWrapper: { + backgroundColor: '#fff', + border: '0.2px solid gray', + padding: '15px 0 0 17px', + borderRadius: '5px', + display: 'flex', + alignItems: 'center', + gap: '10px', + justifyContent: 'space-between', + }, + uploadedFileInfo: { + marginRight: '18rem', + marginTop: '0.2rem', + }, + uploadedFileText: { + fontSize: '16px', + color: '#1f2d3d', + }, + resultsTable: { + width: '60%', + borderCollapse: 'collapse', + }, + resultsRow: { + border: '0.1px solid gray', + padding: '8px', + }, + resultsCell: { + padding: '8px', + width: '30%', + }, + resultsValueCell: { + padding: '8px', + width: '70%', + color: 'red', + }, + resultsTrueValue: { + color: 'inherit', + }, + customLabel: { + fontWeight: 600, fontSize: '14px', color: '#212529' + }, + + // Mobile responsiveness adjustments (if necessary) + responsiveImageStyle: { + width: '100%', + maxHeight: '250px', + objectFit: 'cover', + marginTop: '20px', + }, + responsiveResultContainer: { + padding: '1rem', + border: '1px solid #ccc', + borderRadius: '8px', + marginTop: '20px', + }, + responsiveImageContainer: { + marginTop: '20px', + textAlign: 'center', + }, + responsiveSubmitButton: { + marginTop: '1rem', + }, + responsiveLoadingOverlay: { + position: 'absolute', + top: '0', + left: '0', + width: '100%', + height: '100%', + backgroundColor: 'rgba(0,0,0,0.5)', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + zIndex: '10', + }, + responsiveSpinner: { + border: '4px solid #f3f3f3', + borderTop: '4px solid #3498db', + borderRadius: '50%', + width: '50px', + height: '50px', + animation: 'spin 2s linear infinite', + }, + responsiveLoadingText: { + color: 'white', + marginTop: '10px', + }, + } return (
diff --git a/src/screens/Biometric/OcrKtp/Verify.jsx b/src/screens/Biometric/OcrKtp/Verify.jsx index 441bff3..8baa9ed 100644 --- a/src/screens/Biometric/OcrKtp/Verify.jsx +++ b/src/screens/Biometric/OcrKtp/Verify.jsx @@ -1,124 +1,189 @@ -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 { DummyKtp } from '../../../assets/images' +import React, { useState, useEffect, useRef } from 'react'; import { Link } from 'react-router-dom'; - +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faChevronDown, faChevronLeft, faImage, faTimes } from '@fortawesome/free-solid-svg-icons'; const Verify = () => { - - const BASE_URL = process.env.REACT_APP_BASE_URL - const API_KEY = process.env.REACT_APP_API_KEY + const BASE_URL = process.env.REACT_APP_BASE_URL; + const API_KEY = process.env.REACT_APP_API_KEY; + const fileTypes = ["image/jpeg", "image/png"]; // Use MIME types for better file validation + const fileInputRef = useRef(null); const [isSelectOpen, setIsSelectOpen] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [selectedImageName, setSelectedImageName] = useState(''); - const fileInputRef = useRef(null); - const [showResult, setShowResult] = useState(false); + const [file, setFile] = useState(null); const [applicationId, setApplicationId] = useState(''); - const [imageUrl, setImageUrl] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [applicationIds, setApplicationIds] = useState([]); + const [imageError, setImageError] = useState(''); + const [data, setData] = useState(null); + const [showResult, setShowResult] = useState(false); - // Example usage: - const data = { - nik: "21710121748901", - district: "BATAM KOTA", - name: "HANDOKO", - city: "KOTA BATAM", - dob: "BANJARMASIN, 12-12-1974", - state: "PROVINSI KEPULAUAN RIAU", - gender: "LAKI-LAKI", - religion: "KRISTEN", - bloodType: "A", - maritalStatus: "KAWIN", - address: "GOLDEN LAND BLOK FN NO.39", - occupation: "WIRASWASTA", - rtRw: "002/013", - nationality: "WNI", - village: "TAMAN BALOI", - imageUrl: DummyKtp, // Replace this with the actual image path - dark: false, - blur: false, - grayscale: false, - flashlight: false, - }; - + // Fetch Application IDs useEffect(() => { const fetchApplicationIds = async () => { try { - setIsLoading(true) - - const url = `${BASE_URL}/application/list`; - console.log('Fetching URL:', url); - - const response = await fetch(url, { + setIsLoading(true); + const response = await fetch(`${BASE_URL}/application/list`, { method: 'GET', headers: { 'accept': 'application/json', - 'x-api-key': `${API_KEY}`, + 'x-api-key': API_KEY, }, }); - + + if (!response.ok) { + throw new Error('Failed to fetch application IDs'); + } + const data = await response.json(); - if (data.status_code === 200) { - const ids = data.details.data.map(app => app.id); - console.log('Application Id: ' + ids); - setApplicationIds(data.details.data); + setApplicationIds(data.details.data); } else { - console.error('Failed to fetch data:', data.details.message); + throw new Error('Failed to fetch application IDs'); } } catch (error) { - console.error('Error fetching application IDs:', error); + setErrorMessage(error.message || 'Error fetching application IDs'); } finally { - setIsLoading(false) + setIsLoading(false); } }; - + fetchApplicationIds(); }, []); - const handleFocus = () => { - setIsSelectOpen(true); - }; + const handleFocus = () => setIsSelectOpen(true); + const handleBlur = () => setIsSelectOpen(false); - const handleBlur = () => { - setIsSelectOpen(false); - }; + // Handle file upload + const handleImageUpload = (e) => { + const file = e.target.files[0]; + if (!file) return; - const handleImageUpload = (event) => { - const file = event.target.files[0]; - - if (file && (file.type === 'image/jpeg' || file.type === 'image/jpg')) { - setSelectedImageName(file.name); - setErrorMessage(''); - } else { - alert('Please upload a valid image file (JPG, JPEG).'); + const fileType = file.type; // Use MIME type instead of file extension + if (!fileTypes.includes(fileType)) { + setImageError('Image format is not supported'); + setFile(null); + return; } + + if (file.size > 2 * 1024 * 1024) { // 2MB check + setImageError('File size exceeds 2MB'); + setFile(null); + return; + } + + setSelectedImageName(file.name); + setFile(file); + setImageError(''); }; + // Cancel file upload const handleImageCancel = () => { setSelectedImageName(''); - if (fileInputRef.current) { - fileInputRef.current.value = ''; + setFile(null); + setImageError(''); + fileInputRef.current.value = ''; + }; + + // Submit form and trigger OCR API + const handleCheckClick = async () => { + if (!file || !applicationId) { + setErrorMessage('Please select an application and upload a file.'); + return; + } + + setIsLoading(true); + const formData = new FormData(); + formData.append('application_id', applicationId); + formData.append('file', file); + + console.log(`id: ${applicationId}, file: ${file}`) + + try { + const response = await fetch(`${BASE_URL}/ocr-ktp`, { + method: 'POST', + headers: { + 'accept': 'application/json', + 'x-api-key': API_KEY, + }, + body: formData, + }); + + if (!response.ok) { + throw new Error('OCR processing failed'); + } + + const result = await response.json(); + + console.log('Full response:', result); // Log full response to inspect the structure + + if (result.status_code === 201) { + console.log('Success'); + // Correct the path to access the data-ktp object + const responseData = result.details.data?.['data-ktp'] || {}; + + // Log each field to inspect the data + console.log('NIK:', responseData.nik); + console.log('District:', responseData.kecamatan); + console.log('Name:', responseData.nama); + console.log('City:', responseData.kabkot); + console.log('Date of Birth:', responseData.tanggal_lahir); + console.log('State:', responseData.provinsi); + console.log('Gender:', responseData.jenis_kelamin); + console.log('Religion:', responseData.agama); + console.log('Blood Type:', responseData.golongan_darah); + console.log('Marital Status:', responseData.status_perkawinan); + console.log('Address:', responseData.alamat); + console.log('Occupation:', responseData.pekerjaan); + console.log('RT/RW:', `${responseData.rt}/${responseData.rw}`); + console.log('Nationality:', responseData.kewarganegaraan); + console.log('Image URL:', result.details.image_url); + console.log('Dark:', responseData.dark); + console.log('Blur:', responseData.blur); + console.log('Grayscale:', responseData.grayscale); + console.log('Flashlight:', responseData.flashlight); + + // Map the response data to a new object with default values if the property doesn't exist + const data = { + nik: responseData.nik || 'N/A', + district: responseData.kecamatan || 'N/A', + name: responseData.nama || 'N/A', + city: responseData.kabkot || 'N/A', + dob: responseData.tanggal_lahir || 'N/A', + state: responseData.provinsi || 'N/A', + gender: responseData.jenis_kelamin || 'N/A', + religion: responseData.agama || 'N/A', + bloodType: responseData.golongan_darah || 'N/A', + maritalStatus: responseData.status_perkawinan || 'N/A', + address: responseData.alamat || 'N/A', + occupation: responseData.pekerjaan || 'N/A', + rtRw: `${responseData.rt || 'N/A'}/${responseData.rw || 'N/A'}`, + nationality: responseData.kewarganegaraan || 'N/A', + imageUrl: result.details.image_url || '', + dark: responseData.dark || 'N/A', + blur: responseData.blur || 'N/A', + grayscale: responseData.grayscale || 'N/A', + flashlight: responseData.flashlight || 'N/A', + }; + + setData(data); + setShowResult(true); + setErrorMessage(''); + setSelectedImageName(''); + } else { + setErrorMessage('OCR processing failed'); + } + } catch (error) { + setErrorMessage(error.message || 'Error during OCR processing'); + } finally { + setIsLoading(false); } }; - - const handleCheckClick = async () => { - console.log('Verify - OCR Ktp') - setShowResult(true) - }; - - const getValueStyle = (value) => ({ - color: value ? 'green' : 'red', - }); - return ( -
- {/* Inject keyframes for the spinner */} +
- {isLoading && (

Loading...

)} - {/* Welcome Message */} +
-
-

- Alert -

-

- Get started now by creating an Application ID and explore all the demo services available on the dashboard. - Experience the ease and flexibility of trying out all our features firsthand. -

-
- {/* Tombol di bawah teks */} -
- - - -
+
+

Alert

+

+ Get started now by creating an Application ID and explore all the demo services available on the dashboard. + Experience the ease and flexibility of trying out all our features firsthand. +

+
+
+ + + +
- {/* Section */} -
- {/* Application ID Selection */} -
{/* Added align-items-center for vertical alignment */} +
+
+ {selectedImageName && ( +
+

File: {selectedImageName}

+ +
+ )} + {imageError &&

{imageError}

}
- - {errorMessage && ( - {errorMessage} - )}
- {/* Display uploaded image name */} - {selectedImageName && ( -
-
- -
-
Uploaded File:
-

{selectedImageName}

-
-
- -
-
-
- )} - - {/* Submit Button */} -
-
- {/* Result Section */} - {showResult && ( -
-
-

Results

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NIK{data.nik}
District{data.district}
Name{data.name}
City{data.city}
Date of Birth{data.dob}
State{data.state}
Gender{data.gender}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Religion{data.religion}
Blood Type{data.bloodType}
Marital Status{data.maritalStatus}
Address{data.address}
Occupation{data.occupation}
RT/RW{data.rtRw}
Nationality{data.nationality}
-
-
-
-
- KTP -
-
-

Dark: {data.dark.toString()}

-

Blur: {data.blur.toString()}

-
-
-

Grayscale: {data.grayscale.toString()}

-

Flashlight: {data.flashlight.toString()}

-
-
-
+ {errorMessage && ( +
+

{errorMessage}

)}
-
- ) -} -export default Verify + {showResult && data && ( +
+

OCR Result

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NIK{data.nik}
District{data.district}
Name{data.name}
City{data.city}
Date of Birth{data.dob}
State{data.state}
Gender{data.gender}
Religion{data.religion}
Blood Type{data.bloodType}
Marital Status{data.maritalStatus}
Address{data.address}
Occupation{data.occupation}
RT/RW{data.rtRw}
Nationality{data.nationality}
ImageKTP
+
+ )} +
+ ); +}; const styles = { - formGroup: { - marginTop: '-45px', - }, selectWrapper: { position: 'relative', - marginTop: '0', // Adjusted to remove excessive spacing + display: 'inline-block', + width: '100%', }, select: { + fontSize: '16px', + padding: '10px', width: '100%', - paddingRight: '30px', // Ensures padding for the icon + borderRadius: '4px', + border: '1px solid #ccc', }, chevronIcon: { position: 'absolute', - right: '10px', top: '50%', + right: '10px', transform: 'translateY(-50%)', - pointerEvents: 'none', + color: '#0542cc', }, remainingQuota: { - display: 'flex', // Ensures the text aligns properly - flexDirection: 'row', + display: 'flex', alignItems: 'center', - marginTop: '4px', // Adjust spacing from the label }, quotaText: { - fontSize: '40px', - color: '#0542cc', + fontSize: '24px', fontWeight: '600', }, timesText: { - marginLeft: '8px', - verticalAlign: 'super', - fontSize: '20px', // Adjust font size if necessary - }, - uploadArea: { - backgroundColor: '#e6f2ff', - height: '250px', - cursor: 'pointer', - marginTop: '1rem', - paddingTop: '22px', - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - border: '1px solid #ced4da', - borderRadius: '0.25rem', - }, - uploadIcon: { - fontSize: '40px', - color: '#0542cc', - marginBottom: '7px', - }, - uploadText: { - color: '#1f2d3d', - fontWeight: '400', fontSize: '16px', - lineHeight: '13px', + fontWeight: '300', }, - fileWrapper: { - backgroundColor: '#fff', - border: '0.2px solid gray', - padding: '15px 0 0 17px', - borderRadius: '5px', + uploadWrapper: { position: 'relative', - display: 'flex', - alignItems: 'center', - gap: '10px', - justifyContent: 'space-between', - }, - fileInfo: { - marginTop: '4rem', - display: 'flex', - alignItems: 'center', }, - imageIcon: { - color: '#0542cc', - fontSize: '24px', - marginBottom: '1rem' - }, - closeIcon: { - color: 'red', - cursor: 'pointer', - fontSize: '26px', - marginRight: '1rem', - marginBottom: '1rem' - }, - submitButton: { - marginLeft: 'auto', - marginTop: '4rem', - textAlign: 'start', - position: 'relative', // Menambahkan posisi relative - zIndex: 1, // Menambah z-index jika ada elemen yang menutupi - }, - uploadError: { - color: 'red', - fontSize: '12px', - marginTop: '5px', - }, - - containerResultStyle: { - padding: '20px', - border: '1px solid #ccc', - borderRadius: '8px', - backgroundColor: '#f9f9f9', - marginTop: '20px', - }, - resultContainer: { - overflowX: 'auto', // Allows horizontal scrolling if the table is too wide - }, - tableStyle: { - width: '100%', - borderCollapse: 'collapse', // Ensures that table borders are merged - }, - tableCell: { + errorContainer: { + marginTop: '10px', padding: '10px', - border: '1px solid #ddd', // Light gray border around each cell - textAlign: 'left', + backgroundColor: '#f8d7da', + border: '1px solid #f5c6cb', + borderRadius: '4px', + }, + errorText: { + color: '#721c24', + fontSize: '14px', + margin: '0', }, loadingOverlay: { - position: 'fixed', + position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.2)', display: 'flex', - flexDirection: 'column', justifyContent: 'center', alignItems: 'center', + backgroundColor: 'rgba(0, 0, 0, 0.5)', + color: 'white', + fontSize: '24px', zIndex: 1000, }, spinner: { - border: '4px solid rgba(0, 0, 0, 0.1)', - borderLeftColor: '#0542cc', + border: '4px solid #f3f3f3', + borderTop: '4px solid #3498db', borderRadius: '50%', - width: '90px', - height: '90px', - animation: 'spin 1s ease-in-out infinite', + width: '50px', + height: '50px', + animation: 'spin 2s linear infinite', }, loadingText: { - marginTop: '10px', - fontSize: '1.2rem', - color: '#fff', - textAlign: 'center', + marginLeft: '20px', + }, + tableStyle: { + width: '100%', + borderCollapse: 'collapse', + marginTop: '20px', + }, + tableCell: { + padding: '8px 15px', + border: '1px solid #ccc', + textAlign: 'left', }, }; + +export default Verify;