Initial commit - restaurant dashboard

هذا الالتزام موجود في:
RaghadMAlkous
2025-09-04 01:17:15 +03:00
الأصل 13891b47fd
التزام 7b2f8840cb
136 ملفات معدلة مع 16638 إضافات و6033 حذوفات

عرض الملف

@@ -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&nbsp;
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>Terms of Service</a> and&nbsp;
<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&nbsp;
<a href="#" style={{ color: '#007bff', textDecoration: 'none' }}>
Terms of Service
</a>{' '}
and&nbsp;
<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;