Merge pull request #18 from ualsweb/claude/analyze-produccion-ui-ux-01EqW8hvN6ufZcMtqvuvzK9d
feat(analytics): Improve Production Analytics UI/UX and complete tran…
This commit is contained in:
@@ -131,11 +131,11 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
|
||||
const getTypeColor = (type: AIInsight['type']) => {
|
||||
switch (type) {
|
||||
case 'optimization': return 'text-green-600';
|
||||
case 'prediction': return 'text-blue-600';
|
||||
case 'anomaly': return 'text-red-600';
|
||||
case 'recommendation': return 'text-purple-600';
|
||||
default: return 'text-gray-600';
|
||||
case 'optimization': return 'text-[var(--color-success)]';
|
||||
case 'prediction': return 'text-[var(--color-info)]';
|
||||
case 'anomaly': return 'text-[var(--color-error)]';
|
||||
case 'recommendation': return 'text-[var(--color-secondary)]';
|
||||
default: return 'text-[var(--text-secondary)]';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -207,43 +207,43 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-5">
|
||||
{/* AI Insights Overview Stats */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<Brain className="w-8 h-8 mx-auto text-purple-600 mb-2" />
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)] hover:border-[var(--border-focus)] transition-colors">
|
||||
<Brain className="w-8 h-8 mx-auto text-[var(--color-secondary)] mb-2" />
|
||||
<p className="text-2xl font-bold text-[var(--text-primary)]">{activeInsights.length}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('ai.stats.active_insights')}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('ai.stats.active_insights')}</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<AlertTriangle className="w-8 h-8 mx-auto text-red-600 mb-2" />
|
||||
<p className="text-2xl font-bold text-[var(--text-primary)]">{highPriorityInsights.length}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('ai.stats.high_priority')}</p>
|
||||
<div className="text-center p-4 bg-[var(--color-error)]/10 rounded-lg border border-[var(--color-error)]/20 hover:border-[var(--color-error)]/40 transition-colors">
|
||||
<AlertTriangle className="w-8 h-8 mx-auto text-[var(--color-error)] mb-2" />
|
||||
<p className="text-2xl font-bold text-[var(--color-error)]">{highPriorityInsights.length}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('ai.stats.high_priority')}</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<div className="w-8 h-8 mx-auto bg-green-100 dark:bg-green-900/20 rounded-full flex items-center justify-center mb-2">
|
||||
<span className="text-green-600 font-bold text-sm">€</span>
|
||||
<div className="text-center p-4 bg-[var(--color-success)]/10 rounded-lg border border-[var(--color-success)]/20 hover:border-[var(--color-success)]/40 transition-colors">
|
||||
<div className="w-8 h-8 mx-auto bg-[var(--color-success)]/20 rounded-full flex items-center justify-center mb-2">
|
||||
<span className="text-[var(--color-success)] font-bold text-sm">€</span>
|
||||
</div>
|
||||
<p className="text-2xl font-bold text-[var(--text-primary)]">€{totalPotentialSavings}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('ai.stats.potential_savings')}</p>
|
||||
<p className="text-2xl font-bold text-[var(--color-success)]">€{totalPotentialSavings}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('ai.stats.potential_savings')}</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<div className="w-8 h-8 mx-auto bg-blue-100 dark:bg-blue-900/20 rounded-full flex items-center justify-center mb-2">
|
||||
<span className="text-blue-600 font-bold text-sm">%</span>
|
||||
<div className="text-center p-4 bg-[var(--color-info)]/10 rounded-lg border border-[var(--color-info)]/20 hover:border-[var(--color-info)]/40 transition-colors">
|
||||
<div className="w-8 h-8 mx-auto bg-[var(--color-info)]/20 rounded-full flex items-center justify-center mb-2">
|
||||
<span className="text-[var(--color-info)] font-bold text-sm">%</span>
|
||||
</div>
|
||||
<p className="text-2xl font-bold text-[var(--text-primary)]">{avgConfidence.toFixed(0)}%</p>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('ai.stats.avg_confidence')}</p>
|
||||
<p className="text-2xl font-bold text-[var(--color-info)]">{avgConfidence.toFixed(0)}%</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('ai.stats.avg_confidence')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI Status */}
|
||||
<div className="p-4 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<div className="p-4 bg-[var(--color-success)]/10 border border-[var(--color-success)]/20 rounded-lg">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
|
||||
<span className="text-sm font-medium text-green-600">
|
||||
<div className="w-2 h-2 bg-[var(--color-success)] rounded-full animate-pulse"></div>
|
||||
<span className="text-sm font-semibold text-[var(--color-success)]">
|
||||
{t('ai.status.active')}
|
||||
</span>
|
||||
<span className="text-xs text-[var(--text-secondary)] ml-2">
|
||||
<span className="text-xs text-[var(--text-secondary)] ml-2 font-medium">
|
||||
{t('ai.last_updated')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -252,8 +252,8 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
{/* High Priority Insights */}
|
||||
{highPriorityInsights.length > 0 && (
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-[var(--text-primary)] mb-3 flex items-center">
|
||||
<AlertTriangle className="w-4 h-4 mr-2 text-red-600" />
|
||||
<h4 className="text-sm font-semibold text-[var(--text-primary)] mb-3 flex items-center">
|
||||
<AlertTriangle className="w-4 h-4 mr-2 text-[var(--color-error)]" />
|
||||
{t('ai.high_priority_insights')} ({highPriorityInsights.length})
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
@@ -262,7 +262,7 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
const ImpactIcon = getImpactIcon(insight.impact.type);
|
||||
|
||||
return (
|
||||
<div key={insight.id} className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-red-200 dark:border-red-800">
|
||||
<div key={insight.id} className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--color-error)]/30 hover:border-[var(--color-error)]/50 transition-all duration-200">
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div className="flex items-start space-x-3">
|
||||
<TypeIcon className={`w-5 h-5 mt-1 ${getTypeColor(insight.type)}`} />
|
||||
@@ -287,14 +287,14 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Impact */}
|
||||
<div className="flex items-center justify-between p-3 bg-[var(--bg-tertiary)] rounded-lg">
|
||||
<div className="flex items-center justify-between p-3 bg-[var(--color-success)]/5 border border-[var(--color-success)]/10 rounded-lg">
|
||||
<div className="flex items-center space-x-2">
|
||||
<ImpactIcon className="w-4 h-4 text-[var(--color-primary)]" />
|
||||
<span className="text-sm font-medium text-[var(--text-primary)]">
|
||||
<span className="text-sm font-semibold text-[var(--text-primary)]">
|
||||
{t(`ai.impact.${insight.impact.type}`)}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-lg font-bold text-green-600">
|
||||
<span className="text-lg font-bold text-[var(--color-success)]">
|
||||
{formatImpactValue(insight.impact)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -318,17 +318,17 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
|
||||
{/* All Insights */}
|
||||
<div>
|
||||
<h4 className="text-sm font-medium text-[var(--text-primary)] mb-3 flex items-center">
|
||||
<Brain className="w-4 h-4 mr-2" />
|
||||
<h4 className="text-sm font-semibold text-[var(--text-primary)] mb-3 flex items-center">
|
||||
<Brain className="w-4 h-4 mr-2 text-[var(--color-secondary)]" />
|
||||
{t('ai.all_insights')} ({activeInsights.length})
|
||||
</h4>
|
||||
<div className="space-y-3 max-h-96 overflow-y-auto">
|
||||
<div className="space-y-2 max-h-96 overflow-y-auto pr-1">
|
||||
{activeInsights.map((insight) => {
|
||||
const TypeIcon = getTypeIcon(insight.type);
|
||||
const ImpactIcon = getImpactIcon(insight.impact.type);
|
||||
|
||||
return (
|
||||
<div key={insight.id} className="p-3 bg-[var(--bg-secondary)] rounded-lg hover:bg-[var(--bg-tertiary)] transition-colors">
|
||||
<div key={insight.id} className="p-3 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)] hover:border-[var(--border-focus)] hover:shadow-sm transition-all duration-200">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-3">
|
||||
<TypeIcon className={`w-4 h-4 ${getTypeColor(insight.type)}`} />
|
||||
@@ -362,16 +362,16 @@ export const AIInsightsWidget: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* AI Performance Summary */}
|
||||
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||
<div className="flex items-start space-x-2">
|
||||
<Brain className="w-5 h-5 text-blue-600 mt-0.5" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-blue-600">
|
||||
<div className="p-4 bg-[var(--color-info)]/10 border border-[var(--color-info)]/20 rounded-lg">
|
||||
<div className="flex items-start space-x-3">
|
||||
<Brain className="w-5 h-5 text-[var(--color-info)] mt-0.5" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-[var(--color-info)] mb-1">
|
||||
{t('ai.performance.summary')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] mt-1">
|
||||
{implementedInsights.length} {t('ai.performance.insights_implemented')},
|
||||
{totalPotentialSavings > 0 && ` €${totalPotentialSavings} ${t('ai.performance.in_savings_identified')}`}
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
{implementedInsights.length} {t('ai.performance.insights_implemented')}
|
||||
{totalPotentialSavings > 0 && `, €${totalPotentialSavings} ${t('ai.performance.in_savings_identified')}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Activity, Clock, AlertCircle, CheckCircle, Play, Pause } from 'lucide-react';
|
||||
import { Activity, Clock, AlertCircle, CheckCircle, Play, Pause, Zap } from 'lucide-react';
|
||||
import { AnalyticsWidget } from '../AnalyticsWidget';
|
||||
import { Badge, ProgressBar, Button } from '../../../../ui';
|
||||
import { useActiveBatches } from '../../../../../api/hooks/production';
|
||||
@@ -86,6 +86,19 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
return 'info';
|
||||
};
|
||||
|
||||
const getPriorityColor = (priority: string) => {
|
||||
switch (priority) {
|
||||
case 'URGENT':
|
||||
return 'text-[var(--color-error)]';
|
||||
case 'HIGH':
|
||||
return 'text-[var(--color-warning)]';
|
||||
case 'MEDIUM':
|
||||
return 'text-[var(--color-info)]';
|
||||
default:
|
||||
return 'text-[var(--text-secondary)]';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AnalyticsWidget
|
||||
title={t('tracker.live_batch_tracker')}
|
||||
@@ -110,7 +123,7 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
<p className="text-sm">{t('messages.no_active_batches_description')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3 max-h-96 overflow-y-auto">
|
||||
<div className="space-y-3 max-h-96 overflow-y-auto pr-1">
|
||||
{batches.map((batch) => {
|
||||
const StatusIcon = getStatusIcon(batch.status);
|
||||
const progress = calculateProgress(batch);
|
||||
@@ -119,16 +132,16 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
return (
|
||||
<div
|
||||
key={batch.id}
|
||||
className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)] hover:shadow-md transition-all"
|
||||
className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)] hover:border-[var(--border-focus)] hover:shadow-md transition-all duration-200"
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div className="flex items-start space-x-3 flex-1">
|
||||
<div className="w-8 h-8 bg-[var(--color-primary)]/10 rounded-lg flex items-center justify-center mt-0.5">
|
||||
<div className="w-8 h-8 bg-[var(--color-primary)]/10 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||
<StatusIcon className="w-4 h-4 text-[var(--color-primary)]" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className="font-semibold text-[var(--text-primary)] mb-1">
|
||||
<h4 className="font-semibold text-[var(--text-primary)] mb-1 truncate">
|
||||
{batch.product_name}
|
||||
</h4>
|
||||
<p className="text-sm text-[var(--text-secondary)] mb-1">
|
||||
@@ -144,7 +157,7 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Badge variant={getStatusBadgeVariant(batch.status)}>
|
||||
<Badge variant={getStatusBadgeVariant(batch.status)} className="flex-shrink-0">
|
||||
{t(`status.${batch.status.toLowerCase()}`)}
|
||||
</Badge>
|
||||
</div>
|
||||
@@ -152,11 +165,11 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
{/* Progress Bar */}
|
||||
{batch.status !== ProductionStatus.PENDING && (
|
||||
<div className="mb-3">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span className="text-xs text-[var(--text-secondary)]">
|
||||
<div className="flex items-center justify-between mb-1.5">
|
||||
<span className="text-xs font-medium text-[var(--text-secondary)]">
|
||||
{t('tracker.progress')}
|
||||
</span>
|
||||
<span className="text-xs font-medium text-[var(--text-primary)]">
|
||||
<span className="text-xs font-semibold text-[var(--text-primary)]">
|
||||
{progress}%
|
||||
</span>
|
||||
</div>
|
||||
@@ -169,33 +182,29 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
)}
|
||||
|
||||
{/* Details */}
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="flex items-center justify-between text-xs flex-wrap gap-2">
|
||||
<div className="flex items-center space-x-3">
|
||||
{batch.priority && (
|
||||
<span className={`font-medium ${
|
||||
batch.priority === 'URGENT' ? 'text-red-600' :
|
||||
batch.priority === 'HIGH' ? 'text-orange-600' :
|
||||
batch.priority === 'MEDIUM' ? 'text-blue-600' :
|
||||
'text-gray-600'
|
||||
}`}>
|
||||
<span className={`font-semibold ${getPriorityColor(batch.priority)}`}>
|
||||
{t(`priority.${batch.priority.toLowerCase()}`)}
|
||||
</span>
|
||||
)}
|
||||
{batch.is_rush_order && (
|
||||
<span className="text-red-600 font-medium">
|
||||
<span className="text-[var(--color-error)] font-semibold flex items-center">
|
||||
<Zap className="w-3 h-3 mr-1" />
|
||||
{t('batch.rush_order')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center space-x-1 text-[var(--text-secondary)]">
|
||||
<Clock className="w-3 h-3" />
|
||||
<div className="flex items-center space-x-1.5 text-[var(--text-secondary)]">
|
||||
<Clock className="w-3.5 h-3.5" />
|
||||
<span>
|
||||
{eta ? (
|
||||
<span className={eta.includes('delayed') ? 'text-red-600' : ''}>
|
||||
<span className={eta.includes('delayed') ? 'text-[var(--color-error)] font-medium' : 'font-medium'}>
|
||||
ETA: {eta}
|
||||
</span>
|
||||
) : (
|
||||
t('tracker.pending_start')
|
||||
<span className="font-medium">{t('tracker.pending_start')}</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -203,15 +212,19 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
|
||||
{/* Equipment & Staff */}
|
||||
{(batch.equipment_used?.length > 0 || batch.staff_assigned?.length > 0) && (
|
||||
<div className="mt-2 pt-2 border-t border-[var(--border-primary)] text-xs text-[var(--text-tertiary)]">
|
||||
<div className="mt-3 pt-3 border-t border-[var(--border-secondary)] text-xs">
|
||||
{batch.equipment_used?.length > 0 && (
|
||||
<div className="mb-1">
|
||||
{t('batch.equipment')}: {batch.equipment_used.join(', ')}
|
||||
<div className="mb-1.5 flex items-start">
|
||||
<span className="text-[var(--text-secondary)] font-medium mr-2">{t('batch.equipment')}:</span>
|
||||
<span className="text-[var(--text-tertiary)] flex-1">{batch.equipment_used.join(', ')}</span>
|
||||
</div>
|
||||
)}
|
||||
{batch.staff_assigned?.length > 0 && (
|
||||
<div>
|
||||
{t('batch.staff')}: {batch.staff_assigned.length} {t('common.assigned')}
|
||||
<div className="flex items-center">
|
||||
<span className="text-[var(--text-secondary)] font-medium mr-2">{t('batch.staff')}:</span>
|
||||
<span className="text-[var(--text-tertiary)]">
|
||||
{batch.staff_assigned.length} {t('common.assigned')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -224,31 +237,31 @@ export const LiveBatchTrackerWidget: React.FC = () => {
|
||||
|
||||
{/* Summary */}
|
||||
{batches.length > 0 && (
|
||||
<div className="pt-3 border-t border-[var(--border-primary)]">
|
||||
<div className="grid grid-cols-4 gap-4 text-center text-xs">
|
||||
<div>
|
||||
<p className="font-medium text-green-600">
|
||||
<div className="pt-4 mt-2 border-t border-[var(--border-primary)]">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3 text-center text-xs">
|
||||
<div className="p-3 bg-[var(--color-success)]/10 rounded-lg border border-[var(--color-success)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-success)] mb-1">
|
||||
{batches.filter(b => b.status === ProductionStatus.COMPLETED).length}
|
||||
</p>
|
||||
<p className="text-[var(--text-tertiary)]">{t('status.completed')}</p>
|
||||
<p className="text-[var(--text-secondary)] font-medium">{t('status.completed')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-blue-600">
|
||||
<div className="p-3 bg-[var(--color-info)]/10 rounded-lg border border-[var(--color-info)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-info)] mb-1">
|
||||
{batches.filter(b => b.status === ProductionStatus.IN_PROGRESS).length}
|
||||
</p>
|
||||
<p className="text-[var(--text-tertiary)]">{t('status.in_progress')}</p>
|
||||
<p className="text-[var(--text-secondary)] font-medium">{t('status.in_progress')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-orange-600">
|
||||
<div className="p-3 bg-[var(--color-warning)]/10 rounded-lg border border-[var(--color-warning)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-warning)] mb-1">
|
||||
{batches.filter(b => b.status === ProductionStatus.PENDING).length}
|
||||
</p>
|
||||
<p className="text-[var(--text-tertiary)]">{t('status.pending')}</p>
|
||||
<p className="text-[var(--text-secondary)] font-medium">{t('status.pending')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-red-600">
|
||||
<div className="p-3 bg-[var(--color-error)]/10 rounded-lg border border-[var(--color-error)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-error)] mb-1">
|
||||
{batches.filter(b => [ProductionStatus.FAILED, ProductionStatus.CANCELLED].includes(b.status)).length}
|
||||
</p>
|
||||
<p className="text-[var(--text-tertiary)]">{t('tracker.issues')}</p>
|
||||
<p className="text-[var(--text-secondary)] font-medium">{t('tracker.issues')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -61,7 +61,7 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
id: 'quality-trend',
|
||||
name: t('quality.daily_quality_score'),
|
||||
type: 'line',
|
||||
color: '#16a34a',
|
||||
color: 'var(--color-success)',
|
||||
data: scores
|
||||
}
|
||||
];
|
||||
@@ -83,7 +83,7 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
id: 'quality-distribution',
|
||||
name: t('quality.score_distribution'),
|
||||
type: 'bar',
|
||||
color: '#d97706',
|
||||
color: 'var(--color-primary)',
|
||||
data: distribution.map(item => ({
|
||||
x: item.range,
|
||||
y: item.count,
|
||||
@@ -94,17 +94,17 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
};
|
||||
|
||||
const getScoreColor = (score: number) => {
|
||||
if (score >= 9) return 'text-green-600';
|
||||
if (score >= 8) return 'text-blue-600';
|
||||
if (score >= 7) return 'text-orange-600';
|
||||
return 'text-red-600';
|
||||
if (score >= 9) return 'text-[var(--color-success)]';
|
||||
if (score >= 8) return 'text-[var(--color-info)]';
|
||||
if (score >= 7) return 'text-[var(--color-warning)]';
|
||||
return 'text-[var(--color-error)]';
|
||||
};
|
||||
|
||||
const getScoreStatus = (score: number) => {
|
||||
if (score >= 9) return { status: 'excellent', bgColor: 'bg-green-100 dark:bg-green-900/20' };
|
||||
if (score >= 8) return { status: 'good', bgColor: 'bg-blue-100 dark:bg-blue-900/20' };
|
||||
if (score >= 7) return { status: 'acceptable', bgColor: 'bg-orange-100 dark:bg-orange-900/20' };
|
||||
return { status: 'needs_improvement', bgColor: 'bg-red-100 dark:bg-red-900/20' };
|
||||
if (score >= 9) return { status: 'excellent', bgColor: 'bg-[var(--color-success)]/10 border border-[var(--color-success)]/20' };
|
||||
if (score >= 8) return { status: 'good', bgColor: 'bg-[var(--color-info)]/10 border border-[var(--color-info)]/20' };
|
||||
if (score >= 7) return { status: 'acceptable', bgColor: 'bg-[var(--color-warning)]/10 border border-[var(--color-warning)]/20' };
|
||||
return { status: 'needs_improvement', bgColor: 'bg-[var(--color-error)]/10 border border-[var(--color-error)]/20' };
|
||||
};
|
||||
|
||||
const scoreStatus = getScoreStatus(qualityData.averageScore);
|
||||
@@ -124,23 +124,24 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-5">
|
||||
{/* Quality Score Display */}
|
||||
<div className="text-center">
|
||||
<div className="flex items-center justify-center space-x-2 mb-2">
|
||||
<Star className={`w-6 h-6 ${getScoreColor(qualityData.averageScore)}`} />
|
||||
<span className="text-3xl font-bold text-[var(--text-primary)]">
|
||||
{qualityData.averageScore.toFixed(1)}/10
|
||||
<div className="text-center p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)]">
|
||||
<div className="flex items-center justify-center space-x-3 mb-3">
|
||||
<Star className={`w-8 h-8 fill-current ${getScoreColor(qualityData.averageScore)}`} />
|
||||
<span className="text-4xl font-bold text-[var(--text-primary)]">
|
||||
{qualityData.averageScore.toFixed(1)}
|
||||
</span>
|
||||
<span className="text-xl text-[var(--text-secondary)] font-medium">/10</span>
|
||||
</div>
|
||||
<div className={`inline-flex items-center space-x-2 px-3 py-1 rounded-full text-sm ${scoreStatus.bgColor}`}>
|
||||
<div className={`inline-flex items-center space-x-2 px-4 py-1.5 rounded-full text-sm font-medium ${scoreStatus.bgColor}`}>
|
||||
<span className={getScoreColor(qualityData.averageScore)}>
|
||||
{t(`quality.${scoreStatus.status}`)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-center space-x-1 mt-2">
|
||||
<TrendIcon className={`w-4 h-4 ${qualityData.trend >= 0 ? 'text-green-600' : 'text-red-600'}`} />
|
||||
<span className={`text-sm ${qualityData.trend >= 0 ? 'text-green-600' : 'text-red-600'}`}>
|
||||
<div className="flex items-center justify-center space-x-1.5 mt-3 pt-3 border-t border-[var(--border-secondary)]">
|
||||
<TrendIcon className={`w-4 h-4 ${qualityData.trend >= 0 ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'}`} />
|
||||
<span className={`text-sm font-semibold ${qualityData.trend >= 0 ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'}`}>
|
||||
{qualityData.trend > 0 ? '+' : ''}{qualityData.trend.toFixed(1)} {t('quality.vs_last_week')}
|
||||
</span>
|
||||
</div>
|
||||
@@ -148,17 +149,17 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
|
||||
{/* Key Metrics */}
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="p-4 bg-[var(--bg-secondary)] rounded-lg text-center">
|
||||
<div className="text-2xl font-bold text-[var(--text-primary)] mb-1">
|
||||
<div className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-primary)] text-center hover:border-[var(--border-focus)] transition-colors">
|
||||
<div className="text-3xl font-bold text-[var(--text-primary)] mb-1">
|
||||
{qualityData.totalChecks}
|
||||
</div>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('stats.total_checks')}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('stats.total_checks')}</p>
|
||||
</div>
|
||||
<div className="p-4 bg-[var(--bg-secondary)] rounded-lg text-center">
|
||||
<div className="text-2xl font-bold text-green-600 mb-1">
|
||||
<div className="p-4 bg-[var(--color-success)]/10 rounded-lg border border-[var(--color-success)]/20 text-center hover:border-[var(--color-success)]/40 transition-colors">
|
||||
<div className="text-3xl font-bold text-[var(--color-success)] mb-1">
|
||||
{qualityData.passRate.toFixed(1)}%
|
||||
</div>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{t('stats.pass_rate')}</p>
|
||||
<p className="text-sm text-[var(--text-secondary)] font-medium">{t('stats.pass_rate')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -197,36 +198,36 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
|
||||
{/* Quality Insights */}
|
||||
<div className="grid grid-cols-3 gap-3 text-center">
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<p className="text-lg font-bold text-green-600">
|
||||
<div className="p-3 bg-[var(--color-success)]/10 rounded-lg border border-[var(--color-success)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-success)] mb-1">
|
||||
{Math.round(qualityData.totalChecks * 0.35)}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('quality.excellent_scores')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('quality.excellent_scores')}</p>
|
||||
</div>
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<p className="text-lg font-bold text-blue-600">
|
||||
<div className="p-3 bg-[var(--color-info)]/10 rounded-lg border border-[var(--color-info)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-info)] mb-1">
|
||||
{Math.round(qualityData.totalChecks * 0.30)}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('quality.good_scores')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('quality.good_scores')}</p>
|
||||
</div>
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg">
|
||||
<p className="text-lg font-bold text-red-600">
|
||||
<div className="p-3 bg-[var(--color-error)]/10 rounded-lg border border-[var(--color-error)]/20">
|
||||
<p className="text-2xl font-bold text-[var(--color-error)] mb-1">
|
||||
{Math.round(qualityData.totalChecks * 0.15)}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('quality.needs_improvement')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('quality.needs_improvement')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quality Recommendations */}
|
||||
{qualityData.averageScore < 8 && (
|
||||
<div className="p-3 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
|
||||
<div className="flex items-start space-x-2">
|
||||
<Star className="w-4 h-4 mt-0.5 text-orange-600" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-orange-600">
|
||||
<div className="p-4 bg-[var(--color-warning)]/10 border border-[var(--color-warning)]/20 rounded-lg">
|
||||
<div className="flex items-start space-x-3">
|
||||
<Star className="w-5 h-5 mt-0.5 text-[var(--color-warning)]" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-[var(--color-warning)] mb-1">
|
||||
{t('quality.recommendations.improve_quality')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] mt-1">
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
{t('quality.recommendations.focus_consistency')}
|
||||
</p>
|
||||
</div>
|
||||
@@ -235,14 +236,14 @@ export const QualityScoreTrendsWidget: React.FC = () => {
|
||||
)}
|
||||
|
||||
{qualityData.averageScore >= 9 && (
|
||||
<div className="p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<div className="flex items-start space-x-2">
|
||||
<Award className="w-4 h-4 mt-0.5 text-green-600" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-green-600">
|
||||
<div className="p-4 bg-[var(--color-success)]/10 border border-[var(--color-success)]/20 rounded-lg">
|
||||
<div className="flex items-start space-x-3">
|
||||
<Award className="w-5 h-5 mt-0.5 text-[var(--color-success)]" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-[var(--color-success)] mb-1">
|
||||
{t('quality.recommendations.excellent_quality')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] mt-1">
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
{t('quality.recommendations.maintain_standards')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -154,10 +154,10 @@ export const WasteDefectTrackerWidget: React.FC = () => {
|
||||
|
||||
const getWasteStatus = () => {
|
||||
const totalWastePercentage = wasteData.wastePercentage + wasteData.defectPercentage;
|
||||
if (totalWastePercentage <= 3) return { status: 'excellent', color: 'text-green-600', bgColor: 'bg-green-100 dark:bg-green-900/20' };
|
||||
if (totalWastePercentage <= 5) return { status: 'good', color: 'text-blue-600', bgColor: 'bg-blue-100 dark:bg-blue-900/20' };
|
||||
if (totalWastePercentage <= 8) return { status: 'warning', color: 'text-orange-600', bgColor: 'bg-orange-100 dark:bg-orange-900/20' };
|
||||
return { status: 'critical', color: 'text-red-600', bgColor: 'bg-red-100 dark:bg-red-900/20' };
|
||||
if (totalWastePercentage <= 3) return { status: 'excellent', color: 'text-[var(--color-success)]', bgColor: 'bg-[var(--color-success)]/10 border border-[var(--color-success)]/20' };
|
||||
if (totalWastePercentage <= 5) return { status: 'good', color: 'text-[var(--color-info)]', bgColor: 'bg-[var(--color-info)]/10 border border-[var(--color-info)]/20' };
|
||||
if (totalWastePercentage <= 8) return { status: 'warning', color: 'text-[var(--color-warning)]', bgColor: 'bg-[var(--color-warning)]/10 border border-[var(--color-warning)]/20' };
|
||||
return { status: 'critical', color: 'text-[var(--color-error)]', bgColor: 'bg-[var(--color-error)]/10 border border-[var(--color-error)]/20' };
|
||||
};
|
||||
|
||||
const wasteStatus = getWasteStatus();
|
||||
@@ -177,43 +177,43 @@ export const WasteDefectTrackerWidget: React.FC = () => {
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-5">
|
||||
{/* Overall Waste Metrics */}
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg text-center">
|
||||
<div className="p-4 bg-[var(--color-error)]/10 border border-[var(--color-error)]/20 rounded-lg text-center hover:border-[var(--color-error)]/40 transition-colors">
|
||||
<div className="flex items-center justify-center space-x-2 mb-1">
|
||||
<Trash2 className="w-4 h-4 text-red-600" />
|
||||
<span className="text-lg font-bold text-[var(--text-primary)]">
|
||||
<Trash2 className="w-5 h-5 text-[var(--color-error)]" />
|
||||
<span className="text-2xl font-bold text-[var(--color-error)]">
|
||||
{totalWastePercentage.toFixed(1)}%
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('quality.total_waste')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('quality.total_waste')}</p>
|
||||
</div>
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg text-center">
|
||||
<div className="p-4 bg-[var(--color-warning)]/10 border border-[var(--color-warning)]/20 rounded-lg text-center hover:border-[var(--color-warning)]/40 transition-colors">
|
||||
<div className="flex items-center justify-center space-x-2 mb-1">
|
||||
<AlertTriangle className="w-4 h-4 text-orange-600" />
|
||||
<span className="text-lg font-bold text-[var(--text-primary)]">
|
||||
<AlertTriangle className="w-5 h-5 text-[var(--color-warning)]" />
|
||||
<span className="text-2xl font-bold text-[var(--color-warning)]">
|
||||
{wasteData.totalDefects}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('quality.total_defects')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('quality.total_defects')}</p>
|
||||
</div>
|
||||
<div className="p-3 bg-[var(--bg-secondary)] rounded-lg text-center">
|
||||
<div className="p-4 bg-[var(--color-success)]/10 border border-[var(--color-success)]/20 rounded-lg text-center hover:border-[var(--color-success)]/40 transition-colors">
|
||||
<div className="flex items-center justify-center space-x-2 mb-1">
|
||||
<TrendingDown className="w-4 h-4 text-green-600" />
|
||||
<span className="text-lg font-bold text-[var(--text-primary)]">
|
||||
<TrendingDown className="w-5 h-5 text-[var(--color-success)]" />
|
||||
<span className="text-2xl font-bold text-[var(--color-success)]">
|
||||
€{totalWasteCost.toFixed(0)}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-[var(--text-secondary)]">{t('cost.waste_cost')}</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] font-medium">{t('cost.waste_cost')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Waste Status */}
|
||||
<div className={`p-3 rounded-lg ${wasteStatus.bgColor}`}>
|
||||
<div className={`p-4 rounded-lg ${wasteStatus.bgColor}`}>
|
||||
<div className="flex items-center space-x-2">
|
||||
<AlertTriangle className={`w-4 h-4 ${wasteStatus.color}`} />
|
||||
<span className={`text-sm font-medium ${wasteStatus.color}`}>
|
||||
<AlertTriangle className={`w-5 h-5 ${wasteStatus.color}`} />
|
||||
<span className={`text-sm font-semibold ${wasteStatus.color}`}>
|
||||
{t(`quality.status.${wasteStatus.status}`)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -285,28 +285,28 @@ export const WasteDefectTrackerWidget: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Reduction Recommendations */}
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-3">
|
||||
{wasteSources.filter(s => s.severity === 'high').length > 0 && (
|
||||
<div className="flex items-start space-x-2 p-3 bg-red-50 dark:bg-red-900/20 rounded-lg">
|
||||
<AlertTriangle className="w-4 h-4 mt-0.5 text-red-600" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-red-600">
|
||||
<div className="flex items-start space-x-3 p-4 bg-[var(--color-error)]/10 border border-[var(--color-error)]/20 rounded-lg">
|
||||
<AlertTriangle className="w-5 h-5 mt-0.5 text-[var(--color-error)]" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-[var(--color-error)] mb-1">
|
||||
{t('quality.recommendations.high_waste_detected')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] mt-1">
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
{t('quality.recommendations.check_temperature_timing')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-start space-x-2 p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||
<Target className="w-4 h-4 mt-0.5 text-blue-600" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-blue-600">
|
||||
<div className="flex items-start space-x-3 p-4 bg-[var(--color-info)]/10 border border-[var(--color-info)]/20 rounded-lg">
|
||||
<Target className="w-5 h-5 mt-0.5 text-[var(--color-info)]" />
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-[var(--color-info)] mb-1">
|
||||
{t('quality.recommendations.improvement_opportunity')}
|
||||
</p>
|
||||
<p className="text-xs text-[var(--text-secondary)] mt-1">
|
||||
<p className="text-xs text-[var(--text-secondary)]">
|
||||
{totalWastePercentage > 5
|
||||
? t('quality.recommendations.reduce_waste_target', { target: '3%' })
|
||||
: t('quality.recommendations.maintain_quality_standards')
|
||||
|
||||
@@ -1,88 +1,99 @@
|
||||
{
|
||||
"title": "Ekoizpena",
|
||||
"subtitle": "Kudeatu zure ogindegiko ekoizpena",
|
||||
"production_status": {
|
||||
"PENDING": "Itxaroten",
|
||||
"IN_PROGRESS": "Abian",
|
||||
"COMPLETED": "Osatuta",
|
||||
"CANCELLED": "Ezeztatuta",
|
||||
"ON_HOLD": "Pausatuta",
|
||||
"QUALITY_CHECK": "Kalitate-kontrola",
|
||||
"FAILED": "Huts egin du"
|
||||
},
|
||||
"production_priority": {
|
||||
"LOW": "Baxua",
|
||||
"MEDIUM": "Ertaina",
|
||||
"HIGH": "Altua",
|
||||
"URGENT": "Larria"
|
||||
},
|
||||
"batch_status": {
|
||||
"PLANNED": "Planifikatuta",
|
||||
"IN_PROGRESS": "Abian",
|
||||
"COMPLETED": "Osatuta",
|
||||
"CANCELLED": "Ezeztatuta",
|
||||
"ON_HOLD": "Pausatuta"
|
||||
},
|
||||
"quality_check_status": {
|
||||
"PENDING": "Itxaroten",
|
||||
"IN_PROGRESS": "Abian",
|
||||
"PASSED": "Gaindituta",
|
||||
"FAILED": "Huts egin du",
|
||||
"REQUIRES_ATTENTION": "Arreta behar du"
|
||||
},
|
||||
"fields": {
|
||||
"batch_number": "Sorta-zenbakia",
|
||||
"production_date": "Ekoizpen-data",
|
||||
"planned_quantity": "Planifikatutako kantitatea",
|
||||
"actual_quantity": "Benetako kantitatea",
|
||||
"yield_percentage": "Errendimendu-ehunekoa",
|
||||
"priority": "Lehentasuna",
|
||||
"assigned_staff": "Esleitutako langilea",
|
||||
"production_notes": "Ekoizpen-oharrak",
|
||||
"quality_score": "Kalitate-puntua",
|
||||
"quality_notes": "Kalitate-oharrak",
|
||||
"defect_rate": "Akats-tasa",
|
||||
"rework_required": "Berregitea behar da",
|
||||
"waste_quantity": "Hondakin-kantitatea",
|
||||
"waste_reason": "Hondakinaren arrazoia",
|
||||
"title": "Ekoizpen Kudeaketa",
|
||||
"subtitle": "Planifikatu eta kontrolatu okindegiaren eguneroko ekoizpena",
|
||||
"stats": {
|
||||
"active_batches": "Sorta Aktiboak",
|
||||
"todays_target": "Gaurko Helburua",
|
||||
"capacity_utilization": "Ahalmen Erabilpena",
|
||||
"on_time_completion": "Orduan Bukatuta",
|
||||
"quality_score": "Kalitate Puntuazioa",
|
||||
"total_output": "Ekoizpen Osoa",
|
||||
"efficiency": "Eraginkortasuna",
|
||||
"material_cost": "Material-kostua",
|
||||
"labor_cost": "Lan-kostua",
|
||||
"overhead_cost": "Indirektoko kostua",
|
||||
"total_cost": "Kostu osoa",
|
||||
"cost_per_unit": "Unitateko kostua"
|
||||
"total_checks": "Kontrol Osoak",
|
||||
"pass_rate": "Gainditu Tasa",
|
||||
"average_score": "Batez Besteko Puntuazioa",
|
||||
"failed_checks": "Huts Egindako Kontrolak",
|
||||
"last_7_days": "Azken 7 egunak",
|
||||
"passed": "gaindituta",
|
||||
"out_of_10": "10etik",
|
||||
"requiring_action": "Ekintza behar du",
|
||||
"checks": "kontrolak",
|
||||
"avg_score": "batez besteko puntuazioa",
|
||||
"top_defects": "akats nagusiak",
|
||||
"issues": "arazoak",
|
||||
"defects": "akatsak",
|
||||
"overall_efficiency": "Eraginkortasun Orokorra",
|
||||
"vs_target_95": "vs %95 helburua",
|
||||
"average_cost_per_unit": "Batez Besteko Kostua Unitateko",
|
||||
"down_3_vs_last_week": "−%3 aurreko astearekin alderatuta",
|
||||
"active_equipment": "Ekipo Aktiboak",
|
||||
"one_in_maintenance": "1 mantentze lanetan",
|
||||
"excellent_standards": "Estandar bikainak",
|
||||
"planned_batches": "Planifikatutako Sortak",
|
||||
"batches": "sortak",
|
||||
"best": "onena",
|
||||
"no_yield_data": "Ez dago errendimendu daturik eskuragarri",
|
||||
"product_leaderboard": "Produktuen Sailkapena",
|
||||
"yield_comparison": "Errendimendu Konparaketa",
|
||||
"weekly_yield_trend": "Asteko Errendimendu Joera",
|
||||
"product_yield_rankings_trends": "Produktu errendimenduen sailkapena eta joera",
|
||||
"average_yield": "Batez Besteko Errendimendua",
|
||||
"best_yield": "Errendimendurik Onena",
|
||||
"yield_trend": "Errendimendu Joera"
|
||||
},
|
||||
"actions": {
|
||||
"start_production": "Hasi ekoizpena",
|
||||
"complete_batch": "Osatu sorta",
|
||||
"pause_production": "Pausatu ekoizpena",
|
||||
"cancel_batch": "Ezeztatu sorta",
|
||||
"quality_check": "Kalitate-kontrola",
|
||||
"create_batch": "Sortu sorta",
|
||||
"view_details": "Ikusi xehetasunak",
|
||||
"edit_batch": "Editatu sorta",
|
||||
"duplicate_batch": "Bikoiztu sorta"
|
||||
"status": {
|
||||
"pending": "Zain",
|
||||
"in_progress": "Abian",
|
||||
"completed": "Osatuta",
|
||||
"cancelled": "Ezeztatuta",
|
||||
"on_hold": "Pausatuta",
|
||||
"quality_check": "Kalitate Kontrola",
|
||||
"failed": "Huts Egin Du",
|
||||
"operational": "Operatiboak",
|
||||
"warning": "Abisua",
|
||||
"maintenance": "Mantentze Lanak",
|
||||
"down": "Itzalita",
|
||||
"passed": "GAINDITUTA",
|
||||
"complete": "Osoa",
|
||||
"unknown": "Ezezaguna",
|
||||
"excellent": "Bikaina",
|
||||
"good": "Ona",
|
||||
"critical": "Kritikoa"
|
||||
},
|
||||
"labels": {
|
||||
"current_production": "Uneko ekoizpena",
|
||||
"production_queue": "Ekoizpen-ilara",
|
||||
"completed_today": "Gaur osatuta",
|
||||
"efficiency_rate": "Eraginkortasun-tasa",
|
||||
"quality_score": "Kalitate-puntua",
|
||||
"active_batches": "Sorta aktiboak",
|
||||
"pending_quality_checks": "Kalitate-kontrolak itxaroten"
|
||||
"priority": {
|
||||
"low": "Baxua",
|
||||
"medium": "Ertaina",
|
||||
"high": "Altua",
|
||||
"urgent": "Larria"
|
||||
},
|
||||
"descriptions": {
|
||||
"production_efficiency": "Uneko ekoizpenaren eraginkortasun-ehunekoa",
|
||||
"quality_average": "Azken sorten batez besteko kalitate-puntua",
|
||||
"waste_reduction": "Aurreko hilabetearekin alderatutako hondakin-murrizketa"
|
||||
},
|
||||
"equipment": {
|
||||
"title": "Makinen egoera",
|
||||
"subtitle": "Monitorizatu makinen osasuna eta errendimendua"
|
||||
"batch": {
|
||||
"title": "Ekoizpen Sorta",
|
||||
"batch_number": "Sorta Zenbakia",
|
||||
"product_name": "Produktu Izena",
|
||||
"planned_quantity": "Planifikatutako Kantitatea",
|
||||
"actual_quantity": "Benetako Kantitatea",
|
||||
"planned_start": "Planifikatutako Hasiera",
|
||||
"actual_start": "Benetako Hasiera",
|
||||
"planned_end": "Planifikatutako Amaiera",
|
||||
"actual_end": "Benetako Amaiera",
|
||||
"staff_assigned": "Esleitutako Langilea",
|
||||
"equipment_used": "Erabilitako Ekipoa",
|
||||
"notes": "Oharrak",
|
||||
"yield_percentage": "Errendimendua",
|
||||
"duration": "Iraupena",
|
||||
"cost": "Kostua",
|
||||
"rush_order": "Eskaera Presazkoa",
|
||||
"actual": "Erreala",
|
||||
"staff": "Langilea",
|
||||
"equipment": "Ekipoa"
|
||||
},
|
||||
"quality": {
|
||||
"title": "Kalitate Kontrola",
|
||||
"dashboard": {
|
||||
"title": "Kalitate Panela",
|
||||
"subtitle": "Jarraitu kalitate metrikak eta joerak",
|
||||
"error": "Errorea kalitate datuak kargatzean"
|
||||
},
|
||||
"categories": {
|
||||
"weight_check": "Pisu Kontrola",
|
||||
"temperature_check": "Tenperatura Kontrola",
|
||||
@@ -100,6 +111,557 @@
|
||||
"time_check": "Denbora Kontrola",
|
||||
"chemical": "Kimikoa",
|
||||
"hygiene": "Higienea"
|
||||
},
|
||||
"check_types": {
|
||||
"visual": "Ikusizko",
|
||||
"visual_description": "Ikusizko inspekzioa",
|
||||
"measurement": "Neurketa",
|
||||
"measurement_description": "Neurri zehatzak",
|
||||
"temperature": "Tenperatura",
|
||||
"temperature_description": "Tenperatura kontrola",
|
||||
"weight": "Pisua",
|
||||
"weight_description": "Pisu kontrola",
|
||||
"boolean": "Bai/Ez",
|
||||
"boolean_description": "Bitar egiaztapena",
|
||||
"timing": "Denbora",
|
||||
"timing_description": "Denbora kontrola",
|
||||
"checklist": "Egiaztapen zerrenda",
|
||||
"checklist_description": "Egiaztapen zerrenda"
|
||||
},
|
||||
"inspection": {
|
||||
"title": "Kalitate Inspekzioa",
|
||||
"notes_placeholder": "Gehitu oharrak irizpide honetarako (aukerakoa)..."
|
||||
},
|
||||
"tabs": {
|
||||
"overview": "Ikuspegi Orokorra",
|
||||
"by_product": "Produktuka",
|
||||
"categories": "Kategoriak",
|
||||
"recent": "Azkenak",
|
||||
"inspection": "Inspekzioa",
|
||||
"photos": "Argazkiak",
|
||||
"summary": "Laburpena"
|
||||
},
|
||||
"charts": {
|
||||
"weekly_trends": "Asteko Kalitate Joera",
|
||||
"placeholder": "Kalitate joera grafikoa hemen bistaratuko da"
|
||||
},
|
||||
"photos": {
|
||||
"description": "Gehitu argazkiak kalitate arazoak edo frogak dokumentatzeko",
|
||||
"upload": "Igo Argazkiak",
|
||||
"upload_title": "Igo Kalitate Argazkiak",
|
||||
"upload_help": "Hautatu irudi anitzak igotzeko"
|
||||
},
|
||||
"summary": {
|
||||
"overall_score": "Kalitate Puntuazio Orokorra",
|
||||
"results": "Inspekzio Emaitzak",
|
||||
"final_notes": "Gehitu azken oharrak eta gomendioak..."
|
||||
},
|
||||
"actions": {
|
||||
"new_check": "Kontrol Berria",
|
||||
"view_trends": "Ikusi Joera",
|
||||
"save_draft": "Gorde Zirriborroa",
|
||||
"complete_inspection": "Osatu Inspekzioa",
|
||||
"check_ingredients": "Egiaztatu Osagaiak",
|
||||
"adjust_recipe": "Doitu Errezeta",
|
||||
"view_details": "Ikusi Xehetasunak",
|
||||
"reduce_waste": "Murriztu Hondakinak",
|
||||
"focus_on": "Zentratu murriztean",
|
||||
"investigate_increasing_defects": "Ikertu akats joeren hazkundea",
|
||||
"review_process_controls": "Berrikusi prozesu kontrolak eta prestakuntza"
|
||||
},
|
||||
"required": "Derrigorrezkoa",
|
||||
"optional": "Aukerakoa",
|
||||
"trends": {
|
||||
"vs_last_week": "vs aurreko astea"
|
||||
},
|
||||
"waste_defect_tracker": "Hondakin eta Akats Jarraitzailea",
|
||||
"waste_sources_trends_costs": "Jarraitu hondakin iturriak, joerak eta kostu eragina",
|
||||
"total_waste": "Hondakin Osoa",
|
||||
"total_defects": "Akats Osoak",
|
||||
"estimated_cost": "Estimatutako Kostua",
|
||||
"no_waste_data": "Ez dago hondakin daturik eskuragarri",
|
||||
"top_waste_sources": "Hondakin Iturri Nagusiak",
|
||||
"waste_distribution": "Hondakin Banaketa",
|
||||
"weekly_waste_trend": "Asteko Hondakin Joera",
|
||||
"waste_percentage": "% Hondakinak",
|
||||
"defect_percentage": "% Akatsak",
|
||||
"incidents": "gertaerak",
|
||||
"cost": "kostua",
|
||||
"severity": {
|
||||
"low": "Baxua",
|
||||
"medium": "Ertaina",
|
||||
"high": "Altua"
|
||||
},
|
||||
"trend": {
|
||||
"up": "Igotzen",
|
||||
"down": "Jaisten",
|
||||
"stable": "Egonkorra"
|
||||
},
|
||||
"defects": {
|
||||
"burnt": "Erreta",
|
||||
"underproofed": "Gutxi Hartzituta",
|
||||
"misshapen": "Desitxuratuta",
|
||||
"color_issues": "Kolore Arazoak",
|
||||
"texture_problems": "Testura Arazoak",
|
||||
"temperature_issues": "Tenperatura Arazoak",
|
||||
"expired": "Iraungita"
|
||||
},
|
||||
"recommendations": {
|
||||
"high_waste_detected": "Hondakin maila altuak detektatuta",
|
||||
"check_temperature_timing": "Egiaztatu labearen tenperaturak eta denbora ezarpenak emaitza optimoetarako.",
|
||||
"improvement_opportunity": "Hondakin Murrizketa Aukera",
|
||||
"reduce_waste_target": "Zentratu hondakinak {target} helburura murriztean.",
|
||||
"maintain_quality_standards": "Jarraitu kalitate estandar bikainak mantentzen.",
|
||||
"documentation": "Kalitate Dokumentazioa",
|
||||
"photo_documentation_helps": "Argazki dokumentazioak akatsen sustraiko kausak identifikatzen laguntzen du.",
|
||||
"critical_defects": "Akats Kritikoak Detektatuta",
|
||||
"immediate_action_required": "Larritasun altuko akatsek arreta berehalakoa eta ekintza zuzentzailea behar dute.",
|
||||
"improve_quality": "Kalitate Hobekuntza Beharrezkoa",
|
||||
"focus_consistency": "Zentratu ekoizpen prozesuetan koherentzia hobetzean.",
|
||||
"excellent_quality": "Kalitate Errendimendu Bikaina",
|
||||
"maintain_standards": "Jarraitu estandar altu hauek mantentzen."
|
||||
},
|
||||
"recent_quality_scores": "Azken Kalitate Puntuazioak",
|
||||
"daily_average_quality_trends": "Eguneroko batez besteko kalitate puntuazio joerak",
|
||||
"daily_quality_score": "Eguneroko Kalitate Puntuazioa",
|
||||
"score_distribution": "Puntuazio Banaketa",
|
||||
"excellent": "Bikaina (9-10)",
|
||||
"good": "Ona (8-9)",
|
||||
"acceptable": "Onargarria (7-8)",
|
||||
"poor": "Txarra (6-7)",
|
||||
"failed": "Huts Egin Du (<6)",
|
||||
"vs_last_week": "vs aurreko astea",
|
||||
"no_quality_data": "Ez dago kalitate daturik eskuragarri",
|
||||
"weekly_quality_trends": "Asteko Kalitate Joera",
|
||||
"excellent_scores": "Bikaina",
|
||||
"good_scores": "Ona",
|
||||
"needs_improvement": "Hobekuntza Behar Du",
|
||||
"top_defect_types_24h": "Akats Mota Nagusiak (Azken 24h)",
|
||||
"defect_analysis_cost_impact": "Aztertu akats motak eta haien kostu eragina",
|
||||
"no_defects_detected": "Ez da Akatsik Detektatu",
|
||||
"excellent_quality_standards": "Kalitate estandar bikainak mantentzen produktu guztietan.",
|
||||
"defect_breakdown": "Akats Xehetasuna",
|
||||
"defect_distribution": "Akats Banaketa",
|
||||
"top_defects_weekly_trend": "Akats Nagusiak - Asteko Joera",
|
||||
"recommended_actions": "Gomendatutako Ekintzak"
|
||||
},
|
||||
"cost": {
|
||||
"title": "Ekoizpen Kostu Jarraitzailea",
|
||||
"subtitle": "Jarraitu eta optimizatu ekoizpen kostuak",
|
||||
"total_cost": "Kostu Osoa",
|
||||
"cost_per_unit": "Kostua Unitateko",
|
||||
"labor": "Lan Kostua",
|
||||
"materials": "Materialak",
|
||||
"overhead": "Gastu Orokorrak",
|
||||
"energy": "Energia",
|
||||
"breakdown": "Kostu Banaketa",
|
||||
"budget_usage": "Aurrekontu Erabilpena",
|
||||
"over_budget": "Aurrekontu Gainetik",
|
||||
"near_budget": "Aurrekontu Hurbil",
|
||||
"on_budget": "Aurrekontuan",
|
||||
"vs_yesterday": "vs atzo",
|
||||
"average_today": "Batez bestekoa gaur",
|
||||
"view_details": "Ikusi Xehetasunak",
|
||||
"optimize": "Optimizatu Kostuak",
|
||||
"error": "Errorea kostu datuak kargatzean",
|
||||
"cost_per_unit_analysis": "Unitateko Kostu Analisia",
|
||||
"estimated_vs_actual_costs": "Konparatu estimatutako vs benetako kostuak produktuka",
|
||||
"average_cost_per_unit": "Batez Besteko Kostua Unitateko",
|
||||
"total_production_cost": "Ekoizpen Kostu Osoa",
|
||||
"no_cost_data_available": "Ez dago kostu daturik eskuragarri analisirako",
|
||||
"estimated_vs_actual": "Estimatuta vs Erreala",
|
||||
"product_cost_breakdown": "Kostu Banaketa Produktuka",
|
||||
"estimated_cost": "Estimatutako Kostua",
|
||||
"actual_cost": "Benetako Kostua",
|
||||
"estimated": "Estimatuta",
|
||||
"actual": "Erreala",
|
||||
"variance": "Bariantza",
|
||||
"cost_distribution": "Kostu Banaketa",
|
||||
"units_produced": "Ekoitzitako unitateak",
|
||||
"optimization_opportunity": "Kostu Optimizazio Aukera",
|
||||
"high_variance_detected": "Kostu bariantza altua detektatuta produktu batzuetan. Berrikusi prezioak eta prozesuak.",
|
||||
"costs_within_expected_range": "Kostuak espero den tartean daude. Jarraitu optimizazio aukerak monitorizatzen.",
|
||||
"view_breakdown": "Ikusi Xehetasuna",
|
||||
"waste_cost": "Hondakin Kostua"
|
||||
},
|
||||
"equipment": {
|
||||
"title": "Ekipo Egoera",
|
||||
"subtitle": "Jarraitu ekipoen osasuna eta errendimendua",
|
||||
"manager": {
|
||||
"title": "Ekipo Kudeaketa",
|
||||
"subtitle": "Jarraitu eta kudeatu ekoizpen ekipoak"
|
||||
},
|
||||
"status": {
|
||||
"operational": "Operatiboa",
|
||||
"warning": "Abisua",
|
||||
"maintenance": "Mantentze Lanak",
|
||||
"down": "Itzalita",
|
||||
"equipment_list": "Ekipo Zerrenda",
|
||||
"distribution": "Egoera Banaketa"
|
||||
},
|
||||
"stats": {
|
||||
"total": "Ekipo Osoak",
|
||||
"operational": "Operatiboa",
|
||||
"needs_attention": "Arreta Behar Du",
|
||||
"efficiency": "Eraginkortasuna",
|
||||
"avg_efficiency": "Batez Besteko Eraginkortasuna",
|
||||
"alerts": "Alerta Aktiboak",
|
||||
"by_equipment": "ekipoka"
|
||||
},
|
||||
"filter": {
|
||||
"all": "Egoera Guztiak"
|
||||
},
|
||||
"tabs": {
|
||||
"overview": "Ikuspegi Orokorra",
|
||||
"maintenance": "Mantentze Lanak",
|
||||
"alerts": "Alertak"
|
||||
},
|
||||
"maintenance": {
|
||||
"title": "Mantentze Egutegia",
|
||||
"subtitle": "Planifikatu eta jarraitu mantentze jarduerak",
|
||||
"overdue": "Atzeratuta",
|
||||
"scheduled": "Programatuta",
|
||||
"last": "Azkena",
|
||||
"next": "Hurrengoa",
|
||||
"interval": "Tartea",
|
||||
"history": "Historia",
|
||||
"records": "erregistroak",
|
||||
"avg_duration": "Batez Besteko Iraupena",
|
||||
"total_cost": "Kostu Osoa",
|
||||
"overdue_tasks": "Atzeratutako Zereginak",
|
||||
"immediate_attention_required": "Arreta berehalakoa behar da",
|
||||
"tasks": "Mantentze Zereginak",
|
||||
"duration": "Iraupena",
|
||||
"cost": "Kostua",
|
||||
"technician": "Teknikaria",
|
||||
"this_week": "Aste Honetako Egutegia",
|
||||
"insights": {
|
||||
"title": "Mantentze Ezaugarriak",
|
||||
"completed_this_month": "zeregin osatuta hilabete honetan",
|
||||
"scheduled_next_week": "programatutako zereginak hurrengo asterako"
|
||||
},
|
||||
"status": {
|
||||
"scheduled": "Programatuta",
|
||||
"in_progress": "Abian",
|
||||
"completed": "Osatuta",
|
||||
"overdue": "Atzeratuta"
|
||||
},
|
||||
"type": {
|
||||
"preventive": "Prebentzioa",
|
||||
"corrective": "Zuzentzailea",
|
||||
"inspection": "Inspekzioa"
|
||||
}
|
||||
},
|
||||
"alerts": {
|
||||
"acknowledged": "Onartuta",
|
||||
"new": "Berriak",
|
||||
"acknowledge": "Onartu",
|
||||
"maintenance_required": "Mantentze Lanak Beharrezkoak",
|
||||
"equipment_in_maintenance": "ekipoak mantentze lanetan",
|
||||
"active_alerts": "alerta aktiboak"
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Bilatu ekipoak..."
|
||||
},
|
||||
"actions": {
|
||||
"add": "Gehitu Ekipoa",
|
||||
"export": "Esportatu",
|
||||
"maintenance": "Mantentze Lanak",
|
||||
"schedule_maintenance": "Programatu Mantentze Lanak",
|
||||
"view_history": "Ikusi Historia"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Ekipo Eraginkortasuna",
|
||||
"subtitle": "Jarraitu errendimendua eta optimizazio aukerak",
|
||||
"average": "Batez Besteko Eraginkortasuna",
|
||||
"current": "Unekoa",
|
||||
"target": "Helburua",
|
||||
"current_vs_target": "Uneko vs Helburu Eraginkortasuna",
|
||||
"weekly_trends": "Asteko Eraginkortasun Joera",
|
||||
"by_equipment": "Eraginkortasuna Ekipoka",
|
||||
"analyze": "Aztertu",
|
||||
"optimize": "Optimizatu",
|
||||
"recommendations": "Eraginkortasun Gomendioak",
|
||||
"recommendation_1": "Lehentasunezko Ekintza",
|
||||
"recommendation_2": "Energia Optimizazioa",
|
||||
"recommendation_3": "Prebentziozko Zaintza",
|
||||
"needs_maintenance": "mantentze arreta behar du",
|
||||
"optimize_energy_consumption": "Optimizatu energia kontsumoa punta orduetan",
|
||||
"schedule_preventive_maintenance": "Programatu mantentze prebentiboa ekipo guztientzat"
|
||||
},
|
||||
"efficiency": "Eraginkortasuna",
|
||||
"uptime": "Erabilgarritasun Denbora",
|
||||
"location": "Kokapena",
|
||||
"temperature": "Tenperatura",
|
||||
"energy_usage": "Energia Erabilpena",
|
||||
"energy_consumption": "Energia Kontsumoa",
|
||||
"unread_alerts": "irakurri gabeko alertak",
|
||||
"model": "Modeloa",
|
||||
"serial": "Serie Zenbakia",
|
||||
"install_date": "Instalazio Data",
|
||||
"error": "Errorea ekipo datuak kargatzean",
|
||||
"oven_capacity": "Labe Ahalmena",
|
||||
"mixer_capacity": "Irabiagailu Ahalmena",
|
||||
"coming_soon": "Laster",
|
||||
"equipment_analytics_development": "Ekipo analisiak garatze prozesuan daude. Jarraitzaile aurreratua eta mantentze aurreikuspen ezaugarriak laster eskuragarri egongo dira.",
|
||||
"units_per_hour": "unitateak/ordua",
|
||||
"downtime": {
|
||||
"total": "Geldi Egon Denbora Osoa"
|
||||
},
|
||||
"oee": {
|
||||
"overall": "OEE Orokorra",
|
||||
"breakdown": "OEE Xehetasuna",
|
||||
"availability": "Erabilgarritasuna",
|
||||
"performance": "Errendimendua",
|
||||
"quality": "Kalitatea"
|
||||
}
|
||||
},
|
||||
"ai": {
|
||||
"title": "AI Ezaugarriak",
|
||||
"subtitle": "AIaren gomendioak eta aurreikuspenak",
|
||||
"high_impact": "Eragin Altua",
|
||||
"potential_savings": "Aurrezpen Potentziala",
|
||||
"confidence": "Batez Besteko Konfiantza",
|
||||
"impact": "ERAGINA",
|
||||
"insights": {
|
||||
"reduce_energy_costs": "Murriztu Energia Kostuak %15ean",
|
||||
"energy_description": "Doitu labearen ordutegiak elektrizitate tarifa merkeenak erabiltzeko. Estimatutako aurrezkia: €45/eguna",
|
||||
"demand_increase": "Croissant Eskaera Igoera Aurreikusita",
|
||||
"demand_description": "Eguraldiaren eta gertaeren datuek croissant eskaeran %40 igoera iradokitzen dute asteburu honetan",
|
||||
"quality_decline": "Kalitate Puntuazio Beherakada Detektatuta",
|
||||
"quality_description": "Ogiaren kalitatea %8 jaitsi da azken 3 egunetan. Egiaztatu irinaren hezetasun mailak",
|
||||
"maintenance_due": "Mantentze Prebentiboa Gomendatuta",
|
||||
"maintenance_description": "Irabiagailu #2k higadura goiztiar ereduak erakusten ditu. Programatu mantentzea akatsen prebentzioa"
|
||||
},
|
||||
"actions": {
|
||||
"schedule_optimization": "Optimizatu Ordutegia",
|
||||
"view_details": "Ikusi Xehetasunak",
|
||||
"increase_production": "Handitu Ekoizpena",
|
||||
"order_ingredients": "Eskatu Osagaiak",
|
||||
"schedule_maintenance": "Programatu Mantentze Lanak",
|
||||
"view_equipment": "Ikusi Ekipoa",
|
||||
"train_model": "Trebatu Modeloa",
|
||||
"implement_all": "Inplementatu Denak",
|
||||
"acknowledge": "Onartu",
|
||||
"implement": "Inplementatu"
|
||||
},
|
||||
"status": {
|
||||
"active": "AI jarraitzailea aktibo",
|
||||
"new": "Berria",
|
||||
"acknowledged": "Onartuta",
|
||||
"in_progress": "Abian",
|
||||
"implemented": "Inplementatuta",
|
||||
"dismissed": "Baztertuta"
|
||||
},
|
||||
"last_updated": "Eguneratuta duela 5m",
|
||||
"error": "AI ezaugarriak aldi baterako ez daude eskuragarri",
|
||||
"ai_insights_coming_soon": "AI Ezaugarriak Laster",
|
||||
"ai_powered_recommendations_development": "AIak bultzatutako gomendioak eta aurreikuspen analisiak garatze prozesuan daude. Sartu beta programan goiz sarbidea izateko.",
|
||||
"stats": {
|
||||
"active_insights": "Ezaugarri Aktiboak",
|
||||
"high_priority": "Lehentasun Altua",
|
||||
"potential_savings": "Aurrezpen Potentziala",
|
||||
"avg_confidence": "Batez Besteko Konfiantza"
|
||||
},
|
||||
"priority": {
|
||||
"low": "Baxua",
|
||||
"medium": "Ertaina",
|
||||
"high": "Altua",
|
||||
"critical": "Kritikoa"
|
||||
},
|
||||
"impact": {
|
||||
"cost_savings": "Kostu Aurrezkia",
|
||||
"efficiency_gain": "Eraginkortasun Irabazia",
|
||||
"quality_improvement": "Kalitate Hobekuntza",
|
||||
"risk_mitigation": "Arrisku Murrizketa"
|
||||
},
|
||||
"confidence": "Konfiantza",
|
||||
"timeline": "Kronologia",
|
||||
"equipment": "Ekipoa",
|
||||
"high_priority_insights": "Lehentasun Altuko Ezaugarriak",
|
||||
"all_insights": "Ezaugarri Guztiak",
|
||||
"performance": {
|
||||
"summary": "AI Errendimendu Laburpena",
|
||||
"insights_implemented": "ezaugarriak inplementatuta hilabete honetan",
|
||||
"in_savings_identified": "aurrezpen potentziala identifikatuta"
|
||||
},
|
||||
"predictive_maintenance": {
|
||||
"title": "Mantentze Aurreikuspena",
|
||||
"subtitle": "AIaren akatsen aurreikuspena eta mantentze optimizazioa",
|
||||
"high_risk": "Arrisku Altuko Ekipoak",
|
||||
"estimated_cost": "Estimatutako Kostua",
|
||||
"potential_downtime": "Potentziala Geldi Egotea",
|
||||
"avg_confidence": "Batez Besteko Konfiantza",
|
||||
"high_risk_equipment": "Arrisku Altuko Ekipoak",
|
||||
"immediate_attention_required": "Arreta berehalakoa behar da akatsak prebenitzeko",
|
||||
"predictions": "Mantentze Aurreikuspenak",
|
||||
"confidence": "Konfiantza",
|
||||
"risk_score": "Arrisku Puntuazioa",
|
||||
"days_until_failure": "Egun Akatsera Arte",
|
||||
"condition": "Egoera",
|
||||
"current_condition": "Uneko Egoera",
|
||||
"affected_components": "Osagai Afektatuak",
|
||||
"recommended_actions": "Gomendatutako Ekintzak",
|
||||
"schedule": "Programatu",
|
||||
"details": "Ikusi Xehetasunak",
|
||||
"schedule_all": "Programatu Denak",
|
||||
"retrain_model": "Berriro Trebatu Modeloa",
|
||||
"condition_trends": "Ekipo Egoera Joera",
|
||||
"risk_distribution": "Arrisku Banaketa",
|
||||
"model_status": "ML Modelo Egoera",
|
||||
"last_training": "Azken prestakuntza",
|
||||
"yesterday": "atzo",
|
||||
"accuracy": "Zehaztasuna",
|
||||
"next_training": "Hurrengo prestakuntza",
|
||||
"in_7_days": "7 egunetan",
|
||||
"alert_type": {
|
||||
"wear_prediction": "Higadura ereduak akats potentziala adierazten du",
|
||||
"failure_risk": "Akats arrisku altua detektatuta",
|
||||
"performance_degradation": "Errendimendu degradazioa detektatuta",
|
||||
"component_replacement": "Osagaia ordezkatzea gomendatuta"
|
||||
}
|
||||
},
|
||||
"severity": {
|
||||
"low": "Baxua",
|
||||
"medium": "Ertaina",
|
||||
"high": "Altua",
|
||||
"critical": "Kritikoa"
|
||||
},
|
||||
"risk": {
|
||||
"low": "Arrisku Baxua",
|
||||
"medium": "Arrisku Ertaina",
|
||||
"high": "Arrisku Altua"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"create_batch": "Sortu Sorta",
|
||||
"start_batch": "Hasi Sorta",
|
||||
"complete_batch": "Osatu Sorta",
|
||||
"view_details": "Ikusi Xehetasunak",
|
||||
"edit": "Editatu",
|
||||
"delete": "Ezabatu",
|
||||
"schedule": "Programatu",
|
||||
"optimize": "Optimizatu",
|
||||
"export_report": "Esportatu Txostena",
|
||||
"optimize_production": "Optimizatu Ekoizpena",
|
||||
"analyze_delays": "Aztertu Atzerapenak",
|
||||
"optimize_yields": "Optimizatu Errendimendua",
|
||||
"refresh": "Freskatu",
|
||||
"request_beta_access": "Eskatu Beta Sarbidea",
|
||||
"join_ai_beta": "Sartu AI Beta",
|
||||
"reduce_waste": "Murriztu Hondakinak",
|
||||
"investigate_defects": "Ikertu Akatsak"
|
||||
},
|
||||
"tabs": {
|
||||
"schedule": "Ordutegia",
|
||||
"batches": "Ekoizpen Sortak",
|
||||
"quality": "Kalitate Kontrola",
|
||||
"overview": "Ikuspegi Orokorra",
|
||||
"bakery_operations": "Okindegi Eragiketak",
|
||||
"cost_efficiency": "Kostua eta Eraginkortasuna",
|
||||
"quality_assurance": "Kalitate Bermea",
|
||||
"equipment_maintenance": "Ekipoak eta Mantentze Lanak",
|
||||
"ai_insights": "AI Ezaugarriak"
|
||||
},
|
||||
"forms": {
|
||||
"batch_number": "Sorta Zenbakia",
|
||||
"product_selection": "Produktu Hautapena",
|
||||
"quantity": "Kantitatea",
|
||||
"start_time": "Hasiera Ordua",
|
||||
"end_time": "Amaiera Ordua",
|
||||
"priority": "Lehentasuna",
|
||||
"staff": "Esleitutako Langilea",
|
||||
"equipment": "Ekipoa",
|
||||
"notes": "Ekoizpen Oharrak"
|
||||
},
|
||||
"messages": {
|
||||
"no_batches": "Ez da ekoizpen sortarik aurkitu",
|
||||
"no_active_batches": "Ez dago ekoizpen sorta aktiborik. Sortu lehenengo sorta hasteko.",
|
||||
"no_active_batches_description": "Sortu ekoizpen sorta berria progresioa jarraitzen hasteko.",
|
||||
"no_batches_planned": "Ez dago sortarik planifikatuta gaurkoan",
|
||||
"batch_created": "Ekoizpen sorta arrakastaz sortu da",
|
||||
"batch_updated": "Ekoizpen sorta arrakastaz eguneratu da",
|
||||
"batch_started": "Ekoizpen sorta hasi da",
|
||||
"batch_completed": "Ekoizpen sorta osatu da"
|
||||
},
|
||||
"analytics": {
|
||||
"production_analytics": "Ekoizpen Analisiak",
|
||||
"advanced_insights_professionals_enterprises": "Analisi aurreratuak eta ezaugarriak profesionalentzat eta enpresentzat"
|
||||
},
|
||||
"subscription": {
|
||||
"exclusive_professional_enterprise": "Eduki esklusiboa Professional eta Enterprise planentzat",
|
||||
"advanced_production_analytics_description": "Ekoizpen analisi aurreratuak Professional eta Enterprise erabiltzaileentzat soilik eskuragarri daude. Eguneratu zure plana funtzionalitate guztietara sarbidea izateko.",
|
||||
"upgrade_plan": "Eguneratu Plana"
|
||||
},
|
||||
"schedule": {
|
||||
"todays_summary": "Gaurko Laburpena",
|
||||
"shift_hours_batches_staff": "Txanda orduak, planifikatutako sortak eta langile kopurua",
|
||||
"shift_hours": "Txanda Orduak",
|
||||
"staff_count": "Langile Kopurua",
|
||||
"capacity_utilization": "Ahalmen Erabilpena",
|
||||
"planned_batches": "Planifikatutako Sortak",
|
||||
"active": "Aktiboa",
|
||||
"inactive": "Inaktiboa",
|
||||
"finalized": "Finalizatuta",
|
||||
"draft": "Zirriborroa",
|
||||
"delayed": "atzeratuta",
|
||||
"staff_capacity": "Langile Ahalmena",
|
||||
"work_stations": "Lan Postuak"
|
||||
},
|
||||
"tracker": {
|
||||
"live_batch_tracker": "Zuzeneko Sorta Jarraitzailea",
|
||||
"current_batches_status_progress": "Uneko sortak egoera, progresio barra eta ETA",
|
||||
"progress": "Progresioa",
|
||||
"pending_start": "Hasiera Zain",
|
||||
"issues": "Arazoak"
|
||||
},
|
||||
"insights": {
|
||||
"on_time_vs_planned": "Sorta bukaerak vs planifikatutako ordutegia",
|
||||
"vs_week_avg": "vs asteko batez bestekoa",
|
||||
"target": "Helburua",
|
||||
"progress_to_target": "Progresioa Helburura",
|
||||
"weekly_trend": "Asteko Joera",
|
||||
"performance_insight": "Errendimendu Ezaugarria",
|
||||
"on_time_excellent": "Orduan bukatze errendimendu bikaina! Jarraitu lan bikainarekin.",
|
||||
"on_time_good_room_improvement": "Errendimendu ona hobekuntza aukerarekin.",
|
||||
"on_time_needs_attention": "Orduan bukatzeak arreta behar du. Berrikusi programazioa.",
|
||||
"on_time_critical_delays": "Atzerapen kritikoak detektatuta. Ekintza berehalakoa behar da.",
|
||||
"batches_on_time": "Orduan",
|
||||
"batches_delayed": "Atzeratuta",
|
||||
"avg_delay_minutes": "Batez Besteko Atzerapena (min)",
|
||||
"resource_allocation_efficiency": "Jarraitu baliabide esleipena eta eraginkortasuna",
|
||||
"resource_breakdown": "Baliabide Xehetasuna",
|
||||
"hourly_utilization_pattern": "Orduko Erabilpen Eredua",
|
||||
"peak_hours": "Punta Orduak",
|
||||
"off_peak_optimal": "Puntaz Kanpo (Optimoa)",
|
||||
"hourly_utilization": "Orduko Erabilpena"
|
||||
},
|
||||
"performance": {
|
||||
"excellent": "Bikaina",
|
||||
"good": "Ona",
|
||||
"average": "Batez Bestekoa",
|
||||
"poor": "Txarra",
|
||||
"needs_improvement": "Hobekuntza Behar Du"
|
||||
},
|
||||
"recommendations": {
|
||||
"yield_improvement": "Errendimendu Hobekuntza Aukera",
|
||||
"focus_on_low_performers": "Zentratu errendimendu baxuko produktuak hobetzen eraginkortasun orokorra handitzeko.",
|
||||
"maintain_high_standards": "Jarraitu errendimendu estandar altuak mantentzen produktu guztietan."
|
||||
},
|
||||
"common": {
|
||||
"units": "unitateak",
|
||||
"assigned": "esleituta",
|
||||
"allocated": "esleituta",
|
||||
"available": "eskuragarri"
|
||||
},
|
||||
"alerts": {
|
||||
"capacity_critical": "Ahalmen Kritikoa",
|
||||
"capacity_critical_description": "Baliabide batzuk gehieneko ahalmenean daude. Kontuan hartu lan karga birbanatzea.",
|
||||
"capacity_high": "Ahalmen Erabilpen Altua",
|
||||
"capacity_high_description": "Jarraitu hurbil eztarriak prebenitzeko."
|
||||
},
|
||||
"mobile": {
|
||||
"optimized_experience": "Mugikorretarako Optimizatutako Esperientzia",
|
||||
"swipe_scroll_interact": "Ukitu, korritu eta sakatu analisi widget guztiekin elkarreragiteko."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user