Passed
Pull Request — develop (#758)
by Kevin Van
09:39 queued 05:17
created

src/templates/Team.tsx   B

Complexity

Total Complexity 52
Complexity/F 0

Size

Lines of Code 250
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 52
eloc 161
mnd 52
bc 52
fnc 0
dl 0
loc 250
rs 7.44
bpm 0
cpm 0
noi 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like src/templates/Team.tsx 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 { TeamQuery } from "../Types/Team"
2
import Lineup from "../components/Lineup"
3
import { Seo } from "../components/Seo"
4
import TeamStats from "../components/TeamStats"
5
import Layout from "../layouts"
6
import "./Team.scss"
7
import ReactFitText from "@kennethormandy/react-fittext"
8
import { graphql } from "gatsby"
9
import { GatsbyImage, getSrc } from "gatsby-plugin-image"
10
import React from "react"
11
import { MatchTeasers } from "../components/MatchTeaser"
12
import Matches from "../components/Matches"
13
import { AltTitle } from "../components/AltTitle"
14
import { Ranking } from "../components/Ranking"
15
import RelatedNews from "../components/RelatedNews"
16
17
const Team = ({ data: { nodeTeam } }: TeamQuery) => {
18
  const heroImage = nodeTeam?.relationships?.field_media_article_image
19
  const teamPicture = heroImage?.relationships?.field_media_image?.localFile?.childImageSharp?.gatsbyImageData && (
20
    <GatsbyImage
21
      image={heroImage.relationships?.field_media_image?.localFile?.childImageSharp?.gatsbyImageData}
22
      alt={heroImage?.field_media_image?.alt || ``}
23
      className={`team-detail__team-picture`}
24
    />
25
  )
26
27
  // Helper variable so we don't have to do the check over and over again.
28
  const hasDivision = nodeTeam?.field_vv_id
29
  const articles = nodeTeam?.relationships?.node__article || []
30
31
  console.log(nodeTeam?.relationships?.node__article)
32
33
  const allPlayers = [...(nodeTeam?.relationships?.field_players || [])]
34
35
  // Specific implementation of our groupBy function, to group by a property "field_position".
36
  const groupByPosition = groupBy(allPlayers, (v) => v?.field_position || ``)
37
38
  return (
39
    <Layout>
40
      <header className="page_header__wrapper page_header__wrapper--inset-large">
41
        <div className="page_header">
42
          <h1 className="team__header__name">
43
            {/* > GEWESTELIJKE U13 K */}
44
            <span className="team__header_name__division">
45
              <ReactFitText compressor={1.5}>{nodeTeam?.field_division_full}</ReactFitText>
46
            </span>
47
            {/* > The A-team */}
48
            <span className="team__header_name__division__tagline">{nodeTeam?.field_tagline}</span>
49
          </h1>
50
          {hasDivision && (
51
            <div className="team__header_name__division__number" aria-hidden="true">
52
              {nodeTeam?.field_fb_id}
53
            </div>
54
          )}
55
        </div>
56
      </header>
57
      {(allPlayers.length > 0 || hasDivision) && (
58
        <nav className="team__sub_navigation">
59
          {/* Foundation tabs structure */}
60
          <ul
61
            className="tabs team__sub_navigation__tabs"
62
            data-tabs
63
            data-deep-link="true"
64
            data-update-history="true"
65
            data-deep-link-smudge="true"
66
            data-deep-link-smudge-delay="500"
67
            id="team-subnavigation_tabs"
68
          >
69
            <li className="tabs-title is-active">
70
              <a href="#team-info" className="rich-link-center">
71
                Info
72
              </a>
73
            </li>
74
            {/* Youth teams don't have lineups, so we don't show the tab link. */}
75
            {allPlayers.length > 0 && (
76
              <li className="tabs-title">
77
                <a href="#team-lineup" className="rich-link-center">
78
                  Lineup
79
                </a>
80
              </li>
81
            )}
82
            {hasDivision && (
83
              <>
84
                <li className={`tabs-title`}>
85
                  <a data-tabs-target="team-matches" href="#team-matches" className="rich-link-center">
86
                    Wedstrijden
87
                  </a>
88
                </li>
89
                <li className={`tabs-title`}>
90
                  <a data-tabs-target="team-ranking" href="#team-ranking" className="rich-link-center">
91
                    Stand
92
                  </a>
93
                </li>
94
              </>
95
            )}
96
          </ul>
97
        </nav>
98
      )}
99
      <article className="page__wrapper team__wrapper">
100
        <div className="tabs-content" data-tabs-content="team-subnavigation_tabs">
101
          <div className="tabs-panel is-active" id="team-info">
102
            <div className="team_info__hero_image">{teamPicture || ``}</div>
103
            {nodeTeam?.field_contact_info && (
104
              <div
105
                className={`team_info__contact page__wrapper page__wrapper--limited`}
106
                dangerouslySetInnerHTML={{
107
                  __html: nodeTeam?.field_contact_info.processed || ``,
108
                }}
109
              />
110
            )}
111
            {nodeTeam?.field_vv_id && <TeamStats teamId={+nodeTeam?.field_vv_id} />}
112
            {nodeTeam?.relationships?.field_staff && allPlayers.length <= 0 && (
113
              <main className={`team-detail__lineup team-detail__lineup--staff-only`}>
114
                <Lineup lineup={nodeTeam?.relationships?.field_staff} />
115
              </main>
116
            )}
117
118
            {articles && <RelatedNews items={[...articles]} limit={6} />}
119
          </div>
120
          {allPlayers.length > 0 && (
121
            <div className={`tabs-panel`} id="team-lineup">
122
              <main className={`team-detail__lineup`}>
123
                {nodeTeam?.relationships?.field_staff && <Lineup lineup={nodeTeam.relationships.field_staff} />}
124
                {groupByPosition[`k`] && <Lineup title="Doelmannen" lineup={groupByPosition[`k`]} />}
125
                {groupByPosition[`d`] && <Lineup title="Verdedigers" lineup={groupByPosition[`d`]} />}
126
                {groupByPosition[`m`] && <Lineup title="Middenvelder" lineup={groupByPosition[`m`]} />}
127
                {groupByPosition[`a`] && <Lineup title="Aanvallers" lineup={groupByPosition[`a`]} />}
128
              </main>
129
            </div>
130
          )}
131
          {hasDivision && (
132
            <>
133
              <div className={`tabs-panel`} id="team-matches">
134
                {nodeTeam?.field_vv_id && <MatchTeasers teamId={+nodeTeam?.field_vv_id} />}
135
                {nodeTeam?.field_vv_id && (
136
                  <>
137
                    <AltTitle title="KALENDER" variant="white" />
138
                    <Matches teamId={+nodeTeam?.field_vv_id} />
139
                  </>
140
                )}
141
              </div>
142
              <div className={`tabs-panel`} id="team-ranking">
143
                {nodeTeam?.field_vv_id && <Ranking teamId={+nodeTeam?.field_vv_id} />}
144
              </div>
145
            </>
146
          )}
147
        </div>
148
      </article>
149
    </Layout>
150
  )
151
}
152
153
export default Team
154
155
export const Head = ({ data: { nodeTeam } }: TeamQuery) => {
156
  const pathUrl = nodeTeam?.path?.alias || ``
157
  const heroImage =
158
    nodeTeam?.relationships?.image_og?.relationships?.field_media_image?.localFile?.childImageSharp?.gatsbyImageData
159
160
  const ogImage = heroImage && {
161
    src: getSrc(heroImage) || ``,
162
    width: heroImage.width,
163
    height: heroImage.height,
164
  }
165
  return <Seo title={`${nodeTeam?.title} / ${nodeTeam?.field_division_full}`} path={pathUrl} image={ogImage} />
166
}
167
168
const groupBy = <T, K extends keyof T>(array: T[], groupOn: K | ((i: T) => string)): Record<string, T[]> => {
169
  const groupFn = typeof groupOn === `function` ? groupOn : (o: T) => o[groupOn]
170
171
  return Object.fromEntries(
172
    array.reduce((acc, obj) => {
173
      const groupKey = groupFn(obj)
174
      return acc.set(groupKey, [...(acc.get(groupKey) || []), obj])
175
    }, new Map())
176
  ) as Record<string, T[]>
177
}
178
179
export const query = graphql`
180
  query TeamQuery($slug: String!) {
181
    nodeTeam(path: { alias: { eq: $slug } }) {
182
      path {
183
        alias
184
      }
185
      title
186
      field_contact_info {
187
        processed
188
      }
189
      field_fb_id
190
      field_vv_id
191
      field_division_full
192
      field_tagline
193
      relationships {
194
        field_staff {
195
          path {
196
            alias
197
          }
198
          field_position_short
199
          field_lastname
200
          field_firstname
201
          relationships {
202
            field_image {
203
              localFile {
204
                ...KCVVFluidPlayerTeaser
205
              }
206
            }
207
          }
208
        }
209
        field_players {
210
          path {
211
            alias
212
          }
213
          field_shirtnumber
214
          field_lastname
215
          field_firstname
216
          field_position
217
          relationships {
218
            field_image {
219
              localFile {
220
                ...KCVVFluidPlayerTeaser
221
              }
222
            }
223
          }
224
        }
225
        field_media_article_image {
226
          ...FullImage
227
          field_media_image {
228
            alt
229
          }
230
        }
231
        image_og: field_media_article_image {
232
          ...ArticleImage
233
        }
234
        node__article {
235
          title
236
          timestamp: created(formatString: "x")
237
          path {
238
            alias
239
          }
240
          relationships {
241
            field_media_article_image {
242
              ...ArticleImage
243
            }
244
          }
245
        }
246
      }
247
    }
248
  }
249
`
250