Changeset bc20307 for sources/client/src/components/admin/EmployeeEdit
- Timestamp:
- 02/14/22 01:41:41 (2 years ago)
- Branches:
- master
- Children:
- 747e0ab
- Parents:
- e8b1076
- Location:
- sources/client/src/components/admin/EmployeeEdit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sources/client/src/components/admin/EmployeeEdit/index.js
re8b1076 rbc20307 1 import { use State } from 'react';1 import { useEffect, useState } from 'react'; 2 2 import { useParams, useHistory } from 'react-router-dom'; 3 3 import useForm from '../../../hooks/useForm'; … … 21 21 SaveChangesButton, 22 22 VisibilityIcon, 23 VisibilityOffIcon 23 VisibilityOffIcon, 24 24 } from './styles'; 25 25 26 26 import IconButton from '@mui/material/IconButton'; 27 28 import { 29 employeeStatus 30 } from '../../../config/enums'; 31 32 import { 33 employees 34 } from '../EmployeesTable/mockData'; 27 import Checkbox from '@mui/material/Checkbox'; 28 import ListItemText from '@mui/material/ListItemText'; 29 import AbsoluteLoader from '../../Loaders/AbsoluteLoader'; 30 31 import { employeeStatus } from '../../../config/enums'; 32 import useGetData from '../../../hooks/useGetData'; 33 import useUpdateEmployee from '../../../hooks/useUpdateEmployee'; 34 import useDeleteEmployee from '../../../hooks/useDeleteEmployee'; 35 36 const MenuProps = { 37 PaperProps: { 38 style: { 39 maxHeight: 220, 40 }, 41 }, 42 }; 35 43 36 44 const EmployeeEdit = () => { … … 38 46 let history = useHistory(); 39 47 let { employeeId } = useParams(); 40 employeeId = parseInt(employeeId); 41 42 const employee = employees.find(e => e.id === employeeId); 43 const { data: employeeEditableData, onFormChange: setEmployeeEditableData } = useForm({ ...employee, confirmPassword: employee.password }); 44 const [accStatus, setAccStatus] = useState(employee ? employee.accountActive : false); 45 46 const zoneOptions = [ 48 const { updateEmployee } = useUpdateEmployee(); 49 const { deleteEmployee } = useDeleteEmployee(); 50 const { data: employeeData, isLoading: isLoadingEmployeeData } = useGetData( 47 51 { 48 text: 'Nitu edna zona', 49 value: 'none' 50 }, 51 { 52 text: 'Zona 1', 53 value: 'zone1' 54 }, 55 { 56 text: 'Zona 2', 57 value: 'zone2' 58 }, 59 { 60 text: 'Zona 3', 61 value: 'zone3' 62 }, 63 { 64 text: 'Zona 4', 65 value: 'zone4' 66 }, 67 { 68 text: 'Zona 5', 69 value: 'zone5' 52 url: `/vraboten/${employeeId}`, 70 53 } 71 ]; 72 73 const statusOptions = Object.keys(employeeStatus).map(key => { 54 ); 55 const { data: zoneOptions, isLoading: isLoadingZonesData } = useGetData({ 56 url: `/parkingZone/parkingZoneNames`, 57 }); 58 59 const { 60 data: employeeEditableData, 61 setNewData: setNewDataEmployee, 62 onFormChange: setEmployeeEditableData, 63 } = useForm(null); 64 const [accStatus, setAccStatus] = useState(false); 65 const { 66 data: { confirmPassword }, 67 onFormChange: setConfirmPassword, 68 } = useForm({ confirmPassword: '' }); 69 const [zones, setZones] = useState([]); 70 71 const statusOptions = Object.keys(employeeStatus).map((key) => { 74 72 return { 75 73 text: employeeStatus[key], 76 value: key 74 value: key, 75 }; 76 }); 77 78 const onSaveChanges = () => { 79 if (zones.length === 1 && zones[0] === 'NONE') { 80 zones.shift(); 77 81 } 78 });79 80 const onSaveChanges = () => {82 console.log(`Confirm password: ${confirmPassword}`); 83 const mobileNumber = employeeEditableData.mobile; 84 delete employeeEditableData.mobile; 81 85 const changedEmployee = { 82 86 ...employeeEditableData, 83 accountActive: accStatus 87 mobileNumber: mobileNumber, 88 locked: accStatus, 89 parkingZones: zones, 90 confirmPass: confirmPassword, 91 }; 92 updateEmployee({ employee: changedEmployee }); 93 }; 94 95 const onDeleteEmployee = () => { 96 deleteEmployee({ id: employeeData.workerId }); 97 }; 98 99 const handleZonesChange = (event) => { 100 const { 101 target: { value }, 102 } = event; 103 if (value.length > 1 && value[0] === 'NONE') { 104 value.shift(); 84 105 } 85 console.log('Changed employee: ', changedEmployee); 86 } 87 88 const onDeleteEmployee = () => { 89 console.log(`Empoyee with ${employee.id} is deleted`); 90 } 91 92 return <EmployeeEditWrapper> 93 <Title variant='h5'>Uredi vraboten</Title> 94 <RowWrapper> 95 <LabelAndInputWrapper> 96 <Label>Ime</Label> 97 <StandardInputField 98 value={employeeEditableData?.firstName ?? ''} 99 name='firstName' 100 onChange={setEmployeeEditableData} 106 setZones( 107 typeof value === 'string' 108 ? value.split(', ') 109 : value.length === 0 110 ? ['NONE'] 111 : value 112 ); 113 }; 114 useEffect(() => { 115 if (!employeeData) return; 116 setNewDataEmployee({...employeeData, password: ''}); 117 setAccStatus(employeeData.locked); 118 setZones( 119 employeeData.pzNames.length === 0 120 ? ['NONE'] 121 : employeeData.pzNames 122 ); 123 }, [employeeData]); 124 125 return ( 126 <EmployeeEditWrapper> 127 <Title variant='h5'>Уреди Вработен</Title> 128 {isLoadingEmployeeData ? ( 129 <AbsoluteLoader 130 containerStyle={{ 131 width: '200px', 132 height: '200px', 133 margin: 'auto', 134 }} 101 135 /> 102 </LabelAndInputWrapper> 103 <LabelAndInputWrapper> 104 <Label>Prezime</Label> 105 <StandardInputField 106 value={employeeEditableData?.lastName ?? ''} 107 name='lastName' 108 onChange={setEmployeeEditableData} 109 /> 110 </LabelAndInputWrapper> 111 </RowWrapper> 112 <RowWrapper> 113 <LabelAndInputWrapper> 114 <Label>Email</Label> 115 <StandardInputField 116 value={employeeEditableData?.email ?? ''} 117 name='email' 118 type='email' 119 onChange={setEmployeeEditableData} 120 /> 121 </LabelAndInputWrapper> 122 <LabelAndInputWrapper> 123 <Label>Telefon</Label> 124 <StandardInputField 125 value={employeeEditableData?.phoneNumber ?? ''} 126 name='phoneNumber' 127 onChange={setEmployeeEditableData} 128 /> 129 </LabelAndInputWrapper> 130 </RowWrapper> 131 <RowWrapper> 132 <LabelAndInputWrapper> 133 <Label>Lozinka</Label> 134 <StandardInputField 135 value={employeeEditableData?.password ?? ''} 136 name='password' 137 type={isPasswordVisible ? 'text' : 'password'} 138 onChange={setEmployeeEditableData} 139 /> 140 </LabelAndInputWrapper> 141 <IconButton sx={{ marginTop: '23px' }} onClick={() => setIsPasswordVisible(!isPasswordVisible)}> 142 { 143 isPasswordVisible ? 144 <VisibilityIcon /> 145 : 146 <VisibilityOffIcon /> 147 } 148 </IconButton> 149 <LabelAndInputWrapper> 150 <Label>Potvrdi lozinka</Label> 151 <StandardInputField 152 value={employeeEditableData?.confirmPassword ?? ''} 153 name='confirmPassword' 154 type={isPasswordVisible ? 'text' : 'password'} 155 onChange={setEmployeeEditableData} 156 /> 157 </LabelAndInputWrapper> 158 </RowWrapper> 159 <RowWrapper> 160 <LabelAndInputWrapper> 161 <Label>Odgovoren za</Label> 162 <Dropdown 163 value={employeeEditableData?.zone !== '' ? employeeEditableData?.zone : zoneOptions[0].value} 164 name='zone' 165 onChange={setEmployeeEditableData} 166 > 167 { 168 zoneOptions.map(option => <DropdownOption value={option.value} key={option.value}>{option.text}</DropdownOption>) 169 } 170 </Dropdown> 171 </LabelAndInputWrapper> 172 <LabelAndInputWrapper> 173 <Label>Status</Label> 174 <Dropdown 175 value={employeeEditableData?.status !== '' ? employeeEditableData?.status : statusOptions[0].value} 176 name='status' 177 onChange={setEmployeeEditableData} 178 > 179 { 180 statusOptions.map(option => <DropdownOption value={option.value} key={option.value}>{option.text}</DropdownOption>) 181 } 182 </Dropdown> 183 </LabelAndInputWrapper> 184 </RowWrapper> 185 <SwitchRowWrapper> 186 <SwitchTitle>Akaunt</SwitchTitle> 187 <SwitchLabelAndInputWrapper> 188 <Label>Aktiven:</Label> 189 <AccountSwitch 190 checked={accStatus} 191 value={accStatus} 192 name='accountActive' 193 onClick={() => setAccStatus(!accStatus)} 194 /> 195 </SwitchLabelAndInputWrapper> 196 </SwitchRowWrapper> 197 <RowWrapper> 198 <DeleteButton onClick={onDeleteEmployee}> 199 Izbrisi vraboten 200 </DeleteButton> 201 <BackAndSaveChangesButtonsWrapper> 202 <BackButton onClick={() => history.push('/employees')}> 203 Vrati se nazad 204 </BackButton> 205 <SaveChangesButton onClick={onSaveChanges}> 206 Zacuvaj gi promenti 207 </SaveChangesButton> 208 </BackAndSaveChangesButtonsWrapper> 209 </RowWrapper> 210 </EmployeeEditWrapper> 136 ) : ( 137 <> 138 <RowWrapper> 139 <LabelAndInputWrapper> 140 <Label>Име</Label> 141 <StandardInputField 142 value={employeeEditableData?.firstName ?? ''} 143 name='firstName' 144 onChange={setEmployeeEditableData} 145 /> 146 </LabelAndInputWrapper> 147 <LabelAndInputWrapper> 148 <Label>Презиме</Label> 149 <StandardInputField 150 value={employeeEditableData?.lastName ?? ''} 151 name='lastName' 152 onChange={setEmployeeEditableData} 153 /> 154 </LabelAndInputWrapper> 155 </RowWrapper> 156 <RowWrapper> 157 <LabelAndInputWrapper> 158 <Label>Емаил</Label> 159 <StandardInputField 160 value={employeeEditableData?.email ?? ''} 161 name='email' 162 type='email' 163 onChange={setEmployeeEditableData} 164 /> 165 </LabelAndInputWrapper> 166 <LabelAndInputWrapper> 167 <Label>Телефон</Label> 168 <StandardInputField 169 value={employeeEditableData?.mobile ?? ''} 170 name='mobile' 171 onChange={setEmployeeEditableData} 172 /> 173 </LabelAndInputWrapper> 174 </RowWrapper> 175 <RowWrapper> 176 <LabelAndInputWrapper> 177 <Label>Лозинка</Label> 178 <StandardInputField 179 value={employeeEditableData?.password ?? ''} 180 name='password' 181 type={isPasswordVisible ? 'text' : 'password'} 182 onChange={setEmployeeEditableData} 183 /> 184 </LabelAndInputWrapper> 185 <IconButton 186 sx={{ marginTop: '23px' }} 187 onClick={() => 188 setIsPasswordVisible(!isPasswordVisible) 189 } 190 > 191 {isPasswordVisible ? ( 192 <VisibilityIcon /> 193 ) : ( 194 <VisibilityOffIcon /> 195 )} 196 </IconButton> 197 <LabelAndInputWrapper> 198 <Label>Потврди Лозинка</Label> 199 <StandardInputField 200 value={confirmPassword} 201 name='confirmPassword' 202 type={isPasswordVisible ? 'text' : 'password'} 203 onChange={setConfirmPassword} 204 /> 205 </LabelAndInputWrapper> 206 </RowWrapper> 207 <RowWrapper> 208 {isLoadingZonesData ? ( 209 <AbsoluteLoader 210 containerStyle={{ 211 position: 'absolute', 212 left: '310px', 213 bottom: '5px', 214 width: '40px', 215 height: '40px', 216 }} 217 /> 218 ) : null} 219 <LabelAndInputWrapper> 220 <Label>Одговорен за:</Label> 221 <Dropdown 222 multiple 223 value={zones ?? []} 224 onChange={handleZonesChange} 225 renderValue={(selected) => { 226 return selected.join(', '); 227 }} 228 MenuProps={MenuProps} 229 > 230 {!isLoadingZonesData && 231 zoneOptions.map((zone) => ( 232 <DropdownOption value={zone} key={zone}> 233 <Checkbox 234 checked={ 235 zones.indexOf(zone) > -1 236 } 237 /> 238 <ListItemText primary={zone} /> 239 </DropdownOption> 240 ))} 241 </Dropdown> 242 </LabelAndInputWrapper> 243 <LabelAndInputWrapper> 244 <Label>Статус</Label> 245 <Dropdown 246 value={ 247 employeeEditableData?.status !== '' && 248 employeeEditableData?.status !== null 249 ? employeeEditableData?.status 250 : statusOptions[0].value 251 } 252 name='status' 253 onChange={setEmployeeEditableData} 254 MenuProps={MenuProps} 255 > 256 {statusOptions.map((option) => ( 257 <DropdownOption 258 value={option.value} 259 key={option.value} 260 > 261 {option.text} 262 </DropdownOption> 263 ))} 264 </Dropdown> 265 </LabelAndInputWrapper> 266 </RowWrapper> 267 <SwitchRowWrapper> 268 <SwitchTitle>Акаунт</SwitchTitle> 269 <SwitchLabelAndInputWrapper> 270 <Label>Активен:</Label> 271 <AccountSwitch 272 checked={!accStatus} 273 value={accStatus} 274 name='accountActive' 275 onClick={() => setAccStatus(!accStatus)} 276 /> 277 </SwitchLabelAndInputWrapper> 278 </SwitchRowWrapper> 279 <RowWrapper> 280 <DeleteButton onClick={onDeleteEmployee}> 281 Избриши Вработен 282 </DeleteButton> 283 <BackAndSaveChangesButtonsWrapper> 284 <BackButton 285 onClick={() => history.push('/employees')} 286 > 287 Врати се Назад 288 </BackButton> 289 <SaveChangesButton onClick={onSaveChanges}> 290 Зачувај ги Промените 291 </SaveChangesButton> 292 </BackAndSaveChangesButtonsWrapper> 293 </RowWrapper> 294 </> 295 )} 296 </EmployeeEditWrapper> 297 ); 211 298 }; 212 299 -
sources/client/src/components/admin/EmployeeEdit/styles.js
re8b1076 rbc20307 1 import styled from "styled-components"; 2 import { Button, InputLabel, MenuItem, Select, Switch, TextField, Typography } from "@mui/material"; 1 import styled from 'styled-components'; 2 import { 3 Button, 4 InputLabel, 5 MenuItem, 6 Select, 7 Switch, 8 TextField, 9 Typography, 10 } from '@mui/material'; 3 11 import VIcon from '@mui/icons-material/Visibility'; 4 12 import VOffIcon from '@mui/icons-material/VisibilityOff'; 5 13 6 14 export const EmployeeEditWrapper = styled.div` 7 display: flex; 8 flex-direction: column; 9 max-width: 800px; 10 border: 1px solid whiteSmoke; 11 border-radius: 10px; 12 padding: 10px 20px; 13 margin-top: 20px; 14 margin-left: 30px; 15 background-color: white; 16 box-shadow: 15px 15px 10px ${props => props.theme.palette.background.shadow}; 15 display: flex; 16 flex-direction: column; 17 max-width: 800px; 18 height: 693px; 19 border: 1px solid whiteSmoke; 20 border-radius: 10px; 21 padding: 10px 20px; 22 margin-top: 20px; 23 margin-left: 30px; 24 background-color: white; 25 box-shadow: 15px 15px 10px ${(props) => props.theme.palette.background.shadow}; 17 26 `; 18 27 19 export const Title = styled(Typography).attrs({ 20 21 })` 22 border-bottom: 2px solid rgba(0, 0, 0, 0.12); 23 padding-bottom: 10px; 24 margin-bottom: 15px; 28 export const Title = styled(Typography).attrs({})` 29 border-bottom: 2px solid rgba(0, 0, 0, 0.12); 30 padding-bottom: 10px; 31 margin-bottom: 15px; 25 32 `; 26 33 27 34 export const RowWrapper = styled.div` 28 display: flex; 29 flex-direction: row; 30 justify-content: space-between; 31 margin-bottom: 25px; 35 display: flex; 36 flex-direction: row; 37 justify-content: space-between; 38 margin-bottom: 25px; 39 position: relative; 32 40 `; 33 41 34 export const LabelAndInputWrapper = styled.div` 42 export const LabelAndInputWrapper = styled.div``; 35 43 36 `;44 export const Label = styled(InputLabel).attrs({})``; 37 45 38 export const Label = styled(InputLabel).attrs({ 39 40 })``; 41 42 export const StandardInputField = styled(TextField).attrs({ 43 44 })` 45 width: 300px; 46 export const StandardInputField = styled(TextField).attrs({})` 47 width: 300px; 46 48 `; 47 49 48 50 export const VisibilityIcon = styled(VIcon).attrs({ 49 50 fontSize: '2rem'51 }51 sx: { 52 fontSize: '2rem', 53 }, 52 54 })``; 53 55 54 56 export const VisibilityOffIcon = styled(VOffIcon).attrs({ 55 56 fontSize: '2rem'57 }57 sx: { 58 fontSize: '2rem', 59 }, 58 60 })``; 59 61 60 export const Dropdown = styled(Select).attrs({ 61 62 })` 63 width: 300px; 62 export const Dropdown = styled(Select).attrs({})` 63 width: 300px; 64 64 `; 65 65 66 export const DropdownOption = styled(MenuItem).attrs({ 66 export const DropdownOption = styled(MenuItem).attrs({})` 67 > span { 68 color: ${(props) => props.theme.palette.primary.main}; 69 svg { 70 color: ${(props) => props.theme.palette.primary.main}; 71 } 72 } 73 > div > span { 74 font-size: 1.3rem; 75 } 76 `; 67 77 68 })``; 78 // export const 69 79 70 80 export const SwitchRowWrapper = styled.div` 71 72 73 81 text-align: center; 82 margin-top: 10px; 83 margin-bottom: 50px; 74 84 `; 75 85 76 86 export const SwitchTitle = styled.p` 77 78 79 80 87 font-size: 18px; 88 font-weight: 600; 89 margin: 0; 90 margin-bottom: 5px; 81 91 `; 82 92 83 93 export const SwitchLabelAndInputWrapper = styled.div` 84 display: flex; 85 flex-direction: row; 86 align-items: center; 87 justify-content: center; 88 94 display: flex; 95 flex-direction: row; 96 align-items: center; 97 justify-content: center; 89 98 `; 90 99 91 export const AccountSwitch = styled(Switch).attrs(props => ({ 92 }))` 93 .MuiSwitch-switchBase { 94 color: red; 95 } 96 .MuiSwitch-track { 97 background-color: red; 98 } 99 .MuiSwitch-switchBase.Mui-checked { 100 color: ${props => props.theme.palette.primary.main}; 101 } 102 .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track { 103 background-color: ${props => props.theme.palette.primary.main}; 104 } 100 export const AccountSwitch = styled(Switch).attrs((props) => ({}))` 101 .MuiSwitch-switchBase { 102 color: red; 103 } 104 .MuiSwitch-track { 105 background-color: red; 106 } 107 .MuiSwitch-switchBase.Mui-checked { 108 color: ${(props) => props.theme.palette.primary.main}; 109 } 110 .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track { 111 background-color: ${(props) => props.theme.palette.primary.main}; 112 } 105 113 `; 106 114 115 export const BackAndSaveChangesButtonsWrapper = styled.div``; 107 116 108 export const BackAndSaveChangesButtonsWrapper = styled.div` 109 110 `; 111 112 export const DeleteButton = styled(Button).attrs(props => ({ 113 variant: 'contained', 114 sx: { 115 backgroundColor: `${props.theme.palette.error.main}` 116 } 117 export const DeleteButton = styled(Button).attrs((props) => ({ 118 variant: 'contained', 119 sx: { 120 backgroundColor: `${props.theme.palette.error.main}`, 121 }, 117 122 }))` 118 119 background-color: ${props=> props.theme.palette.error.dark};120 123 :hover { 124 background-color: ${(props) => props.theme.palette.error.dark}; 125 } 121 126 `; 122 127 123 128 export const BackButton = styled(Button).attrs({ 124 variant: 'outlined'129 variant: 'outlined', 125 130 })` 126 127 128 129 130 131 margin-right: 15px; 132 :hover { 133 border: 2px solid; 134 font-weight: 600; 135 } 131 136 `; 132 137 133 export const SaveChangesButton = styled(Button).attrs( props=> ({134 135 136 backgroundColor: `${props.theme.palette.primary.main}`137 }138 export const SaveChangesButton = styled(Button).attrs((props) => ({ 139 variant: 'contained', 140 sx: { 141 backgroundColor: `${props.theme.palette.primary.main}`, 142 }, 138 143 }))` 139 140 141 background-color: ${props => props.theme.palette.primary.dark}142 144 padding: 10px 16px; 145 :hover { 146 background-color: ${(props) => props.theme.palette.primary.dark}; 147 } 143 148 `;
Note:
See TracChangeset
for help on using the changeset viewer.