-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Learn quizzes #8094
Merged
Merged
Learn quizzes #8094
Changes from 48 commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
fa9d865
base start to quiz component
corwintines f8bcc47
resolve quiz based on url, or with quizKey
corwintines 7a711ba
temp
corwintines e1cf364
Merge branch 'dev' into learnQuizzes
wackerow 4880b35
Add quiz data types
wackerow 2792437
refactor quiz-data data structure
wackerow 815ea35
update QuizQuestion to accept callback function
wackerow 0a22340
set up action handlers for Quiz, clean up useState
wackerow 386c6fd
update types
wackerow 179d540
update QuizWidget logic
wackerow fe4ddc5
update QuizQuestion
wackerow 4dbb1e6
feat: QuizWidget mvp
wackerow a2251f9
add trophy/status svg indicators
wackerow 0393f71
update question bank and quizzes
wackerow 69b0219
add QuizWidget to eth and wallets pages
wackerow 5802edd
fix quiz svg colors
wackerow 343c1df
quis adjustments
wackerow 219004f
add QuizWidget to nft/web3/security pages
wackerow 72a786a
fix genesis year
wackerow 1ca0ff5
Update QuizQuestion styling
wackerow cb47e81
styling adjustments
wackerow fc18ef7
add Spinner loading indicator
wackerow d1c384d
Create QuizRadioGroup.tsx
wackerow fb9c5bc
update QuizWidget with QuizRadioGroup
wackerow 0fec992
update QuizWidget with share tweet functionality
wackerow 840d399
internationalize percentages
wackerow 0dd51c2
deprecate QuizQuestion component
wackerow 1dfb514
feat: custom matomo tracking for quiz widget
wackerow e9e54d1
apply suggestions from code review
wackerow 44a1c97
remove "quizButton" theming
wackerow 45c5074
update theming variables
wackerow 69adef7
update constants, add numberToPercent util
wackerow 810e8be
update logic for Quiz components
wackerow fa61dbd
add explicit quizKey prop
wackerow 22f4b0a
clean up magic numbers and progress bar logic
wackerow ce9805e
small layout adjustments
wackerow 13a08d3
getLocaleForNumberFormat with numberToPercent
wackerow 7628ecb
chore: code clean up
wackerow 2cc1e87
feat: improve progress bar responsiveness
wackerow 7f7fe11
Merge branch 'dev' into learnQuizzes
wackerow 532b041
fix: hover outline coloring
wackerow 7a8e293
update prop typing for numberToPercent util
wackerow dc447fd
fix: confetti z-index below copy and trophy
wackerow 4cb155c
fix: button layout
wackerow d08bb9a
conditionally hide "Try again" on 100%
wackerow 485c1cc
mobile responsiveness for QuizSummary
wackerow 594352b
chore: improve DRY code
wackerow d58cb8e
chore: remove comments
wackerow e7cc5e0
clean up duplicate function
corwintines 4c79ace
remove unused function
corwintines 9711871
remove duplicate function
corwintines d52fa01
import: layer 2 questions
wackerow 6694807
import: merge quiz questions
wackerow f29fc4f
adjust padding
wackerow 6b9a841
Update content
minimalsm e824f84
Update Twitter hashtag for quiz share function
minimalsm afb076b
fix: add hashlink to #quiz for twitter share
wackerow c094343
fix: padding adjustments
wackerow File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,12 +34,17 @@ const semanticTokens = { | |
primaryLight: { _light: "blue.100", _dark: "orange.100" }, | ||
primaryDark: { _light: "blue.700", _dark: "orange.800" }, | ||
primaryHover: { _light: "blue.300", _dark: "orange.300" }, | ||
primaryPressed: { _light: "blue.300", _dark: "orange.800" }, | ||
body: { _light: "gray.700", _dark: "gray.100" }, | ||
bodyInverted: { _light: "gray.100", _dark: "gray.700" }, | ||
bodyLight: { _light: "gray.500", _dark: "gray.100" }, | ||
disabled: { _light: "gray.400", _dark: "gray.500" }, | ||
background: { _light: "white", _dark: "gray.700" }, | ||
success: "green.500", | ||
neutral: { _light: "white", _dark: "gray.900" }, | ||
success: { _light: "green.500", _dark: "green.400" }, | ||
successNeutral: { _light: "green.100", _dark: "green.900" }, | ||
error: "red.500", | ||
errorNeutral: { _light: "red.100", _dark: "red.900" }, | ||
Comment on lines
+37
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc: @nloureiro @konopkja |
||
attention: "yellow.200", | ||
}, | ||
} | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// Import libraries | ||
import React, { useMemo } from "react" | ||
import { | ||
Box, | ||
chakra, | ||
Circle, | ||
Flex, | ||
RadioProps, | ||
Text, | ||
useRadio, | ||
useRadioGroup, | ||
} from "@chakra-ui/react" | ||
|
||
// Import types | ||
import { Question } from "../../types" | ||
|
||
// Interfaces | ||
export interface CustomRadioProps extends RadioProps { | ||
index: number | ||
label: string | ||
} | ||
export interface IProps { | ||
questionData: Question | ||
showAnswer: boolean | ||
handleSelection: (answerId: string) => void | ||
selectedAnswer: string | null | ||
} | ||
|
||
// Component | ||
const QuizRadioGroup: React.FC<IProps> = ({ | ||
questionData, | ||
showAnswer, | ||
handleSelection, | ||
selectedAnswer, | ||
}) => { | ||
const { getRadioProps, getRootProps } = useRadioGroup({ | ||
onChange: handleSelection, | ||
}) | ||
const { prompt, answers, correctAnswerId } = questionData | ||
|
||
// Memoized values | ||
const explanation = useMemo<string>(() => { | ||
if (!selectedAnswer) return "" | ||
return answers.filter(({ id }) => id === selectedAnswer)[0].explanation | ||
}, [selectedAnswer]) | ||
|
||
const isSelectedCorrect = useMemo<boolean>( | ||
() => correctAnswerId === selectedAnswer, | ||
[selectedAnswer] | ||
) | ||
|
||
// Custom radio button component | ||
const CustomRadio: React.FC<CustomRadioProps> = ({ | ||
index, | ||
label, | ||
...radioProps | ||
}) => { | ||
const { state, getInputProps, getCheckboxProps, htmlProps } = | ||
useRadio(radioProps) | ||
|
||
// Memoized values | ||
const buttonBg = useMemo<string>(() => { | ||
if (!state.isChecked) return "bodyInverted" | ||
if (!showAnswer) return "primary" | ||
if (!isSelectedCorrect) return "error" | ||
return "success" | ||
}, [state.isChecked, showAnswer, isSelectedCorrect]) | ||
|
||
// Render CustomRadio component | ||
return ( | ||
<chakra.label {...htmlProps} cursor="pointer" data-group w="100%"> | ||
<input {...getInputProps({})} hidden /> | ||
<Flex | ||
{...getCheckboxProps()} | ||
w="100%" | ||
p={2} | ||
alignItems="center" | ||
bg={buttonBg} | ||
color={state.isChecked ? "white" : "text"} | ||
borderRadius="base" | ||
_hover={{ | ||
boxShadow: showAnswer ? "none" : "primary", | ||
outline: showAnswer | ||
? "none" | ||
: "1px solid var(--eth-colors-primary)", | ||
cursor: showAnswer ? "default" : "pointer", | ||
}} | ||
> | ||
<Circle | ||
size="25px" | ||
bg={ | ||
showAnswer | ||
? "white" | ||
: state.isChecked | ||
? "primaryPressed" | ||
: "disabled" | ||
} | ||
_groupHover={{ | ||
bg: showAnswer ? "white" : "primaryPressed", | ||
}} | ||
me={2} | ||
> | ||
<Text | ||
m="0" | ||
fontWeight="700" | ||
fontSize="lg" | ||
color={ | ||
!showAnswer ? "white" : isSelectedCorrect ? "success" : "error" | ||
} | ||
> | ||
{String.fromCharCode(97 + index).toUpperCase()} | ||
wackerow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</Text> | ||
</Circle> | ||
{label} | ||
</Flex> | ||
</chakra.label> | ||
) | ||
} | ||
|
||
// Render QuizRadioGroup | ||
return ( | ||
<Flex {...getRootProps()} direction="column" w="100%"> | ||
<Text fontWeight="700" fontSize="2xl" mb={6}> | ||
{prompt} | ||
</Text> | ||
<Flex direction="column" gap={4}> | ||
{answers.map(({ id, label }, index) => { | ||
const display = | ||
!showAnswer || id === selectedAnswer ? "inline-flex" : "none" | ||
return ( | ||
<CustomRadio | ||
key={id} | ||
display={display} | ||
index={index} | ||
label={label} | ||
{...getRadioProps({ value: id })} | ||
/> | ||
) | ||
})} | ||
</Flex> | ||
{showAnswer && ( | ||
<Box mt={5}> | ||
<Text fontWeight="bold" mt={0} mb={2}> | ||
Explanation | ||
</Text> | ||
<Text m={0}>{explanation}</Text> | ||
</Box> | ||
)} | ||
</Flex> | ||
) | ||
} | ||
|
||
export default QuizRadioGroup | ||
wackerow marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Import libraries | ||
import React, { useMemo } from "react" | ||
import { Box, Flex, Text, useMediaQuery } from "@chakra-ui/react" | ||
import { useIntl } from "react-intl" | ||
|
||
// Import utilities | ||
import { numberToPercent } from "../../utils/numberToPercent" | ||
|
||
// Import constants | ||
import { PASSING_QUIZ_SCORE } from "../../constants" | ||
|
||
// Interfaces | ||
export interface IProps { | ||
correctCount: number | ||
questionCount: number | ||
} | ||
|
||
// Component | ||
const QuizSummary: React.FC<IProps> = ({ correctCount, questionCount }) => { | ||
const { locale } = useIntl() | ||
const [largerThanMobile] = useMediaQuery("(min-width: 30em)") | ||
|
||
// Memoized values | ||
const ratioCorrect = useMemo<number>( | ||
() => correctCount / questionCount, | ||
[correctCount, questionCount] | ||
) | ||
|
||
const score = useMemo<number>( | ||
() => Math.floor(ratioCorrect * 100), | ||
[ratioCorrect] | ||
) | ||
|
||
const isPassingScore = useMemo<boolean>( | ||
() => score > PASSING_QUIZ_SCORE, | ||
[score] | ||
) | ||
|
||
const valueStyles = { fontWeight: "700", mb: 2 } | ||
const labelStyles = { fontSize: "sm", m: 0, color: "disabled" } | ||
|
||
// Render QuizSummary component | ||
return ( | ||
<Box w="full" mb={10} fontSize={["xl", "2xl"]}> | ||
<Text fontWeight="700" textAlign="center"> | ||
{isPassingScore ? "You passed the quiz!" : "Your results"} | ||
</Text> | ||
<Flex | ||
p={4} | ||
justify="center" | ||
boxShadow="drop" | ||
bg="background" | ||
mx="auto" | ||
w="fit-content" | ||
sx={{ | ||
"div:not(:last-of-type)": { | ||
borderEnd: "1px", | ||
borderColor: "disabled", | ||
}, | ||
div: { | ||
p: 4, | ||
flexDirection: "column", | ||
alignItems: "center", | ||
}, | ||
}} | ||
overflowX="hidden" | ||
> | ||
<Flex> | ||
<Text {...valueStyles}>{numberToPercent(ratioCorrect, locale)}</Text> | ||
<Text {...labelStyles}>Score</Text> | ||
</Flex> | ||
<Flex> | ||
<Text {...valueStyles}>+{correctCount}</Text> | ||
<Text {...labelStyles}>Correct</Text> | ||
</Flex> | ||
{largerThanMobile && ( | ||
<Flex> | ||
<Text {...valueStyles}>{questionCount}</Text> | ||
<Text {...labelStyles}>Total</Text> | ||
</Flex> | ||
)} | ||
</Flex> | ||
</Box> | ||
) | ||
} | ||
|
||
export default QuizSummary |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do find this red hard to see in dark mode