Refactor: Execute remaining phases

This commit is contained in:
gpt-engineer-app[bot]
2025-10-20 13:30:02 +00:00
parent 6f1baef8c0
commit 368b97da04
10 changed files with 167 additions and 105 deletions

View File

@@ -19,6 +19,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
import { submitDesignerCreation, submitDesignerUpdate } from '@/lib/entitySubmissionHelpers'; import { submitDesignerCreation, submitDesignerUpdate } from '@/lib/entitySubmissionHelpers';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { handleError } from '@/lib/errorHandler';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import type { UploadedImage } from '@/types/company'; import type { UploadedImage } from '@/types/company';
@@ -113,9 +114,11 @@ export function DesignerForm({ onSubmit, onCancel, initialData }: DesignerFormPr
toast.success('Designer submitted for review'); toast.success('Designer submitted for review');
onCancel(); onCancel();
} }
} catch (error) { } catch (error: unknown) {
console.error('Submission error:', error); handleError(error, {
toast.error(error instanceof Error ? error.message : 'Failed to submit designer'); action: initialData?.id ? 'Update Designer' : 'Create Designer',
metadata: { companyName: data.name }
});
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }

View File

@@ -122,10 +122,9 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
setResults(data); setResults(data);
setShowResults(true); setShowResults(true);
setSearchError(null); setSearchError(null);
} catch (error) { } catch (error: unknown) {
const errorMsg = error instanceof Error ? error.message : 'Failed to search locations. Please check your connection.'; logger.error('Location search failed', { query: searchQuery });
console.error('Error searching locations:', error); setSearchError('Failed to search locations. Please check your connection.');
setSearchError(errorMsg);
setResults([]); setResults([]);
setShowResults(false); setShowResults(false);
} finally { } finally {

View File

@@ -19,6 +19,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
import { submitManufacturerCreation, submitManufacturerUpdate } from '@/lib/entitySubmissionHelpers'; import { submitManufacturerCreation, submitManufacturerUpdate } from '@/lib/entitySubmissionHelpers';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { handleError } from '@/lib/errorHandler';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { toDateOnly } from '@/lib/dateUtils'; import { toDateOnly } from '@/lib/dateUtils';
import type { UploadedImage } from '@/types/company'; import type { UploadedImage } from '@/types/company';
@@ -116,9 +117,11 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur
toast.success('Manufacturer submitted for review'); toast.success('Manufacturer submitted for review');
onCancel(); onCancel();
} }
} catch (error) { } catch (error: unknown) {
console.error('Submission error:', error); handleError(error, {
toast.error(error instanceof Error ? error.message : 'Failed to submit manufacturer'); action: initialData?.id ? 'Update Manufacturer' : 'Create Manufacturer',
metadata: { companyName: data.name }
});
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }

View File

@@ -19,6 +19,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
import { submitOperatorCreation, submitOperatorUpdate } from '@/lib/entitySubmissionHelpers'; import { submitOperatorCreation, submitOperatorUpdate } from '@/lib/entitySubmissionHelpers';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { handleError } from '@/lib/errorHandler';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import type { UploadedImage } from '@/types/company'; import type { UploadedImage } from '@/types/company';
@@ -113,9 +114,11 @@ export function OperatorForm({ onSubmit, onCancel, initialData }: OperatorFormPr
toast.success('Operator submitted for review'); toast.success('Operator submitted for review');
onCancel(); onCancel();
} }
} catch (error) { } catch (error: unknown) {
console.error('Submission error:', error); handleError(error, {
toast.error(error instanceof Error ? error.message : 'Failed to submit operator'); action: initialData?.id ? 'Update Operator' : 'Create Operator',
metadata: { companyName: data.name }
});
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }

View File

@@ -15,7 +15,7 @@ import { DatePicker } from '@/components/ui/date-picker';
import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input'; import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input';
import { SlugField } from '@/components/ui/slug-field'; import { SlugField } from '@/components/ui/slug-field';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler';
import { MapPin, Save, X, Plus } from 'lucide-react'; import { MapPin, Save, X, Plus } from 'lucide-react';
import { toDateOnly } from '@/lib/dateUtils'; import { toDateOnly } from '@/lib/dateUtils';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@@ -193,12 +193,16 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
? "The park information has been updated successfully." ? "The park information has been updated successfully."
: "The new park has been created successfully." : "The new park has been created successfully."
}); });
} catch (error) { } catch (error: unknown) {
const errorMsg = getErrorMessage(error); handleError(error, {
toast({ action: isEditing ? 'Update Park' : 'Create Park',
title: "Error", userId: user?.id,
description: errorMsg, metadata: {
variant: "destructive" parkName: data.name,
hasLocation: !!data.location_id,
hasNewOperator: !!tempNewOperator,
hasNewOwner: !!tempNewPropertyOwner
}
}); });
} finally { } finally {
setSubmitting(false); setSubmitting(false);

View File

@@ -19,6 +19,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
import { submitPropertyOwnerCreation, submitPropertyOwnerUpdate } from '@/lib/entitySubmissionHelpers'; import { submitPropertyOwnerCreation, submitPropertyOwnerUpdate } from '@/lib/entitySubmissionHelpers';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { handleError } from '@/lib/errorHandler';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import type { UploadedImage } from '@/types/company'; import type { UploadedImage } from '@/types/company';
@@ -113,9 +114,11 @@ export function PropertyOwnerForm({ onSubmit, onCancel, initialData }: PropertyO
toast.success('Property owner submitted for review'); toast.success('Property owner submitted for review');
onCancel(); onCancel();
} }
} catch (error) { } catch (error: unknown) {
console.error('Submission error:', error); handleError(error, {
toast.error(error instanceof Error ? error.message : 'Failed to submit property owner'); action: initialData?.id ? 'Update Property Owner' : 'Create Property Owner',
metadata: { companyName: data.name }
});
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }

View File

@@ -20,7 +20,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } f
import { Combobox } from '@/components/ui/combobox'; import { Combobox } from '@/components/ui/combobox';
import { SlugField } from '@/components/ui/slug-field'; import { SlugField } from '@/components/ui/slug-field';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler';
import { Plus, Zap, Save, X } from 'lucide-react'; import { Plus, Zap, Save, X } from 'lucide-react';
import { toDateOnly } from '@/lib/dateUtils'; import { toDateOnly } from '@/lib/dateUtils';
import { useUnitPreferences } from '@/hooks/useUnitPreferences'; import { useUnitPreferences } from '@/hooks/useUnitPreferences';
@@ -264,12 +264,14 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
? "Ride, manufacturer, and model submitted for review" ? "Ride, manufacturer, and model submitted for review"
: "Ride submitted for review" : "Ride submitted for review"
}); });
} catch (error) { } catch (error: unknown) {
const errorMsg = getErrorMessage(error); handleError(error, {
toast({ action: isEditing ? 'Update Ride' : 'Create Ride',
title: "Error", metadata: {
description: errorMsg, rideName: data.name,
variant: "destructive" hasNewManufacturer: !!tempNewManufacturer,
hasNewModel: !!tempNewRideModel
}
}); });
} finally { } finally {
setSubmitting(false); setSubmitting(false);

View File

@@ -8,7 +8,7 @@ import { Separator } from '@/components/ui/separator';
import { Zap, Mail, Lock, User, Eye, EyeOff } from 'lucide-react'; import { Zap, Mail, Lock, User, Eye, EyeOff } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler';
import { TurnstileCaptcha } from './TurnstileCaptcha'; import { TurnstileCaptcha } from './TurnstileCaptcha';
import { notificationService } from '@/lib/notificationService'; import { notificationService } from '@/lib/notificationService';
import { useCaptchaBypass } from '@/hooks/useCaptchaBypass'; import { useCaptchaBypass } from '@/hooks/useCaptchaBypass';
@@ -121,12 +121,15 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
await new Promise(resolve => setTimeout(resolve, 100)); await new Promise(resolve => setTimeout(resolve, 100));
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
setSignInCaptchaKey(prev => prev + 1); setSignInCaptchaKey(prev => prev + 1);
toast({ handleError(error, {
variant: "destructive", action: 'Sign In',
title: "Sign in failed", metadata: {
description: getErrorMessage(error) method: 'password',
hasCaptcha: !!tokenToUse
// ⚠️ NEVER log: email, password, tokens
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -249,12 +252,15 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
description: "Please check your email to verify your account." description: "Please check your email to verify your account."
}); });
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
setCaptchaKey(prev => prev + 1); setCaptchaKey(prev => prev + 1);
toast({ handleError(error, {
variant: "destructive", action: 'Sign Up',
title: "Sign up failed", metadata: {
description: getErrorMessage(error) hasCaptcha: !!tokenToUse,
hasUsername: !!formData.username
// ⚠️ NEVER log: email, password, username
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -288,11 +294,13 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
description: "Check your email for a sign-in link." description: "Check your email for a sign-in link."
}); });
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
toast({ handleError(error, {
variant: "destructive", action: 'Send Magic Link',
title: "Failed to send magic link", metadata: {
description: getErrorMessage(error) method: 'magic_link'
// ⚠️ NEVER log: email, link
}
}); });
} finally { } finally {
setMagicLinkLoading(false); setMagicLinkLoading(false);
@@ -312,11 +320,13 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
} }
}); });
if (error) throw error; if (error) throw error;
} catch (error) { } catch (error: unknown) {
toast({ handleError(error, {
variant: "destructive", action: 'Social Sign In',
title: "Social sign in failed", metadata: {
description: getErrorMessage(error) provider,
method: 'oauth'
}
}); });
} }
}; };

View File

@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler';
import { import {
fetchSubmissionItems, fetchSubmissionItems,
buildDependencyTree, buildDependencyTree,
@@ -108,11 +108,11 @@ export function SubmissionReviewManager({
.filter(item => item.status === 'pending') .filter(item => item.status === 'pending')
.map(item => item.id); .map(item => item.id);
setSelectedItemIds(new Set(pendingIds)); setSelectedItemIds(new Set(pendingIds));
} catch (error) { } catch (error: unknown) {
toast({ handleError(error, {
title: 'Error', action: 'Load Submission Items',
description: getErrorMessage(error), userId: user?.id,
variant: 'destructive', metadata: { submissionId, submissionType }
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -147,11 +147,11 @@ export function SubmissionReviewManager({
// No conflicts, proceed with approval // No conflicts, proceed with approval
handleApprove(); handleApprove();
} }
} catch (error) { } catch (error: unknown) {
toast({ handleError(error, {
title: 'Error', action: 'Check Dependency Conflicts',
description: getErrorMessage(error), userId: user?.id,
variant: 'destructive', metadata: { submissionId, selectedCount: selectedItemIds.size }
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -253,12 +253,16 @@ export function SubmissionReviewManager({
onComplete(); onComplete();
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
console.error('Error approving items:', error); handleError(error, {
toast({ action: 'Approve Submission Items',
title: 'Error', userId: user?.id,
description: getErrorMessage(error), metadata: {
variant: 'destructive', submissionId,
itemCount: selectedItemIds.size,
hasWarnings: userConfirmedWarnings,
hasBlockingErrors
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -308,12 +312,16 @@ export function SubmissionReviewManager({
onComplete(); onComplete();
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
console.error('Error rejecting items:', error); handleError(error, {
toast({ action: 'Reject Submission Items',
title: 'Error', userId: user?.id,
description: getErrorMessage(error), metadata: {
variant: 'destructive', submissionId,
itemCount: selectedItemIds.size,
cascade,
reason: reason.substring(0, 100)
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -361,12 +369,14 @@ export function SubmissionReviewManager({
onComplete(); onComplete();
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
console.error('Error escalating submission:', error); handleError(error, {
toast({ action: 'Escalate Submission',
title: 'Error', userId: user?.id,
description: getErrorMessage(error), metadata: {
variant: 'destructive', submissionId,
reason: reason.substring(0, 100)
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -429,12 +439,15 @@ export function SubmissionReviewManager({
} }
await loadSubmissionItems(); await loadSubmissionItems();
} catch (error) { } catch (error: unknown) {
console.error('Error changing item status:', error); handleError(error, {
toast({ action: `${status === 'approved' ? 'Approve' : 'Reject'} Item`,
title: 'Error', userId: user?.id,
description: getErrorMessage(error), metadata: {
variant: 'destructive', submissionId,
itemId,
status
}
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@@ -557,11 +570,11 @@ export function SubmissionReviewManager({
}); });
onComplete(); onComplete();
onOpenChange(false); onOpenChange(false);
} catch (error) { } catch (error: unknown) {
toast({ handleError(error, {
title: 'Error', action: 'Archive Corrupted Submission',
description: getErrorMessage(error), userId: user?.id,
variant: 'destructive', metadata: { submissionId }
}); });
} }
}} }}

View File

@@ -5,7 +5,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Plus, LayoutGrid, List, GripVertical } from 'lucide-react'; import { Plus, LayoutGrid, List, GripVertical } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client'; import { supabase } from '@/integrations/supabase/client';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { getErrorMessage } from '@/lib/errorHandler'; import { handleError } from '@/lib/errorHandler';
import { AddRideCreditDialog } from './AddRideCreditDialog'; import { AddRideCreditDialog } from './AddRideCreditDialog';
import { RideCreditCard } from './RideCreditCard'; import { RideCreditCard } from './RideCreditCard';
import { SortableRideCreditCard } from './SortableRideCreditCard'; import { SortableRideCreditCard } from './SortableRideCreditCard';
@@ -135,9 +135,12 @@ export function RideCreditsManager({ userId }: RideCreditsManagerProps) {
} }
setCredits(processedData); setCredits(processedData);
} catch (error) { } catch (error: unknown) {
console.error('Error fetching ride credits:', error); handleError(error, {
toast.error(getErrorMessage(error)); action: 'Fetch Ride Credits',
userId,
metadata: { sortBy }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -196,9 +199,12 @@ export function RideCreditsManager({ userId }: RideCreditsManagerProps) {
// Add to existing array // Add to existing array
setCredits(prev => [...prev, newCredit]); setCredits(prev => [...prev, newCredit]);
setIsAddDialogOpen(false); setIsAddDialogOpen(false);
} catch (error) { } catch (error: unknown) {
console.error('Error fetching new credit:', error); handleError(error, {
toast.error(getErrorMessage(error)); action: 'Add Ride Credit',
userId,
metadata: { creditId: newCreditId }
});
} }
}; };
@@ -226,9 +232,12 @@ export function RideCreditsManager({ userId }: RideCreditsManagerProps) {
if (error) throw error; if (error) throw error;
toast.success('Ride credit removed'); toast.success('Ride credit removed');
} catch (error) { } catch (error: unknown) {
console.error('Error deleting credit:', error); handleError(error, {
toast.error(getErrorMessage(error)); action: 'Delete Ride Credit',
userId,
metadata: { creditId }
});
// Rollback on error // Rollback on error
if (deletedCredit) { if (deletedCredit) {
@@ -247,8 +256,12 @@ export function RideCreditsManager({ userId }: RideCreditsManagerProps) {
if (error) throw error; if (error) throw error;
// No refetch - optimistic update is already applied // No refetch - optimistic update is already applied
} catch (error) { } catch (error: unknown) {
console.error('Error reordering credit:', error); handleError(error, {
action: 'Reorder Ride Credit',
userId,
metadata: { creditId, newPosition }
});
throw error; throw error;
} }
}; };
@@ -273,8 +286,17 @@ export function RideCreditsManager({ userId }: RideCreditsManagerProps) {
try { try {
await handleReorder(String(active.id), newIndex + 1); await handleReorder(String(active.id), newIndex + 1);
toast.success('Order updated'); toast.success('Order updated');
} catch (error) { } catch (error: unknown) {
toast.error(getErrorMessage(error)); handleError(error, {
action: 'Drag Reorder Ride Credit',
userId,
metadata: {
activeId: String(active.id),
overId: String(over.id),
oldIndex,
newIndex
}
});
// Rollback to old order // Rollback to old order
setCredits(oldCredits); setCredits(oldCredits);
} }