mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-20 13:48:21 +02:00
Create a new sales registry app with identity verification features
Initial commit of the React application with UI components, form, camera, and indexedDB integration for sale data management. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 91318273-c764-4fd4-be04-bdc12c38af32 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/02867739-9ff7-4441-aca2-12e0153376c5.jpg
This commit is contained in:
1 parent
4969159ef9
commit
4fac1078a1
83 files changed
+16585
No files matched your search
@@ -0,0 +1,102 @@
|
||||
import { useState, useRef, useCallback } from 'react';
|
||||
import { PhotoType } from '@/types/sale';
|
||||
|
||||
export function useCamera() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [currentPhotoType, setCurrentPhotoType] = useState<PhotoType | null>(null);
|
||||
const [isCapturing, setIsCapturing] = useState(false);
|
||||
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const streamRef = useRef<MediaStream | null>(null);
|
||||
|
||||
const startCamera = useCallback(async (photoType: PhotoType) => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: 'environment' }
|
||||
});
|
||||
|
||||
streamRef.current = stream;
|
||||
setCurrentPhotoType(photoType);
|
||||
setIsOpen(true);
|
||||
|
||||
if (videoRef.current) {
|
||||
videoRef.current.srcObject = stream;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Camera error:', error);
|
||||
throw new Error('Impossible d\'accéder à la caméra');
|
||||
}
|
||||
}, []);
|
||||
|
||||
const capturePhoto = useCallback((): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!videoRef.current || !canvasRef.current) {
|
||||
reject(new Error('Video or canvas not available'));
|
||||
return;
|
||||
}
|
||||
|
||||
setIsCapturing(true);
|
||||
|
||||
const video = videoRef.current;
|
||||
const canvas = canvasRef.current;
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
if (!context) {
|
||||
reject(new Error('Canvas context not available'));
|
||||
return;
|
||||
}
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
|
||||
context.drawImage(video, 0, 0);
|
||||
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
if (!blob) {
|
||||
reject(new Error('Failed to create image blob'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
setIsCapturing(false);
|
||||
resolve(e.target?.result as string);
|
||||
};
|
||||
reader.onerror = () => {
|
||||
setIsCapturing(false);
|
||||
reject(new Error('Failed to read image'));
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
},
|
||||
'image/jpeg',
|
||||
0.8
|
||||
);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const stopCamera = useCallback(() => {
|
||||
if (streamRef.current) {
|
||||
streamRef.current.getTracks().forEach(track => track.stop());
|
||||
streamRef.current = null;
|
||||
}
|
||||
|
||||
setIsOpen(false);
|
||||
setCurrentPhotoType(null);
|
||||
setIsCapturing(false);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
isOpen,
|
||||
currentPhotoType,
|
||||
isCapturing,
|
||||
videoRef,
|
||||
canvasRef,
|
||||
startCamera,
|
||||
capturePhoto,
|
||||
stopCamera
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user