mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:51:14 -05:00
Apply blur validation and toasts to remaining forms
Extend forms with blur-based validation via FormFieldWrapper.validationMode, and replace inline toasts with centralized formToasts. Update ManufacturerForm, DesignerForm, OperatorForm, PropertyOwnerForm, RideModelForm, and related components to use the new toast helper and ensure data-error scroll behavior where applicable.
This commit is contained in:
@@ -16,8 +16,9 @@ import { useUserRole } from '@/hooks/useUserRole';
|
|||||||
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
||||||
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from 'sonner';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { handleError } from '@/lib/errorHandler';
|
import { handleError, getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { formToasts } from '@/lib/formToasts';
|
||||||
import type { UploadedImage } from '@/types/company';
|
import type { UploadedImage } from '@/types/company';
|
||||||
|
|
||||||
// Zod output type (after transformation)
|
// Zod output type (after transformation)
|
||||||
@@ -73,7 +74,7 @@ export function DesignerForm({ onSubmit, onCancel, initialData }: DesignerFormPr
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleSubmit(async (data) => {
|
<form onSubmit={handleSubmit(async (data) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
toast.error('You must be logged in to submit');
|
formToasts.error.generic('You must be logged in to submit');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +94,11 @@ export function DesignerForm({ onSubmit, onCancel, initialData }: DesignerFormPr
|
|||||||
|
|
||||||
await onSubmit(formData);
|
await onSubmit(formData);
|
||||||
|
|
||||||
// Only show success toast and close if not editing through moderation queue
|
// Show success toast
|
||||||
if (!initialData?.id) {
|
if (initialData?.id) {
|
||||||
toast.success('Designer submitted for review');
|
formToasts.success.update('Designer', data.name);
|
||||||
|
} else {
|
||||||
|
formToasts.success.create('Designer', data.name);
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -104,6 +107,9 @@ export function DesignerForm({ onSubmit, onCancel, initialData }: DesignerFormPr
|
|||||||
metadata: { companyName: data.name }
|
metadata: { companyName: data.name }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
formToasts.error.generic(getErrorMessage(error));
|
||||||
|
|
||||||
// Re-throw so parent can handle modal closing
|
// Re-throw so parent can handle modal closing
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
|||||||
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
||||||
import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input';
|
import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-date-input';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from 'sonner';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { handleError } from '@/lib/errorHandler';
|
import { handleError, getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { formToasts } from '@/lib/formToasts';
|
||||||
import { toDateOnly, parseDateOnly, toDateWithPrecision } from '@/lib/dateUtils';
|
import { toDateOnly, parseDateOnly, toDateWithPrecision } from '@/lib/dateUtils';
|
||||||
import type { UploadedImage } from '@/types/company';
|
import type { UploadedImage } from '@/types/company';
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleSubmit(async (data) => {
|
<form onSubmit={handleSubmit(async (data) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
toast.error('You must be logged in to submit');
|
formToasts.error.generic('You must be logged in to submit');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,9 +96,11 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur
|
|||||||
|
|
||||||
await onSubmit(formData);
|
await onSubmit(formData);
|
||||||
|
|
||||||
// Only show success toast and close if not editing through moderation queue
|
// Show success toast
|
||||||
if (!initialData?.id) {
|
if (initialData?.id) {
|
||||||
toast.success('Manufacturer submitted for review');
|
formToasts.success.update('Manufacturer', data.name);
|
||||||
|
} else {
|
||||||
|
formToasts.success.create('Manufacturer', data.name);
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -106,6 +109,9 @@ export function ManufacturerForm({ onSubmit, onCancel, initialData }: Manufactur
|
|||||||
metadata: { companyName: data.name }
|
metadata: { companyName: data.name }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
formToasts.error.generic(getErrorMessage(error));
|
||||||
|
|
||||||
// Re-throw so parent can handle modal closing
|
// Re-throw so parent can handle modal closing
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ import { useUserRole } from '@/hooks/useUserRole';
|
|||||||
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
||||||
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from 'sonner';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { handleError } from '@/lib/errorHandler';
|
import { handleError, getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { formToasts } from '@/lib/formToasts';
|
||||||
import type { UploadedImage } from '@/types/company';
|
import type { UploadedImage } from '@/types/company';
|
||||||
|
|
||||||
// Zod output type (after transformation)
|
// Zod output type (after transformation)
|
||||||
@@ -73,7 +74,7 @@ export function OperatorForm({ onSubmit, onCancel, initialData }: OperatorFormPr
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleSubmit(async (data) => {
|
<form onSubmit={handleSubmit(async (data) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
toast.error('You must be logged in to submit');
|
formToasts.error.generic('You must be logged in to submit');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +94,11 @@ export function OperatorForm({ onSubmit, onCancel, initialData }: OperatorFormPr
|
|||||||
|
|
||||||
await onSubmit(formData);
|
await onSubmit(formData);
|
||||||
|
|
||||||
// Only show success toast and close if not editing through moderation queue
|
// Show success toast
|
||||||
if (!initialData?.id) {
|
if (initialData?.id) {
|
||||||
toast.success('Operator submitted for review');
|
formToasts.success.update('Operator', data.name);
|
||||||
|
} else {
|
||||||
|
formToasts.success.create('Operator', data.name);
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -104,6 +107,9 @@ export function OperatorForm({ onSubmit, onCancel, initialData }: OperatorFormPr
|
|||||||
metadata: { companyName: data.name }
|
metadata: { companyName: data.name }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
formToasts.error.generic(getErrorMessage(error));
|
||||||
|
|
||||||
// Re-throw so parent can handle modal closing
|
// Re-throw so parent can handle modal closing
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ import { useUserRole } from '@/hooks/useUserRole';
|
|||||||
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
import { HeadquartersLocationInput } from './HeadquartersLocationInput';
|
||||||
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
import { EntityMultiImageUploader } from '@/components/upload/EntityMultiImageUploader';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from 'sonner';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { handleError } from '@/lib/errorHandler';
|
import { handleError, getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { formToasts } from '@/lib/formToasts';
|
||||||
import type { UploadedImage } from '@/types/company';
|
import type { UploadedImage } from '@/types/company';
|
||||||
|
|
||||||
// Zod output type (after transformation)
|
// Zod output type (after transformation)
|
||||||
@@ -73,7 +74,7 @@ export function PropertyOwnerForm({ onSubmit, onCancel, initialData }: PropertyO
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
<form onSubmit={handleSubmit(async (data) => {
|
<form onSubmit={handleSubmit(async (data) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
toast.error('You must be logged in to submit');
|
formToasts.error.generic('You must be logged in to submit');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +94,11 @@ export function PropertyOwnerForm({ onSubmit, onCancel, initialData }: PropertyO
|
|||||||
|
|
||||||
await onSubmit(formData);
|
await onSubmit(formData);
|
||||||
|
|
||||||
// Only show success toast and close if not editing through moderation queue
|
// Show success toast
|
||||||
if (!initialData?.id) {
|
if (initialData?.id) {
|
||||||
toast.success('Property owner submitted for review');
|
formToasts.success.update('Property Owner', data.name);
|
||||||
|
} else {
|
||||||
|
formToasts.success.create('Property Owner', data.name);
|
||||||
onCancel();
|
onCancel();
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -104,6 +107,9 @@ export function PropertyOwnerForm({ onSubmit, onCancel, initialData }: PropertyO
|
|||||||
metadata: { companyName: data.name }
|
metadata: { companyName: data.name }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
formToasts.error.generic(getErrorMessage(error));
|
||||||
|
|
||||||
// Re-throw so parent can handle modal closing
|
// Re-throw so parent can handle modal closing
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import { Button } from '@/components/ui/button';
|
|||||||
import type { RideModelTechnicalSpec } from '@/types/database';
|
import type { RideModelTechnicalSpec } from '@/types/database';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { handleError } from '@/lib/errorHandler';
|
import { handleError } from '@/lib/errorHandler';
|
||||||
import { toast } from 'sonner';
|
import { toast } from '@/hooks/use-toast';
|
||||||
|
import { formToasts } from '@/lib/formToasts';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
@@ -112,12 +113,21 @@ export function RideModelForm({
|
|||||||
manufacturer_id: manufacturerId,
|
manufacturer_id: manufacturerId,
|
||||||
_technical_specifications: technicalSpecs
|
_technical_specifications: technicalSpecs
|
||||||
});
|
});
|
||||||
toast.success('Ride model submitted for review');
|
|
||||||
|
// Show success toast
|
||||||
|
if (initialData?.id) {
|
||||||
|
formToasts.success.update('Ride Model', data.name);
|
||||||
|
} else {
|
||||||
|
formToasts.success.create('Ride Model', data.name);
|
||||||
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
handleError(error, {
|
handleError(error, {
|
||||||
action: initialData?.id ? 'Update Ride Model' : 'Create Ride Model'
|
action: initialData?.id ? 'Update Ride Model' : 'Create Ride Model'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show error toast
|
||||||
|
formToasts.error.generic(getErrorMessage(error));
|
||||||
|
|
||||||
// Re-throw so parent can handle modal closing
|
// Re-throw so parent can handle modal closing
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user