source: sources/client/src/components/user/Session/index.js@ bc20307

Last change on this file since bc20307 was bc20307, checked in by Tasevski2 <39170279+Tasevski2@…>, 2 years ago

Push before video

  • Property mode set to 100644
File size: 15.8 KB
Line 
1import { useState, useEffect, useContext, useRef, useMemo } from 'react';
2import moment from 'moment';
3
4import SessionGuest from './SessionGuest';
5import SessionUser from './SessionUser';
6import Buttons from './Buttons';
7import AbsoluteLoader from '../../Loaders/AbsoluteLoader';
8import { IconButton, Slide } from '@mui/material';
9import Radio from '@mui/material/Radio';
10import RadioGroup from '@mui/material/RadioGroup';
11import FormControlLabel from '@mui/material/FormControlLabel';
12import {
13 Wrapper,
14 ButtonWrapper,
15 ModalContainer,
16 CloseIcon,
17 KeyValueWrapper,
18 Key,
19 Value,
20 PaymentMethodWrapper,
21 PayWithText,
22 PaymentMethodsWrapper,
23 PayButtonWrapper,
24 ModalPayButton,
25 CardDetails,
26 DateAndCCVWrapper,
27 ModalInput,
28 CreditCard,
29 ModalInputCardNumber,
30} from './styles';
31import Modal from '@mui/material/Modal';
32import Backdrop from '@mui/material/Backdrop';
33
34import {
35 roles,
36 sessionStatus as enumsSessionStatus,
37} from '../../../config/enums';
38import theme from '../../../theme';
39import { UserContext } from '../../../context/UserContext';
40import useUserStartSession from '../../../hooks/useUserStartSession';
41import useForm from '../../../hooks/useForm';
42import useUserFinishedSession from '../../../hooks/useUserFinishedSession';
43import useUserPayForSession from '../../../hooks/useUserPayForSession';
44import useGetSessionOverInfo from '../../../hooks/useGetSessionOverInfo';
45import useGetData from '../../../hooks/useGetData';
46
47import { convertMinutesToString } from '../../../utils/convertMinToString';
48
49const normalizeSesionData = session => ({
50 plate: session?.plate?.plate ?? '',
51 zone: session?.parkingZone?.pzName ?? ''
52});
53
54const defaultTime = 15000;
55const Session = () => {
56 // const [timer, setTimer] = useState(10000);
57 // let timer = 10000;
58 // const timerInterval = setInterval(() => {
59 // console.log('VIKTOR', timer);
60 // // setTimer(defaultTime);
61 // timer = 15000;
62 // }, timer);
63 // useEffect(() => {
64 // return () => {
65 // clearInterval(timerInterval);
66 // }
67 // })
68 const { data: fetchedSelectZones, isLoading: isLoadingSelectZones } =
69 useGetData({ url: '/parkingZone/parkingZoneNames' });
70 const { user } = useContext(UserContext);
71 const [isModalOpen, setModalOpen] = useState(false);
72 const [paymentMethod, setPaymentMethod] = useState('');
73 const [cardNumber, setCardNumber] = useState('');
74 const [cardExpDate, setCardExpDate] = useState('');
75 const [cardCCV, setCardCCV] = useState('');
76 const { data: session, isLoading: isLoadingSession, setData: setSession } = useGetData({
77 url: '/parkingSession',
78 });
79 console.log('SESSION', session);
80 const {
81 data: userSessionInfo,
82 onFormChange: onFormChangeUserSessionInfo,
83 setNewData: setNewUserSessionData,
84 } = useForm({
85 plate: 'NONE',
86 zone: 'NONE',
87 });
88 const { userFinishedSession } = useUserFinishedSession();
89 const timerRef = useRef(0);
90 const { userStartSession } = useUserStartSession();
91 const { userPayForSession, isLoading: isLoadingPayForSession } =
92 useUserPayForSession();
93 const {
94 getSessionInfoOver,
95 isLoading: isLoadingSessionInfoOver,
96 totalPrice,
97 } = useGetSessionOverInfo();
98 const cardNumberHandler = (e) => {
99 const newVal = e.target.value.replace(/\s+/g, '');
100 let parts = [];
101 for (let i = 0; i < newVal.length; i += 4) {
102 parts.push(newVal.substring(i, i + 4));
103 }
104 console.log(parts);
105 if (parts.length) {
106 setCardNumber(parts.join(' '));
107 } else {
108 setCardNumber(newVal);
109 }
110 };
111
112 const cardExpDateHandler = (e) => {
113 const newVal = e.target.value.replace(/[^0-9]/, '');
114 let first = newVal.substring(0, 2);
115 let second = newVal.substring(2, 4);
116 if (second !== '') {
117 setCardExpDate([first, second].join('/'));
118 } else {
119 setCardExpDate(newVal);
120 }
121 };
122
123 const handleStartSession = () => {
124 userStartSession({ sessionData: userSessionInfo, setSession });
125 };
126
127 const handleEndSession = () => {
128 userFinishedSession({ setSession });
129 };
130
131 const handlePayForSession = () => {
132 if (paymentMethod) {
133 if (
134 paymentMethod === 'card' &&
135 (cardNumber === '' || cardCCV === '' || cardExpDate === '')
136 ) {
137 return;
138 }
139 let paymentCredentials = null;
140 if (paymentMethod === 'card') {
141 paymentCredentials = {
142 cardNumber: cardNumber,
143 cardExpDate: cardExpDate,
144 cardCCV: cardCCV,
145 };
146 }
147 userPayForSession({
148 method: paymentMethod,
149 paymentCredentials,
150 });
151 }
152 };
153
154 const checkForDoubleClick = (e) => {
155 timerRef.current++;
156 setTimeout(() => {
157 if (timerRef.current !== 0) {
158 timerRef.current = 0;
159 }
160 }, 500);
161 if (timerRef.current >= 2) {
162 timerRef.current = 0;
163 if (!session) {
164 handleStartSession();
165 } else if (
166 session.status === enumsSessionStatus.active ||
167 session.status === enumsSessionStatus.idle
168 ) {
169 handleEndSession();
170 }
171 }
172 };
173
174 const handlePayButton = () => {
175 setModalOpen(true);
176 if (totalPrice) return; // don't send request if they are already set
177 getSessionInfoOver();
178 };
179
180 useEffect(() => {
181 if(session) {
182 setNewUserSessionData(normalizeSesionData(session));
183 }
184 }, [session])
185
186 const totalTime = useMemo(() => {
187 if(session?.timeEnd && session?.timeStart) {
188 const start = moment(session.timeStart);
189 const end = moment(session.timeEnd);
190 const diffMin = Math.round(end.diff(start) / 60000);
191 return convertMinutesToString(diffMin);
192 }
193 return null;
194 }, [session])
195
196 return (
197 <>
198 <Modal
199 open={isModalOpen}
200 onClose={() => {
201 setModalOpen(false);
202 }}
203 closeAfterTransition
204 BackdropComponent={Backdrop}
205 BackdropProps={{
206 timeout: 500,
207 }}
208 style={{
209 display: 'flex',
210 alignItems: 'center',
211 justifyContent: 'center',
212 }}
213 >
214 <Slide in={isModalOpen}>
215 <ModalContainer>
216 <IconButton
217 style={{
218 marginLeft: 295,
219 }}
220 onClick={() => {
221 setModalOpen(false);
222 }}
223 >
224 <CloseIcon />
225 </IconButton>
226 {isLoadingSessionInfoOver ? ( // TODO FETCH SESSION DATA
227 <AbsoluteLoader
228 containerStyle={{
229 width: '200px',
230 height: '200px',
231 margin: 'auto',
232 marginTop: '50px',
233 }}
234 />
235 ) : (
236 <>
237 <KeyValueWrapper>
238 <Key>Време:</Key>
239 <Value>{totalTime}</Value>
240 </KeyValueWrapper>
241 <KeyValueWrapper>
242 <Key>Вкупна сума:</Key>
243 <Value>{totalPrice} ден.</Value>
244 </KeyValueWrapper>
245 <PaymentMethodWrapper>
246 <PayWithText>Плати со:</PayWithText>
247 <PaymentMethodsWrapper>
248 <RadioGroup
249 aria-label='payment-methods'
250 name='payment-method'
251 value={paymentMethod}
252 onChange={(e) =>
253 setPaymentMethod(e.target.value)
254 }
255 >
256 <FormControlLabel
257 value='mobile'
258 control={
259 <Radio
260 sx={{
261 color: theme.palette
262 .primary.main,
263 '&.Mui-checked': {
264 color: theme
265 .palette
266 .primary
267 .main,
268 },
269 }}
270 />
271 }
272 label='Мобилен'
273 labelPlacement='start'
274 />
275 <FormControlLabel
276 value='card'
277 control={
278 <Radio
279 sx={{
280 color: theme.palette
281 .primary.main,
282 '&.Mui-checked': {
283 color: theme
284 .palette
285 .primary
286 .main,
287 },
288 }}
289 />
290 }
291 label='Картичка'
292 labelPlacement='start'
293 />
294 </RadioGroup>
295 </PaymentMethodsWrapper>
296 </PaymentMethodWrapper>
297 {paymentMethod === 'card' ? (
298 <CardDetails>
299 <ModalInputCardNumber
300 InputProps={{
301 startAdornment: <CreditCard />,
302 }}
303 onChange={cardNumberHandler}
304 value={cardNumber}
305 />
306 <DateAndCCVWrapper>
307 <ModalInput
308 InputProps={{
309 placeholder: 'Exp: 11/21',
310 }}
311 style={{
312 width: '45%',
313 }}
314 onChange={cardExpDateHandler}
315 value={cardExpDate}
316 />
317 <ModalInput
318 InputProps={{
319 placeholder: 'CCV',
320 }}
321 style={{ width: '35%' }}
322 value={cardCCV}
323 onChange={(e) =>
324 setCardCCV(e.target.value)
325 }
326 />
327 </DateAndCCVWrapper>
328 </CardDetails>
329 ) : null}
330 <PayButtonWrapper>
331 {isLoadingPayForSession ? (
332 <AbsoluteLoader
333 containerStyle={{
334 width: '51px',
335 height: '51px',
336 margin: 'auto',
337 }}
338 />
339 ) : (
340 <ModalPayButton
341 onClick={handlePayForSession}
342 >
343 Плати
344 </ModalPayButton>
345 )}
346 </PayButtonWrapper>
347 </>
348 )}
349 </ModalContainer>
350 </Slide>
351 </Modal>
352 {!isLoadingSession && (
353 <Wrapper>
354 {user.role === roles.user ? (
355 <SessionUser
356 sessionStatus={session?.status ?? null}
357 sessionInfo={normalizeSesionData(session)}
358 zones={fetchedSelectZones ?? []}
359 data={userSessionInfo}
360 onFormChange={onFormChangeUserSessionInfo}
361 setNewData={setNewUserSessionData}
362 />
363 ) : (
364 <SessionGuest
365 sessionStatus={session?.status ?? null}
366 sessionInfo={normalizeSesionData(session)}
367 zones={fetchedSelectZones ?? []}
368 data={userSessionInfo}
369 onFormChange={onFormChangeUserSessionInfo}
370 setNewData={setNewUserSessionData}
371 />
372 )}
373 <ButtonWrapper>
374 <Buttons
375 status={session?.status ?? null}
376 handlePayButton={handlePayButton}
377 onClick={checkForDoubleClick}
378 />
379 </ButtonWrapper>
380 </Wrapper>
381 )}
382 </>
383 );
384};
385
386export default Session;
Note: See TracBrowser for help on using the repository browser.