diff options
Diffstat (limited to 'app/lib/camera/component')
| -rw-r--r-- | app/lib/camera/component/camera.tsx | 79 | ||||
| -rw-r--r-- | app/lib/camera/component/cardFoto.tsx | 27 | ||||
| -rw-r--r-- | app/lib/camera/component/hedear.tsx | 21 | ||||
| -rw-r--r-- | app/lib/camera/component/pakageCamera.tsx | 44 | ||||
| -rw-r--r-- | app/lib/camera/component/scannerBarcode.tsx | 56 | ||||
| -rw-r--r-- | app/lib/camera/component/sjCamera.tsx | 48 |
6 files changed, 275 insertions, 0 deletions
diff --git a/app/lib/camera/component/camera.tsx b/app/lib/camera/component/camera.tsx new file mode 100644 index 0000000..b398616 --- /dev/null +++ b/app/lib/camera/component/camera.tsx @@ -0,0 +1,79 @@ +import { CameraSharp } from "@mui/icons-material"; +import { Button, IconButton } from "@mui/material"; +import Image from "next/image"; +import React, { useRef } from "react"; +import Webcam from "react-webcam"; + +interface WebcamCaptureProps { + image: string | null; + setImage: (image: string | null) => void; + isWebcamVisible: boolean; + setIsWebcamVisible: (isVisible: boolean) => void; +} + +const WebcamCapture: React.FC<WebcamCaptureProps> = ({ + image, + setImage, + isWebcamVisible, + setIsWebcamVisible, +}) => { + const webcamRef = useRef<Webcam>(null); + + // Mengambil foto dari webcam + const capture = () => { + const image = webcamRef.current?.getScreenshot(); + setIsWebcamVisible(false); + setImage(image || null); + }; + + const takePicture = () => { + setImage(null); + setIsWebcamVisible(true); + }; + + // Mengatur ukuran webcam + const videoConstraints = { + width: 500, + height: 480, + facingMode: { + exact: "environment" // untuk kamera belakang + }, + }; + + return ( + <div className="items-center"> + {!isWebcamVisible && ( + <Button variant="text" size="large" onClick={() => takePicture()}> + Ambil Foto Surat Jalan + </Button> + )} + + {isWebcamVisible && ( + <div> + <Webcam + audio={false} + ref={webcamRef} + screenshotFormat="image/jpeg" + videoConstraints={videoConstraints} + /> + <IconButton aria-label="camera" size="large" onClick={() => capture()}> + <CameraSharp fontSize="inherit" /> + </IconButton> + </div> + )} + {image && ( + <div> + <Image + src={image} + alt="Captured" + width={500} + height={480} + unoptimized + /> + </div> + )} + </div> + ); +}; + +export default WebcamCapture; diff --git a/app/lib/camera/component/cardFoto.tsx b/app/lib/camera/component/cardFoto.tsx new file mode 100644 index 0000000..34da216 --- /dev/null +++ b/app/lib/camera/component/cardFoto.tsx @@ -0,0 +1,27 @@ +import { Card, CardContent, Typography } from "@mui/material"; +import Image from "next/image"; +import React from "react"; +import useCameraStore from "../hooks/useCameraStore"; + +const CardFotos = () => { + const { imagePackage } = useCameraStore(); + return ( + <Card sx={{ maxWidth: 200 }}> + <Image + src={imagePackage ?? ''} + alt="Captured" + layout="fill" + objectFit="cover" + unoptimized + className="p-2" + /> + <CardContent> + <Typography gutterBottom variant="h5" component="div"> + Lizard + </Typography> + </CardContent> + </Card> + ); +} + +export default CardFotos diff --git a/app/lib/camera/component/hedear.tsx b/app/lib/camera/component/hedear.tsx new file mode 100644 index 0000000..5cf3f1d --- /dev/null +++ b/app/lib/camera/component/hedear.tsx @@ -0,0 +1,21 @@ +// components/Header.tsx +import Image from "next/image"; + +export default function Header() { + return ( + <nav className="fixed top-0 left-0 w-full bg-white border-b-2 border-red-500 py-4 px-4 sm:px-96 z-50 shadow-md"> + <div className="flex justify-between items-center"> + <div className="flex items-center"> + <Image + src="/images/indoteknik-logo.png" // Ganti dengan path logo Anda + alt="Logo" + width={120} + height={60} + className="rounded-full" + /> + </div> + + </div> + </nav> + ); +} diff --git a/app/lib/camera/component/pakageCamera.tsx b/app/lib/camera/component/pakageCamera.tsx new file mode 100644 index 0000000..e0c7158 --- /dev/null +++ b/app/lib/camera/component/pakageCamera.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import useCameraStore from "../hooks/useCameraStore"; +import { IconButton } from "@mui/material"; +import { PhotoCameraFrontOutlined } from "@mui/icons-material"; + +const PackageCamera: React.FC = () => { + const { setImagePackage } = useCameraStore(); + const handleCapture = (event: React.ChangeEvent<HTMLInputElement>) => { + const file = event.target.files?.[0]; + if (file) { + const reader = new FileReader(); + reader.onloadend = () => { + setImagePackage(reader.result as string); + }; + reader.readAsDataURL(file); + } + }; + + return ( + <div className="px-4 py-8 items-center border-2 rounded-md shadow-sm w-[49%] text-center "> + <input + type="file" + accept="image/*" + capture="environment" + onChange={handleCapture} + className="hidden" + id="pakageCameraInput" + /> + <label htmlFor="pakageCameraInput" className="text-gray-600"> + <IconButton + color="primary" + aria-label="upload picture" + component="span" + > + <PhotoCameraFrontOutlined fontSize="large" /> + </IconButton> + <br /> + Foto Penerima + </label> + </div> + ); +}; + +export default PackageCamera; diff --git a/app/lib/camera/component/scannerBarcode.tsx b/app/lib/camera/component/scannerBarcode.tsx new file mode 100644 index 0000000..3079e33 --- /dev/null +++ b/app/lib/camera/component/scannerBarcode.tsx @@ -0,0 +1,56 @@ +import { QrCode2 } from "@mui/icons-material"; +import { Button, TextField } from "@mui/material"; +import dynamic from "next/dynamic"; +import React, { useState } from "react"; +import useCameraStore from "../hooks/useCameraStore"; + +const BarcodeScannerComponent = dynamic( + () => import("react-qr-barcode-scanner"), + { ssr: false } +); +const BarcodeScanner: React.FC = () => { + const { barcode, setBarcode } = useCameraStore(); + const [isCameraActive, setIsCameraActive] = useState(false); + + return ( + <div> + <Button + variant="outlined" + onClick={() => setIsCameraActive(!isCameraActive)} + startIcon={<QrCode2 />} + color="error" + className="mb-2" + > + {isCameraActive ? "Cancel" : "Scane Code"} + </Button> + + {isCameraActive && ( + <BarcodeScannerComponent + width={500} // Tingkatkan ukuran untuk memperjelas gambar + height={300} + onUpdate={(err, result) => { + if (result) { + setBarcode(result.getText()); + setIsCameraActive(false); + } + }} + /> + )} + + <div className="mt-4"> + <TextField + fullWidth + label="Detected Picking Code" + id="outlined-basic" + value={barcode} + onChange={ (e) => setBarcode(e.target.value) } + InputLabelProps={{ + shrink: true, // Label akan selalu berada di atas (outline) + }} + /> + </div> + </div> + ); +}; + +export default BarcodeScanner; diff --git a/app/lib/camera/component/sjCamera.tsx b/app/lib/camera/component/sjCamera.tsx new file mode 100644 index 0000000..5cc39ad --- /dev/null +++ b/app/lib/camera/component/sjCamera.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import useCameraStore from "../hooks/useCameraStore"; +import { IconButton } from "@mui/material"; +import { PendingActions } from "@mui/icons-material"; + +const SjCamera: React.FC = () => { + const { setImageSj } = useCameraStore(); + const handleSuratJalanCapture = ( + event: React.ChangeEvent<HTMLInputElement> + ) => { + const file = event.target.files?.[0]; + if (file) { + const reader = new FileReader(); + reader.onloadend = () => { + setImageSj(reader.result as string); + }; + reader.readAsDataURL(file); + } + }; + + return ( + <> + <div className="p-4 py-8 items-center border-2 rounded-md shadow-sm w-[49%] text-center"> + <input + type="file" + accept="image/*" + capture="environment" + onChange={handleSuratJalanCapture} + className="hidden" + id="suratJalanInput" + /> + <label htmlFor="suratJalanInput" className="text-gray-600"> + <IconButton + color="primary" + aria-label="upload picture" + component="span" + > + <PendingActions fontSize="large" /> + </IconButton> + <br /> + Foto Surat Jalan + </label> + </div> + </> + ); +}; + +export default SjCamera; |
