From 53c5e2102f8e9f0c84de7aefa44a82ad1a75451d Mon Sep 17 00:00:00 2001 From: Ruben Ramirez Date: Thu, 3 Apr 2025 20:24:33 -0500 Subject: [PATCH] FIXED: Added a 'Send Assessment Invite' metabox to the Job edit screen. Includes metabox --- admin/js/job-metabox.js | 54 +++++++++++++++ src/Admin/JobMetaboxes.php | 138 +++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 admin/js/job-metabox.js create mode 100644 src/Admin/JobMetaboxes.php diff --git a/admin/js/job-metabox.js b/admin/js/job-metabox.js new file mode 100644 index 0000000..d34b971 --- /dev/null +++ b/admin/js/job-metabox.js @@ -0,0 +1,54 @@ +/** + * Handles the "Send Invite" metabox functionality on the Job edit screen. + */ +(function($) { + 'use strict'; + + $(document).ready(function() { + const $metabox = $('#quiztech_send_invite_metabox'); + if (!$metabox.length) { + return; // Metabox not found + } + + const $button = $metabox.find('#quiztech_send_invite_button'); + const $emailInput = $metabox.find('#quiztech_applicant_email'); + const $statusSpan = $metabox.find('#quiztech_invite_status'); + + $button.on('click', function() { + const email = $emailInput.val().trim(); + + // Basic email validation (more robust validation can be added) + if (!email || !/\S+@\S+\.\S+/.test(email)) { + $statusSpan.text('Please enter a valid email address.').css('color', 'red').show(); + $emailInput.focus(); + return; + } + + // Disable button and show status + $button.prop('disabled', true); + $statusSpan.text(quiztechJobMetabox.sending_text).css('color', '').show(); + + // AJAX request + $.post(quiztechJobMetabox.ajax_url, { + action: 'quiztech_send_job_invite', + nonce: quiztechJobMetabox.nonce, + job_id: quiztechJobMetabox.job_id, // Passed via wp_localize_script + email: email + }, function(response) { + if (response.success) { + $statusSpan.text(response.data.message).css('color', 'green'); + $emailInput.val(''); // Clear email field on success + } else { + const errorMsg = response.data && response.data.message ? response.data.message : 'Unknown error.'; + $statusSpan.text(quiztechJobMetabox.error_text + ' ' + errorMsg).css('color', 'red'); + } + }).fail(function() { + $statusSpan.text(quiztechJobMetabox.ajax_fail_text).css('color', 'red'); + }).always(function() { + // Re-enable button + $button.prop('disabled', false); + }); + }); + }); + +})(jQuery); \ No newline at end of file diff --git a/src/Admin/JobMetaboxes.php b/src/Admin/JobMetaboxes.php new file mode 100644 index 0000000..9e546fe --- /dev/null +++ b/src/Admin/JobMetaboxes.php @@ -0,0 +1,138 @@ + +

+
+ +

+ + +

+ +

+ __( 'Permission denied.', 'quiztech' ) ], 403 ); + } + + $job_id = isset( $_POST['job_id'] ) ? absint( $_POST['job_id'] ) : 0; + $applicant_email = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : ''; + + if ( ! $job_id || ! is_email( $applicant_email ) ) { + wp_send_json_error( [ 'message' => __( 'Invalid Job ID or Email Address.', 'quiztech' ) ] ); + } + + // Get linked assessment ID + $assessment_id = get_post_meta( $job_id, '_quiztech_associated_assessment_id', true ); + if ( empty( $assessment_id ) || 'assessment' !== get_post_type( $assessment_id ) ) { + wp_send_json_error( [ 'message' => __( 'No valid assessment linked to this job.', 'quiztech' ) ] ); + } + + $invitations = new Invitations(); + $token_or_error = $invitations->create_invitation( $job_id, $assessment_id, $applicant_email ); + + if ( is_wp_error( $token_or_error ) ) { + wp_send_json_error( [ 'message' => $token_or_error->get_error_message() ] ); + } + + $token = $token_or_error; + $email_sent = $invitations->send_invitation_email( $applicant_email, $token, [ 'job_title' => get_the_title( $job_id ) ] ); // Pass job title + + if ( $email_sent ) { + wp_send_json_success( [ 'message' => __( 'Invitation sent successfully!', 'quiztech' ) ] ); + } else { + // Note: create_invitation succeeded, but email failed. Might want specific handling. + wp_send_json_error( [ 'message' => __( 'Invitation created, but email failed to send. Check SMTP settings.', 'quiztech' ) ] ); + } + } + + /** + * Enqueues admin scripts and styles for the Job edit screen. + * + * @param string $hook_suffix The current admin page hook. + */ + public function enqueue_admin_scripts( $hook_suffix ) { + // Script enqueue logic will go here (Step 7) + global $post_type; + + if ( 'job' === $post_type && ( 'post.php' === $hook_suffix || 'post-new.php' === $hook_suffix ) ) { + $script_path = plugin_dir_url( QUIZTECH_PLUGIN_FILE ) . 'admin/js/job-metabox.js'; + $script_asset_path = plugin_dir_path( QUIZTECH_PLUGIN_FILE ) . 'admin/js/job-metabox.asset.php'; + $script_asset = file_exists( $script_asset_path ) ? require( $script_asset_path ) : [ 'dependencies' => [], 'version' => filemtime( plugin_dir_path( QUIZTECH_PLUGIN_FILE ) . $script_path ) ]; + + wp_enqueue_script( + 'quiztech-job-metabox-script', + $script_path, + array_merge( $script_asset['dependencies'], [ 'jquery' ] ), // Add jquery dependency + $script_asset['version'], + true // Load in footer + ); + + // Pass data to the script + wp_localize_script( 'quiztech-job-metabox-script', 'quiztechJobMetabox', [ + 'ajax_url' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'quiztech_send_invite_nonce_ajax' ), + 'job_id' => get_the_ID(), // Get current post ID + 'sending_text' => __( 'Sending...', 'quiztech' ), + 'error_text' => __( 'Error:', 'quiztech' ), + 'ajax_fail_text' => __( 'AJAX request failed.', 'quiztech' ), + ]); + } + } +} \ No newline at end of file