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 / js / admin / edit-course / edit-curriculum / edit-curriculum-ai.js

edit-curriculum-ai.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.9, at assets/src/js/admin/edit-course/edit-curriculum/edit-curriculum-ai.js

262 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Generate data with OpenAI
3 */
4
5 import * as lpUtils from 'lpAssetsJsPath/utils.js';
6 import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
7 import SweetAlert from 'sweetalert2';
8 import { EditSection } from './edit-section.js';
9 import { EditSectionItem } from './edit-section-item.js';
10 import { EditCourseCurriculum } from 'lpAssetsJsPath/admin/edit-course/edit-curriculum.js';
11
12 let editSection = null;
13 let editSectionItem = null;
14
15 export class EditCurriculumAi {
16 constructor( options = {} ) {
17 this.options = {
18 isCourseBuilder: false,
19 ...options,
20 };
21
22 this.init();
23 }
24
25 static selectors = {
26 elBtnApplyCurriculum: '.lp-btn-apply-curriculum',
27 };
28
29 init() {
30 if ( ! lpData?.enable_open_ai ) {
31 return;
32 }
33
34 if ( this.options.isCourseBuilder ) {
35 lpUtils.lpOnElementReady( EditCourseCurriculum.selectors.idElEditCurriculum, ( el ) => {
36 const elCountSections = el.querySelector( EditSection.selectors.elCountSections );
37 elCountSections.insertAdjacentHTML(
38 'beforebegin',
39 `<button type="button"
40 class="cb-course-edit-ai-btn lp-btn-generate-with-ai"
41 data-template="#lp-tmpl-edit-course-curriculum-ai">
42 <i class="lp-ico-ai"></i>
43 </button>`
44 );
45 } );
46 } else {
47 lpUtils.lpOnElementReady( EditCourseCurriculum.selectors.idElEditCurriculum, ( el ) => {
48 const elCountSections = el.querySelector( EditSection.selectors.elCountSections );
49 elCountSections.insertAdjacentHTML(
50 'afterend',
51 `<button type="button"
52 class="lp-btn-generate-with-ai lp-btn-ai-style"
53 data-template="#lp-tmpl-edit-course-curriculum-ai">
54 <i class="lp-ico-ai"></i><span>Generate with AI</span>
55 </button>`,
56 );
57 } );
58 }
59
60 this.events();
61 }
62
63 events() {
64 if ( EditCurriculumAi._loadedEvents ) {
65 return;
66 }
67 EditCurriculumAi._loadedEvents = true;
68
69 lpUtils.eventHandlers( 'click', [
70 {
71 selector: EditCurriculumAi.selectors.elBtnApplyCurriculum,
72 class: this,
73 callBack: this.applyData.name,
74 },
75 ] );
76 }
77
78 async applyData( args ) {
79 const { e, target } = args;
80 let dataSend = JSON.parse( target.dataset.send );
81 dataSend = lpUtils.mergeDataWithDatForm( target.closest( 'form' ), dataSend );
82
83 if ( ! dataSend[ 'lp-openai-generated-data' ] ) {
84 return;
85 }
86
87 const data = JSON.parse( dataSend[ 'lp-openai-generated-data' ] );
88
89 //console.log( 'Generated Data:', data );
90
91 const sections = data[ 0 ].sections;
92 if ( ! sections || sections.length === 0 ) {
93 lpToastify.show( 'No sections found in the generated data.', 'error' );
94 }
95
96 // console.log( 'Generated Sections:', sections );
97
98 SweetAlert.close();
99
100 // Wait half second to ensure SweetAlert is closed completely
101 await new Promise( ( resolve ) => setTimeout( resolve, 500 ) );
102
103 // New edit section instance
104 editSection = new EditSection();
105 editSection.init();
106
107 // New edit section item instance
108 editSectionItem = new EditSectionItem();
109 editSectionItem.init();
110
111 // Scroll to element add section
112 const elEditCurriculum = document.querySelector(
113 EditCourseCurriculum.selectors.idElEditCurriculum
114 );
115 const elDivAddNewSection = elEditCurriculum.querySelector(
116 EditSection.selectors.elDivAddNewSection
117 );
118 elDivAddNewSection.scrollIntoView( {
119 behavior: 'smooth',
120 block: 'center',
121 } );
122
123 // Wait 800ms to ensure scroll completely
124 await new Promise( ( resolve ) => setTimeout( resolve, 800 ) );
125
126 for ( const sectionData of sections ) {
127 // Set title
128 const elSectionTitleNewInput = elEditCurriculum.querySelector(
129 EditSection.selectors.elSectionTitleNewInput
130 );
131 const elBtnAddSection = elEditCurriculum.querySelector(
132 EditSection.selectors.elBtnAddSection
133 );
134 elSectionTitleNewInput.value = sectionData.section_title || '';
135
136 await new Promise( ( resolve ) => {
137 editSection.addSection( {
138 e: new PointerEvent( 'click' ),
139 target: elBtnAddSection,
140 callBackNest: this.updateSectionDescription( {
141 sectionData,
142 elEditCurriculum,
143 } ),
144 resolve,
145 } );
146 } );
147 }
148 }
149
150 /**
151 * Update section description after create new section
152 * @param args
153 */
154 updateSectionDescription( args ) {
155 const { sectionData, elEditCurriculum } = args;
156
157 return {
158 success: async ( args ) => {
159 const { elSection } = args;
160 await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
161
162 // Set description for the new section
163 const elSectionDesInput = elSection.querySelector(
164 EditSection.selectors.elSectionDesInput
165 );
166 elSectionDesInput.value = sectionData.section_description || '';
167
168 // Call AJAX to save description
169 await new Promise( ( resolve ) => {
170 editSection.updateSectionDescription( {
171 e: new PointerEvent( 'click' ),
172 target: elSectionDesInput,
173 callBackNest: this.addSectionItems( {
174 sectionData,
175 elEditCurriculum,
176 } ),
177 resolve,
178 } );
179 } );
180
181 setTimeout( args.resolve, 1 );
182 },
183 error: ( error ) => {},
184 completed: () => {},
185 };
186 }
187
188 addSectionItems( args ) {
189 const { sectionData, elEditCurriculum } = args;
190 const lessons = sectionData.lessons || [];
191 const quizzes = sectionData.quizzes || [];
192
193 return {
194 success: async ( args ) => {
195 //await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
196 const { elSection } = args;
197
198 const elBtnSelectItemTypeLesson = elSection.querySelector(
199 `${ EditSectionItem.selectors.elBtnSelectItemType }[data-item-type=lp_lesson]`
200 );
201
202 const elBtnSelectItemTypeQuiz = elSection.querySelector(
203 `${ EditSectionItem.selectors.elBtnSelectItemType }[data-item-type=lp_quiz]`
204 );
205
206 for ( const itemData of lessons ) {
207 elBtnSelectItemTypeLesson.click();
208
209 await this.addItemToSection( {
210 itemData,
211 elSection,
212 elEditCurriculum,
213 } );
214 }
215
216 for ( const itemData of quizzes ) {
217 elBtnSelectItemTypeQuiz.click();
218
219 await this.addItemToSection( {
220 itemData,
221 elSection,
222 elEditCurriculum,
223 } );
224 }
225
226 setTimeout( args.resolve, 1 );
227 },
228 error: ( error ) => {},
229 completed: () => {},
230 };
231 }
232
233 async addItemToSection( args ) {
234 const { itemData, elSection, elEditCurriculum } = args;
235
236 const elBtnAddItem = elSection.querySelector( EditSectionItem.selectors.elBtnAddItem );
237 const elAddItemTypeTitleInput = elSection.querySelector(
238 EditSectionItem.selectors.elAddItemTypeTitleInput
239 );
240 elAddItemTypeTitleInput.value = itemData.lesson_title || itemData.quiz_title || '';
241
242 // Scroll to element add item
243 elBtnAddItem.scrollIntoView( { behavior: 'smooth', block: 'center' } );
244
245 // Call AJAX to add item to section
246 await new Promise( ( resolve ) => {
247 editSectionItem.addItemToSection( {
248 e: new PointerEvent( 'click' ),
249 target: elBtnAddItem,
250 resolve,
251 callBackNest: {
252 completed: async ( args ) => {
253 setTimeout( resolve, 1000 );
254 },
255 },
256 } );
257 } );
258
259 setTimeout( args.resolve, 1 );
260 }
261 }
262