Improve the UI add button

This commit is contained in:
Urtzi Alfaro
2025-11-16 22:13:52 +01:00
parent 54b7a5e080
commit d36f2ab9af
23 changed files with 2047 additions and 1740 deletions

View File

@@ -1,102 +0,0 @@
import React from 'react';
import { Clock, X, FileText, Trash2 } from 'lucide-react';
import { formatTimeAgo } from '../../../hooks/useWizardDraft';
interface DraftRecoveryPromptProps {
isOpen: boolean;
lastSaved: Date;
onRestore: () => void;
onDiscard: () => void;
onClose: () => void;
wizardName: string;
}
export const DraftRecoveryPrompt: React.FC<DraftRecoveryPromptProps> = ({
isOpen,
lastSaved,
onRestore,
onDiscard,
onClose,
wizardName
}) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-[60] flex items-center justify-center">
{/* Backdrop */}
<div
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
onClick={onClose}
/>
{/* Modal */}
<div className="relative w-full max-w-md bg-[var(--bg-primary)] rounded-xl shadow-2xl overflow-hidden">
{/* Header */}
<div className="px-6 py-4 border-b border-[var(--border-secondary)] bg-gradient-to-r from-[var(--color-warning)]/10 to-[var(--color-warning)]/5">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-full bg-[var(--color-warning)]/20 flex items-center justify-center">
<FileText className="w-5 h-5 text-[var(--color-warning)]" />
</div>
<div>
<h2 className="text-lg font-semibold text-[var(--text-primary)]">
Borrador Detectado
</h2>
<p className="text-sm text-[var(--text-secondary)]">
{wizardName}
</p>
</div>
</div>
<button
onClick={onClose}
className="p-1.5 hover:bg-[var(--bg-secondary)] rounded-lg transition-colors"
>
<X className="w-4 h-4 text-[var(--text-secondary)]" />
</button>
</div>
</div>
{/* Content */}
<div className="p-6 space-y-4">
{/* Info Card */}
<div className="p-4 bg-[var(--bg-secondary)] rounded-lg border border-[var(--border-secondary)]">
<div className="flex items-start gap-3">
<Clock className="w-5 h-5 text-[var(--text-tertiary)] mt-0.5 flex-shrink-0" />
<div className="flex-1">
<p className="text-sm text-[var(--text-primary)] font-medium mb-1">
Progreso guardado automáticamente
</p>
<p className="text-sm text-[var(--text-secondary)]">
Guardado {formatTimeAgo(lastSaved)}
</p>
</div>
</div>
</div>
{/* Description */}
<p className="text-sm text-[var(--text-secondary)]">
Encontramos un borrador de este formulario. ¿Deseas continuar desde donde lo dejaste o empezar de nuevo?
</p>
</div>
{/* Footer */}
<div className="px-6 py-4 border-t border-[var(--border-secondary)] bg-[var(--bg-secondary)] flex items-center gap-3">
<button
onClick={onDiscard}
className="flex-1 px-4 py-2.5 bg-[var(--bg-primary)] border border-[var(--border-secondary)] text-[var(--text-primary)] rounded-lg hover:bg-[var(--bg-tertiary)] transition-colors flex items-center justify-center gap-2 text-sm font-medium"
>
<Trash2 className="w-4 h-4" />
Descartar y Empezar de Nuevo
</button>
<button
onClick={onRestore}
className="flex-1 px-4 py-2.5 bg-[var(--color-primary)] text-white rounded-lg hover:bg-[var(--color-primary-dark)] transition-colors flex items-center justify-center gap-2 text-sm font-medium"
>
<FileText className="w-4 h-4" />
Restaurar Borrador
</button>
</div>
</div>
</div>
);
};

View File

@@ -1 +0,0 @@
export { DraftRecoveryPrompt } from './DraftRecoveryPrompt';

View File

@@ -19,6 +19,9 @@ export interface WizardStepProps {
currentStepIndex: number;
totalSteps: number;
goToStep: (index: number) => void;
// New architecture: dataRef and onDataChange passed from UnifiedAddWizard
dataRef?: React.MutableRefObject<any>;
onDataChange?: (data: any) => void;
}
interface WizardModalProps {
@@ -29,6 +32,9 @@ interface WizardModalProps {
steps: WizardStep[];
icon?: React.ReactNode;
size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
// New architecture: optional dataRef and onDataChange for wizards that use them
dataRef?: React.MutableRefObject<any>;
onDataChange?: (data: any) => void;
}
export const WizardModal: React.FC<WizardModalProps> = ({
@@ -38,7 +44,9 @@ export const WizardModal: React.FC<WizardModalProps> = ({
title,
steps,
icon,
size = 'xl'
size = 'xl',
dataRef,
onDataChange
}) => {
const [currentStepIndex, setCurrentStepIndex] = useState(0);
const [isValidating, setIsValidating] = useState(false);
@@ -55,12 +63,36 @@ export const WizardModal: React.FC<WizardModalProps> = ({
'2xl': 'max-w-7xl'
};
const handleClose = useCallback(() => {
setCurrentStepIndex(0);
onClose();
}, [onClose]);
const handleComplete = useCallback(() => {
onComplete();
handleClose();
}, [onComplete, handleClose]);
const goToStep = useCallback((index: number) => {
if (index >= 0 && index < steps.length) {
setCurrentStepIndex(index);
}
}, [steps.length]);
const handleBack = useCallback(() => {
setCurrentStepIndex(prev => Math.max(prev - 1, 0));
}, []);
const handleNext = useCallback(async () => {
// Access current step inside callback to avoid re-creating function on every render
const step = steps[currentStepIndex];
const lastStep = currentStepIndex === steps.length - 1;
// Validate current step if validator exists
if (currentStep.validate) {
if (step.validate) {
setIsValidating(true);
try {
const isValid = await currentStep.validate();
const isValid = await step.validate();
if (!isValid) {
setIsValidating(false);
return;
@@ -73,32 +105,12 @@ export const WizardModal: React.FC<WizardModalProps> = ({
setIsValidating(false);
}
if (isLastStep) {
if (lastStep) {
handleComplete();
} else {
setCurrentStepIndex(prev => Math.min(prev + 1, steps.length - 1));
}
}, [currentStep, isLastStep, steps.length]);
const handleBack = useCallback(() => {
setCurrentStepIndex(prev => Math.max(prev - 1, 0));
}, []);
const handleComplete = useCallback(() => {
onComplete();
handleClose();
}, [onComplete]);
const handleClose = useCallback(() => {
setCurrentStepIndex(0);
onClose();
}, [onClose]);
const goToStep = useCallback((index: number) => {
if (index >= 0 && index < steps.length) {
setCurrentStepIndex(index);
}
}, [steps.length]);
}, [steps, currentStepIndex, handleComplete]);
if (!isOpen) return null;
@@ -184,6 +196,8 @@ export const WizardModal: React.FC<WizardModalProps> = ({
currentStepIndex={currentStepIndex}
totalSteps={steps.length}
goToStep={goToStep}
dataRef={dataRef}
onDataChange={onDataChange}
/>
</div>