نسخ من RaghadAlkhous/RestaurantDash
Initial commit - restaurant dashboard
هذا الالتزام موجود في:
@@ -1,147 +1,226 @@
|
||||
// EmailInputSection.js
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Button, TextField, Typography ,useTheme} from '@mui/material';
|
||||
import { Box, Button, TextField, Typography, useTheme, Snackbar, Alert } from '@mui/material';
|
||||
import authService from '../../../services/authService';
|
||||
|
||||
const EmailInputSection = ({ emailOrPhone, setEmailOrPhone }) => {
|
||||
const theme = useTheme();
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const slides = [0, 1, 2, 3];
|
||||
const EmailInputSection = ({ emailOrPhone, setEmailOrPhone, onStepComplete }) => {
|
||||
const theme = useTheme();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleSend = () => {
|
||||
// عملية الإرسال
|
||||
};
|
||||
// حالات Snackbar
|
||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||
const [snackbarMessage, setSnackbarMessage] = useState('');
|
||||
const [snackbarSeverity, setSnackbarSeverity] = useState('success');
|
||||
const [inputError, setInputError] = useState('');
|
||||
|
||||
const handleNext = () => {
|
||||
if (currentSlide < slides.length - 1) {
|
||||
setCurrentSlide(prev => prev + 1);
|
||||
}
|
||||
};
|
||||
const handleCloseSnackbar = (event, reason) => {
|
||||
if (reason === 'clickaway') return;
|
||||
setSnackbarOpen(false);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
if (currentSlide > 0) {
|
||||
setCurrentSlide(prev => prev - 1);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Box
|
||||
component="img"
|
||||
src="/image.png"
|
||||
alt="logo"
|
||||
sx={{
|
||||
width: { xs: '5vh', sm: '7vh' },
|
||||
maxWidth: { xs: '40px', sm: '80px' },
|
||||
height: 'auto',
|
||||
objectFit: 'contain',
|
||||
overflow: 'auto',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
const validateEmail = (email) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
<Typography
|
||||
variant="h4"
|
||||
fontWeight={700}
|
||||
sx={{
|
||||
fontSize: {
|
||||
xs: '1.8rem',
|
||||
sm: '2rem',
|
||||
md: '2.2rem'
|
||||
}
|
||||
}}
|
||||
>
|
||||
Forget Password
|
||||
</Typography>
|
||||
const handleSend = async () => {
|
||||
setInputError(''); // مسح الأخطاء السابقة
|
||||
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Enter your email to reset it and regain access to your account.
|
||||
</Typography>
|
||||
if (!emailOrPhone) {
|
||||
setInputError("Please enter your email.");
|
||||
return;
|
||||
}
|
||||
|
||||
<Box sx={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="black"
|
||||
sx={{
|
||||
fontWeight: '500',
|
||||
fontSize: '16px'
|
||||
}}
|
||||
>
|
||||
Email/Phone
|
||||
</Typography>
|
||||
<TextField
|
||||
placeholder="Enter your email"
|
||||
type="email"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={emailOrPhone}
|
||||
onChange={(e) => setEmailOrPhone(e.target.value)}
|
||||
sx={{
|
||||
'& input': {
|
||||
fontWeight: 500,
|
||||
fontSize: '15px'
|
||||
},
|
||||
'& input::placeholder': {
|
||||
color: '#969BA7'
|
||||
},
|
||||
'& .MuiOutlinedInput-root': {
|
||||
borderRadius: '10px',
|
||||
transition: '0.3s',
|
||||
'&.Mui-focused fieldset': { // أضف هذا الجزء لتغيير لون الحدود عند التركيز
|
||||
borderColor: '#FF914D',
|
||||
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>
|
||||
if (!validateEmail(emailOrPhone)) {
|
||||
setInputError("Please enter a valid email address.");
|
||||
return;
|
||||
}
|
||||
|
||||
{/* send */}
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
onClick={handleSend}
|
||||
sx={{
|
||||
color:'white',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: '30px',
|
||||
textTransform: 'none',
|
||||
fontWeight: 600,
|
||||
fontSize: '16px',
|
||||
height: '48px',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.primary.hover ,
|
||||
transition: 'all 0.4s ease'
|
||||
}
|
||||
}}
|
||||
>
|
||||
Send
|
||||
</Button>
|
||||
setLoading(true);
|
||||
const response = await authService.resetPassword(emailOrPhone);
|
||||
setLoading(false);
|
||||
|
||||
<Typography
|
||||
textAlign="center"
|
||||
fontWeight={500}
|
||||
sx={{
|
||||
fontSize: '16px',
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
mx: 'auto',
|
||||
color: '#969BA7'
|
||||
}}
|
||||
>
|
||||
By log in, I agree to the
|
||||
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>Terms of Service</a> and
|
||||
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>Privacy Policy</a>
|
||||
</Typography>
|
||||
</>
|
||||
);
|
||||
if (response.success !== false) {
|
||||
setSnackbarMessage("A reset code has been sent to your email.");
|
||||
setSnackbarSeverity('success');
|
||||
setSnackbarOpen(true);
|
||||
|
||||
setTimeout(() => {
|
||||
if (onStepComplete) onStepComplete();
|
||||
}, 5000);
|
||||
|
||||
} else {
|
||||
setInputError('');
|
||||
let errorMessage = "";
|
||||
if (response.errors) {
|
||||
const firstError = Object.values(response.errors)[0];
|
||||
errorMessage = Array.isArray(firstError) ? firstError[0] : firstError;
|
||||
} else if (response.message) {
|
||||
errorMessage = response.message;
|
||||
} else {
|
||||
errorMessage = "Failed to send reset code.";
|
||||
}
|
||||
|
||||
if (
|
||||
errorMessage.toLowerCase().includes("not found") ||
|
||||
errorMessage.toLowerCase().includes("not registered") ||
|
||||
errorMessage.toLowerCase().includes("doesn't exist") ||
|
||||
errorMessage.toLowerCase().includes("email")
|
||||
) {
|
||||
setInputError("This email is not registered.");
|
||||
} else if (errorMessage.toLowerCase().includes("invalid credentials")) {
|
||||
setInputError("Email or password is incorrect.");
|
||||
} else {
|
||||
setSnackbarMessage(errorMessage);
|
||||
setSnackbarSeverity('error');
|
||||
setSnackbarOpen(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '100%' }}>
|
||||
<Box>
|
||||
<Box
|
||||
component="img"
|
||||
src="/image.png"
|
||||
alt="logo"
|
||||
sx={{
|
||||
width: { xs: '5vh', sm: '7vh' },
|
||||
maxWidth: { xs: '40px', sm: '80px' },
|
||||
height: 'auto',
|
||||
objectFit: 'contain',
|
||||
overflow: 'auto',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': { display: 'none' },
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Typography
|
||||
variant="h4"
|
||||
fontWeight={700}
|
||||
sx={{ fontSize: { xs: '1.8rem', sm: '2rem', md: '2.2rem' } }}
|
||||
>
|
||||
Forget Password
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body1" color="text.secondary" mb={2}>
|
||||
Enter your email to reset it and regain access to your account.
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 1, mb: 2 }}>
|
||||
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
|
||||
Email
|
||||
</Typography>
|
||||
<TextField
|
||||
placeholder="Enter your email"
|
||||
type="email"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={emailOrPhone}
|
||||
onChange={(e) => setEmailOrPhone(e.target.value)}
|
||||
error={!!inputError}
|
||||
helperText={inputError}
|
||||
sx={{
|
||||
'& input': { fontWeight: 500, fontSize: '15px' },
|
||||
'& input::placeholder': { color: '#969BA7' },
|
||||
'& .MuiOutlinedInput-root': {
|
||||
borderRadius: '10px',
|
||||
transition: '0.3s',
|
||||
'&.Mui-focused fieldset': {
|
||||
borderColor: '#FF914D',
|
||||
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>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
onClick={handleSend}
|
||||
disabled={loading}
|
||||
sx={{
|
||||
color: 'white',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
borderRadius: '30px',
|
||||
textTransform: 'none',
|
||||
fontWeight: 600,
|
||||
fontSize: '16px',
|
||||
height: '48px',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.primary.hover,
|
||||
transition: 'all 0.4s ease',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{loading ? "Sending..." : "Send"}
|
||||
</Button>
|
||||
{/*
|
||||
<Typography
|
||||
textAlign="center"
|
||||
fontWeight={500}
|
||||
sx={{ fontSize: '16px', width: '100%', mx: 'auto', color: '#969BA7', mt: 2 }}
|
||||
>
|
||||
By log in, I agree to the
|
||||
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>
|
||||
Terms of Service
|
||||
</a>{' '}
|
||||
and
|
||||
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>
|
||||
Privacy Policy
|
||||
</a>
|
||||
</Typography> */}
|
||||
|
||||
{/* Terms */}
|
||||
<Typography
|
||||
// variant="caption"
|
||||
textAlign="center"
|
||||
fontWeight={500}
|
||||
|
||||
sx={{ fontSize: '16px', width: '100%', mx: 'auto', color: '#969BA7', mt: 2 }}
|
||||
|
||||
>
|
||||
By logging in, I agree to the{' '}
|
||||
<Box
|
||||
component="span"
|
||||
sx={{ color: '#2261FF', cursor: 'pointer', textDecoration: 'none' }}
|
||||
onClick={() => window.open('/terms', 'TermsOfService')}
|
||||
>
|
||||
Terms of Service
|
||||
</Box>{' '}
|
||||
and{' '}
|
||||
<Box
|
||||
component="span"
|
||||
sx={{ color: '#2261FF', cursor: 'pointer', textDecoration: 'none' }}
|
||||
onClick={() => window.open('/privacy', 'PrivacyPolicy')}
|
||||
>
|
||||
Privacy Policy
|
||||
</Box>.
|
||||
</Typography>
|
||||
|
||||
<Snackbar
|
||||
open={snackbarOpen}
|
||||
autoHideDuration={4000}
|
||||
onClose={handleCloseSnackbar}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
|
||||
>
|
||||
<Alert
|
||||
onClose={handleCloseSnackbar}
|
||||
severity={snackbarSeverity}
|
||||
sx={{ width: { xs: '40%', sm: '60%', md: '100%' }, color: 'white', fontSize: '16px', fontWeight: '500', backgroundColor: '#e57f3f', borderRadius: 6, mb: 6 }}
|
||||
variant="filled"
|
||||
>
|
||||
{snackbarMessage}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmailInputSection;
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم