Passed
Push — feature/share-pages ( c39874...7d93ee )
by Kevin Van
03:52
created

PlayerShare.renderPlayerImage   A

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 13
rs 9.95
c 0
b 0
f 0
cc 1
1
import React, { Component, Fragment } from "react"
2
import { graphql, StaticQuery } from "gatsby"
3
import { mapPositionCode } from "../scripts/helper"
4
import { getSrc } from "gatsby-plugin-image"
5
import { useQueryParam, StringParam } from "use-query-params"
6
7
import moment from "moment"
8
9
import "./player.scss"
10
import { Link } from "gatsby"
11
import Helmet from "react-helmet"
12
13
import Icon from "../components/Icon"
14
import RelatedNews from "../components/RelatedNews"
15
16
import iconCleansheet from "../images/i_cleansheet.png"
17
import iconCardRed from "../images/i_card_red.png"
18
import iconCardYellow from "../images/i_card_yellow.png"
19
import iconGoal from "../images/i_goal.png"
20
import Card from "./Card"
21
22
// eslint-disable-next-line
23
String.prototype.replaceAll = function (search, replacement) {
24
  var target = this
25
  return target.replace(new RegExp(search, `g`), replacement)
26
}
27
28
class Player extends Component {
29
  render() {
30
    const { player, config } = this.props
31
    const [view, setView] = useQueryParam(`view`, StringParam)
32
33
    if (view === `share`) {
34
      return <PlayerShare player={player} />
35
    }
36
    return <PlayerDetail player={player} config={config} />
37
  }
38
}
39
40
class PlayerShare extends Component {
41
  renderPlayerName = (player) => (
42
    <h1 className={`player-detail__name`}>
43
      <span className={`player-detail__name-first`}>{player.field_firstname}</span>
44
      <span className={`player-detail__name-last`}>{player.field_lastname}</span>
45
    </h1>
46
  )
47
  renderPlayerImage = (player) => (
48
    <Fragment>
49
      <div
50
        className={`player-detail__bg-avatar`}
51
        style={
52
          player.relationships.field_image && {
53
            backgroundImage: `url(${getSrc(
54
              player.relationships.field_image.localFile.childImageSharp.gatsbyImageData
55
            )})`,
56
          }
57
        }
58
      />
59
    </Fragment>
60
  )
61
  renderPlayerHeader = (player) => (
62
    <Fragment>
63
      {this.renderPlayerName(player)}
64
      {this.renderPlayerImage(player)}
65
66
      <div className={`player-detail__bg-shirt-number`} aria-hidden="true">
67
        {player.field_shirtnumber || ``}
68
      </div>
69
    </Fragment>
70
  )
71
72
  render() {
73
    const { player } = this.props
74
    const [score] = useQueryParam(`score`, StringParam)
75
    const [match] = useQueryParam(`match`, StringParam)
76
    const [assist] = useQueryParam(`assist`, StringParam)
77
78
    const fallback =
79
      player.relationships?.field_image?.localFile?.childImageSharp?.gatsbyImageData?.placeholder?.fallback || null
80
81
    return (
82
      <article className={`player-detail player-detail--share`}>
83
        <Helmet
84
          bodyAttributes={{
85
            class: `share`,
86
          }}
87
        />
88
          <img src={fallback} class="player-detail__bg--fallback" />
89
          {this.renderPlayerHeader(player)}
90
91
          <div className={`bg-green-mask`}>
92
          <p>{score}</p>
93
          <p>{match}</p>
94
          <p>{assist}</p></div>
95
      </article>
96
    )
97
  }
98
}
99
100
/**
101
 */
102
class PlayerDetail extends Component {
103
  constructor(props) {
104
    super(props)
105
106
    this.state = {
107
      data: [],
108
      loading: true,
109
    }
110
111
    const {
112
      config: {
113
        site: {
114
          siteMetadata: { kcvvPsdApi },
115
        },
116
      },
117
      player: { field_vv_id: playerId },
118
    } = this.props
119
120
    this.kcvvPsdApi = kcvvPsdApi
121
    this.playerId = playerId
122
  }
123
124
  updateData() {
125
    if (this.playerId === null) {
126
      return
127
    }
128
129
    const apiUrl = `${this.kcvvPsdApi}/stats/player/${this.playerId}`
130
131
    fetch(apiUrl)
132
      .then((response) => response.json())
133
      .then((json) => this.setState({ data: json, loading: false }))
134
      .catch(() => this.setState({ data: {}, loading: false }))
135
  }
136
137
  componentDidMount() {
138
    this.updateData()
139
  }
140
141
  renderPlayerName = (player) => (
142
    <h1 className={`player-detail__name`}>
143
      <span className={`player-detail__name-first`}>{player.field_firstname}</span>
144
      <span className={`player-detail__name-last`}>{player.field_lastname}</span>
145
    </h1>
146
  )
147
  renderPlayerImage = (player) => (
148
    <div className={`bg-green-mask`}>
149
      <div
150
        className={`player-detail__bg-avatar`}
151
        style={
152
          player.relationships.field_image && {
153
            backgroundImage: `url(${getSrc(
154
              player.relationships.field_image.localFile.childImageSharp.gatsbyImageData
155
            )})`,
156
          }
157
        }
158
      />
159
      <div className={`bg-white-end`} />
160
    </div>
161
  )
162
  renderPlayerHeader = (player) => (
163
    <header className={`player-detail__header`}>
164
      {this.renderPlayerName(player)}
165
      {this.renderPlayerImage(player)}
166
167
      <div className={`player-detail__bg-shirt-number`} aria-hidden="true">
168
        {player.field_shirtnumber || ``}
169
      </div>
170
    </header>
171
  )
172
  renderPlayerStats = (player) => {
173
    if (this.state.loading === false && this.state.data) {
174
      const { playerStatistics = [] } = this.state.data
175
176
      return (
177
        <aside className={`player-detail__statistics`}>
178
          <section className={`player-detail__statistics-item`}>
179
            <div className={`player-detail__statistics-item__number`}>
180
              {playerStatistics.reduce((a, b) => a + (b?.gamesPlayed || 0), 0) || `0`}
181
            </div>
182
            <div className={`player-detail__statistics-item__label`}>Wedstrijden</div>
183
          </section>
184
185
          {(player.field_position === `k` || player.field_position === `d`) && (
186
            <section className={`player-detail__statistics-item`}>
187
              <div className={`player-detail__statistics-item__number`}>
188
                {playerStatistics.reduce((a, b) => a + (b?.cleanSheets || 0), 0) || `0`}
189
              </div>
190
              <div className={`player-detail__statistics-item__label`}>Cleansheets</div>
191
            </section>
192
          )}
193
          {player.field_position !== `k` && (
194
            <section className={`player-detail__statistics-item`}>
195
              <div className={`player-detail__statistics-item__number`}>
196
                {playerStatistics.reduce((a, b) => a + (b?.goals || 0), 0) || `0`}
197
              </div>
198
              <div className={`player-detail__statistics-item__label`}>Doelpunten</div>
199
            </section>
200
          )}
201
          <section className={`player-detail__statistics-item`}>
202
            <div className={`player-detail__statistics-item__number`}>
203
              {playerStatistics.reduce((a, b) => a + (b?.yellowCards || 0), 0) || `0`}
204
            </div>
205
            <div className={`player-detail__statistics-item__label`}>Gele kaarten</div>
206
          </section>
207
          <section className={`player-detail__statistics-item`}>
208
            <div className={`player-detail__statistics-item__number`}>
209
              {playerStatistics.reduce((a, b) => a + (b?.redCards || 0), 0) || `0`}
210
            </div>
211
            <div className={`player-detail__statistics-item__label`}>Rode kaarten</div>
212
          </section>
213
        </aside>
214
      )
215
    }
216
  }
217
218
  renderPlayerStatsFull = (player) => {
219
    if (this.state.loading === false && this.state.data) {
220
      const { playerStatistics = [] } = this.state.data
221
222
      return (
223
        <Card title="Statistieken" className={`player-detail__stats`} hasTable={true}>
224
          <table className={`player-detail__stats__table`}>
225
            <thead>
226
              <tr>
227
                <th className={`player-detail__column player-detail__column--string`}>Team</th>
228
                <th className={`player-detail__column player-detail__column--number show-for-medium`}>
229
                  <span title="Wedstrijden gespeeld">P</span>
230
                </th>
231
                <th className={`player-detail__column player-detail__column--number`}>
232
                  <span title="Wedstrijden gewonnen">W</span>
233
                </th>
234
                <th className={`player-detail__column player-detail__column--number`}>
235
                  <span title="Wedstrijden gelijkgespeeld">D</span>
236
                </th>
237
                <th className={`player-detail__column player-detail__column--number`}>
238
                  <span title="Wedstrijden verloren">L</span>
239
                </th>
240
                <th className={`player-detail__column player-detail__column--number`}>
241
                  <img
242
                    src={iconCardYellow}
243
                    title="Gele kaart"
244
                    alt="Gele kaart"
245
                    className="player-detail__stats--header_icon"
246
                  />
247
                </th>
248
                <th className={`player-detail__column player-detail__column--number`}>
249
                  <img
250
                    src={iconCardRed}
251
                    title="Rode kaart"
252
                    alt="Rode kaart"
253
                    className="player-detail__stats--header_icon"
254
                  />
255
                </th>
256
                <th className={`player-detail__column player-detail__column--number`}>
257
                  <img
258
                    src={iconGoal}
259
                    title="Doelpunt(en) gescoord"
260
                    alt="Doelpunt(en) gescoord"
261
                    className="player-detail__stats--header_icon"
262
                  />
263
                </th>
264
                <th className={`player-detail__column player-detail__column--number  show-for-medium`}>
265
                  <img
266
                    src={iconCleansheet}
267
                    title="Cleansheets"
268
                    alt="Cleansheets"
269
                    className="player-detail__stats--header_icon"
270
                  />
271
                </th>
272
                <th className={`player-detail__column player-detail__column--number`}>
273
                  <span title="Minuten gespeeld">
274
                    <Icon icon="fa-clock-o" />
275
                  </span>
276
                </th>
277
              </tr>
278
            </thead>
279
            <tbody>
280
              {playerStatistics.map(function (stats) {
281
                return (
282
                  <tr>
283
                    <td className={`player-detail__column player-detail__column--string`}>
284
                      {stats.team.replace(`Voetbal : `, ``)}
285
                    </td>
286
                    <td className={`player-detail__column player-detail__column--number show-for-medium`}>
287
                      {stats.gamesPlayed}
288
                    </td>
289
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesWon}</td>
290
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesEqual}</td>
291
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesLost}</td>
292
                    <td className={`player-detail__column player-detail__column--number`}>{stats.yellowCards}</td>
293
                    <td className={`player-detail__column player-detail__column--number`}>{stats.redCards}</td>
294
                    <td className={`player-detail__column player-detail__column--number`}>{stats.goals}</td>
295
                    <td className={`player-detail__column player-detail__column--number show-for-medium`}>
296
                      {stats.cleanSheets}
297
                    </td>
298
                    <td className={`player-detail__column player-detail__column--number`}>{stats.minutes}'</td>
299
                  </tr>
300
                )
301
              })}
302
            </tbody>
303
          </table>
304
        </Card>
305
      )
306
    }
307
  }
308
  renderPlayerGamesFull = () => {
309
    if (this.state.loading === false && this.state.data) {
310
      const { gameReports = [] } = this.state.data
311
312
      return (
313
        <Card className={`player-detail__games`} title="Wedstrijden" hasTable={true}>
314
          <table className={`player-detail__games__table responsive-card-table`}>
315
            <thead>
316
              <tr>
317
                <th className={`player-detail__column player-detail__column--string`}>Team</th>
318
                <th className={`player-detail__column player-detail__column--string`}>Type</th>
319
                <th className={`player-detail__column player-detail__column--string`}>Datum</th>
320
                <th className={`player-detail__column player-detail__column--number`}>
321
                  <span title="Thuis/uit">H/A</span>
322
                </th>
323
                <th className={`player-detail__column player-detail__column--score`}>Score</th>
324
                <th className={`player-detail__column player-detail__column--string`}>Tegenstander</th>
325
                <th className={`player-detail__column player-detail__column--number`}>
326
                  <img
327
                    src={iconCardYellow}
328
                    title="Gele kaart"
329
                    alt="Gele kaart"
330
                    className="player-detail__stats--header_icon"
331
                  />
332
                </th>
333
                <th className={`player-detail__column player-detail__column--number`}>
334
                  <img
335
                    src={iconCardRed}
336
                    title="Rode kaart"
337
                    alt="Rode kaart"
338
                    className="player-detail__stats--header_icon"
339
                  />
340
                </th>
341
                <th className={`player-detail__column player-detail__column--number`}>
342
                  <img
343
                    src={iconGoal}
344
                    title="Doelpunten gescoord"
345
                    alt="Rode kaart"
346
                    className="player-detail__stats--header_icon"
347
                  />
348
                </th>
349
                <th className={`player-detail__column player-detail__column--number`}>
350
                  <span title="Minuten gespeeld">
351
                    <Icon icon="fa-clock-o" />
352
                  </span>
353
                </th>
354
              </tr>
355
            </thead>
356
            <tbody>
357
              {gameReports.map(function (game) {
358
                return (
359
                  <tr>
360
                    <td data-label="Team" className={`player-detail__column player-detail__column--string`}>
361
                      {game.team.replace(`Voetbal : `, ``)}
362
                    </td>
363
                    <td data-label="Type" className={`player-detail__column player-detail__column--string`}>
364
                      {game.competition}
365
                    </td>
366
                    <td data-label="Datum" className={`player-detail__column player-detail__column--string`}>
367
                      {moment(game.date).format(`DD/MM/YYYY`)}
368
                    </td>
369
                    <td data-label="Thuis/uit" className={`player-detail__column player-detail__column--number`}>
370
                      {game.home ? (
371
                        <span className={`player-detail__games__home`} title="Thuiswedstrijd">
372
                          <Icon icon="fa-home" alt="Thuiswedstrijd" />
373
                        </span>
374
                      ) : (
375
                        <span className={`player-detail__games__away`} title="Uitwedstrijd">
376
                          <Icon icon="fa-bus" alt="Uitwedstrijd" />
377
                        </span>
378
                      )}
379
                    </td>
380
                    <td data-label="Score" className={`player-detail__column player-detail__column--score`}>
381
                      {game.goalsHomeTeam}&nbsp;-&nbsp;{game.goalsAwayTeam}
382
                    </td>
383
                    <td data-label="Tegenstander" className={`player-detail__column player-detail__column--string`}>
384
                      {game.opponent}
385
                    </td>
386
                    <td data-label="Gele kaart(en)" className={`player-detail__column player-detail__column--number`}>
387
                      {game.yellowCards}
388
                    </td>
389
                    <td data-label="Rode kaart(en)" className={`player-detail__column player-detail__column--number`}>
390
                      {game.redCards}
391
                    </td>
392
                    <td data-label="Doelpunten" className={`player-detail__column player-detail__column--number`}>
393
                      {game.goals}
394
                    </td>
395
                    <td data-label="Speeltijd" className={`player-detail__column player-detail__column--number`}>
396
                      {game.minutesPlayed}'
397
                    </td>
398
                  </tr>
399
                )
400
              })}
401
            </tbody>
402
          </table>
403
        </Card>
404
      )
405
    }
406
  }
407
408
  renderPlayerBirthdate = (player) => (
409
    <div className={`player-detail__data-item player-detail__data-item--birthdate`}>
410
      <span className={`player-detail__data-item__label`}>Geboortedatum</span>
411
      <span className={`player-detail__data-item__data`}>{player.field_birth_date || `Onbekend`}</span>
412
    </div>
413
  )
414
  renderPlayerPosition = (player) => (
415
    <div className={`player-detail__data-item player-detail__data-item--position`}>
416
      <span className={`player-detail__date-item__data`}>
417
        {player.field_position && mapPositionCode(player.field_position)}
418
      </span>
419
      <span className={`player-detail__data-item__label`}>
420
        {player.relationships.node__team && (
421
          <Link to={player.relationships.node__team[0].path.alias}>{player.relationships.node__team[0].title}</Link>
422
        )}
423
      </span>
424
    </div>
425
  )
426
  renderPlayerJoinDate = (player) => {
427
    const currentlyPlaying = !player.field_date_leave
428
    return (
429
      <div className={`player-detail__data-item player-detail__data-item--joindate`}>
430
        <span className={`player-detail__data-item__label`}>
431
          {currentlyPlaying && `Speler bij KCVV sinds`}
432
          {!currentlyPlaying && `Speler tussen`}
433
        </span>
434
        <span className={`player-detail__data-item__data`}>
435
          {player.field_join_date || `Onbekend`}
436
          {!currentlyPlaying && (
437
            <Fragment>
438
              <span className={`text--regular`}> en </span> {player.field_date_leave}
439
            </Fragment>
440
          )}
441
        </span>
442
      </div>
443
    )
444
  }
445
  renderPlayerData = (player) => (
446
    <section className={`player-detail__data`}>
447
      {this.renderPlayerBirthdate(player)}
448
      {this.renderPlayerPosition(player)}
449
      {this.renderPlayerJoinDate(player)}
450
    </section>
451
  )
452
  renderPlayerBody = (player) => {
453
    const cleanBody =
454
      (player.body &&
455
        player.body.processed.replaceAll(`/sites/default/`, `${process.env.GATSBY_API_DOMAIN}/sites/default/`)) ||
456
      ``
457
458
    return (
459
      <section className={`player-detail__body`}>
460
        <div dangerouslySetInnerHTML={{ __html: cleanBody }} />
461
      </section>
462
    )
463
  }
464
  render() {
465
    const { player } = this.props
466
467
    const team = player.relationships.node__team || []
468
    const articles = player.relationships.node__article || []
469
470
    return (
471
      <Fragment>
472
        <article className={`player-detail`}>
473
          {this.renderPlayerHeader(player)}
474
          {this.renderPlayerStats(player)}
475
          <div className={`player-break`}></div>
476
          {this.renderPlayerData(player)}
477
          {this.renderPlayerBody(player)}
478
          {this.renderPlayerStatsFull(player)}
479
          {this.renderPlayerGamesFull(player)}
480
        </article>
481
482
        {(team || articles) && <RelatedNews items={team.concat(articles)} limit={6} />}
483
      </Fragment>
484
    )
485
  }
486
}
487
488
// Retrieve endpoint of the logo's api from the site metadata (gatsby-config.js).
489
const query = graphql`
490
  query {
491
    site {
492
      siteMetadata {
493
        kcvvPsdApi
494
      }
495
    }
496
  }
497
`
498
499
export default ({ player }) => (
500
  <StaticQuery
501
    query={query}
502
    render={(data) => (
503
      <Player
504
        // Data is the result of our query.
505
        config={data}
506
        player={player}
507
      />
508
    )}
509
  />
510
)
511