Calculate gender and date of birth from the Italian tax code ReactJS

const months = [
  { code: 'A', month: '01' },
  { code: 'B', month: '02' },
  { code: 'C', month: '03' },
  { code: 'D', month: '04' },
  { code: 'E', month: '05' },
  { code: 'H', month: '06' },
  { code: 'L', month: '07' },
  { code: 'M', month: '08' },
  { code: 'P', month: '09' },
  { code: 'R', month: '10' },
  { code: 'S', month: '11' },
  { code: 'T', month: '12' }
]
  inverseFiscalCodeCalculate = event => {
    var fiscalCode = event.target.value
    const { t } = this.props

    if (strongRegexFiscalCode.test(fiscalCode)) {

      var getNumberGender = fiscalCode.substring(9, 11)
      var getNumberDayDate = getNumberGender > 40 ? Math.abs(getNumberGender - 40) : getNumberGender
      var getNumberMonthDate = fiscalCode.substring(8, 9)
      var getNumberYearDate = fiscalCode.substring(6, 8)
      var filterMonth = months.filter(item => item.code.includes(getNumberMonthDate));

      var yearCheck = parseInt(getNumberYearDate) + 1900
      var dateCheck = new Date();
      var yearBorn = 0
      dateCheck.setFullYear(dateCheck.getFullYear() - 85);

      if (yearCheck < dateCheck.getFullYear())
        yearBorn = parseInt(getNumberYearDate)  + 2000
      else yearBorn = yearCheck

      this.setState({
        isFiscalCodeCorrect: true,
        infoUser: fcUtility.getFiscalCodeInfo(fiscalCode),
        gender: getNumberGender < 32 ? 'M' : 'F',
        bornDate: yearBorn + '-' + filterMonth[0].month + '-' + getNumberDayDate
      });

    }
    else {
      this.setState({
        isFiscalCodeCorrect: false,
      });
    }
  }
  <AvField
              type="text"
              name="fiscalCode"
              id="fiscalCode"
              label={"fiscalCode"}
              defaultValue={fiscalCode}
              onChange={this.inverseFiscalCodeCalculate}
              validate={{
                required: { value: true, errorMessage: 'Campo obbligatorio' },
                pattern: {
                  value: '^([A-Za-z]{6}[0-9lmnpqrstuvLMNPQRSTUV]{2}[abcdehlmprstABCDEHLMPRST]{1}[0-9lmnpqrstuvLMNPQRSTUV]{2}[A-Za-z]{1}[0-9lmnpqrstuvLMNPQRSTUV]{3}[A-Za-z]{1})$|^([0-9]{11})$',
                  errorMessage: t("Message.fiscalCodeError")
                },
                maxLength: { value: 16, errorMessage: 'Il codice fiscale deve essere 16 caratteri' }
              }}
            />

React-Leaflet and Google Map Layer with controls draw

React component built on top of React-Leaflet and Google Map Layer with controls for drawing figures and markers

npm install react-leaflet-draw
npm install leaflet
npm install react-leaflet
npm install react-leaflet-google-layer
npm install lodash-es
<head>
...

   <!-- MAP -->
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css" />
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css" />
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.3/leaflet.draw.css" />

...
</head>
.leaflet-container {
  width: 100%;
  height: 50vh;
}
import { PropTypes } from 'prop-types';
import isEqual from 'lodash-es/isEqual';

import { MapControl, withLeaflet } from 'react-leaflet';
import leaflet, { Map, Control } from 'leaflet';

const eventHandlers = {
  onEdited: 'draw:edited',
  onDrawStart: 'draw:drawstart',
  onDrawStop: 'draw:drawstop',
  onDrawVertex: 'draw:drawvertex',
  onEditStart: 'draw:editstart',
  onEditMove: 'draw:editmove',
  onEditResize: 'draw:editresize',
  onEditVertex: 'draw:editvertex',
  onEditStop: 'draw:editstop',
  onDeleted: 'draw:deleted',
  onDeleteStart: 'draw:deletestart',
  onDeleteStop: 'draw:deletestop',
};

class EditControl extends MapControl {
  static propTypes = {
    ...Object.keys(eventHandlers).reduce((acc, val) => {
      acc[val] = PropTypes.func;
      return acc;
    }, {}),
    onCreated: PropTypes.func,
    onMounted: PropTypes.func,
    draw: PropTypes.shape({
      polyline: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      polygon: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      rectangle: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      circle: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      marker: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
    }),
    edit: PropTypes.shape({
      edit: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      remove: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      poly: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
      allowIntersection: PropTypes.bool,
    }),
    position: PropTypes.oneOf([
      'topright',
      'topleft',
      'bottomright',
      'bottomleft'
    ]),
    leaflet: PropTypes.shape({
      map: PropTypes.instanceOf(Map),
      layerContainer: PropTypes.shape({
        addLayer: PropTypes.func.isRequired,
        removeLayer: PropTypes.func.isRequired
      })
    })
  };

  createLeafletElement(props) {
    return createDrawElement(props);
  }

  onDrawCreate = (e) => {
    const { onCreated } = this.props;
    const { layerContainer } = this.props.leaflet;

    layerContainer.addLayer(e.layer);
    onCreated && onCreated(e);
  };

  componentDidMount() {
    super.componentDidMount();
    const { map } = this.props.leaflet;
    const { onMounted } = this.props;

    for (const key in eventHandlers) {
      if (this.props[key]) {
        map.on(eventHandlers[key], this.props[key]);
      }
    }

    map.on(leaflet.Draw.Event.CREATED, this.onDrawCreate);

    onMounted && onMounted(this.leafletElement);
  }

  componentWillUnmount() {
    super.componentWillUnmount();
    const { map } = this.props.leaflet;

    map.off(leaflet.Draw.Event.CREATED, this.onDrawCreate);

    for (const key in eventHandlers) {
      if (this.props[key]) {
        map.off(eventHandlers[key], this.props[key]);
      }
    }
  }

  componentDidUpdate(prevProps) {
    // super updates positions if thats all that changed so call this first
    super.componentDidUpdate(prevProps);

    if (isEqual(this.props.draw, prevProps.draw) || this.props.position !== prevProps.position) {
      return false;
    }

    const { map } = this.props.leaflet;

    this.leafletElement.remove(map);
    this.leafletElement = createDrawElement(this.props);
    this.leafletElement.addTo(map);

    return null;
  }
}

function createDrawElement(props) {
  const { layerContainer } = props.leaflet;
  const { draw, edit, position } = props;
  const options = {
    edit: {
      ...edit,
      featureGroup: layerContainer
    }
  };

  if (draw) {
    options.draw = { ...draw };
  }

  if (position) {
    options.position = position;
  }

  return new Control.Draw(options);
}

export default withLeaflet(EditControl);
import React, { Component } from 'react';
import { Map, TileLayer, Circle, FeatureGroup, Marker, Popup, LayersControl } from 'react-leaflet';
import "./map.css";
import L from 'leaflet';
import EditControl from './EditControl';
import ReactLeafletGoogleLayer from "react-leaflet-google-layer";

// work around broken icons when using webpack, see https://github.com/PaulLeCam/react-leaflet/issues/255

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-icon.png',
  iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-icon.png',
  shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-shadow.png',
});

export default class LeafletMap extends Component {

  // see http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-event for leaflet-draw events doc

  _onEdited = (e) => {

    let numEdited = 0;
    e.layers.eachLayer((layer) => {
      numEdited += 1;
    });
    console.log(`_onEdited: edited ${numEdited} layers`, e);

    this._onChange();
  }

  _onCreated = (eobjCreated) => {
    let type = eobjCreated.layerType;
    let layer = eobjCreated.layer;
    if (type === 'marker') {
      // Do marker specific actions
      console.log("_onCreated: marker created", eobjCreated);
    }
    else {
      console.log("_onCreated: something else created:", type, eobjCreated);
    }

    this._onChange();
  }

  _onDeleted = (e) => {

    let numDeleted = 0;
    e.layers.eachLayer((layer) => {
      numDeleted += 1;
    });
    console.log(`onDeleted: removed ${numDeleted} layers`, e);

    this._onChange();
  }

  _onMounted = (drawControl) => {
    console.log('_onMounted', drawControl);
  }

  _onEditStart = (e) => {
    console.log('_onEditStart', e);
  }

  _onEditStop = (e) => {
    console.log('_onEditStop', e);
  }

  _onDeleteStart = (e) => {
    console.log('_onDeleteStart', e);
  }

  _onDeleteStop = (e) => {
    console.log('_onDeleteStop', e);
  }

  render() {
    return (
      <>
        <Map
          center={[38.132060, 13.331277]}
          zoom={12}
        >

          <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
          />

          {/* watercolor Style 
          <TileLayer
            url="http://a.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"
            
            attribution='&copy; <a id="home-link" target="_top" href="../">Map tiles</a> by <a target="_top" href="http://stamen.com">Stamen Design</a>, under <a target="_top" href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a target="_top" href="http://openstreetmap.org">OpenStreetMap</a>, under <a target="_top" href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>'
          /> */}

          {/* 
        GIS Style
         <TileLayer
              url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png"
              attribution='&copy; <a href="Esri &mdash">Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community</a> contributors'
            />
        
        */}




          <FeatureGroup ref={(reactFGref) => { this._onFeatureGroupReady(reactFGref); }}>

            <EditControl

              position='topright'
              onEdited={this._onEdited}
              onCreated={this._onCreated}
              onDeleted={this._onDeleted}
              onMounted={this._onMounted}
              onEditStart={this._onEditStart}
              onEditStop={this._onEditStop}
              onDeleteStart={this._onDeleteStart}
              onDeleteStop={this._onDeleteStop}
              edit={{
                remove: true,
                edit: true
              }}
              draw={{
                rectangle: true,
                polyline: true,
                polygon: true,
                circle: true,
                marker: true,

                polygon: {
                  allowIntersection: false,
                  shapeOptions: { color: "red" },
                  edit: false,
                  showLength: true,
                  metric: false,
                  feet: false,
                  showArea: true
                },

                circle: {
                  shapeOptions: { color: "blue" },
                  showLength: true,
                  metric: false,
                  feet: false,
                  showArea: true
                },

              }}
            />

          </FeatureGroup>

          <ReactLeafletGoogleLayer
            googleMapsLoaderConf={{ KEY: "YOUR_TOKEN_GOOGLE_MAP" }}
            type={"satellite"}
          />
        </Map>
      </>
    );
  }

  _editableFG = null

  _onFeatureGroupReady = (reactFGref) => {

    // populate the leaflet FeatureGroup with the geoJson layers

    let leafletGeoJSON = new L.GeoJSON(getGeoJson());
    let leafletFG = reactFGref.leafletElement;

    leafletGeoJSON.eachLayer((layer) => {
      leafletFG.addLayer(layer);
    });

    // store the ref for future access to content

    this._editableFG = reactFGref;
  }

  _onChange = () => {

    // this._editableFG contains the edited geometry, which can be manipulated through the leaflet API

    const { onChange } = this.props;

    if (!this._editableFG || !onChange) {
      return;
    }

    const geojsonData = this._editableFG.leafletElement.toGeoJSON();
    onChange(geojsonData);
  }
}

// data taken from the example in https://github.com/PaulLeCam/react-leaflet/issues/176

function getGeoJson() {
  return {
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [
              13.25441561846926,
              38.162839676288336
            ],
            [
              13.269521819641135,
              38.150961340209484
            ],
            [
              13.250982390930197,
              38.150961340209484
            ],
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                13.250982390930197,
                38.150961340209484
              ],
              [
                13.269521819641135,
                38.150961340209484
              ],
              [
                13.25441561846926,
                38.162839676288336
              ],
              [
                13.24342929034426,
                38.150691355539586
              ]
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                13.277074920227072,
                38.18335224460118

              ],
              [
                13.30660067706301,
                38.18389197106355

              ],
              [
                13.278104888488791,
                38.165808957979515

              ]
            ]
          ]
        }
      },
      {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                13.309476005126974,
                38.13233005362,
              ],
              [

                13.337628470947287,
                38.135030534863766
              ],
              [
                13.31805907397463,
                38.11153300139878
              ]
            ]
          ]
        }
      }
    ]
  }
}

Menu item icon without children in Dandelion Pro – React

In the Dandelion Pro React theme, they designed the sidebar to contain the menu items with icon only if the menu item has children. Therefore it is necessary to make a change to display the menu item without children with icon

<pre>
// app/api/ui/menu.js
// add parent menu with linkParent property

{
    key: 'home2',
    name: 'Home',
    icon: 'ios-home-outline',
    linkParent: '/home2',
  },
</pre>
// app/components/Sidebar/MainMenu.js
// make menu type condition in getMenus constant
if (item.child || item.linkParent) {
        return (
          <div key={index.toString()}>
            <ListItem
              component={LinkBtn}
              to={item.linkParent ? item.linkParent : '#'}
              button
              className={
                classNames(
                  classes.head,
                  item.icon ? classes.iconed : '',
                  open.indexOf(item.key) > -1 ? classes.opened : '',
                )
              }
              onClick={() => openSubMenu(item.key, item.keyParent)}
            >
              {item.icon && (
                <ListItemIcon className={classes.icon}>
                  <Ionicon icon={item.icon} />
                </ListItemIcon>
              )}
              <ListItemText classes={{ primary: classes.primary }} variant="inset" primary={item.name} />
              { !item.linkParent && (
                <span>
                  { open.indexOf(item.key) > -1 ? <ExpandLess /> : <ExpandMore /> }
                </span>
              )}
            </ListItem>
            { !item.linkParent && (
              <Collapse
                component="div"
                className={classNames(
                  classes.nolist,
                  (item.keyParent ? classes.child : ''),
                )}
                in={open.indexOf(item.key) > -1}
                timeout="auto"
                unmountOnExit
              >
                <List className={classes.dense} component="nav" dense>
                  { getMenus(item.child, 'key') }
                </List>
              </Collapse>
            )}
          </div>
        );
      }
<br />

REACT: Add item into array if it does not exist otherwise delete it

Add item into array if it does not exist otherwise delete it

import React from 'react';

class PushOrSpliceArray extends React.Component {

state = {array: []}

  addItemArray = (item) => {

    var newArray = [...this.state.array]
    var indexItem = newArray.indexOf(item)
    indexItem === -1 ? newArray.push(item) : newArray.splice(item, 1);
    this.setState({ array: newArray });

  }
}