PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.0
Tutor LMS – eLearning and online course solution v4.0.0
4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / templates / dashboard / announcements.php
tutor / templates / dashboard Last commit date
account 1 day ago components 1 day ago courses 1 day ago discussions 1 day ago elements 1 day ago instructor 1 day ago my-courses 1 year ago my-quiz-attempts 1 day ago quiz-attempts 1 day ago student 1 day ago wishlist 1 day ago announcements.php 1 day ago courses.php 1 day ago create-course.php 1 day ago dashboard.php 1 day ago discussions.php 1 day ago index.php 3 years ago logged-in.php 3 years ago my-courses.php 1 day ago my-quiz-attempts.php 1 day ago quiz-attempts.php 1 day ago registration.php 1 day ago wishlist.php 1 day ago
announcements.php
379 lines
1 <?php
2 /**
3 * Template for displaying Announcements
4 *
5 * @package Tutor\Templates
6 * @subpackage Dashboard
7 * @author Themeum <support@themeum.com>
8 * @link https://themeum.com
9 * @since 1.7.9
10 */
11
12 defined( 'ABSPATH' ) || exit;
13
14 use TUTOR\Announcements;
15 use Tutor\Components\ConfirmationModal;
16 use Tutor\Components\Constants\InputType;
17 use Tutor\Components\Constants\Size;
18 use TUTOR\Icon;
19 use TUTOR\Input;
20 use Tutor\Models\CourseModel;
21 use Tutor\Components\Button;
22 use Tutor\Components\CourseFilter;
23 use Tutor\Components\DateFilter;
24 use Tutor\Components\EmptyState;
25 use Tutor\Components\InputField;
26 use Tutor\Components\Pagination;
27 use Tutor\Components\PreviewTrigger;
28 use Tutor\Components\SearchFilter;
29 use Tutor\Components\Sorting;
30 use Tutor\Components\Constants\Variant;
31 use Tutor\Components\Constants\Color;
32 use Tutor\Components\SvgIcon;
33
34 $limit = (int) tutor_utils()->get_option( 'pagination_per_page', 10 );
35 $current_page = max( 1, Input::get( 'current_page', 1, Input::TYPE_INT ) );
36
37 $order_filter = Input::get( 'order', 'DESC' );
38 $search_filter = Input::get( 'search', '' );
39
40 // Announcement's parent.
41 $course_id = Input::get( 'course-id', 0, Input::TYPE_INT );
42 $start_date = Input::get( 'start_date', '' );
43 $end_date = Input::get( 'end_date', '' );
44
45 $args = array(
46 's' => $search_filter,
47 'posts_per_page' => sanitize_text_field( $limit ),
48 'paged' => $current_page,
49 'orderBy' => 'ID',
50 'order' => sanitize_text_field( $order_filter ),
51 );
52
53 if ( $course_id ) {
54 $args['post_parent'] = $course_id;
55 }
56
57 if ( ! empty( $start_date ) && ! empty( $end_date ) ) {
58 $args['date_query'] = array(
59 array(
60 'before' => $end_date,
61 'after' => $start_date,
62 'inclusive' => true,
63 ),
64 );
65 }
66 if ( ! current_user_can( 'administrator' ) ) {
67 $args['author'] = get_current_user_id();
68 }
69 $the_query = Announcements::get_announcements( $args );
70 $announcements = $the_query->have_posts() ? $the_query->posts : array();
71 $total_announcements = $the_query->found_posts;
72
73 $current_url = tutor_utils()->get_tutor_dashboard_page_permalink( 'announcements' );
74 $courses = ( current_user_can( 'administrator' ) ) ? CourseModel::get_courses() : CourseModel::get_courses_by_instructor();
75
76 $form_id = 'tutor-announcement-form';
77 $delete_modal_id = 'tutor-announcement-delete-modal';
78 $create_modal_id = 'tutor-announcement-form-modal';
79 ?>
80
81 <div
82 class="tutor-dashboard-announcements"
83 x-data="tutorAnnouncements({
84 formId: '<?php echo esc_attr( $form_id ); ?>',
85 deleteModalId: '<?php echo esc_attr( $delete_modal_id ); ?>',
86 createModalId: '<?php echo esc_attr( $create_modal_id ); ?>',
87 })"
88 >
89 <div class="tutor-hidden tutor-sm-flex tutor-items-center tutor-justify-between tutor-mb-5">
90 <h4 class="tutor-h4"><?php esc_html_e( 'Announcements', 'tutor' ); ?></h4>
91 <?php
92 Button::make()
93 ->label( __( 'New Announcement', 'tutor' ) )
94 ->size( Size::SMALL )
95 ->icon( Icon::ADD )
96 ->icon_only()
97 ->attr( '@click', 'openCreateModal()' )
98 ->render();
99 ?>
100 </div>
101 <div class="tutor-surface-l1 tutor-border tutor-rounded-2xl tutor-overflow-hidden">
102 <div class="tutor-flex tutor-flex-wrap tutor-gap-4 tutor-items-center tutor-justify-between tutor-px-6 tutor-py-5 tutor-sm-p-5 tutor-border-b">
103 <?php
104 CourseFilter::make()
105 ->size( Size::SMALL )
106 ->courses( $courses )
107 ->count( $total_announcements )
108 ->render();
109
110 DateFilter::make()
111 ->type( DateFilter::TYPE_RANGE )
112 ->placement( DateFilter::PLACEMENT_BOTTOM_END )
113 ->hide_initial_label()
114 ->attr( 'class', 'tutor-hidden tutor-sm-flex' )
115 ->render();
116
117 Button::make()
118 ->label( __( 'New Announcement', 'tutor' ) )
119 ->size( Size::SMALL )
120 ->icon( Icon::ADD )
121 ->attr( '@click', 'openCreateModal()' )
122 ->attr( 'class', 'tutor-force-sm-hidden' )
123 ->render();
124 ?>
125 </div>
126 <div class="tutor-flex tutor-flex-wrap tutor-gap-4 tutor-items-center tutor-justify-between tutor-py-5 tutor-px-6 tutor-sm-p-5 tutor-border-b">
127 <?php
128 SearchFilter::make()
129 ->form_id( 'tutor-my-courses-search-form' )
130 ->size( Size::SMALL )
131 ->placeholder( __( 'Search announcements...', 'tutor' ) )
132 ->action( $current_url )
133 ->size( Size::SMALL )
134 ->attr( 'class', 'tutor-sm-flex-1' )
135 ->render();
136 ?>
137 <div class="tutor-flex tutor-items-center tutor-gap-3">
138 <?php
139 DateFilter::make()
140 ->type( DateFilter::TYPE_RANGE )
141 ->placement( DateFilter::PLACEMENT_BOTTOM_END )
142 ->hide_initial_label()
143 ->attr( 'class', 'tutor-sm-hidden' )
144 ->render();
145
146 Sorting::make()
147 ->order( $order_filter )
148 ->size( Size::SMALL )
149 ->render();
150 ?>
151 </div>
152 </div>
153
154 <?php if ( empty( $announcements ) ) : ?>
155 <?php
156 EmptyState::make()
157 ->title( __( 'No Announcements Found', 'tutor' ) )
158 ->icon( tutor_utils()->get_themed_svg( 'images/illustrations/no-announcements.svg' ) )
159 ->render();
160 ?>
161 <?php else : ?>
162 <div class="tutor-announcement-list">
163 <?php
164 foreach ( $announcements as $announcement ) :
165 ?>
166 <div class="tutor-announcement-item">
167 <div class="tutor-flex tutor-items-center tutor-justify-between tutor-mb-5">
168 <div class="tutor-flex tutor-items-center tutor-gap-3">
169 <?php SvgIcon::make()->name( Icon::ANNOUNCEMENT )->color( Color::IDLE )->render(); ?>
170 <div class="tutor-tiny tutor-text-secondary">
171 <?php echo esc_html( tutor_i18n_get_formated_date( $announcement->post_date ) ); ?>
172 </div>
173 </div>
174 <div class="tutor-announcement-actions">
175 <div class="tutor-flex tutor-items-center tutor-gap-3 tutor-sm-hidden">
176 <?php
177 Button::make()
178 ->label( __( 'Edit', 'tutor' ) )
179 ->size( Size::X_SMALL )
180 ->variant( Variant::SECONDARY )
181 ->icon( Icon::EDIT_2 )
182 ->icon_only()
183 ->attr(
184 '@click',
185 sprintf(
186 'openEditModal(%s)',
187 wp_json_encode(
188 array(
189 'id' => (int) $announcement->ID,
190 'title' => $announcement->post_title,
191 'summary' => $announcement->post_content,
192 'course_id' => (int) $announcement->post_parent,
193 )
194 )
195 )
196 )
197 ->render();
198
199 Button::make()
200 ->label( __( 'Delete', 'tutor' ) )
201 ->size( Size::X_SMALL )
202 ->variant( Variant::SECONDARY )
203 ->icon( Icon::DELETE_2 )
204 ->icon_only()
205 ->attr( '@click', "TutorCore.modal.showModal('$delete_modal_id', { announcementId: $announcement->ID });" )
206 ->render();
207 ?>
208 </div>
209 <!-- Mobile Popover -->
210 <div x-data="tutorPopover({ placement: 'bottom-end' })" class="tutor-hidden tutor-sm-block">
211 <button x-ref="trigger" @click="toggle()" class="tutor-btn tutor-btn-ghost tutor-btn-x-small tutor-btn-icon" aria-label="<?php esc_attr_e( 'Announcement actions', 'tutor' ); ?>">
212 <?php SvgIcon::make()->name( Icon::ELLIPSES )->size( 16 )->color( Color::SECONDARY )->render(); ?>
213 </button>
214 <div x-ref="content" x-show="open" x-cloak @click.outside="handleClickOutside()" class="tutor-popover">
215 <div class="tutor-popover-menu" style="min-width: 104px;">
216 <button
217 class="tutor-popover-menu-item"
218 @click="hide(); openEditModal(
219 <?php
220 echo esc_attr(
221 wp_json_encode(
222 array(
223 'id' => (int) $announcement->ID,
224 'title' => $announcement->post_title,
225 'summary' => $announcement->post_content,
226 'course_id' => (int) $announcement->post_parent,
227 )
228 )
229 );
230 ?>
231 )"
232 >
233 <?php SvgIcon::make()->name( Icon::EDIT_2 )->render(); ?>
234 <?php esc_html_e( 'Edit', 'tutor' ); ?>
235 </button>
236 <button
237 class="tutor-popover-menu-item"
238 @click="hide(); TutorCore.modal.showModal('<?php echo esc_attr( $delete_modal_id ); ?>', { announcementId: <?php echo esc_html( $announcement->ID ); ?> });"
239 >
240 <?php SvgIcon::make()->name( Icon::DELETE_2 )->render(); ?>
241 <?php esc_html_e( 'Delete', 'tutor' ); ?>
242 </button>
243 </div>
244 </div>
245 </div>
246 </div>
247 </div>
248 <div class="tutor-medium tutor-font-medium tutor-mb-4">
249 <?php echo esc_html( $announcement->post_title ); ?>
250 </div>
251 <div class="tutor-p2 tutor-mb-6 tutor-whitespace-pre-line">
252 <?php echo wp_kses_post( $announcement->post_content ); ?>
253 </div>
254 <div class="tutor-tiny tutor-text-secondary tutor-flex tutor-items-center tutor-gap-2">
255 <span class="tutor-flex-shrink-0"><?php esc_html_e( 'Course', 'tutor' ); ?></span>
256 <?php PreviewTrigger::make()->id( $announcement->post_parent )->render(); ?>
257 </div>
258 </div>
259 <?php
260 endforeach;
261 ?>
262 </div>
263 <?php endif; ?>
264
265 <?php if ( $total_announcements > $limit ) : ?>
266 <div class="tutor-p-6 tutor-sm-p-5 tutor-border-t">
267 <?php Pagination::make()->current( $current_page )->total( $total_announcements )->limit( $limit )->render(); ?>
268 </div>
269 <?php endif; ?>
270 </div>
271
272 <?php if ( ! empty( $announcements ) ) : ?>
273 <?php
274 ConfirmationModal::make()
275 ->id( $delete_modal_id )
276 ->title( __( 'Delete This Announcement?', 'tutor' ) )
277 ->message( __( 'Are you sure you want to delete this announcement permanently? Please confirm your choice.', 'tutor' ) )
278 ->confirm_text( __( 'Yes, Delete This', 'tutor' ) )
279 ->confirm_handler( 'handleDeleteAnnouncement(payload?.announcementId)' )
280 ->mutation_state( 'deleteMutation' )
281 ->render();
282 ?>
283 <?php endif; ?>
284
285 <div x-data="tutorModal({ id: '<?php echo esc_attr( $create_modal_id ); ?>', isCloseable: false })" x-cloak>
286 <template x-teleport="body">
287 <div x-bind="getModalBindings()">
288 <div x-bind="getBackdropBindings()"></div>
289 <div x-bind="getModalContentBindings()" style="max-width: 480px;">
290 <button x-data="tutorIcon({ name: 'cross', width: 16, height: 16})", x-bind="getCloseButtonBindings()"></button>
291
292 <div class="tutor-flex tutor-items-center tutor-gap-4 tutor-px-7 tutor-py-6 tutor-border-b">
293 <?php SvgIcon::make()->name( Icon::ANNOUNCEMENT )->size( 24 )->color( Color::BRAND )->render(); ?>
294 <h5 class="tutor-modal-title" x-text="formTitle"></h5>
295 </div>
296
297 <?php
298 $course_options = array_map(
299 function ( $course ) {
300 return array(
301 'label' => $course->post_title,
302 'value' => $course->ID,
303 );
304 },
305 $courses
306 );
307 ?>
308 <form
309 id="<?php echo esc_attr( $form_id ); ?>"
310 x-data="tutorForm({ id: '<?php echo esc_attr( $form_id ); ?>' })"
311 x-bind="getFormBindings()"
312 @submit.prevent="handleSubmit((data) => handleFormSubmit(data))($event)"
313 >
314 <div class="tutor-flex tutor-flex-column tutor-gap-5 tutor-p-7">
315 <?php
316 InputField::make()
317 ->type( InputType::SELECT )
318 ->name( 'tutor_announcement_course' )
319 ->label( __( 'Select Course', 'tutor' ) )
320 ->placeholder( __( 'Select a course', 'tutor' ) )
321 ->options( $course_options )
322 ->searchable()
323 ->attr( 'x-bind', "register('tutor_announcement_course', { required: 'Please select a course' })" )
324 ->render();
325
326 InputField::make()
327 ->type( InputType::TEXT )
328 ->name( 'tutor_announcement_title' )
329 ->label( __( 'Announcement Title', 'tutor' ) )
330 ->placeholder( __( 'Announcement title', 'tutor' ) )
331 ->clearable()
332 ->attr( 'x-bind', "register('tutor_announcement_title', { required: 'Title is required' })" )
333 ->render();
334
335 InputField::make()
336 ->type( InputType::TEXTAREA )
337 ->name( 'tutor_announcement_summary' )
338 ->label( __( 'Description', 'tutor' ) )
339 ->placeholder( __( 'Write a short announcement description.', 'tutor' ) )
340 ->attr( 'rows', '5' )
341 ->attr( 'x-bind', "register('tutor_announcement_summary', { required: 'Summary is required' })" )
342 ->render();
343 ?>
344
345 <?php do_action( 'tutor_announcement_editor/after' ); ?>
346 </div>
347
348 <div class="tutor-modal-footer">
349 <?php
350 Button::make()
351 ->label( __( 'Cancel', 'tutor' ) )
352 ->size( Size::SMALL )
353 ->variant( Variant::SECONDARY )
354 ->attr( 'type', 'button' )
355 ->attr( '@click', sprintf( 'TutorCore.modal.closeModal("%s")', $create_modal_id ) )
356 ->render();
357
358 Button::make()
359 ->label( __( 'Publish', 'tutor' ) )
360 ->size( Size::SMALL )
361 ->variant( Variant::PRIMARY )
362 ->attr( ':class', "createUpdateMutation?.isPending ? 'tutor-btn-loading' : ''" )
363 ->attr( ':disabled', 'createUpdateMutation?.isPending' )
364 ->attr(
365 '@click',
366 'handleSubmit((data) => handleFormSubmit(data))($event)'
367 )
368 ->attr( 'x-text', 'formActionText' )
369 ->render();
370 ?>
371
372 </div>
373 </form>
374 </div>
375 </div>
376 </template>
377 </div>
378 </div>
379