feat(dashboard): Add i18n support for action buttons
- Create getActionLabelKey() mapper function for action types - Map action types (approve_po, call_supplier, etc.) to i18n keys - Extract parameters from metadata (amount, supplier, customer, hours) - Update button rendering to use translations instead of backend strings Translation updates: - Add missing action keys: reject_po, complete_receipt, mark_received - Spanish translations: "Rechazar pedido", "Completar recepción", etc. - Basque translations: "Baztertu eskaera", "Osatu stockaren harrera", etc. Action buttons now respect user's language preference (EN/ES/EU) instead of showing hardcoded backend strings. Fixes: Issue #4 - Missing i18n for action buttons 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -110,6 +110,71 @@ function EscalationBadge({ alert }: { alert: EnrichedAlert }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map action type to i18n translation key with extracted parameters
|
||||||
|
*/
|
||||||
|
function getActionLabelKey(actionType: string, metadata?: Record<string, any>): { key: string; params: Record<string, any> } {
|
||||||
|
const actionTypeMap: Record<string, { key: string; extractParams?: (meta: Record<string, any>) => Record<string, any> }> = {
|
||||||
|
'approve_po': {
|
||||||
|
key: 'alerts:actions.approve_po',
|
||||||
|
extractParams: (meta) => ({ amount: meta.amount || meta.po_amount || 0 })
|
||||||
|
},
|
||||||
|
'reject_po': {
|
||||||
|
key: 'alerts:actions.reject_po',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'call_supplier': {
|
||||||
|
key: 'alerts:actions.call_supplier',
|
||||||
|
extractParams: (meta) => ({ supplier: meta.supplier || meta.name || 'Supplier', phone: meta.phone || '' })
|
||||||
|
},
|
||||||
|
'open_reasoning': {
|
||||||
|
key: 'alerts:actions.see_reasoning',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'complete_stock_receipt': {
|
||||||
|
key: 'alerts:actions.complete_receipt',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'mark_delivery_received': {
|
||||||
|
key: 'alerts:actions.mark_received',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'adjust_production': {
|
||||||
|
key: 'alerts:actions.adjust_production',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'navigate': {
|
||||||
|
key: 'alerts:actions.navigate',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'notify_customer': {
|
||||||
|
key: 'alerts:actions.notify_customer',
|
||||||
|
extractParams: (meta) => ({ customer: meta.customer_name || meta.customer || 'Customer' })
|
||||||
|
},
|
||||||
|
'snooze': {
|
||||||
|
key: 'alerts:actions.snooze',
|
||||||
|
extractParams: (meta) => ({ hours: meta.duration_hours || meta.hours || 4 })
|
||||||
|
},
|
||||||
|
'dismiss': {
|
||||||
|
key: 'alerts:actions.dismiss',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'mark_read': {
|
||||||
|
key: 'alerts:actions.mark_read',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
'cancel_auto_action': {
|
||||||
|
key: 'alerts:actions.cancel_auto_action',
|
||||||
|
extractParams: () => ({})
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const config = actionTypeMap[actionType] || { key: 'alerts:actions.navigate', extractParams: () => ({}) };
|
||||||
|
const params = config.extractParams ? config.extractParams(metadata || {}) : {};
|
||||||
|
|
||||||
|
return { key: config.key, params };
|
||||||
|
}
|
||||||
|
|
||||||
function ActionCard({ alert, showEscalationBadge = false, onActionSuccess, onActionError }: ActionCardProps) {
|
function ActionCard({ alert, showEscalationBadge = false, onActionSuccess, onActionError }: ActionCardProps) {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const [loadingAction, setLoadingAction] = useState<string | null>(null);
|
const [loadingAction, setLoadingAction] = useState<string | null>(null);
|
||||||
@@ -305,7 +370,10 @@ function ActionCard({ alert, showEscalationBadge = false, onActionSuccess, onAct
|
|||||||
}}
|
}}
|
||||||
className={`${isPrimary ? 'font-semibold' : ''} sm:w-auto w-full`}
|
className={`${isPrimary ? 'font-semibold' : ''} sm:w-auto w-full`}
|
||||||
>
|
>
|
||||||
{action.label}
|
{(() => {
|
||||||
|
const { key, params } = getActionLabelKey(action.type, action.metadata);
|
||||||
|
return String(t(key, params));
|
||||||
|
})()}
|
||||||
{action.estimated_time_minutes && !isLoading && (
|
{action.estimated_time_minutes && !isLoading && (
|
||||||
<span className="ml-1 opacity-60 text-xs">({action.estimated_time_minutes}m)</span>
|
<span className="ml-1 opacity-60 text-xs">({action.estimated_time_minutes}m)</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
299
frontend/src/locales/en/alerts.json
Normal file
299
frontend/src/locales/en/alerts.json
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
{
|
||||||
|
"priority": {
|
||||||
|
"critical": "Critical",
|
||||||
|
"important": "Important",
|
||||||
|
"standard": "Standard",
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
|
"type_class": {
|
||||||
|
"action_needed": "Action Needed",
|
||||||
|
"prevented_issue": "Issue Prevented",
|
||||||
|
"trend_warning": "Trend Warning",
|
||||||
|
"escalation": "Escalation",
|
||||||
|
"information": "Information"
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"already_addressed": "AI already handled this",
|
||||||
|
"financial_impact": "€{amount} at risk",
|
||||||
|
"time_until": "Needs decision in {time}",
|
||||||
|
"can_user_fix": "You can fix this",
|
||||||
|
"requires_supplier": "Requires {supplier}",
|
||||||
|
"prevented_savings": "Saved €{amount}",
|
||||||
|
"grouped_count": "{count} grouped"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"approve_po": "Approve €{amount} order",
|
||||||
|
"reject_po": "Reject order",
|
||||||
|
"call_supplier": "Call {supplier} ({phone})",
|
||||||
|
"see_reasoning": "See full reasoning",
|
||||||
|
"complete_receipt": "Complete stock receipt",
|
||||||
|
"mark_received": "Mark as received",
|
||||||
|
"adjust_production": "Adjust production schedule",
|
||||||
|
"snooze": "Snooze {hours}h",
|
||||||
|
"mark_read": "Mark as read",
|
||||||
|
"dismiss": "Dismiss",
|
||||||
|
"navigate": "View details",
|
||||||
|
"notify_customer": "Notify {customer}",
|
||||||
|
"cancel_auto_action": "Cancel auto-action"
|
||||||
|
},
|
||||||
|
"orchestration": {
|
||||||
|
"reasoning_title": "🤖 Daily Orchestrator Reasoning",
|
||||||
|
"analyzed_title": "This morning, I analyzed:",
|
||||||
|
"actions_taken": "So I scheduled:",
|
||||||
|
"prevented_issues": "✅ Issues Prevented",
|
||||||
|
"estimated_impact": "Estimated Impact",
|
||||||
|
"impact_description": "Savings from prevented rush orders, stockouts, and waste",
|
||||||
|
"last_run": "Last run",
|
||||||
|
"what_ai_did": "What AI did for you"
|
||||||
|
},
|
||||||
|
"metrics": {
|
||||||
|
"hours": "{count, plural, =1 {# hour} other {# hours}}",
|
||||||
|
"minutes": "{count, plural, =1 {# minute} other {# minutes}}",
|
||||||
|
"days": "{count, plural, =1 {# day} other {# days}}"
|
||||||
|
},
|
||||||
|
"escalated": "Escalated",
|
||||||
|
"action_success": "Action completed successfully",
|
||||||
|
"action_error": "Action failed. Please try again.",
|
||||||
|
"hub": {
|
||||||
|
"tab_list_label": "Alert categories",
|
||||||
|
"tabs": {
|
||||||
|
"all": "All Alerts",
|
||||||
|
"all_description": "Every alert for your bakery",
|
||||||
|
"for_me": "For Me",
|
||||||
|
"for_me_description": "Alerts assigned to you or requiring your action",
|
||||||
|
"archived": "Archived",
|
||||||
|
"archived_description": "Resolved and dismissed alerts"
|
||||||
|
},
|
||||||
|
"toggle_filters": "Toggle filters",
|
||||||
|
"filters": "Filters",
|
||||||
|
"active": "Active"
|
||||||
|
},
|
||||||
|
"auto_action": {
|
||||||
|
"title": "Auto-action Pending",
|
||||||
|
"remaining": "remaining",
|
||||||
|
"financial_impact": "Impact:",
|
||||||
|
"cancel_button": "Cancel Auto-action",
|
||||||
|
"cancelling": "Cancelling...",
|
||||||
|
"cancelled_title": "Auto-action Cancelled",
|
||||||
|
"cancelled_message": "The automatic action has been prevented. You can now handle this manually.",
|
||||||
|
"completed_title": "Auto-action Executed",
|
||||||
|
"help_text": "AI will automatically execute this action when the timer expires. Click \"Cancel\" to prevent it and handle manually.",
|
||||||
|
"urgency": {
|
||||||
|
"critical": "URGENT",
|
||||||
|
"warning": "SOON",
|
||||||
|
"info": "SCHEDULED"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority_explainer": {
|
||||||
|
"title": "Understanding Priority Scores",
|
||||||
|
"subtitle": "How AI calculates what needs your attention first",
|
||||||
|
"overview": {
|
||||||
|
"title": "The Priority Score (0-100)",
|
||||||
|
"description": "Every alert receives a priority score from 0-100 based on four weighted components. This helps you focus on what truly matters for your bakery."
|
||||||
|
},
|
||||||
|
"example_alert": "Example Alert Priority",
|
||||||
|
"level": {
|
||||||
|
"critical": "CRITICAL",
|
||||||
|
"important": "IMPORTANT",
|
||||||
|
"standard": "STANDARD",
|
||||||
|
"info": "INFO"
|
||||||
|
},
|
||||||
|
"components_title": "Score Components",
|
||||||
|
"weight": "weight",
|
||||||
|
"business_impact": {
|
||||||
|
"name": "Business Impact",
|
||||||
|
"description": "Financial consequences, affected orders, customer satisfaction",
|
||||||
|
"example1": "€500 in potential revenue at risk",
|
||||||
|
"example2": "10 customer orders affected",
|
||||||
|
"example3": "High customer satisfaction impact"
|
||||||
|
},
|
||||||
|
"urgency": {
|
||||||
|
"name": "Urgency",
|
||||||
|
"description": "Time sensitivity, deadlines, escalation potential",
|
||||||
|
"example1": "Deadline in 2 hours",
|
||||||
|
"example2": "Stockout imminent (4 hours)",
|
||||||
|
"example3": "Production window closing soon"
|
||||||
|
},
|
||||||
|
"agency": {
|
||||||
|
"name": "User Agency",
|
||||||
|
"description": "Can you take action? Do you have control over the outcome?",
|
||||||
|
"example1": "Requires approval from you",
|
||||||
|
"example2": "One-click action available",
|
||||||
|
"example3": "Decision needed within your authority"
|
||||||
|
},
|
||||||
|
"confidence": {
|
||||||
|
"name": "AI Confidence",
|
||||||
|
"description": "How certain is the AI about this alert's validity?",
|
||||||
|
"example1": "Based on historical patterns (95% match)",
|
||||||
|
"example2": "Data quality: High",
|
||||||
|
"example3": "Prediction accuracy validated"
|
||||||
|
},
|
||||||
|
"formula_title": "The Formula",
|
||||||
|
"footer": "This scoring helps AI prioritize alerts, ensuring you see the most important issues first.",
|
||||||
|
"got_it": "Got it!"
|
||||||
|
},
|
||||||
|
"trend": {
|
||||||
|
"near_threshold": "Near threshold"
|
||||||
|
},
|
||||||
|
"action_preview": {
|
||||||
|
"title": "Action Preview",
|
||||||
|
"outcome": "What will happen",
|
||||||
|
"financial_impact": "Financial Impact",
|
||||||
|
"affected_systems": "Affected Systems",
|
||||||
|
"reversible": "This action can be undone",
|
||||||
|
"not_reversible": "This action cannot be undone",
|
||||||
|
"confidence": "AI Confidence: {{confidence}}%",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"confirm": "Confirm Action"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"title": "Response Time Performance",
|
||||||
|
"subtitle": "How quickly you respond to alerts",
|
||||||
|
"on_time": "On Time",
|
||||||
|
"alerts": "alerts",
|
||||||
|
"average": "Average",
|
||||||
|
"target": "Target",
|
||||||
|
"on_time_responses": "On-Time Responses",
|
||||||
|
"needs_improvement": "Needs improvement",
|
||||||
|
"benchmark_title": "Performance Perspective",
|
||||||
|
"excellent": "Excellent! You're responding faster than 80% of bakeries. Keep it up!",
|
||||||
|
"good": "Good job! Try responding to critical alerts within target time to improve further.",
|
||||||
|
"needs_work": "Faster responses to critical alerts can prevent issues and save money. Try meeting target times.",
|
||||||
|
"tip": "Tip: Enable mobile notifications to respond faster to critical alerts"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"critical_stock_shortage": {
|
||||||
|
"title": "🚨 Critical Stock: {{ingredient_name}}",
|
||||||
|
"message_with_po_pending": "Only {{current_stock}}kg of {{ingredient_name}} (need {{required_stock}}kg). Already created {{po_id}} for delivery on {{delivery_day_name}}. Please approve €{{po_amount}}.",
|
||||||
|
"message_with_po_created": "Only {{current_stock}}kg of {{ingredient_name}} (need {{required_stock}}kg). Already created {{po_id}}. Review and approve €{{po_amount}}.",
|
||||||
|
"message_with_hours": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg in {{hours_until}} hours).",
|
||||||
|
"message_with_date": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg for production on {{production_day_name}}).",
|
||||||
|
"message_generic": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg)."
|
||||||
|
},
|
||||||
|
"low_stock": {
|
||||||
|
"title": "⚠️ Low Stock: {{ingredient_name}}",
|
||||||
|
"message_with_po": "{{ingredient_name}} stock: {{current_stock}}kg (minimum: {{minimum_stock}}kg). Already scheduled PO for replenishment.",
|
||||||
|
"message_generic": "{{ingredient_name}} stock: {{current_stock}}kg (minimum: {{minimum_stock}}kg). Consider placing an order."
|
||||||
|
},
|
||||||
|
"stock_depleted": {
|
||||||
|
"title": "📦 Stock Depleted by Order",
|
||||||
|
"message_with_supplier": "Order #{{order_id}} requires {{ingredient_name}} but it's depleted. Contact {{supplier_name}} ({{supplier_phone}}).",
|
||||||
|
"message_generic": "Order #{{order_id}} requires {{ingredient_name}} but it's depleted. Immediate action required."
|
||||||
|
},
|
||||||
|
"ingredient_shortage": {
|
||||||
|
"title": "⚠️ Ingredient Shortage in Production",
|
||||||
|
"message_with_customers": "{{ingredient_name}} insufficient for batches in progress. {{affected_orders}} orders affected ({{customer_names}}). Current stock: {{current_stock}}kg, required: {{required_stock}}kg.",
|
||||||
|
"message_generic": "{{ingredient_name}} insufficient for batches in progress. Current stock: {{current_stock}}kg, required: {{required_stock}}kg."
|
||||||
|
},
|
||||||
|
"expired_products": {
|
||||||
|
"title": "🚫 Expired or Expiring Products",
|
||||||
|
"message_with_names": "{{count}} products expiring: {{product_names}}. Total value: €{{total_value}}.",
|
||||||
|
"message_generic": "{{count}} products expiring. Total value: €{{total_value}}."
|
||||||
|
},
|
||||||
|
"production_delay": {
|
||||||
|
"title": "⏰ Production Delay: {{batch_name}}",
|
||||||
|
"message_with_customers": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. Affected customers: {{customer_names}}. Original delivery time: {{scheduled_time}}.",
|
||||||
|
"message_with_orders": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. {{affected_orders}} orders affected. Original delivery time: {{scheduled_time}}.",
|
||||||
|
"message_generic": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. Original delivery time: {{scheduled_time}}."
|
||||||
|
},
|
||||||
|
"equipment_failure": {
|
||||||
|
"title": "🔧 Equipment Failure: {{equipment_name}}",
|
||||||
|
"message_with_batches": "{{equipment_name}} failed. {{affected_batches}} batches in production affected ({{batch_names}}).",
|
||||||
|
"message_generic": "{{equipment_name}} failed. Requires immediate repair."
|
||||||
|
},
|
||||||
|
"maintenance_required": {
|
||||||
|
"title": "🔧 Maintenance Required: {{equipment_name}}",
|
||||||
|
"message_with_hours": "{{equipment_name}} requires maintenance in {{hours_until}} hours. Schedule now to prevent disruptions.",
|
||||||
|
"message_with_days": "{{equipment_name}} requires maintenance in {{days_until}} days. Schedule before {{maintenance_date}}."
|
||||||
|
},
|
||||||
|
"low_equipment_efficiency": {
|
||||||
|
"title": "📉 Low Efficiency: {{equipment_name}}",
|
||||||
|
"message": "{{equipment_name}} operating at {{efficiency_percent}}% efficiency (expected: >{{threshold_percent}}%). Consider maintenance."
|
||||||
|
},
|
||||||
|
"order_overload": {
|
||||||
|
"title": "📊 Order Overload",
|
||||||
|
"message_with_orders": "Capacity overloaded by {{overload_percent}}%. {{total_orders}} orders scheduled, capacity: {{capacity_orders}}. Consider adjusting schedule.",
|
||||||
|
"message_generic": "Capacity overloaded by {{overload_percent}}%. Consider adjusting production schedule."
|
||||||
|
},
|
||||||
|
"supplier_delay": {
|
||||||
|
"title": "🚚 Supplier Delay: {{supplier_name}}",
|
||||||
|
"message": "{{supplier_name}} delayed delivery of {{ingredient_name}} (PO: {{po_id}}). New date: {{new_delivery_date}}. Original: {{original_delivery_date}}."
|
||||||
|
},
|
||||||
|
"temperature_breach": {
|
||||||
|
"title": "🌡️ Temperature Breach",
|
||||||
|
"message": "Temperature {{location}}: {{current_temp}}°C (range: {{min_temp}}°C-{{max_temp}}°C). Duration: {{duration_minutes}} minutes."
|
||||||
|
},
|
||||||
|
"demand_surge_weekend": {
|
||||||
|
"title": "📈 Demand Surge: Weekend",
|
||||||
|
"message": "Expected demand {{surge_percent}}% higher for {{weekend_date}}. Affected products: {{products}}. Consider increasing production."
|
||||||
|
},
|
||||||
|
"weather_impact_alert": {
|
||||||
|
"title": "🌦️ Expected Weather Impact",
|
||||||
|
"message": "{{weather_condition}} expected {{date}}. Demand impact: {{impact_percent}}%. Affected products: {{products}}."
|
||||||
|
},
|
||||||
|
"holiday_preparation": {
|
||||||
|
"title": "🎉 Holiday Preparation: {{holiday_name}}",
|
||||||
|
"message": "{{holiday_name}} in {{days_until}} days ({{holiday_date}}). Expected demand {{expected_increase}}% higher. Key products: {{products}}."
|
||||||
|
},
|
||||||
|
"severe_weather_impact": {
|
||||||
|
"title": "⛈️ Severe Weather Impact",
|
||||||
|
"message": "Severe {{weather_condition}} expected {{date}}. Demand impact: {{impact_percent}}%. Consider adjusting delivery schedules."
|
||||||
|
},
|
||||||
|
"unexpected_demand_spike": {
|
||||||
|
"title": "📊 Unexpected Demand Spike",
|
||||||
|
"message": "Demand increased {{spike_percent}}% for {{products}}. Current stock may run out in {{hours_until_stockout}} hours."
|
||||||
|
},
|
||||||
|
"demand_pattern_optimization": {
|
||||||
|
"title": "💡 Demand Pattern Optimization",
|
||||||
|
"message": "Pattern detected: {{pattern_description}}. Recommend adjusting production of {{products}} to optimize efficiency."
|
||||||
|
},
|
||||||
|
"inventory_optimization": {
|
||||||
|
"title": "📦 Inventory Optimization",
|
||||||
|
"message": "{{ingredient_name}} consistently over-stocked by {{excess_percent}}%. Recommend reducing order to {{recommended_amount}}kg."
|
||||||
|
},
|
||||||
|
"production_efficiency": {
|
||||||
|
"title": "⚡ Production Efficiency Opportunity",
|
||||||
|
"message": "{{product_name}} more efficient at {{suggested_time}}. Production time {{time_saved}} minutes shorter ({{savings_percent}}% savings)."
|
||||||
|
},
|
||||||
|
"sales_opportunity": {
|
||||||
|
"title": "💰 Sales Opportunity",
|
||||||
|
"message": "High demand for {{products}} detected. Consider additional production. Potential revenue: €{{potential_revenue}}."
|
||||||
|
},
|
||||||
|
"seasonal_adjustment": {
|
||||||
|
"title": "🍂 Seasonal Adjustment Recommended",
|
||||||
|
"message": "{{season}} season approaching. Adjust production of {{products}} based on historical trends ({{adjustment_percent}}% {{adjustment_direction}})."
|
||||||
|
},
|
||||||
|
"cost_reduction": {
|
||||||
|
"title": "💵 Cost Reduction Opportunity",
|
||||||
|
"message": "Switching to {{alternative_ingredient}} can save €{{savings_amount}}/month. Similar quality, lower cost."
|
||||||
|
},
|
||||||
|
"waste_reduction": {
|
||||||
|
"title": "♻️ Waste Reduction Opportunity",
|
||||||
|
"message": "{{product_name}} waste high ({{waste_percent}}%). Recommend reducing batch to {{recommended_quantity}} units."
|
||||||
|
},
|
||||||
|
"quality_improvement": {
|
||||||
|
"title": "⭐ Quality Improvement Recommended",
|
||||||
|
"message": "{{issue_description}} detected in {{product_name}}. Recommended action: {{recommended_action}}."
|
||||||
|
},
|
||||||
|
"customer_satisfaction": {
|
||||||
|
"title": "😊 Customer Satisfaction Opportunity",
|
||||||
|
"message": "Customer {{customer_name}} consistently orders {{product_name}}. Consider special offer or loyalty program."
|
||||||
|
},
|
||||||
|
"energy_optimization": {
|
||||||
|
"title": "⚡ Energy Optimization",
|
||||||
|
"message": "Energy usage for {{equipment_name}} peaks at {{peak_time}}. Shifting to {{off_peak_start}}-{{off_peak_end}} can save €{{savings_amount}}/month."
|
||||||
|
},
|
||||||
|
"staff_optimization": {
|
||||||
|
"title": "👥 Staff Optimization",
|
||||||
|
"message": "{{shift_name}} over-staffed by {{excess_percent}}%. Consider adjusting staff levels to reduce labor costs."
|
||||||
|
},
|
||||||
|
"po_approval_needed": {
|
||||||
|
"title": "Purchase Order #{{po_number}} requires approval",
|
||||||
|
"message": "Purchase order for {{supplier_name}} totaling {{currency}} {{total_amount}} is pending approval. Delivery required by {{required_delivery_date}}."
|
||||||
|
},
|
||||||
|
"production_batch_start": {
|
||||||
|
"title": "Production Batch Ready: {{product_name}}",
|
||||||
|
"message": "Batch #{{batch_number}} ({{quantity_planned}} {{unit}} of {{product_name}}) is ready to start. Priority: {{priority}}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
297
frontend/src/locales/es/alerts.json
Normal file
297
frontend/src/locales/es/alerts.json
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
{
|
||||||
|
"priority": {
|
||||||
|
"critical": "Crítico",
|
||||||
|
"important": "Importante",
|
||||||
|
"standard": "Estándar",
|
||||||
|
"info": "Info"
|
||||||
|
},
|
||||||
|
"type_class": {
|
||||||
|
"action_needed": "Acción Requerida",
|
||||||
|
"prevented_issue": "Problema Prevenido",
|
||||||
|
"trend_warning": "Aviso de Tendencia",
|
||||||
|
"escalation": "Escalación",
|
||||||
|
"information": "Información"
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"already_addressed": "La IA ya gestionó esto",
|
||||||
|
"financial_impact": "€{amount} en riesgo",
|
||||||
|
"time_until": "Necesita decisión en {time}",
|
||||||
|
"can_user_fix": "Puedes solucionarlo",
|
||||||
|
"requires_supplier": "Requiere {supplier}",
|
||||||
|
"prevented_savings": "Ahorrado €{amount}",
|
||||||
|
"grouped_count": "{count} agrupadas"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"approve_po": "Aprobar pedido €{amount}",
|
||||||
|
"reject_po": "Rechazar pedido",
|
||||||
|
"call_supplier": "Llamar a {supplier} ({phone})",
|
||||||
|
"see_reasoning": "Ver razonamiento completo",
|
||||||
|
"complete_receipt": "Completar recepción de stock",
|
||||||
|
"mark_received": "Marcar como recibido",
|
||||||
|
"adjust_production": "Ajustar calendario de producción",
|
||||||
|
"snooze": "Posponer {hours}h",
|
||||||
|
"mark_read": "Marcar como leído",
|
||||||
|
"dismiss": "Descartar",
|
||||||
|
"navigate": "Ver detalles",
|
||||||
|
"notify_customer": "Notificar a {customer}",
|
||||||
|
"cancel_auto_action": "Cancelar acción automática"
|
||||||
|
},
|
||||||
|
"orchestration": {
|
||||||
|
"reasoning_title": "🤖 Razonamiento del Orquestador Diario",
|
||||||
|
"analyzed_title": "Esta mañana, analicé:",
|
||||||
|
"actions_taken": "Así que programé:",
|
||||||
|
"prevented_issues": "✅ Problemas Prevenidos",
|
||||||
|
"estimated_impact": "Impacto Estimado",
|
||||||
|
"impact_description": "Ahorros por prevención de pedidos urgentes, faltas de stock y desperdicios",
|
||||||
|
"last_run": "Última ejecución",
|
||||||
|
"what_ai_did": "Lo que hizo la IA por ti"
|
||||||
|
},
|
||||||
|
"metrics": {
|
||||||
|
"hours": "{count, plural, =1 {# hora} other {# horas}}",
|
||||||
|
"minutes": "{count, plural, =1 {# minuto} other {# minutos}}",
|
||||||
|
"days": "{count, plural, =1 {# día} other {# días}}"
|
||||||
|
},
|
||||||
|
"escalated": "Escalado",
|
||||||
|
"hub": {
|
||||||
|
"tab_list_label": "Categorías de alertas",
|
||||||
|
"tabs": {
|
||||||
|
"all": "Todas las Alertas",
|
||||||
|
"all_description": "Todas las alertas de tu panadería",
|
||||||
|
"for_me": "Para Mí",
|
||||||
|
"for_me_description": "Alertas asignadas a ti o que requieren tu acción",
|
||||||
|
"archived": "Archivadas",
|
||||||
|
"archived_description": "Alertas resueltas y descartadas"
|
||||||
|
},
|
||||||
|
"toggle_filters": "Activar/desactivar filtros",
|
||||||
|
"filters": "Filtros",
|
||||||
|
"active": "Activos"
|
||||||
|
},
|
||||||
|
"auto_action": {
|
||||||
|
"title": "Acción Automática Pendiente",
|
||||||
|
"remaining": "restante",
|
||||||
|
"financial_impact": "Impacto:",
|
||||||
|
"cancel_button": "Cancelar Acción Automática",
|
||||||
|
"cancelling": "Cancelando...",
|
||||||
|
"cancelled_title": "Acción Automática Cancelada",
|
||||||
|
"cancelled_message": "La acción automática ha sido prevenida. Ahora puedes gestionarlo manualmente.",
|
||||||
|
"completed_title": "Acción Automática Ejecutada",
|
||||||
|
"help_text": "La IA ejecutará automáticamente esta acción cuando expire el temporizador. Haz clic en \"Cancelar\" para prevenirlo y gestionarlo manualmente.",
|
||||||
|
"urgency": {
|
||||||
|
"critical": "URGENTE",
|
||||||
|
"warning": "PRONTO",
|
||||||
|
"info": "PROGRAMADO"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority_explainer": {
|
||||||
|
"title": "Entendiendo las Puntuaciones de Prioridad",
|
||||||
|
"subtitle": "Cómo la IA calcula qué necesita tu atención primero",
|
||||||
|
"overview": {
|
||||||
|
"title": "La Puntuación de Prioridad (0-100)",
|
||||||
|
"description": "Cada alerta recibe una puntuación de prioridad de 0-100 basada en cuatro componentes ponderados. Esto te ayuda a enfocarte en lo que realmente importa para tu panadería."
|
||||||
|
},
|
||||||
|
"example_alert": "Prioridad de Alerta de Ejemplo",
|
||||||
|
"level": {
|
||||||
|
"critical": "CRÍTICO",
|
||||||
|
"important": "IMPORTANTE",
|
||||||
|
"standard": "ESTÁNDAR",
|
||||||
|
"info": "INFO"
|
||||||
|
},
|
||||||
|
"components_title": "Componentes de la Puntuación",
|
||||||
|
"weight": "peso",
|
||||||
|
"business_impact": {
|
||||||
|
"name": "Impacto Empresarial",
|
||||||
|
"description": "Consecuencias financieras, pedidos afectados, satisfacción del cliente",
|
||||||
|
"example1": "€500 en ingresos potenciales en riesgo",
|
||||||
|
"example2": "10 pedidos de clientes afectados",
|
||||||
|
"example3": "Alto impacto en la satisfacción del cliente"
|
||||||
|
},
|
||||||
|
"urgency": {
|
||||||
|
"name": "Urgencia",
|
||||||
|
"description": "Sensibilidad temporal, plazos, potencial de escalada",
|
||||||
|
"example1": "Plazo en 2 horas",
|
||||||
|
"example2": "Falta de stock inminente (4 horas)",
|
||||||
|
"example3": "Ventana de producción cerrándose pronto"
|
||||||
|
},
|
||||||
|
"agency": {
|
||||||
|
"name": "Capacidad de Acción del Usuario",
|
||||||
|
"description": "¿Puedes tomar acción? ¿Tienes control sobre el resultado?",
|
||||||
|
"example1": "Requiere tu aprobación",
|
||||||
|
"example2": "Acción con un clic disponible",
|
||||||
|
"example3": "Decisión necesaria dentro de tu autoridad"
|
||||||
|
},
|
||||||
|
"confidence": {
|
||||||
|
"name": "Confianza de la IA",
|
||||||
|
"description": "¿Qué tan segura está la IA sobre la validez de esta alerta?",
|
||||||
|
"example1": "Basado en patrones históricos (95% coincidencia)",
|
||||||
|
"example2": "Calidad de datos: Alta",
|
||||||
|
"example3": "Precisión de predicción validada"
|
||||||
|
},
|
||||||
|
"formula_title": "La Fórmula",
|
||||||
|
"footer": "Esta puntuación ayuda a la IA a priorizar alertas, asegurando que veas los problemas más importantes primero.",
|
||||||
|
"got_it": "¡Entendido!"
|
||||||
|
},
|
||||||
|
"trend": {
|
||||||
|
"near_threshold": "Cerca del umbral"
|
||||||
|
},
|
||||||
|
"action_preview": {
|
||||||
|
"title": "Vista Previa de Acción",
|
||||||
|
"outcome": "Qué sucederá",
|
||||||
|
"financial_impact": "Impacto Financiero",
|
||||||
|
"affected_systems": "Sistemas Afectados",
|
||||||
|
"reversible": "Esta acción se puede deshacer",
|
||||||
|
"not_reversible": "Esta acción no se puede deshacer",
|
||||||
|
"confidence": "Confianza de IA: {{confidence}}%",
|
||||||
|
"cancel": "Cancelar",
|
||||||
|
"confirm": "Confirmar Acción"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"title": "Rendimiento de Tiempo de Respuesta",
|
||||||
|
"subtitle": "Qué tan rápido respondes a las alertas",
|
||||||
|
"on_time": "A Tiempo",
|
||||||
|
"alerts": "alertas",
|
||||||
|
"average": "Promedio",
|
||||||
|
"target": "Objetivo",
|
||||||
|
"on_time_responses": "Respuestas a Tiempo",
|
||||||
|
"needs_improvement": "Necesita mejora",
|
||||||
|
"benchmark_title": "Perspectiva de Rendimiento",
|
||||||
|
"excellent": "¡Excelente! Estás respondiendo más rápido que el 80% de las panaderías. ¡Sigue así!",
|
||||||
|
"good": "¡Buen trabajo! Intenta responder a alertas críticas dentro del tiempo objetivo para mejorar aún más.",
|
||||||
|
"needs_work": "Respuestas más rápidas a alertas críticas pueden prevenir problemas y ahorrar dinero. Intenta cumplir los tiempos objetivo.",
|
||||||
|
"tip": "Consejo: Activa las notificaciones móviles para responder más rápido a alertas críticas"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"critical_stock_shortage": {
|
||||||
|
"title": "🚨 Stock Crítico: {{ingredient_name}}",
|
||||||
|
"message_with_po_pending": "Solo {{current_stock}}kg de {{ingredient_name}} (necesitas {{required_stock}}kg). Ya creé {{po_id}} para entrega el {{delivery_day_name}}. Por favor aprueba €{{po_amount}}.",
|
||||||
|
"message_with_po_created": "Solo {{current_stock}}kg de {{ingredient_name}} (necesitas {{required_stock}}kg). Ya creé {{po_id}}. Revisa y aprueba €{{po_amount}}.",
|
||||||
|
"message_with_hours": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg en {{hours_until}} horas).",
|
||||||
|
"message_with_date": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg para producción del {{production_day_name}}).",
|
||||||
|
"message_generic": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg)."
|
||||||
|
},
|
||||||
|
"low_stock": {
|
||||||
|
"title": "⚠️ Stock Bajo: {{ingredient_name}}",
|
||||||
|
"message_with_po": "Stock de {{ingredient_name}}: {{current_stock}}kg (mínimo: {{minimum_stock}}kg). Ya programé PO para reposición.",
|
||||||
|
"message_generic": "Stock de {{ingredient_name}}: {{current_stock}}kg (mínimo: {{minimum_stock}}kg). Considera hacer un pedido."
|
||||||
|
},
|
||||||
|
"stock_depleted": {
|
||||||
|
"title": "📦 Stock Agotado por Pedido",
|
||||||
|
"message_with_supplier": "Pedido #{{order_id}} requiere {{ingredient_name}} pero está agotado. Contacta a {{supplier_name}} ({{supplier_phone}}).",
|
||||||
|
"message_generic": "Pedido #{{order_id}} requiere {{ingredient_name}} pero está agotado. Acción inmediata requerida."
|
||||||
|
},
|
||||||
|
"ingredient_shortage": {
|
||||||
|
"title": "⚠️ Falta de Ingrediente en Producción",
|
||||||
|
"message_with_customers": "{{ingredient_name}} insuficiente para lotes en curso. {{affected_orders}} pedidos afectados ({{customer_names}}). Stock actual: {{current_stock}}kg, necesario: {{required_stock}}kg.",
|
||||||
|
"message_generic": "{{ingredient_name}} insuficiente para lotes en curso. Stock actual: {{current_stock}}kg, necesario: {{required_stock}}kg."
|
||||||
|
},
|
||||||
|
"expired_products": {
|
||||||
|
"title": "🚫 Productos Caducados o por Caducar",
|
||||||
|
"message_with_names": "{{count}} productos caducando: {{product_names}}. Valor total: €{{total_value}}.",
|
||||||
|
"message_generic": "{{count}} productos caducando. Valor total: €{{total_value}}."
|
||||||
|
},
|
||||||
|
"production_delay": {
|
||||||
|
"title": "⏰ Retraso en Producción: {{batch_name}}",
|
||||||
|
"message_with_customers": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. Clientes afectados: {{customer_names}}. Hora entrega original: {{scheduled_time}}.",
|
||||||
|
"message_with_orders": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. {{affected_orders}} pedidos afectados. Hora entrega original: {{scheduled_time}}.",
|
||||||
|
"message_generic": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. Hora entrega original: {{scheduled_time}}."
|
||||||
|
},
|
||||||
|
"equipment_failure": {
|
||||||
|
"title": "🔧 Fallo de Equipo: {{equipment_name}}",
|
||||||
|
"message_with_batches": "{{equipment_name}} falló. {{affected_batches}} lotes en producción afectados ({{batch_names}}).",
|
||||||
|
"message_generic": "{{equipment_name}} falló. Requiere reparación inmediata."
|
||||||
|
},
|
||||||
|
"maintenance_required": {
|
||||||
|
"title": "🔧 Mantenimiento Requerido: {{equipment_name}}",
|
||||||
|
"message_with_hours": "{{equipment_name}} requiere mantenimiento en {{hours_until}} horas. Programa ahora para evitar interrupciones.",
|
||||||
|
"message_with_days": "{{equipment_name}} requiere mantenimiento en {{days_until}} días. Programa antes del {{maintenance_date}}."
|
||||||
|
},
|
||||||
|
"low_equipment_efficiency": {
|
||||||
|
"title": "📉 Baja Eficiencia: {{equipment_name}}",
|
||||||
|
"message": "{{equipment_name}} operando a {{efficiency_percent}}% eficiencia (esperado: >{{threshold_percent}}%). Considera mantenimiento."
|
||||||
|
},
|
||||||
|
"order_overload": {
|
||||||
|
"title": "📊 Sobrecarga de Pedidos",
|
||||||
|
"message_with_orders": "Capacidad sobrecargada en {{overload_percent}}%. {{total_orders}} pedidos programados, capacidad: {{capacity_orders}}. Considera ajustar el calendario.",
|
||||||
|
"message_generic": "Capacidad sobrecargada en {{overload_percent}}%. Considera ajustar el calendario de producción."
|
||||||
|
},
|
||||||
|
"supplier_delay": {
|
||||||
|
"title": "🚚 Retraso de Proveedor: {{supplier_name}}",
|
||||||
|
"message": "{{supplier_name}} retrasó entrega de {{ingredient_name}} (PO: {{po_id}}). Nueva fecha: {{new_delivery_date}}. Original: {{original_delivery_date}}."
|
||||||
|
},
|
||||||
|
"temperature_breach": {
|
||||||
|
"title": "🌡️ Violación de Temperatura",
|
||||||
|
"message": "Temperatura {{location}}: {{current_temp}}°C (rango: {{min_temp}}°C-{{max_temp}}°C). Duración: {{duration_minutes}} minutos."
|
||||||
|
},
|
||||||
|
"demand_surge_weekend": {
|
||||||
|
"title": "📈 Aumento de Demanda: Fin de Semana",
|
||||||
|
"message": "Demanda esperada {{surge_percent}}% mayor para {{weekend_date}}. Productos afectados: {{products}}. Considera aumentar producción."
|
||||||
|
},
|
||||||
|
"weather_impact_alert": {
|
||||||
|
"title": "🌦️ Impacto Climático Esperado",
|
||||||
|
"message": "{{weather_condition}} esperado {{date}}. Impacto en demanda: {{impact_percent}}%. Productos afectados: {{products}}."
|
||||||
|
},
|
||||||
|
"holiday_preparation": {
|
||||||
|
"title": "🎉 Preparación para Festivo: {{holiday_name}}",
|
||||||
|
"message": "{{holiday_name}} en {{days_until}} días ({{holiday_date}}). Demanda esperada {{expected_increase}}% mayor. Productos clave: {{products}}."
|
||||||
|
},
|
||||||
|
"severe_weather_impact": {
|
||||||
|
"title": "⛈️ Impacto Climático Severo",
|
||||||
|
"message": "{{weather_condition}} severo esperado {{date}}. Impacto en demanda: {{impact_percent}}%. Considera ajustar horarios de entrega."
|
||||||
|
},
|
||||||
|
"unexpected_demand_spike": {
|
||||||
|
"title": "📊 Pico de Demanda Inesperado",
|
||||||
|
"message": "Demanda aumentó {{spike_percent}}% para {{products}}. Stock actual podría agotarse en {{hours_until_stockout}} horas."
|
||||||
|
},
|
||||||
|
"demand_pattern_optimization": {
|
||||||
|
"title": "💡 Optimización de Patrón de Demanda",
|
||||||
|
"message": "Patrón detectado: {{pattern_description}}. Recomienda ajustar producción de {{products}} para optimizar eficiencia."
|
||||||
|
},
|
||||||
|
"inventory_optimization": {
|
||||||
|
"title": "📦 Optimización de Inventario",
|
||||||
|
"message": "{{ingredient_name}} consistentemente sobre-stock por {{excess_percent}}%. Recomienda reducir pedido a {{recommended_amount}}kg."
|
||||||
|
},
|
||||||
|
"production_efficiency": {
|
||||||
|
"title": "⚡ Oportunidad de Eficiencia en Producción",
|
||||||
|
"message": "{{product_name}} más eficiente a las {{suggested_time}}. Tiempo de producción {{time_saved}} minutos menor ({{savings_percent}}% ahorro)."
|
||||||
|
},
|
||||||
|
"sales_opportunity": {
|
||||||
|
"title": "💰 Oportunidad de Ventas",
|
||||||
|
"message": "Alta demanda de {{products}} detectada. Considera producción adicional. Ingresos potenciales: €{{potential_revenue}}."
|
||||||
|
},
|
||||||
|
"seasonal_adjustment": {
|
||||||
|
"title": "🍂 Ajuste Estacional Recomendado",
|
||||||
|
"message": "Temporada {{season}} acercándose. Ajusta producción de {{products}} basado en tendencias históricas ({{adjustment_percent}}% {{adjustment_direction}})."
|
||||||
|
},
|
||||||
|
"cost_reduction": {
|
||||||
|
"title": "💵 Oportunidad de Reducción de Costos",
|
||||||
|
"message": "Cambiando a {{alternative_ingredient}} puede ahorrar €{{savings_amount}}/mes. Calidad similar, menor costo."
|
||||||
|
},
|
||||||
|
"waste_reduction": {
|
||||||
|
"title": "♻️ Oportunidad de Reducción de Desperdicio",
|
||||||
|
"message": "{{product_name}} desperdicio alto ({{waste_percent}}%). Recomienda reducir lote a {{recommended_quantity}} unidades."
|
||||||
|
},
|
||||||
|
"quality_improvement": {
|
||||||
|
"title": "⭐ Mejora de Calidad Recomendada",
|
||||||
|
"message": "{{issue_description}} detectado en {{product_name}}. Acción recomendada: {{recommended_action}}."
|
||||||
|
},
|
||||||
|
"customer_satisfaction": {
|
||||||
|
"title": "😊 Oportunidad de Satisfacción del Cliente",
|
||||||
|
"message": "Cliente {{customer_name}} consistentemente ordena {{product_name}}. Considera oferta especial o programa de lealtad."
|
||||||
|
},
|
||||||
|
"energy_optimization": {
|
||||||
|
"title": "⚡ Optimización de Energía",
|
||||||
|
"message": "Uso de energía para {{equipment_name}} pico a las {{peak_time}}. Cambiando a {{off_peak_start}}-{{off_peak_end}} puede ahorrar €{{savings_amount}}/mes."
|
||||||
|
},
|
||||||
|
"staff_optimization": {
|
||||||
|
"title": "👥 Optimización de Personal",
|
||||||
|
"message": "{{shift_name}} sobrestimado por {{excess_percent}}%. Considera ajustar niveles de personal para reducir costos laborales."
|
||||||
|
},
|
||||||
|
"po_approval_needed": {
|
||||||
|
"title": "Orden de Compra #{{po_number}} requiere aprobación",
|
||||||
|
"message": "Orden de compra para {{supplier_name}} por un total de {{currency}} {{total_amount}} pendiente de aprobación. Entrega requerida para {{required_delivery_date}}."
|
||||||
|
},
|
||||||
|
"production_batch_start": {
|
||||||
|
"title": "Lote de Producción Listo: {{product_name}}",
|
||||||
|
"message": "Lote #{{batch_number}} ({{quantity_planned}} {{unit}} de {{product_name}}) está listo para comenzar. Prioridad: {{priority}}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
297
frontend/src/locales/eu/alerts.json
Normal file
297
frontend/src/locales/eu/alerts.json
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
{
|
||||||
|
"priority": {
|
||||||
|
"critical": "Kritikoa",
|
||||||
|
"important": "Garrantzitsua",
|
||||||
|
"standard": "Estandarra",
|
||||||
|
"info": "Informazioa"
|
||||||
|
},
|
||||||
|
"type_class": {
|
||||||
|
"action_needed": "Ekintza Behar Da",
|
||||||
|
"prevented_issue": "Arazoa Saihestua",
|
||||||
|
"trend_warning": "Joera Abisua",
|
||||||
|
"escalation": "Eskalazio",
|
||||||
|
"information": "Informazioa"
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"already_addressed": "AIak dagoeneko kudeatu du hau",
|
||||||
|
"financial_impact": "€{amount} arriskuan",
|
||||||
|
"time_until": "Erabakia behar da {time}n",
|
||||||
|
"can_user_fix": "Konpon dezakezu hau",
|
||||||
|
"requires_supplier": "{supplier} behar da",
|
||||||
|
"prevented_savings": "Aurreztua €{amount}",
|
||||||
|
"grouped_count": "{count} bilduta"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"approve_po": "Onartu €{amount} eskaera",
|
||||||
|
"reject_po": "Baztertu eskaera",
|
||||||
|
"call_supplier": "Deitu {supplier}ri ({phone})",
|
||||||
|
"see_reasoning": "Ikusi arrazoibide osoa",
|
||||||
|
"complete_receipt": "Osatu stockaren harrera",
|
||||||
|
"mark_received": "Markatu jasota gisa",
|
||||||
|
"adjust_production": "Doitu ekoizpen egutegia",
|
||||||
|
"snooze": "Atzeratu {hours}h",
|
||||||
|
"mark_read": "Markatu irakurrita gisa",
|
||||||
|
"dismiss": "Baztertu",
|
||||||
|
"navigate": "Ikusi xehetasunak",
|
||||||
|
"notify_customer": "Jakinarazi {customer}ri",
|
||||||
|
"cancel_auto_action": "Ezeztatu ekintza automatikoa"
|
||||||
|
},
|
||||||
|
"orchestration": {
|
||||||
|
"reasoning_title": "🤖 Eguneko Orkestatzailearen Arrazoibidea",
|
||||||
|
"analyzed_title": "Goiz honetan, aztertu dut:",
|
||||||
|
"actions_taken": "Beraz, antolatu dut:",
|
||||||
|
"prevented_issues": "✅ Arazoak Saihestuta",
|
||||||
|
"estimated_impact": "Aurreikusitako Eragina",
|
||||||
|
"impact_description": "Aurrezkiak eskabide presagarriak, stock falta eta hondakinak saihestuz",
|
||||||
|
"last_run": "Azken exekuzioa",
|
||||||
|
"what_ai_did": "AIak zuretzat egin duena"
|
||||||
|
},
|
||||||
|
"metrics": {
|
||||||
|
"hours": "{count, plural, =1 {# ordu} other {# ordu}}",
|
||||||
|
"minutes": "{count, plural, =1 {# minutu} other {# minutu}}",
|
||||||
|
"days": "{count, plural, =1 {# egun} other {# egun}}"
|
||||||
|
},
|
||||||
|
"escalated": "Eskalatuta",
|
||||||
|
"hub": {
|
||||||
|
"tab_list_label": "Alerta kategoriak",
|
||||||
|
"tabs": {
|
||||||
|
"all": "Alerta Guztiak",
|
||||||
|
"all_description": "Zure ogi-dendan dauden alerta guztiak",
|
||||||
|
"for_me": "Niretzat",
|
||||||
|
"for_me_description": "Zuri esleitutako alertak edo zure ekintza behar dutenak",
|
||||||
|
"archived": "Artxibatuta",
|
||||||
|
"archived_description": "Konpondutako eta baztertutako alertak"
|
||||||
|
},
|
||||||
|
"toggle_filters": "Aktibatu/desaktibatu iragazkiak",
|
||||||
|
"filters": "Iragazkiak",
|
||||||
|
"active": "Aktiboak"
|
||||||
|
},
|
||||||
|
"auto_action": {
|
||||||
|
"title": "Ekintza Automatiko Zain",
|
||||||
|
"remaining": "geratzen da",
|
||||||
|
"financial_impact": "Eragina:",
|
||||||
|
"cancel_button": "Ezeztatu Ekintza Automatikoa",
|
||||||
|
"cancelling": "Ezeztatzen...",
|
||||||
|
"cancelled_title": "Ekintza Automatikoa Ezeztatuta",
|
||||||
|
"cancelled_message": "Ekintza automatikoa saihestu da. Orain eskuz kudea dezakezu.",
|
||||||
|
"completed_title": "Ekintza Automatikoa Exekutatuta",
|
||||||
|
"help_text": "AIak automatikoki exekutatuko du ekintza hau tenporizadorea amaitzen denean. Egin klik \"Ezeztatu\"n saihestu eta eskuz kudeatzeko.",
|
||||||
|
"urgency": {
|
||||||
|
"critical": "PRESAZKOA",
|
||||||
|
"warning": "LASTER",
|
||||||
|
"info": "PROGRAMATUTA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority_explainer": {
|
||||||
|
"title": "Lehentasun Puntuazioak Ulertzea",
|
||||||
|
"subtitle": "Nola kalkulatzen duen AIak zerk behar duen zure arreta lehenik",
|
||||||
|
"overview": {
|
||||||
|
"title": "Lehentasun Puntuazioa (0-100)",
|
||||||
|
"description": "Alerta bakoitzak 0-100 bitarteko lehentasun puntuazioa jasotzen du lau osagai ponderatuen arabera. Honek zure ogi-dendarako benetan garrantzitsua denean zentratzea laguntzen dizu."
|
||||||
|
},
|
||||||
|
"example_alert": "Alerta Adibidearen Lehentasuna",
|
||||||
|
"level": {
|
||||||
|
"critical": "KRITIKOA",
|
||||||
|
"important": "GARRANTZITSUA",
|
||||||
|
"standard": "ESTANDARRA",
|
||||||
|
"info": "INFORMAZIOA"
|
||||||
|
},
|
||||||
|
"components_title": "Puntuazioaren Osagaiak",
|
||||||
|
"weight": "pisua",
|
||||||
|
"business_impact": {
|
||||||
|
"name": "Negozio Eragina",
|
||||||
|
"description": "Finantza ondorioak, eskaerak eraginduta, bezeroaren gogobetetasuna",
|
||||||
|
"example1": "€500 sarrera potentzialean arriskuan",
|
||||||
|
"example2": "10 bezero eskabide eraginda",
|
||||||
|
"example3": "Bezeroaren gogobetetasunean eragin handia"
|
||||||
|
},
|
||||||
|
"urgency": {
|
||||||
|
"name": "Premura",
|
||||||
|
"description": "Denbora sentikortasuna, epe-mugak, eskalazio potentziala",
|
||||||
|
"example1": "Epe-muga 2 ordutan",
|
||||||
|
"example2": "Stock falta gertu (4 ordu)",
|
||||||
|
"example3": "Ekoizpen leihoa laster ixten"
|
||||||
|
},
|
||||||
|
"agency": {
|
||||||
|
"name": "Erabiltzailearen Ekintza Gaitasuna",
|
||||||
|
"description": "Ekintza har dezakezu? Emaitzaren gaineko kontrola duzu?",
|
||||||
|
"example1": "Zure onespena behar du",
|
||||||
|
"example2": "Klik bakarreko ekintza erabilgarri",
|
||||||
|
"example3": "Zure autoritatearen barruko erabakia behar da"
|
||||||
|
},
|
||||||
|
"confidence": {
|
||||||
|
"name": "AIaren Konfiantza",
|
||||||
|
"description": "Zenbat ziur dago AIa alerta honen baliozkotasunaz?",
|
||||||
|
"example1": "Historian oinarritutako patroietan (95% bat etortzea)",
|
||||||
|
"example2": "Datu kalitatea: Altua",
|
||||||
|
"example3": "Iragarpen zehaztasuna balioztatua"
|
||||||
|
},
|
||||||
|
"formula_title": "Formula",
|
||||||
|
"footer": "Puntuazio honek AIari alertak lehentasunez ipintzen laguntzen dio, garrantzitsuenak lehenik ikusten dituzula ziurtatuz.",
|
||||||
|
"got_it": "Ulertu dut!"
|
||||||
|
},
|
||||||
|
"trend": {
|
||||||
|
"near_threshold": "Atalasearen ondoan"
|
||||||
|
},
|
||||||
|
"action_preview": {
|
||||||
|
"title": "Ekintzaren Aurrebista",
|
||||||
|
"outcome": "Zer gertatuko da",
|
||||||
|
"financial_impact": "Finantza Eragina",
|
||||||
|
"affected_systems": "Sistema Eragindak",
|
||||||
|
"reversible": "Ekintza hau desegin daiteke",
|
||||||
|
"not_reversible": "Ekintza hau ezin da desegin",
|
||||||
|
"confidence": "AIaren Konfiantza: {{confidence}}%",
|
||||||
|
"cancel": "Ezeztatu",
|
||||||
|
"confirm": "Berretsi Ekintza"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"title": "Erantzun Denboraren Errendimendua",
|
||||||
|
"subtitle": "Zenbat azkar erantzuten diozun alertei",
|
||||||
|
"on_time": "Garaiz",
|
||||||
|
"alerts": "alertak",
|
||||||
|
"average": "Batez Bestekoa",
|
||||||
|
"target": "Helburua",
|
||||||
|
"on_time_responses": "Garaiz Erantzunak",
|
||||||
|
"needs_improvement": "Hobetzea behar du",
|
||||||
|
"benchmark_title": "Errendimenduaren Ikuspegia",
|
||||||
|
"excellent": "Bikaina! Ogi-denda %80 baino azkarrago erantzuten ari zara. Jarraitu horrela!",
|
||||||
|
"good": "Lan ona! Saiatu alerta kritikoei helburu denboran erantzuten gehiago hobetzeko.",
|
||||||
|
"needs_work": "Alerta kritikoei erantzun azkarragoak arazoak sahiestu eta dirua aurreztu dezakete. Saiatu helburu denborak betetzen.",
|
||||||
|
"tip": "Aholkua: Gaitu mugikorretako jakinarazpenak alerta kritikoei azkarrago erantzuteko"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"critical_stock_shortage": {
|
||||||
|
"title": "🚨 Stock Kritikoa: {{ingredient_name}}",
|
||||||
|
"message_with_po_pending": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik ({{required_stock}}kg behar dituzu). Dagoeneko {{po_id}} sortu dut {{delivery_day_name}}rako entregarako. Mesedez onartu €{{po_amount}}.",
|
||||||
|
"message_with_po_created": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik ({{required_stock}}kg behar dituzu). Dagoeneko {{po_id}} sortu dut. Berrikusi eta onartu €{{po_amount}}.",
|
||||||
|
"message_with_hours": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu {{hours_until}} ordutan).",
|
||||||
|
"message_with_date": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu {{production_day_name}}ko ekoizpenerako).",
|
||||||
|
"message_generic": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu)."
|
||||||
|
},
|
||||||
|
"low_stock": {
|
||||||
|
"title": "⚠️ Stock Baxua: {{ingredient_name}}",
|
||||||
|
"message_with_po": "{{ingredient_name}} stocka: {{current_stock}}kg (gutxienekoa: {{minimum_stock}}kg). Dagoeneko PO programatu dut osatzeko.",
|
||||||
|
"message_generic": "{{ingredient_name}} stocka: {{current_stock}}kg (gutxienekoa: {{minimum_stock}}kg). Eskaera egitea kontuan hartu."
|
||||||
|
},
|
||||||
|
"stock_depleted": {
|
||||||
|
"title": "📦 Eskaeragatik Stocka Agortu Da",
|
||||||
|
"message_with_supplier": "#{{order_id}} eskaerak {{ingredient_name}} behar du baina agortu da. Jarri harremanetan {{supplier_name}}rekin ({{supplier_phone}}).",
|
||||||
|
"message_generic": "#{{order_id}} eskaerak {{ingredient_name}} behar du baina agortu da. Berehala ekintza behar da."
|
||||||
|
},
|
||||||
|
"ingredient_shortage": {
|
||||||
|
"title": "⚠️ Osagaien Falta Ekoizpenean",
|
||||||
|
"message_with_customers": "{{ingredient_name}} nahikoa ez abian dauden loteentzat. {{affected_orders}} eskabide eraginda ({{customer_names}}). Oraingo stocka: {{current_stock}}kg, beharrezkoa: {{required_stock}}kg.",
|
||||||
|
"message_generic": "{{ingredient_name}} nahikoa ez abian dauden loteentzat. Oraingo stocka: {{current_stock}}kg, beharrezkoa: {{required_stock}}kg."
|
||||||
|
},
|
||||||
|
"expired_products": {
|
||||||
|
"title": "🚫 Iraungitako edo Iraungitzear Dauden Produktuak",
|
||||||
|
"message_with_names": "{{count}} produktu iraungitzen: {{product_names}}. Balio osoa: €{{total_value}}.",
|
||||||
|
"message_generic": "{{count}} produktu iraungitzen. Balio osoa: €{{total_value}}."
|
||||||
|
},
|
||||||
|
"production_delay": {
|
||||||
|
"title": "⏰ Ekoizpen Atzerapena: {{batch_name}}",
|
||||||
|
"message_with_customers": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. Bezeroak eraginda: {{customer_names}}. Jatorrizko entrega ordua: {{scheduled_time}}.",
|
||||||
|
"message_with_orders": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. {{affected_orders}} eskabide eraginda. Jatorrizko entrega ordua: {{scheduled_time}}.",
|
||||||
|
"message_generic": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. Jatorrizko entrega ordua: {{scheduled_time}}."
|
||||||
|
},
|
||||||
|
"equipment_failure": {
|
||||||
|
"title": "🔧 Ekipamendu Matxura: {{equipment_name}}",
|
||||||
|
"message_with_batches": "{{equipment_name}} huts egin du. {{affected_batches}} ekoizpeneko lote eraginda ({{batch_names}}).",
|
||||||
|
"message_generic": "{{equipment_name}} huts egin du. Berehala konponketa behar du."
|
||||||
|
},
|
||||||
|
"maintenance_required": {
|
||||||
|
"title": "🔧 Mantentze-lanak Behar Dira: {{equipment_name}}",
|
||||||
|
"message_with_hours": "{{equipment_name}}(e)k mantentze-lanak behar ditu {{hours_until}} ordutan. Programatu orain etetenak saihesteko.",
|
||||||
|
"message_with_days": "{{equipment_name}}(e)k mantentze-lanak behar ditu {{days_until}} egunetan. Programatu {{maintenance_date}} baino lehen."
|
||||||
|
},
|
||||||
|
"low_equipment_efficiency": {
|
||||||
|
"title": "📉 Eraginkortasun Baxua: {{equipment_name}}",
|
||||||
|
"message": "{{equipment_name}} %{{efficiency_percent}} eraginkortasunarekin funtzionatzen (esperoa: >{{threshold_percent}}%). Mantentze-lanak kontuan hartu."
|
||||||
|
},
|
||||||
|
"order_overload": {
|
||||||
|
"title": "📊 Eskabideen Gainzama",
|
||||||
|
"message_with_orders": "Gaitasuna %{{overload_percent}}z gainzamatuta. {{total_orders}} eskabide programatuta, gaitasuna: {{capacity_orders}}. Egutegia doitzea kontuan hartu.",
|
||||||
|
"message_generic": "Gaitasuna %{{overload_percent}}z gainzamatuta. Ekoizpen egutegia doitzea kontuan hartu."
|
||||||
|
},
|
||||||
|
"supplier_delay": {
|
||||||
|
"title": "🚚 Hornitzaile Atzerapena: {{supplier_name}}",
|
||||||
|
"message": "{{supplier_name}}(e)k {{ingredient_name}} entrega atzeratu du (PO: {{po_id}}). Data berria: {{new_delivery_date}}. Jatorrizkoa: {{original_delivery_date}}."
|
||||||
|
},
|
||||||
|
"temperature_breach": {
|
||||||
|
"title": "🌡️ Tenperatura Haustea",
|
||||||
|
"message": "Tenperatura {{location}}: {{current_temp}}°C (tartea: {{min_temp}}°C-{{max_temp}}°C). Iraupena: {{duration_minutes}} minutu."
|
||||||
|
},
|
||||||
|
"demand_surge_weekend": {
|
||||||
|
"title": "📈 Eskariaren Igoera: Asteburua",
|
||||||
|
"message": "Eskatutako eskaria %{{surge_percent}} handiagoa {{weekend_date}}rako. Produktu eragindak: {{products}}. Ekoizpena handitzea kontuan hartu."
|
||||||
|
},
|
||||||
|
"weather_impact_alert": {
|
||||||
|
"title": "🌦️ Espero den Eguraldiaren Eragina",
|
||||||
|
"message": "{{weather_condition}} esperotzen da {{date}}. Eskarian eragina: %{{impact_percent}}. Produktu eragindak: {{products}}."
|
||||||
|
},
|
||||||
|
"holiday_preparation": {
|
||||||
|
"title": "🎉 Jai Prestaketa: {{holiday_name}}",
|
||||||
|
"message": "{{holiday_name}} {{days_until}} egunetan ({{holiday_date}}). Eskatutako eskaria %{{expected_increase}} handiagoa. Funtsezko produktuak: {{products}}."
|
||||||
|
},
|
||||||
|
"severe_weather_impact": {
|
||||||
|
"title": "⛈️ Eguraldi Larriaren Eragina",
|
||||||
|
"message": "{{weather_condition}} larria esperotzen da {{date}}. Eskarian eragina: %{{impact_percent}}. Entrega ordutegiak doitzea kontuan hartu."
|
||||||
|
},
|
||||||
|
"unexpected_demand_spike": {
|
||||||
|
"title": "📊 Ustekabeko Eskariaren Igoera",
|
||||||
|
"message": "Eskaria %{{spike_percent}} igo da {{products}}entzat. Oraingo stocka agor daiteke {{hours_until_stockout}} ordutan."
|
||||||
|
},
|
||||||
|
"demand_pattern_optimization": {
|
||||||
|
"title": "💡 Eskari Ereduaren Optimizazioa",
|
||||||
|
"message": "Eredua detektatua: {{pattern_description}}. Gomendatzen da {{products}} ekoizpena doitzea eraginkortasuna optimizatzeko."
|
||||||
|
},
|
||||||
|
"inventory_optimization": {
|
||||||
|
"title": "📦 Inbentarioaren Optimizazioa",
|
||||||
|
"message": "{{ingredient_name}} etengabe gehiegizko stockarekin %{{excess_percent}}z. Gomendatzen da eskaera {{recommended_amount}}kg-ra murriztea."
|
||||||
|
},
|
||||||
|
"production_efficiency": {
|
||||||
|
"title": "⚡ Ekoizpen Eraginkortasunaren Aukera",
|
||||||
|
"message": "{{product_name}} eraginkorragoa da {{suggested_time}}etan. Ekoizpen denbora {{time_saved}} minutu laburragoa (%{{savings_percent}} aurrezkia)."
|
||||||
|
},
|
||||||
|
"sales_opportunity": {
|
||||||
|
"title": "💰 Salmenten Aukera",
|
||||||
|
"message": "{{products}}entzako eskari handia detektatuta. Ekoizpen gehigarria kontuan hartu. Sarrera potentziala: €{{potential_revenue}}."
|
||||||
|
},
|
||||||
|
"seasonal_adjustment": {
|
||||||
|
"title": "🍂 Sasoiko Doikuntza Gomendatua",
|
||||||
|
"message": "{{season}} sasoia hurbiltzen. Doitu {{products}} ekoizpena historia joerei oinarrituta (%{{adjustment_percent}} {{adjustment_direction}})."
|
||||||
|
},
|
||||||
|
"cost_reduction": {
|
||||||
|
"title": "💵 Kostu Murrizketa Aukera",
|
||||||
|
"message": "{{alternative_ingredient}}ra aldatzeak €{{savings_amount}}/hilabetean aurreztu dezake. Antzeko kalitatea, kostu txikiagoa."
|
||||||
|
},
|
||||||
|
"waste_reduction": {
|
||||||
|
"title": "♻️ Hondakin Murrizketa Aukera",
|
||||||
|
"message": "{{product_name}} hondakin handia (%{{waste_percent}}). Gomendatzen da lotea {{recommended_quantity}} unitatetara murriztea."
|
||||||
|
},
|
||||||
|
"quality_improvement": {
|
||||||
|
"title": "⭐ Kalitate Hobekuntza Gomendatua",
|
||||||
|
"message": "{{issue_description}} detektatuta {{product_name}}n. Gomendatutako ekintza: {{recommended_action}}."
|
||||||
|
},
|
||||||
|
"customer_satisfaction": {
|
||||||
|
"title": "😊 Bezeroaren Gogobetetasun Aukera",
|
||||||
|
"message": "{{customer_name}} bezeroak etengabe eskatzen du {{product_name}}. Eskaintza berezia edo leialtasun programa kontuan hartu."
|
||||||
|
},
|
||||||
|
"energy_optimization": {
|
||||||
|
"title": "⚡ Energia Optimizazioa",
|
||||||
|
"message": "{{equipment_name}}rako energia erabilera gailurra {{peak_time}}etan. {{off_peak_start}}-{{off_peak_end}}ra aldatzeak €{{savings_amount}}/hilabetean aurreztu dezake."
|
||||||
|
},
|
||||||
|
"staff_optimization": {
|
||||||
|
"title": "👥 Langile Optimizazioa",
|
||||||
|
"message": "{{shift_name}} langileak gehiegi %{{excess_percent}}z. Langile mailak doitzea kontuan hartu lan kostuak murrizteko."
|
||||||
|
},
|
||||||
|
"po_approval_needed": {
|
||||||
|
"title": "Erosketa Agindua #{{po_number}} onarpenaren beharra",
|
||||||
|
"message": "{{supplier_name}}-(r)entzako erosketa agindua {{currency}} {{total_amount}} onarpenaren zain. Entreaga {{required_delivery_date}}-(e)rako behar da."
|
||||||
|
},
|
||||||
|
"production_batch_start": {
|
||||||
|
"title": "Ekoizpen Lote Prest: {{product_name}}",
|
||||||
|
"message": "#{{batch_number}} lotea ({{quantity_planned}} {{unit}} {{product_name}}) hasteko prest. Lehentasuna: {{priority}}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user