Advertisement
Guest User

Untitled

a guest
Dec 16th, 2021
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.73 KB | None | 0 0
  1. import React, { useState, useEffect } from "react";
  2. import Box from "@mui/material/Box";
  3. import Grid from "@mui/material/Grid";
  4. import Stack from "@mui/material/Stack";
  5. import Typography from "@mui/material/Typography";
  6. import IconButton from "@mui/material/IconButton";
  7. import ArrowBackOutlinedIcon from "@mui/icons-material/ArrowBackOutlined";
  8. import {
  9. AddAddressDrawer,
  10. ChooseLocationCard,
  11. ChooseServiceCard,
  12. CustomButton,
  13. DescriptionCard,
  14. ErrorHandler,
  15. SavedAddressDrawer,
  16. StyledToggleButtonGroup,
  17. SubscriptionOverviewCard,
  18. } from "../../components";
  19. import { RightArrowStripesIcon } from "../../assets";
  20. import { withDrawer, withSnackBar } from "../../HOC's";
  21. import { ACTIVITY_MODE_TYPE, drawerProps, snackProps } from "../../utils";
  22. import ChooseSlot from "./chooseSlot";
  23. import { useLocation, useParams } from "react-router";
  24. import { useDispatch, useSelector } from "react-redux";
  25. import { actions } from "tanyacare-middleware";
  26. import { CustomCard } from "../../components/composedComponents/subscriptions/customCard";
  27. import { useHistory } from "react-router-dom";
  28. import { routes } from "../../router/routes";
  29. import { useDateValidation } from "@mui/lab/internal/pickers/hooks/useValidation";
  30.  
  31. const MAX_LETTER_COUNT = 200;
  32.  
  33. const {
  34. GET_CLIENT_SUBSCRIPTION_DETAILS,
  35. GET_CLIENT_ADDRESS,
  36. GET_ADDRESS_TYPES,
  37. // UPDATE_SUBSCRIPTION_REFUND_STATUS,
  38. // DELETE_ACTIVITY,
  39. } = actions;
  40.  
  41. function ServiceBooking(props) {
  42. const dispatch = useDispatch();
  43. const location = useLocation();
  44. const history = useHistory();
  45. const params = useParams();
  46. const { drawer, snack } = props;
  47.  
  48. const isEdit = location?.state?.isEdit ?? false;
  49.  
  50. // Store States
  51. const subscriptionData = useSelector(
  52. (state) => state?.clientSubscription?.getSubscriptionDetails
  53. );
  54. const clientAddress = useSelector(
  55. (state) => state?.clientAddress?.getAddress
  56. );
  57.  
  58. const address_type = useSelector(
  59. (state) => state?.clientMaster?.clientAddressTypes
  60. );
  61.  
  62. const validateArray = (testData) => {
  63. return Array.isArray(testData) && testData?.length > 0 ? testData : [];
  64. };
  65.  
  66. //
  67. const { loading, error, data } = subscriptionData;
  68.  
  69. // unique services list with
  70. const getServices = () => {
  71. const filtereServiceOptions = data?.services?.map((service) => ({
  72. ...service,
  73. label: `${service?.name}${
  74. service?.pending_services_count > 0 ? " (1)" : ""
  75. }`,
  76. value: service?.id,
  77. }));
  78. if (!isEdit) {
  79. filtereServiceOptions?.filter(
  80. (option) => option?.pending_services_count > 0
  81. );
  82. }
  83. const key = "id";
  84. const serviceOptions = [
  85. ...new Map(
  86. filtereServiceOptions?.map((item) => [item[key], item])
  87. ).values(),
  88. ];
  89.  
  90. return serviceOptions;
  91. };
  92.  
  93. const filterServiceAndServiceId = (id) => {
  94. if (id) {
  95. const serviceData = getServices()?.filter(
  96. (service) => service?.id === id
  97. )?.[0];
  98. return {
  99. serviceId: location.state?.serviceId,
  100. selectedService: serviceData,
  101. };
  102. }
  103. return {};
  104. };
  105.  
  106. // Component States
  107. const [, setNotFound] = useState(false);
  108. // getServices()?.[0]?.value
  109. const [serviceId, setServiceId] = useState(null);
  110. // getServices()?.[0]
  111. const [selectedService, setSelectedService] = useState(null);
  112. const [mode, setMode] = useState({});
  113. const [address, setAddress] = useState({});
  114. const [selectedVenue, setSelectedVenue] = useState("");
  115. const [description, setDescription] = useState("");
  116. const [client_address, setClientAddress] = useState([])
  117. const [clientAddressLoader, setClientAddressLoader] = useState(true)
  118.  
  119. useEffect(() => {
  120. // if()
  121. dispatch(GET_CLIENT_ADDRESS({}))
  122. // .then((res) => {
  123. // debugger
  124. // // setClientAddress(res?.payload?.data)
  125. // // setClientAddressLoader(false)
  126. // })
  127. // .catch((err) => console.error(err));
  128.  
  129. }, [dispatch]);
  130.  
  131.  
  132. useEffect(() => {
  133. if (params?.id) {
  134. dispatch(GET_ADDRESS_TYPES({}));
  135. getSubscriptionDetailsData(params?.id);
  136. } else {
  137. setNotFound(true);
  138. }
  139. }, []);
  140.  
  141. // Setting the initial state if user navigated to book a service from detail page services row.
  142. useEffect(() => {
  143. // debugger;
  144. const id = location?.state?.serviceId;
  145. const { serviceId: filteredServiceId, selectedService: filteredService } =
  146. filterServiceAndServiceId(id);
  147. setServiceId(filteredServiceId);
  148. setSelectedService(filteredService);
  149. let act_mode = filteredService?.modeOfActivity;
  150. if (act_mode?.length < 2) {
  151. setMode(act_mode?.[0]);
  152. }
  153. }, [location]);
  154.  
  155. // const getEditedService = () => {
  156. // const filtereServiceOptions = location?.state?.edit_data?.service?.map((service) => ({
  157. // ...service,
  158. // label: `${service?.name}${
  159. // service?.pending_services_count > 0 ? " (1)" : ""
  160. // }`,
  161. // value: service?.id,
  162. // })).filter(
  163. // (option) => option?.pending_services_count > 0
  164. // );
  165. // const key = "id";
  166. // const serviceOptions = [
  167. // ...new Map(
  168. // filtereServiceOptions?.map((item) => [item[key], item])
  169. // ).values(),
  170. // ];
  171.  
  172. // return location?.state?.edit_data?.service;
  173. // }
  174.  
  175. const filterEditedServiceAndServiceId = (id) => {
  176. if (id) {
  177. const serviceData = location?.state?.edit_data?.service;
  178. return {
  179. serviceId: location.state?.serviceId,
  180. selectedService: serviceData,
  181. };
  182. }
  183. return {};
  184. };
  185.  
  186. useEffect(() => {
  187. // debugger;
  188. const isEdit = location?.state?.isEdit;
  189. const id = location?.state?.serviceId;
  190. const { serviceId: filteredServiceId, selectedService: filteredService } =
  191. filterEditedServiceAndServiceId(id);
  192. setServiceId(filteredServiceId);
  193. setSelectedService(filteredService);
  194. let activity_mode_options = [];
  195. if (Array.isArray(location?.state?.edit_data?.service?.modeOfActivity)) {
  196. activity_mode_options = [
  197. ...location?.state?.edit_data?.service?.modeOfActivity,
  198. ];
  199. }
  200. let selected_mode = activity_mode_options?.filter(
  201. (mode) => mode?.value === location?.state?.edit_data?.mode
  202. )?.[0];
  203. setMode(selected_mode);
  204. setDescription(location?.state?.description)
  205. // Promise.resolve(dispatch(GET_CLIENT_ADDRESS({})))
  206. // .then((res) => {
  207. // // setClientAddress(res?.payload?.data)
  208. // debugger
  209. onSavedAddressSelect(location?.state?.edit_data?.selectedVenue)
  210. // })
  211. // .catch((err) => console.error(err));
  212.  
  213.  
  214. // let act_mode = filteredService?.modeOfActivity;
  215. // if (act_mode?.length < 2) {
  216. // setMode(act_mode?.[0]);
  217. // }
  218. }, [location?.state?.isEdit]);
  219.  
  220. const getSubscriptionDetailsData = (id) => {
  221. Promise.resolve(dispatch(GET_CLIENT_SUBSCRIPTION_DETAILS({ id: id })))
  222. .then((res) => {
  223. // if (isEdit) {
  224. // debugger;
  225. // let event = {
  226. // target: {
  227. // value: location.state?.edit_data?.service?.id,
  228. // },
  229. // };
  230. // handleServiceChange(event, location.state?.edit_data?.mode);
  231. // }
  232. })
  233. .catch((err) => console.error(err));
  234. };
  235.  
  236.  
  237.  
  238. const navigateToTracking = () => {
  239. // Navigate to tracker
  240. if (history) history.push(routes.tracker.pathName);
  241. };
  242.  
  243. const continueBooking = () => {
  244. if (!selectedService?.id) {
  245. return snack.setSnack({
  246. open: true,
  247. message: "Please choose the service to continue",
  248. severity: snackProps.severity.error,
  249. });
  250. }
  251. if (!mode?.value) {
  252. return snack.setSnack({
  253. open: true,
  254. message: "Please choose the mode of activity",
  255. severity: snackProps.severity.error,
  256. });
  257. }
  258. if (mode?.value === ACTIVITY_MODE_TYPE?.IN_PERSON && !address) {
  259. return snack.setSnack({
  260. open: true,
  261. message: "Please choose the address to continue",
  262. severity: snackProps.severity.error,
  263. });
  264. }
  265.  
  266. const selectedData = {
  267. activity_type_id: selectedService?.id,
  268. // title: isEdit
  269. // ? params?.data?.title
  270. // : `Appointment for ${selectedService?.name ?? 'Service'}`,
  271. title: `Appointment for ${selectedService?.name ?? "Service"}`,
  272. activityTypeName: selectedService?.name,
  273. serviceId: selectedService?.id,
  274. subscriptionId: subscriptionData?.data?.id,
  275. subscriptionType: subscriptionData?.data?.subscriptionType,
  276. duration: selectedService?.duration,
  277. providerId: selectedService?.partnerId,
  278. resourceTypeCategoryId: selectedService?.resourceTypeCategoryId,
  279. // ...params?.data,
  280. address:
  281. mode?.value === ACTIVITY_MODE_TYPE.VIDEO
  282. ? null
  283. : address?.add_location?.address,
  284. selectedVenue: selectedVenue,
  285. description: description,
  286. latitude:
  287. mode?.value === ACTIVITY_MODE_TYPE.VIDEO
  288. ? null
  289. : `${address?.add_location?.latitude}` ?? null,
  290. longitude:
  291. mode?.value === ACTIVITY_MODE_TYPE.VIDEO
  292. ? null
  293. : `${address?.add_location?.longitude}` ?? null,
  294. mode: mode?.value,
  295. };
  296.  
  297. // If everything okay continue booking
  298. drawer.setDrawer({
  299. open: true,
  300. anchor: drawerProps.direction.right,
  301. component: (handleClose) => (
  302. <ChooseSlot
  303. data={selectedData}
  304. navigateToTracking={navigateToTracking}
  305. handleClose={handleClose}
  306. />
  307. ),
  308. sx: {
  309. Drawer: {
  310. "& .MuiDrawer-paper": {
  311. minHeight: "100vh",
  312. maxWidth: "600px",
  313. },
  314. },
  315. },
  316. });
  317. };
  318.  
  319. const handleServiceChange = (event, userSelectedMode) => {
  320. setServiceId(event.target.value);
  321. let act_mode = getServices()?.filter(
  322. (service) => service?.id === event.target.value
  323. )?.[0]?.modeOfActivity;
  324. setSelectedService(
  325. getServices()?.filter(
  326. (service) => service?.id === event.target.value
  327. )?.[0]
  328. );
  329.  
  330. if (userSelectedMode) {
  331. return setMode(userSelectedMode);
  332. } else if (act_mode?.length < 2) {
  333. setMode(act_mode?.[0]);
  334. }
  335. };
  336.  
  337. useEffect(() => {
  338. console.log("_______________________________");
  339. console.log(selectedService);
  340. });
  341.  
  342. const handleModeChange = (event, newMode) => {
  343. const selectedMode = selectedService?.modeOfActivity?.filter(
  344. (activityMode) => activityMode?.value === newMode
  345. )?.[0];
  346. if (newMode !== null) {
  347. setMode(selectedMode);
  348. }
  349. };
  350.  
  351. const handleDescriptionChange = (evt) => {
  352. if (evt.target.value?.length <= MAX_LETTER_COUNT) {
  353. setDescription(evt.target.value);
  354. }
  355. };
  356.  
  357. // Selected Saved Address
  358. const onSavedAddressSelect = (addressId) => {
  359. debugger
  360. if (addressId) {
  361. const { data: selectedAddress = [] } = clientAddress ?? {} ;
  362. console.clear()
  363. console.log(selectedAddress)
  364.  
  365. if(Array.isArray(selectedAddress))
  366. {
  367. const addressObj = selectedAddress?.filter(
  368. (addressItem) => addressItem?.value === addressId
  369. )?.[0];
  370. setAddress(addressObj);
  371. setSelectedVenue(addressObj?.value);
  372. }
  373.  
  374. }
  375. props.drawer.setDrawer({
  376. open: false,
  377. });
  378. };
  379.  
  380. const onSavedAddressButtonClick = () => {
  381. const { data: selectedAddress } = clientAddress ?? {};
  382. props.drawer.setDrawer({
  383. open: true,
  384. component: (handleClose) => (
  385. <SavedAddressDrawer
  386. data={
  387. Array.isArray(selectedAddress) && selectedAddress?.length > 0
  388. ? selectedAddress
  389. : []
  390. }
  391. value={address}
  392. onSave={onSavedAddressSelect}
  393. handleClose={handleClose}
  394. />
  395. ),
  396. });
  397. };
  398.  
  399. const onNewAddressSave = (newLocation) => {
  400. // Close the drawer first
  401. props.drawer.setDrawer({
  402. open: false,
  403. });
  404. setAddress({ add_location: { ...newLocation } });
  405. setSelectedVenue("NEW_ADDRESS");
  406. };
  407.  
  408. const onAddEditAddressButtonClick = () => {
  409. props.drawer.setDrawer({
  410. open: true,
  411. component: (handleClose) => (
  412. <AddAddressDrawer
  413. isEdit={selectedVenue === "NEW_ADDRESS"}
  414. data={address}
  415. options={validateArray(address_type?.data)}
  416. onSave={onNewAddressSave}
  417. handleClose={handleClose}
  418. />
  419. ),
  420. });
  421. };
  422.  
  423. if (error) {
  424. return (
  425. <Stack sx={{ height: "100%", width: "100%" }}>
  426. <ErrorHandler onRetry={() => getSubscriptionDetailsData(params?.id)} />
  427. </Stack>
  428. );
  429. }
  430.  
  431. return (
  432. <Box sx={{ p: 2 }}>
  433. {/* <Typography
  434. variant="body1"
  435. color="textSecondary"
  436. sx={{ pt: { xs: 1, sm: 1 } }}
  437. >
  438. Breadcrumbs section
  439. </Typography> */}
  440.  
  441. <Typography variant="h6" sx={{ pt: { xs: 1, sm: 1 }, fontWeight: 500 }}>
  442. <IconButton size="small" onClick={() => history.goBack()}>
  443. <ArrowBackOutlinedIcon fontSize="small" />
  444. </IconButton>
  445. Subscription Booking
  446. </Typography>
  447.  
  448. {/* Main Container */}
  449. <Box sx={{ py: 2 }}>
  450. <Grid container spacing={2}>
  451. <Grid item xs={12}>
  452. <SubscriptionOverviewCard
  453. loading={loading}
  454. data={data}
  455. showCallToActions={false}
  456. />
  457. </Grid>
  458. <Grid container item xs={12} md={6} spacing={2}>
  459. <Grid item xs={12} md={12}>
  460. <ChooseServiceCard
  461. loading={loading}
  462. options={getServices()}
  463. value={serviceId}
  464. onChange={handleServiceChange}
  465. isEdit={isEdit ? true : false}
  466. />
  467. </Grid>
  468. <Grid item xs={12} md={12}>
  469. <DescriptionCard
  470. value={description}
  471. onChange={handleDescriptionChange}
  472. maxCount={MAX_LETTER_COUNT}
  473. />
  474. </Grid>
  475. </Grid>
  476.  
  477. <Grid container item xs={12} md={6} spacing={2}>
  478. {Array?.isArray(selectedService?.modeOfActivity) &&
  479. selectedService?.modeOfActivity?.length > 0 && (
  480. <Grid item xs={12} md={12}>
  481. <CustomCard title={"Mode of Activity"}>
  482. {/* Modes */}
  483. <Box sx={{ py: 2, px: 3.5 }}>
  484. <StyledToggleButtonGroup
  485. data={mode}
  486. options={selectedService?.modeOfActivity}
  487. onChange={handleModeChange}
  488. />
  489. </Box>
  490. </CustomCard>
  491. </Grid>
  492. )}
  493. {mode?.value === ACTIVITY_MODE_TYPE.IN_PERSON && (
  494. <Grid item xs={12} md={12}>
  495. <ChooseLocationCard
  496. data={address}
  497. label={"address"}
  498. isEdit={selectedVenue === "NEW_ADDRESS"}
  499. onSavedAddressButtonClick={onSavedAddressButtonClick}
  500. onAddEditAddressButtonClick={onAddEditAddressButtonClick}
  501. />
  502. </Grid>
  503. )}
  504. </Grid>
  505.  
  506. <Grid item xs={12} md={12}>
  507. <Stack
  508. sx={{
  509. flexDirection: "row",
  510. gap: 2,
  511. height: "100%",
  512. justifyContent: "flex-end",
  513. alignItems: "flex-end",
  514. flexWrap: { xs: "wrap-reverse", md: "nowrap" },
  515. }}
  516. >
  517. {/* <Box sx={{ minWidth: 100 }}>
  518. <CustomButton
  519. fullWidth
  520. variant="outlined"
  521. color="primary"
  522. sx={{
  523. bgcolor: "background.paper",
  524. border: 0,
  525. color: "text.primary",
  526. minHeight: (theme) => theme.spacing(5),
  527. "&:hover": {
  528. bgcolor: "background.paper",
  529. border: 0,
  530. },
  531. }}
  532. >
  533. Cancel
  534. </CustomButton>
  535. </Box> */}
  536. <Box>
  537. <CustomButton
  538. onClick={continueBooking}
  539. fullWidth
  540. endIcon={<RightArrowStripesIcon />}
  541. >
  542. Continue Booking
  543. </CustomButton>
  544. </Box>
  545. </Stack>
  546. </Grid>
  547. </Grid>
  548. </Box>
  549. </Box>
  550. );
  551. }
  552.  
  553. export default withSnackBar(withDrawer(ServiceBooking));
  554.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement