build: migrate to vite and update dependencies
Migrates the React app from Create React App (CRA) to Vite for faster build times and improved development experience. Also updates all dependencies to their latest versions. BREAKING CHANGE: Removes react-scripts and CRA-related dependencies. The development and build processes now rely on Vite.
This commit is contained in:
134
kawruh-app/src/LoginPage.jsx
Normal file
134
kawruh-app/src/LoginPage.jsx
Normal file
@@ -0,0 +1,134 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const LoginPage = () => {
|
||||
const [loginType, setLoginType] = useState('email'); // 'email' or 'phone'
|
||||
const [identifier, setIdentifier] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const handleLogin = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!identifier || !password) {
|
||||
alert('Please fill in all fields.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (loginType === 'email') {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(identifier)) {
|
||||
alert('Please enter a valid email address.');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Basic phone number validation (e.g., starts with + and has digits)
|
||||
const phoneRegex = /^\+?[0-9\s-]{8,}$/;
|
||||
if (!phoneRegex.test(identifier)) {
|
||||
alert('Please enter a valid phone number.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Attempting to log in with ${loginType}: ${identifier}`);
|
||||
// In a real application, you would make an API call here
|
||||
alert(`Login successful with ${loginType}!`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen bg-gray-50 dark:bg-gray-900">
|
||||
<div className="w-full max-w-md p-8 space-y-6 bg-white rounded-lg shadow-md dark:bg-gray-800">
|
||||
<div className="text-center">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Welcome Back</h1>
|
||||
<p className="mt-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
Login to access your account.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex border border-gray-300 dark:border-gray-600 rounded-lg p-1">
|
||||
<button
|
||||
onClick={() => setLoginType('email')}
|
||||
className={`w-full py-2 text-sm font-medium rounded-md transition-all duration-300 ${
|
||||
loginType === 'email'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
Email
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setLoginType('phone')}
|
||||
className={`w-full py-2 text-sm font-medium rounded-md transition-all duration-300 ${
|
||||
loginType === 'phone'
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
Phone Number
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form className="space-y-4" onSubmit={handleLogin}>
|
||||
<div>
|
||||
<label htmlFor={loginType} className="sr-only">
|
||||
{loginType === 'email' ? 'Email' : 'Phone Number'}
|
||||
</label>
|
||||
<input
|
||||
id={loginType}
|
||||
name={loginType}
|
||||
type={loginType === 'email' ? 'email' : 'tel'}
|
||||
autoComplete={loginType}
|
||||
required
|
||||
value={identifier}
|
||||
onChange={(e) => setIdentifier(e.target.value)}
|
||||
className="w-full px-4 py-2 text-gray-900 bg-white border border-gray-300 rounded-lg appearance-none focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
placeholder={loginType === 'email' ? 'name@company.com' : '+1 (555) 000-0000'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="password" className="sr-only">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
required
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full px-4 py-2 text-gray-900 bg-white border border-gray-300 rounded-lg appearance-none focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
id="remember-me"
|
||||
name="remember-me"
|
||||
type="checkbox"
|
||||
className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
/>
|
||||
<label htmlFor="remember-me" className="ml-2 text-sm text-gray-600 dark:text-gray-300">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<a href="#" className="font-medium text-blue-600 hover:underline dark:text-blue-500">
|
||||
Forgot password?
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-gray-800"
|
||||
>
|
||||
Sign In
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
Reference in New Issue
Block a user