Improve photo capture process with error handling and browser support

Implement enhanced camera access with browser compatibility checks and error handling in useSimpleCamera hook and NewSaleFormMulti component.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 4b008663-bd72-492b-b0b6-fa252367e730
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/4b008663-bd72-492b-b0b6-fa252367e730/N4gXSMv
This commit is contained in:
michaelschal committed 2025-07-19 13:20:11 +00:00
1 parent 4254ebf94a
commit ba643b557a
3 files changed
+124 -9

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

+79 -2
View File
@@ -137,7 +137,84 @@ export default function NewSaleFormMulti() {
}; };
const handlePhotoCapture = async (photoType: PhotoType) => { const handlePhotoCapture = async (photoType: PhotoType) => {
await startCamera(photoType); console.log('=== PHOTO CAPTURE REQUESTED ===');
console.log('Photo type:', photoType);
// Vérifications préliminaires
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
toast({
title: "Navigateur non compatible",
description: "Votre navigateur ne supporte pas la capture photo. Utilisez Chrome, Firefox ou Safari récent.",
variant: "destructive",
});
return;
}
// Vérifier si nous sommes en HTTPS (requis par certains navigateurs)
if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
toast({
title: "Connexion sécurisée requise",
description: "L'accès à la caméra nécessite une connexion HTTPS.",
variant: "destructive",
});
return;
}
try {
console.log('Attempting to start camera...');
// Afficher toast de démarrage
toast({
title: "Démarrage de la caméra",
description: "Préparation de la caméra en cours...",
});
// Démarrer la caméra simple
await startCamera(photoType);
console.log('Simple camera started successfully');
} catch (error) {
console.error('Camera start failed:', error);
toast({
title: "Erreur d'accès à la caméra",
description: error instanceof Error ? error.message : "Impossible d'accéder à la caméra",
variant: "destructive",
});
}
};
const handleCapturePhoto = async () => {
if (!currentPhotoType) return;
try {
console.log('Attempting to capture photo...');
const photoData = await capturePhoto();
console.log('Photo captured successfully, data length:', photoData.length);
if (currentPhotoType === 'recto') {
form.setValue('photoRecto', photoData);
} else if (currentPhotoType === 'verso') {
form.setValue('photoVerso', photoData);
} else if (currentPhotoType === 'ticket') {
form.setValue('photoTicket', photoData);
}
toast({
title: "Photo capturée",
description: `Photo ${currentPhotoType} enregistrée avec succès`,
variant: "success",
});
stopCamera();
} catch (error) {
console.error('Photo capture failed:', error);
toast({
title: "Erreur de capture",
description: error instanceof Error ? error.message : "Impossible de capturer la photo",
variant: "destructive",
});
}
}; };
const handleRemovePhoto = (photoType: PhotoType) => { const handleRemovePhoto = (photoType: PhotoType) => {
@@ -188,7 +265,7 @@ export default function NewSaleFormMulti() {
canvasRef={canvasRef} canvasRef={canvasRef}
isCapturing={isCapturing} isCapturing={isCapturing}
onClose={stopCamera} onClose={stopCamera}
onCapture={capturePhoto} onCapture={handleCapturePhoto}
/> />
<Form {...form}> <Form {...form}>
+45 -7
View File
@@ -19,14 +19,49 @@ export function useSimpleCamera() {
stream.getTracks().forEach(track => track.stop()); stream.getTracks().forEach(track => track.stop());
} }
// Demander l'accès à la caméra // Vérifier la disponibilité des médias
const mediaStream = await navigator.mediaDevices.getUserMedia({ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
video: { throw new Error('Votre navigateur ne supporte pas l\'accès à la caméra. Utilisez un navigateur moderne comme Chrome, Firefox ou Safari.');
width: { ideal: 1280 }, }
height: { ideal: 720 },
facingMode: 'environment' let mediaStream: MediaStream;
try {
// Essayer d'abord avec des contraintes avancées
mediaStream = await navigator.mediaDevices.getUserMedia({
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
facingMode: 'environment'
}
});
} catch (constraintError) {
console.warn('Failed with advanced constraints, trying basic video:', constraintError);
try {
// Fallback avec des contraintes basiques
mediaStream = await navigator.mediaDevices.getUserMedia({
video: true
});
} catch (basicError) {
console.error('Basic camera access failed:', basicError);
// Gestion des erreurs spécifiques
if (basicError instanceof Error) {
if (basicError.name === 'NotAllowedError') {
throw new Error('Permission d\'accès à la caméra refusée. Veuillez autoriser l\'accès dans votre navigateur et actualiser la page.');
} else if (basicError.name === 'NotFoundError') {
throw new Error('Aucune caméra trouvée sur cet appareil. Veuillez connecter une caméra ou utiliser l\'option d\'importation de fichier.');
} else if (basicError.name === 'NotReadableError') {
throw new Error('Caméra déjà utilisée par une autre application. Fermez les autres applications utilisant la caméra.');
} else if (basicError.name === 'OverconstrainedError') {
throw new Error('Contraintes de caméra non supportées par votre appareil.');
}
}
throw new Error('Erreur d\'accès à la caméra. Utilisez l\'option d\'importation de fichier comme alternative.');
} }
}); }
console.log('Media stream obtained:', mediaStream); console.log('Media stream obtained:', mediaStream);
setStream(mediaStream); setStream(mediaStream);
@@ -55,6 +90,9 @@ export function useSimpleCamera() {
} catch (error) { } catch (error) {
console.error('Camera start failed:', error); console.error('Camera start failed:', error);
// Nettoyer l'état en cas d'erreur
setIsOpen(false);
setCurrentPhotoType(null);
throw error; throw error;
} }
}, [stream]); }, [stream]);