Fix issue error handling (KTP dan NPWP)

This commit is contained in:
Rizqika 2024-12-06 11:20:13 +07:00
parent 2a559da0d3
commit c0709ca144
3 changed files with 301 additions and 241 deletions

View File

@ -126,8 +126,8 @@ const Verify = () => {
img.onload = () => {
URL.revokeObjectURL(img.src);
if (img.width > 300 || img.height > 300) {
reject('Image dimensions must not exceed 300x300 pixels');
if (img.width > 320 || img.height > 200) {
reject('Image dimensions must not exceed 320x200 pixels');
} else {
resolve(true);
}
@ -142,6 +142,7 @@ const Verify = () => {
// Update handleImageUpload to include dimension checking
const handleImageUpload = async (file) => {
setErrorMessage('');
setFile(file);
setSelectedImageName(file.name);
@ -206,7 +207,8 @@ const Verify = () => {
};
const handleApiError = (response) => {
// Handle 400 Bad Request
// Handle 400 Bad
if (response.status_code === 400) {
console.error('❌ Bad Request:', {
status: response.status_code,
@ -233,9 +235,9 @@ const Verify = () => {
};
// Submit form and trigger OCR API
const handleCheckClick = async () => {
const handleCheckClick = () => {
if (!validateForm()) {
return; // Form is not valid
return;
}
setIsLoading(true);
@ -243,30 +245,34 @@ const Verify = () => {
formData.append('application_id', applicationId);
formData.append('file', file);
try {
const response = await fetch(`${BASE_URL}/ocr-ktp`, {
fetch(`${BASE_URL}/ocr-ktp`, {
method: 'POST',
headers: {
'accept': 'application/json',
'x-api-key': API_KEY,
},
body: formData,
})
.then(response => {
if (response.status === 400) {
return response.json().then(errorData => {
throw new Error(errorData.detail);
});
if (!response.ok) {
throw new Error('OCR processing failed, Please check your input, Please check your input');
}
const result = await response.json();
if (!response.ok) {
throw new Error('OCR processing failed, Please check your input');
}
return response.json();
})
.then(result => {
console.log('📡 API Response:', result);
// Log the full result to verify structure
console.log('OCR API Response:', result);
if (result.status_code !== 201) {
throw new Error(handleApiError(result));
}
if (result.status_code === 201) {
const responseData = result.details.data?.['data-ktp'] || {};
console.log('✅ OCR Success:', result);
const updateQuota = result.details.data.quota
const updateQuota = result.details.data.quota;
const data = {
nik: responseData.nik || 'N/A',
@ -283,47 +289,32 @@ const Verify = () => {
occupation: responseData.pekerjaan || 'N/A',
rtRw: `${responseData.rt || 'N/A'}/${responseData.rw || 'N/A'}`,
nationality: responseData.kewarganegaraan || 'N/A',
imageUrl: result.details.data?.image_url || '', // Properly access image_url
imageUrl: result.details.data?.image_url || '',
};
setSelectedQuota(updateQuota)
console.log('Image URL from OCR:', result.details.data?.image_url); // Log the image URL correctly
setSelectedQuota(updateQuota);
setData(data);
setShowResult(true);
setErrorMessage('');
setSelectedImageName('');
setResultImageLabel(selectedImageName);
// Fetch image if image URL exists in the result
if (result.details.data?.image_url) {
const imageFileName = result.details.data.image_url.split('/').pop(); // Get the image filename
console.log('Image file name:', imageFileName); // Debug the file name
await fetchImage(imageFileName); // Call the fetchImage function to fetch the image
const imageFileName = result.details.data.image_url.split('/').pop();
return fetchImage(imageFileName);
}
} else {
const errorMsg = handleApiError(result);
setErrorMessage(errorMsg);
})
.catch(error => {
console.error('🔥 Request Failed:', error);
setErrorMessage(error.message);
setShowResult(false);
console.error('❌ OCR Failed:', {
error: errorMsg,
response: result
});
}
} catch (error) {
const errorMsg = 'Internal Server Error';
setErrorMessage(errorMsg);
setShowResult(false);
console.error('🔥 Request Failed:', {
error: error.message,
detail: error
});
} finally {
})
.finally(() => {
setIsLoading(false);
}
});
};
// The fetchImage function you already have in your code
const fetchImage = async (imageFileName) => {
setIsLoading(true);
@ -602,7 +593,7 @@ const Verify = () => {
<p style={styles.uploadText}>Drag and Drop Here</p>
<p>Or</p>
<a href="#" onClick={() => fileInputRef.current.click()} style={styles.browseLink}>Browse</a>
<p className="text-muted" style={styles.uploadText}>Recommended size: 300x300 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Recommended size: 320x200 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Supported file types: JPG, JPEG</p>
</div>

View File

@ -126,8 +126,8 @@ const Verify = () => {
img.onload = () => {
URL.revokeObjectURL(img.src);
if (img.width > 300 || img.height > 300) {
reject('Image dimensions must not exceed 300x300 pixels');
if (img.width > 320 || img.height > 200) {
reject('Image dimensions must not exceed 320x200 pixels');
} else {
resolve(true);
}
@ -142,6 +142,7 @@ const Verify = () => {
// Update handleImageUpload function
const handleImageUpload = async (file) => {
setErrorMessage('');
setFile(file);
setSelectedImageName(file.name);
@ -205,10 +206,33 @@ const Verify = () => {
return Object.values(errors).every(error => error === '');
};
// Submit form and trigger OCR API
const handleCheckClick = async () => {
const handleApiError = (response) => {
if (response.status_code === 400) {
console.error('❌ Bad Request:', {
status: response.status_code,
detail: response.detail || 'Mohon Upload NPWP'
});
return response.detail || 'Mohon Upload NPWP';
}
if (response.status_code >= 500) {
console.error('🔥 Server Error:', {
status: response.status_code,
message: 'Internal Server Error'
});
return 'Internal Server Error';
}
console.error('⚠️ Unknown Error:', {
status: response.status_code,
response
});
return 'Terjadi kesalahan. Silakan coba lagi.';
};
const handleCheckClick = () => {
if (!validateForm()) {
return; // Form is not valid
return;
}
setIsLoading(true);
@ -216,63 +240,66 @@ const Verify = () => {
formData.append('application_id', applicationId);
formData.append('file', file);
try {
const response = await fetch(`${BASE_URL}/ocr-npwp`, {
fetch(`${BASE_URL}/ocr-npwp`, {
method: 'POST',
headers: {
'accept': 'application/json',
'x-api-key': API_KEY,
},
body: formData,
})
.then(response => {
if (response.status === 400) {
return response.json().then(errorData => {
throw new Error(errorData.detail);
});
}
if (!response.ok) {
throw new Error('OCR processing failed');
throw new Error('OCR processing failed, Please check your input');
}
return response.json();
})
.then(result => {
console.log('📡 API Response:', result);
if (result.status_code !== 201) {
throw new Error(handleApiError(result));
}
const result = await response.json();
// Log the full result to verify structure
console.log('OCR API Response:', result);
if (result.status_code === 201) {
const responseData = result.details.data?.['data-npwp'] || {};
const updateQuota = result.details.data.quota
const updateQuota = result.details.data.quota;
const data = {
npwp: responseData.npwp || 'N/A',
npwpName: responseData.name || 'N/A',
npwpAddress: responseData.address || 'N/A',
npwpX: responseData.npwp_x || 'N/A',
imageUrl: result.details.data?.image_url || '', // Properly access image_url
imageUrl: result.details.data?.image_url || '',
};
setSelectedQuota(updateQuota)
console.log('Image URL from OCR:', result.details.data?.image_url); // Log the image URL correctly
setSelectedQuota(updateQuota);
setData(data);
setShowResult(true);
setErrorMessage('');
setSelectedImageName('');
setResultImageLabel(selectedImageName);
// Fetch image if image URL exists in the result
if (result.details.data?.image_url) {
const imageFileName = result.details.data.image_url.split('/').pop(); // Get the image filename
console.log('Image file name:', imageFileName); // Debug the file name
await fetchImage(imageFileName); // Call the fetchImage function to fetch the image
const imageFileName = result.details.data.image_url.split('/').pop();
return fetchImage(imageFileName);
}
} else {
setErrorMessage('OCR processing failed');
}
} catch (error) {
setErrorMessage(error.message || 'Error during OCR processing');
} finally {
})
.catch(error => {
console.error('🔥 Request Failed:', error);
setErrorMessage(error.message);
setShowResult(false);
})
.finally(() => {
setIsLoading(false);
}
});
};
// The fetchImage function you already have in your code
const fetchImage = async (imageFileName) => {
setIsLoading(true);
@ -425,16 +452,6 @@ const Verify = () => {
},
};
const formatFileSize = (sizeInBytes) => {
if (sizeInBytes < 1024) {
return `${sizeInBytes} bytes`; // Jika ukuran lebih kecil dari 1 KB
} else if (sizeInBytes < 1048576) {
return `${(sizeInBytes / 1024).toFixed(2)} KB`; // Jika ukuran lebih kecil dari 1 MB
} else {
return `${(sizeInBytes / 1048576).toFixed(2)} MB`; // Jika ukuran lebih besar dari 1 MB
}
};
if (!isServer) {
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
@ -549,7 +566,7 @@ const Verify = () => {
<p style={styles.uploadText}>Drag and Drop Here</p>
<p>Or</p>
<a href="#" onClick={() => fileInputRef.current.click()} style={styles.browseLink}>Browse</a>
<p className="text-muted" style={styles.uploadText}>Recommended size: 300x300 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Recommended size: 320x200 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Supported file types: JPG, JPEG, PNG</p>
</div>
@ -567,11 +584,6 @@ const Verify = () => {
{selectedImageName && (
<div className="mt-3">
<p><strong>File:</strong> {selectedImageName}</p>
{file && (
<p style={styles.fileSize}>
Size: {formatFileSize(file.size)}
</p>
)}
<button className="btn btn-danger" onClick={handleImageCancel}>
<FontAwesomeIcon icon={faTimes} className="me-2" />Cancel
</button>

View File

@ -119,17 +119,61 @@ const Verify = () => {
}
};
const handleImageUpload = (file) => {
const checkImageDimensions = (file) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(img.src);
if (img.width > 320 || img.height > 200) {
reject('Image dimensions must not exceed 320x200 pixels');
} else {
resolve(true);
}
};
img.onerror = () => {
URL.revokeObjectURL(img.src);
reject('Failed to load image');
};
});
};
const handleImageUpload = async (file) => {
setErrorMessage('');
setFile(file);
setSelectedImageName(file.name);
try {
// Check if file is PNG
if (file.type === 'image/png') {
setImageError('The image format is not suitable. Only JPG and JPEG files are allowed.');
setFile(null);
setSelectedImageName('');
return;
}
// Validate file type
if (!fileTypes.includes(file.type)) {
setImageError('Invalid file type. Only JPG, JPEG, and PNG are allowed.');
} else if (file.size > 2 * 1024 * 1024) { // Max 2MB
setImageError('Invalid file type. Only JPG and JPEG are allowed.');
return;
}
// Validate file size
if (file.size > 2 * 1024 * 1024) {
setImageError('File size exceeds 2MB.');
} else {
return;
}
// Validate image dimensions
await checkImageDimensions(file);
setImageError('');
} catch (error) {
setImageError(error);
setFile(null);
setSelectedImageName('');
}
};
@ -161,10 +205,33 @@ const Verify = () => {
return Object.values(errors).every(error => error === '');
};
// Submit form and trigger OCR API
const handleCheckClick = async () => {
const handleApiError = (response) => {
if (response.status_code === 400) {
console.error('❌ Bad Request:', {
status: response.status_code,
detail: response.detail || 'Mohon Upload SIM'
});
return response.detail || 'Mohon Upload SIM';
}
if (response.status_code >= 500) {
console.error('🔥 Server Error:', {
status: response.status_code,
message: 'Internal Server Error'
});
return 'Internal Server Error';
}
console.error('⚠️ Unknown Error:', {
status: response.status_code,
response
});
return 'Terjadi kesalahan. Silakan coba lagi.';
};
const handleCheckClick = () => {
if (!validateForm()) {
return; // Form is not valid
return;
}
setIsLoading(true);
@ -172,28 +239,34 @@ const Verify = () => {
formData.append('application_id', applicationId);
formData.append('file', file);
try {
const response = await fetch(`${BASE_URL}/ocr-sim`, {
fetch(`${BASE_URL}/ocr-sim`, {
method: 'POST',
headers: {
'accept': 'application/json',
'x-api-key': API_KEY,
},
body: formData,
})
.then(response => {
if (response.status === 400) {
return response.json().then(errorData => {
throw new Error(errorData.detail);
});
}
if (!response.ok) {
throw new Error('OCR processing failed');
throw new Error('OCR processing failed, Please check your input');
}
return response.json();
})
.then(result => {
console.log('📡 API Response:', result);
if (result.status_code !== 201) {
throw new Error(handleApiError(result));
}
const result = await response.json();
// Log the full result to verify structure
console.log('OCR API Response:', result);
if (result.status_code === 201) {
const responseData = result.details.data?.['data-sim'] || {};
const updateQuota = result.details.data.quota
const updateQuota = result.details.data.quota;
const data = {
sim: responseData.sim || 'N/A',
@ -208,35 +281,32 @@ const Verify = () => {
simHeight: responseData.height || 'N/A',
simBlood: responseData.blood || 'N/A',
simOccupation: responseData.occupation || 'N/A',
imageUrl: result.details.data?.image_url || '', // Properly access image_url
imageUrl: result.details.data?.image_url || '',
};
setSelectedQuota(updateQuota)
console.log('Image URL from OCR:', result.details.data?.image_url); // Log the image URL correctly
setSelectedQuota(updateQuota);
setData(data);
setShowResult(true);
setErrorMessage('');
setSelectedImageName('');
setResultImageLabel(selectedImageName);
// Fetch image if image URL exists in the result
if (result.details.data?.image_url) {
const imageFileName = result.details.data.image_url.split('/').pop(); // Get the image filename
console.log('Image file name:', imageFileName); // Debug the file name
await fetchImage(imageFileName); // Call the fetchImage function to fetch the image
const imageFileName = result.details.data.image_url.split('/').pop();
return fetchImage(imageFileName);
}
} else {
setErrorMessage('OCR processing failed');
}
} catch (error) {
setErrorMessage(error.message || 'Error during OCR processing');
} finally {
})
.catch(error => {
console.error('🔥 Request Failed:', error);
setErrorMessage(error.message);
setShowResult(false);
})
.finally(() => {
setIsLoading(false);
}
});
};
// The fetchImage function you already have in your code
const fetchImage = async (imageFileName) => {
setIsLoading(true);
@ -388,16 +458,6 @@ const Verify = () => {
},
};
const formatFileSize = (sizeInBytes) => {
if (sizeInBytes < 1024) {
return `${sizeInBytes} bytes`; // Jika ukuran lebih kecil dari 1 KB
} else if (sizeInBytes < 1048576) {
return `${(sizeInBytes / 1024).toFixed(2)} KB`; // Jika ukuran lebih kecil dari 1 MB
} else {
return `${(sizeInBytes / 1048576).toFixed(2)} MB`; // Jika ukuran lebih besar dari 1 MB
}
};
if (!isServer) {
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
@ -512,7 +572,7 @@ const Verify = () => {
<p style={styles.uploadText}>Drag and Drop Here</p>
<p>Or</p>
<a href="#" onClick={() => fileInputRef.current.click()} style={styles.browseLink}>Browse</a>
<p className="text-muted" style={styles.uploadText}>Recommended size: 300x300 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Recommended size: 320x200 (Max File Size: 2MB)</p>
<p className="text-muted" style={styles.uploadText}>Supported file types: JPG, JPEG, PNG</p>
</div>
@ -523,24 +583,21 @@ const Verify = () => {
id="imageInput"
className="form-control"
style={{ display: 'none' }}
accept="image/jpeg, image/png"
accept="image/jpeg, image/jpg"
onChange={(e) => handleImageUpload(e.target.files[0])}
/>
{selectedImageName && (
<div className="mt-3">
<p><strong>File:</strong> {selectedImageName}</p>
{file && (
<p style={styles.fileSize}>
Size: {formatFileSize(file.size)}
</p>
)}
<button className="btn btn-danger" onClick={handleImageCancel}>
<FontAwesomeIcon icon={faTimes} className="me-2" />Cancel
</button>
</div>
)}
{/* Display validation errors */}
{validationErrors.file && <p style={styles.errorText}>{validationErrors.file}</p>}
{imageError && <p style={styles.errorText}>{imageError}</p>}
</div>
</div>
</div>