Fix few issues

This commit is contained in:
Urtzi Alfaro
2025-09-26 12:12:17 +02:00
parent d573c38621
commit a27f159e24
32 changed files with 2694 additions and 575 deletions

View File

@@ -4,6 +4,7 @@ import { StatusCard, StatusIndicatorConfig } from '../../ui/StatusCard/StatusCar
import { statusColors } from '../../../styles/colors';
import { ProductionBatchResponse, ProductionStatus, ProductionPriority } from '../../../api/types/production';
import { useTranslation } from 'react-i18next';
import { TextOverflowPrevention, safeText } from '../../../utils/textUtils';
export interface ProductionStatusCardProps {
batch: ProductionBatchResponse;
@@ -76,7 +77,7 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
return {
color: getStatusColorForProduction(status),
text: t(`production:status.${status}`),
text: t(`production:status.${status.toLowerCase()}`),
icon: Icon,
isCritical,
isHighlight
@@ -157,7 +158,7 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
if (onView) {
actions.push({
label: 'Ver Detalles',
label: 'Ver',
icon: Eye,
priority: 'primary' as const,
onClick: () => onView(batch)
@@ -166,7 +167,7 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
if (batch.status === ProductionStatus.PENDING && onStart) {
actions.push({
label: 'Iniciar Producción',
label: 'Iniciar',
icon: Play,
priority: 'primary' as const,
onClick: () => onStart(batch)
@@ -205,7 +206,7 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
if (batch.status === ProductionStatus.QUALITY_CHECK && onQualityCheck) {
console.log('ProductionStatusCard - Adding quality check button for batch:', batch.batch_number);
actions.push({
label: 'Control Calidad',
label: 'Calidad',
icon: Package,
priority: 'primary' as const,
onClick: () => onQualityCheck(batch)
@@ -268,16 +269,18 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
}
if (batch.staff_assigned && batch.staff_assigned.length > 0) {
metadata.push(`Personal: ${batch.staff_assigned.join(', ')}`);
const staff = TextOverflowPrevention.production.staffList(batch.staff_assigned);
metadata.push(`Personal: ${staff}`);
}
if (batch.equipment_used && batch.equipment_used.length > 0) {
metadata.push(`Equipos: ${batch.equipment_used.join(', ')}`);
const equipment = TextOverflowPrevention.production.equipmentList(batch.equipment_used);
metadata.push(`Equipos: ${equipment}`);
}
const qualityInfo = getQualityStatusInfo(batch);
if (qualityInfo) {
metadata.push(qualityInfo);
metadata.push(safeText(qualityInfo, qualityInfo, 50));
}
if (batch.priority === ProductionPriority.URGENT) {
@@ -299,21 +302,22 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
if (batch.actual_quantity && batch.planned_quantity) {
const completionPercent = Math.round((batch.actual_quantity / batch.planned_quantity) * 100);
return {
label: 'Progreso Cantidad',
label: 'Progreso',
value: `${batch.actual_quantity}/${batch.planned_quantity} (${completionPercent}%)`
};
}
if (batch.staff_assigned && batch.staff_assigned.length > 0) {
const staff = TextOverflowPrevention.mobile.staff(batch.staff_assigned);
return {
label: 'Personal Asignado',
value: batch.staff_assigned.join(', ')
label: 'Personal',
value: staff
};
}
return {
label: 'Prioridad',
value: t(`production:priority.${batch.priority}`)
value: t(`production:priority.${batch.priority.toLowerCase()}`)
};
};
@@ -324,10 +328,10 @@ export const ProductionStatusCard: React.FC<ProductionStatusCardProps> = ({
<StatusCard
id={batch.id}
statusIndicator={statusConfig}
title={batch.product_name}
subtitle={`Lote: ${batch.batch_number}`}
title={TextOverflowPrevention.production.productName(batch.product_name)}
subtitle={`Lote: ${TextOverflowPrevention.production.batchNumber(batch.batch_number)}`}
primaryValue={batch.planned_quantity}
primaryValueLabel="unidades"
primaryValueLabel="uds"
secondaryInfo={getSecondaryInfo()}
progress={progress !== undefined ? {
label: getProgressLabel(batch),

View File

@@ -18,13 +18,12 @@ import {
} from 'lucide-react';
import {
Button,
Input,
Card,
Badge,
Select,
StatusCard,
Modal,
StatsGrid
StatsGrid,
SearchAndFilter,
type FilterConfig
} from '../../ui';
import { LoadingSpinner } from '../../ui';
import { PageHeader } from '../../layout';
@@ -285,59 +284,45 @@ export const QualityTemplateManager: React.FC<QualityTemplateManagerProps> = ({
columns={4}
/>
{/* Filters */}
<Card className="p-4">
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-[var(--text-tertiary)]" />
<Input
placeholder="Buscar plantillas..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="pl-10"
/>
</div>
<Select
value={selectedCheckType}
onChange={(e) => setSelectedCheckType(e.target.value as QualityCheckType | '')}
placeholder="Tipo de control"
>
<option value="">Todos los tipos</option>
{Object.entries(QUALITY_CHECK_TYPE_CONFIG).map(([type, config]) => (
<option key={type} value={type}>
{config.label}
</option>
))}
</Select>
<Select
value={selectedStage}
onChange={(e) => setSelectedStage(e.target.value as ProcessStage | '')}
placeholder="Etapa del proceso"
>
<option value="">Todas las etapas</option>
{Object.entries(PROCESS_STAGE_LABELS).map(([stage, label]) => (
<option key={stage} value={stage}>
{label}
</option>
))}
</Select>
<div className="flex items-center space-x-2">
<input
type="checkbox"
id="activeOnly"
checked={showActiveOnly}
onChange={(e) => setShowActiveOnly(e.target.checked)}
className="rounded border-[var(--border-primary)]"
/>
<label htmlFor="activeOnly" className="text-sm text-[var(--text-secondary)]">
Solo activas
</label>
</div>
</div>
</Card>
{/* Search and Filter Controls */}
<SearchAndFilter
searchValue={searchTerm}
onSearchChange={setSearchTerm}
searchPlaceholder="Buscar plantillas..."
filters={[
{
key: 'checkType',
label: 'Tipo de control',
type: 'dropdown',
value: selectedCheckType,
onChange: (value) => setSelectedCheckType(value as QualityCheckType | ''),
placeholder: 'Todos los tipos',
options: Object.entries(QUALITY_CHECK_TYPE_CONFIG).map(([type, config]) => ({
value: type,
label: config.label
}))
},
{
key: 'stage',
label: 'Etapa del proceso',
type: 'dropdown',
value: selectedStage,
onChange: (value) => setSelectedStage(value as ProcessStage | ''),
placeholder: 'Todas las etapas',
options: Object.entries(PROCESS_STAGE_LABELS).map(([stage, label]) => ({
value: stage,
label: label
}))
},
{
key: 'activeOnly',
label: 'Solo activas',
type: 'checkbox',
value: showActiveOnly,
onChange: (value) => setShowActiveOnly(value as boolean)
}
] as FilterConfig[]}
/>
{/* Templates Grid */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">