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
← All changes | assets/src/apps/js/frontend/single-course.js +99 -49 4.1.7 → 4.4.9 View file →
@@ -1,9 +1,14 @@
1 1 import SingleCourse from './single-course/index';
2 -import { addQueryArgs } from '@wordpress/url';
3 2 import lpModalOverlayCompleteItem from './show-lp-overlay-complete-item';
4 3 import lpModalOverlay from '../utils/lp-modal-overlay';
5 4 import courseCurriculumSkeleton from './single-curriculum/skeleton';
5 +import lpMaterialsLoad from './material';
6 +import TabsDragScroll from './tabs-scroll';
7 +import { lpSetLoadingEl } from '../../../js/utils.js';
8 +import Toastify from 'toastify-js';
9 +import 'toastify-js/src/toastify.css';
10 +import LPCopyToClipboard from '../../../js/frontend/copy-to-clipboard.js';
6 11
7 12 export default SingleCourse;
8 13
9 14 export const init = () => {
@@ -74,8 +79,10 @@
74 79
75 80 if ( formEnrolls.length > 0 ) {
76 81 formEnrolls.forEach( ( formEnroll ) => {
77 82 const submit = async ( id, btnEnroll ) => {
83 + const status = 'error';
84 +
78 85 try {
79 86 const response = await wp.apiFetch( {
80 87 path: 'lp/v1/courses/enroll-course',
81 88 method: 'POST',
@@ -81,23 +88,33 @@
81 88 method: 'POST',
82 89 data: { id },
83 90 } );
84 91
85 - btnEnroll.classList.remove( 'loading' );
86 - btnEnroll.disabled = false;
92 + const { status, data: { redirect }, message } = response;
87 93
88 - const { status, data: { redirect }, message } = response;
94 + if ( status === 'success' ) {
95 + btnEnroll.remove();
96 + } else {
97 + lpSetLoadingEl( btnEnroll, 0 );
98 + throw new Error( message );
99 + }
89 100
90 101 if ( message && status ) {
91 - btnEnroll.style.display = 'none';
92 - formEnroll.innerHTML += `<div class="lp-enroll-notice ${ status }">${ message }</div>`;
93 -
102 + formEnroll.innerHTML += `<div class="learn-press-message ${ status }">${ message }</div>`;
94 103 if ( redirect ) {
95 104 window.location.href = redirect;
96 105 }
97 106 }
98 107 } catch ( error ) {
99 - form.innerHTML += `<div class="lp-enroll-notice error">${ error.message && error.message }</div>`;
108 + Toastify( {
109 + text: error.message,
110 + gravity: lpData.toast.gravity, // `top` or `bottom`
111 + position: lpData.toast.position, // `left`, `center` or `right`
112 + className: `${ lpData.toast.classPrefix } ${ status }`,
113 + close: lpData.toast.close == 1,
114 + stopOnFocus: lpData.toast.stopOnFocus == 1,
115 + duration: lpData.toast.duration,
116 + } ).showToast();
100 117 }
101 118 };
102 119
103 120 formEnroll.addEventListener( 'submit', ( event ) => {
@@ -103,10 +120,9 @@
103 120 formEnroll.addEventListener( 'submit', ( event ) => {
104 121 event.preventDefault();
105 122 const id = formEnroll.querySelector( 'input[name=enroll-course]' ).value;
106 123 const btnEnroll = formEnroll.querySelector( 'button.button-enroll-course' );
107 - btnEnroll.classList.add( 'loading' );
108 - btnEnroll.disabled = true;
124 + lpSetLoadingEl( btnEnroll, 1 );
109 125 submit( id, btnEnroll );
110 126 } );
111 127 } );
112 128 }
@@ -129,9 +145,9 @@
129 145 if ( forms.length > 0 ) {
130 146 forms.forEach( ( form ) => {
131 147 // Allow Repurchase.
132 148 const allowRepurchase = () => {
133 - const continueRepurchases = document.querySelectorAll( '.lp_allow_repuchase_select' );
149 + const continueRepurchases = document.querySelectorAll( '.lp_allow_repurchase_select' );
134 150
135 151 continueRepurchases.forEach( ( repurchase ) => {
136 152 const radios = repurchase.querySelectorAll( '[name=_lp_allow_repurchase_type]' );
137 153
@@ -139,13 +155,12 @@
139 155 if ( radios[ i ].checked ) {
140 156 const repurchaseType = radios[ i ].value;
141 157 const id = form.querySelector( 'input[name=purchase-course]' ).value;
142 158
143 - const btnBuynow = form.querySelector( 'button.button-purchase-course' );
144 - btnBuynow.classList.add( 'loading' );
145 - btnBuynow.disabled = true;
159 + const btnBuyNow = form.querySelector( 'button.button-purchase-course' );
160 + lpSetLoadingEl( btnBuyNow, 1 );
146 161
147 - submit( id, btnBuynow, repurchaseType );
162 + submit( id, btnBuyNow, repurchaseType );
148 163 break;
149 164 }
150 165 }
151 166 } );
@@ -151,24 +166,42 @@
151 166 } );
152 167 };
153 168
154 169 const submit = async ( id, btn, repurchaseType = false ) => {
170 + const status = 'error';
171 +
155 172 try {
173 + const formData = new FormData( form );
174 + const dataSend = Object.fromEntries( Array.from( formData.keys(), ( key ) => {
175 + const val = formData.getAll( key );
176 +
177 + return [ key, val.length > 1 ? val : val.pop() ];
178 + } ) );
179 +
180 + dataSend.id = id;
181 + dataSend.repurchaseType = repurchaseType;
182 +
156 183 const response = await wp.apiFetch( {
157 184 path: 'lp/v1/courses/purchase-course',
158 185 method: 'POST',
159 - data: { id, repurchaseType },
186 + data: dataSend,
160 187 } );
161 188
162 - if ( btn ) {
163 - btn.classList.remove( 'loading' );
164 - btn.disabled = false;
189 + const { status, data: { redirect, type, html, titlePopup }, message } = response;
190 +
191 + if ( status === 'success' ) {
192 + if ( type === 'allow_repurchase' ) {
193 + lpSetLoadingEl( btn, 0 );
194 + } else {
195 + btn.remove();
196 + }
197 + } else {
198 + lpSetLoadingEl( btn, 0 );
199 + throw new Error( message );
165 200 }
166 201
167 - const { status, data: { redirect, type, html, titlePopup }, message } = response;
168 -
169 202 if ( type === 'allow_repurchase' && status === 'success' ) {
170 - if ( ! form.querySelector( '.lp_allow_repuchase_select' ) ) {
203 + if ( ! form.querySelector( '.lp_allow_repurchase_select' ) ) {
171 204 if ( ! lpModalOverlay.init() ) {
172 205 return;
173 206 }
174 207
@@ -184,9 +217,9 @@
184 217 allowRepurchase();
185 218 };
186 219 }
187 220 } else if ( message && status ) {
188 - form.innerHTML += `<div class="lp-enroll-notice ${ status }">${ message }</div>`;
221 + form.innerHTML += `<div class="learn-press-message ${ status }">${ message }</div>`;
189 222
190 223 if ( 'success' === status && redirect ) {
191 224 window.location.href = redirect;
192 225 }
@@ -191,9 +224,17 @@
191 224 window.location.href = redirect;
192 225 }
193 226 }
194 227 } catch ( error ) {
195 - form.innerHTML += `<div class="lp-enroll-notice error">${ error.message && error.message }</div>`;
228 + Toastify( {
229 + text: error.message,
230 + gravity: lpData.toast.gravity, // `top` or `bottom`
231 + position: lpData.toast.position, // `left`, `center` or `right`
232 + className: `${ lpData.toast.classPrefix } ${ status }`,
233 + close: lpData.toast.close == 1,
234 + stopOnFocus: lpData.toast.stopOnFocus == 1,
235 + duration: lpData.toast.duration,
236 + } ).showToast();
196 237 }
197 238 };
198 239
199 240 form.addEventListener( 'submit', ( event ) => {
@@ -199,11 +240,9 @@
199 240 form.addEventListener( 'submit', ( event ) => {
200 241 event.preventDefault();
201 242 const id = form.querySelector( 'input[name=purchase-course]' ).value;
202 243 const btn = form.querySelector( 'button.button-purchase-course' );
203 - btn.classList.add( 'loading' );
204 - btn.disabled = true;
205 -
244 + lpSetLoadingEl( btn, 1 );
206 245 submit( id, btn );
207 246 } );
208 247 } );
209 248 }
@@ -239,9 +278,9 @@
239 278 }
240 279 } ).catch( ( err ) => {
241 280 elAjaxMessage.classList.add( 'error' );
242 281 elAjaxMessage.innerHTML = 'error: ' + err.message;
243 - } ).then( ( ) => {
282 + } ).then( () => {
244 283 elButtonRetakeCourse.classList.remove( 'loading' );
245 284 elButtonRetakeCourse.disabled = false;
246 285 elAjaxMessage.style.display = 'block';
247 286 } );
@@ -263,9 +302,9 @@
263 302 } );
264 303 };
265 304
266 305 // Rest API load content course progress - Nhamdv.
267 -const courseProgress = () => {
306 +/*const courseProgress = () => {
268 307 const elements = document.querySelectorAll( '.lp-course-progress-wrapper' );
269 308
270 309 if ( ! elements.length ) {
271 310 return;
@@ -289,14 +328,19 @@
289 328 [ ...elements ].map( ( ele ) => eleObserver.observe( ele ) );
290 329 }
291 330
292 331 const getResponse = async ( ele ) => {
332 + let url = 'lp/v1/lazy-load/course-progress';
333 + if ( lpData.urlParams.hasOwnProperty( 'lang' ) ) {
334 + url += '?lang=' + lpData.urlParams.lang;
335 + }
336 +
293 337 const response = await wp.apiFetch( {
294 - path: 'lp/v1/lazy-load/course-progress',
338 + path: url,
295 339 method: 'POST',
296 340 data: {
297 341 courseId: lpGlobalSettings.post_id || '',
298 - userId: lpGlobalSettings.user_id || '',
342 + userId: lpData.user_id || '',
299 343 },
300 344 } );
301 345
302 346 const { data } = response;
@@ -302,31 +346,34 @@
302 346 const { data } = response;
303 347
304 348 ele.innerHTML = data;
305 349 };
306 -};
350 +};*/
307 351
308 352 const accordionExtraTab = () => {
309 353 const elements = document.querySelectorAll( '.course-extra-box' );
310 -
311 354 [ ...elements ].map( ( ele ) => {
312 355 const title = ele.querySelector( '.course-extra-box__title' );
356 + ele.classList.remove( 'active' );
357 + const content = ele.querySelector( '.course-extra-box__content' );
358 + content.style.height = '0';
313 359
314 360 title.addEventListener( 'click', () => {
315 - const panel = title.nextElementSibling;
316 - const eleActive = document.querySelector( '.course-extra-box.active' );
361 + const isActive = ele.classList.contains( 'active' );
317 362
318 - if ( eleActive && ! ele.classList.contains( 'active' ) ) {
319 - eleActive.classList.remove( 'active' );
320 - eleActive.querySelector( '.course-extra-box__content' ).style.display = 'none';
321 - }
363 + [ ...elements ].forEach( ( otherEle ) => {
364 + if ( otherEle !== ele ) {
365 + otherEle.classList.remove( 'active' );
366 + otherEle.querySelector( '.course-extra-box__content' ).style.height = '0';
367 + }
368 + } );
322 369
323 - if ( ! ele.classList.contains( 'active' ) ) {
370 + if ( isActive ) {
371 + ele.classList.remove( 'active' );
372 + content.style.height = '0';
373 + } else {
324 374 ele.classList.add( 'active' );
325 - panel.style.display = 'block';
326 - } else {
327 - ele.classList.remove( 'active' );
328 - panel.style.display = 'none';
375 + content.style.height = content.scrollHeight + 'px';
329 376 }
330 377 } );
331 378 } );
332 379 };
@@ -332,10 +379,9 @@
332 379 };
333 380
334 381 const courseContinue = () => {
335 382 const formContinue = document.querySelectorAll( 'form.continue-course' );
336 -
337 - if ( formContinue != null && lpGlobalSettings.user_id > 0 ) {
383 + if ( formContinue.length && lpData.user_id > 0 ) {
338 384 const getResponse = async ( ele ) => {
339 385 const response = await wp.apiFetch( {
340 386 path: 'lp/v1/courses/continue-course',
341 387 method: 'POST',
@@ -350,9 +396,9 @@
350 396
351 397 getResponse( formContinue ).then( function( result ) {
352 398 if ( result.status === 'success' ) {
353 399 formContinue.forEach( ( form ) => {
354 - form.style.display = 'block';
400 + form.style.display = 'inline-block';
355 401 form.action = result.data;
356 402 } );
357 403 }
358 404 } );
@@ -364,9 +410,9 @@
364 410 initCourseSidebar,
365 411 enrollCourse,
366 412 };
367 413
368 -$( window ).on( 'load', () => {
414 +document.addEventListener( 'DOMContentLoaded', function() {
369 415 const $popup = $( '#popup-course' );
370 416 let timerClearScroll;
371 417 const $curriculum = $( '#learn-press-course-curriculum' );
372 418 accordionExtraTab();
@@ -374,12 +420,15 @@
374 420 initCourseSidebar();
375 421 enrollCourse();
376 422 purchaseCourse();
377 423 retakeCourse();
378 - courseProgress();
424 + //courseProgress();
379 425 courseContinue();
380 426 lpModalOverlayCompleteItem.init();
427 + lpMaterialsLoad();
381 428 //courseCurriculumSkeleton();
429 + TabsDragScroll();
430 + LPCopyToClipboard();
382 431 } );
383 432
384 433 const detectedElCurriculum = setInterval( function() {
385 434 const elementCurriculum = document.querySelector( '.learnpress-course-curriculum' );
@@ -384,8 +433,9 @@
384 433 const detectedElCurriculum = setInterval( function() {
385 434 const elementCurriculum = document.querySelector( '.learnpress-course-curriculum' );
386 435 if ( elementCurriculum ) {
387 436 courseCurriculumSkeleton();
437 +
388 438 clearInterval( detectedElCurriculum );
389 439 }
390 440 }, 1 );
391 441