From e38d9670157d56b4feeb5ebdca962899397fee79 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Sat, 19 Jul 2025 13:07:03 +0000 Subject: [PATCH] Restore camera functionality and update new sales form component Refactors CameraModal.tsx to restore camera functionality, updates NewSaleForm to NewSaleFormMultiProduct in FireworksApp.tsx. Replit-Commit-Author: Agent Replit-Commit-Session-Id: c7151ec8-4e6b-4fcf-b628-65b094ac18fd Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/c7151ec8-4e6b-4fcf-b628-65b094ac18fd/PgD91fN --- client/src/components/CameraModal.tsx | 144 ++++++++++--------------- client/src/components/FireworksApp.tsx | 4 +- 2 files changed, 58 insertions(+), 90 deletions(-) diff --git a/client/src/components/CameraModal.tsx b/client/src/components/CameraModal.tsx index e9b4b1c..d391013 100644 --- a/client/src/components/CameraModal.tsx +++ b/client/src/components/CameraModal.tsx @@ -1,4 +1,4 @@ -import { useState, useRef, useEffect } from 'react'; +import { useEffect } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Camera, X } from 'lucide-react'; @@ -7,108 +7,76 @@ import { PhotoType } from '@/types/sale'; interface CameraModalProps { isOpen: boolean; photoType: PhotoType | null; + videoRef: React.RefObject; + canvasRef: React.RefObject; + isCapturing: boolean; onClose: () => void; - onPhotoTaken: (photoData: string) => void; + onCapture: () => void; } export default function CameraModal({ isOpen, photoType, + videoRef, + canvasRef, + isCapturing, onClose, - onPhotoTaken + onCapture }: CameraModalProps) { - const videoRef = useRef(null); - const canvasRef = useRef(null); - const [stream, setStream] = useState(null); - const [isCapturing, setIsCapturing] = useState(false); - useEffect(() => { - if (isOpen) { - startCamera(); - } else { - stopCamera(); - } - - return () => { - stopCamera(); - }; - }, [isOpen]); - - const startCamera = async () => { - try { - const mediaStream = await navigator.mediaDevices.getUserMedia({ - video: { - facingMode: 'environment', - width: { ideal: 1280 }, - height: { ideal: 720 } + if (isOpen && videoRef.current) { + const video = videoRef.current; + console.log('CameraModal useEffect - video element ready'); + + const handleLoadedMetadata = () => { + console.log('CameraModal: Video metadata loaded, dimensions:', video.videoWidth, 'x', video.videoHeight); + }; + + const handleCanPlay = () => { + console.log('CameraModal: Video can play, readyState:', video.readyState); + }; + + const handleError = (error: Event) => { + console.error('CameraModal: Video error event:', error); + }; + + const handlePlay = () => { + console.log('CameraModal: Video started playing'); + }; + + video.addEventListener('loadedmetadata', handleLoadedMetadata); + video.addEventListener('canplay', handleCanPlay); + video.addEventListener('error', handleError); + video.addEventListener('play', handlePlay); + + // Forcer le play avec gestion d'erreur + const startPlayback = async () => { + try { + await video.play(); + console.log('CameraModal: Video play() successful'); + } catch (playError) { + console.error('CameraModal: Video play() failed:', playError); } - }); - - if (videoRef.current) { - videoRef.current.srcObject = mediaStream; - setStream(mediaStream); - } - } catch (error) { - console.error('Error accessing camera:', error); - // Fallback: try without specific constraints - try { - const mediaStream = await navigator.mediaDevices.getUserMedia({ - video: true - }); - - if (videoRef.current) { - videoRef.current.srcObject = mediaStream; - setStream(mediaStream); - } - } catch (fallbackError) { - console.error('Fallback camera access failed:', fallbackError); - } + }; + + startPlayback(); + + return () => { + video.removeEventListener('loadedmetadata', handleLoadedMetadata); + video.removeEventListener('canplay', handleCanPlay); + video.removeEventListener('error', handleError); + video.removeEventListener('play', handlePlay); + }; } - }; - - const stopCamera = () => { - if (stream) { - stream.getTracks().forEach(track => track.stop()); - setStream(null); - } - }; - - const capturePhoto = () => { - if (!videoRef.current || !canvasRef.current) return; - - setIsCapturing(true); - const video = videoRef.current; - const canvas = canvasRef.current; - const context = canvas.getContext('2d'); - - if (!context) return; - - // Set canvas dimensions to match video - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - - // Draw video frame to canvas - context.drawImage(video, 0, 0, canvas.width, canvas.height); - - // Convert to data URL - const photoData = canvas.toDataURL('image/jpeg', 0.8); - - onPhotoTaken(photoData); - setIsCapturing(false); - }; - - const handleClose = () => { - stopCamera(); - onClose(); - }; + }, [isOpen, videoRef]); return ( - + Capturer photo {photoType} - @@ -131,14 +99,14 @@ export default function CameraModal({
-
diff --git a/client/src/components/FireworksApp.tsx b/client/src/components/FireworksApp.tsx index 349a62a..bfdc37f 100644 --- a/client/src/components/FireworksApp.tsx +++ b/client/src/components/FireworksApp.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Shield, Flame, Plus, History } from 'lucide-react'; -import NewSaleForm from './NewSaleForm'; +import NewSaleFormMultiProduct from './NewSaleFormMultiProduct'; import SalesHistory from './SalesHistory'; import { useAuth } from '@/hooks/useAuth'; import { useStoreContext } from '@/hooks/useStoreContext'; @@ -68,7 +68,7 @@ export default function FireworksApp() { - +