1- import { Link , useParams } from 'react-router-dom' ;
1+ import { Link } from 'react-router-dom' ;
22
33import { useMutation , useQuery } from '@apollo/client' ;
44import { useState } from 'preact/hooks' ;
@@ -9,12 +9,15 @@ import Loader from './components/Loader';
99import LoaderOverlay from './components/LoaderOverlay' ;
1010import { UserSelector } from './components/UserSelector' ;
1111import { formatDate , userIdentifier } from './helpers' ;
12+ import useAssertParams from './hooks/useAssertParams' ;
13+ import { useUnsubmittedAnswers } from './hooks/useUnsubmittedAnswers' ;
1214import { COMPLETE_QUIZ , QUIZ , QUIZ_AND_AVAILABLE_USERS , QUIZZES } from './queries/quiz' ;
15+ import { UnsubmittedAnswer } from './services/db' ;
1316import { Quiz } from './types/quiz' ;
1417import { User } from './types/user' ;
1518
1619export default function EnterQuizResults ( ) {
17- const { id } = useParams ( ) ;
20+ const { id } = useAssertParams ( ) ;
1821 const { loading, data } = useQuery < {
1922 quiz : Quiz ;
2023 users : { edges : { node : User } [ ] } ;
@@ -32,18 +35,33 @@ export default function EnterQuizResults() {
3235
3336 const { user : authenticatedUser } = useQuizlord ( ) ;
3437
35- async function handleSubmit ( score : number , participants : string [ ] ) {
38+ const { unsubmittedAnswers, currentTotalScore, handleScoresDeleted } = useUnsubmittedAnswers ( id ) ;
39+
40+ async function handleSubmit ( score : number , unsubmittedAnswers : UnsubmittedAnswer [ ] , participants : string [ ] ) {
3641 const participantsWithAuthenticatedUser = [ authenticatedUser ?. email , ...participants ] ;
42+ const questionResults = unsubmittedAnswers . map ( ( answer ) => ( {
43+ questionNum : answer . questionNumber ,
44+ score : answer . score ,
45+ } ) ) ;
3746 await completeQuiz ( {
38- variables : { quizId : id , completedBy : participantsWithAuthenticatedUser , score } ,
47+ variables : {
48+ quizId : id ,
49+ completedBy : participantsWithAuthenticatedUser ,
50+ score,
51+ questionResults,
52+ } ,
3953 } ) ;
54+ handleScoresDeleted ( ) ;
4055 setComplete ( true ) ;
4156 }
4257
43- const [ score , setScore ] = useState < number > ( 0 ) ;
58+ const [ manuallyEnteredScore , setManuallyEnteredTotalScore ] = useState < number > ( 0 ) ;
4459 const [ participants , setParticipants ] = useState < string [ ] > ( [ ] ) ;
4560 const [ complete , setComplete ] = useState ( false ) ;
4661
62+ const missingAnswers =
63+ unsubmittedAnswers . length > 0 && unsubmittedAnswers . length < ( data ?. quiz ?. questions ?. length || 0 ) ;
64+
4765 if ( ! data || loading ) {
4866 return < Loader message = 'Loading your quiz...' /> ;
4967 }
@@ -69,14 +87,31 @@ export default function EnterQuizResults() {
6987 Score
7088 </ label >
7189 < div className = 'mt-1' >
72- < input
73- type = 'number'
74- name = 'score'
75- autoComplete = 'quiz-score'
76- value = { score }
77- onChange = { ( e ) => setScore ( parseFloat ( ( e . target as HTMLInputElement ) . value ) ) }
78- className = 'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border border-gray-300 rounded-md'
79- />
90+ { unsubmittedAnswers . length > 0 ? (
91+ < div >
92+ < div > Calculated: { currentTotalScore } </ div >
93+ < Link to = { `/quiz/${ id } /question/1` } >
94+ < Button > Edit</ Button >
95+ </ Link >
96+ < Button warning onClick = { ( ) => handleScoresDeleted ( ) } >
97+ Delete & Override
98+ </ Button >
99+ </ div >
100+ ) : (
101+ < div >
102+ < input
103+ type = 'number'
104+ name = 'score'
105+ autoComplete = 'quiz-score'
106+ value = { manuallyEnteredScore }
107+ onChange = { ( e ) => setManuallyEnteredTotalScore ( parseFloat ( ( e . target as HTMLInputElement ) . value ) ) }
108+ className = 'shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border border-gray-300 rounded-md'
109+ />
110+ < Link to = { `/quiz/${ id } /question/1` } >
111+ < Button > Individual Entry</ Button >
112+ </ Link >
113+ </ div >
114+ ) }
80115 </ div >
81116 </ div >
82117 < div >
@@ -119,9 +154,26 @@ export default function EnterQuizResults() {
119154 Cancel
120155 </ Button >
121156 </ Link >
122- < Button onClick = { ( ) => handleSubmit ( score , participants ) } disabled = { isCompletingQuiz } >
157+ < Button
158+ onClick = { ( ) =>
159+ handleSubmit (
160+ unsubmittedAnswers . length > 0 ? currentTotalScore : manuallyEnteredScore ,
161+ unsubmittedAnswers ,
162+ participants ,
163+ )
164+ }
165+ disabled = { isCompletingQuiz || missingAnswers }
166+ >
123167 Submit Results
124168 </ Button >
169+ { missingAnswers && (
170+ < p className = 'mt-2 text-sm text-red-600 font-medium' >
171+ Questions results have been only partially entered.
172+ < br />
173+ Please either press "Edit" above and complete the remaining questions, or press "Delete &
174+ Override & quot ; above and manually enter your score .
175+ </ p >
176+ ) }
125177 </ div >
126178 ) }
127179 </ div >
0 commit comments