mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 18:51:13 -05:00
Improve component stability and user experience with safety checks
Implement robust error handling, safety checks for data structures, and state management improvements across various components to prevent runtime errors and enhance user experience. Replit-Commit-Author: Agent Replit-Commit-Session-Id: a71e826a-1d38-4b6e-a34f-fbf5ba1f1b25 Replit-Commit-Checkpoint-Type: intermediate_checkpoint
This commit is contained in:
@@ -11,6 +11,36 @@ interface EntityEditPreviewProps {
|
||||
entityName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep equality check for detecting changes in nested objects/arrays
|
||||
*/
|
||||
const deepEqual = (a: any, b: any): boolean => {
|
||||
// Handle null/undefined cases
|
||||
if (a === b) return true;
|
||||
if (a == null || b == null) return false;
|
||||
if (typeof a !== typeof b) return false;
|
||||
|
||||
// Handle primitives and functions
|
||||
if (typeof a !== 'object') return a === b;
|
||||
|
||||
// Handle arrays
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
if (a.length !== b.length) return false;
|
||||
return a.every((item, index) => deepEqual(item, b[index]));
|
||||
}
|
||||
|
||||
// One is array, other is not
|
||||
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
||||
|
||||
// Handle objects
|
||||
const keysA = Object.keys(a);
|
||||
const keysB = Object.keys(b);
|
||||
|
||||
if (keysA.length !== keysB.length) return false;
|
||||
|
||||
return keysA.every(key => deepEqual(a[key], b[key]));
|
||||
};
|
||||
|
||||
interface ImageAssignments {
|
||||
uploaded: Array<{
|
||||
url: string;
|
||||
@@ -51,7 +81,10 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
||||
.eq('submission_id', submissionId)
|
||||
.order('order_index', { ascending: true });
|
||||
|
||||
if (error) throw error;
|
||||
if (error) {
|
||||
console.error('EntityEditPreview.fetchSubmissionItems: Failed to fetch submission items:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (items && items.length > 0) {
|
||||
const firstItem = items[0];
|
||||
@@ -75,21 +108,35 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
||||
if (data.images) {
|
||||
const images: ImageAssignments = data.images;
|
||||
|
||||
// Safety check: verify uploaded array exists and is valid
|
||||
if (!images.uploaded || !Array.isArray(images.uploaded)) {
|
||||
// Invalid images data structure, skip image processing
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract banner image
|
||||
if (images.banner_assignment !== null && images.banner_assignment !== undefined) {
|
||||
const bannerImg = images.uploaded[images.banner_assignment];
|
||||
if (bannerImg) {
|
||||
setBannerImageUrl(bannerImg.url);
|
||||
changed.push('banner_image');
|
||||
// Safety check: verify index is within bounds
|
||||
if (images.banner_assignment >= 0 && images.banner_assignment < images.uploaded.length) {
|
||||
const bannerImg = images.uploaded[images.banner_assignment];
|
||||
// Validate nested image data
|
||||
if (bannerImg && bannerImg.url) {
|
||||
setBannerImageUrl(bannerImg.url);
|
||||
changed.push('banner_image');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract card image
|
||||
if (images.card_assignment !== null && images.card_assignment !== undefined) {
|
||||
const cardImg = images.uploaded[images.card_assignment];
|
||||
if (cardImg) {
|
||||
setCardImageUrl(cardImg.url);
|
||||
changed.push('card_image');
|
||||
// Safety check: verify index is within bounds
|
||||
if (images.card_assignment >= 0 && images.card_assignment < images.uploaded.length) {
|
||||
const cardImg = images.uploaded[images.card_assignment];
|
||||
// Validate nested image data
|
||||
if (cardImg && cardImg.url) {
|
||||
setCardImageUrl(cardImg.url);
|
||||
changed.push('card_image');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,9 +146,12 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
||||
const originalData = firstItem.original_data as any;
|
||||
const excludeFields = ['images', 'updated_at', 'created_at'];
|
||||
Object.keys(data).forEach(key => {
|
||||
if (!excludeFields.includes(key) &&
|
||||
data[key] !== originalData[key]) {
|
||||
changed.push(key);
|
||||
if (!excludeFields.includes(key)) {
|
||||
// Use deep equality check for objects and arrays
|
||||
const isEqual = deepEqual(data[key], originalData[key]);
|
||||
if (!isEqual) {
|
||||
changed.push(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -109,7 +159,7 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
|
||||
setChangedFields(changed);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching submission items:', error);
|
||||
console.error('EntityEditPreview.fetchSubmissionItems: Error fetching submission items:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user