feat: Setup project with Vite and React

Initializes the Condopay frontend project using Vite, React, and TypeScript. Includes basic project structure, dependencies, and configuration for Tailwind CSS and React Router.
This commit is contained in:
2025-12-06 18:55:48 +01:00
parent 559c340f22
commit 79e249b638
26 changed files with 2364 additions and 8 deletions

98
pages/Login.tsx Normal file
View File

@@ -0,0 +1,98 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { CondoService } from '../services/mockDb';
import { Building, Lock, Mail, AlertCircle } from 'lucide-react';
export const LoginPage: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setLoading(true);
try {
await CondoService.login(email, password);
navigate('/');
} catch (err) {
setError('Credenziali non valide o errore di connessione.');
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen bg-slate-50 flex items-center justify-center p-4">
<div className="bg-white rounded-2xl shadow-xl w-full max-w-sm sm:max-w-md overflow-hidden">
<div className="bg-blue-600 p-8 text-center">
<div className="inline-flex p-3 bg-white/20 rounded-xl mb-4">
<Building className="w-10 h-10 text-white" />
</div>
<h1 className="text-2xl font-bold text-white">CondoPay</h1>
<p className="text-blue-100 mt-2">Gestione Condominiale Semplice</p>
</div>
<div className="p-6 sm:p-8">
<form onSubmit={handleSubmit} className="space-y-6">
{error && (
<div className="bg-red-50 text-red-600 p-3 rounded-lg text-sm flex items-center gap-2">
<AlertCircle className="w-4 h-4 flex-shrink-0" />
{error}
</div>
)}
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Email</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Mail className="h-5 w-5 text-slate-400" />
</div>
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="block w-full pl-10 pr-3 py-2.5 border border-slate-300 rounded-lg focus:ring-blue-500 focus:border-blue-500 outline-none transition-all"
placeholder="admin@condominio.it"
/>
</div>
</div>
<div>
<label className="block text-sm font-medium text-slate-700 mb-2">Password</label>
<div className="relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-slate-400" />
</div>
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="block w-full pl-10 pr-3 py-2.5 border border-slate-300 rounded-lg focus:ring-blue-500 focus:border-blue-500 outline-none transition-all"
placeholder="••••••••"
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-70 transition-colors"
>
{loading ? 'Accesso in corso...' : 'Accedi'}
</button>
</form>
<div className="mt-6 text-center text-xs text-slate-400">
&copy; 2024 CondoPay Manager
</div>
</div>
</div>
</div>
);
};