diff --git a/assets/js/editor.js b/assets/js/editor.js index 6f6ac18c5..241ab11c9 100644 --- a/assets/js/editor.js +++ b/assets/js/editor.js @@ -246,6 +246,130 @@ const PrplLessonItemsHTML = () => { ); }; +/** + * Render the Remind Me button section. + * + * @return {Element} Element to render. + */ +const PrplRemindMeSection = () => { + // Callback function for the Remind Me button + const handleRemindMeClick = () => { + // Get the current post ID + const postId = wp.data.select( 'core/editor' ).getCurrentPostId(); + + // Get the current post title + const postTitle = wp.data + .select( 'core/editor' ) + .getEditedPostAttribute( 'title' ); + + // Show loading state + wp.data + .dispatch( 'core/notices' ) + .createInfoNotice( prplL10n( 'remindMeToReviewContentSetting' ), { + type: 'snackbar', + isDismissible: true, + } ); + + // Make AJAX request to set reminder + const formData = new FormData(); + formData.append( 'action', 'progress_planner_set_reminder' ); + formData.append( 'post_id', postId ); + formData.append( 'post_title', postTitle ); + formData.append( 'nonce', progressPlannerEditor.nonce ); + + fetch( progressPlannerEditor.ajaxUrl, { + method: 'POST', + credentials: 'same-origin', + body: formData, + } ) + .then( ( response ) => response.json() ) + .then( ( responseData ) => { + if ( responseData.success ) { + // Show success notification + wp.data + .dispatch( 'core/notices' ) + .createSuccessNotice( + responseData.data.message || + prplL10n( 'remindMeToReviewContentSuccess' ) + + postTitle, + { + type: 'snackbar', + isDismissible: true, + } + ); + } else { + // Show error notification + wp.data + .dispatch( 'core/notices' ) + .createErrorNotice( + responseData.data.message || + prplL10n( 'remindMeToReviewContentError' ), + { + type: 'snackbar', + isDismissible: true, + } + ); + } + } ) + .catch( ( error ) => { + console.error( 'Error setting reminder:', error ); + // Show error notification + wp.data + .dispatch( 'core/notices' ) + .createErrorNotice( + prplL10n( 'remindMeToReviewContentError' ), + { + type: 'snackbar', + isDismissible: true, + } + ); + } ); + }; + + return el( + PanelBody, + { + key: 'progress-planner-sidebar-remind-me-section', + title: prplL10n( 'remindMeToReviewContent' ), + initialOpen: true, + }, + el( + 'div', + { + style: { + padding: '10px 0', + }, + }, + el( + Button, + { + key: 'progress-planner-sidebar-remind-me-button', + onClick: handleRemindMeClick, + icon: 'clock', + variant: 'secondary', + style: { + width: '100%', + margin: '15px 0', + color: '#38296D', + boxShadow: 'inset 0 0 0 1px #38296D', + whiteSpace: 'normal', + height: 'auto', + minHeight: '60px', + padding: '10px 15px', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + textAlign: 'center', + lineHeight: '1.4', + }, + }, + prplL10n( 'remindMeToReviewContent' ) + ) + ) + ); +}; + /** * Render the Progress Planner sidebar. * This sidebar will display the lessons and videos for the current page. @@ -282,7 +406,8 @@ const PrplProgressPlannerSidebar = () => }, }, PrplRenderPageTypeSelector(), - PrplLessonItemsHTML() + PrplLessonItemsHTML(), + PrplRemindMeSection() ) ) ); diff --git a/classes/admin/class-editor.php b/classes/admin/class-editor.php index 2ec2058e0..a1a8ed584 100644 --- a/classes/admin/class-editor.php +++ b/classes/admin/class-editor.php @@ -56,6 +56,8 @@ public function enqueue_editor_script() { 'lessons' => \progress_planner()->get_lessons()->get_items(), 'pageTypes' => $page_types, 'defaultPageType' => $prpl_preselected_page_type, + 'ajaxUrl' => \admin_url( 'admin-ajax.php' ), + 'nonce' => \wp_create_nonce( 'progress_planner' ), ], ] ); diff --git a/classes/admin/class-enqueue.php b/classes/admin/class-enqueue.php index 0ba45627d..d8789ac90 100644 --- a/classes/admin/class-enqueue.php +++ b/classes/admin/class-enqueue.php @@ -294,54 +294,58 @@ private function get_badge_urls() { public function get_localized_strings() { // Strings alphabetically ordered. return [ - 'badge' => \esc_html__( 'Badge', 'progress-planner' ), - 'checklistProgressDescription' => sprintf( + 'badge' => \esc_html__( 'Badge', 'progress-planner' ), + 'checklistProgressDescription' => sprintf( /* translators: %s: the checkmark icon. */ \esc_html__( 'Check off all required elements %s in the element checks below', 'progress-planner' ), '' ), - 'close' => \esc_html__( 'Close', 'progress-planner' ), - 'doneBtnText' => \esc_html__( 'Finish', 'progress-planner' ), - 'howLong' => \esc_html__( 'How long?', 'progress-planner' ), - 'info' => \esc_html__( 'Info', 'progress-planner' ), - 'markAsComplete' => \esc_html__( 'Mark as completed', 'progress-planner' ), - 'nextBtnText' => \esc_html__( 'Next →', 'progress-planner' ), - 'prevBtnText' => \esc_html__( '← Previous', 'progress-planner' ), - 'pageType' => \esc_html__( 'Page type', 'progress-planner' ), - 'progressPlannerSidebar' => \esc_html__( 'Progress Planner Sidebar', 'progress-planner' ), - 'progressText' => sprintf( + 'close' => \esc_html__( 'Close', 'progress-planner' ), + 'doneBtnText' => \esc_html__( 'Finish', 'progress-planner' ), + 'howLong' => \esc_html__( 'How long?', 'progress-planner' ), + 'info' => \esc_html__( 'Info', 'progress-planner' ), + 'markAsComplete' => \esc_html__( 'Mark as completed', 'progress-planner' ), + 'nextBtnText' => \esc_html__( 'Next →', 'progress-planner' ), + 'prevBtnText' => \esc_html__( '← Previous', 'progress-planner' ), + 'pageType' => \esc_html__( 'Page type', 'progress-planner' ), + 'progressPlannerSidebar' => \esc_html__( 'Progress Planner Sidebar', 'progress-planner' ), + 'progressText' => sprintf( /* translators: %1$s: The current step number. %2$s: The total number of steps. */ \esc_html__( 'Step %1$s of %2$s', 'progress-planner' ), '{{current}}', '{{total}}' ), - 'saving' => \esc_html__( 'Saving...', 'progress-planner' ), - 'snooze' => \esc_html__( 'Snooze', 'progress-planner' ), - 'snoozeDurationOneWeek' => \esc_html__( '1 week', 'progress-planner' ), - 'snoozeDurationOneMonth' => \esc_html__( '1 month', 'progress-planner' ), - 'snoozeDurationThreeMonths' => \esc_html__( '3 months', 'progress-planner' ), - 'snoozeDurationSixMonths' => \esc_html__( '6 months', 'progress-planner' ), - 'snoozeDurationOneYear' => \esc_html__( '1 year', 'progress-planner' ), - 'snoozeDurationForever' => \esc_html__( 'forever', 'progress-planner' ), - 'snoozeThisTask' => \esc_html__( 'Snooze this task?', 'progress-planner' ), - 'subscribed' => \esc_html__( 'Subscribed...', 'progress-planner' ), - 'subscribing' => \esc_html__( 'Subscribing...', 'progress-planner' ), + 'saving' => \esc_html__( 'Saving...', 'progress-planner' ), + 'snooze' => \esc_html__( 'Snooze', 'progress-planner' ), + 'snoozeDurationOneWeek' => \esc_html__( '1 week', 'progress-planner' ), + 'snoozeDurationOneMonth' => \esc_html__( '1 month', 'progress-planner' ), + 'snoozeDurationThreeMonths' => \esc_html__( '3 months', 'progress-planner' ), + 'snoozeDurationSixMonths' => \esc_html__( '6 months', 'progress-planner' ), + 'snoozeDurationOneYear' => \esc_html__( '1 year', 'progress-planner' ), + 'snoozeDurationForever' => \esc_html__( 'forever', 'progress-planner' ), + 'snoozeThisTask' => \esc_html__( 'Snooze this task?', 'progress-planner' ), + 'subscribed' => \esc_html__( 'Subscribed...', 'progress-planner' ), + 'subscribing' => \esc_html__( 'Subscribing...', 'progress-planner' ), /* translators: %s: The task content. */ - 'taskCompleted' => \esc_html__( "Task '%s' completed and moved to the bottom", 'progress-planner' ), + 'taskCompleted' => \esc_html__( "Task '%s' completed and moved to the bottom", 'progress-planner' ), /* translators: %s: The task content. */ - 'taskDelete' => \esc_html__( "Delete task '%s'", 'progress-planner' ), - 'taskMovedDown' => \esc_html__( 'Task moved down', 'progress-planner' ), - 'taskMovedUp' => \esc_html__( 'Task moved up', 'progress-planner' ), + 'taskDelete' => \esc_html__( "Delete task '%s'", 'progress-planner' ), + 'taskMovedDown' => \esc_html__( 'Task moved down', 'progress-planner' ), + 'taskMovedUp' => \esc_html__( 'Task moved up', 'progress-planner' ), /* translators: %s: The task content. */ - 'taskMoveDown' => \esc_html__( "Move task '%s' down", 'progress-planner' ), + 'taskMoveDown' => \esc_html__( "Move task '%s' down", 'progress-planner' ), /* translators: %s: The task content. */ - 'taskMoveUp' => \esc_html__( "Move task '%s' up", 'progress-planner' ), + 'taskMoveUp' => \esc_html__( "Move task '%s' up", 'progress-planner' ), /* translators: %s: The task content. */ - 'taskNotCompleted' => \esc_html__( "Task '%s' marked as not completed and moved to the top", 'progress-planner' ), - 'video' => \esc_html__( 'Video', 'progress-planner' ), - 'watchVideo' => \esc_html__( 'Watch video', 'progress-planner' ), - 'disabledRRCheckboxTooltip' => \esc_html__( 'Don\'t worry! This task will be checked off automatically when you\'ve completed it.', 'progress-planner' ), - 'opensInNewWindow' => \esc_html__( 'Opens in new window', 'progress-planner' ), + 'taskNotCompleted' => \esc_html__( "Task '%s' marked as not completed and moved to the top", 'progress-planner' ), + 'video' => \esc_html__( 'Video', 'progress-planner' ), + 'watchVideo' => \esc_html__( 'Watch video', 'progress-planner' ), + 'disabledRRCheckboxTooltip' => \esc_html__( 'Don\'t worry! This task will be checked off automatically when you\'ve completed it.', 'progress-planner' ), + 'remindMeToReviewContent' => \esc_html__( 'Remind me to review content in 30 days', 'progress-planner' ), + 'remindMeToReviewContentSuccess' => \esc_html__( 'Reminder set for:', 'progress-planner' ), + 'remindMeToReviewContentError' => \esc_html__( 'Failed to set reminder. Please try again.', 'progress-planner' ), + 'remindMeToReviewContentSetting' => \esc_html__( 'Setting reminder...', 'progress-planner' ), + 'opensInNewWindow' => \esc_html__( 'Opens in new window', 'progress-planner' ), ]; } } diff --git a/classes/class-todo.php b/classes/class-todo.php index b847a3ddf..bea416bd5 100644 --- a/classes/class-todo.php +++ b/classes/class-todo.php @@ -23,6 +23,9 @@ public function __construct() { \add_action( 'wp_ajax_progress_planner_save_user_suggested_task', [ $this, 'save_user_suggested_task' ] ); \add_action( 'wp_ajax_progress_planner_save_suggested_user_tasks_order', [ $this, 'save_suggested_user_tasks_order' ] ); + // Set a reminder for the current post. + \add_action( 'wp_ajax_progress_planner_set_reminder', [ $this, 'set_reminder' ] ); + \add_action( 'progress_planner_task_status_changed', [ $this, 'remove_order_from_completed_user_task' ], 10, 2 ); $this->maybe_change_first_item_points_on_monday(); @@ -121,6 +124,11 @@ public function get_pending_items() { continue; } + // Skip tasks that are not available yet. + if ( isset( $task['available_at'] ) && $task['available_at'] > time() ) { + continue; + } + if ( ! isset( $task['order'] ) ) { $task['order'] = $max_order + 1; ++$max_order; @@ -228,6 +236,43 @@ public function save_suggested_user_tasks_order() { \progress_planner()->get_settings()->set( 'tasks', $saved_tasks ); } + /** + * Set a reminder for the current post. + * + * @return void + */ + public function set_reminder() { + // Check the nonce. + if ( ! \check_ajax_referer( 'progress_planner', 'nonce', false ) ) { + \wp_send_json_error( [ 'message' => \esc_html__( 'Invalid nonce.', 'progress-planner' ) ] ); + } + + $post_id = isset( $_POST['post_id'] ) ? \sanitize_text_field( \wp_unslash( $_POST['post_id'] ) ) : ''; + if ( ! $post_id ) { + \wp_send_json_error( [ 'message' => \esc_html__( 'Missing post ID.', 'progress-planner' ) ] ); + } + + $post_title = isset( $_POST['post_title'] ) ? \sanitize_text_field( \wp_unslash( $_POST['post_title'] ) ) : ''; + if ( ! $post_title ) { + \wp_send_json_error( [ 'message' => \esc_html__( 'Missing post title.', 'progress-planner' ) ] ); + } + + $task = [ + 'task_id' => 'user-task-' . md5( $post_id ), + 'provider_id' => 'user', + 'status' => 'pending', + /* translators: %s: The post title. */ + 'title' => sprintf( __( 'Review %s', 'progress-planner' ), $post_title ), + 'available_at' => time() + 30 * DAY_IN_SECONDS, + 'post_id' => $post_id, + ]; + + // Add the task to the local tasks. + progress_planner()->get_suggested_tasks()->get_tasks_manager()->add_pending_task( $task ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Reminder set.', 'progress-planner' ) ] ); + } + /** * Get the points for a new task. *