نسخ من RaghadAlkhous/RestaurantDash
Work on Create your restaurant and Inventory
هذا الالتزام موجود في:
434
src/components/Home/Inventory/ProductEntry.js
Normal file
434
src/components/Home/Inventory/ProductEntry.js
Normal file
@@ -0,0 +1,434 @@
|
||||
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;
|
||||
المرجع في مشكلة جديدة
حظر مستخدم