PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.6.9.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.6.9.2
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 4.2.0 All 139 releases
learnpress / assets / src / apps / js / frontend / single-course.js

single-course.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.6.9.2, at assets/src/apps/js/frontend/single-course.js

386 lines 10.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import SingleCourse from './single-course/index';
2 import { addQueryArgs } from '@wordpress/url';
3 import lpModalOverlayCompleteItem from './show-lp-overlay-complete-item';
4 import lpModalOverlay from '../utils/lp-modal-overlay';
5 import courseCurriculumSkeleton from './single-curriculum/skeleton';
6
7 export default SingleCourse;
8
9 export const init = () => {
10 wp.element.render(
11 <SingleCourse />,
12 );
13 };
14
15 const $ = jQuery;
16
17 const initCourseTabs = function() {
18 $( '#learn-press-course-tabs' ).on(
19 'change',
20 'input[name="learn-press-course-tab-radio"]',
21 function( e ) {
22 const selectedTab = $( 'input[name="learn-press-course-tab-radio"]:checked' ).val();
23
24 LP.Cookies.set( 'course-tab', selectedTab );
25
26 $( 'label[for="' + $( e.target ).attr( 'id' ) + '"]' ).closest( 'li' ).addClass( 'active' ).siblings().removeClass( 'active' );
27 }
28 );
29 };
30
31 const initCourseSidebar = function initCourseSidebar() {
32 const $sidebar = $( '.course-summary-sidebar' );
33
34 if ( ! $sidebar.length ) {
35 return;
36 }
37
38 const $window = $( window );
39 const $scrollable = $sidebar.children();
40 const offset = $sidebar.offset();
41 let scrollTop = 0;
42 const maxHeight = $sidebar.height();
43 const scrollHeight = $scrollable.height();
44 const options = {
45 offsetTop: 32,
46 };
47
48 const onScroll = function() {
49 scrollTop = $window.scrollTop();
50
51 const top = scrollTop - offset.top + options.offsetTop;
52
53 if ( top < 0 ) {
54 $sidebar.removeClass( 'slide-top slide-down' );
55 $scrollable.css( 'top', '' );
56 return;
57 }
58
59 if ( top > maxHeight - scrollHeight ) {
60 $sidebar.removeClass( 'slide-down' ).addClass( 'slide-top' );
61 $scrollable.css( 'top', maxHeight - scrollHeight );
62 } else {
63 $sidebar.removeClass( 'slide-top' ).addClass( 'slide-down' );
64 $scrollable.css( 'top', options.offsetTop );
65 }
66 };
67
68 $window.on( 'scroll.fixed-course-sidebar', onScroll ).trigger( 'scroll.fixed-course-sidebar' );
69 };
70
71 // Rest API Enroll course - Nhamdv.
72 const enrollCourse = () => {
73 const formEnrolls = document.querySelectorAll( 'form.enroll-course' );
74
75 if ( formEnrolls.length > 0 ) {
76 formEnrolls.forEach( ( formEnroll ) => {
77 const submit = async ( id, btnEnroll ) => {
78 try {
79 const response = await wp.apiFetch( {
80 path: 'lp/v1/courses/enroll-course',
81 method: 'POST',
82 data: { id },
83 } );
84
85 btnEnroll.classList.remove( 'loading' );
86 btnEnroll.disabled = false;
87
88 const { status, data: { redirect }, message } = response;
89
90 if ( message && status ) {
91 btnEnroll.style.display = 'none';
92 formEnroll.innerHTML += `<div class="lp-enroll-notice ${ status }">${ message }</div>`;
93
94 if ( redirect ) {
95 window.location.href = redirect;
96 }
97 }
98 } catch ( error ) {
99 form.innerHTML += `<div class="lp-enroll-notice error">${ error.message && error.message }</div>`;
100 }
101 };
102
103 formEnroll.addEventListener( 'submit', ( event ) => {
104 event.preventDefault();
105 const id = formEnroll.querySelector( 'input[name=enroll-course]' ).value;
106 const btnEnroll = formEnroll.querySelector( 'button.button-enroll-course' );
107 btnEnroll.classList.add( 'loading' );
108 btnEnroll.disabled = true;
109 submit( id, btnEnroll );
110 } );
111 } );
112 }
113
114 // Reload when press back button in chrome.
115 if ( document.querySelector( '.course-detail-info' ) !== null ) {
116 window.addEventListener( 'pageshow', ( event ) => {
117 const hasCache = event.persisted || ( typeof window.performance != 'undefined' && String( window.performance.getEntriesByType( 'navigation' )[ 0 ].type ) == 'back_forward' );
118 if ( hasCache ) {
119 location.reload();
120 }
121 } );
122 }
123 };
124
125 // Rest API purchase course - Nhamdv.
126 const purchaseCourse = () => {
127 const forms = document.querySelectorAll( 'form.purchase-course' );
128
129 if ( forms.length > 0 ) {
130 forms.forEach( ( form ) => {
131 // Allow Repurchase.
132 const allowRepurchase = () => {
133 const continueRepurchases = document.querySelectorAll( '.lp_allow_repuchase_select' );
134
135 continueRepurchases.forEach( ( repurchase ) => {
136 const radios = repurchase.querySelectorAll( '[name=_lp_allow_repurchase_type]' );
137
138 for ( let i = 0, length = radios.length; i < length; i++ ) {
139 if ( radios[ i ].checked ) {
140 const repurchaseType = radios[ i ].value;
141 const id = form.querySelector( 'input[name=purchase-course]' ).value;
142
143 const btnBuynow = form.querySelector( 'button.button-purchase-course' );
144 btnBuynow.classList.add( 'loading' );
145 btnBuynow.disabled = true;
146
147 submit( id, btnBuynow, repurchaseType );
148 break;
149 }
150 }
151 } );
152 };
153
154 const submit = async ( id, btn, repurchaseType = false ) => {
155 try {
156 const response = await wp.apiFetch( {
157 path: 'lp/v1/courses/purchase-course',
158 method: 'POST',
159 data: { id, repurchaseType },
160 } );
161
162 if ( btn ) {
163 btn.classList.remove( 'loading' );
164 btn.disabled = false;
165 }
166
167 const { status, data: { redirect, type, html, titlePopup }, message } = response;
168
169 if ( type === 'allow_repurchase' && status === 'success' ) {
170 if ( ! form.querySelector( '.lp_allow_repuchase_select' ) ) {
171 if ( ! lpModalOverlay.init() ) {
172 return;
173 }
174
175 lpModalOverlay.elLPOverlay.show();
176
177 lpModalOverlay.setTitleModal( titlePopup || '' );
178
179 lpModalOverlay.setContentModal( html );
180
181 lpModalOverlay.callBackYes = () => {
182 lpModalOverlay.elLPOverlay.hide();
183
184 allowRepurchase();
185 };
186 }
187 } else if ( message && status ) {
188 form.innerHTML += `<div class="lp-enroll-notice ${ status }">${ message }</div>`;
189
190 if ( 'success' === status && redirect ) {
191 window.location.href = redirect;
192 }
193 }
194 } catch ( error ) {
195 form.innerHTML += `<div class="lp-enroll-notice error">${ error.message && error.message }</div>`;
196 }
197 };
198
199 form.addEventListener( 'submit', ( event ) => {
200 event.preventDefault();
201 const id = form.querySelector( 'input[name=purchase-course]' ).value;
202 const btn = form.querySelector( 'button.button-purchase-course' );
203 btn.classList.add( 'loading' );
204 btn.disabled = true;
205
206 submit( id, btn );
207 } );
208 } );
209 }
210 };
211
212 const retakeCourse = () => {
213 const elFormRetakeCourses = document.querySelectorAll( '.lp-form-retake-course' );
214
215 if ( ! elFormRetakeCourses.length ) {
216 return;
217 }
218
219 elFormRetakeCourses.forEach( ( elFormRetakeCourse ) => {
220 const elButtonRetakeCourses = elFormRetakeCourse.querySelector( '.button-retake-course' );
221 const elCourseId = elFormRetakeCourse.querySelector( '[name=retake-course]' ).value;
222 const elAjaxMessage = elFormRetakeCourse.querySelector( '.lp-ajax-message' );
223 const submit = ( elButtonRetakeCourse ) => {
224 wp.apiFetch( {
225 path: '/lp/v1/courses/retake-course',
226 method: 'POST',
227 data: { id: elCourseId },
228 } ).then( ( res ) => {
229 const { status, message, data } = res;
230 elAjaxMessage.innerHTML = message;
231
232 if ( undefined != status && status === 'success' ) {
233 elButtonRetakeCourse.style.display = 'none';
234 setTimeout( () => {
235 window.location.replace( data.url_redirect );
236 }, 1000 );
237 } else {
238 elAjaxMessage.classList.add( 'error' );
239 }
240 } ).catch( ( err ) => {
241 elAjaxMessage.classList.add( 'error' );
242 elAjaxMessage.innerHTML = 'error: ' + err.message;
243 } ).then( ( ) => {
244 elButtonRetakeCourse.classList.remove( 'loading' );
245 elButtonRetakeCourse.disabled = false;
246 elAjaxMessage.style.display = 'block';
247 } );
248 };
249
250 elFormRetakeCourse.addEventListener( 'submit', ( e ) => {
251 e.preventDefault();
252 } );
253
254 elButtonRetakeCourses.addEventListener(
255 'click',
256 ( e ) => {
257 e.preventDefault();
258 elButtonRetakeCourses.classList.add( 'loading' );
259 elButtonRetakeCourses.disabled = true;
260 submit( elButtonRetakeCourses );
261 }
262 );
263 } );
264 };
265
266 // Rest API load content course progress - Nhamdv.
267 const courseProgress = () => {
268 const elements = document.querySelectorAll( '.lp-course-progress-wrapper' );
269
270 if ( ! elements.length ) {
271 return;
272 }
273
274 if ( 'IntersectionObserver' in window ) {
275 const eleObserver = new IntersectionObserver( ( entries, observer ) => {
276 entries.forEach( ( entry ) => {
277 if ( entry.isIntersecting ) {
278 const ele = entry.target;
279
280 setTimeout( function() {
281 getResponse( ele );
282 }, 600 );
283
284 eleObserver.unobserve( ele );
285 }
286 } );
287 } );
288
289 [ ...elements ].map( ( ele ) => eleObserver.observe( ele ) );
290 }
291
292 const getResponse = async ( ele ) => {
293 const response = await wp.apiFetch( {
294 path: 'lp/v1/lazy-load/course-progress',
295 method: 'POST',
296 data: {
297 courseId: lpGlobalSettings.post_id || '',
298 userId: lpGlobalSettings.user_id || '',
299 },
300 } );
301
302 const { data } = response;
303
304 ele.innerHTML = data;
305 };
306 };
307
308 const accordionExtraTab = () => {
309 const elements = document.querySelectorAll( '.course-extra-box' );
310
311 [ ...elements ].map( ( ele ) => {
312 const title = ele.querySelector( '.course-extra-box__title' );
313
314 title.addEventListener( 'click', () => {
315 const panel = title.nextElementSibling;
316 const eleActive = document.querySelector( '.course-extra-box.active' );
317
318 if ( eleActive && ! ele.classList.contains( 'active' ) ) {
319 eleActive.classList.remove( 'active' );
320 eleActive.querySelector( '.course-extra-box__content' ).style.display = 'none';
321 }
322
323 if ( ! ele.classList.contains( 'active' ) ) {
324 ele.classList.add( 'active' );
325 panel.style.display = 'block';
326 } else {
327 ele.classList.remove( 'active' );
328 panel.style.display = 'none';
329 }
330 } );
331 } );
332 };
333
334 const courseContinue = () => {
335 const formContinue = document.querySelector( 'form.continue-course' );
336
337 if ( formContinue != null ) {
338 const getResponse = async ( ele ) => {
339 const response = await wp.apiFetch( {
340 path: 'lp/v1/courses/continue-course',
341 method: 'POST',
342 data: {
343 courseId: lpGlobalSettings.post_id || '',
344 userId: lpGlobalSettings.user_id || '',
345 },
346 } );
347
348 return response;
349 };
350 getResponse( formContinue ).then( function( result ) {
351 if ( result.status === 'success' ) {
352 formContinue.style.display = 'block';
353 formContinue.action = result.data;
354 }
355 } );
356 }
357 };
358
359 export {
360 initCourseTabs,
361 initCourseSidebar,
362 enrollCourse,
363 };
364
365 $( window ).on( 'load', () => {
366 const $popup = $( '#popup-course' );
367 let timerClearScroll;
368 const $curriculum = $( '#learn-press-course-curriculum' );
369 accordionExtraTab();
370 initCourseTabs();
371 initCourseSidebar();
372 enrollCourse();
373 purchaseCourse();
374 retakeCourse();
375 courseProgress();
376 courseContinue();
377 lpModalOverlayCompleteItem.init();
378 courseCurriculumSkeleton();
379 } );
380
381 // Add callback for Thimkits
382 LP.Hook.addAction( 'lp_course_curriculum_skeleton', function( id ) {
383 courseCurriculumSkeleton( id );
384 } );
385
386