PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 All 140 releases
learnpress / assets / src / apps / js / frontend / quiz / components / result / index.js

index.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.9, at assets/src/apps/js/frontend/quiz/components/result/index.js

282 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Quizz Result.
3 * Edit: Use React hook.
4 *
5 * @author Nhamdv - ThimPress
6 */
7 import { useState, useEffect } from '@wordpress/element';
8 import { useSelect } from '@wordpress/data';
9 import { __ } from '@wordpress/i18n';
10
11 import { getResponse } from '../../../single-curriculum/components/items-progress';
12
13 const { debounce } = lodash;
14 const Result = () => {
15 const [ percentage, setPercentage ] = useState( 0 );
16 const [ done, setDone ] = useState( false );
17 const QuizID = useSelect( ( select ) => {
18 return select( 'learnpress/quiz' ).getData( 'id' );
19 }, [] );
20 const results = useSelect( ( select ) => {
21 return select( 'learnpress/quiz' ).getData( 'results' );
22 }, [] );
23
24 const passingGrade = useSelect( ( select ) => {
25 return select( 'learnpress/quiz' ).getData( 'passingGrade' );
26 }, [] );
27
28 const submitting = useSelect( ( select ) => {
29 return select( 'learnpress/quiz' ).getData( 'submitting' );
30 }, [] );
31
32 useEffect( () => {
33 animate();
34
35 let graduation = '';
36 if ( results.graduation ) {
37 graduation = results.graduation;
38 } else if ( results.result >= passingGradeValue ) {
39 graduation = 'passed';
40 } else {
41 graduation = 'failed';
42 }
43
44 if ( graduation ) {
45 const ele = document.querySelector( `.course-curriculum .course-item.course-item-${ QuizID }` );
46
47 if ( ele ) {
48 ele.classList.remove( 'failed', 'passed' );
49 ele.classList.add( 'has-status', 'status-completed', graduation );
50 }
51 }
52
53 const item = [ ...document.querySelectorAll( '#popup-header .items-progress' ) ][ 0 ];
54 if ( item ) {
55 const totalItems = item.dataset.totalItems;
56
57 const itemCompleted = item.querySelector( '.items-completed' );
58 const elProgress = item.querySelector( '.learn-press-progress__active' );
59
60 if ( itemCompleted ) {
61 // const number = parseInt( itemCompleted.textContent );
62
63 const allItemCompleted = document.querySelectorAll( '#popup-sidebar .course-curriculum .course-item__status .completed' );
64
65 itemCompleted.textContent = parseInt( allItemCompleted.length );
66
67 // Set progress
68 const perCent = parseInt( allItemCompleted.length ) * 100 / parseInt( totalItems );
69 const percentSet = 100 - perCent;
70
71 elProgress.style.left = '-' + percentSet + '%';
72 }
73 }
74 }, [ results ] );
75
76 useEffect( () => {
77 if ( submitting !== undefined ) {
78 updateItemsProgress();
79 }
80 }, [ submitting ] );
81
82 const updateItemsProgress = () => {
83 const elements = document.querySelectorAll( '.popup-header__inner' );
84
85 if ( elements.length > 0 && elements[ 0 ].querySelectorAll( 'form.form-button-finish-course' ).length === 0 ) {
86 getResponse( elements[ 0 ] );
87 }
88 };
89
90 const animate = () => {
91 setPercentage( 0 );
92 setDone( false );
93
94 jQuery.easing._customEasing = function( e, f, a, h, g ) {
95 return ( h * Math.sqrt( 1 - ( ( f = ( f / g ) - 1 ) * f ) ) ) + a;
96 };
97
98 debounce( () => {
99 const $el = jQuery( '<span />' ).css( {
100 width: 1,
101 height: 1,
102 } ).appendTo( document.body );
103
104 $el.css( 'left', 0 ).animate( { left: results.result }, {
105 duration: 1500,
106 step: ( now, fx ) => {
107 setPercentage( now );
108 },
109 done: () => {
110 setDone( true );
111 $el.remove();
112
113 jQuery( '#quizResultGrade' ).css( {
114 transform: 'scale(1.3)',
115 transition: 'all 0.25s',
116 } );
117
118 debounce( () => {
119 jQuery( '#quizResultGrade' ).css( {
120 transform: 'scale(1)',
121 } );
122 }, 500 )();
123 },
124 easing: '_customEasing',
125 } );
126 }, results.result > 0 ? 1000 : 10 )();
127 };
128
129 /**
130 * Render HTML elements.
131 *
132 */
133
134 let percentResult = percentage;
135
136 if ( ! Number.isInteger( percentage ) ) {
137 percentResult = parseFloat( percentage ).toFixed( 2 );
138 }
139
140 const border = 10;
141 const width = 200;
142 const radius = width / 2;
143 const r = ( width - border ) / 2;
144 const circumference = r * 2 * Math.PI;
145 const offset = circumference - ( percentResult / 100 * circumference );
146 const styles = {
147 strokeDasharray: `${ circumference } ${ circumference }`,
148 strokeDashoffset: offset,
149 };
150 const passingGradeValue = parseFloat( results.passingGrade || passingGrade );
151
152 let graduation = '';
153 if ( results.graduation ) {
154 graduation = results.graduation;
155 } else if ( percentResult >= passingGradeValue ) {
156 graduation = 'passed';
157 } else {
158 graduation = 'failed';
159 }
160
161 let message = '';
162 if ( results.graduationText ) {
163 message = results.graduationText;
164 } else if ( graduation === 'passed' ) {
165 message = __( 'Passed', 'learnpress' );
166 } else {
167 message = __( 'Failed', 'learnpress' );
168 }
169
170 const classNames = [ 'quiz-result', graduation ];
171
172 return (
173 <div className={ classNames.join( ' ' ) }>
174 <h3 className="result-heading">{ __( 'Your Result', 'learnpress' ) }</h3>
175
176 <div id="quizResultGrade" className="result-grade">
177 <svg className="circle-progress-bar" width={ width } height={ width }>
178 <circle className="circle-progress-bar__circle" stroke="" strokeWidth={ border } style={ styles }
179 fill="transparent" r={ r } cx={ radius } cy={ radius }></circle>
180 </svg>
181
182 <span className="result-achieved">{ `${ percentResult }%` }</span>
183 <span className="result-require">
184 { passingGradeValue + '%' || '-' }
185 </span>
186 </div>
187
188 { done && <p className="result-message">{ message }</p> }
189
190 <ul className="result-statistic">
191 <li className="result-statistic-field result-time-spend">
192 <span>{ __( 'Time spent', 'learnpress' ) }</span>
193 <p>{ results.timeSpend }</p>
194 </li>
195 <li className="result-statistic-field result-point">
196 <span>{ __( 'Points', 'learnpress' ) }</span>
197 <p>{ results.userMark } / { results.mark }</p>
198 </li>
199 <li className="result-statistic-field result-questions">
200 <span>{ __( 'Questions', 'learnpress' ) }</span>
201 <p>{ results.questionCount }</p>
202 </li>
203 <li className="result-statistic-field result-questions-correct">
204 <span>{ __( 'Correct', 'learnpress' ) }</span>
205 <p>{ results.questionCorrect }</p>
206 </li>
207 <li className="result-statistic-field result-questions-wrong">
208 <span>{ __( 'Wrong', 'learnpress' ) }</span>
209 <p>{ results.questionWrong }</p>
210 </li>
211 <li className="result-statistic-field result-questions-skipped">
212 <span>{ __( 'Skipped', 'learnpress' ) }</span>
213 <p>{ results.questionEmpty }</p>
214 </li>
215 { typeof results.minusPoint !== 'undefined' && (
216 <li className="result-statistic-field result-questions-minus">
217 <span>{ __( 'Minus points', 'learnpress' ) }</span>
218 <p>{ results.minusPoint }</p>
219 </li>
220 ) }
221 </ul>
222 </div>
223 );
224
225 function timeDifference( earlierDate, laterDate ) {
226 const oDiff = new Object();
227
228 // Calculate Differences
229 // ------------------------------------------------------------------- //
230 let nTotalDiff = laterDate - earlierDate;
231
232 oDiff.days = Math.floor( nTotalDiff / 1000 / 60 / 60 / 24 );
233 nTotalDiff -= oDiff.days * 1000 * 60 * 60 * 24;
234
235 oDiff.hours = Math.floor( nTotalDiff / 1000 / 60 / 60 );
236 nTotalDiff -= oDiff.hours * 1000 * 60 * 60;
237
238 oDiff.minutes = Math.floor( nTotalDiff / 1000 / 60 );
239 nTotalDiff -= oDiff.minutes * 1000 * 60;
240
241 oDiff.seconds = Math.floor( nTotalDiff / 1000 );
242 // ------------------------------------------------------------------- //
243
244 // Format Duration
245 // ------------------------------------------------------------------- //
246 // Format Hours
247 let hourtext = '00';
248 if ( oDiff.days > 0 ) {
249 hourtext = String( oDiff.days );
250 }
251 if ( hourtext.length == 1 ) {
252 hourtext = '0' + hourtext;
253 }
254
255 // Format Minutes
256 let mintext = '00';
257 if ( oDiff.minutes > 0 ) {
258 mintext = String( oDiff.minutes );
259 }
260 if ( mintext.length == 1 ) {
261 mintext = '0' + mintext;
262 }
263
264 // Format Seconds
265 let sectext = '00';
266 if ( oDiff.seconds > 0 ) {
267 sectext = String( oDiff.seconds );
268 }
269 if ( sectext.length == 1 ) {
270 sectext = '0' + sectext;
271 }
272 // Set Duration
273 const sDuration = hourtext + ':' + mintext + ':' + sectext;
274 oDiff.duration = sDuration;
275 // ------------------------------------------------------------------- //
276
277 return oDiff;
278 }
279 };
280
281 export default Result;
282