Passed
Push — feature/match-teasers ( 1ddcdb )
by Kevin Van
06:03
created

MatchTeaser.tsx ➔ getData   D

Complexity

Conditions 12

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
rs 4.8
c 0
b 0
f 0
cc 12

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