1
0

Initial commit - restaurant dashboard

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

عرض الملف

@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { Box, useTheme, useMediaQuery } from '@mui/material';
import { Box, useTheme, useMediaQuery, Snackbar, Alert } from '@mui/material';
import KitchPlusAppBar from '../AppBar';
import Sidebar from '../SideHome';
import CloudKitchenProject from './contcet/CloudKitchenProject';
@@ -10,7 +10,9 @@ import Budget from './contcet/Budget';
import AdditionalSupport from './contcet/AdditionalSupport';
import AdditionalNotes from './contcet/AdditionalNotes';
import SideProfile from './SideProfile';
import authService from '../../../services/authService';
const { createNewRestaurant } = authService;
const drawerWidth = 230;
const CreateRestaurant = () => {
@@ -19,30 +21,98 @@ const CreateRestaurant = () => {
const [hasProducts, setHasProducts] = useState(false);
const [sidebarOpen, setSidebarOpen] = useState(!isMobile);
// ⬇️ إدارة الخطوة الحالية
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [currentStep, setCurrentStep] = useState(0);
// إدارة بيانات النموذج لجميع الخطوات (مشاركة البيانات بين الخطوات)
const [formData, setFormData] = useState({
});
// دالة لتحديث بيانات النموذج بشكل مرن (دمج الجديد مع القديم)
const updateFormData = (newData) => {
setFormData(prev => ({
...prev,
...newData,
}));
};
// دالة لإغلاق السناك بار
const handleSnackbarClose = (event, reason) => {
if (reason === 'clickaway') return;
setSnackbarOpen(false);
};
const handleSubmit = async () => {
try {
await createNewRestaurant(formData);
setSnackbarOpen(true);
} catch (error) {
console.error(error);
}
};
const steps = [
<CloudKitchenProject onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<OperationalDetails onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<RequiredEquipments onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<VisualIdentity onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<Budget onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<AdditionalSupport onNext={() => setCurrentStep(currentStep + 1)} onBack={() => setCurrentStep(currentStep - 1)} />,
<AdditionalNotes onBack={() => setCurrentStep(currentStep - 1)} />,
<CloudKitchenProject
key="step-0"
formData={formData}
updateFormData={updateFormData}
onNext={() => setCurrentStep(prev => Math.min(prev + 1, steps.length - 1))}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>,
<OperationalDetails
key="step-1"
formData={formData}
updateFormData={updateFormData}
onNext={() => setCurrentStep(prev => Math.min(prev + 1, steps.length - 1))}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>,
<RequiredEquipments
key="step-2"
formData={formData}
updateFormData={updateFormData}
onNext={() => setCurrentStep(prev => Math.min(prev + 1, steps.length - 1))}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>,
<VisualIdentity
key="step-3"
formData={formData}
updateFormData={updateFormData}
onNext={() => setCurrentStep(prev => Math.min(prev + 1, steps.length - 1))}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>,
<Budget
key="step-4"
formData={formData}
updateFormData={updateFormData}
onNext={() => setCurrentStep(prev => Math.min(prev + 1, steps.length - 1))}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>,
<AdditionalNotes
key="step-5"
formData={formData}
updateFormData={updateFormData}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
onSubmit={handleSubmit}
/>
];
useEffect(() => {
const checkProducts = async () => {
const productsExist = await checkIfProductsExist();
setHasProducts(productsExist);
};
checkProducts();
}, []);
const checkIfProductsExist = async () => {
return false;
};
// useEffect(() => {
// const checkProducts = async () => {
// const productsExist = await checkIfProductsExist();
// setHasProducts(productsExist);
// };
// checkProducts();
// }, []);
// const checkIfProductsExist = async () => {
// return false;
// };
useEffect(() => {
if (window.innerWidth >= theme.breakpoints.values.md) {
@@ -71,12 +141,14 @@ const CreateRestaurant = () => {
};
return (
<Box sx={{
display: 'flex',
height: '100vh',
backgroundColor: '#F6F6F6',
overflow: 'hidden',
}}>
<Box
sx={{
display: 'flex',
height: '100vh',
backgroundColor: '#F6F6F6',
overflow: 'hidden',
}}
>
<Sidebar
open={sidebarOpen}
onClose={handleDrawerToggle}
@@ -84,82 +156,102 @@ const CreateRestaurant = () => {
drawerWidth={drawerWidth}
/>
<Box sx={{
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
width: { xs: '100%', sm: '100%', md: '100%' },
marginLeft: { xs: 0, sm: sidebarOpen ? `${drawerWidth}px` : 0, md: 0 },
transition: theme.transitions.create(['width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
}}>
<Box
sx={{
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
width: { xs: '100%', sm: '100%', md: '100%' },
marginLeft: { xs: 0, sm: sidebarOpen ? `${drawerWidth}px` : 0, md: 0 },
transition: theme.transitions.create(['width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
}}
>
<KitchPlusAppBar
onDrawerToggle={handleDrawerToggle}
sidebarOpen={sidebarOpen}
isMobile={isMobile}
/>
<Box>
<Box sx={{
display: 'flex', height: '100vh',
}}>
<Box sx={{
<Box
sx={{
display: 'flex',
height: '100vh',
ml: 3,
mb: 2,
width: { md: '30%' },
display: { xs: 'none', sm: 'none', md: 'block' },
overflowY: 'auto',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
}}>
<Box sx={{
minHeight: '100%', pb: 15, pt: 3,
}}>
}}
>
<Box
sx={{
height: '100vh',
ml: 3,
mb: 2,
width: { md: '30%' },
display: { xs: 'none', sm: 'none', md: 'block' },
overflowY: 'auto',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
}}
>
<Box
sx={{
minHeight: '100%',
pb: 15,
pt: 3,
}}
>
<SideProfile
currentStepIndex={currentStep}
onBack={() => setCurrentStep(prev => Math.max(prev - 1, 0))}
/>
</Box>
</Box>
<Box sx={{
ml: { xs: 2, md: 3 },
flexGrow: 1,
height: '100vh',
pr: { sm: 2, md: 1 },
pt: 3,
mb: { sm: 20 },
width: { md: '60%' }, display: { xs: 'block', sm: 'block', md: 'block' },
overflowY: 'auto',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
}}>
<Box sx={{
minHeight: '100%', pb: 18,
}}>
<Box
sx={{
ml: { xs: 2, md: 3 },
flexGrow: 1,
height: '100vh',
pr: { sm: 2, md: 1 },
pt: 3,
mb: { sm: 20 },
width: { md: '60%' },
display: { xs: 'block', sm: 'block', md: 'block' },
overflowY: 'auto',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
}}
>
<Box
sx={{
minHeight: '100%',
pb: 18,
}}
>
{steps[currentStep]}
</Box>
</Box>
</Box>
</Box>
</Box>
<Snackbar
open={snackbarOpen}
autoHideDuration={4000}
onClose={handleSnackbarClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
>
<Alert onClose={handleSnackbarClose} severity="success" sx={{ width: '100%' }}>
عملية إنشاء المطعم تمت بنجاح
</Alert>
</Snackbar>
</Box>
);
};
export default CreateRestaurant;
export default CreateRestaurant;

عرض الملف

@@ -8,7 +8,6 @@ const steps = [
{ title: 'Required Equipments', icon: '/images/createProfile/equipment.png'},
{ title: 'Visual Identity', icon: '/images/createProfile/Vector.png' },
{ title: 'Budget & Expansion', icon: '/images/createProfile/Expansion.png' },
{ title: 'Additional Support', icon: '/images/createProfile/hand.png' },
{ title: 'Additional Notes & Concerns', icon: '/images/createProfile/Group.png' },
{ title: 'Submit & Confirmation', icon: '/images/createProfile/Confirmation.png' },
];

عرض الملف

@@ -1,151 +1,171 @@
import React, { useState } from 'react';
import {
Box,
Typography,
Stack,
Button,
useTheme,
TextField
Box,
Typography,
Stack,
Button,
useTheme,
TextField
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import ConfirmationDialog from './ConfirmationDialog'; // ✅ استدعاء المودال المنفصل
import ConfirmationDialog from './ConfirmationDialog';
import { useLocation, useNavigate } from 'react-router-dom';
const AdditionalNotes = ({ currentStepIndex = 0, onNext, onBack }) => {
const theme = useTheme();
const navigate = useNavigate();
const [openModal, setOpenModal] = useState(false);
const AdditionalNotes = ({ currentStepIndex = 0, onNext, onBack, formData, updateFormData, onSubmit }) => {
const theme = useTheme();
const [openModal, setOpenModal] = useState(false);
const [loading, setLoading] = useState(false);
const handleOpenModal = () => setOpenModal(true);
const handleCloseModal = () => setOpenModal(false);
const handleConfirmNext = () => {
handleCloseModal();
onNext();
};
const navigate = useNavigate();
const location = useLocation();
return (
<Box
sx={{
height: { xs: '90%', sm: '100%', md: 740 },
backgroundColor: '#FFFFFF',
px: 4,
pt: { xs: 4, md: 11 },
pb: 10,
display: 'block',
borderRadius: 2,
boxShadow: '0px 1px 4px rgba(0,0,0,0.05)',
position: 'relative',
width: { xs: '85%', sm: '90%' },
}}
>
<Stack spacing={2.5}>
<Typography fontWeight={700} sx={{
fontSize: { xs: '1.8rem', sm: '2rem', md: '2.2rem' }
}}>
Additional Notes
</Typography>
const handleOpenModal = () => setOpenModal(true);
const handleCloseModal = () => setOpenModal(false);
<Box sx={{ width: '70%' }}>
<Typography fontSize="16px" color="text.secondary" fontWeight={500} sx={{ pb: 1 }}>
Enter your basic information to proceed to registration of your own restaurant on this platform
</Typography>
</Box>
const handleNotesChange = (e) => {
updateFormData({ need_help: e.target.value });
};
{/*Notes / Concerns Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Notes / Concerns
</Typography>
<TextField
placeholder="Write for us"
variant="outlined"
fullWidth
multiline
minRows={7}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
fontSize: '15px',
alignItems: 'start',
},
'& textarea::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>
const handleConfirmSubmit = async () => {
setLoading(true);
try {
if (onSubmit) {
await onSubmit();
}
setOpenModal(false);
// التوجيه فقط إذا كانت الصفحة هي /create-restaurant
if (location.pathname === '/create-restaurant') {
navigate('/restaurant');
}
// إذا كانت من رابط آخر مثل /create-kitchen لا نفعل شيئًا
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
{/* Buttons */}
<Box sx={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={handleOpenModal}
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
}
}}
>
Next
</Button>
return (
<Box
sx={{
height: { xs: '90%', sm: '100%', md: 740 },
backgroundColor: '#FFFFFF',
px: 4,
pt: { xs: 4, md: 11 },
pb: 10,
display: 'block',
borderRadius: 2,
boxShadow: '0px 1px 4px rgba(0,0,0,0.05)',
position: 'relative',
width: { xs: '85%', sm: '90%' },
}}
>
<Stack spacing={2.5}>
<Typography fontWeight={700} sx={{ fontSize: { xs: '1.8rem', sm: '2rem', md: '2.2rem' } }}>
Additional Notes
</Typography>
<Button
variant="outlined"
fullWidth
onClick={onBack}
sx={{
mt: 2,
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
fontSize: { xs: '14px', sm: '16px' },
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.primary.light,
borderColor: theme.palette.primary.main,
}
}}
>
Back
</Button>
</Box>
</Stack>
{/* ✅ Confirmation Modal */}
<ConfirmationDialog
open={openModal}
onClose={handleCloseModal}
onConfirm={handleConfirmNext}
title="Confirm Submission"
description="Are you sure you want to proceed to the next step?"
/>
<Box sx={{ width: '70%' }}>
<Typography fontSize="16px" color="text.secondary" fontWeight={500} sx={{ pb: 1 }}>
Enter your basic information to proceed to registration of your own restaurant on this platform
</Typography>
</Box>
);
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Notes / Concerns
</Typography>
<TextField
placeholder="Write for us"
variant="outlined"
fullWidth
multiline
minRows={7}
value={formData.need_help || ''}
onChange={handleNotesChange}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
fontSize: '15px',
alignItems: 'start',
},
'& textarea::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={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={handleOpenModal}
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
}
}}
>
Next
</Button>
<Button
variant="outlined"
fullWidth
onClick={onBack}
sx={{
mt: 2,
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
fontSize: { xs: '14px', sm: '16px' },
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.primary.light,
borderColor: theme.palette.primary.main,
}
}}
>
Back
</Button>
</Box>
</Stack>
<ConfirmationDialog
open={openModal}
onClose={handleCloseModal}
onConfirm={handleConfirmSubmit}
loading={loading}
title="Confirm Submission"
description="Are you sure you want to proceed to the next step?"
/>
</Box>
);
};
export default AdditionalNotes;

عرض الملف

@@ -1,9 +1,8 @@
import React from 'react';
import { Box, Typography, Stack, Button, useTheme, TextField } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import { useNavigate } from 'react-router-dom';
const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
const Budget = ({ currentStepIndex = 0, onNext, onBack, formData, updateFormData }) => {
const theme = useTheme();
const navigate = useNavigate();
@@ -12,6 +11,10 @@ const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
else navigate('/dashboard');
};
const handleInputChange = (field) => (e) => {
updateFormData({ [field]: e.target.value });
};
return (
<Box
sx={{
@@ -44,20 +47,29 @@ const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
</Box>
{/* Estimated Budget Input */}
<InputField label="Estimated Budget" placeholder="$4200" theme={theme} />
<InputField
label="Estimated Budget"
placeholder="$4200"
theme={theme}
value={formData.estimated_budget || ''}
onChange={handleInputChange('estimated_budget')}
/>
{/* Expansion Plans Through Cloud Kitchen (No of Branches) Input */}
<InputField label="Expansion Plans Through Cloud Kitchen (No of Branches)" placeholder="200" theme={theme} />
<InputField
label="Expansion Plans Through Cloud Kitchen (No of Branches)"
placeholder="200"
theme={theme}
value={formData.expansion_branches || ''}
onChange={handleInputChange('expansion_branches')}
/>
{/* Next Button */}
<Box sx={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={onNext}
onClick={handleNext}
sx={{
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
@@ -75,7 +87,6 @@ const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
Next
</Button>
{/* زر Back تحت زر Next */}
<Button
variant="outlined"
fullWidth
@@ -88,7 +99,7 @@ const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' }, // يظهر فقط في xs و sm
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
@@ -100,14 +111,12 @@ const Budget = ({ currentStepIndex = 0, onNext, onBack }) => {
Back
</Button>
</Box>
</Stack>
</Box>
);
};
// مكون فرعي لتقليل التكرار في الحقول
const InputField = ({ label, placeholder, theme }) => (
const InputField = ({ label, placeholder, theme, value, onChange }) => (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px', color: 'black' }}>
{label}
@@ -116,6 +125,8 @@ const InputField = ({ label, placeholder, theme }) => (
placeholder={placeholder}
variant="outlined"
fullWidth
value={value}
onChange={onChange}
sx={{
'& input': { fontWeight: 500, fontSize: '15px' },
'& input::placeholder': { color: '#969BA7' },

عرض الملف

@@ -1,12 +1,85 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import {
Box, Typography, Stack, Button, useTheme, TextField, Radio,
Box,
Typography,
Stack,
Button,
useTheme,
TextField,
Radio,
RadioGroup,
FormControlLabel,
MenuItem,
FormControl,
FormHelperText
} from '@mui/material';
const CloudKitchenProject = ({ currentStepIndex = 0, onNext, onBack }) => {
import authService from '../../../../services/authService'; // تأكد من المسار الصحيح
const CloudKitchenProject = ({
currentStepIndex = 0,
onNext,
formData,
updateFormData,
}) => {
const theme = useTheme();
const [cuisineTypes, setCuisineTypes] = useState([]);
const [errors, setErrors] = useState({});
//cuisineTypes
useEffect(() => {
const fetchCuisineTypes = async () => {
const data = await authService.cuisineTypes();
setCuisineTypes(data);
};
fetchCuisineTypes();
}, []);
useEffect(() => {
if (formData.menu_status === undefined) {
updateFormData({ menu_status: false });
}
if (formData.is_existing_brand === undefined) {
updateFormData({ is_existing_brand: false });
}
}, []);
const handleChange = (e) => {
const { name, value } = e.target;
if (name === 'is_existing_brand' || name === 'menu_status') {
updateFormData({ [name]: value === 'yes' });
} else {
updateFormData({ [name]: value });
}
};
const validate = () => {
let tempErrors = {};
if (!formData.name || formData.name.trim() === '') {
tempErrors.name = 'Restaurant Name is required';
}
if (!formData.cuisine_type_id) {
tempErrors.cuisine_type_id = 'Cuisine Type is required';
}
if (typeof formData.is_existing_brand !== 'boolean') {
tempErrors.is_existing_brand = 'Existing Brand selection is required';
}
if (!formData.location || formData.location.trim() === '') {
tempErrors.location = 'Location is required';
}
if (typeof formData.menu_status !== 'boolean') {
tempErrors.menu_status = 'Menu Status selection is required';
}
setErrors(tempErrors);
return Object.keys(tempErrors).length === 0;
};
const handleNext = () => {
if (validate()) {
onNext();
}
};
return (
<Box
@@ -47,92 +120,150 @@ const CloudKitchenProject = ({ currentStepIndex = 0, onNext, onBack }) => {
</Typography>
</Box>
{[
{ label: 'Restaurant Name', placeholder: 'Al-Baik Foods' },
{ label: 'Cuisine Type', placeholder: 'Italian, Chinese, etc.' },
].map((field, index) => (
<Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
{field.label}
</Typography>
<TextField
placeholder={field.placeholder}
variant="outlined"
fullWidth
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)'
{/* Restaurant Name */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Restaurant Name
</Typography>
<TextField
name="name"
placeholder="Al-Baik Foods"
variant="outlined"
fullWidth
value={formData.name || ''}
onChange={handleChange}
error={!!errors.name}
helperText={errors.name}
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)'
}
}}
/>
</Box>
))}
},
'& .MuiOutlinedInput-root.Mui-focused': {
borderColor: '#3f51b5',
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)'
}
}}
/>
</Box>
{/* Cuisine Type */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Cuisine Type
</Typography>
<TextField
select
name="cuisine_type_id"
placeholder="Select Cuisine Type"
variant="outlined"
fullWidth
value={formData.cuisine_type_id || ''}
onChange={handleChange}
error={!!errors.cuisine_type_id}
helperText={errors.cuisine_type_id}
sx={{
'& .MuiSelect-select': { fontWeight: 500, fontSize: '15px' },
'& .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)'
}
}}
>
{cuisineTypes.length > 0 ? (
cuisineTypes.map((type) => (
<MenuItem key={type.id} value={type.id}>
{type.name}
</MenuItem>
))
) : (
<MenuItem disabled>No Cuisine Types Found</MenuItem>
)}
</TextField>
</Box>
<Box sx={{}}>
{/* Existing Brand */}
<Box>
<Typography
variant="body2"
sx={{ fontWeight: 500, fontSize: '16px', mb: 1, mt: 2, color: '#191635' }}
>
Existing Brand
</Typography>
<RadioGroup row name="additionalFacilities">
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)', // شفافية اللون
transform: 'scale(0.85)', // تقليل حجم الزر لتقليل "سُمك الحواف"
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="Yes"
/>
<FormControlLabel
value="no"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="No"
/>
</RadioGroup>
<FormControl error={!!errors.is_existing_brand}>
<RadioGroup
row
name="is_existing_brand"
value={formData.is_existing_brand ? 'yes' : 'no'}
onChange={handleChange}
>
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="Yes"
/>
<FormControlLabel
value="no"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="No"
/>
</RadioGroup>
{errors.is_existing_brand && (
<FormHelperText>{errors.is_existing_brand}</FormHelperText>
)}
</FormControl>
</Box>
{/* Further Brand Details Input */}
{/* Further Brand Details */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Further Brand Details
</Typography>
<TextField
name="brand_details"
placeholder="We need Pizza Machine"
variant="outlined"
fullWidth
multiline
minRows={3}
value={formData.brand_details || ''}
onChange={handleChange}
error={!!errors.brand_details}
helperText={errors.brand_details}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
@@ -158,122 +289,130 @@ const CloudKitchenProject = ({ currentStepIndex = 0, onNext, onBack }) => {
/>
</Box>
{[
{ label: 'Age Group', placeholder: '15 - 75' },
{ label: 'Location', placeholder: 'Street 123, Jordan' },
].map((field, index) => (
<Box key={index} sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
{field.label}
</Typography>
<TextField
placeholder={field.placeholder}
variant="outlined"
fullWidth
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)'
{/* Age Group */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Age Group
</Typography>
<TextField
name="age_group"
placeholder="15 - 75"
variant="outlined"
fullWidth
value={formData.age_group || ''}
onChange={handleChange}
error={!!errors.age_group}
helperText={errors.age_group}
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)'
}
}}
/>
</Box>
))}
},
'& .MuiOutlinedInput-root.Mui-focused': {
borderColor: '#3f51b5',
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)'
}
}}
/>
</Box>
{/* Location */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Location
</Typography>
<TextField
name="location"
placeholder="Street 123, Jordan"
variant="outlined"
fullWidth
value={formData.location || ''}
onChange={handleChange}
error={!!errors.location}
helperText={errors.location}
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={{}}>
{/* Menu Status */}
<Box>
<Typography
variant="body2"
sx={{ fontWeight: 500, fontSize: '16px', mb: 1, mt: 2, color: '#191635' }}
>
Menu Status
</Typography>
<RadioGroup row name="additionalFacilities">
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)', // شفافية اللون
transform: 'scale(0.85)', // تقليل حجم الزر لتقليل "سُمك الحواف"
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="Yes"
/>
<FormControlLabel
value="no"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="No"
/>
</RadioGroup>
</Box>
{/* Further Brand Details Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Need Help
</Typography>
<TextField
placeholder="Write here..."
variant="outlined"
fullWidth
multiline
minRows={3}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
fontSize: '15px',
alignItems: 'start',
},
'& textarea::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)',
}
}}
/>
<FormControl error={!!errors.menu_status}>
<RadioGroup
row
name="menu_status"
value={formData.menu_status ? 'yes' : 'no'}
onChange={handleChange}
>
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="Yes"
/>
<FormControlLabel
value="no"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
}}
/>
}
label="No"
/>
</RadioGroup>
{errors.menu_status && (
<FormHelperText>{errors.menu_status}</FormHelperText>
)}
</FormControl>
</Box>
{/* زر Next */}
<Box sx={{ pt: 2.8 }}>
<Button
variant="contained"
fullWidth
onClick={onNext}
onClick={handleNext}
sx={{
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
@@ -290,33 +429,7 @@ const CloudKitchenProject = ({ currentStepIndex = 0, onNext, onBack }) => {
>
Next
</Button>
{/* زر Back تحت زر Next */}
<Button
variant="outlined"
fullWidth
onClick={onBack}
sx={{
mt: 2,
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
fontSize: { xs: '14px', sm: '16px' },
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'none', md: 'none' }, // يظهر فقط في xs و sm
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.primary.light,
borderColor: theme.palette.primary.main,
},
}}
>
Back
</Button>
</Box>
</Stack>
</Box>
);

عرض الملف

@@ -9,10 +9,10 @@ import {
Box,
Typography,
useTheme,
Divider
CircularProgress
} from '@mui/material';
import EditIcon from '@mui/icons-material/Edit';
const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
const ConfirmationDialog = ({ open, onClose, onConfirm, loading }) => {
const theme = useTheme();
return (
<Dialog
@@ -24,7 +24,7 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
PaperProps={{
sx: {
width: '525px',
height: '300px',
height: '350px',
maxWidth: '100%',
maxHeight: '100%',
borderRadius: '12px',
@@ -69,7 +69,7 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
zIndex: 0,
}} />
{/* الدائرة الأمامية مع الأيقونة */}
<Box sx={{
width: 80,
height: 80,
@@ -92,7 +92,6 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
</Box>
</Box>
{/* العنوان بجانب الدائرة */}
<DialogTitle sx={{ p: 0 }}>
<Typography
variant="h4"
@@ -115,7 +114,7 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
fontWeight: 500,
color: theme.palette.text.secondary
}}>
Congratulations! you have registered your restaurant successfully on our platform
Congratulations! you well register your restaurant successfully on our platform
</DialogContentText>
</DialogContent>
@@ -128,7 +127,7 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
gap: 2,
}}
>
{/* الزر الأول - Filled */}
<Button
variant="contained"
fullWidth
@@ -146,9 +145,34 @@ const ConfirmationDialog = ({ open, onClose, onConfirm }) => {
},
}}
>
Done
Censel
</Button>
{/* الزر الأول - Filled */}
<Button
variant="contained"
fullWidth
onClick={onConfirm}
disabled={loading}
sx={{
fontWeight: 600,
fontSize: '16px',
height: '48px',
borderRadius: '50px',
textTransform: 'none',
color: 'white',
backgroundColor: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.primary.dark,
},
}}
>
{loading ? (
<CircularProgress size={24} sx={{ color: 'white' }} />
) : (
'Submit'
)}
</Button>
</DialogActions>
</Box>
</Dialog>

عرض الملف

@@ -1,20 +1,71 @@
import React from 'react';
import { Box, Typography, Stack, Button, useTheme, TextField, MenuItem } from '@mui/material';
import React, { useEffect, useState } from 'react';
import {
Box,
Typography,
Stack,
Button,
useTheme,
TextField,
MenuItem,
} from '@mui/material';
import authService from '../../../../services/authService'; // ← عدّل المسار حسب مكانك
const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
const OperationalDetails = ({
currentStepIndex = 0,
onNext,
onBack,
formData,
updateFormData,
}) => {
const theme = useTheme();
const countries = [
{ code: 'US', name: 'United States' },
{ code: 'GB', name: 'United Kingdom' },
{ code: 'FR', name: 'France' },
{ code: 'DE', name: 'Germany' },
{ code: 'SA', name: 'Saudi Arabia' },
{ code: 'EG', name: 'Egypt' },
{ code: 'AE', name: 'United Arab Emirates' },
// أضف المزيد حسب الحاجة
];
const [countries, setCountries] = useState([]);
const [loadingCountries, setLoadingCountries] = useState(false);
const [errors, setErrors] = useState({}); // <-- حالة الأخطاء
useEffect(() => {
const fetchCountries = async () => {
setLoadingCountries(true);
const result = await authService.getCountries();
if (result.success) {
setCountries(result.data);
} else {
console.error(result.message);
}
setLoadingCountries(false);
};
fetchCountries();
}, []);
const handleChange = (e) => {
const { name, value } = e.target;
updateFormData({ [name]: value });
};
// التحقق من صحة الحقول
const validate = () => {
let tempErrors = {};
// التحقق من أن الحقل غير فارغ
if (!formData.staff_members || formData.staff_members.trim() === '') {
tempErrors.staff_members = 'Staff Members is required';
}
// التحقق من أن القيمة رقمية
else if (isNaN(formData.staff_members)) {
tempErrors.staff_members = 'Staff Members must be a number';
}
if (!formData.country_id || formData.country_id === '') {
tempErrors.country_id = 'Country selection is required';
}
setErrors(tempErrors);
return Object.keys(tempErrors).length === 0;
};
const handleNext = () => {
if (onNext) {
if (validate()) {
onNext();
}
};
@@ -41,12 +92,13 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
fontSize: {
xs: '1.8rem',
sm: '2rem',
md: '2.2rem'
}
md: '2.2rem',
},
}}
>
Operational Details
</Typography>
<Box sx={{ width: '70%' }}>
<Typography
fontSize="16px"
@@ -54,19 +106,29 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
fontWeight={500}
sx={{ pb: 1 }}
>
Enter your basic information to proceed to registration of your own restaurant on this platform
Enter your basic information to proceed to registration of your
own restaurant on this platform
</Typography>
</Box>
{/* Staff MembersInput */}
{/* Staff Members Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
<Typography
variant="body2"
color="black"
sx={{ fontWeight: '500', fontSize: '16px' }}
>
Staff Members
</Typography>
<TextField
name="staff_members"
placeholder="200 (100 Chefs, 100 Cooks)"
variant="outlined"
fullWidth
value={formData.staff_members || ''}
onChange={handleChange}
error={!!errors.staff_members}
helperText={errors.staff_members}
sx={{
'& input': { fontWeight: 500, fontSize: '15px' },
'& input::placeholder': { color: '#969BA7' },
@@ -75,35 +137,42 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
transition: '0.3s',
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.main,
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)'
}
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)'
}
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)',
},
}}
/>
</Box>
{/* Country Selector */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
<Typography
variant="body2"
color="black"
sx={{ fontWeight: '500', fontSize: '16px' }}
>
Country
</Typography>
<TextField
select
name="country_id"
fullWidth
defaultValue=""
placeholder="Select your country"
value={formData.country_id || ''}
onChange={handleChange}
disabled={loadingCountries}
error={!!errors.country_id}
helperText={errors.country_id}
sx={{
'& .MuiSelect-select': {
fontWeight: 500,
fontSize: '15px',
minHeight: '40px',
minHeight: '40px',
display: 'flex',
alignItems: 'center'
alignItems: 'center',
},
'& .MuiOutlinedInput-input': { padding: '10.5px 14px' },
'& .MuiOutlinedInput-root': {
@@ -111,37 +180,42 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
transition: '0.3s',
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.main,
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)'
}
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)'
}
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)',
},
}}
>
<MenuItem value="" disabled hidden>
Select your country
{loadingCountries ? 'Loading...' : 'Select your country'}
</MenuItem>
{countries.map((country) => (
<MenuItem key={country.code} value={country.code}>
<MenuItem key={country.id} value={country.id}>
{country.name}
</MenuItem>
))}
</TextField>
</Box>
{/* Expansion Plan Cities MembersInput */}
{/* Expansion Plan Cities Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Expansion Plan Cities
<Typography
variant="body2"
color="black"
sx={{ fontWeight: '500', fontSize: '16px' }}
>
Expansion Plan Cities
</Typography>
<TextField
name="expansion_plan_cities" // ← ✅ الاسم الصحيح المتوقع من الـ API
placeholder="Layyah Lahore Islamabad"
variant="outlined"
fullWidth
value={formData.expansion_plan_cities || ''}
onChange={handleChange}
sx={{
'& input': { fontWeight: 500, fontSize: '15px' },
'& input::placeholder': { color: '#969BA7' },
@@ -150,23 +224,24 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
transition: '0.3s',
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.main,
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)'
}
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)'
}
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)',
},
}}
/>
</Box>
{/* Next Button */}
</Box>
{/* Next Button */}
<Box sx={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={onNext}
onClick={handleNext}
sx={{
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
@@ -184,7 +259,7 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
Next
</Button>
{/* زر Back تحت زر Next */}
{/* Back Button */}
<Button
variant="outlined"
fullWidth
@@ -197,7 +272,7 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' }, // يظهر فقط في xs و sm
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
@@ -209,7 +284,6 @@ const OperationalDetails = ({ currentStepIndex = 0, onNext, onBack }) => {
Back
</Button>
</Box>
</Stack>
</Box>
);

عرض الملف

@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import {
Box,
Typography,
@@ -11,10 +11,56 @@ import {
Radio
} from '@mui/material';
const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack, formData, updateFormData }) => {
const theme = useTheme();
const [errors, setErrors] = useState({});
const [selectedDays, setSelectedDays] = useState([]);
// تعيين القيمة الافتراضية لـ needSpecializedEquipment إذا غير موجودة
useEffect(() => {
if (!formData.needSpecializedEquipment) {
updateFormData({ needSpecializedEquipment: 'no' });
}
}, [formData.needSpecializedEquipment, updateFormData]);
// التعامل مع تغير القيمة النصية للمعدات العامة
const handleEquipmentChange = (e) => {
updateFormData({ equipment: e.target.value });
};
const handleNeedSpecializedChange = (e) => {
updateFormData({ needSpecializedEquipment: e.target.value });
};
// التعامل مع القيمة النصية للمعدات المتخصصة
const handleSpecializedEquipmentChange = (e) => {
updateFormData({ specialized_equipment: e.target.value });
};
// دالة التحقق من صحة الحقول
const validate = () => {
let tempErrors = {};
// if (!formData.equipment || formData.equipment.trim() === '') {
// tempErrors.equipment = 'Equipment is required';
// }
// if (!formData.needSpecializedEquipment || (formData.needSpecializedEquipment !== 'yes' && formData.needSpecializedEquipment !== 'no')) {
// tempErrors.needSpecializedEquipment = 'Please select Yes or No';
// }
if (formData.needSpecializedEquipment === 'yes' && (!formData.specialized_equipment || formData.specialized_equipment.trim() === '')) {
tempErrors.specialized_equipment = 'Please specify specialized equipments';
}
setErrors(tempErrors);
return Object.keys(tempErrors).length === 0;
};
// دالة معالجة الضغط على زر Next مع تحقق الفالديشن
const handleNext = () => {
if (validate()) {
onNext();
}
};
return (
<Box
@@ -56,15 +102,19 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
</Typography>
</Box>
{/* Operational Hours Input */}
{/* Equipment Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" color="black" sx={{ fontWeight: '500', fontSize: '16px' }}>
Equipment
</Typography>
<TextField
placeholder=" Ovens Refrigerators Pizza Machines |"
placeholder="Ovens Refrigerators Pizza Machines |"
variant="outlined"
fullWidth
value={formData.equipment || ''}
onChange={handleEquipmentChange}
error={!!errors.equipment}
helperText={errors.equipment}
sx={{
'& input': { fontWeight: 500, fontSize: '15px' },
'& input::placeholder': { color: '#969BA7' },
@@ -84,22 +134,27 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
/>
</Box>
<Box sx={{}}>
{/* Need Specialized Equipment */}
<Box>
<Typography
variant="body2"
sx={{ fontWeight: 500, fontSize: '16px', mb: 1, mt: 2, color: '#191635' }}
>
Need Specialized Equipment
</Typography>
<RadioGroup row name="additionalFacilities">
<RadioGroup
row
name="needSpecializedEquipment"
value={formData.needSpecializedEquipment || 'no'}
onChange={handleNeedSpecializedChange}
>
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)', // شفافية اللون
transform: 'scale(0.85)', // تقليل حجم الزر لتقليل "سُمك الحواف"
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
@@ -125,53 +180,62 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
label="No"
/>
</RadioGroup>
{errors.needSpecializedEquipment && (
<Typography color="error" variant="caption" sx={{ mt: 0.5 }}>
{errors.needSpecializedEquipment}
</Typography>
)}
</Box>
{/* Specialized Equipments For Food Preparation Input */}
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Specialized Equipments For Food Preparation
</Typography>
<TextField
placeholder="Knife Spoon Handle |"
variant="outlined"
fullWidth
multiline
minRows={3}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
fontSize: '15px',
alignItems: 'start',
},
'& textarea::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)',
{/* Specialized Equipments For Food Preparation */}
{formData.needSpecializedEquipment === 'yes' && (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 500, fontSize: '16px' }}>
Specialized Equipments For Food Preparation
</Typography>
<TextField
placeholder="Knife Spoon Handle |"
variant="outlined"
fullWidth
multiline
minRows={3}
value={formData.specialized_equipment || ''}
onChange={handleSpecializedEquipmentChange}
error={!!errors.specialized_equipment}
helperText={errors.specialized_equipment
}
sx={{
'& .MuiInputBase-root': {
fontWeight: 500,
fontSize: '15px',
alignItems: 'start',
},
},
'& .MuiOutlinedInput-root.Mui-focused': {
borderColor: '#3f51b5',
boxShadow: '0 0 0 2px rgba(63,81,181,0.1)',
}
}}
/>
</Box>
{/* Next Button */}
'& textarea::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>
)}
{/* Buttons */}
<Box sx={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={onNext}
onClick={handleNext}
sx={{
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
@@ -189,7 +253,6 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
Next
</Button>
{/* زر Back تحت زر Next */}
<Button
variant="outlined"
fullWidth
@@ -202,7 +265,7 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' }, // يظهر فقط في xs و sm
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
@@ -214,7 +277,6 @@ const RequiredEquipments = ({ currentStepIndex = 0, onNext, onBack }) => {
Back
</Button>
</Box>
</Stack>
</Box>
);

عرض الملف

@@ -1,19 +1,61 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import {
Box,
Typography,
Stack,
Button,
useTheme,
TextField,
RadioGroup,
FormControlLabel,
Radio
Radio,
Typography as MuiTypography
} from '@mui/material';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack, formData, updateFormData }) => {
const theme = useTheme();
const [errors, setErrors] = useState({});
// تأكد من وجود قيمة افتراضية
useEffect(() => {
if (!formData.visualIdentity) {
updateFormData({ visualIdentity: 'no' });
}
}, [formData.visualIdentity, updateFormData]);
const handleVisualIdentityChange = (e) => {
updateFormData({ visualIdentity: e.target.value });
};
const handleFileChange = (e) => {
const file = e.target.files[0];
if (file) {
updateFormData({ logo: file });
}
};
const validate = () => {
let tempErrors = {};
if (!formData.visualIdentity || (formData.visualIdentity !== 'yes' && formData.visualIdentity !== 'no')) {
tempErrors.visualIdentity = 'Please select Yes or No';
}
/*
if (!formData.logo) {
tempErrors.logo = 'Please upload a logo or color scheme image';
}
*/
setErrors(tempErrors);
return Object.keys(tempErrors).length === 0;
};
const handleNext = () => {
if (validate()) {
onNext();
}
};
return (
<Box
@@ -54,23 +96,26 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
</Typography>
</Box>
<Box sx={{}}>
<Box>
<Typography
variant="body2"
sx={{ fontWeight: 500, fontSize: '16px', mb: 1, mt: 2, color: '#191635' }}
>
Visual Identity
</Typography>
<RadioGroup row name="additionalFacilities">
<RadioGroup
row
name="visualIdentity"
value={formData.visualIdentity || ''}
onChange={handleVisualIdentityChange}
>
<FormControlLabel
value="yes"
control={
<Radio
sx={{
color: 'rgba(150, 155, 167, 0.6)', // شفافية اللون
transform: 'scale(0.85)', // تقليل حجم الزر لتقليل "سُمك الحواف"
color: 'rgba(150, 155, 167, 0.6)',
transform: 'scale(0.85)',
'&.Mui-checked': {
color: theme.palette.primary.main
}
@@ -96,31 +141,34 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
label="No"
/>
</RadioGroup>
{errors.visualIdentity && (
<MuiTypography color="error" variant="caption" sx={{ mt: 0.5 }}>
{errors.visualIdentity}
</MuiTypography>
)}
</Box>
{/* OR Separator */}
{/* Upload Logo / Color Scheme */}
<Box>
<Typography
sx={{
fontWeight: 500,
fontSize: '16px',
color: 'black',
mb:2 ,
pl: 1, // padding left (اختياري)
mb: 2,
pl: 1,
}}
>
Upload Logo / Color Scheme If Any
</Typography>
{/* Upload Menu Picture */}
<Box
component="label"
htmlFor="upload-image"
sx={{
border: '2px dashed #ccc',
border: errors.logo_path ? '2px solid red' : '2px dashed #ccc',
borderRadius: '10px',
height: '100px',
height: '150px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
@@ -137,19 +185,28 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
}
}}
>
Upload Picture
<input id="upload-image" type="file" accept="image/*" hidden />
{formData.logo ? (formData.logo.name || 'Uploaded Image') : 'Upload Picture'}
<input
id="upload-image"
type="file"
accept="image/*"
hidden
onChange={handleFileChange}
/>
</Box>
{errors.logo && (
<MuiTypography color="error" variant="caption" sx={{ mt: 0.5 }}>
{errors.logo}
</MuiTypography>
)}
</Box>
{/* Buttons: Back and Next */}
{/* Buttons */}
<Box sx={{ pt: 2 }}>
<Button
variant="contained"
fullWidth
onClick={onNext}
onClick={handleNext}
sx={{
fontFamily: 'PlusJakartaSans',
fontWeight: 600,
@@ -167,7 +224,6 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
Next
</Button>
{/* زر Back تحت زر Next */}
<Button
variant="outlined"
fullWidth
@@ -180,7 +236,7 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
height: { xs: '45px', sm: '52px' },
borderRadius: '50px',
textTransform: 'none',
display: { xs: 'block', sm: 'block', md: 'none' }, // يظهر فقط في xs و sm
display: { xs: 'block', sm: 'block', md: 'none' },
borderColor: theme.palette.primary.main,
color: theme.palette.primary.main,
'&:hover': {
@@ -192,7 +248,6 @@ const VisualIdentity = ({ currentStepIndex = 0, onNext, onBack }) => {
Back
</Button>
</Box>
</Stack>
</Box>
);