fix: Prevent undefined rendering in reasoning translations

Fixed React error #306 (text content mismatch) caused by undefined values
in reasoning translations.

Root cause: Translation functions could return undefined when:
- Translation key doesn't exist
- reasoning_data has unexpected structure
- parameters are missing

Changes:
- Added defaultValue to all translation calls
- Added || fallback operators to ensure strings are always returned
- Added proper null/undefined checks with empty string fallbacks
- Enhanced getInsightDescription with multiple fallback levels

This ensures all translation functions return valid strings, preventing
React hydration mismatches and rendering errors on the dashboard.
This commit is contained in:
Claude
2025-11-07 20:02:53 +00:00
parent e67a83ceb0
commit 027c539768
2 changed files with 25 additions and 12 deletions

View File

@@ -34,7 +34,8 @@ export function useReasoningTranslation() {
return t('purchaseOrder.low_stock_detection', { return t('purchaseOrder.low_stock_detection', {
supplier_name: 'Unknown', supplier_name: 'Unknown',
product_names_joined: 'Items', product_names_joined: 'Items',
days_until_stockout: 7 days_until_stockout: 7,
defaultValue: 'Purchase order required for inventory replenishment'
}); });
} }
@@ -45,10 +46,11 @@ export function useReasoningTranslation() {
...parameters, ...parameters,
product_names_joined: Array.isArray(parameters.product_names) product_names_joined: Array.isArray(parameters.product_names)
? parameters.product_names.join(', ') ? parameters.product_names.join(', ')
: parameters.product_names || 'Items' : parameters.product_names || 'Items',
defaultValue: `Purchase order: ${type}`
}; };
return t(`purchaseOrder.${type}`, params); return t(`purchaseOrder.${type}`, params) || `Purchase order: ${type}`;
}; };
/** /**
@@ -60,12 +62,17 @@ export function useReasoningTranslation() {
product_name: 'Product', product_name: 'Product',
predicted_demand: 0, predicted_demand: 0,
current_stock: 0, current_stock: 0,
confidence_score: 85 confidence_score: 85,
defaultValue: 'Production batch scheduled based on demand forecast'
}); });
} }
const { type, parameters } = reasoningData; const { type, parameters } = reasoningData;
return t(`productionBatch.${type}`, parameters); const params = {
...parameters,
defaultValue: `Production batch: ${type}`
};
return t(`productionBatch.${type}`, params) || `Production batch: ${type}`;
}; };
/** /**
@@ -80,10 +87,11 @@ export function useReasoningTranslation() {
...consequenceData, ...consequenceData,
affected_products_joined: Array.isArray(consequenceData.affected_products) affected_products_joined: Array.isArray(consequenceData.affected_products)
? consequenceData.affected_products.join(', ') ? consequenceData.affected_products.join(', ')
: consequenceData.affected_products || 'products' : consequenceData.affected_products || 'products',
defaultValue: `Impact: ${consequenceData.type}`
}; };
return t(`consequence.${consequenceData.type}`, params); return t(`consequence.${consequenceData.type}`, params) || '';
}; };
/** /**
@@ -91,7 +99,7 @@ export function useReasoningTranslation() {
*/ */
const translateSeverity = (severity?: string): string => { const translateSeverity = (severity?: string): string => {
if (!severity) return ''; if (!severity) return '';
return t(`severity.${severity}`); return t(`severity.${severity}`, { defaultValue: severity }) || '';
}; };
/** /**
@@ -99,7 +107,7 @@ export function useReasoningTranslation() {
*/ */
const translateTrigger = (trigger?: string): string => { const translateTrigger = (trigger?: string): string => {
if (!trigger) return ''; if (!trigger) return '';
return t(`triggers.${trigger}`); return t(`triggers.${trigger}`, { defaultValue: trigger }) || '';
}; };
/** /**

View File

@@ -137,13 +137,18 @@ const AIInsightsPage: React.FC = () => {
} }
try { try {
return t(`${category}.${insight.reasoning_data.type}`, insight.reasoning_data.parameters); const params = {
...insight.reasoning_data.parameters,
defaultValue: insight.description || `${category}: ${insight.reasoning_data.type}`
};
const translated = t(`${category}.${insight.reasoning_data.type}`, params);
return translated || insight.description || `AI Insight: ${insight.reasoning_data.type}`;
} catch (e) { } catch (e) {
// Fall back to description if translation key not found // Fall back to description if translation key not found
return insight.description; return insight.description || 'AI Insight';
} }
} }
return insight.description; return insight.description || 'AI Insight';
}; };
return ( return (