mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 01:31:12 -05:00
Fix: Resolve milestone validation errors
This commit is contained in:
@@ -31,8 +31,8 @@ export function ValidationSummary({ item, onValidationChange, compact = false }:
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
// Type guard for valid entity types
|
// Type guard for valid entity types
|
||||||
type ValidEntityType = 'park' | 'ride' | 'manufacturer' | 'operator' | 'designer' | 'property_owner' | 'ride_model' | 'photo';
|
type ValidEntityType = 'park' | 'ride' | 'manufacturer' | 'operator' | 'designer' | 'property_owner' | 'ride_model' | 'photo' | 'milestone' | 'timeline_event';
|
||||||
const validEntityTypes: ValidEntityType[] = ['park', 'ride', 'manufacturer', 'operator', 'designer', 'property_owner', 'ride_model', 'photo'];
|
const validEntityTypes: ValidEntityType[] = ['park', 'ride', 'manufacturer', 'operator', 'designer', 'property_owner', 'ride_model', 'photo', 'milestone', 'timeline_event'];
|
||||||
|
|
||||||
if (!validEntityTypes.includes(item.item_type as ValidEntityType)) {
|
if (!validEntityTypes.includes(item.item_type as ValidEntityType)) {
|
||||||
setValidationResult({
|
setValidationResult({
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ export const entitySchemas = {
|
|||||||
ride_model: rideModelValidationSchema,
|
ride_model: rideModelValidationSchema,
|
||||||
photo: photoValidationSchema,
|
photo: photoValidationSchema,
|
||||||
milestone: milestoneValidationSchema,
|
milestone: milestoneValidationSchema,
|
||||||
|
timeline_event: milestoneValidationSchema, // Alias for milestone
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ export type EntityType =
|
|||||||
| 'designer'
|
| 'designer'
|
||||||
| 'property_owner'
|
| 'property_owner'
|
||||||
| 'photo_edit'
|
| 'photo_edit'
|
||||||
| 'photo_delete';
|
| 'photo_delete'
|
||||||
|
| 'milestone'
|
||||||
|
| 'timeline_event';
|
||||||
|
|
||||||
export interface PhotoSubmission {
|
export interface PhotoSubmission {
|
||||||
url: string;
|
url: string;
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ export function validateEntityDataStrict(
|
|||||||
warnings: []
|
warnings: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common validations (blocking)
|
// Skip name/slug validations for timeline events (they use title instead)
|
||||||
|
const isTimelineEvent = entityType === 'milestone' || entityType === 'timeline_event';
|
||||||
|
|
||||||
|
// Common validations (blocking) - only for entities with name/slug
|
||||||
|
if (!isTimelineEvent) {
|
||||||
if (!data.name?.trim()) {
|
if (!data.name?.trim()) {
|
||||||
result.blockingErrors.push('Name is required');
|
result.blockingErrors.push('Name is required');
|
||||||
}
|
}
|
||||||
@@ -58,6 +62,12 @@ export function validateEntityDataStrict(
|
|||||||
if (data.email && data.email !== '' && !isValidEmail(data.email)) {
|
if (data.email && data.email !== '' && !isValidEmail(data.email)) {
|
||||||
result.warnings.push('Email format may be invalid');
|
result.warnings.push('Email format may be invalid');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Validations specific to timeline events
|
||||||
|
if (data.description && data.description.length > 2000) {
|
||||||
|
result.blockingErrors.push('Description must be less than 2000 characters');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Entity-specific validations
|
// Entity-specific validations
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
@@ -145,6 +155,28 @@ export function validateEntityDataStrict(
|
|||||||
result.blockingErrors.push('Caption must be less than 500 characters');
|
result.blockingErrors.push('Caption must be less than 500 characters');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'milestone':
|
||||||
|
case 'timeline_event':
|
||||||
|
if (!data.title?.trim()) {
|
||||||
|
result.blockingErrors.push('Event title is required');
|
||||||
|
}
|
||||||
|
if (data.title && data.title.length > 200) {
|
||||||
|
result.blockingErrors.push('Title must be less than 200 characters');
|
||||||
|
}
|
||||||
|
if (!data.event_type) {
|
||||||
|
result.blockingErrors.push('Event type is required');
|
||||||
|
}
|
||||||
|
if (!data.event_date) {
|
||||||
|
result.blockingErrors.push('Event date is required');
|
||||||
|
}
|
||||||
|
if (!data.entity_type) {
|
||||||
|
result.blockingErrors.push('Entity type is required');
|
||||||
|
}
|
||||||
|
if (!data.entity_id) {
|
||||||
|
result.blockingErrors.push('Entity ID is required');
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.valid = result.blockingErrors.length === 0;
|
result.valid = result.blockingErrors.length === 0;
|
||||||
@@ -171,7 +203,11 @@ function isValidEmail(email: string): boolean {
|
|||||||
export function validateEntityData(entityType: string, data: any): ValidationResult {
|
export function validateEntityData(entityType: string, data: any): ValidationResult {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
// Common validations for all entities
|
// Skip name/slug validations for timeline events
|
||||||
|
const isTimelineEvent = entityType === 'milestone' || entityType === 'timeline_event';
|
||||||
|
|
||||||
|
// Common validations for entities with name/slug
|
||||||
|
if (!isTimelineEvent) {
|
||||||
if (!data.name || data.name.trim().length === 0) {
|
if (!data.name || data.name.trim().length === 0) {
|
||||||
errors.push('Name is required');
|
errors.push('Name is required');
|
||||||
}
|
}
|
||||||
@@ -193,6 +229,12 @@ export function validateEntityData(entityType: string, data: any): ValidationRes
|
|||||||
if (data.email && data.email !== '' && !data.email.includes('@')) {
|
if (data.email && data.email !== '' && !data.email.includes('@')) {
|
||||||
errors.push('Invalid email format');
|
errors.push('Invalid email format');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Validations for timeline events
|
||||||
|
if (data.description && data.description.length > 2000) {
|
||||||
|
errors.push('Description must be less than 2000 characters');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Entity-specific validations
|
// Entity-specific validations
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
@@ -256,6 +298,20 @@ export function validateEntityData(entityType: string, data: any): ValidationRes
|
|||||||
errors.push('Caption must be less than 500 characters');
|
errors.push('Caption must be less than 500 characters');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'milestone':
|
||||||
|
case 'timeline_event':
|
||||||
|
if (!data.title || data.title.trim().length === 0) {
|
||||||
|
errors.push('Event title is required');
|
||||||
|
}
|
||||||
|
if (data.title && data.title.length > 200) {
|
||||||
|
errors.push('Title must be less than 200 characters');
|
||||||
|
}
|
||||||
|
if (!data.event_type) errors.push('Event type is required');
|
||||||
|
if (!data.event_date) errors.push('Event date is required');
|
||||||
|
if (!data.entity_type) errors.push('Entity type is required');
|
||||||
|
if (!data.entity_id) errors.push('Entity ID is required');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user