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:
pac7
2025-10-08 19:27:31 +00:00
parent f21602b992
commit bfba3baf7e
12 changed files with 224 additions and 110 deletions

View File

@@ -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);
}