Passed
Push — feature/game-reports ( f5935e...eef989 )
by Kevin Van
04:16
created

GamePage.renderEventLine   B

Complexity

Conditions 5

Size

Total Lines 81
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 66
dl 0
loc 81
rs 7.646
c 0
b 0
f 0
cc 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import React, { Component } from "react"
2
import LazyLoad from "react-lazy-load"
3
4
import { graphql } from "gatsby"
5
6
import moment from "moment"
7
import "moment/locale/nl-be"
8
9
import { mapPsdStatus } from "../scripts/helper"
10
11
import Layout from "../layouts/index"
12
import SEO from "../components/seo"
13
import Icon from "../components/icon"
14
15
import iconBench from "../images/i_bench_2.png"
16
import iconCardRed from "../images/i_card_red.png"
17
import iconCardYellowRed from "../images/i_card_yellow_red.png"
18
import iconCardYellow from "../images/i_card_yellow.png"
19
import iconGoal from "../images/i_goal.png"
20
import iconStart from "../images/i_start.png"
21
import iconSubIn from "../images/i_sub_in.png"
22
import iconSubOut from "../images/i_sub_out.png"
23
24
class GamePage extends Component {
25
  constructor(props) {
26
    super(props)
27
28
    this.state = {
29
      data: [],
30
      loading: true,
31
    }
32
33
    const {
34
      data: {
35
        site: {
36
          siteMetadata: { kcvvPsdApi },
37
        },
38
      },
39
    } = this.props
40
41
    this.kcvvPsdApi = kcvvPsdApi
42
    this.matchId = this.props.id || null
43
  }
44
45
  updateData() {
46
    if (this.matchId === null) {
47
      return
48
    }
49
50
    const apiUrl = `${this.kcvvPsdApi}/match/${this.matchId}`
51
52
    fetch(apiUrl)
53
      .then((response) => response.json())
54
      .then((json) => this.setState({ data: json, loading: false }))
55
  }
56
57
  componentDidMount() {
58
    this.updateData()
59
  }
60
61
  render() {
62
    if (this.matchId === null) {
63
      return (
64
        <Layout>
65
          <section className="grid-container site-content">
66
            Geen match beschikbaar...
67
          </section>
68
        </Layout>
69
      )
70
    }
71
72
    moment.locale("nl-be")
73
74
    if (this.state.loading === false && this.state.data) {
75
      const {
76
        general = {},
77
        substitutes = {},
78
        lineup = {},
79
        events = [],
80
      } = this.state.data
81
      const homeTeamId = general.homeClub.id
82
      const ogImage = {
83
        src: general?.homeClub.logo,
84
        width: 180,
85
        height: 180,
86
      }
87
88
      const { home: homeLineup = [], away: awayLineup = [] } = lineup || {}
89
      const { home: homeSubs = [], away: awaySubs = [] } = substitutes || {}
90
91
      const matchTime = moment(general.date)
92
93
      return (
94
        <Layout>
95
          <SEO
96
            lang="nl-BE"
97
            title={`Matchverslag ${general?.homeClub?.name} - ${general?.awayClub?.name}`}
98
            description={`Matchverslag ${general?.homeClub?.name} - ${general?.awayClub?.name}`}
99
            path={`/game/${general?.id}`}
100
            image={ogImage}
101
          />
102
103
          <section className="grid-container game-stats">
104
            <div className="grid-x grid-margin-x">
105
              <div className={"cell large-12 center game__details"}>
106
                <div className="game__teams">
107
                  <div className={"game__teams-inner"}>
108
                    <LazyLoad debounce={false}>
109
                      <img
110
                        src={general.homeClub.logo}
111
                        alt={general.homeClub.name}
112
                      />
113
                    </LazyLoad>
114
                  </div>
115
                  {this.renderScore(
116
                    general.goalsHomeTeam,
117
                    general.goalsAwayTeam
118
                  )}
119
                  <div className={"game__teams-inner"}>
120
                    <LazyLoad debounce={false}>
121
                      <img
122
                        src={general.awayClub.logo}
123
                        alt={general.awayClub.name}
124
                      />
125
                    </LazyLoad>
126
                  </div>
127
                </div>
128
                <h1>{`${general.homeClub.name} - ${general.awayClub.name}`}</h1>
129
                <h4>{general.competitionType}</h4>
130
                <time dateTime={matchTime.format("YYYY-MM-DD - H:mm")}>
131
                  {matchTime.format("dddd DD MMMM YYYY - H:mm")}
132
                </time>
133
                <br />
134
                {general.status !== 0 && mapPsdStatus(general.status)}
135
                <br />
136
              </div>
137
138
              {(homeLineup.length !== 0 || awayLineup.length !== 0) && (
139
                <div
140
                  className={
141
                    "lineup__wrapper grid-x grid-margin-x cell large-12"
142
                  }
143
                >
144
                  <div className={"cell large-6 lineup__wrapper--home"}>
145
                    <h3>{general.homeClub.name}</h3>
146
                    {homeLineup && this.renderLineup(homeLineup, homeSubs)}
147
                  </div>
148
                  <div className={"cell large-6 lineup__wrapper--away"}>
149
                    <h3>{general.awayClub.name}</h3>
150
                    {awayLineup && this.renderLineup(awayLineup, awaySubs)}
151
                  </div>
152
                </div>
153
              )}
154
155
              {events.length !== 0 && (
156
                <div className={"cell large-12 event__wrapper"}>
157
                  <h3>Gebeurtenissen</h3>
158
                  {events && this.renderEvents(events, homeTeamId)}
159
                </div>
160
              )}
161
            </div>
162
          </section>
163
        </Layout>
164
      )
165
    } else {
166
      return (
167
        <Layout>
168
          <section className="grid-container site-content">
169
            Matchverslag inladen...
170
          </section>
171
        </Layout>
172
      )
173
    }
174
  }
175
176
  renderScore = (resultHome, resultAway) => {
177
    return resultHome !== null && resultAway !== null ? (
178
      <div className={"match-details__vs match-details__vs--score"}>
179
        {this.renderScoreWithWinnerIndicator(resultHome, resultAway, "home")}
180
        <span className={"match-details__divider"}> - </span>
181
        {this.renderScoreWithWinnerIndicator(resultAway, resultHome, "away")}
182
      </div>
183
    ) : (
184
      <div className={"match-details__vs"}>VS</div>
185
    )
186
  }
187
188
  renderScoreWithWinnerIndicator = (result1, result2, extraClass) => {
189
    return result1 > result2 ? (
190
      <span
191
        className={`match-details__winner match-details__winner--${extraClass}`}
192
      >
193
        {result1}
194
      </span>
195
    ) : (
196
      <span className={"match-details__loser"}>{result1}</span>
197
    )
198
  }
199
200
  renderEvents(events, homeTeamId) {
201
    return (
202
      <>
203
        {events.map((element, i) =>
204
          this.renderEventLine(i, element, homeTeamId)
205
        )}
206
      </>
207
    )
208
  }
209
210
  renderEventLine(i, element, homeTeamId) {
211
    const homeTeam = element.clubId == homeTeamId
212
    let actionIcon = null
213
    let actionMessage = ""
214
    let actionText = ""
215
216
    switch (element.action) {
217
      case "geel":
218
        actionIcon = iconCardYellow
219
        actionText = "Gele kaart voor"
220
        actionMessage = "Gele kaart"
221
        break
222
      case "rood":
223
        actionIcon = iconCardRed
224
        actionText = "Rode kaart voor"
225
        actionMessage = "Rode kaart"
226
        break
227
      case "tweedegeel":
228
        actionIcon = iconCardYellowRed
229
        actionText = "Tweede gele kaart voor"
230
        actionMessage = "Tweede gele kaart"
231
        break
232
      case "doelpunt":
233
        actionIcon = iconGoal
234
        actionText = `${element?.goalsHome} - ${element?.goalsAway} — Doelpunt gescoord door`
235
        actionMessage = "Doelpunt"
236
        break
237
    }
238
239
    return (
240
      <div
241
        className={`event__row ${
242
          homeTeam ? "event__row--home" : "event__row--away"
243
        } grid-x grid-margin-x`}
244
        key={i}
245
      >
246
        {homeTeam && (
247
          <span
248
            className={
249
              "event__row__item event__row__item--home lineup__item--name cell small-10 large-4"
250
            }
251
          >
252
            {actionText} {element.playerName}
253
          </span>
254
        )}
255
        {homeTeam && (
256
          <span
257
            className={
258
              "event__row__item event__row__item--home lineup__item--action cell small-1 center"
259
            }
260
            style={{ backgroundImage: `url(${actionIcon})` }}
261
            title={actionMessage}
262
          ></span>
263
        )}
264
        <span
265
          className={
266
            "event__row__item lineup__item--time cell small-1 large-2 center"
267
          }
268
        >
269
          {element.minute}'
270
        </span>
271
        {homeTeam || (
272
          <span
273
            className={
274
              "event__row__item event__row__item--away lineup__item--action cell small-1 center"
275
            }
276
            style={{ backgroundImage: `url(${actionIcon})` }}
277
            title={actionMessage}
278
          ></span>
279
        )}
280
        {homeTeam || (
281
          <span
282
            className={
283
              "event__row__item event__row__item--away lineup__item--name cell small-10 large-4"
284
            }
285
          >
286
            {actionText} {element.playerName}
287
          </span>
288
        )}
289
      </div>
290
    )
291
  }
292
  renderLineup(lineup, substitutes) {
293
    return (
294
      <>
295
        {this.renderLineupHeader()}
296
        {lineup.map((element, i) => this.renderLineupLine(i, element))}
297
        <hr />
298
        {substitutes.map((element, i) => this.renderSubLine(i, element))}
299
      </>
300
    )
301
  }
302
303
  renderLineupHeader() {
304
    return (
305
      <div className={"lineup__header grid-x grid-margin-x"}>
306
        <span
307
          className={"lineup__header__item lineup__item--status cell small-1"}
308
        ></span>
309
        <span
310
          className={"lineup__header__item lineup__item--number cell small-1"}
311
        >
312
          #
313
        </span>
314
        <span
315
          className={"lineup__header__item lineup__item--name cell small-9"}
316
        >
317
          Name
318
        </span>
319
        <span
320
          className={"lineup__header__item lineup__item--time cell small-1"}
321
        >
322
          <Icon icon="fa-clock-o" />
323
        </span>
324
      </div>
325
    )
326
  }
327
328
  renderSubLine(i, element) {
329
    return (
330
      <div
331
        className={"lineup__row lineup__row--substitute grid-x grid-margin-x"}
332
        key={i}
333
      >
334
        <span
335
          className={"lineup__row__item lineup__item--status cell small-1"}
336
          style={{
337
            backgroundImage: `url(${element.changed ? iconSubIn : iconBench})`,
338
          }}
339
          title={`${element.changed ? "Wisselspeler ingevallen" : "Wisselspeler"}`}
340
        ></span>
341
        <span className={"lineup__row__item lineup__item--number cell small-1"}>
342
          {element.number}
343
        </span>
344
        <span className={"lineup__row__item lineup__item--name cell small-9"}>
345
          {element.playerName}
346
        </span>
347
        <span className={"lineup__row__item lineup__item--time cell small-1"}>
348
          {element.minutesPlayed}'
349
        </span>
350
      </div>
351
    )
352
  }
353
354
  renderLineupLine(i, element) {
355
    return (
356
      <div
357
        className={"lineup__row lineup__row--lineup grid-x grid-margin-x"}
358
        key={i}
359
      >
360
        <span
361
          className={"lineup__row__item lineup__item--status cell small-1"}
362
          style={{
363
            backgroundImage: `url(${element.changed ? iconSubOut : iconStart})`
364
          }}
365
          title={`${element.changed ? "Basisspeler gewisseld" : "Basisspeler"}`}
366
        ></span>
367
        <span className={"lineup__row__item lineup__item--number cell small-1"}>
368
          {element.number}
369
        </span>
370
        <span className={"lineup__row__item lineup__item--name cell small-9"}>
371
          {element.playerName} {element.captain && `(C)`}
372
        </span>
373
        <span className={"lineup__row__item lineup__item--time cell small-1"}>
374
          {element.minutesPlayed}'
375
        </span>
376
      </div>
377
    )
378
  }
379
}
380
381
export const pageQuery = graphql`
382
  query {
383
    site {
384
      siteMetadata {
385
        kcvvPsdApi
386
      }
387
    }
388
  }
389
`
390
391
export default GamePage
392