webapp/components/dashboard/seller/new/pages/index.js

import {Meteor} from 'meteor/meteor';
import {styled} from '@mui/material/styles';
import React, {useState} from 'react';
import Grid from '@mui/material/Grid';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import {Helmet} from 'react-helmet';
import PropTypes from 'prop-types';
import getIndPhonesOrEmails from '/common/utils/getIndPhonesOrEmails';
import UserPhoneOtp from '/components/forms/OtpCompForRHF';
import {Switch, Route, Redirect} from 'react-router-dom';
import RouteWithProps from '/common/components/routeWithProps';
import NotFound from '/components/NotFound';
import Form1 from './MandatoryNew';
import Form2 from './OptionalNew';
import Form3 from './ImageUploadNew';
import {useTracker} from 'meteor/react-meteor-data';
import Projects from '/common/db/project';
import {Mongo} from 'meteor/mongo';
import {useForm, FormProvider} from 'react-hook-form';
import dateFormat from '/common/utils/date/toStr';

const PREFIX = 'RawUnitFormWrapper';

const classes = {
	phoneVerificationPaper: `${PREFIX}-phoneVerificationPaper`,
	propertyDetail: `${PREFIX}-propertyDetail`,
	formStyle: `${PREFIX}-formStyle`,
};

// TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed.
const DashboardSellerStyledComp = styled('div')((
	{
		theme,
	},
) => ({
	[`& .${classes.phoneVerificationPaper}`]: {
		display: 'flex',
		height: theme.spacing(27),
		alignItems: 'center',
		marginTop: theme.spacing(2),
	},

	[`& .${classes.propertyDetail}`]: {
		opacity: '0.8',
		margin: theme.spacing(1),
	},

	[`& .${classes.formStyle}`]: {
		margin: 'auto',
	},
}));

const SellerRawUnitEdit = new Mongo.Collection('seller-rawUnit-edit');

/**
 * This Component renders a react hook form for adding Property with basic details.
 * @param {object} props props
 * @return {ReactElement} React component
 */
function RawUnitFormWrapper({user, waitingForData, error, match, location, history} ) {
	const form = useForm();
	const {watch} = form;
	const phoneValue = watch('verifyPhones');
	const [vNExists, setVNExists] = useState(getIndPhonesOrEmails(user, 'phones')?.filter(({verified}) => verified === true)?.length);

	const {phones: verifiedPhones, _id} = user || {};
	const {phones: unverifiedPhones} = user.profile || {};

	const onOtpVerify = ({cb}) => {
		setVNExists(true);
		if (cb) cb();
	};

	const {params: {rawUnitId}} = match;
	let ruData;
	const sellerId = user.relationships?.seller?._id;

	const data = useTracker(() => {
		const subscribedData = Meteor.subscribe('seller.rawUnitEdit', {rawUnitId, sellerId});

		if (!subscribedData.ready) return [];

		if (rawUnitId !== 'new') {
			ruData = SellerRawUnitEdit.findOne({_id: rawUnitId});
			if (!ruData) return [];
			const {bedrooms, propertyType, plotFacing, floor, facing, constructedOn, parking, balconies, floors, bathrooms, waterSource, saleInfo, location: ruLocation, amenities, projectName} = ruData;
			ruData.bedrooms = bedrooms?.number;
			ruData.level = propertyType.level;
			ruData.bathrooms = bathrooms?.number;
			ruData.facing = facing;
			ruData.floor = floor;
			ruData.constructedOn = constructedOn ? dateFormat(constructedOn, 'YYYY-MM') : '';
			ruData.waterSource = waterSource ? Object.keys(waterSource)?.filter(k => waterSource[k] === true || 'true') : [];
			ruData.price = saleInfo?.price?.total;
			delete ruData?.saleInfo;
			ruData.locality = [{value: ruLocation?.locality, label: ruLocation?.locality?.toSentenceCase()}];
			delete ruData?.location;
			if (propertyType.project) {
				let project = Projects.findOne({name: projectName});
				ruData.project = [{label: projectName, value: project?._id}];
				delete ruData.projectName;
				ruData.amenities = amenities?.map(({name}) => name);
			}
			ruData.balconies = balconies?.number;
			ruData.floors = floors?.number;
			ruData.cParking = parking?.covered?.number;
			ruData.uParking = parking?.uncovered?.number;
			ruData.facing = plotFacing;
			delete ruData?.parking;
			return {ruData, waitingForData: false};
		}
		return {ruData: {}, waitingForData: true};
	}, []);

	const submitData = ({data: formData, id, page, params}) => {
		Meteor.call('rawUnit.addFromDashBoard', {data: formData, page}, (err, res) => {
			if (err) Log.fatal('Unable to list your property', err, {formData, id, page, params, res});
			if (res?.message) Log.info(res?.message);
			else if (res?.id || id) history.push(`/dashboard/seller/listing/${id || res.id}/${params}`);
		});
	};

	if (error) return <NotFound {...{location, history}}/>;
	return (
		(
			<DashboardSellerStyledComp>
				<Helmet>
					<title>
						Dash: List Property
					</title>
					<style>
						{`
					.hide { display: hidden };`
						}
					</style>
				</Helmet>
				{vNExists ? (
					<Grid container item justifyContent='space-around' xs={12}>
						<Grid>
							<Typography align='center' className={classes.propertyDetail} variant='h5'>
								Property Details
							</Typography>
						</Grid>
						<Grid item xs={12}>
							<Switch>
								<Route component={() => <Redirect to='/dashboard/seller/listing/new/details'/>} exact path='/dashboard/seller/listing/:rawUnitId'/>
								<RouteWithProps component={Form1} exact path='/dashboard/seller/listing/:rawUnitId/details' {...{user, ruData: data, waitingForData, error, submitData}}/>
								<RouteWithProps component={Form2} exact path='/dashboard/seller/listing/:rawUnitId/extraDetails' {...{user, ruData: data, waitingForData, error, submitData}}/>
								<RouteWithProps component={Form3} exact path='/dashboard/seller/listing/:rawUnitId/imageUpload' {...{user, ruData: data, waitingForData, error, submitData}}/>
								<RouteWithProps component={NotFound}/>
							</Switch>
						</Grid>
					</Grid>
				)
					: (
						<FormProvider {...form}>
							<Paper className={classes.phoneVerificationPaper}>
								<form className={classes.formStyle}>
									<Grid container item justifyContent='space-around' xs={12}>
										<Grid item lg={6} md={5} xs={11}>
											<Typography>
												Kindly verify your number to proceed.
											</Typography>
										</Grid>
										<Grid item lg={6} md={6} xs={11}>
											<UserPhoneOtp
												config={{rhf: true, showPhoneOptions: true}}
												label='Mobile'
												name='verifyPhones'
												onOtpSubmitCallback={onOtpVerify}
												phone={phoneValue}
												user={{verifiedPhones, unverifiedPhones, _id}}
											/>
										</Grid>
									</Grid>
								</form>
							</Paper>
						</FormProvider>
					)}
			</DashboardSellerStyledComp>
		)
	);
}

RawUnitFormWrapper.propTypes = {
	error: PropTypes.string,
	history: PropTypes.object,
	location: PropTypes.object,
	match: PropTypes.object,
	params: PropTypes.object,
	ruData: PropTypes.object,
	user: PropTypes.object,
	waitingForData: PropTypes.bool,
};

export default RawUnitFormWrapper;