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 / js / dist / blocks / course-item-template.js

course-item-template.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.9, at assets/js/dist/blocks/course-item-template.js

1,150 lines 39.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/apps/js/blocks/courses/course-item-template/edit.js"
5 /*!************************************************************************!*\
6 !*** ./assets/src/apps/js/blocks/courses/course-item-template/edit.js ***!
7 \************************************************************************/
8 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
10 "use strict";
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
14 /* harmony export */ });
15 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
16 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
17 /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
18 /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__);
19 /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! classnames */ "./node_modules/classnames/index.js");
20 /* harmony import */ var classnames__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(classnames__WEBPACK_IMPORTED_MODULE_2__);
21 /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
22 /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_3__);
23 /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
24 /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_4__);
25 /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
26 /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__);
27 /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
28 /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__);
29 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
30 /* harmony import */ var lpAssetsJsPath_api_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lpAssetsJsPath/api.js */ "./assets/src/js/api.js");
31
32
33
34
35
36
37
38
39
40 const TEMPLATE_DEFAULT = [['learnpress/course-image'], ['learnpress/course-title'], ['learnpress/course-price']];
41 function PostTemplateInnerBlocks({
42 classList
43 }) {
44 const innerBlocksProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.useInnerBlocksProps)({
45 className: classnames__WEBPACK_IMPORTED_MODULE_2___default()('wp-block-learnpress-course-item-template')
46 }, {
47 template: TEMPLATE_DEFAULT
48 });
49 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("li", {
50 className: "course"
51 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
52 ...innerBlocksProps
53 }));
54 }
55 function PostTemplateBlockPreview({
56 blocks,
57 blockContextId,
58 classList,
59 isHidden,
60 setActiveBlockContextId
61 }) {
62 const blockPreviewProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.__experimentalUseBlockPreview)({
63 blocks
64 });
65 const handleOnClick = () => {
66 setActiveBlockContextId(blockContextId);
67 };
68 const style = {
69 display: isHidden ? 'none' : undefined
70 };
71 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("li", {
72 className: "course",
73 tabIndex: 0
74 // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
75 ,
76 role: "button",
77 onClick: handleOnClick,
78 onKeyPress: handleOnClick,
79 style: style
80 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
81 ...blockPreviewProps,
82 className: "wp-block-learnpress-course-item-template"
83 }));
84 }
85 const fetchLearnPressCourses = async (courseQuery, signal) => {
86 let url = lpAssetsJsPath_api_js__WEBPACK_IMPORTED_MODULE_8__["default"].apiEditCoursesArchiveBlock;
87 url = lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_7__.lpAddQueryArgs(url, courseQuery);
88 const response = await fetch(url, {
89 method: 'GET',
90 signal
91 });
92 if (!response.ok) {
93 throw new Error(`HTTP error! Status: ${response.status}`);
94 }
95 return await response.json();
96 };
97 const MemoizedPostTemplateBlockPreview = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.memo)(PostTemplateBlockPreview);
98 const Edit = ({
99 clientId,
100 context,
101 attributes,
102 setAttributes
103 }) => {
104 const blockProps = (0,_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.useBlockProps)({
105 className: classnames__WEBPACK_IMPORTED_MODULE_2___default()('learn-press-courses')
106 });
107 const [activeBlockContextId, setActiveBlockContextId] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useState)();
108 const [coursesData, setCoursesData] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useState)();
109 const [listCourses, setListCourses] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useState)([]);
110 const [loadingAPI, setLoadingAPI] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useState)(0);
111 // const [ totalPages, setTotalPages ] = useState( 1 );
112 const {
113 columns
114 } = attributes;
115 const layoutPagination = context.lpCourseQuery?.pagination_type || 'number';
116
117 // Fetch courses when query parameters change
118 (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useEffect)(() => {
119 var _context$lpCourseQuer;
120 const courseQuery = (_context$lpCourseQuer = context.lpCourseQuery) !== null && _context$lpCourseQuer !== void 0 ? _context$lpCourseQuer : {};
121 let signal, controller;
122 const fetchCourses = async () => {
123 try {
124 setLoadingAPI(1);
125 controller = new AbortController();
126 signal = controller.signal;
127 const response = await fetchLearnPressCourses(courseQuery, signal);
128 const {
129 data
130 } = response;
131 const {
132 courses,
133 page,
134 total,
135 total_pages
136 } = data;
137 setCoursesData(response);
138 setListCourses(courses);
139 // setTotalPages( total_pages );
140 } catch (error) {
141 if (error.name !== 'AbortError') {
142 console.error('Failed to fetch courses:', error);
143 }
144 } finally {
145 setLoadingAPI(0);
146 }
147 };
148 fetchCourses();
149 return () => {
150 controller.abort();
151 };
152 }, [context.lpCourseQuery?.order_by, context.lpCourseQuery?.limit]);
153 const {
154 blocks
155 } = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_3__.useSelect)(select => {
156 const {
157 getBlocks
158 } = select(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.store);
159 return {
160 blocks: getBlocks(clientId)
161 };
162 }, [clientId]);
163 const blockContexts = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_4__.useMemo)(() => listCourses?.map(course => ({
164 lpCourseData: course,
165 courseId: course?.ID
166 })), [listCourses]);
167 if (loadingAPI) {
168 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("ul", {
169 ...blockProps
170 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("li", null, (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Courses Fetching…', 'learnpress')));
171 }
172 if (listCourses.length === 0 && !loadingAPI) {
173 const dataDummy = [{
174 ID: 1,
175 post_title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Course One', 'learnpress')
176 }, {
177 ID: 2,
178 post_title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Course two', 'learnpress')
179 }];
180 setListCourses(dataDummy);
181 }
182 function paginationTypeDisplay(type) {
183 switch (type) {
184 case 'load-more':
185 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("button", {
186 className: "courses-btn-load-more"
187 }, (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Load More', 'learnpress'));
188 case 'infinite':
189 return '';
190 default:
191 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("nav", {
192 className: "learnpress-block-pagination navigation pagination"
193 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("ul", {
194 className: "page-numbers"
195 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("li", null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("a", {
196 className: "prev page-numbers",
197 href: "?paged=1"
198 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("i", {
199 className: "lp-icon-arrow-left"
200 }))), Array.from({
201 length: 3
202 }, (_, index) => (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("li", {
203 key: index
204 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("a", {
205 className: "page-numbers",
206 href: "{index}"
207 }, index + 1)))));
208 }
209 }
210 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.InspectorControls, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.PanelBody, {
211 title: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Settings', 'learnpress')
212 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalToggleGroupControl, {
213 label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Layout', 'learnpress'),
214 value: attributes.layout || 'gird',
215 onChange: value => {
216 setAttributes({
217 layout: value || 'gird'
218 });
219 },
220 isBlock: true
221 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalToggleGroupControlOption, {
222 value: "list",
223 label: "Stack"
224 }), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.__experimentalToggleGroupControlOption, {
225 value: "grid",
226 label: "Grid"
227 })), attributes.layout === 'grid' && (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_5__.RangeControl, {
228 label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_6__.__)('Columns', 'learnpress'),
229 value: attributes.columns || 3,
230 onChange: value => {
231 setAttributes({
232 columns: value
233 });
234 },
235 min: 2,
236 max: 6,
237 step: 1,
238 marks: [{
239 value: 2,
240 label: '2'
241 }, {
242 value: 3,
243 label: '3'
244 }, {
245 value: 4,
246 label: '4'
247 }, {
248 value: 5,
249 label: '5'
250 }, {
251 value: 6,
252 label: '6'
253 }],
254 withInputField: true
255 }))), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("ul", {
256 className: "learn-press-courses wp-block-learn-press-courses",
257 "data-layout": attributes.layout ? attributes.layout : 'list',
258 style: {
259 '--columns': attributes.columns || 3
260 }
261 }, blockContexts && blockContexts.map(blockContext => (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.BlockContextProvider, {
262 key: blockContext.courseId,
263 value: blockContext
264 }, blockContext.courseId === (activeBlockContextId || blockContexts[0]?.courseId) ? (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(PostTemplateInnerBlocks, {
265 classList: blockContext.classList
266 }) : null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(MemoizedPostTemplateBlockPreview, {
267 blocks: blocks,
268 blockContextId: blockContext.courseId,
269 classList: blockContext.classList,
270 setActiveBlockContextId: setActiveBlockContextId,
271 isHidden: blockContext.courseId === (activeBlockContextId || blockContexts[0]?.courseId)
272 })))), context.lpCourseQuery?.pagination ? paginationTypeDisplay(layoutPagination) : null);
273 };
274 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Edit);
275
276 /***/ },
277
278 /***/ "./assets/src/apps/js/blocks/courses/course-item-template/save.js"
279 /*!************************************************************************!*\
280 !*** ./assets/src/apps/js/blocks/courses/course-item-template/save.js ***!
281 \************************************************************************/
282 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
283
284 "use strict";
285 __webpack_require__.r(__webpack_exports__);
286 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
287 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
288 /* harmony export */ });
289 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
290 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
291 /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/block-editor */ "@wordpress/block-editor");
292 /* harmony import */ var _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__);
293
294
295 const Save = props => {
296 const blockProps = _wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.useBlockProps.save();
297 return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
298 ...blockProps
299 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_block_editor__WEBPACK_IMPORTED_MODULE_1__.InnerBlocks.Content, null));
300 };
301 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Save);
302
303 /***/ },
304
305 /***/ "./assets/src/js/api.js"
306 /*!******************************!*\
307 !*** ./assets/src/js/api.js ***!
308 \******************************/
309 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
310
311 "use strict";
312 __webpack_require__.r(__webpack_exports__);
313 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
314 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
315 /* harmony export */ });
316 /**
317 * List API on backend
318 *
319 * @since 4.2.6
320 * @version 1.0.2
321 */
322
323 const lplistAPI = {};
324 let lp_rest_url;
325 if ('undefined' !== typeof lpDataAdmin) {
326 lp_rest_url = lpDataAdmin.lp_rest_url;
327 lplistAPI.admin = {
328 // apiAdminNotice: lp_rest_url + 'lp/v1/admin/tools/admin-notices',
329 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
330 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
331 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
332 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
333 };
334 }
335 if ('undefined' !== typeof lpData) {
336 lp_rest_url = lpData.lp_rest_url;
337 lplistAPI.frontend = {
338 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
339 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
340 // Deprecated API, don't load from v4.3.7
341 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
342 // Deprecated since 4.3.0
343 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
344 };
345 }
346 if (lp_rest_url) {
347 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
348 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
349 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
350 }
351 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
352
353 /***/ },
354
355 /***/ "./assets/src/js/utils.js"
356 /*!********************************!*\
357 !*** ./assets/src/js/utils.js ***!
358 \********************************/
359 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
360
361 "use strict";
362 __webpack_require__.r(__webpack_exports__);
363 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
364 /* harmony export */ debounce: () => (/* binding */ debounce),
365 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
366 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
367 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
368 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
369 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
370 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
371 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
372 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
373 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
374 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
375 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
376 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
377 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
378 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
379 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
380 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
381 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
382 /* harmony export */ });
383 /**
384 * Utils functions
385 *
386 * @param url
387 * @param data
388 * @param functions
389 * @since 4.2.5.1
390 * @version 1.0.7
391 */
392 const lpClassName = {
393 hidden: 'lp-hidden',
394 loading: 'loading',
395 elCollapse: 'lp-collapse',
396 elSectionToggle: '.lp-section-toggle',
397 elTriggerToggle: '.lp-trigger-toggle',
398 elBtnFullScreen: '.lp-btn-full-screen-view',
399 elFullScreen: 'lp-full-screen-view',
400 elBtnFullScreenClose: 'lp-full-screen-view__close'
401 };
402 const lpFetchAPI = (url, data = {}, functions = {}) => {
403 if ('function' === typeof functions.before) {
404 functions.before();
405 }
406 fetch(url, {
407 method: 'GET',
408 ...data
409 }).then(response => response.json()).then(response => {
410 if ('function' === typeof functions.success) {
411 functions.success(response);
412 }
413 }).catch(err => {
414 if ('function' === typeof functions.error) {
415 functions.error(err);
416 }
417 }).finally(() => {
418 if ('function' === typeof functions.completed) {
419 functions.completed();
420 }
421 });
422 };
423
424 /**
425 * Get current URL without params.
426 *
427 * @since 4.2.5.1
428 */
429 const lpGetCurrentURLNoParam = () => {
430 let currentUrl = window.location.href;
431 const hasParams = currentUrl.includes('?');
432 if (hasParams) {
433 currentUrl = currentUrl.split('?')[0];
434 }
435 return currentUrl;
436 };
437 const lpAddQueryArgs = (endpoint, args) => {
438 const url = new URL(endpoint);
439 Object.keys(args).forEach(arg => {
440 url.searchParams.set(arg, args[arg]);
441 });
442 return url;
443 };
444
445 /**
446 * Listen element viewed.
447 *
448 * @param el
449 * @param callback
450 * @since 4.2.5.8
451 */
452 const listenElementViewed = (el, callback) => {
453 const observerSeeItem = new IntersectionObserver(function (entries) {
454 for (const entry of entries) {
455 if (entry.isIntersecting) {
456 callback(entry);
457 }
458 }
459 });
460 observerSeeItem.observe(el);
461 };
462
463 /**
464 * Listen element created.
465 *
466 * @param callback
467 * @since 4.2.5.8
468 */
469 const listenElementCreated = callback => {
470 const observerCreateItem = new MutationObserver(function (mutations) {
471 mutations.forEach(function (mutation) {
472 if (mutation.addedNodes) {
473 mutation.addedNodes.forEach(function (node) {
474 if (node.nodeType === 1) {
475 callback(node);
476 }
477 });
478 }
479 });
480 });
481 observerCreateItem.observe(document, {
482 childList: true,
483 subtree: true
484 });
485 // End.
486 };
487
488 /**
489 * Listen element created.
490 *
491 * @param selector
492 * @param callback
493 * @since 4.2.7.1
494 */
495 const lpOnElementReady = (selector, callback) => {
496 const element = document.querySelector(selector);
497 if (element) {
498 callback(element);
499 return;
500 }
501 const observer = new MutationObserver((mutations, obs) => {
502 const element = document.querySelector(selector);
503 if (element) {
504 obs.disconnect();
505 callback(element);
506 }
507 });
508 observer.observe(document.documentElement, {
509 childList: true,
510 subtree: true
511 });
512 };
513
514 // Parse JSON from string with content include LP_AJAX_START.
515 const lpAjaxParseJsonOld = data => {
516 if (typeof data !== 'string') {
517 return data;
518 }
519 const m = String.raw({
520 raw: data
521 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
522 try {
523 if (m) {
524 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
525 } else {
526 data = JSON.parse(data);
527 }
528 } catch (e) {
529 data = {};
530 }
531 return data;
532 };
533
534 // status 0: hide, 1: show
535 const lpShowHideEl = (el, status = 0) => {
536 if (!el) {
537 return;
538 }
539 if (!status) {
540 el.classList.add(lpClassName.hidden);
541 } else {
542 el.classList.remove(lpClassName.hidden);
543 }
544 };
545
546 // status 0: hide, 1: show
547 const lpSetLoadingEl = (el, status) => {
548 if (!el) {
549 return;
550 }
551 if (!status) {
552 el.classList.remove(lpClassName.loading);
553 } else {
554 el.classList.add(lpClassName.loading);
555 }
556 };
557
558 // Toggle collapse section
559 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
560 if (!elTriggerClassName) {
561 elTriggerClassName = lpClassName.elTriggerToggle;
562 }
563
564 // Exclude elements, which should not trigger the collapse toggle
565 if (elsExclude && elsExclude.length > 0) {
566 for (const elExclude of elsExclude) {
567 if (target.closest(elExclude)) {
568 return;
569 }
570 }
571 }
572 const elTrigger = target.closest(elTriggerClassName);
573 if (!elTrigger) {
574 return;
575 }
576
577 //console.log( 'elTrigger', elTrigger );
578
579 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
580 if (!elSectionToggle) {
581 return;
582 }
583 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
584 if ('function' === typeof callback) {
585 callback(elSectionToggle);
586 }
587 };
588
589 // Get data of form
590 const getDataOfForm = form => {
591 const dataSend = {};
592 const formData = new FormData(form);
593 for (const pair of formData.entries()) {
594 const key = pair[0];
595 const value = formData.getAll(key);
596 if (!dataSend.hasOwnProperty(key)) {
597 // Convert value array to string.
598 dataSend[key] = value.join(',');
599 }
600 }
601 return dataSend;
602 };
603
604 // Get field keys of form
605 const getFieldKeysOfForm = form => {
606 const keys = [];
607 const elements = form.elements;
608 for (let i = 0; i < elements.length; i++) {
609 const name = elements[i].name;
610 if (name && !keys.includes(name)) {
611 keys.push(name);
612 }
613 }
614 return keys;
615 };
616
617 // Merge data handle with data form.
618 const mergeDataWithDatForm = (elForm, dataHandle) => {
619 const dataForm = getDataOfForm(elForm);
620 const keys = getFieldKeysOfForm(elForm);
621 keys.forEach(key => {
622 if (!dataForm.hasOwnProperty(key)) {
623 delete dataHandle[key];
624 } else if (dataForm[key][0] === '') {
625 delete dataForm[key];
626 delete dataHandle[key];
627 }
628 });
629 dataHandle = {
630 ...dataHandle,
631 ...dataForm
632 };
633 return dataHandle;
634 };
635
636 /**
637 * Event trigger
638 * For each list of event handlers, listen event on document.
639 *
640 * eventName: 'click', 'change', ...
641 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
642 *
643 * @param eventName
644 * @param eventHandlers
645 */
646 const eventHandlers = (eventName, eventHandlers) => {
647 document.addEventListener(eventName, e => {
648 const target = e.target;
649 let args = {
650 e,
651 target
652 };
653 eventHandlers.forEach(eventHandler => {
654 args = {
655 ...args,
656 ...eventHandler
657 };
658
659 //console.log( args );
660
661 // Check condition before call back
662 if (eventHandler.conditionBeforeCallBack) {
663 if (eventHandler.conditionBeforeCallBack(args) !== true) {
664 return;
665 }
666 }
667
668 // Special check for keydown event with checkIsEventEnter = true
669 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
670 if (e.key !== 'Enter') {
671 return;
672 }
673 }
674 if (target.closest(eventHandler.selector)) {
675 if (eventHandler.class) {
676 // Call method of class, function callBack will understand exactly {this} is class object.
677 eventHandler.class[eventHandler.callBack](args);
678 } else {
679 // For send args is objected, {this} is eventHandler object, not class object.
680 eventHandler.callBack(args);
681 }
682 }
683 });
684 });
685 };
686
687 /**
688 * Debounce - delays function execution until after `wait` ms of inactivity.
689 *
690 * Each call resets the timer. Only the last call in a burst executes.
691 *
692 * USE CASES:
693 * - Search inputs, form validation, window resize
694 * - Multiple elements need independent timers
695 * - When you need to call with different arguments
696 *
697 * EXAMPLES:
698 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
699 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
700 *
701 * const debouncedResize = debounce( recalculateLayout, 250 );
702 * window.addEventListener('resize', debouncedResize);
703 *
704 * ⚠️ Create ONCE outside event handlers, not inside.
705 *
706 * @param {Function} func - Function to debounce (can be anonymous)
707 * @param {number} wait - Milliseconds to wait (default: 500)
708 * @return {Function} Debounced wrapper function
709 * @since 4.3.7
710 * @version 1.0.0
711 */
712 const debounce = (func, wait = 500) => {
713 let timer;
714 return args => {
715 clearTimeout(timer);
716 timer = setTimeout(() => func(args), wait);
717 };
718 };
719
720 /**
721 * Initialize lp-toggle-enable components.
722 *
723 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
724 * Reads initial state from `data-enabled` attribute ("true"/"false").
725 * Calls `data-on-toggle` callback (if provided via options) on state change.
726 *
727 * HTML structure:
728 * <label class="lp-toggle-enable" data-enabled="true">
729 * <input type="checkbox" class="lp-toggle-enable__input" />
730 * <span class="lp-toggle-enable__track"></span>
731 * </label>
732 *
733 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
734 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
735 * @since 4.4.5
736 * @version 1.0.0
737 */
738 window.lpToggleEnableInit = 0;
739 const toggleEnable = (onToggle = null) => {
740 if (window.lpToggleEnableInit) {
741 return;
742 }
743 window.lpToggleEnableInit = 1;
744 const selector = '.lp-toggle-enable';
745 const updateUI = (toggle, isEnabled) => {
746 toggle.classList.toggle('is-enabled', isEnabled);
747 const input = toggle.querySelector('.lp-toggle-enable__input');
748 if (input) {
749 input.checked = isEnabled;
750 input.value = isEnabled ? '1' : '0';
751 }
752 };
753
754 // Delegate click handling via eventHandlers.
755 eventHandlers('click', [{
756 selector,
757 callBack: args => {
758 const {
759 e,
760 target
761 } = args;
762 const toggle = target.closest(selector);
763 if (!toggle || toggle.classList.contains('is-disabled')) {
764 return;
765 }
766 e.preventDefault();
767 const isEnabled = !toggle.classList.contains('is-enabled');
768 updateUI(toggle, isEnabled);
769 if ('function' === typeof onToggle) {
770 onToggle(toggle, isEnabled);
771 }
772 }
773 }]);
774 };
775
776 /**
777 * Initialize custom fullscreen view buttons.
778 *
779 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
780 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
781 * target element. Falls back to the button's parent element when
782 * `data-target` is not provided.
783 *
784 * @since 4.4.5
785 * @version 1.0.0
786 */
787 window.lpFullScreenViewInit = 0;
788 const fullScreenView = () => {
789 if (window.lpFullScreenViewInit) {
790 return;
791 }
792 window.lpFullScreenViewInit = 1;
793 let lastScrollY = 0;
794 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
795 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
796 if (isFullscreen) {
797 elTarget.classList.remove(lpClassName.elFullScreen);
798 document.documentElement.classList.remove('lp-full-screen-active');
799 window.scrollTo(0, lastScrollY);
800 } else {
801 lastScrollY = window.scrollY;
802 elTarget.classList.add(lpClassName.elFullScreen);
803 document.documentElement.classList.add('lp-full-screen-active');
804 }
805 if (!isFullscreen) {
806 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
807 const closeButton = document.createElement('button');
808 closeButton.type = 'button';
809 closeButton.className = lpClassName.elBtnFullScreenClose;
810 closeButton.setAttribute('aria-label', 'Close');
811 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
812 closeButton.addEventListener('click', e => {
813 e.preventDefault();
814 lpToggleFullscreenView(elTarget);
815 });
816 elTarget.appendChild(closeButton);
817 }
818 } else {
819 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
820 if (closeButton) {
821 closeButton.remove();
822 }
823 }
824 };
825 eventHandlers('click', [{
826 selector: lpClassName.elBtnFullScreen,
827 callBack: args => {
828 const {
829 e,
830 target
831 } = args;
832 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
833 if (!elBtnFullScreen) {
834 console.log('No full screen button found');
835 return;
836 }
837 e.preventDefault();
838 let elTarget = null;
839 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
840 console.log(targetSelector);
841 if (targetSelector) {
842 elTarget = document.querySelector(targetSelector);
843 }
844 if (!elTarget) {
845 console.log('No target element found');
846 return;
847 }
848 lpToggleFullscreenView(elTarget, elBtnFullScreen);
849 }
850 }]);
851 };
852
853 /***/ },
854
855 /***/ "react"
856 /*!************************!*\
857 !*** external "React" ***!
858 \************************/
859 (module) {
860
861 "use strict";
862 module.exports = window["React"];
863
864 /***/ },
865
866 /***/ "@wordpress/block-editor"
867 /*!*************************************!*\
868 !*** external ["wp","blockEditor"] ***!
869 \*************************************/
870 (module) {
871
872 "use strict";
873 module.exports = window["wp"]["blockEditor"];
874
875 /***/ },
876
877 /***/ "@wordpress/blocks"
878 /*!********************************!*\
879 !*** external ["wp","blocks"] ***!
880 \********************************/
881 (module) {
882
883 "use strict";
884 module.exports = window["wp"]["blocks"];
885
886 /***/ },
887
888 /***/ "@wordpress/components"
889 /*!************************************!*\
890 !*** external ["wp","components"] ***!
891 \************************************/
892 (module) {
893
894 "use strict";
895 module.exports = window["wp"]["components"];
896
897 /***/ },
898
899 /***/ "@wordpress/data"
900 /*!******************************!*\
901 !*** external ["wp","data"] ***!
902 \******************************/
903 (module) {
904
905 "use strict";
906 module.exports = window["wp"]["data"];
907
908 /***/ },
909
910 /***/ "@wordpress/element"
911 /*!*********************************!*\
912 !*** external ["wp","element"] ***!
913 \*********************************/
914 (module) {
915
916 "use strict";
917 module.exports = window["wp"]["element"];
918
919 /***/ },
920
921 /***/ "@wordpress/i18n"
922 /*!******************************!*\
923 !*** external ["wp","i18n"] ***!
924 \******************************/
925 (module) {
926
927 "use strict";
928 module.exports = window["wp"]["i18n"];
929
930 /***/ },
931
932 /***/ "./node_modules/classnames/index.js"
933 /*!******************************************!*\
934 !*** ./node_modules/classnames/index.js ***!
935 \******************************************/
936 (module, exports) {
937
938 var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
939 Copyright (c) 2018 Jed Watson.
940 Licensed under the MIT License (MIT), see
941 http://jedwatson.github.io/classnames
942 */
943 /* global define */
944
945 (function () {
946 'use strict';
947
948 var hasOwn = {}.hasOwnProperty;
949
950 function classNames () {
951 var classes = '';
952
953 for (var i = 0; i < arguments.length; i++) {
954 var arg = arguments[i];
955 if (arg) {
956 classes = appendClass(classes, parseValue(arg));
957 }
958 }
959
960 return classes;
961 }
962
963 function parseValue (arg) {
964 if (typeof arg === 'string' || typeof arg === 'number') {
965 return arg;
966 }
967
968 if (typeof arg !== 'object') {
969 return '';
970 }
971
972 if (Array.isArray(arg)) {
973 return classNames.apply(null, arg);
974 }
975
976 if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
977 return arg.toString();
978 }
979
980 var classes = '';
981
982 for (var key in arg) {
983 if (hasOwn.call(arg, key) && arg[key]) {
984 classes = appendClass(classes, key);
985 }
986 }
987
988 return classes;
989 }
990
991 function appendClass (value, newClass) {
992 if (!newClass) {
993 return value;
994 }
995
996 if (value) {
997 return value + ' ' + newClass;
998 }
999
1000 return value + newClass;
1001 }
1002
1003 if ( true && module.exports) {
1004 classNames.default = classNames;
1005 module.exports = classNames;
1006 } else if (true) {
1007 // register as 'classnames', consistent with npm package name
1008 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
1009 return classNames;
1010 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1011 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1012 } else // removed by dead control flow
1013 {}
1014 }());
1015
1016
1017 /***/ },
1018
1019 /***/ "./assets/src/apps/js/blocks/courses/course-item-template/block.json"
1020 /*!***************************************************************************!*\
1021 !*** ./assets/src/apps/js/blocks/courses/course-item-template/block.json ***!
1022 \***************************************************************************/
1023 (module) {
1024
1025 "use strict";
1026 module.exports = /*#__PURE__*/JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"learnpress/course-item-template","title":"Course Item Template","category":"","description":"Course Item Template","textdomain":"learnpress","keywords":["course item","learnpress"],"usesContext":["lpCourseQuery"],"supports":{"align":true},"attributes":{"layout":{"type":"string","default":"list"},"columns":{"type":"number","default":3}},"ancestor":["learnpress/list-courses"]}');
1027
1028 /***/ }
1029
1030 /******/ });
1031 /************************************************************************/
1032 /******/ // The module cache
1033 /******/ var __webpack_module_cache__ = {};
1034 /******/
1035 /******/ // The require function
1036 /******/ function __webpack_require__(moduleId) {
1037 /******/ // Check if module is in cache
1038 /******/ var cachedModule = __webpack_module_cache__[moduleId];
1039 /******/ if (cachedModule !== undefined) {
1040 /******/ return cachedModule.exports;
1041 /******/ }
1042 /******/ // Create a new module (and put it into the cache)
1043 /******/ var module = __webpack_module_cache__[moduleId] = {
1044 /******/ // no module.id needed
1045 /******/ // no module.loaded needed
1046 /******/ exports: {}
1047 /******/ };
1048 /******/
1049 /******/ // Execute the module function
1050 /******/ if (!(moduleId in __webpack_modules__)) {
1051 /******/ delete __webpack_module_cache__[moduleId];
1052 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
1053 /******/ e.code = 'MODULE_NOT_FOUND';
1054 /******/ throw e;
1055 /******/ }
1056 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
1057 /******/
1058 /******/ // Return the exports of the module
1059 /******/ return module.exports;
1060 /******/ }
1061 /******/
1062 /************************************************************************/
1063 /******/ /* webpack/runtime/compat get default export */
1064 /******/ (() => {
1065 /******/ // getDefaultExport function for compatibility with non-harmony modules
1066 /******/ __webpack_require__.n = (module) => {
1067 /******/ var getter = module && module.__esModule ?
1068 /******/ () => (module['default']) :
1069 /******/ () => (module);
1070 /******/ __webpack_require__.d(getter, { a: getter });
1071 /******/ return getter;
1072 /******/ };
1073 /******/ })();
1074 /******/
1075 /******/ /* webpack/runtime/define property getters */
1076 /******/ (() => {
1077 /******/ // define getter functions for harmony exports
1078 /******/ __webpack_require__.d = (exports, definition) => {
1079 /******/ for(var key in definition) {
1080 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
1081 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
1082 /******/ }
1083 /******/ }
1084 /******/ };
1085 /******/ })();
1086 /******/
1087 /******/ /* webpack/runtime/hasOwnProperty shorthand */
1088 /******/ (() => {
1089 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
1090 /******/ })();
1091 /******/
1092 /******/ /* webpack/runtime/make namespace object */
1093 /******/ (() => {
1094 /******/ // define __esModule on exports
1095 /******/ __webpack_require__.r = (exports) => {
1096 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
1097 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1098 /******/ }
1099 /******/ Object.defineProperty(exports, '__esModule', { value: true });
1100 /******/ };
1101 /******/ })();
1102 /******/
1103 /************************************************************************/
1104 var __webpack_exports__ = {};
1105 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
1106 (() => {
1107 "use strict";
1108 /*!*************************************************************************!*\
1109 !*** ./assets/src/apps/js/blocks/courses/course-item-template/index.js ***!
1110 \*************************************************************************/
1111 __webpack_require__.r(__webpack_exports__);
1112 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
1113 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1114 /* harmony import */ var _edit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./edit */ "./assets/src/apps/js/blocks/courses/course-item-template/edit.js");
1115 /* harmony import */ var _save__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./save */ "./assets/src/apps/js/blocks/courses/course-item-template/save.js");
1116 /* harmony import */ var _block_json__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./block.json */ "./assets/src/apps/js/blocks/courses/course-item-template/block.json");
1117 /* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/blocks */ "@wordpress/blocks");
1118 /* harmony import */ var _wordpress_blocks__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__);
1119
1120 /**
1121 * Register block single course property.
1122 */
1123
1124
1125
1126
1127 (0,_wordpress_blocks__WEBPACK_IMPORTED_MODULE_4__.registerBlockType)('learnpress/course-item-template', {
1128 ..._block_json__WEBPACK_IMPORTED_MODULE_3__,
1129 icon: {
1130 src: (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("svg", {
1131 xmlns: "http://www.w3.org/2000/svg",
1132 viewBox: "0 0 24 24",
1133 width: "24",
1134 height: "24",
1135 "aria-hidden": "true",
1136 focusable: "false"
1137 }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("path", {
1138 fillRule: "evenodd",
1139 d: "M5 5.5h14a.5.5 0 01.5.5v1.5a.5.5 0 01-.5.5H5a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 9.232A2 2 0 013 7.5V6a2 2 0 012-2h14a2 2 0 012 2v1.5a2 2 0 01-1 1.732V18a2 2 0 01-2 2H6a2 2 0 01-2-2V9.232zm1.5.268V18a.5.5 0 00.5.5h12a.5.5 0 00.5-.5V9.5h-13z",
1140 clipRule: "evenodd"
1141 }))
1142 },
1143 edit: _edit__WEBPACK_IMPORTED_MODULE_1__["default"],
1144 save: _save__WEBPACK_IMPORTED_MODULE_2__["default"]
1145 });
1146 })();
1147
1148 /******/ })()
1149 ;
1150 //# sourceMappingURL=course-item-template.js.map