Passed
Push — feature/full-redesign ( 58f6d4...ff7e17 )
by Kevin Van
04:32
created

src/templates/Team.tsx   C

Complexity

Total Complexity 55
Complexity/F 0

Size

Lines of Code 246
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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