نسخ من RaghadAlkhous/RestaurantDash
435 أسطر
16 KiB
JavaScript
435 أسطر
16 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
Box,
|
|
Typography,
|
|
TextField,
|
|
Button,
|
|
styled,
|
|
useTheme,
|
|
MenuItem,
|
|
Radio,
|
|
RadioGroup,
|
|
FormControlLabel,
|
|
Radio as MuiRadio
|
|
} from '@mui/material';
|
|
import axios from 'axios';
|
|
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
|
import TableView from './TableView';
|
|
|
|
const ProductEntry = ({ onAdd, onShowTable }) => {
|
|
const theme = useTheme();
|
|
const [profileImage, setProfileImage] = useState(null);
|
|
const [fullName, setFullName] = useState('');
|
|
const [username, setUsername] = useState('');
|
|
const [bio, setBio] = useState('');
|
|
const [email, setEmail] = useState('');
|
|
const [phone, setPhone] = useState('');
|
|
const [selectedBranch, setSelectedBranch] = useState('default');
|
|
const [branches, setBranches] = useState([
|
|
{ label: 'Damascus Branch', value: 'damascus' },
|
|
{ label: 'Aleppo Branch', value: 'aleppo' },
|
|
{ label: 'Homs Branch', value: 'homs' }
|
|
]);
|
|
const [expirationDate, setExpirationDate] = useState(null);
|
|
const [consumptionStatus, setConsumptionStatus] = useState(false);
|
|
const [showTable, setShowTable] = useState(false);
|
|
const [products, setProducts] = useState([]);
|
|
|
|
// حالات جديدة للحفظ
|
|
const [stocksLevel, setStocksLevel] = useState('');
|
|
const [productCategory, setProductCategory] = useState('default');
|
|
const [supplierName, setSupplierName] = useState('');
|
|
const [supplierNumber, setSupplierNumber] = useState('');
|
|
const [productPrice, setProductPrice] = useState('');
|
|
const [phoneNumber, setPhoneNumber] = useState('');
|
|
const [productCost, setProductCost] = useState('');
|
|
|
|
// قائمة فئات المنتجات
|
|
const productCategories = [
|
|
{ label: 'Food', value: 'food' },
|
|
{ label: 'Beverages', value: 'beverages' },
|
|
{ label: 'Electronics', value: 'electronics' },
|
|
{ label: 'Clothing', value: 'clothing' },
|
|
];
|
|
const handleShowTable = () => {
|
|
setShowTable(true);
|
|
};
|
|
useEffect(() => {
|
|
axios.get('https://mocki.io/v1/0b9d4121-d7e7-42f4-b1d5-b14f82e35b69')
|
|
.then((response) => {
|
|
setBranches(response.data);
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error fetching branches:', error);
|
|
});
|
|
|
|
const savedData = localStorage.getItem('productEntryData');
|
|
if (savedData) {
|
|
const data = JSON.parse(savedData);
|
|
setFullName(data.fullName || '');
|
|
setUsername(data.username || '');
|
|
setEmail(data.email || '');
|
|
setSelectedBranch(data.selectedBranch || 'default');
|
|
setExpirationDate(data.expirationDate ? new Date(data.expirationDate) : null);
|
|
setConsumptionStatus(data.consumptionStatus || false);
|
|
setStocksLevel(data.stocksLevel || '');
|
|
setProductCategory(data.productCategory || 'default');
|
|
setSupplierName(data.supplierName || '');
|
|
setSupplierNumber(data.supplierNumber || '');
|
|
setProductPrice(data.productPrice || '');
|
|
setPhoneNumber(data.phoneNumber || '');
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const dataToSave = {
|
|
fullName,
|
|
username,
|
|
email,
|
|
selectedBranch,
|
|
expirationDate: expirationDate ? expirationDate.toISOString() : null,
|
|
consumptionStatus,
|
|
stocksLevel,
|
|
productCategory,
|
|
supplierName,
|
|
supplierNumber,
|
|
productPrice,
|
|
phoneNumber,
|
|
};
|
|
localStorage.setItem('productEntryData', JSON.stringify(dataToSave));
|
|
}, [
|
|
fullName,
|
|
username,
|
|
email,
|
|
selectedBranch,
|
|
expirationDate,
|
|
consumptionStatus,
|
|
stocksLevel,
|
|
productCategory,
|
|
supplierName,
|
|
supplierNumber,
|
|
productPrice,
|
|
phoneNumber,
|
|
]);
|
|
|
|
const handleImageUpload = (event) => {
|
|
if (event.target.files && event.target.files[0]) {
|
|
setProfileImage(URL.createObjectURL(event.target.files[0]));
|
|
}
|
|
};
|
|
|
|
const Input = styled('input')({
|
|
display: 'none',
|
|
});
|
|
|
|
const customInputStyle = {
|
|
'& 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)',
|
|
},
|
|
};
|
|
|
|
|
|
|
|
const renderField = (label, value, onChange, type = 'text', placeholder = '') => (
|
|
<Box
|
|
sx={{
|
|
flex: 1,
|
|
minWidth: { xs: '100%', sm: '45%' },
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<Typography variant="body2" sx={{ fontWeight: '500', fontSize: '16px' }}>
|
|
{label}
|
|
</Typography>
|
|
<TextField
|
|
placeholder={placeholder}
|
|
type={type}
|
|
value={value}
|
|
onChange={onChange}
|
|
variant="outlined"
|
|
fullWidth
|
|
sx={customInputStyle}
|
|
/>
|
|
</Box>
|
|
);
|
|
|
|
const renderSelectField = (label, value, onChange, options = []) => (
|
|
<Box
|
|
sx={{
|
|
flex: 1,
|
|
minWidth: { xs: '100%', sm: '45%' },
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<Typography variant="body2" sx={{ fontWeight: '500', fontSize: '16px' }}>
|
|
{label}
|
|
</Typography>
|
|
<TextField
|
|
select
|
|
value={value}
|
|
onChange={onChange}
|
|
fullWidth
|
|
sx={customInputStyle}
|
|
>
|
|
<MenuItem value="default" disabled sx={{ color: '#9e9e9e' }}>
|
|
Select {label}...
|
|
</MenuItem>
|
|
{options.map((option) => (
|
|
<MenuItem key={option.value} value={option.value}>
|
|
{option.label}
|
|
</MenuItem>
|
|
))}
|
|
</TextField>
|
|
</Box>
|
|
);
|
|
|
|
const handleSave = () => {
|
|
// احصل على أكبر رقم منتج موجود في القائمة
|
|
const maxProductNumber = products.length > 0
|
|
? Math.max(...products.map(p => Number(p.username) || 0))
|
|
: 0;
|
|
|
|
const newProductNumber = maxProductNumber + 1;
|
|
|
|
const newProduct = {
|
|
fullName,
|
|
username: newProductNumber.toString(), // هنا رقم المنتج يتزاد تلقائياً
|
|
email,
|
|
selectedBranch,
|
|
expirationDate: expirationDate ? expirationDate.toISOString().split('T')[0] : '',
|
|
consumptionStatus,
|
|
stocksLevel,
|
|
productCategory,
|
|
supplierName,
|
|
supplierNumber,
|
|
productPrice,
|
|
phoneNumber,
|
|
productCost,
|
|
};
|
|
|
|
// أضف المنتج الجديد لقائمة المنتجات
|
|
setProducts(prev => [...prev, newProduct]);
|
|
|
|
// استدعي دالة onAdd إن كانت موجودة
|
|
if (onAdd) {
|
|
onAdd(newProduct);
|
|
}
|
|
|
|
// إعادة تعيين الحقول (يمكنك إزالة إعادة تعيين username لأنه أصبح تلقائي)
|
|
setFullName('');
|
|
setEmail('');
|
|
setSelectedBranch('default');
|
|
setExpirationDate(null);
|
|
setConsumptionStatus(false);
|
|
setStocksLevel('');
|
|
setProductCategory('default');
|
|
setSupplierName('');
|
|
setSupplierNumber('');
|
|
setProductPrice('');
|
|
setPhoneNumber('');
|
|
setProductCost('');
|
|
};
|
|
|
|
|
|
return (
|
|
<Box
|
|
sx={{
|
|
p: { xs: 2, sm: 3 },
|
|
backgroundColor: '#FFFFFF',
|
|
maxWidth: { xs: '90%', md: '100%' },
|
|
borderRadius: 2,
|
|
}}
|
|
>
|
|
{/* الحقول النصية */}
|
|
<Box sx={{ mb: 3 }}>
|
|
{/* السطر الأول: Product Name + Barcode Maker */}
|
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
|
|
{renderField('Product Name', fullName, (e) => setFullName(e.target.value), 'text', 'Pizza')}
|
|
{renderField('Barcode Maker', email, (e) => setEmail(e.target.value), 'text', '12344')}
|
|
</Box>
|
|
|
|
{/* السطر الثاني: Branch Select + Product Number */}
|
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
|
|
{renderField('Product Number', username, (e) => setUsername(e.target.value), 'text', '#123')}
|
|
{renderSelectField('Branch Select', selectedBranch, (e) => setSelectedBranch(e.target.value), branches)}
|
|
</Box>
|
|
|
|
{/* السطر الثالث: Expiration Date + Consumption Status */}
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
flexWrap: 'wrap',
|
|
gap: 2,
|
|
mb: 2,
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
<Box
|
|
sx={{
|
|
flex: 1,
|
|
minWidth: { xs: '100%', sm: '45%' },
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ fontWeight: '500', fontSize: '16px', mb: 1 }}
|
|
>
|
|
Expiration Date
|
|
</Typography>
|
|
<DatePicker
|
|
value={expirationDate}
|
|
onChange={(newValue) => setExpirationDate(newValue)}
|
|
renderInput={(params) => (
|
|
<TextField
|
|
{...params}
|
|
fullWidth
|
|
sx={{
|
|
'& .MuiOutlinedInput-root': {
|
|
borderRadius: '2px !important',
|
|
transition: '0.3s',
|
|
'&.Mui-focused fieldset': {
|
|
borderColor: theme.palette.primary.main,
|
|
boxShadow: '0 0 0 2px rgba(255, 145, 77, 0.2)',
|
|
},
|
|
},
|
|
'& fieldset': {
|
|
borderRadius: '20px !important',
|
|
},
|
|
flex: 1,
|
|
minWidth: { xs: '100%', sm: '45%' },
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 1,
|
|
}}
|
|
/>
|
|
)}
|
|
/>
|
|
</Box>
|
|
</LocalizationProvider>
|
|
|
|
<Box sx={{ flex: 1, minWidth: { xs: '100%', sm: '45%' } }}>
|
|
<Typography
|
|
variant="body2"
|
|
sx={{ fontWeight: '500', fontSize: '16px', mb: 1 }}
|
|
>
|
|
Consumption Status
|
|
</Typography>
|
|
<RadioGroup
|
|
row
|
|
aria-label="consumption-status"
|
|
name="row-radio-buttons-group"
|
|
value={consumptionStatus ? 'yes' : 'no'}
|
|
onChange={(e) => setConsumptionStatus(e.target.value === 'yes')}
|
|
>
|
|
<FormControlLabel
|
|
value="yes"
|
|
control={<MuiRadio />}
|
|
label="Yes"
|
|
/>
|
|
<FormControlLabel
|
|
value="no"
|
|
control={<MuiRadio />}
|
|
label="No"
|
|
/>
|
|
</RadioGroup>
|
|
</Box>
|
|
</Box>
|
|
|
|
{/* السطر الرابع: Stocks Level + Product Category */}
|
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
|
|
{renderField('Stocks Level', stocksLevel, (e) => setStocksLevel(e.target.value), 'number', 'Enter level')}
|
|
{renderSelectField('Product Category', productCategory, (e) => setProductCategory(e.target.value), productCategories)}
|
|
</Box>
|
|
|
|
{/* السطر الخامس: Supplier Name + Supplier Number */}
|
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 2 }}>
|
|
{renderField('Supplier Name', supplierName, (e) => setSupplierName(e.target.value), 'text', 'Supplier XYZ')}
|
|
{renderField('Supplier Number', supplierNumber, (e) => setSupplierNumber(e.target.value), 'text', '0900-78601')}
|
|
</Box>
|
|
|
|
{/* السطر السادس: Product Price + Phone Number */}
|
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, mb: 3 }}>
|
|
{renderField('Product Price', productPrice, (e) => setProductPrice(e.target.value), 'number', '$200')}
|
|
{renderField('Product Cost', productCost, (e) => setProductCost(e.target.value), 'number', '$230')}
|
|
</Box>
|
|
|
|
{/* زر الحفظ */}
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
justifyContent: 'flex-end',
|
|
mb: 2,
|
|
gap:2
|
|
}}
|
|
>
|
|
<Button
|
|
variant="contained"
|
|
onClick={handleSave}
|
|
sx={{
|
|
width: '150px',
|
|
height: '50px',
|
|
backgroundColor: theme.palette.primary.main,
|
|
color: 'white',
|
|
borderRadius: '10px',
|
|
fontWeight: 'bold',
|
|
fontSize: '16px',
|
|
textTransform: 'none',
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.primary.dark,
|
|
},
|
|
}}
|
|
>
|
|
Save Product
|
|
</Button>
|
|
|
|
<Button
|
|
variant="outlined"
|
|
onClick={onShowTable}
|
|
sx={{
|
|
width: '150px',
|
|
height: '50px',
|
|
borderRadius: '10px',
|
|
fontWeight: 'bold',
|
|
fontSize: '16px',
|
|
textTransform: 'none',
|
|
color: theme.palette.primary.main,
|
|
borderColor: theme.palette.primary.main,
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.primary.main,
|
|
color: '#fff',
|
|
borderColor: theme.palette.primary.dark,
|
|
},
|
|
}}
|
|
>
|
|
Show Table
|
|
</Button>
|
|
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default ProductEntry;
|