Completed
Pull Request — master (#268)
by Alejandro
16:58
created

src/common/MenuLayout.js   A

Complexity

Total Complexity 2
Complexity/F 0

Size

Lines of Code 99
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 14.29%

Importance

Changes 0
Metric Value
wmc 2
eloc 86
mnd 2
bc 2
fnc 0
dl 0
loc 99
ccs 3
cts 21
cp 0.1429
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import React, { useEffect } from 'react';
2
import { Route, Switch } from 'react-router-dom';
3
import { Swipeable } from 'react-swipeable';
4
import { faBars as burgerIcon } from '@fortawesome/free-solid-svg-icons';
5
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
import classNames from 'classnames';
7
import * as PropTypes from 'prop-types';
8
import { serverType } from '../servers/prop-types';
9
import { withSelectedServer } from '../servers/helpers/withSelectedServer';
10
import { useToggle } from '../utils/helpers/hooks';
11
import { versionMatch } from '../utils/helpers/version';
12
import NotFound from './NotFound';
13
import './MenuLayout.scss';
14
15
const propTypes = {
16
  match: PropTypes.object,
17
  location: PropTypes.object,
18
  selectedServer: serverType,
19
};
20
21
const MenuLayout = (
22
  TagsList,
23
  ShortUrls,
24
  AsideMenu,
25
  CreateShortUrl,
26
  ShortUrlVisits,
27
  TagVisits,
28
  ShlinkVersions,
29
  ServerError
30
) => {
31
  const MenuLayoutComp = ({ match, location, selectedServer }) => {
32
    const [ sidebarVisible, toggleSidebar, showSidebar, hideSidebar ] = useToggle();
33
    const { params: { serverId } } = match;
34
35
    useEffect(() => hideSidebar(), [ location ]);
36
37 2
    if (selectedServer.serverNotReachable) {
38
      return <ServerError type="not-reachable" />;
39
    }
40
41
    const addTagsVisitsRoute = versionMatch(selectedServer.version, { minVersion: '2.2.0' });
42
    const burgerClasses = classNames('menu-layout__burger-icon', {
43
      'menu-layout__burger-icon--active': sidebarVisible,
44
    });
45
    const swipeMenuIfNoModalExists = (callback) => (e) => {
46
      const swippedOnVisitsTable = e.event.path.some(
47 2
        ({ classList }) => classList && classList.contains('visits-table')
48
      );
49
50 4
      if (swippedOnVisitsTable || document.querySelector('.modal')) {
51
        return;
52
      }
53
54
      callback();
55
    };
56
57
    return (
58
      <React.Fragment>
59
        <FontAwesomeIcon icon={burgerIcon} className={burgerClasses} onClick={toggleSidebar} />
60
61
        <Swipeable
62
          delta={40}
63
          className="menu-layout__swipeable"
64
          onSwipedLeft={swipeMenuIfNoModalExists(hideSidebar)}
65
          onSwipedRight={swipeMenuIfNoModalExists(showSidebar)}
66
        >
67
          <div className="row menu-layout__swipeable-inner">
68
            <AsideMenu className="col-lg-2 col-md-3" selectedServer={selectedServer} showOnMobile={sidebarVisible} />
69
            <div className="col-lg-10 offset-lg-2 col-md-9 offset-md-3" onClick={() => hideSidebar()}>
70
              <div className="menu-layout__container">
71
                <Switch>
72
                  <Route exact path="/server/:serverId/list-short-urls/:page" component={ShortUrls} />
73
                  <Route exact path="/server/:serverId/create-short-url" component={CreateShortUrl} />
74
                  <Route exact path="/server/:serverId/short-code/:shortCode/visits" component={ShortUrlVisits} />
75
                  {addTagsVisitsRoute && <Route exact path="/server/:serverId/tag/:tag/visits" component={TagVisits} />}
76
                  <Route exact path="/server/:serverId/manage-tags" component={TagsList} />
77
                  <Route
78
                    render={() => <NotFound to={`/server/${serverId}/list-short-urls/1`}>List short URLs</NotFound>}
79
                  />
80
                </Switch>
81
              </div>
82
83
              <div className="menu-layout__footer text-center text-md-right">
84
                <ShlinkVersions />
85
              </div>
86
            </div>
87
          </div>
88
        </Swipeable>
89
      </React.Fragment>
90
    );
91
  };
92
93
  MenuLayoutComp.propTypes = propTypes;
94
95
  return withSelectedServer(MenuLayoutComp, ServerError);
96
};
97
98
export default MenuLayout;
99