update the dashbord and router

هذا الالتزام موجود في:
raghad
2025-05-19 12:53:59 +03:00
الأصل 9b0d90560e
التزام aacc58c4a6
110 ملفات معدلة مع 6404 إضافات و44 حذوفات

عرض الملف

@@ -0,0 +1,132 @@
import React from 'react';
import { Box, TextField, Typography, Button, useTheme } from '@mui/material';
import { useNavigate } from 'react-router-dom';
const Congratulations = ({ emailOrPhone, setEmailOrPhone }) => {
const navigate = useNavigate();
const theme = useTheme();
return (
<Box
sx={{
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
overflow: 'auto',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
mt: { xs: 4, sm: 8, md: 2 } // هامش علوي متجاوب
}}
>
<Box
sx={{
marginTop: '90px',
position: 'relative',
width: 132,
height: 132,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Box
sx={{
position: 'absolute',
width: 139,
height: 139,
borderRadius: '50%',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: 0,
backgroundColor: '#FAFAFA'
}}
/>
<Box
sx={{
width: 120,
height: 120,
backgroundColor: '#E9EFFF',
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1,
}}
>
<img
src="/images/hand.png"
style={{ width: 60, height: 60, objectFit: 'contain' }}
/>
</Box>
</Box>
<Typography
variant="h4"
fontWeight={700}
marginTop={3}
marginBottom={2}
sx={{
fontSize: {
xs: '1.8rem',
sm: '2rem',
md: '2.2rem'
}
}}
>
Congratulations!
</Typography>
<Typography
variant="h4"
fontWeight={400}
width='390px'
marginLeft='20px'
sx={{
color: '#5F6868',
fontSize: {
xs: '0.8rem',
md: '1.1rem'
}
}}
>
Your password has been successfully updated. Thank you for choosing our service
</Typography>
{/* زر التنقل إلى صفحة تسجيل الدخول */}
<Button
variant="contained"
fullWidth
onClick={() => navigate('/login')}
sx={{
marginTop: '20px',
color: 'white',
backgroundColor: theme.palette.primary.main,
borderRadius: '30px',
textTransform: 'none',
fontWeight: 500,
fontSize: '16px',
height: '52px',
padding: '12px',
maxWidth: '390px',
px: 2,
'&:hover': {
backgroundColor: theme.palette.primary.hover,
transition: 'all 0.4s ease'
}
}}
>
Login
</Button>
</Box>
);
};
export default Congratulations;

عرض الملف

@@ -0,0 +1,147 @@
// EmailInputSection.js
import React, { useState } from 'react';
import { Box, Button, TextField, Typography ,useTheme} from '@mui/material';
const EmailInputSection = ({ emailOrPhone, setEmailOrPhone }) => {
const theme = useTheme();
const [currentSlide, setCurrentSlide] = useState(0);
const slides = [0, 1, 2, 3];
const handleSend = () => {
// عملية الإرسال
};
const handleNext = () => {
if (currentSlide < slides.length - 1) {
setCurrentSlide(prev => prev + 1);
}
};
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>
<Typography
variant="h4"
fontWeight={700}
sx={{
fontSize: {
xs: '1.8rem',
sm: '2rem',
md: '2.2rem'
}
}}
>
Forget Password
</Typography>
<Typography variant="body1" color="text.secondary">
Enter your email to reset it and regain access to your account.
</Typography>
<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>
{/* 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>
<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>
</>
);
};
export default EmailInputSection;

عرض الملف

@@ -0,0 +1,125 @@
import React, { useState } from 'react';
import { Box, Stack ,useTheme} from '@mui/material';
import Side from './Side';
import EmailInputSection from './EmailInputSection';
import OtpVerification from './OtpVerification';
import NewPassword from './NewPassword';
import Congratulations from './Congratulations';
const ForgetForm = () => {
const [emailOrPhone, setEmailOrPhone] = useState('');
const [currentSlide, setCurrentSlide] = useState(0);
const theme = useTheme();
const slides = [
{ component: EmailInputSection, title: "Email Verification" },
{ component: OtpVerification, title: "OTP Verification" },
{ component: NewPassword, title: "New Password" },
{ component: Congratulations, title: "Congratulations" }
];
const handleNext = () => {
if (currentSlide < slides.length - 1) {
setCurrentSlide(prev => prev + 1);
}
};
const handleBack = () => {
if (currentSlide > 0) {
setCurrentSlide(prev => prev - 1);
}
};
const CurrentComponent = slides[currentSlide].component;
return (
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', sm: 'row' },
minHeight: '100vh',
backgroundColor: '#fff',
}}
>
{/* ✅ Sidebar يظهر فقط من sm+ */}
<Box sx={{ width: { sm: '40%', xs: '0%' }, display: { xs: 'none', sm: 'block' } }}>
<Side currentStepIndex={currentSlide} onNext={handleNext} onBack={handleBack} />
</Box>
{/* ✅ Form */}
<Box
sx={{
width: { sm: '60%' },
minHeight: { xs: '100vh', sm: '130vh', md: '90vh' },
position: 'relative',
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-start',
paddingTop: { xs: 2, sm: 4 },
paddingLeft: { xs: 2, sm: 4 },
backgroundColor: '#fff',
}}
>
<Box
sx={{
width: '100%',
maxWidth: 686,
pr: { xs: 3, sm: 2, md: 1 },
pt: { xs: 2, sm: 4, md: 1 },
}}
>
<Stack spacing={2} alignItems="flex-start">
{/* إظهار المكون الحالي فقط */}
<CurrentComponent
emailOrPhone={emailOrPhone}
setEmailOrPhone={setEmailOrPhone}
/>
</Stack>
</Box>
{/* ✅ مؤشر الشرائح السفلي */}
<Box
sx={{
position: { xs: 'absolute', sm: 'absolute' },
bottom: { xs: '5%', sm: '-1%', md: '2%' },
left: '50%',
transform: 'translateX(-50%)',
display: 'flex',
gap: 1,
width: '80%',
maxWidth: 600,
justifyContent: 'center',
height: {
xs: 3,
sm: 5,
md: 6,
},
}}
>
{slides.map((_, index) => (
<Box
key={index}
sx={{
width: '100vh',
height: 5,
bgcolor: index === currentSlide ? theme.palette.primary.main : 'rgba(0, 0, 0, 0.2)',
borderRadius: 2,
cursor: 'pointer',
transition: 'background-color 0.3s',
}}
// onClick={() => setCurrentSlide(index)} // يمكنك تفعيلها لاحقًا
/>
))}
</Box>
</Box>
</Box>
);
};
export default ForgetForm;

عرض الملف

@@ -0,0 +1,217 @@
// EmailInputSection.js
import React, { useState } from 'react';
import { Box, Button, TextField, Typography } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { IconButton, InputAdornment } from '@mui/material';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import { VisibilityOutlined } from '@mui/icons-material';
const EmailInputSection = ({ emailOrPhone, setEmailOrPhone }) => {
const theme = useTheme();
const handleTogglePassword = () => {
setShowPassword((prev) => !prev);
};
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const [currentSlide, setCurrentSlide] = useState(0);
const slides = [0, 1, 2, 3];
const handleSend = () => {
// عملية الإرسال
};
const handleToggleConfirmPassword = () => {
setShowConfirmPassword((prev) => !prev);
};
const handleNext = () => {
if (currentSlide < slides.length - 1) {
setCurrentSlide(prev => prev + 1);
}
};
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'
}}
/>
</Box>
<Typography
variant="h4"
fontWeight={700}
sx={{
fontSize: {
xs: '1.8rem',
sm: '2rem',
md: '2.2rem'
}
}}
>
Create a New Password
</Typography>
<Typography variant="body1" color="text.secondary">
Enter your email to reset it and regai access to your account.
</Typography>
{/* Password Input */}
<Box sx={{ width: '100%', 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"
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)' // ظل برتقالي خفيف
}
},
'& input::-ms-reveal, & input::-ms-clear': {
display: 'none',
},
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleTogglePassword} edge="end">
{showPassword ? <VisibilityOffOutlinedIcon /> : <VisibilityOutlined />}
</IconButton>
</InputAdornment>
)
}}
/>
</Box>
{/* Confirm Password Input */}
<Box sx={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography
variant="body2"
color="black"
sx={{
fontWeight: '500',
fontSize: '16px'
}}
>
Confirm Password
</Typography>
<TextField
type={showConfirmPassword ? 'text' : 'password'}
placeholder="Confirm your password"
fullWidth
variant="outlined"
autoComplete="new-password"
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)'
},
'& input::-ms-reveal, & input::-ms-clear': {
display: 'none',
},
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleToggleConfirmPassword} edge="end">
{showConfirmPassword ? <VisibilityOffOutlinedIcon /> : <VisibilityOutlined />}
</IconButton>
</InputAdornment>
)
}}
/>
</Box>
{/* 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>
<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>
</>
);
};
export default EmailInputSection;

عرض الملف

@@ -0,0 +1,183 @@
import React, { useState, useRef } from 'react';
import { Box, TextField, Typography, Button, Stack ,useTheme} from '@mui/material';
const OtpVerification = () => {
const [emailOrPhone, setEmailOrPhone] = useState('');
const [currentSlide, setCurrentSlide] = useState(0);
const slides = [0, 1, 2, 3];
const [otp, setOtp] = useState(Array(7).fill(''));
const inputRefs = useRef(Array(7).fill().map(() => React.createRef()));
const handleSend = () => {
const otpCode = otp.join('');
console.log('Submitted OTP:', otpCode);
// عملية التحقق من الكود
};
const handleOtpChange = (e, index) => {
const value = e.target.value;
if (!/^[0-9]?$/.test(value)) return;
const newOtp = [...otp];
newOtp[index] = value;
setOtp(newOtp);
if (value && index < 6) {
inputRefs.current[index + 1].current.focus();
}
};
const handleKeyDown = (e, index) => {
if (e.key === 'Backspace' && !otp[index] && index > 0) {
inputRefs.current[index - 1].current.focus();
}
};
const handleNext = () => {
if (currentSlide < slides.length - 1) {
setCurrentSlide(prev => prev + 1);
}
};
const handleBack = () => {
if (currentSlide > 0) {
setCurrentSlide(prev => prev - 1);
}
};
const theme = useTheme();
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'
}}
/>
</Box>
<Typography
variant="h4"
fontWeight={700}
sx={{
fontSize: {
xs: '1.8rem',
sm: '2rem',
md: '2.2rem'
}
}}
>
Enter OTP Verification
</Typography>
<Typography variant="body1" color="text.secondary">
Kindly enter the OTP code sent to your registered email/phone for account verification.
</Typography>
<Box sx={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 1 }}>
<Stack
direction="row"
spacing={{ xs: 0, sm: 1, md: 1.5 }}
justifyContent={{ xs: 'center', sm: 'center', md: 'flex-start' }}
flexWrap="wrap"
sx={{
width: '100%',
px: { xs: 0, sm: '0.5rem', md: '1.5rem' },
gap: { xs: '1.5rem', sm: '1.5rem', md: '1rem' }
}}
>
{otp.map((digit, index) => (
<TextField
key={index}
inputRef={inputRefs.current[index]}
value={digit}
onChange={(e) => handleOtpChange(e, index)}
onKeyDown={(e) => handleKeyDown(e, index)}
inputProps={{
maxLength: 1,
style: {
textAlign: 'center',
fontSize: '20px',
},
}}
sx={{
width: { xs: '3rem', sm: '3.25rem', md: '4rem' },
height: { xs: '3rem', sm: '3.25rem', md: '4rem' },
'& .MuiOutlinedInput-root': {
borderRadius: '0.5rem',
height: '100%', // تأكيد تطابق الطول
'& fieldset': {
borderColor: '#ccc',
},
'&:hover fieldset': {
borderColor: theme.palette.primary.main,
},
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.main,
},
},
'& .MuiInputBase-input': {
color: theme.palette.primary.main,
textAlign: 'center',
fontSize: '20px',
padding: 0,
height: '100%',
},
}}
/>
))}
</Stack>
</Box>
<Button
variant="contained"
fullWidth
onClick={handleSend}
sx={{
color:'white',
backgroundColor: theme.palette.primary.main,
borderRadius: '30px',
textTransform: 'none',
fontWeight: 600,
fontSize: '16px',
width: '95%',
height: '48px',
'&:hover': {
backgroundColor: theme.palette.primary.hover ,
transition: 'all 0.4s ease'
}
}}
>
Send
</Button>
<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>
</>
);
};
export default OtpVerification;

عرض الملف

@@ -0,0 +1,187 @@
import React from 'react';
import { Box, Typography, Stack, Button ,useTheme } from '@mui/material';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
const steps = [
{
title: 'Forget Password',
description: 'Provide an email to change your password',
icon: '/images/icons/key.png',
},
{
title: 'Verify your email',
description: 'Enter your otp verification',
icon: '/images/icons/email.png',
},
{
title: 'Create a new password',
description: 'Create your a new password',
icon: '/images/icons/pen.png',
},
{
title: 'Welcome to KitchPlus app',
description: 'Get up and running in 3 minutes',
icon: '/images/icons/rocket.png',
},
];
const Side = ({ currentStepIndex, onNext, onBack }) => {
const theme = useTheme();
return (
<Box
sx={{
height: { xs: '100vh', sm: '130vh', md: '87.5vh' },
backgroundColor: '#FAFAFA',
px: { xs: 2, sm: 4 },
py: 5,
display: { xs: 'none', sm: 'block' },
position: 'relative',
}}
>
<Typography variant="h6" fontWeight={700} mb={2}>
Step for change your password
</Typography>
<Typography variant="body2" color="text.secondary" mb={4}>
Instructions for secure password modification. Follow simple steps for password change.
</Typography>
<Stack spacing={6} position="relative" sx={{ ml: 3 }}>
{steps.map((step, index) => (
<Box key={index} display="flex" alignItems="flex-start" gap={2} position="relative">
{index !== steps.length - 1 && (
<Box
sx={{
position: 'absolute',
left: '3.8vh',
top: '6vh',
width: '2px',
height: 'calc(100% + 24px)',
backgroundColor: '#e0e0e0',
zIndex: 0,
}}
/>
)}
<Box
sx={{
position: 'relative',
width: 50,
height: 53,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Box
sx={{
position: 'absolute',
width: 60,
height: 63,
borderRadius: '50%',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: 0,
backgroundImage:
index === currentStepIndex
? 'linear-gradient(0deg, #FF914D, #F3F3F3 )'
: 'none',
backgroundColor: index === currentStepIndex ? 'transparent' : '#F3F3F3',
}}
/>
<Box
sx={{
width: 50,
height: 53,
backgroundColor: '#FFFFFF',
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 1,
}}
>
<img
src={step.icon}
alt={step.title}
style={{ width: 24, height: 24, objectFit: 'contain' }}
/>
</Box>
</Box>
<Box>
<Typography variant="subtitle1" sx={{ fontSize: '16px', fontWeight: 600 }}>
{step.title}
</Typography>
<Typography variant="body2" sx={{ color: '#A0A0A0', fontSize: '12px', fontWeight: 500 }}>
{step.description}
</Typography>
</Box>
</Box>
))}
</Stack>
{/* ... (بقية محتوى الـ Side كما هو بدون تغيير) ... */}
{/* أزرار التنقل */}
<Box
sx={{
position: 'absolute',
bottom: 2,
left: '50%',
transform: 'translateX(-50%)',
width: '90%',
maxWidth: 600,
display: 'flex',
justifyContent: 'space-between',
px: 2,
}}
>
{/* Back */}
<Button
variant="text"
startIcon={<ArrowBackIosIcon sx={{ fontSize: '16px' }} />}
onClick={onBack}
disabled={currentStepIndex === 0}
sx={{
color: currentStepIndex === 0 ? '#C2C2C2' : '#6B7283',
minWidth: '100px',
fontWeight: 400,
fontSize: '16px',
textTransform: 'none',
'&:hover': {
backgroundColor: 'transparent',
color: theme.palette.primary.main
}
}}
>
Back
</Button>
{/* Next */}
<Button
variant="text"
endIcon={<ArrowForwardIosIcon sx={{ fontSize: '16px' }} />}
onClick={onNext}
disabled={currentStepIndex === steps.length - 1}
sx={{
color: currentStepIndex === steps.length - 1 ? '#C2C2C2' : '#6B7283',
minWidth: '100px',
fontWeight: 400,
fontSize: '16px',
textTransform: 'none',
'&:hover': {
backgroundColor: 'transparent',
color: theme.palette.primary.main,
transition: 'all 0.4s ease'
}
}}
>
Next
</Button>
</Box>
</Box>
);
};
export default Side;