11import { useEffect , useReducer } from 'react'
2+ import ErrorMsg from './ErrorMsg'
3+ import FinishScreen from './FinishScreen'
4+ import Footer from './Footer'
25import Header from './Header'
3- import Main from './Main'
46import Loader from './Loader'
5- import Error from './Error'
6- import StartScreen from './StartScreen'
7+ import Main from './Main'
8+ import NextButton from './NextButton'
9+ import Progress from './Progress'
710import Question from './Question'
11+ import StartScreen from './StartScreen'
12+ import Timer from './Timer'
13+
14+ const SEC_PER_QUESTION = 5
815
916const initialState = {
1017 questions : [ ] ,
@@ -14,6 +21,8 @@ const initialState = {
1421 index : 0 ,
1522 answer : null ,
1623 points : 0 ,
24+ highscore : 0 ,
25+ secondsRemaining : null ,
1726}
1827
1928function reducer ( state , action ) {
@@ -33,6 +42,7 @@ function reducer(state, action) {
3342 return {
3443 ...state ,
3544 status : 'active' ,
45+ secondsRemaining : state . questions . length * SEC_PER_QUESTION ,
3646 }
3747 case 'newAnswer' :
3848 const question = state . questions [ state . index ]
@@ -47,22 +57,65 @@ function reducer(state, action) {
4757 ? state . points + question . points
4858 : state . points ,
4959 }
60+ case 'nextQuestion' :
61+ return {
62+ ...state ,
63+ index : state . index + 1 ,
64+ answer : null ,
65+ }
66+ case 'finish' :
67+ return {
68+ ...state ,
69+ status : 'finished' ,
70+ highscore :
71+ state . points > state . highscore
72+ ? state . points
73+ : state . highscore ,
74+ }
75+ case 'restart' :
76+ return {
77+ ...initialState ,
78+ status : 'ready' ,
79+ questions : state . questions ,
80+ highscore : state . highscore ,
81+ }
82+ case 'tick' :
83+ return {
84+ ...state ,
85+ secondsRemaining : state . secondsRemaining - 1 ,
86+ status :
87+ state . secondsRemaining - 1 <= 0 ? 'finished' : state . status ,
88+ }
5089 default :
51- throw new Error ( `Invalid action ${ action . type } ` )
90+ throw new Error ( `Invalid action " ${ action . type } " ` )
5291 }
5392}
5493
5594function App ( ) {
56- const [ { questions, status, index, answer, points } , dispatch ] = useReducer (
57- reducer ,
58- initialState ,
59- )
95+ const [
96+ {
97+ questions,
98+ status,
99+ index,
100+ answer,
101+ points,
102+ highscore,
103+ secondsRemaining,
104+ } ,
105+ dispatch ,
106+ ] = useReducer ( reducer , initialState )
60107 const numQuestions = questions . length
108+ const totalPoints = questions . reduce ( ( prev , { points } ) => prev + points , 0 )
61109
62110 useEffect ( ( ) => {
63111 fetch ( 'http://localhost:8000/questions' )
64112 . then ( ( res ) => res . json ( ) )
65- . then ( ( data ) => dispatch ( { type : 'dataReceived' , payload : data } ) )
113+ . then ( ( data ) =>
114+ dispatch ( {
115+ type : 'dataReceived' ,
116+ payload : data ,
117+ } ) ,
118+ )
66119 . catch ( ( err ) => dispatch ( { type : 'dataFailed' } ) )
67120 } , [ ] )
68121
@@ -71,18 +124,47 @@ function App() {
71124 < Header />
72125 < Main >
73126 { status === 'loading' && < Loader /> }
74- { status === 'error' && < Error /> }
127+ { status === 'error' && < ErrorMsg /> }
75128 { status === 'ready' && (
76129 < StartScreen
77130 numQuestions = { numQuestions }
78131 dispatch = { dispatch }
79132 />
80133 ) }
81134 { status === 'active' && (
82- < Question
83- question = { questions [ index ] }
135+ < >
136+ < Progress
137+ index = { index }
138+ numQuestions = { numQuestions }
139+ points = { points }
140+ totalPoints = { totalPoints }
141+ answer = { answer }
142+ />
143+ < Question
144+ question = { questions [ index ] }
145+ dispatch = { dispatch }
146+ answer = { answer }
147+ />
148+ < Footer >
149+ < Timer
150+ secondsRemaining = { secondsRemaining }
151+ dispatch = { dispatch }
152+ />
153+ < NextButton
154+ dispatch = { dispatch }
155+ answer = { answer }
156+ index = { index }
157+ numQuestions = { numQuestions }
158+ />
159+ </ Footer >
160+ </ >
161+ ) }
162+ { status === 'finished' && (
163+ < FinishScreen
164+ points = { points }
165+ totalPoints = { totalPoints }
166+ highscore = { highscore }
84167 dispatch = { dispatch }
85- answer = { answer }
86168 />
87169 ) }
88170 </ Main >
0 commit comments