Browse Source
* fix: reset showHint to false when click Next Challenge * Split Challenges into two components * clean code, add to flag whether the activeChallenge has changed to avoid scrolling to Chalenges when page mounted * Simplify Co-authored-by: Dan Abramov <dan.abramov@gmail.com>main
committed by
GitHub
3 changed files with 165 additions and 144 deletions
@ -0,0 +1,130 @@ |
|||
/* |
|||
* Copyright (c) Facebook, Inc. and its affiliates. |
|||
*/ |
|||
|
|||
import * as React from 'react'; |
|||
import cn from 'classnames'; |
|||
import {Button} from 'components/Button'; |
|||
import {ChallengeContents} from './Challenges'; |
|||
import {IconHint} from '../../Icon/IconHint'; |
|||
import {IconSolution} from '../../Icon/IconSolution'; |
|||
import {IconArrowSmall} from '../../Icon/IconArrowSmall'; |
|||
|
|||
interface ChallengeProps { |
|||
isRecipes?: boolean; |
|||
totalChallenges: number; |
|||
currentChallenge: ChallengeContents; |
|||
hasNextChallenge: boolean; |
|||
handleClickNextChallenge: () => void; |
|||
} |
|||
|
|||
export function Challenge({ |
|||
isRecipes, |
|||
totalChallenges, |
|||
currentChallenge, |
|||
hasNextChallenge, |
|||
handleClickNextChallenge, |
|||
}: ChallengeProps) { |
|||
const [showHint, setShowHint] = React.useState(false); |
|||
const [showSolution, setShowSolution] = React.useState(false); |
|||
|
|||
const toggleHint = () => { |
|||
if (showSolution && !showHint) { |
|||
setShowSolution(false); |
|||
} |
|||
setShowHint((hint) => !hint); |
|||
}; |
|||
|
|||
const toggleSolution = () => { |
|||
if (showHint && !showSolution) { |
|||
setShowHint(false); |
|||
} |
|||
setShowSolution((solution) => !solution); |
|||
}; |
|||
|
|||
return ( |
|||
<div className="p-5 sm:py-8 sm:px-8"> |
|||
<div> |
|||
<h3 className="text-xl text-primary dark:text-primary-dark mb-2"> |
|||
<div className="font-bold block md:inline"> |
|||
{isRecipes ? 'Example' : 'Challenge'} {currentChallenge.order} of{' '} |
|||
{totalChallenges} |
|||
<span className="text-primary dark:text-primary-dark">: </span> |
|||
</div> |
|||
{currentChallenge.name} |
|||
</h3> |
|||
{currentChallenge.content} |
|||
</div> |
|||
<div className="flex justify-between items-center mt-4"> |
|||
{currentChallenge.hint ? ( |
|||
<div> |
|||
<Button className="mr-2" onClick={toggleHint} active={showHint}> |
|||
<IconHint className="mr-1.5" />{' '} |
|||
{showHint ? 'Hide hint' : 'Show hint'} |
|||
</Button> |
|||
<Button |
|||
className="mr-2" |
|||
onClick={toggleSolution} |
|||
active={showSolution}> |
|||
<IconSolution className="mr-1.5" />{' '} |
|||
{showSolution ? 'Hide solution' : 'Show solution'} |
|||
</Button> |
|||
</div> |
|||
) : ( |
|||
!isRecipes && ( |
|||
<Button |
|||
className="mr-2" |
|||
onClick={toggleSolution} |
|||
active={showSolution}> |
|||
<IconSolution className="mr-1.5" />{' '} |
|||
{showSolution ? 'Hide solution' : 'Show solution'} |
|||
</Button> |
|||
) |
|||
)} |
|||
|
|||
{hasNextChallenge && ( |
|||
<Button |
|||
className={cn( |
|||
isRecipes |
|||
? 'bg-purple-50 border-purple-50 hover:bg-purple-50 focus:bg-purple-50 active:bg-purple-50' |
|||
: 'bg-link dark:bg-link-dark' |
|||
)} |
|||
onClick={handleClickNextChallenge} |
|||
active> |
|||
Next {isRecipes ? 'Example' : 'Challenge'} |
|||
<IconArrowSmall displayDirection="right" className="block ml-1.5" /> |
|||
</Button> |
|||
)} |
|||
</div> |
|||
{showHint && currentChallenge.hint} |
|||
|
|||
{showSolution && ( |
|||
<div className="mt-6"> |
|||
<h3 className="text-2xl font-bold text-primary dark:text-primary-dark"> |
|||
Solution |
|||
</h3> |
|||
{currentChallenge.solution} |
|||
<div className="flex justify-between items-center mt-4"> |
|||
<Button onClick={() => setShowSolution(false)}> |
|||
Close solution |
|||
</Button> |
|||
{hasNextChallenge && ( |
|||
<Button |
|||
className={cn( |
|||
isRecipes ? 'bg-purple-50' : 'bg-link dark:bg-link-dark' |
|||
)} |
|||
onClick={handleClickNextChallenge} |
|||
active> |
|||
Next Challenge |
|||
<IconArrowSmall |
|||
displayDirection="right" |
|||
className="block ml-1.5" |
|||
/> |
|||
</Button> |
|||
)} |
|||
</div> |
|||
</div> |
|||
)} |
|||
</div> |
|||
); |
|||
} |
Loading…
Reference in new issue