Imporve onboarding UI
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { SetupStepProps } from '../SetupWizard';
|
||||
import { SetupStepProps } from '../types';
|
||||
import { useQualityTemplates, useCreateQualityTemplate } from '../../../../api/hooks/qualityTemplates';
|
||||
import { useCurrentTenant } from '../../../../stores/tenant.store';
|
||||
import { useAuthUser } from '../../../../stores/auth.store';
|
||||
import { QualityCheckType, ProcessStage } from '../../../../api/types/qualityTemplates';
|
||||
import type { QualityCheckTemplateCreate } from '../../../../api/types/qualityTemplates';
|
||||
import { QualityCheckType, ProcessStage, QualityCheckTemplate, QualityCheckTemplateCreate } from '../../../../api/types/qualityTemplates';
|
||||
|
||||
export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplete, canContinue }) => {
|
||||
export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplete, onPrevious, canContinue }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Get tenant ID and user
|
||||
@@ -75,14 +74,14 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
try {
|
||||
const templateData: QualityCheckTemplateCreate = {
|
||||
name: formData.name,
|
||||
check_type: formData.check_type,
|
||||
check_type: (formData.check_type as QualityCheckType) || QualityCheckType.VISUAL,
|
||||
description: formData.description || undefined,
|
||||
applicable_stages: formData.applicable_stages,
|
||||
is_required: formData.is_required,
|
||||
is_critical: formData.is_critical,
|
||||
is_active: true,
|
||||
weight: formData.is_critical ? 10 : 5,
|
||||
created_by: userId,
|
||||
created_by: userId || '',
|
||||
};
|
||||
|
||||
await createTemplateMutation.mutateAsync(templateData);
|
||||
@@ -165,7 +164,7 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium text-[var(--text-primary)]">
|
||||
{t('setup_wizard:quality.added_count', { count: templates.length, defaultValue: '{{count}} quality check added' })}
|
||||
{t('setup_wizard:quality.added_count', { count: templates.length, defaultValue: '{count} quality check added' })}
|
||||
</span>
|
||||
</div>
|
||||
{templates.length >= 2 ? (
|
||||
@@ -252,7 +251,7 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
type="text"
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
className={`w-full px-3 py-2 bg-[var(--bg-primary)] border ${errors.name ? 'border-[var(--color-error)]' : 'border-[var(--border-secondary)]'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]`}
|
||||
className={`w - full px - 3 py - 2 bg - [var(--bg - primary)] border ${errors.name ? 'border-[var(--color-error)]' : 'border-[var(--border-secondary)]'} rounded - lg focus: outline - none focus: ring - 2 focus: ring - [var(--color - primary)]text - [var(--text - primary)]`}
|
||||
placeholder={t('setup_wizard:quality.placeholders.name', 'e.g., Crust color check, Dough temperature')}
|
||||
/>
|
||||
{errors.name && <p className="mt-1 text-xs text-[var(--color-error)]">{errors.name}</p>}
|
||||
@@ -274,11 +273,10 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
console.log('Check type clicked:', option.value, 'current:', formData.check_type);
|
||||
setFormData(prev => ({ ...prev, check_type: option.value }));
|
||||
}}
|
||||
className={`p-3 text-left border-2 rounded-lg transition-all cursor-pointer ${
|
||||
formData.check_type === option.value
|
||||
? 'border-[var(--color-primary)] bg-[var(--color-primary)]/20 shadow-lg ring-2 ring-[var(--color-primary)]/30'
|
||||
: 'border-[var(--border-secondary)] hover:border-[var(--color-primary)]/50 hover:bg-[var(--bg-secondary)]'
|
||||
}`}
|
||||
className={`p - 3 text - left border - 2 rounded - lg transition - all cursor - pointer ${formData.check_type === option.value
|
||||
? 'border-[var(--color-primary)] bg-[var(--color-primary)]/20 shadow-lg ring-2 ring-[var(--color-primary)]/30'
|
||||
: 'border-[var(--border-secondary)] hover:border-[var(--color-primary)]/50 hover:bg-[var(--bg-secondary)]'
|
||||
} `}
|
||||
>
|
||||
<div className="text-lg mb-1">{option.icon}</div>
|
||||
<div className="text-xs font-medium text-[var(--text-primary)]">{option.label}</div>
|
||||
@@ -325,11 +323,10 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
: [...prev.applicable_stages, option.value]
|
||||
}));
|
||||
}}
|
||||
className={`p-2 text-sm text-left border-2 rounded-lg transition-all cursor-pointer ${
|
||||
formData.applicable_stages.includes(option.value)
|
||||
? 'border-[var(--color-primary)] bg-[var(--color-primary)]/20 text-[var(--color-primary)] font-semibold shadow-md ring-1 ring-[var(--color-primary)]/30'
|
||||
: 'border-[var(--border-secondary)] text-[var(--text-secondary)] hover:border-[var(--color-primary)]/50 hover:bg-[var(--bg-secondary)]'
|
||||
}`}
|
||||
className={`p - 2 text - sm text - left border - 2 rounded - lg transition - all cursor - pointer ${formData.applicable_stages.includes(option.value)
|
||||
? 'border-[var(--color-primary)] bg-[var(--color-primary)]/20 text-[var(--color-primary)] font-semibold shadow-md ring-1 ring-[var(--color-primary)]/30'
|
||||
: 'border-[var(--border-secondary)] text-[var(--text-secondary)] hover:border-[var(--color-primary)]/50 hover:bg-[var(--bg-secondary)]'
|
||||
} `}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
@@ -429,16 +426,29 @@ export const QualitySetupStep: React.FC<SetupStepProps> = ({ onUpdate, onComplet
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Continue button - only shown when used in onboarding context */}
|
||||
{onComplete && (
|
||||
<div className="flex justify-end mt-6 pt-6 border-t border-[var(--border-secondary)]">
|
||||
<button
|
||||
onClick={() => onComplete()}
|
||||
disabled={canContinue === false}
|
||||
className="px-6 py-3 bg-[var(--color-primary)] text-white rounded-lg hover:bg-[var(--color-primary-dark)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors font-medium"
|
||||
>
|
||||
{t('setup_wizard:navigation.continue', 'Continue →')}
|
||||
</button>
|
||||
{/* Navigation buttons */}
|
||||
{!isAdding && onComplete && (
|
||||
<div className="flex items-center justify-between gap-4 pt-6 mt-6 border-t border-[var(--border-secondary)]">
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onPrevious}
|
||||
className="px-4 py-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-secondary)] rounded-lg transition-colors font-medium"
|
||||
>
|
||||
← {t('common:previous', 'Anterior')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onComplete()}
|
||||
disabled={canContinue === false}
|
||||
className="px-6 py-2.5 bg-[var(--color-primary)] text-white rounded-lg hover:bg-[var(--color-primary-dark)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors font-medium flex items-center gap-2"
|
||||
>
|
||||
{t('common:next', 'Continuar →')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user