Passed
Pull Request — develop (#758)
by Kevin Van
08:22 queued 04:35
created

src/templates/Team.tsx   B

Complexity

Total Complexity 51
Complexity/F 0

Size

Lines of Code 238
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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