Skip to content

Commit bfe53a6

Browse files
committed
Merge branch 'feat-learning-quizzes-hub' of github.com:ethereum/ethereum-org-website into feat-learning-quizzes-hub
2 parents 1c3fabe + 2e8627c commit bfe53a6

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

src/components/Quiz/QuizzesStats.tsx

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ import {
1010
Text,
1111
} from "@chakra-ui/react"
1212
import { FaTwitter } from "react-icons/fa"
13+
import { useI18next } from "gatsby-plugin-react-i18next"
1314

1415
import Button from "../Button"
1516
import Translation from "../Translation"
1617
import { TrophyIcon } from "../icons/quiz"
1718

1819
import { QuizzesHubContext } from "./context"
1920

21+
// Utils
2022
import {
23+
getFormattedStats,
2124
getNumberOfCompletedQuizzes,
2225
getTotalQuizzesPoints,
2326
shareOnTwitter,
@@ -42,24 +45,26 @@ const handleShare = ({ score, total }: QuizShareStats) => {
4245
}
4346

4447
const QuizzesStats: React.FC = () => {
48+
const { language } = useI18next()
4549
const {
4650
userStats: { score: userScore, completed, average },
4751
} = useContext(QuizzesHubContext)
4852
const numberOfCompletedQuizzes = getNumberOfCompletedQuizzes(
4953
JSON.parse(completed)
5054
)
5155

52-
const computedAverage =
53-
average.length > 0 ? average.reduce((a, b) => a + b, 0) / average.length : 0
54-
const parsedAverage = Number.isInteger(computedAverage)
55-
? computedAverage
56-
: computedAverage.toFixed(2)
57-
5856
// These values are not fixed but calculated each time, can't be moved to /constants
5957
const totalQuizzesNumber =
6058
ethereumBasicsQuizzes.length + usingEthereumQuizzes.length
6159
const totalQuizzesPoints = getTotalQuizzesPoints()
6260

61+
const {
62+
formattedUserAverageScore,
63+
formattedCollectiveQuestionsAnswered,
64+
formattedCollectiveAverageScore,
65+
formattedCollectiveRetryRate,
66+
} = getFormattedStats(language, average)
67+
6368
return (
6469
<Box flex={1} order={{ base: 1, lg: 2 }} w="full">
6570
<Stack mt={{ base: 0, lg: 12 }} gap={{ base: 8, lg: 4 }}>
@@ -127,7 +132,7 @@ const QuizzesStats: React.FC = () => {
127132
<Text mr={10} mb={0} mt={{ base: 2, lg: 0 }} color="bodyMedium">
128133
<Translation id="average-score" />{" "}
129134
<Text as="span" color="body">
130-
{parsedAverage}%
135+
{formattedUserAverageScore}
131136
</Text>
132137
</Text>
133138

@@ -165,7 +170,7 @@ const QuizzesStats: React.FC = () => {
165170
<Translation id="average-score" />
166171
</Text>
167172
{/* Data from Matomo, manually updated */}
168-
<Text color="body">67.4%</Text>
173+
<Text color="body">{formattedCollectiveAverageScore}</Text>
169174
</Stack>
170175

171176
<Stack>
@@ -174,7 +179,10 @@ const QuizzesStats: React.FC = () => {
174179
</Text>
175180

176181
{/* Data from Matomo, manually updated */}
177-
<Text color="body">100 000+</Text>
182+
<Text color="body">
183+
{formattedCollectiveQuestionsAnswered}
184+
<Text as="span">+</Text>
185+
</Text>
178186
</Stack>
179187

180188
<Stack>
@@ -183,7 +191,7 @@ const QuizzesStats: React.FC = () => {
183191
</Text>
184192

185193
{/* Data from Matomo, manually updated */}
186-
<Text color="body">15.6%</Text>
194+
<Text color="body">{formattedCollectiveRetryRate}</Text>
187195
</Stack>
188196
</Flex>
189197
</Flex>

src/components/Quiz/utils.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import { USER_STATS_KEY } from "../../constants"
1+
import { getLocaleForNumberFormat } from "../../utils/translations"
2+
import { Lang } from "../../utils/languages"
23

34
import { CompletedQuizzes, QuizShareStats } from "../../types"
45

6+
import {
7+
TOTAL_QUIZ_AVERAGE_SCORE,
8+
TOTAL_QUIZ_QUESTIONS_ANSWERED,
9+
TOTAL_QUIZ_RETRY_RATE,
10+
USER_STATS_KEY,
11+
} from "../../constants"
12+
513
import allQuizzesData, {
614
ethereumBasicsQuizzes,
715
usingEthereumQuizzes,
@@ -85,3 +93,42 @@ export const shareOnTwitter = ({ score, total }: QuizShareStats): void => {
8593
`https://twitter.com/intent/tweet?text=${tweet}&hashtags=${hashtags}`
8694
)
8795
}
96+
97+
const mean = (values: number[]) =>
98+
values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0
99+
100+
export const getFormattedStats = (language, average) => {
101+
const localeForNumbers = getLocaleForNumberFormat(language as Lang)
102+
103+
// Initialize number and percent formatters
104+
const numberFormatter = new Intl.NumberFormat(localeForNumbers, {
105+
style: "decimal",
106+
minimumSignificantDigits: 1,
107+
maximumSignificantDigits: 3,
108+
})
109+
110+
const percentFormatter = new Intl.NumberFormat(localeForNumbers, {
111+
style: "percent",
112+
minimumSignificantDigits: 1,
113+
maximumSignificantDigits: 3,
114+
})
115+
116+
const computedAverage = average.length > 0 ? mean(average) : 0
117+
118+
// Convert collective stats to fraction for percentage format
119+
const normalizedCollectiveAverageScore = TOTAL_QUIZ_AVERAGE_SCORE / 100
120+
const normalizedCollectiveRetryRate = TOTAL_QUIZ_RETRY_RATE / 100
121+
122+
return {
123+
formattedUserAverageScore: percentFormatter.format(computedAverage / 100), // Normalize user average
124+
formattedCollectiveQuestionsAnswered: numberFormatter.format(
125+
TOTAL_QUIZ_QUESTIONS_ANSWERED
126+
),
127+
formattedCollectiveAverageScore: percentFormatter.format(
128+
normalizedCollectiveAverageScore
129+
),
130+
formattedCollectiveRetryRate: percentFormatter.format(
131+
normalizedCollectiveRetryRate
132+
),
133+
}
134+
}

src/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ export const PROGRESS_BAR_GAP = "4px"
55
export const PASSING_QUIZ_SCORE = 65
66
export const USER_STATS_KEY = "quizzes-stats"
77
export const INITIAL_QUIZ = "what-is-ethereum"
8+
export const TOTAL_QUIZ_QUESTIONS_ANSWERED = 100000
9+
export const TOTAL_QUIZ_AVERAGE_SCORE = 67.4
10+
export const TOTAL_QUIZ_RETRY_RATE = 15.6

0 commit comments

Comments
 (0)