PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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 / js / frontend / course-builder / builder-dashboard.js

builder-dashboard.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at assets/src/js/frontend/course-builder/builder-dashboard.js

181 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Dashboard charts and interactions for Course Builder.
3 *
4 * @since 4.3.0
5 * @version 1.0.0
6 */
7
8 import Chart from 'chart.js/auto';
9
10 export class BuilderDashboard {
11 constructor() {
12 this.charts = {};
13 this.init();
14 }
15
16 init() {
17 const dataEl = document.getElementById( 'lp-cb-dashboard-chart-data' );
18 if ( ! dataEl ) {
19 return;
20 }
21
22 try {
23 this.chartData = JSON.parse( dataEl.textContent );
24 } catch ( e ) {
25 console.warn( 'Dashboard: Failed to parse chart data', e );
26 return;
27 }
28
29 this.initSalesChart();
30 this.initStudentsChart();
31 this.bindFilterEvents();
32 }
33
34 createGradient( ctx, color ) {
35 const gradient = ctx.createLinearGradient( 0, 0, 0, ctx.canvas.height );
36 gradient.addColorStop( 0, color + '40' );
37 gradient.addColorStop( 1, color + '05' );
38 return gradient;
39 }
40
41 getChartConfig( labels, data, color, prefix = '', isInteger = false ) {
42 return {
43 type: 'line',
44 data: {
45 labels,
46 datasets: [ {
47 data,
48 borderColor: color,
49 borderWidth: 2.5,
50 backgroundColor: ( context ) => {
51 const { ctx } = context.chart;
52 return this.createGradient( ctx, color );
53 },
54 fill: true,
55 tension: 0.4,
56 pointBackgroundColor: color,
57 pointBorderColor: '#fff',
58 pointBorderWidth: 2,
59 pointRadius: 0,
60 pointHoverRadius: 6,
61 pointHoverBorderWidth: 2,
62 } ],
63 },
64 options: {
65 responsive: true,
66 maintainAspectRatio: false,
67 plugins: {
68 legend: { display: false },
69 tooltip: {
70 backgroundColor: '#1e1e1e',
71 titleColor: '#fff',
72 bodyColor: '#fff',
73 borderColor: 'rgba(255,255,255,0.1)',
74 borderWidth: 1,
75 cornerRadius: 8,
76 padding: 12,
77 displayColors: false,
78 callbacks: {
79 label: ( context ) => {
80 const val = context.parsed.y || 0;
81 return prefix + val.toLocaleString();
82 },
83 },
84 },
85 },
86 scales: {
87 x: {
88 grid: { display: false },
89 ticks: {
90 color: '#9ca3af',
91 font: { size: 11 },
92 maxRotation: 0,
93 },
94 border: { display: false },
95 },
96 y: {
97 grid: {
98 color: 'rgba(0,0,0,0.04)',
99 drawBorder: false,
100 },
101 ticks: {
102 stepSize: isInteger ? 1 : undefined,
103 color: '#9ca3af',
104 font: { size: 11 },
105 callback: ( value ) => prefix + value.toLocaleString(),
106 },
107 border: { display: false },
108 beginAtZero: true,
109 },
110 },
111 interaction: {
112 intersect: false,
113 mode: 'index',
114 },
115 },
116 };
117 }
118
119 initSalesChart() {
120 const canvas = document.getElementById( 'lp-cb-chart-sales' );
121 if ( ! canvas ) {
122 return;
123 }
124
125 const { labels = [], data = [] } = this.chartData.sales || {};
126 const config = this.getChartConfig( labels, data, '#10b981', '$' );
127 this.charts.sales = new Chart( canvas, config );
128 }
129
130 initStudentsChart() {
131 const canvas = document.getElementById( 'lp-cb-chart-students' );
132 if ( ! canvas ) {
133 return;
134 }
135
136 const { labels = [], data = [] } = this.chartData.students || {};
137 const config = this.getChartConfig( labels, data, '#f59e0b', '', true );
138 this.charts.students = new Chart( canvas, config );
139 }
140
141 bindFilterEvents() {
142 const filters = document.querySelectorAll( '.chart-card__filter' );
143 filters.forEach( ( select ) => {
144 select.addEventListener( 'change', ( e ) => {
145 const chartType = e.target.dataset.chart;
146 const period = e.target.value;
147 this.fetchChartData( chartType, period );
148 } );
149 } );
150 }
151
152 async fetchChartData( chartType, period ) {
153 const chart = this.charts[ chartType ];
154 if ( ! chart ) {
155 return;
156 }
157
158 const formData = new FormData();
159 formData.append( 'action', 'lp_cb_dashboard_chart_data' );
160 formData.append( 'chart_type', chartType );
161 formData.append( 'period', period );
162 formData.append( 'nonce', this.chartData.nonce );
163
164 try {
165 const response = await fetch( this.chartData.ajaxUrl, {
166 method: 'POST',
167 body: formData,
168 } );
169
170 const result = await response.json();
171 if ( result.success && result.data ) {
172 chart.data.labels = result.data.labels || [];
173 chart.data.datasets[ 0 ].data = result.data.data || [];
174 chart.update( 'none' );
175 }
176 } catch ( e ) {
177 console.warn( 'Dashboard: Failed to fetch chart data', e );
178 }
179 }
180 }
181