Passed
Push — master ( 3278dc...27a5bd )
by Kevin Van
03:53 queued 11s
created

MatchTeaser.tsx ➔ getData   C

Complexity

Conditions 10

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
rs 5.9999
c 0
b 0
f 0
cc 10

How to fix   Complexity   

Complexity

Complex classes like MatchTeaser.tsx ➔ getData often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import React, { FunctionComponent, useState, useEffect, Fragment } from "react"
2
import { graphql, useStaticQuery } from "gatsby"
3
4
import axios from "axios"
5
import LazyLoad from "react-lazyload"
6
import classNames from "classnames"
7
import Moment from "moment-timezone"
8
import "moment/locale/nl-be"
9
10
import { mapPsdStatus } from "../scripts/helper"
11
12
import "./MatchTeaser.scss"
13
import MiniRanking from "./MiniRanking"
14
15
export const MatchTeaserDetail: FunctionComponent<MatchTeaserDetailProps> = ({
16
  match,
17
  includeRankings = false,
18
}: MatchTeaserDetailProps) => {
19
  Moment.locale(`nl-BE`)
20
  const d = Moment.tz(match.date, `Europe/Brussels`)
21
  const matchPlayed =
22
    ((match.status === 0 || match.status === null) && match.goalsHomeTeam !== null && match.goalsAwayTeam !== null) ||
23
    false
24
25
  return (
26
    <article className="match__teaser">
27
      <header>
28
        <h3>{match.teamName.replace(`Voetbal : `, ``)}</h3>
29
        <div>
30
          {match.status !== 0 && (
31
            <Fragment>
32
              <time
33
                className="match__teaser__datetime match__teaser__datetime--date"
34
                dateTime={d.format(`YYYY-MM-DD - H:mm`)}
35
              >
36
                {d.format(`dddd DD MMMM - H:mm`)}
37
              </time>
38
              <span className="match__teaser__datetime match__teaser__datetime--status">
39
                {mapPsdStatus(match.status)}
40
              </span>
41
            </Fragment>
42
          )}
43
          {(match.status === 0 || match.status === null) && (
44
            <Fragment>
45
              <time className="match__teaser__datetime match__teaser__datetime--date" dateTime={d.format(`YYYY-MM-DD`)}>
46
                {d.format(`dddd DD MMMM`)}
47
              </time>
48
              <time className="match__teaser__datetime match__teaser__datetime--time" dateTime={d.format(`H:mm`)}>
49
                {d.format(`H:mm`)}
50
              </time>
51
            </Fragment>
52
          )}
53
        </div>
54
      </header>
55
      <main>
56
        <div
57
          className={classNames(`match__teaser__team`, `match__teaser__team--home`, {
58
            "match__teaser__team--winner": matchPlayed && match.goalsHomeTeam > match.goalsAwayTeam,
59
          })}
60
        >
61
          <LazyLoad debounce={false}>
62
            <img
63
              src={match.homeClub?.logo}
64
              alt={match.homeClub?.name}
65
              className="match__teaser__logo match__teaser__logo--home"
66
            />
67
          </LazyLoad>
68
          {match.homeClub?.name}
69
        </div>
70
71
        {matchPlayed || <span className="match__teaser__vs">vs</span>}
72
        {matchPlayed && (
73
          <span className="match__teaser__vs match__teaser__vs--score">
74
            {match.goalsHomeTeam} - {match.goalsAwayTeam}
75
          </span>
76
        )}
77
78
        <div
79
          className={classNames(`match__teaser__team`, `match__teaser__team--away`, {
80
            "match__teaser__team--winner": matchPlayed && match.goalsHomeTeam < match.goalsAwayTeam,
81
          })}
82
        >
83
          <LazyLoad debounce={false}>
84
            <img
85
              src={match.awayClub?.logo}
86
              alt={match.awayClub?.name}
87
              className="match__teaser__logo match__teaser__logo--away"
88
            />
89
          </LazyLoad>
90
          {match.awayClub?.name}
91
        </div>
92
      </main>
93
      {includeRankings && (
94
        <MiniRanking
95
          teamId={match.homeTeamId || match.awayTeamId}
96
          homeTeam={match.homeClub?.name}
97
          awayTeam={match.awayClub?.name}
98
        />
99
      )}
100
    </article>
101
  )
102
}
103
104
export const MatchTeaser: FunctionComponent<MatchTeaserProps> = ({
105
  teamId,
106
  action,
107
  includeRankings = false,
108
}: MatchTeaserProps) => {
109
  if (action !== `prev` && action !== `next`) {
110
    throw new Error(`Invalid action provided`)
111
  }
112
113
  const [data, setData] = useState<Match[]>([])
114
115
  const {
116
    site: {
117
      siteMetadata: { kcvvPsdApi },
118
    },
119
  }: MatchesQueryData = useStaticQuery(graphql`
120
    {
121
      site {
122
        siteMetadata {
123
          kcvvPsdApi
124
        }
125
      }
126
    }
127
  `)
128
129
  useEffect(() => {
130
    async function getData() {
131
      const response = await axios.get(`${kcvvPsdApi}/matches/${action}`, {
132
        params: { include: teamId },
133
      })
134
      setData(response.data)
135
    }
136
    getData()
137
  }, [])
138
139
  if (data.length > 0) {
140
    return <MatchTeaserDetail match={data[0]} includeRankings={includeRankings} />
141
  } else {
142
    return <div className="match__teaser__no_match">Geen wedstrijd gevonden</div>
143
  }
144
}
145
146
export const MatchTeasers: FunctionComponent<MatchTeasersProps> = ({
147
  teamId,
148
  includeRankings = false,
149
}: MatchTeasersProps) => (
150
  <div className="match__teasers">
151
    <MatchTeaser teamId={teamId} action="prev" includeRankings={includeRankings} />
152
    <MatchTeaser teamId={teamId} action="next" includeRankings={includeRankings} />
153
  </div>
154
)
155