نسخ من RaghadAlkhous/RestaurantDash
368 أسطر
12 KiB
JavaScript
368 أسطر
12 KiB
JavaScript
import React, { useState } from 'react';
|
||
import { TextField, Button, Typography, Stack, Box, IconButton, InputAdornment } from '@mui/material';
|
||
import { useTheme } from '@mui/material/styles';
|
||
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
|
||
import { VisibilityOutlined } from '@mui/icons-material';
|
||
import SidePanel from './SidePanel';
|
||
import { useNavigate, Link } from 'react-router-dom';
|
||
import authService from '../../../services/authService';
|
||
|
||
const LoginForm = () => {
|
||
const navigate = useNavigate();
|
||
const theme = useTheme();
|
||
|
||
const [showPassword, setShowPassword] = useState(false);
|
||
const [email, setEmail] = useState('');
|
||
const [password, setPassword] = useState('');
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState('');
|
||
|
||
const handleTogglePassword = () => {
|
||
setShowPassword(prev => !prev);
|
||
};
|
||
|
||
const handleLogin = async () => {
|
||
setLoading(true);
|
||
setError('');
|
||
|
||
const result = await authService.login(email, password);
|
||
|
||
if (!result.success) {
|
||
setError(result.message || 'Login failed');
|
||
setLoading(false);
|
||
return;
|
||
}
|
||
|
||
|
||
localStorage.setItem('token', result.data.token);
|
||
localStorage.setItem('refresh_token', result.data.refresh_token);
|
||
|
||
setLoading(false);
|
||
|
||
// الانتقال للداشبورد مع منع الرجوع
|
||
navigate('/dashboard', { replace: true });
|
||
};
|
||
|
||
return (
|
||
<Box
|
||
bgcolor={"background.default"}
|
||
color={"text.primary"}
|
||
display="flex"
|
||
sx={{
|
||
width: '100vw',
|
||
height: '100vh',
|
||
overflow: 'auto',
|
||
scrollbarWidth: 'none',
|
||
'&::-webkit-scrollbar': {
|
||
display: 'none',
|
||
},
|
||
}}
|
||
>
|
||
<SidePanel />
|
||
<Box
|
||
sx={{
|
||
marginLeft: { xs: 0, sm: '50%' },
|
||
width: { xs: '100%', sm: '50%', md: '70%' },
|
||
}}
|
||
>
|
||
<Box
|
||
flex={1}
|
||
paddingTop={4}
|
||
paddingBottom={4}
|
||
paddingLeft={2}
|
||
paddingRight={2}
|
||
sx={{
|
||
backgroundColor: '#FFFFFF',
|
||
minHeight: '10vh',
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
position: 'sticky',
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
width: {
|
||
xs: '120%',
|
||
sm: '100%',
|
||
md: '150%',
|
||
lg: '150%'
|
||
},
|
||
maxWidth: '600px'
|
||
}}
|
||
>
|
||
<Stack spacing={2}>
|
||
|
||
{/* الشعار */}
|
||
<Box>
|
||
<img
|
||
src="/image.png"
|
||
alt="logo"
|
||
style={{
|
||
width: '4vw',
|
||
maxWidth: '80px',
|
||
height: 'auto',
|
||
objectFit: 'contain'
|
||
}}
|
||
/>
|
||
</Box>
|
||
|
||
{/* عنوان تسجيل الدخول */}
|
||
<Typography variant="h4" fontWeight={700} sx={{ fontSize: { xs: '1.8rem', sm: '2rem', md: '2.2rem' } }}>
|
||
Login
|
||
</Typography>
|
||
|
||
<Typography variant="body2" color="text.secondary" fontWeight={500} sx={{ pb: 1 }}>
|
||
Enter your username and password to access your account securely. Welcome back to our service!
|
||
</Typography>
|
||
|
||
{/* إدخال البريد */}
|
||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
|
||
Email
|
||
</Typography>
|
||
<TextField
|
||
placeholder="Enter your email"
|
||
type="email"
|
||
variant="outlined"
|
||
fullWidth
|
||
value={email}
|
||
onChange={e => setEmail(e.target.value)}
|
||
sx={{
|
||
'& input': { fontWeight: 500, fontSize: '15px' },
|
||
'& input::placeholder': { color: '#969BA7' },
|
||
'& .MuiOutlinedInput-root': {
|
||
borderRadius: '10px',
|
||
transition: '0.3s',
|
||
'&.Mui-focused fieldset': {
|
||
borderColor: theme.palette.primary.main,
|
||
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)'
|
||
}
|
||
},
|
||
'& .MuiOutlinedInput-root.Mui-focused': {
|
||
borderColor: '#3f51b5',
|
||
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)'
|
||
}
|
||
}}
|
||
/>
|
||
</Box>
|
||
|
||
{/* إدخال كلمة السر */}
|
||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
|
||
Password
|
||
</Typography>
|
||
<TextField
|
||
type={showPassword ? 'text' : 'password'}
|
||
placeholder="Enter your password"
|
||
fullWidth
|
||
variant="outlined"
|
||
autoComplete="new-password"
|
||
value={password}
|
||
onChange={e => setPassword(e.target.value)}
|
||
sx={{
|
||
'& input': { fontWeight: 500, fontSize: '15px' },
|
||
'& input::placeholder': { color: '#969BA7' },
|
||
'& .MuiOutlinedInput-root': {
|
||
borderRadius: '10px',
|
||
transition: '0.3s',
|
||
'&.Mui-focused fieldset': {
|
||
borderColor: theme.palette.primary.main,
|
||
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)'
|
||
}
|
||
},
|
||
'& .MuiOutlinedInput-root.Mui-focused': {
|
||
borderColor: '#3f51b5',
|
||
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)'
|
||
},
|
||
'& input::-ms-reveal, & input::-ms-clear': {
|
||
display: 'none',
|
||
},
|
||
}}
|
||
InputProps={{
|
||
endAdornment: (
|
||
<InputAdornment position="end">
|
||
<IconButton onClick={handleTogglePassword} edge="end">
|
||
{showPassword ? <VisibilityOffOutlinedIcon /> : <VisibilityOutlined />}
|
||
</IconButton>
|
||
</InputAdornment>
|
||
)
|
||
}}
|
||
/>
|
||
</Box>
|
||
|
||
{/* عرض الخطأ */}
|
||
{error && (
|
||
<Typography color="error" textAlign="center">
|
||
{error}
|
||
</Typography>
|
||
)}
|
||
|
||
{/* زر تسجيل الدخول */}
|
||
<Box sx={{ pt: 2 }}>
|
||
<Button
|
||
variant="contained"
|
||
fullWidth
|
||
onClick={handleLogin}
|
||
disabled={loading}
|
||
sx={{
|
||
fontFamily: 'PlusJakartaSans',
|
||
fontWeight: 600,
|
||
fontSize: { xs: '14px', sm: '16px' },
|
||
height: { xs: '45px', sm: '52px' },
|
||
borderRadius: '50px',
|
||
textTransform: 'none',
|
||
color: 'white',
|
||
backgroundColor: theme.palette.primary.main,
|
||
'&:hover': {
|
||
backgroundColor: theme.palette.primary.hover
|
||
}
|
||
}}
|
||
>
|
||
{loading ? 'Loading...' : 'Log in'}
|
||
</Button>
|
||
</Box>
|
||
|
||
{/* Divider */}
|
||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, py: 2 }}>
|
||
<Box sx={{ flex: 1, height: '1px', backgroundColor: '#E0E0E0' }} />
|
||
<Typography variant="body1" sx={{ fontWeight: 500, fontSize: '16px', color: 'black' , fontFamily: 'PlusJakartaSans' }}>
|
||
Or
|
||
</Typography>
|
||
<Box sx={{ flex: 1, height: '1px', backgroundColor: '#E0E0E0' }} />
|
||
</Box>
|
||
|
||
{/* Google Button */}
|
||
<Button
|
||
variant="outlined"
|
||
fullWidth
|
||
sx={{
|
||
fontWeight: 500,
|
||
fontSize: '16px',
|
||
borderRadius: '50px',
|
||
height: '50px',
|
||
textTransform: 'none',
|
||
gap: 1,
|
||
borderColor: '#E6E6E6',
|
||
color: 'black',
|
||
'&:hover': {
|
||
borderColor: 'black',
|
||
backgroundColor: 'transparent'
|
||
}
|
||
, fontFamily: 'PlusJakartaSans'
|
||
}}
|
||
>
|
||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||
<img
|
||
src="https://upload.wikimedia.org/wikipedia/commons/c/c1/Google_%22G%22_logo.svg"
|
||
alt="Google"
|
||
style={{ width: 25, height: 25 }}
|
||
/>
|
||
</Box>
|
||
Login with Google
|
||
</Button>
|
||
|
||
{/* Facebook Button */}
|
||
<Button
|
||
variant="outlined"
|
||
fullWidth
|
||
sx={{
|
||
fontWeight: 500,
|
||
fontSize: '16px',
|
||
borderRadius: '50px',
|
||
height: '50px',
|
||
textTransform: 'none',
|
||
gap: 1,
|
||
borderColor: '#E6E6E6',
|
||
color: 'black',
|
||
'&:hover': {
|
||
borderColor: 'black',
|
||
backgroundColor: 'transparent'
|
||
}
|
||
, fontFamily: 'PlusJakartaSans'
|
||
}}
|
||
>
|
||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||
<img
|
||
src="https://upload.wikimedia.org/wikipedia/commons/0/05/Facebook_Logo_%282019%29.png"
|
||
alt="Facebook"
|
||
style={{ width: 25, height: 25 }}
|
||
/>
|
||
</Box>
|
||
Login with Facebook
|
||
</Button>
|
||
|
||
|
||
{/* Register Link */}
|
||
<Typography
|
||
variant="body2"
|
||
sx={{
|
||
fontSize: '16px',
|
||
textAlign: 'center',
|
||
color: '#969BA7',
|
||
pt: 3
|
||
}}
|
||
>
|
||
Don’t have an account?{' '}
|
||
<Link
|
||
to="/register"
|
||
style={{
|
||
color: '#2261FF',
|
||
textDecoration: 'none'
|
||
}}
|
||
>
|
||
Register
|
||
</Link>
|
||
</Typography>
|
||
|
||
{/* ForgetPassword Link */}
|
||
<Typography
|
||
variant="body2"
|
||
sx={{
|
||
fontSize: '14px',
|
||
textAlign: 'center',
|
||
color: '#969BA7',
|
||
pt: 3
|
||
}}
|
||
>
|
||
Did you forget the password?{' '}
|
||
<Link
|
||
to="/forget"
|
||
style={{
|
||
color: '#2261FF',
|
||
textDecoration: 'none'
|
||
}}
|
||
>
|
||
Forget Password
|
||
</Link>
|
||
</Typography>
|
||
|
||
{/* Terms */}
|
||
<Typography
|
||
variant="caption"
|
||
sx={{
|
||
fontSize: '14px',
|
||
textAlign: 'center',
|
||
color: '#969BA7',
|
||
pt: 5
|
||
}}
|
||
>
|
||
By logging in, I agree to the{' '}
|
||
<a href="#" style={{ color: '#2261FF', textDecoration: 'none' }}>
|
||
Terms of Service
|
||
</a>{' '}
|
||
and{' '}
|
||
<a href="#" style={{ color: '#2261FF', textDecoration: 'none' }}>
|
||
Privacy Policy
|
||
</a>.
|
||
</Typography>
|
||
</Stack>
|
||
</Box>
|
||
</Box>
|
||
</Box>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
export default LoginForm;
|