Advertisement
Guest User

Untitled

a guest
Nov 6th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2. import './VehicleOwnerForm.css';
  3. import validator from 'validator';
  4. import axios from 'axios';
  5. import VehicleFormList from '../Vehicle/VehicleFormList';
  6. import CardFormList from '../Card/CardFormList';
  7. import ReactPhoneInput from 'react-phone-input-2';
  8. import {
  9.     Button,
  10.     Col,
  11.     Container,
  12.     Form,
  13.     Input,
  14.     InputGroup,
  15.     InputGroupAddon,
  16.     Label,
  17.     Row,
  18.     Popover,
  19.     PopoverBody
  20. } from 'reactstrap';
  21. import NavbarComponent from "../../NavbarComponent/NavbarComponent";
  22. import {AUTHORIZATION, GARAGE, VEHICLE_LOGIN_ROUTE} from "../../Text/constants"
  23. import cloneDeep from 'lodash.clonedeep';
  24. import {getHeader} from "../../AuthorizationConfig/GetHeader";
  25. import _request from "../../AuthorizationConfig/AuthRequest";
  26. import moment from "moment";
  27.  
  28. class VehicleOwnerForm extends React.Component {
  29.  
  30.     state = {
  31.         name: {value: '', isValid: true, message: ''},
  32.         surname: {value: '', isValid: true, message: ''},
  33.         dateOfBirth: {value: '', isValid: true, message: ''},
  34.         gender: {value: 'male', isValid: true, message: ''},
  35.         email: {value: '', isValid: true, message: ''},
  36.         phone: {value: '', isValid: true, message: ''},
  37.         password: {value: '', isValid: true, message: ''},
  38.         repeatedPassword: {value: '', isValid: true, message: ''},
  39.         vehicles: [
  40.             {
  41.                 registration: {value: '', isValid: true, message: ''},
  42.                 type: {value: 'car', isValid: true, message: ''},
  43.                 isAdded: false
  44.             }
  45.         ],
  46.         activeCard: {iban: {value: '', isValid: true, message: ''}},
  47.         cards: [
  48.             {
  49.                 iban: {value: '', isValid: true, message: ''},
  50.                 isAdded: false
  51.             }
  52.         ],
  53.         vehicleTypes: []
  54.     };
  55.  
  56.     componentDidMount() {
  57.         _request(GARAGE + 'garage/vehicleTypes', 'get')
  58.             .then(resp => {
  59.                 this.setState({vehicleTypes: resp.data.map(type => type.type)})
  60.             })
  61.             .catch(() => alert('Garage service unavailable!'))
  62.     }
  63.  
  64.     addVehicle = (uid) => {
  65.         let vehicles = cloneDeep(this.state.vehicles);
  66.         vehicles[uid].isAdded = true;
  67.         vehicles[uid].registration.value = vehicles[uid].registration.value.toUpperCase();
  68.  
  69.         vehicles.push({
  70.             registration: {value: '', isValid: true, message: ''},
  71.             type: {value: 'car', isValid: true, message: ''},
  72.             isAdded: false
  73.         });
  74.  
  75.         this.setState({
  76.             vehicles: vehicles
  77.         })
  78.     };
  79.  
  80.     removeVehicle = uid => {
  81.         let vehicles = cloneDeep(this.state.vehicles);
  82.         vehicles.splice(uid, 1);
  83.         this.setState({
  84.             vehicles: vehicles
  85.         })
  86.     };
  87.  
  88.     handleOnChangeVehicle = event => {
  89.         let vehicles = cloneDeep(this.state.vehicles);
  90.         vehicles[event.target.id] = {
  91.             ...vehicles[event.target.id],
  92.             [event.target.name]: {
  93.                 value: event.target.value,
  94.                 isValid: true,
  95.                 isAdded: false,
  96.                 message: ''
  97.             }
  98.         };
  99.  
  100.         this.setState({
  101.             vehicles: vehicles
  102.         })
  103.     };
  104.  
  105.  
  106.     addCard = uid => {
  107.         let cards = cloneDeep(this.state.cards);
  108.  
  109.         if (!cards[uid].iban.value.match('\\b[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?!(?:[ ]?[0-9]){3})(?:[ ]?[0-9]{1,2})?\\b')) {
  110.             cards[uid].iban.isValid = false;
  111.             cards[uid].iban.message = 'Invalid IBAN format.';
  112.         } else {
  113.             cards[uid].isAdded = true;
  114.             cards.push({
  115.                 iban: {value: '', isValid: true, message: ''},
  116.                 isAdded: false
  117.             });
  118.         }
  119.  
  120.         this.setState({
  121.             cards: cards
  122.         })
  123.     };
  124.  
  125.     removeCard = uid => {
  126.         let cards = cloneDeep(this.state.cards);
  127.         cards.splice(uid, 1);
  128.         this.setState({
  129.             cards: cards
  130.         })
  131.     };
  132.  
  133.     handleOnChangeCard = event => {
  134.         let cards = cloneDeep(this.state.cards);
  135.         cards[event.target.id] = {
  136.             iban:
  137.                 {
  138.                     value: event.target.value,
  139.                     isValid: true,
  140.                     isAdded: false,
  141.                     message: ''
  142.                 }
  143.         };
  144.  
  145.         this.setState({
  146.             cards: cards
  147.         })
  148.     };
  149.  
  150.     handleSubmit = () => {
  151.         if (this.formIsValid()) {
  152.  
  153.             const {name, surname, phone, email, password, vehicles, cards, dateOfBirth, gender} = this.state;
  154.  
  155.             axios.post(
  156.                 AUTHORIZATION + 'user/register/vehicleOwner',
  157.                 {
  158.                     user: {
  159.                         name: name.value,
  160.                         surname: surname.value,
  161.                         email: email.value,
  162.                         password: password.value,
  163.                         phone: phone.value,
  164.                         dateOfBirth: dateOfBirth.value,
  165.                         gender: gender.value
  166.                     },
  167.                     vehicles: vehicles.slice().filter(vehicle => vehicle.registration.value !== '').map(vehicle => {
  168.                         return {
  169.                             registration: vehicle.registration.value,
  170.                             type: vehicle.type.value
  171.                         };
  172.                     }),
  173.                     bankAccounts: cards[0].iban.value !== '' ?
  174.                         cards.slice().filter(card => card.iban.value !== '').map(card => {
  175.                             return {
  176.                                 iban: card.iban.value,
  177.                             }
  178.                         }) : null
  179.                 }, {headers: getHeader()})
  180.                 .then(
  181.                     () => this.props.history.push('/login?mode=vehicle_owner')
  182.                 ).catch(error => {
  183.                     if (error.response.data && error.response.data.exceptions) {
  184.                         Object.keys(error.response.data.exceptions).forEach(key => {
  185.                             if (key === 'iban') {
  186.                                 this.setState({
  187.                                     cards: [
  188.                                         {
  189.                                             iban: {
  190.                                                 value: '',
  191.                                                 isValid: false,
  192.                                                 message: error.response.data.exceptions[key]
  193.                                             },
  194.                                             isAdded: false
  195.                                         }
  196.                                     ]
  197.                                 });
  198.                                 alert("IBAN given is not valid!");
  199.                             } else if (key === 'registration') {
  200.                                 this.setState({
  201.                                     vehicles: [
  202.                                         {
  203.                                             registration: {value: '', isValid: false, message: error.response.data.exceptions[key]},
  204.                                             type: {value: 'car', isValid: true, message: ''},
  205.                                             isAdded: false
  206.                                         }
  207.                                     ]
  208.                                 })
  209.                             } else {
  210.                                 this.setState({
  211.                                     [key]: {
  212.                                         isValid: false,
  213.                                         value: '',
  214.                                         message: error.response.data.exceptions[key]
  215.                                     }
  216.                                 });
  217.                             }
  218.                         })
  219.                     }
  220.                 });
  221.         } else {
  222.             alert("Given data is not valid. Try again!");
  223.         }
  224.  
  225.     };
  226.  
  227.     formIsValid = () => {
  228.         let validationFlag = true;
  229.         let state = cloneDeep(this.state);
  230.  
  231.         if (!validator.isEmail(state.email.value)) {
  232.             state.email.isValid = false;
  233.             state.email.message = 'Not a valid email address.';
  234.             validationFlag = false;
  235.         } else {
  236.             state.email.isValid = true;
  237.             state.email.message = '';
  238.         }
  239.  
  240.         if (!state.name.value.match(/^[A-Za-zčćžđšČĆŽĐŠ\s]+$/)) {
  241.             state.name.isValid = false;
  242.             state.name.message = 'First name should contains only letters.';
  243.             validationFlag = false;
  244.         } else {
  245.             state.name.isValid = true;
  246.             state.name.message = '';
  247.         }
  248.  
  249.         if (!state.surname.value.match(/^[A-Za-zčćžđšČĆŽĐŠ\s]+$/)) {
  250.             state.surname.isValid = false;
  251.             state.surname.message = 'Last name should contains only letters.';
  252.             validationFlag = false;
  253.         } else {
  254.             state.surname.isValid = true;
  255.             state.surname.message = '';
  256.         }
  257.  
  258.         if (state.password.value.length < 8) {
  259.             state.password.isValid = false;
  260.             state.password.message = 'Password is too short. Minimum length is 8 characters.';
  261.             validationFlag = false;
  262.         } else {
  263.             state.password.isValid = true;
  264.             state.password.message = '';
  265.         }
  266.  
  267.         if (state.password.value !== state.repeatedPassword.value) {
  268.             state.repeatedPassword.isValid = false;
  269.             state.repeatedPassword.message = 'Incorrect password. Please repeat password.';
  270.             validationFlag = false;
  271.         } else {
  272.             state.repeatedPassword.isValid = true;
  273.             state.repeatedPassword.message = '';
  274.         }
  275.  
  276.         if (state.vehicles.length === 1 && state.vehicles[0].registration.value === '') {
  277.             state.vehicles[0].registration.message = 'This field is required';
  278.             state.vehicles[0].registration.isValid = false;
  279.             validationFlag = false;
  280.         }
  281.  
  282.         let yearDiff = this.calculateYearDifference();
  283.  
  284.         if (moment().isBefore(moment(this.state.dateOfBirth.value)._i)){
  285.             state.dateOfBirth.isValid = false;
  286.             state.dateOfBirth.message = "Invalid date of birth.";
  287.             validationFlag = false;
  288.         } else if (yearDiff > 150) {
  289.             state.dateOfBirth.isValid = false;
  290.             state.dateOfBirth.message = "You are too old.";
  291.             validationFlag = false;
  292.         } else if (yearDiff < 18) {
  293.             state.dateOfBirth.isValid = false;
  294.             state.dateOfBirth.message = "You have to be at least 18 years old.";
  295.             validationFlag = false;
  296.         } else {
  297.             state.dateOfBirth.isValid = true;
  298.             state.dateOfBirth.message = '';
  299.         }
  300.  
  301.         Object.keys(state).forEach(key => {
  302.             if(key === 'dateOfBirth' || key === 'phone' || key === 'vehicles' || key === 'vehicleTypes' || key === 'activeCard') return;
  303.  
  304.             if(key === 'cards'){
  305.                 state[key].forEach(c => {
  306.                     if (!c.isAdded) {
  307.                         return;
  308.                     }
  309.  
  310.                     if (!c.iban.value.match('\\b[A-Z]{2}[0-9]{2}(?:[ ]?[0-9]{4}){4}(?!(?:[ ]?[0-9]){3})(?:[ ]?[0-9]{1,2})?\\b')) {
  311.                         c.iban.isValid = false;
  312.                         c.iban.message = 'Invalid IBAN format.';
  313.                         validationFlag = false;
  314.                     } else {
  315.                         c.iban.isValid = true;
  316.                         c.iban.message = '';
  317.                     }
  318.                 });
  319.             return;
  320.             }
  321.  
  322.             if (state[key].value === '') {
  323.                 state[key].isValid = false;
  324.                 state[key].message = 'This field is required.';
  325.                 validationFlag = false;
  326.             } else if (state[key].value.length > 128) {
  327.                 state[key].isValid = false;
  328.                 state[key].message = 'Input too long.';
  329.                 state[key].value = '';
  330.                 validationFlag = false;
  331.             } else if (!state[key].isValid) {
  332.                 validationFlag = false;
  333.             }
  334.         });
  335.  
  336.         this.setState(state);
  337.         return validationFlag;
  338.     };
  339.  
  340.     calculateYearDifference(){
  341.         let firstDate = moment(this.state.dateOfBirth.value, 'YYYY-MM-DD');
  342.         let secondDate = moment(moment(), 'YYYY-MM-DD');
  343.         let duration = moment.duration(secondDate.diff(firstDate));
  344.         let years = duration.asYears();
  345.         return years;
  346.     };
  347.  
  348.     handleOnChange = event => {
  349.         let state = cloneDeep(this.state);
  350.         state[event.target.name].value = event.target.value;
  351.         this.setState(state);
  352.     };
  353.  
  354.     handleOnChangePhone = phone => {
  355.         this.setState({
  356.             phone: {
  357.                 value: phone,
  358.                 isValid: true,
  359.                 message: ''
  360.             }
  361.         })
  362.     };
  363.  
  364.     handleCancel = () => this.props.history.push(VEHICLE_LOGIN_ROUTE);
  365.  
  366.     togglePopoverBirthDate = () => {
  367.         this.setState({
  368.             dateOfBirth : {
  369.                 ...this.state.dateOfBirth,
  370.                 message: ''
  371.             }
  372.         });
  373.     };
  374.  
  375.     render() {
  376.         const {name, surname, phone, email, password, repeatedPassword, dateOfBirth, gender} = this.state;
  377.  
  378.         return (
  379.             <div>
  380.                 <NavbarComponent mode={"vehicle_registration"}/>
  381.                 <Container fluid>
  382.                     <div id="user" className="form-container">
  383.                         <div className="form-container-tab">
  384.                             <Col xs="auto" md="auto">
  385.                                 <Row>
  386.                                     Personal info:
  387.                                 </Row>
  388.                             </Col>
  389.                             <Col md={{offset: 2, size: 8}} xs={{offset: 0, size: 12}}>
  390.  
  391.                                 <Row>
  392.                                     <Col md={3}>
  393.                                         <Label for="name">First name:</Label>
  394.                                     </Col>
  395.                                     <Col xs={12} md={9}>
  396.                                         <InputGroup>
  397.                                             <Input
  398.                                                 placeholder={name.message}
  399.                                                 name="name"
  400.                                                 invalid={!name.isValid}
  401.                                                 onChange={this.handleOnChange}
  402.                                                 value={name.value}
  403.                                             />
  404.                                         </InputGroup>
  405.                                     </Col>
  406.                                 </Row>
  407.                                 <Row>
  408.                                     <Col md={3}>
  409.                                         <Label for="surname">Last name:</Label>
  410.                                     </Col>
  411.                                     <Col xs={12} md={9}>
  412.                                         <InputGroup>
  413.                                             <Input
  414.                                                 placeholder={surname.message}
  415.                                                 name="surname"
  416.                                                 invalid={!surname.isValid}
  417.                                                 onChange={this.handleOnChange}
  418.                                                 value={surname.value}
  419.                                             />
  420.                                         </InputGroup>
  421.                                     </Col>
  422.                                 </Row>
  423.                                 <Row>
  424.                                     <Col md={3}>
  425.                                         <Label for="dateOfBirth">Date of birth:</Label>
  426.                                     </Col>
  427.                                     <Col xs={12} md={9}>
  428.                                         <InputGroup id="dateOfBirth">
  429.                                             <Input
  430.                                                    placeholder={dateOfBirth.message}
  431.                                                    name="dateOfBirth"
  432.                                                    invalid={!dateOfBirth.isValid}
  433.                                                    onChange={this.handleOnChange}
  434.                                                    type="date"
  435.                                                    value={dateOfBirth.value}
  436.                                             />
  437.                                         </InputGroup>
  438.                                         <Popover style={{background: "tomato", borderRadius: "0.5vh"}}
  439.                                                  placement="right"
  440.                                                  isOpen={dateOfBirth.message !== ''}
  441.                                                  target="dateOfBirth"
  442.                                                  toggle={this.togglePopoverBirthDate}>
  443.                                             <PopoverBody>{dateOfBirth.message}</PopoverBody>
  444.                                         </Popover>
  445.                                     </Col>
  446.                                 </Row>
  447.                                 <Row>
  448.                                     <Col md={3}>
  449.                                         <Label for="gender">Gender:</Label>
  450.                                     </Col>
  451.                                     <Col xs="auto" md="auto">
  452.                                         <Form inline>
  453.                                             <InputGroup>
  454.                                                 <Input
  455.                                                     checked={gender.value.toLowerCase() === 'male'}
  456.                                                     type="radio"
  457.                                                     name="gender"
  458.                                                     value="male"
  459.                                                     onChange={this.handleOnChange}/>
  460.                                                 <InputGroupAddon addonType="append">
  461.                                                     {' '}male{' '}
  462.                                                 </InputGroupAddon>
  463.                                             </InputGroup>
  464.                                             <InputGroup>
  465.                                                 <Input
  466.                                                     checked={gender.value.toLowerCase() === 'female'}
  467.                                                     type="radio"
  468.                                                     name="gender"
  469.                                                     value="female"
  470.                                                     onChange={this.handleOnChange}/>
  471.                                                 <InputGroupAddon addonType="append">
  472.                                                     {' '}female{' '}
  473.                                                 </InputGroupAddon>
  474.                                             </InputGroup>
  475.                                             <InputGroup>
  476.                                                 <Input
  477.                                                     checked={gender.value.toLowerCase() === 'other'}
  478.                                                     type="radio"
  479.                                                     name="gender"
  480.                                                     value="other"
  481.                                                     onChange={this.handleOnChange}/>
  482.                                                 <InputGroupAddon addonType="append">
  483.                                                     {' '}other{' '}
  484.                                                 </InputGroupAddon>
  485.                                             </InputGroup>
  486.                                         </Form>
  487.                                     </Col>
  488.                                 </Row>
  489.                                 <Row>
  490.                                     <Col md={3}>
  491.                                         <Label for="phone">Phone number:</Label>
  492.                                     </Col>
  493.                                     <Col xs={12} md={9}>
  494.                                         <InputGroup>
  495.                                             <InputGroupAddon addonType="append">
  496.                                                 <ReactPhoneInput
  497.                                                     inputStyle={{
  498.                                                         borderRadius: "0",
  499.                                                         height: "100%",
  500.                                                         width: "100%",
  501.                                                         display: "inline-block",
  502.                                                         position: "relative",
  503.                                                         boxSizing: "border-box"
  504.                                                     }}
  505.                                                     defaultCountry={'hr'}
  506.                                                     name="phone"
  507.                                                     placeholder={phone.message}
  508.                                                     value={phone.value}
  509.                                                     invalid={!phone.isValid}
  510.                                                     onChange={this.handleOnChangePhone}
  511.                                                 />
  512.                                             </InputGroupAddon>
  513.                                         </InputGroup>
  514.                                     </Col>
  515.                                 </Row>
  516.                                 <Row>
  517.                                     <Col md={3}>
  518.                                         <Label>Email address:</Label>
  519.                                     </Col>
  520.                                     <Col xs={12} md={9}>
  521.                                         <InputGroup>
  522.                                             <Input
  523.                                                 placeholder={email.message}
  524.                                                 name="email"
  525.                                                 invalid={!email.isValid}
  526.                                                 onChange={this.handleOnChange}
  527.                                                 type="email"
  528.                                                 value={email.value}
  529.                                             />
  530.                                         </InputGroup>
  531.                                     </Col>
  532.                                 </Row>
  533.                                 <Row>
  534.                                     <Col md={3}>
  535.                                         <Label for="password">Password:</Label>
  536.  
  537.                                     </Col>
  538.                                     <Col xs={12} md={9}>
  539.                                         <InputGroup>
  540.                                             <Input
  541.                                                 placeholder={password.message}
  542.                                                 name="password"
  543.                                                 invalid={!password.isValid}
  544.                                                 onChange={this.handleOnChange}
  545.                                                 type="password"
  546.                                                 value={password.value}
  547.                                             />
  548.                                         </InputGroup>
  549.                                     </Col>
  550.                                 </Row>
  551.                                 <Row>
  552.                                     <Col md={3}>
  553.                                         <Label for="repeatedPassword">Repeated password:</Label>
  554.  
  555.                                     </Col>
  556.                                     <Col xs={12} md={9}>
  557.                                         <InputGroup>
  558.                                             <Input
  559.                                                 placeholder={repeatedPassword.message}
  560.                                                 name="repeatedPassword"
  561.                                                 invalid={!repeatedPassword.isValid}
  562.                                                 onChange={this.handleOnChange}
  563.                                                 type="password"
  564.                                                 value={repeatedPassword.value}
  565.                                             />
  566.                                         </InputGroup>
  567.                                     </Col>
  568.                                 </Row>
  569.                             </Col>
  570.                         </div>
  571.                     </div>
  572.                     <div id="vehicles" className="form-container">
  573.                         <div className="form-container-tab">
  574.                             <Col xs="auto" md="auto">
  575.                                 <Row>
  576.                                     Vehicles:
  577.                                 </Row>
  578.                             </Col>
  579.                             <Col md={{offset: 2, size: 8}} xs={{offset: 0, size: 12}}>
  580.                                 <VehicleFormList
  581.                                     vehicles={this.state.vehicles}
  582.                                     vehicleTypes={this.state.vehicleTypes}
  583.                                     addVehicle={this.addVehicle}
  584.                                     removeVehicle={this.removeVehicle}
  585.                                     handleOnChangeVehicle={this.handleOnChangeVehicle}
  586.                                 />
  587.                             </Col>
  588.                         </div>
  589.                     </div>
  590.                     <div id="user" className="form-container">
  591.                         <div className="form-container-tab">
  592.                             <Col xs="auto" md="auto">
  593.                                 <Row>
  594.                                     Accounts:
  595.                                 </Row>
  596.                             </Col>
  597.                             <Col md={{offset: 2, size: 8}} xs={{offset: 0, size: 12}}>
  598.                                 <CardFormList
  599.                                     register={true}
  600.                                     cards={this.state.cards}
  601.                                     addCard={this.addCard}
  602.                                     removeCard={this.removeCard}
  603.                                     handleOnChangeCard={this.handleOnChangeCard}
  604.                                 />
  605.                             </Col>
  606.                         </div>
  607.                     </div>
  608.                 </Container>
  609.                 <div className="button-group">
  610.                     <Button size="lg" onClick={this.handleCancel}>Cancel</Button>
  611.                     <Button size="lg" onClick={this.handleSubmit}>Submit</Button>
  612.                 </div>
  613.             </div>
  614.         );
  615.     }
  616.     ;
  617.  
  618. }
  619.  
  620. export default VehicleOwnerForm;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement