ok
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Modal from "./Modal";
|
||||
import FormComponent from "./FormComponent";
|
||||
import PaginatedFormEditable from "./PaginatedFormEditable";
|
||||
import pixelmatch from "pixelmatch";
|
||||
import Tesseract from "tesseract.js";
|
||||
|
||||
const STORAGE_KEY = "camera_canvas_gallery";
|
||||
|
||||
@@ -53,13 +54,23 @@ const CameraCanvas = () => {
|
||||
null,
|
||||
canvasA.width,
|
||||
canvasA.height,
|
||||
{ threshold: 0.6 }
|
||||
{ threshold: 0.5 }
|
||||
);
|
||||
|
||||
const similarity = diffPixels / (canvasA.width * canvasA.height);
|
||||
return similarity < 0.2; // you can adjust the threshold
|
||||
};
|
||||
|
||||
const extractTextFromCanvas = async (canvas) => {
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
|
||||
const result = await Tesseract.recognize(dataUrl, "ind", {
|
||||
logger: (m) => console.log(m), // opsional: untuk melihat progress
|
||||
});
|
||||
|
||||
return result.data.text;
|
||||
};
|
||||
|
||||
const rectRef = useRef({
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -232,7 +243,22 @@ const CameraCanvas = () => {
|
||||
);
|
||||
|
||||
const isSimilar = isImageSimilar(cropCanvas, sampleKtpCanvas);
|
||||
setKTPdetected(isSimilar);
|
||||
if (isSimilar) {
|
||||
const extractedText = await extractTextFromCanvas(cropCanvas);
|
||||
console.log("OCR Result:", extractedText);
|
||||
|
||||
const lowercaseText = extractedText.toLowerCase();
|
||||
|
||||
if (
|
||||
lowercaseText.includes("provinsi") ||
|
||||
lowercaseText.includes("nik") ||
|
||||
lowercaseText.includes("kewarganegaraan")
|
||||
) {
|
||||
setKTPdetected(true);
|
||||
} else {
|
||||
setKTPdetected(false);
|
||||
}
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
// Continue to OCR etc...
|
||||
@@ -582,6 +608,7 @@ const CameraCanvas = () => {
|
||||
</h4>
|
||||
</div>
|
||||
)}
|
||||
{fileTemp && <PaginatedFormEditable data={fileTemp} />}
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
|
||||
94
src/PaginatedFormEditable.js
Normal file
94
src/PaginatedFormEditable.js
Normal file
@@ -0,0 +1,94 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
// Helper to format ISO date
|
||||
const formatDate = (iso) => {
|
||||
if (!iso) return "";
|
||||
const date = new Date(iso);
|
||||
return date.toISOString().split("T")[0]; // YYYY-MM-DD
|
||||
};
|
||||
|
||||
const PaginatedFormEditable = ({ data }) => {
|
||||
const [formData, setFormData] = useState(() => {
|
||||
const flat = {};
|
||||
Object.entries(data[0]).forEach(([key, value]) => {
|
||||
if (value && typeof value === "object" && "value" in value) {
|
||||
flat[key] = formatDate(value.value);
|
||||
} else {
|
||||
flat[key] = value;
|
||||
}
|
||||
});
|
||||
return flat;
|
||||
});
|
||||
|
||||
const fields = Object.keys(formData);
|
||||
const fieldsPerPage = 3;
|
||||
const [page, setPage] = useState(0);
|
||||
const totalPages = Math.ceil(fields.length / fieldsPerPage);
|
||||
|
||||
const handleChange = (key, newValue) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[key]: newValue,
|
||||
}));
|
||||
};
|
||||
|
||||
const startIndex = page * fieldsPerPage;
|
||||
const currentFields = fields.slice(startIndex, startIndex + fieldsPerPage);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 400,
|
||||
margin: "auto",
|
||||
padding: 20,
|
||||
border: "1px solid #ccc",
|
||||
borderRadius: 10,
|
||||
}}
|
||||
>
|
||||
<h3>Edit Form Data</h3>
|
||||
|
||||
{currentFields.map((key) => (
|
||||
<div key={key} style={{ marginBottom: 10 }}>
|
||||
<label style={{ fontWeight: "bold", textTransform: "capitalize" }}>
|
||||
{key}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData[key] || ""}
|
||||
onChange={(e) => handleChange(key, e.target.value)}
|
||||
style={{
|
||||
width: "100%",
|
||||
padding: 8,
|
||||
borderRadius: 5,
|
||||
border: "1px solid #ddd",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
marginTop: 20,
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => setPage((prev) => Math.max(prev - 1, 0))}
|
||||
disabled={page === 0}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => setPage((prev) => Math.min(prev + 1, totalPages - 1))}
|
||||
disabled={page >= totalPages - 1}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaginatedFormEditable;
|
||||
Reference in New Issue
Block a user