diff --git a/src/lib/submissionChangeDetection.ts b/src/lib/submissionChangeDetection.ts index 3c304766..ed2aeccc 100644 --- a/src/lib/submissionChangeDetection.ts +++ b/src/lib/submissionChangeDetection.ts @@ -126,30 +126,50 @@ export async function detectChanges( const oldValue = originalData[key]; const newValue = itemData[key]; - // Handle location changes specially - if (key === 'location' || key === 'location_id') { - if (!isEqual(oldValue, newValue)) { - hasLocationChange = true; - fieldChanges.push({ - field: key, - oldValue, - newValue, - changeType: 'modified', - }); + // Handle location changes specially - compare objects not IDs + if (key === 'location') { + const oldLoc = originalData.location; + const newLoc = itemData.location; + + // Only compare if we have location objects with actual data + if (newLoc && typeof newLoc === 'object' && oldLoc && typeof oldLoc === 'object') { + // Compare actual location data (city, state, country) + const locChanged = + oldLoc.city !== newLoc.city || + oldLoc.state_province !== newLoc.state_province || + oldLoc.country !== newLoc.country; + + if (locChanged) { + hasLocationChange = true; + fieldChanges.push({ + field: 'location', + oldValue: oldLoc, + newValue: newLoc, + changeType: 'modified', + }); + } } return; } + // Skip if both are "empty" (null, undefined, or empty string) + const oldEmpty = oldValue === null || oldValue === undefined || oldValue === ''; + const newEmpty = newValue === null || newValue === undefined || newValue === ''; + + if (oldEmpty && newEmpty) { + return; // Both empty, no change + } + // Check for changes if (!isEqual(oldValue, newValue)) { - if ((oldValue === null || oldValue === undefined || oldValue === '') && newValue) { + if (oldEmpty && !newEmpty) { fieldChanges.push({ field: key, oldValue, newValue, changeType: 'added', }); - } else if ((newValue === null || newValue === undefined || newValue === '') && oldValue) { + } else if (newEmpty && !oldEmpty) { fieldChanges.push({ field: key, oldValue, @@ -194,16 +214,37 @@ export async function detectChanges( */ function shouldTrackField(key: string): boolean { const excludedFields = [ + // System fields 'id', 'created_at', 'updated_at', 'slug', + + // Image-related (handled separately) + 'images', 'image_assignments', 'banner_image_url', 'banner_image_id', 'card_image_url', 'card_image_id', + + // Reference IDs (not editable, just for linking) + 'park_id', + 'ride_id', + 'company_id', + 'manufacturer_id', + 'operator_id', + 'designer_id', + 'property_owner_id', + 'location_id', // Location object is tracked instead + + // Computed/aggregated fields (not editable) + 'ride_count', + 'review_count', + 'coaster_count', + 'average_rating', ]; + return !excludedFields.includes(key); } @@ -242,10 +283,20 @@ function getImageIds(data: any): { banner?: string; card?: string } { if (data.card_image_id) result.card = data.card_image_id; // Handle nested structure (item_data from form) - if (data.images?.uploaded) { + if (data.images?.uploaded && Array.isArray(data.images.uploaded)) { const uploaded = data.images.uploaded; - if (uploaded[0]?.id) result.banner = uploaded[0].id; - if (uploaded[1]?.id) result.card = uploaded[1].id; + + // Handle banner/card assignment mapping (default to indices 0 and 1) + const bannerIdx = data.images.banner_assignment ?? 0; + const cardIdx = data.images.card_assignment ?? 1; + + // Try both 'cloudflare_id' and 'id' for compatibility + if (uploaded[bannerIdx]) { + result.banner = uploaded[bannerIdx].cloudflare_id || uploaded[bannerIdx].id; + } + if (uploaded[cardIdx]) { + result.card = uploaded[cardIdx].cloudflare_id || uploaded[cardIdx].id; + } } return result;