Fix new Frontend 2

This commit is contained in:
Urtzi Alfaro
2025-08-03 19:49:57 +02:00
parent 11ab73ae97
commit 5b16545a0d
7 changed files with 782 additions and 274 deletions

View File

@@ -1,247 +1,3 @@
{/* Register Form */}
<div className="bg-white py-8 px-6 shadow-strong rounded-3xl">
<div className="space-y-6">
{/* Full Name Field */}
<div>
<label htmlFor="fullName" className="block text-sm font-medium text-gray-700 mb-2">
Nombre completo
</label>
<input
id="fullName"
name="fullName"
type="text"
autoComplete="name"
required
value={formData.fullName}
onChange={handleInputChange}
className={`
appearance-none relative block w-full px-4 py-3 border rounded-xl
placeholder-gray-400 text-gray-900 focus:outline-none focus:ring-2
focus:ring-primary-500 focus:border-primary-500 focus:z-10
transition-all duration-200
${errors.fullName
? 'border-red-300 bg-red-50'
: 'border-gray-300 hover:border-gray-400'
}
`}
placeholder="Tu nombre completo"
/>
{errors.fullName && (
<p className="mt-1 text-sm text-red-600">{errors.fullName}</p>
)}
</div>
{/* Email Field */}
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
Correo electrónico
</label>
<input
id="email"
name="email"
type="email"
autoComplete="email"
required
value={formData.email}
onChange={handleInputChange}
className={`
appearance-none relative block w-full px-4 py-3 border rounded-xl
placeholder-gray-400 text-gray-900 focus:outline-none focus:ring-2
focus:ring-primary-500 focus:border-primary-500 focus:z-10
transition-all duration-200
${errors.email
? 'border-red-300 bg-red-50'
: 'border-gray-300 hover:border-gray-400'
}
`}
placeholder="tu@panaderia.com"
/>
{errors.email && (
<p className="mt-1 text-sm text-red-600">{errors.email}</p>
)}
</div>
{/* Password Field */}
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-2">
Contraseña
</label>
<div className="relative">
<input
id="password"
name="password"
type={showPassword ? 'text' : 'password'}
autoComplete="new-password"
required
value={formData.password}
onChange={handleInputChange}
className={`
appearance-none relative block w-full px-4 py-3 pr-12 border rounded-xl
placeholder-gray-400 text-gray-900 focus:outline-none focus:ring-2
focus:ring-primary-500 focus:border-primary-500 focus:z-10
transition-all duration-200
${errors.password
? 'border-red-300 bg-red-50'
: 'border-gray-300 hover:border-gray-400'
}
`}
placeholder="••••••••"
/>
<button
type="button"
className="absolute inset-y-0 right-0 pr-3 flex items-center"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="h-5 w-5 text-gray-400 hover:text-gray-600" />
) : (
<Eye className="h-5 w-5 text-gray-400 hover:text-gray-600" />
)}
</button>
</div>
{/* Password Strength Indicator */}
{formData.password && (
<div className="mt-2">
<div className="flex space-x-1">
{[...Array(5)].map((_, i) => (
<div
key={i}
className={`h-1 flex-1 rounded ${
i < passwordStrength ? strengthColors[passwordStrength - 1] : 'bg-gray-200'
}`}
/>
))}
</div>
<p className="text-xs text-gray-600 mt-1">
Seguridad: {strengthLabels[passwordStrength - 1] || 'Muy débil'}
</p>
</div>
)}
{errors.password && (
<p className="mt-1 text-sm text-red-600">{errors.password}</p>
)}
</div>
{/* Confirm Password Field */}
<div>
<label htmlFor="confirmPassword" className="block text-sm font-medium text-gray-700 mb-2">
Confirmar contraseña
</label>
<div className="relative">
<input
id="confirmPassword"
name="confirmPassword"
type={showConfirmPassword ? 'text' : 'password'}
autoComplete="new-password"
required
value={formData.confirmPassword}
onChange={handleInputChange}
className={`
appearance-none relative block w-full px-4 py-3 pr-12 border rounded-xl
placeholder-gray-400 text-gray-900 focus:outline-none focus:ring-2
focus:ring-primary-500 focus:border-primary-500 focus:z-10
transition-all duration-200
${errors.confirmPassword
? 'border-red-300 bg-red-50'
: formData.confirmPassword && formData.password === formData.confirmPassword
? 'border-green-300 bg-green-50'
: 'border-gray-300 hover:border-gray-400'
}
`}
placeholder="••••••••"
/>
<button
type="button"
className="absolute inset-y-0 right-0 pr-3 flex items-center"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
>
{showConfirmPassword ? (
<EyeOff className="h-5 w-5 text-gray-400 hover:text-gray-600" />
) : (
<Eye className="h-5 w-5 text-gray-400 hover:text-gray-600" />
)}
</button>
{formData.confirmPassword && formData.password === formData.confirmPassword && (
<div className="absolute inset-y-0 right-10 flex items-center">
<Check className="h-5 w-5 text-green-500" />
</div>
)}
</div>
{errors.confirmPassword && (
<p className="mt-1 text-sm text-red-600">{errors.confirmPassword}</p>
)}
</div>
{/* Terms and Conditions */}
<div>
<div className="flex items-start">
<input
id="acceptTerms"
name="acceptTerms"
type="checkbox"
checked={formData.acceptTerms}
onChange={handleInputChange}
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded mt-0.5"
/>
<label htmlFor="acceptTerms" className="ml-2 block text-sm text-gray-700">
Acepto los{' '}
<a href="#" className="font-medium text-primary-600 hover:text-primary-500">
términos y condiciones
</a>{' '}
y la{' '}
<a href="#" className="font-medium text-primary-600 hover:text-primary-500">
política de privacidad
</a>
</label>
</div>
{errors.acceptTerms && (
<p className="mt-1 text-sm text-red-600">{errors.acceptTerms}</p>
)}
</div>
{/* Submit Button */}
<div>
<button
type="button"
onClick={handleSubmit}
disabled={isLoading}
className={`
group relative w-full flex justify-center py-3 px-4 border border-transparent
text-sm font-medium rounded-xl text-white transition-all duration-200
focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500
${isLoading
? 'bg-gray-400 cursor-not-allowed'
: 'bg-primary-500 hover:bg-primary-600 hover:shadow-lg transform hover:-translate-y-0.5'
}
`}
>
{isLoading ? (
<>
<Loader2 className="h-5 w-5 mr-2 animate-spin" />
Creando cuenta...
</>
) : (
'Crear cuenta gratis'
)}
</button>
</div>
</div>
{/* Login Link */}
<div className="mt-6 text-center">
<p className="text-sm text-gray-600">
¿Ya tienes una cuenta?{' '}
<button
onClick={onNavigateToLogin}
className="font-medium text-primary-600 hover:text-primary-500 transition-colors"
>
Inicia sesión aquí
</button>
</p>
</div>
</div>import React, { useState } from 'react';
import { Eye, EyeOff, Loader2, Check } from 'lucide-react';
import toast from 'react-hot-toast';

View File

@@ -27,6 +27,27 @@ interface MetricsData {
}
const DashboardPage: React.FC<DashboardPageProps> = ({ user }) => {
const [isLoading, setIsLoading] = useState(true);
const [weather, setWeather] = useState<WeatherData | null>(null);
const [todayForecasts, setTodayForecasts] = useState<ForecastData[]>([]);
const [metrics, setMetrics] = useState<MetricsData>({
totalSales: 0,
wasteReduction: 0,
accuracy: 0,
stockouts: 0
});
// Sample historical data for charts
const salesHistory = [
{ date: '2024-10-28', ventas: 145, prediccion: 140 },
{ date: '2024-10-29', ventas: 128, prediccion: 135 },
{ date: '2024-10-30', ventas: 167, prediccion: 160 },
{ date: '2024-10-31', ventas: 143, prediccion: 145 },
{ date: '2024-11-01', ventas: 156, prediccion: 150 },
{ date: '2024-11-02', ventas: 189, prediccion: 185 },
{ date: '2024-11-03', ventas: 134, prediccion: 130 },
];
const topProducts = [
{ name: 'Croissants', quantity: 45, trend: 'up' },
{ name: 'Pan de molde', quantity: 32, trend: 'up' },
@@ -405,25 +426,4 @@ const DashboardPage: React.FC<DashboardPageProps> = ({ user }) => {
);
};
export default DashboardPage; [isLoading, setIsLoading] = useState(true);
const [weather, setWeather] = useState<WeatherData | null>(null);
const [todayForecasts, setTodayForecasts] = useState<ForecastData[]>([]);
const [metrics, setMetrics] = useState<MetricsData>({
totalSales: 0,
wasteReduction: 0,
accuracy: 0,
stockouts: 0
});
// Sample historical data for charts
const salesHistory = [
{ date: '2024-10-28', ventas: 145, prediccion: 140 },
{ date: '2024-10-29', ventas: 128, prediccion: 135 },
{ date: '2024-10-30', ventas: 167, prediccion: 160 },
{ date: '2024-10-31', ventas: 143, prediccion: 145 },
{ date: '2024-11-01', ventas: 156, prediccion: 150 },
{ date: '2024-11-02', ventas: 189, prediccion: 185 },
{ date: '2024-11-03', ventas: 134, prediccion: 130 },
];
const
export default DashboardPage;