diff --git a/src/components/admin/MarkdownEditor.tsx b/src/components/admin/MarkdownEditor.tsx index 682f6681..11ee860d 100644 --- a/src/components/admin/MarkdownEditor.tsx +++ b/src/components/admin/MarkdownEditor.tsx @@ -35,6 +35,8 @@ import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils'; import { useAutoSave } from '@/hooks/useAutoSave'; import { CheckCircle2, Loader2, AlertCircle } from 'lucide-react'; import { cn } from '@/lib/utils'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; interface MarkdownEditorProps { value: string; @@ -155,7 +157,7 @@ export function MarkdownEditor({ return imageUrl; } catch (error: unknown) { - console.error('Image upload failed:', error); + logger.error('Image upload failed', { error: getErrorMessage(error) }); throw new Error(error instanceof Error ? error.message : 'Failed to upload image'); } } diff --git a/src/components/admin/SystemActivityLog.tsx b/src/components/admin/SystemActivityLog.tsx index 000c0b74..5b017509 100644 --- a/src/components/admin/SystemActivityLog.tsx +++ b/src/components/admin/SystemActivityLog.tsx @@ -49,6 +49,8 @@ import { ReviewLifecycleDetails, SubmissionWorkflowDetails } from '@/lib/systemActivityService'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; export interface SystemActivityLogRef { refresh: () => Promise; @@ -192,7 +194,7 @@ export const SystemActivityLog = forwardRef { - console.error('Failed to register Novu subscriber:', err); + logger.error('Failed to register Novu subscriber', { error: getErrorMessage(err) }); }); } diff --git a/src/components/auth/MFARemovalDialog.tsx b/src/components/auth/MFARemovalDialog.tsx index 670b096b..3e12089a 100644 --- a/src/components/auth/MFARemovalDialog.tsx +++ b/src/components/auth/MFARemovalDialog.tsx @@ -1,8 +1,7 @@ import { useState, useEffect } from 'react'; import { supabase } from '@/integrations/supabase/client'; import { invokeWithTracking } from '@/lib/edgeFunctionTracking'; -import { toast } from 'sonner'; -import { getSessionAAL } from '@/types/supabase-session'; +import { useToast } from '@/hooks/use-toast'; import { getErrorMessage } from '@/lib/errorHandler'; import { useRequireMFA } from '@/hooks/useRequireMFA'; import { @@ -30,6 +29,7 @@ interface MFARemovalDialogProps { export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MFARemovalDialogProps) { const { requiresMFA } = useRequireMFA(); + const { toast } = useToast(); const [step, setStep] = useState<'password' | 'totp' | 'confirm'>('password'); const [password, setPassword] = useState(''); const [totpCode, setTotpCode] = useState(''); @@ -43,7 +43,11 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF const currentAal = getSessionAAL(session); if (currentAal !== 'aal2') { - toast.error('Please verify your identity with MFA before making security changes'); + toast({ + title: 'MFA Required', + description: 'Please verify your identity with MFA before making security changes', + variant: 'destructive' + }); onOpenChange(false); } }; @@ -62,7 +66,11 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF const handlePasswordVerification = async () => { if (!password.trim()) { - toast.error('Please enter your password'); + toast({ + title: 'Password Required', + description: 'Please enter your password', + variant: 'destructive' + }); return; } @@ -80,10 +88,12 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF if (error) throw error; - toast.success('Password verified'); + toast({ + title: 'Password Verified', + description: 'Password verified successfully' + }); setStep('totp'); } catch (error: unknown) { - console.error('Password verification failed:', error); toast.error(getErrorMessage(error)); } finally { setLoading(false); @@ -92,7 +102,11 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF const handleTOTPVerification = async () => { if (!totpCode.trim() || totpCode.length !== 6) { - toast.error('Please enter a valid 6-digit code'); + toast({ + title: 'Invalid Code', + description: 'Please enter a valid 6-digit code', + variant: 'destructive' + }); return; } @@ -122,10 +136,12 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF throw new Error('Session must be at AAL2 to remove MFA'); } - toast.success('TOTP code verified'); + toast({ + title: 'Code Verified', + description: 'TOTP code verified successfully' + }); setStep('confirm'); } catch (error: unknown) { - console.error('TOTP verification failed:', error); toast.error(getErrorMessage(error)); } finally { setLoading(false); @@ -135,7 +151,11 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF const handleMFARemoval = async () => { // Phase 2: Check if user's role requires MFA if (requiresMFA) { - toast.error('Your role requires two-factor authentication and it cannot be disabled'); + toast({ + title: 'MFA Required', + description: 'Your role requires two-factor authentication and it cannot be disabled', + variant: 'destructive' + }); handleClose(); return; } @@ -152,11 +172,13 @@ export function MFARemovalDialog({ open, onOpenChange, factorId, onSuccess }: MF if (error) throw error; if (data?.error) throw new Error(data.error); - toast.success('Two-factor authentication has been disabled'); + toast({ + title: 'MFA Disabled', + description: 'Two-factor authentication has been disabled' + }); handleClose(); onSuccess(); } catch (error: unknown) { - console.error('MFA removal failed:', error); toast.error(getErrorMessage(error)); } finally { setLoading(false); diff --git a/src/components/homepage/ContentTabs.tsx b/src/components/homepage/ContentTabs.tsx index 427e85ff..b8ec5b9a 100644 --- a/src/components/homepage/ContentTabs.tsx +++ b/src/components/homepage/ContentTabs.tsx @@ -6,6 +6,8 @@ import { RecentChangeCard } from './RecentChangeCard'; import { Badge } from '@/components/ui/badge'; import { Park, Ride, ActivityEntry } from '@/types/database'; import { supabase } from '@/integrations/supabase/client'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; export function ContentTabs() { const [trendingParks, setTrendingParks] = useState([]); @@ -92,7 +94,7 @@ export function ContentTabs() { setRecentChanges(processedChanges); setRecentlyOpened(combinedOpened); } catch (error: unknown) { - console.error('Error fetching content:', error); + logger.error('Failed to fetch content', { error: getErrorMessage(error) }); } finally { setLoading(false); } diff --git a/src/components/homepage/FeaturedParks.tsx b/src/components/homepage/FeaturedParks.tsx index 5444c99a..57d0e423 100644 --- a/src/components/homepage/FeaturedParks.tsx +++ b/src/components/homepage/FeaturedParks.tsx @@ -5,6 +5,8 @@ import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Park } from '@/types/database'; import { supabase } from '@/integrations/supabase/client'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; export function FeaturedParks() { const [topRatedParks, setTopRatedParks] = useState([]); @@ -42,7 +44,7 @@ export function FeaturedParks() { setTopRatedParks(topRated || []); setMostRidesParks(mostRides || []); } catch (error: unknown) { - console.error('Error fetching featured parks:', error); + logger.error('Failed to fetch featured parks', { error: getErrorMessage(error) }); } finally { setLoading(false); } diff --git a/src/components/moderation/EntityEditPreview.tsx b/src/components/moderation/EntityEditPreview.tsx index f6e0b79e..bad0682a 100644 --- a/src/components/moderation/EntityEditPreview.tsx +++ b/src/components/moderation/EntityEditPreview.tsx @@ -82,10 +82,7 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti .eq('submission_id', submissionId) .order('order_index', { ascending: true }); - if (error) { - console.error('EntityEditPreview.fetchSubmissionItems: Failed to fetch submission items:', error); - throw error; - } + if (error) throw error; if (items && items.length > 0) { const firstItem = items[0]; diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index ea853b03..9d2cf566 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -4,6 +4,7 @@ import { TooltipProvider } from '@/components/ui/tooltip'; import { useToast } from '@/hooks/use-toast'; import { useUserRole } from '@/hooks/useUserRole'; import { useAuth } from '@/hooks/useAuth'; +import { getErrorMessage } from '@/lib/errorHandler'; import { PhotoModal } from './PhotoModal'; import { SubmissionReviewManager } from './SubmissionReviewManager'; import { ItemEditDialog } from './ItemEditDialog'; @@ -110,10 +111,9 @@ export const ModerationQueue = forwardRef 0); } catch (err) { - console.error('Error fetching submission items:', err); + logger.error('Failed to fetch submission items', { error: getErrorMessage(err) }); setError('Failed to load submission details'); } finally { setLoading(false); diff --git a/src/components/moderation/SubmissionReviewManager.tsx b/src/components/moderation/SubmissionReviewManager.tsx index 8f621c73..d0890016 100644 --- a/src/components/moderation/SubmissionReviewManager.tsx +++ b/src/components/moderation/SubmissionReviewManager.tsx @@ -35,6 +35,7 @@ import { ItemEditDialog } from './ItemEditDialog'; import { ValidationBlockerDialog } from './ValidationBlockerDialog'; import { WarningConfirmDialog } from './WarningConfirmDialog'; import { validateMultipleItems, ValidationResult } from '@/lib/entityValidationSchemas'; +import { logger } from '@/lib/logger'; interface SubmissionReviewManagerProps { submissionId: string; @@ -417,7 +418,7 @@ export function SubmissionReviewManager({ ); if (error) { - console.error('Edge function error:', error); + logger.error('Edge function failed', { error: getErrorMessage(error) }); // Fallback to direct database update if email fails await escalateSubmission(submissionId, reason, user.id); toast({ diff --git a/src/components/moderation/UserRoleManager.tsx b/src/components/moderation/UserRoleManager.tsx index db35339b..a2da0684 100644 --- a/src/components/moderation/UserRoleManager.tsx +++ b/src/components/moderation/UserRoleManager.tsx @@ -9,7 +9,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { supabase } from '@/integrations/supabase/client'; import { useAuth } from '@/hooks/useAuth'; import { useUserRole } from '@/hooks/useUserRole'; -import { handleError, handleSuccess } from '@/lib/errorHandler'; +import { handleError, handleSuccess, getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; // Type-safe role definitions const VALID_ROLES = ['admin', 'moderator', 'user'] as const; @@ -122,7 +123,7 @@ export function UserRoleManager() { const filteredResults = (data || []).filter(profile => !existingUserIds.includes(profile.user_id)); setSearchResults(filteredResults); } catch (error: unknown) { - console.error('Error searching users:', error); + logger.error('User search failed', { error: getErrorMessage(error) }); } }; useEffect(() => { diff --git a/src/components/parks/ParkGrid.tsx b/src/components/parks/ParkGrid.tsx index 45723f69..bdeb8a9f 100644 --- a/src/components/parks/ParkGrid.tsx +++ b/src/components/parks/ParkGrid.tsx @@ -8,6 +8,8 @@ import { Sheet, SheetContent, SheetTrigger, SheetHeader, SheetTitle } from '@/co import { ParkCard } from './ParkCard'; import { Park } from '@/types/database'; import { supabase } from '@/integrations/supabase/client'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; export function ParkGrid() { const [parks, setParks] = useState([]); @@ -41,7 +43,7 @@ export function ParkGrid() { if (error) throw error; setParks(data || []); } catch (error: unknown) { - console.error('Error fetching parks:', error); + logger.error('Failed to fetch featured parks', { error: getErrorMessage(error) }); } finally { setLoading(false); } diff --git a/src/components/profile/AddRideCreditDialog.tsx b/src/components/profile/AddRideCreditDialog.tsx index e9f536a2..cc464a4a 100644 --- a/src/components/profile/AddRideCreditDialog.tsx +++ b/src/components/profile/AddRideCreditDialog.tsx @@ -69,7 +69,6 @@ export function AddRideCreditDialog({ userId, open, onOpenChange, onSuccess }: A onSuccess(data.id); // Pass the new ID onOpenChange(false); } catch (error: unknown) { - console.error('Error adding credit:', error); toast.error(getErrorMessage(error)); } finally { setSubmitting(false); diff --git a/src/components/profile/RideCreditCard.tsx b/src/components/profile/RideCreditCard.tsx index 0ce697c2..b3d5e7d1 100644 --- a/src/components/profile/RideCreditCard.tsx +++ b/src/components/profile/RideCreditCard.tsx @@ -69,7 +69,6 @@ export function RideCreditCard({ credit, position, maxPosition, viewMode, isEdit // Optimistic update - pass specific changes onUpdate(credit.id, { ride_count: editCount }); } catch (error: unknown) { - console.error('Error updating count:', error); toast.error(getErrorMessage(error)); } finally { setUpdating(false); @@ -92,7 +91,6 @@ export function RideCreditCard({ credit, position, maxPosition, viewMode, isEdit toast.success('Ride count increased'); } catch (error: unknown) { - console.error('Error incrementing count:', error); toast.error(getErrorMessage(error)); // Rollback on error onUpdate(credit.id, { ride_count: credit.ride_count }); @@ -112,7 +110,6 @@ export function RideCreditCard({ credit, position, maxPosition, viewMode, isEdit await onReorder(credit.id, editPosition); toast.success('Position updated'); } catch (error: unknown) { - console.error('Error changing position:', error); toast.error(getErrorMessage(error)); setEditPosition(position); } diff --git a/src/components/profile/UserBlockButton.tsx b/src/components/profile/UserBlockButton.tsx index 047e3c53..52449d6f 100644 --- a/src/components/profile/UserBlockButton.tsx +++ b/src/components/profile/UserBlockButton.tsx @@ -44,11 +44,9 @@ export function UserBlockButton({ targetUserId, targetUsername, variant = 'outli setReason(''); } catch (error: unknown) { - const errorMsg = getErrorMessage(error); - console.error('Error blocking user:', errorMsg); toast({ title: 'Error', - description: 'Failed to block user', + description: getErrorMessage(error), variant: 'destructive' }); } finally { diff --git a/src/components/profile/UserReviewsList.tsx b/src/components/profile/UserReviewsList.tsx index 651955de..0f0d4ddd 100644 --- a/src/components/profile/UserReviewsList.tsx +++ b/src/components/profile/UserReviewsList.tsx @@ -94,7 +94,6 @@ export function UserReviewsList({ userId, reviewCount }: UserReviewsListProps) { if (error) throw error; setReviews(data || []); } catch (error: unknown) { - console.error('Error fetching reviews:', error); toast.error(getErrorMessage(error)); } finally { setLoading(false); diff --git a/src/components/reviews/ReviewForm.tsx b/src/components/reviews/ReviewForm.tsx index 55c3f8dd..14e291b1 100644 --- a/src/components/reviews/ReviewForm.tsx +++ b/src/components/reviews/ReviewForm.tsx @@ -15,6 +15,8 @@ import { toast } from '@/hooks/use-toast'; import { PhotoUpload } from '@/components/upload/PhotoUpload'; import { StarRating } from './StarRating'; import { toDateOnly } from '@/lib/dateUtils'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; const reviewSchema = z.object({ rating: z.number().min(0.5).max(5).multipleOf(0.5), title: z.string().optional(), @@ -107,7 +109,7 @@ export function ReviewForm({ .insert(photoRecords); if (photosError) { - console.error('Error inserting review photos:', photosError); + logger.error('Failed to insert review photos', { error: getErrorMessage(photosError) }); // Don't throw - review is already created } } @@ -121,10 +123,9 @@ export function ReviewForm({ setPhotos([]); onReviewSubmitted(); } catch (error: unknown) { - console.error('Error submitting review:', error); toast({ title: "Error", - description: "Failed to submit review. Please try again.", + description: getErrorMessage(error), variant: "destructive" }); } finally { diff --git a/src/components/reviews/ReviewsList.tsx b/src/components/reviews/ReviewsList.tsx index 7f013f68..3393943d 100644 --- a/src/components/reviews/ReviewsList.tsx +++ b/src/components/reviews/ReviewsList.tsx @@ -6,6 +6,8 @@ import { Star, ThumbsUp, Calendar, MapPin } from 'lucide-react'; import { supabase } from '@/integrations/supabase/client'; import { ReportButton } from '@/components/moderation/ReportButton'; import { StarRating } from './StarRating'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; interface ReviewWithProfile { id: string; @@ -63,7 +65,7 @@ export function ReviewsList({ entityType, entityId, entityName }: ReviewsListPro const { data } = await query; setReviews((data || []) as ReviewWithProfile[]); } catch (error: unknown) { - console.error('Error fetching reviews:', error); + logger.error('Failed to fetch reviews', { error: getErrorMessage(error), entityType, entityId }); } finally { setLoading(false); } diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index 992309bb..453ed196 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -6,6 +6,8 @@ import { MapPin, Star, Search as SearchIcon, Castle, FerrisWheel, Waves, Theater import { Park, Ride, Company } from '@/types/database'; import { supabase } from '@/integrations/supabase/client'; import { useNavigate } from 'react-router-dom'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; interface SearchResultsProps { query: string; @@ -64,7 +66,7 @@ export function SearchResults({ query, onClose }: SearchResultsProps) { setResults(allResults); } catch (error: unknown) { - console.error('Search error:', error); + logger.error('Search failed', { error: getErrorMessage(error), query }); } finally { setLoading(false); } diff --git a/src/components/settings/AccountProfileTab.tsx b/src/components/settings/AccountProfileTab.tsx index 0473bdf5..30a028b6 100644 --- a/src/components/settings/AccountProfileTab.tsx +++ b/src/components/settings/AccountProfileTab.tsx @@ -168,7 +168,6 @@ export function AccountProfileTab() { const { data: { session }, error: sessionError } = await supabase.auth.getSession(); if (sessionError || !session?.access_token) { - console.error('Session error:', sessionError); throw new Error('Your session has expired. Please refresh the page and try again.'); } @@ -180,7 +179,6 @@ export function AccountProfileTab() { ); if (error) { - console.error('Edge function error:', error); throw error; } diff --git a/src/components/upload/EntityMultiImageUploader.tsx b/src/components/upload/EntityMultiImageUploader.tsx index 2d761009..120b8a75 100644 --- a/src/components/upload/EntityMultiImageUploader.tsx +++ b/src/components/upload/EntityMultiImageUploader.tsx @@ -13,6 +13,8 @@ import { DragDropZone } from './DragDropZone'; import { supabase } from '@/integrations/supabase/client'; import { toast } from '@/hooks/use-toast'; import { Skeleton } from '@/components/ui/skeleton'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; export interface UploadedImage { url: string; @@ -68,7 +70,7 @@ export function EntityMultiImageUploader({ try { URL.revokeObjectURL(image.url); } catch (error: unknown) { - console.error('Error revoking object URL:', error); + logger.error('Failed to revoke object URL', { error: getErrorMessage(error) }); } } }); @@ -106,10 +108,9 @@ export function EntityMultiImageUploader({ card_assignment: cardIndex >= 0 ? cardIndex : null, }); } catch (error: unknown) { - console.error('Failed to load entity photos:', error); toast({ title: 'Error', - description: 'Failed to load existing photos', + description: getErrorMessage(error), variant: 'destructive', }); } finally { diff --git a/src/components/upload/EntityPhotoGallery.tsx b/src/components/upload/EntityPhotoGallery.tsx index 8a5a47ef..6bf8ab98 100644 --- a/src/components/upload/EntityPhotoGallery.tsx +++ b/src/components/upload/EntityPhotoGallery.tsx @@ -17,6 +17,8 @@ import { PhotoModal } from '@/components/moderation/PhotoModal'; import { supabase } from '@/integrations/supabase/client'; import { EntityPhotoGalleryProps } from '@/types/submissions'; import { useUserRole } from '@/hooks/useUserRole'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; interface Photo { id: string; @@ -72,7 +74,7 @@ export function EntityPhotoGallery({ setPhotos(mappedPhotos); } catch (error: unknown) { - console.error('📷 [FETCH PHOTOS] Error:', error); + logger.error('Failed to fetch photos', { error: getErrorMessage(error), entityId, entityType }); } finally { setLoading(false); } diff --git a/src/components/upload/PhotoManagementDialog.tsx b/src/components/upload/PhotoManagementDialog.tsx index 13eab5cd..7b3d38a2 100644 --- a/src/components/upload/PhotoManagementDialog.tsx +++ b/src/components/upload/PhotoManagementDialog.tsx @@ -25,6 +25,8 @@ import { Textarea } from '@/components/ui/textarea'; import { useToast } from '@/hooks/use-toast'; import { Trash2, Pencil } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; +import { getErrorMessage } from '@/lib/errorHandler'; +import { logger } from '@/lib/logger'; interface Photo { id: string; @@ -78,10 +80,9 @@ export function PhotoManagementDialog({ if (error) throw error; setPhotos(data || []); } catch (error: unknown) { - console.error('Error fetching photos:', error); toast({ title: 'Error', - description: 'Failed to load photos', + description: getErrorMessage(error), variant: 'destructive', }); } finally { @@ -123,7 +124,7 @@ export function PhotoManagementDialog({ if (data?.name) entityName = data.name; } } catch (err) { - console.error('Error fetching entity name:', err); + logger.error('Failed to fetch entity name', { error: getErrorMessage(err), entityType, entityId }); } // Create content submission @@ -173,10 +174,9 @@ export function PhotoManagementDialog({ setDeleteReason(''); onOpenChange(false); } catch (error: unknown) { - console.error('Error requesting photo deletion:', error); toast({ title: 'Error', - description: 'Failed to submit deletion request', + description: getErrorMessage(error), variant: 'destructive', }); } @@ -238,10 +238,9 @@ export function PhotoManagementDialog({ }); onOpenChange(false); } catch (error: unknown) { - console.error('Error requesting photo edit:', error); toast({ title: 'Error', - description: 'Failed to submit edit request', + description: getErrorMessage(error), variant: 'destructive', }); } diff --git a/src/components/upload/PhotoUpload.tsx b/src/components/upload/PhotoUpload.tsx index b04893c3..a44edd63 100644 --- a/src/components/upload/PhotoUpload.tsx +++ b/src/components/upload/PhotoUpload.tsx @@ -72,7 +72,7 @@ export function PhotoUpload({ try { URL.revokeObjectURL(url); } catch (error: unknown) { - console.error('Error revoking object URL:', error); + logger.error('Failed to revoke object URL', { error: getErrorMessage(error) }); } }); objectUrlsRef.current.clear(); @@ -91,7 +91,7 @@ export function PhotoUpload({ URL.revokeObjectURL(url); objectUrlsRef.current.delete(url); } catch (error: unknown) { - console.error('Error revoking object URL:', error); + logger.error('Failed to revoke object URL', { error: getErrorMessage(error) }); } } }; @@ -129,7 +129,6 @@ export function PhotoUpload({ ); if (uploadError) { - console.error('Upload URL error:', uploadError); revokeObjectUrl(previewUrl); throw new Error(uploadError.message); } @@ -196,7 +195,7 @@ export function PhotoUpload({ } } } catch (error: unknown) { - console.error('Status poll error:', error); + logger.error('Status poll error', { error: getErrorMessage(error) }); } await new Promise(resolve => setTimeout(resolve, 500)); @@ -340,7 +339,7 @@ export function PhotoUpload({ alt="Avatar" className="w-24 h-24 rounded-full object-cover border-2 border-border" onError={(e) => { - console.error('Failed to load avatar image:', uploadedImages[0].thumbnailUrl); + logger.warn('Failed to load avatar image'); e.currentTarget.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSIjZjNmNGY2Ii8+CjxwYXRoIGQ9Im0xNSAxMi0zLTMtMy4wMDEgM0w2IDlsNi02aDZ2NloiIGZpbGw9IiM5Y2EzYWYiLz4KPC9zdmc+'; }} /> @@ -488,7 +487,7 @@ export function PhotoUpload({ alt={image.filename} className="w-full aspect-square object-cover rounded-lg border" onError={(e) => { - console.error('Failed to load image:', image.thumbnailUrl); + logger.warn('Failed to load thumbnail image'); e.currentTarget.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSIjZjNmNGY2Ii8+CjxwYXRoIGQ9Im0xNSAxMi0zLTMtMy4wMDEgM0w2IDlsNi02aDZ2NloiIGZpbGw9IiM5Y2EzYWYiLz4KPC9zdmc+'; }} />