blob: 18f953d7aa0c3d8c141c052aa0365602a44fe3e9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
import { QrCode2 } from "@mui/icons-material";
import { Button, TextField } from "@mui/material";
import { BrowserMultiFormatReader } from "@zxing/browser";
import React, { useEffect, useRef, useState } from "react";
import useCameraStore from "../hooks/useCameraStore";
const BarcodeScanner: React.FC = () => {
const { barcode, setBarcode } = useCameraStore();
const [isCameraActive, setIsCameraActive] = useState(false);
const videoRef = useRef<HTMLVideoElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const stopCamera = () => {
const video = videoRef.current;
if (!video || !video.srcObject) return;
const stream = video.srcObject as MediaStream;
stream.getTracks().forEach((track) => track.stop());
video.srcObject = null;
};
useEffect(() => {
if (!isCameraActive || !videoRef.current) return;
const reader = new BrowserMultiFormatReader();
let cancelled = false;
reader
.decodeOnceFromVideoDevice(undefined, videoRef.current)
.then((result) => {
if (cancelled) return;
setBarcode(result.getText());
setIsCameraActive(false);
stopCamera();
// 🔥 fokus ke input biar bisa diedit
setTimeout(() => {
inputRef.current?.focus();
}, 100);
})
.catch(() => {
// ignore cancel / permission stop
});
return () => {
cancelled = true;
stopCamera();
};
}, [isCameraActive, setBarcode]);
return (
<div>
<Button
variant="outlined"
color="error"
startIcon={<QrCode2 />}
className="mb-2"
onClick={() => {
if (isCameraActive) stopCamera();
setIsCameraActive((v) => !v);
}}
>
{isCameraActive ? "Cancel" : "Scan Code"}
</Button>
{isCameraActive && (
<>
<p className="text-xs text-gray-500 mb-1">
Arahkan barcode ke tengah layar
</p>
<video ref={videoRef} className="w-full h-[300px] border rounded" />
</>
)}
<div className="mt-4">
<TextField
fullWidth
label="Detected Picking Code"
value={barcode}
inputRef={inputRef}
onChange={(e) => setBarcode(e.target.value)}
InputLabelProps={{ shrink: true }}
/>
</div>
</div>
);
};
export default BarcodeScanner;
|