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

View File

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

View File

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

View File

@@ -19,6 +19,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
import { submitOperatorCreation, submitOperatorUpdate } from '@/lib/entitySubmissionHelpers';
import { useAuth } from '@/hooks/useAuth';
import { toast } from 'sonner';
import { handleError } from '@/lib/errorHandler';
import { useNavigate } from 'react-router-dom';
import type { UploadedImage } from '@/types/company';
@@ -113,9 +114,11 @@ export function OperatorForm({ onSubmit, onCancel, initialData }: OperatorFormPr
toast.success('Operator submitted for review');
onCancel();
}
} catch (error) {
console.error('Submission error:', error);
toast.error(error instanceof Error ? error.message : 'Failed to submit operator');
} catch (error: unknown) {
handleError(error, {
action: initialData?.id ? 'Update Operator' : 'Create Operator',
metadata: { companyName: data.name }
});
} finally {
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 { SlugField } from '@/components/ui/slug-field';
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 { toDateOnly } from '@/lib/dateUtils';
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 new park has been created successfully."
});
} catch (error) {
const errorMsg = getErrorMessage(error);
toast({
title: "Error",
description: errorMsg,
variant: "destructive"
} catch (error: unknown) {
handleError(error, {
action: isEditing ? 'Update Park' : 'Create Park',
userId: user?.id,
metadata: {
parkName: data.name,
hasLocation: !!data.location_id,
hasNewOperator: !!tempNewOperator,
hasNewOwner: !!tempNewPropertyOwner
}
});
} finally {
setSubmitting(false);

View File

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

View File

@@ -20,7 +20,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } f
import { Combobox } from '@/components/ui/combobox';
import { SlugField } from '@/components/ui/slug-field';
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 { toDateOnly } from '@/lib/dateUtils';
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 submitted for review"
});
} catch (error) {
const errorMsg = getErrorMessage(error);
toast({
title: "Error",
description: errorMsg,
variant: "destructive"
} catch (error: unknown) {
handleError(error, {
action: isEditing ? 'Update Ride' : 'Create Ride',
metadata: {
rideName: data.name,
hasNewManufacturer: !!tempNewManufacturer,
hasNewModel: !!tempNewRideModel
}
});
} finally {
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 { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler';
import { handleError } from '@/lib/errorHandler';
import { TurnstileCaptcha } from './TurnstileCaptcha';
import { notificationService } from '@/lib/notificationService';
import { useCaptchaBypass } from '@/hooks/useCaptchaBypass';
@@ -121,12 +121,15 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
await new Promise(resolve => setTimeout(resolve, 100));
onOpenChange(false);
} catch (error) {
} catch (error: unknown) {
setSignInCaptchaKey(prev => prev + 1);
toast({
variant: "destructive",
title: "Sign in failed",
description: getErrorMessage(error)
handleError(error, {
action: 'Sign In',
metadata: {
method: 'password',
hasCaptcha: !!tokenToUse
// ⚠️ NEVER log: email, password, tokens
}
});
} finally {
setLoading(false);
@@ -249,12 +252,15 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
description: "Please check your email to verify your account."
});
onOpenChange(false);
} catch (error) {
} catch (error: unknown) {
setCaptchaKey(prev => prev + 1);
toast({
variant: "destructive",
title: "Sign up failed",
description: getErrorMessage(error)
handleError(error, {
action: 'Sign Up',
metadata: {
hasCaptcha: !!tokenToUse,
hasUsername: !!formData.username
// ⚠️ NEVER log: email, password, username
}
});
} finally {
setLoading(false);
@@ -288,11 +294,13 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
description: "Check your email for a sign-in link."
});
onOpenChange(false);
} catch (error) {
toast({
variant: "destructive",
title: "Failed to send magic link",
description: getErrorMessage(error)
} catch (error: unknown) {
handleError(error, {
action: 'Send Magic Link',
metadata: {
method: 'magic_link'
// ⚠️ NEVER log: email, link
}
});
} finally {
setMagicLinkLoading(false);
@@ -312,11 +320,13 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
}
});
if (error) throw error;
} catch (error) {
toast({
variant: "destructive",
title: "Social sign in failed",
description: getErrorMessage(error)
} catch (error: unknown) {
handleError(error, {
action: 'Social Sign In',
metadata: {
provider,
method: 'oauth'
}
});
}
};

View File

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

View File

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