Initial dashboard widgets
This commit is contained in:
parent
c0687c652b
commit
0124c0fa85
3 changed files with 349 additions and 2 deletions
144
functions.php
144
functions.php
|
|
@ -585,4 +585,148 @@ function quiztech_ajax_save_question() {
|
||||||
}
|
}
|
||||||
add_action( 'wp_ajax_quiztech_save_question', 'quiztech_ajax_save_question' );
|
add_action( 'wp_ajax_quiztech_save_question', 'quiztech_ajax_save_question' );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --- Dashboard Helper Functions ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get URLs for dashboard quick links.
|
||||||
|
*
|
||||||
|
* @return array Associative array of 'Label' => 'URL'.
|
||||||
|
*/
|
||||||
|
function quiztech_get_dashboard_quick_links() {
|
||||||
|
$links = [];
|
||||||
|
$page_slugs = [
|
||||||
|
'manage-jobs' => __('Manage Jobs', 'quiztech'),
|
||||||
|
'assessment-builder' => __('Manage Assessments', 'quiztech'), // Link to builder/manager
|
||||||
|
'manage-questions' => __('Manage Questions', 'quiztech'),
|
||||||
|
'manage-credits' => __('Manage Credits', 'quiztech'),
|
||||||
|
// Add 'Create New' links if separate pages exist, otherwise link to managers
|
||||||
|
// 'create-job' => __('Create New Job', 'quiztech'),
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($page_slugs as $slug => $label) {
|
||||||
|
$page = get_page_by_path($slug);
|
||||||
|
$links[$label] = $page ? get_permalink($page->ID) : ''; // Return empty string if page not found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add direct links for creating new content if possible (often handled by query args on manager pages)
|
||||||
|
// Example: $links[__('Create New Job', 'quiztech')] = add_query_arg('action', 'new', $links[__('Manage Jobs', 'quiztech')]);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get recent invitations sent.
|
||||||
|
*
|
||||||
|
* @param int $count Number of invitations to retrieve.
|
||||||
|
* @return array Array of invitation objects/arrays.
|
||||||
|
*/
|
||||||
|
function quiztech_get_dashboard_recent_invitations($count = 5) {
|
||||||
|
global $wpdb;
|
||||||
|
$invitations_table = $wpdb->prefix . 'quiztech_invitations';
|
||||||
|
$posts_table = $wpdb->posts;
|
||||||
|
|
||||||
|
// Ensure table exists before querying
|
||||||
|
if ($wpdb->get_var("SHOW TABLES LIKE '{$invitations_table}'") != $invitations_table) {
|
||||||
|
return []; // Table doesn't exist
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $wpdb->prepare(
|
||||||
|
"SELECT inv.applicant_email, inv.created_at, p.post_title AS job_title
|
||||||
|
FROM {$invitations_table} inv
|
||||||
|
LEFT JOIN {$posts_table} p ON inv.job_id = p.ID
|
||||||
|
ORDER BY inv.created_at DESC
|
||||||
|
LIMIT %d",
|
||||||
|
absint($count)
|
||||||
|
);
|
||||||
|
|
||||||
|
$results = $wpdb->get_results($query);
|
||||||
|
|
||||||
|
return $results ? $results : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get recent completed assessments.
|
||||||
|
*
|
||||||
|
* @param int $count Number of completions to retrieve.
|
||||||
|
* @return array Array of completion data.
|
||||||
|
*/
|
||||||
|
function quiztech_get_dashboard_recent_completions($count = 5) {
|
||||||
|
global $wpdb;
|
||||||
|
$invitations_table = $wpdb->prefix . 'quiztech_invitations';
|
||||||
|
$completions = [];
|
||||||
|
|
||||||
|
$args = [
|
||||||
|
'post_type' => 'user_evaluation',
|
||||||
|
'post_status' => 'completed', // Assuming 'completed' status is used
|
||||||
|
'posts_per_page' => absint($count),
|
||||||
|
'orderby' => 'date',
|
||||||
|
'order' => 'DESC',
|
||||||
|
'meta_query' => [
|
||||||
|
[
|
||||||
|
'key' => 'quiztech_invitation_id',
|
||||||
|
'compare' => 'EXISTS' // Ensure it's linked
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$query = new WP_Query($args);
|
||||||
|
|
||||||
|
if ($query->have_posts()) {
|
||||||
|
// Check if invitations table exists
|
||||||
|
$invitations_table_exists = ($wpdb->get_var("SHOW TABLES LIKE '{$invitations_table}'") == $invitations_table);
|
||||||
|
|
||||||
|
while ($query->have_posts()) {
|
||||||
|
$query->the_post();
|
||||||
|
$evaluation_id = get_the_ID();
|
||||||
|
$completion_date = get_the_date(); // Or post_modified if that's more relevant
|
||||||
|
$invitation_id = get_post_meta($evaluation_id, 'quiztech_invitation_id', true);
|
||||||
|
$applicant_email = 'N/A';
|
||||||
|
$job_title = 'N/A';
|
||||||
|
|
||||||
|
if ($invitation_id && $invitations_table_exists) {
|
||||||
|
$invitation_data = $wpdb->get_row($wpdb->prepare(
|
||||||
|
"SELECT inv.applicant_email, p.post_title AS job_title
|
||||||
|
FROM {$invitations_table} inv
|
||||||
|
LEFT JOIN {$wpdb->posts} p ON inv.job_id = p.ID
|
||||||
|
WHERE inv.id = %d",
|
||||||
|
absint($invitation_id)
|
||||||
|
));
|
||||||
|
if ($invitation_data) {
|
||||||
|
$applicant_email = $invitation_data->applicant_email;
|
||||||
|
$job_title = $invitation_data->job_title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$completions[] = [
|
||||||
|
'applicant_email' => $applicant_email,
|
||||||
|
'job_title' => $job_title,
|
||||||
|
'completion_date' => $completion_date,
|
||||||
|
'evaluation_id' => $evaluation_id // For potential linking
|
||||||
|
];
|
||||||
|
}
|
||||||
|
wp_reset_postdata();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of active job posts.
|
||||||
|
*
|
||||||
|
* @return int Count of published jobs.
|
||||||
|
*/
|
||||||
|
function quiztech_get_dashboard_active_job_count() {
|
||||||
|
$args = [
|
||||||
|
'post_type' => 'job',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'posts_per_page' => -1, // Count all
|
||||||
|
'fields' => 'ids' // Only need IDs for counting
|
||||||
|
];
|
||||||
|
$query = new WP_Query($args);
|
||||||
|
return $query->post_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- End Dashboard Helper Functions ---
|
||||||
add_action( 'template_redirect', 'quiztech_handle_credit_purchase_submission', 1 ); // Hook earlier (priority 1)
|
add_action( 'template_redirect', 'quiztech_handle_credit_purchase_submission', 1 ); // Hook earlier (priority 1)
|
||||||
|
|
|
||||||
111
style.css
111
style.css
|
|
@ -116,3 +116,114 @@
|
||||||
#assessment-builder-library .library-question-item:active {
|
#assessment-builder-library .library-question-item:active {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Quiztech Dashboard Styles */
|
||||||
|
.quiztech-dashboard-widgets {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* Responsive grid */
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-widget {
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
padding: 15px 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 1px 1px rgba(0,0,0,.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-widget h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-widget h3 {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quick Links Widget */
|
||||||
|
.quick-links ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-links li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-links a.button,
|
||||||
|
.quick-links span.button.disabled {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
color: #555;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-links a.button:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-color: #999;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-links span.button.disabled {
|
||||||
|
background-color: #eee;
|
||||||
|
color: #aaa;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Statistics Widget */
|
||||||
|
.statistics p {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistics strong {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recent Activity Widget */
|
||||||
|
.recent-activity .activity-section {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activity ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activity li {
|
||||||
|
padding: 5px 0;
|
||||||
|
border-bottom: 1px dotted #eee;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activity li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activity strong {
|
||||||
|
color: #0073aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recent-activity em {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,100 @@ get_header(); ?>
|
||||||
</header><!-- .entry-header -->
|
</header><!-- .entry-header -->
|
||||||
|
|
||||||
<div class="entry-content">
|
<div class="entry-content">
|
||||||
<p><?php esc_html_e( 'Welcome to the Quiztech Dashboard. Placeholder content.', 'quiztech' ); ?></p>
|
<?php
|
||||||
<!-- Add dashboard widgets, summaries, links here -->
|
// Fetch dashboard data using helper functions
|
||||||
|
$quick_links = function_exists('quiztech_get_dashboard_quick_links') ? quiztech_get_dashboard_quick_links() : [];
|
||||||
|
$recent_invitations = function_exists('quiztech_get_dashboard_recent_invitations') ? quiztech_get_dashboard_recent_invitations() : [];
|
||||||
|
$recent_completions = function_exists('quiztech_get_dashboard_recent_completions') ? quiztech_get_dashboard_recent_completions() : [];
|
||||||
|
$active_job_count = function_exists('quiztech_get_dashboard_active_job_count') ? quiztech_get_dashboard_active_job_count() : 0;
|
||||||
|
$credit_balance = ( function_exists('\Quiztech\AssessmentPlatform\Includes\quiztech_get_user_credit_balance') && is_user_logged_in() ) // Correct function name and namespace check
|
||||||
|
? \Quiztech\AssessmentPlatform\Includes\quiztech_get_user_credit_balance( get_current_user_id() ) // Correct function call
|
||||||
|
: __('N/A', 'quiztech');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="quiztech-dashboard-widgets">
|
||||||
|
|
||||||
|
<!-- Quick Links Widget -->
|
||||||
|
<div class="dashboard-widget quick-links">
|
||||||
|
<h2><?php esc_html_e('Quick Links', 'quiztech'); ?></h2>
|
||||||
|
<?php if (!empty($quick_links)) : ?>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($quick_links as $label => $url) : ?>
|
||||||
|
<?php if (!empty($url)) : ?>
|
||||||
|
<li><a href="<?php echo esc_url($url); ?>" class="button"><?php echo esc_html($label); ?></a></li>
|
||||||
|
<?php else : ?>
|
||||||
|
<li><span class="button disabled"><?php echo esc_html($label); ?> (<?php esc_html_e('Page not found', 'quiztech'); ?>)</span></li>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e('Quick links could not be loaded.', 'quiztech'); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Statistics Widget -->
|
||||||
|
<div class="dashboard-widget statistics">
|
||||||
|
<h2><?php esc_html_e('Statistics', 'quiztech'); ?></h2>
|
||||||
|
<p>
|
||||||
|
<strong><?php esc_html_e('Active Jobs:', 'quiztech'); ?></strong>
|
||||||
|
<?php echo esc_html($active_job_count); ?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong><?php esc_html_e('Credits Remaining:', 'quiztech'); ?></strong>
|
||||||
|
<?php echo esc_html($credit_balance); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Recent Activity Widget -->
|
||||||
|
<div class="dashboard-widget recent-activity">
|
||||||
|
<h2><?php esc_html_e('Recent Activity', 'quiztech'); ?></h2>
|
||||||
|
|
||||||
|
<div class="activity-section">
|
||||||
|
<h3><?php esc_html_e('Invitations Sent', 'quiztech'); ?></h3>
|
||||||
|
<?php if (!empty($recent_invitations)) : ?>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($recent_invitations as $invitation) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo esc_html(gmdate('Y-m-d', strtotime($invitation->created_at))); ?> -
|
||||||
|
<?php printf(
|
||||||
|
/* translators: 1: Applicant Email, 2: Job Title */
|
||||||
|
esc_html__('Invited %1$s for %2$s', 'quiztech'),
|
||||||
|
'<strong>' . esc_html($invitation->applicant_email) . '</strong>',
|
||||||
|
'<em>' . esc_html($invitation->job_title ?: __('N/A', 'quiztech')) . '</em>'
|
||||||
|
); ?>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e('No recent invitations found.', 'quiztech'); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="activity-section">
|
||||||
|
<h3><?php esc_html_e('Assessments Completed', 'quiztech'); ?></h3>
|
||||||
|
<?php if (!empty($recent_completions)) : ?>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($recent_completions as $completion) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo esc_html(gmdate('Y-m-d', strtotime($completion['completion_date']))); ?> -
|
||||||
|
<?php printf(
|
||||||
|
/* translators: 1: Applicant Email, 2: Job Title */
|
||||||
|
esc_html__('%1$s completed assessment for %2$s', 'quiztech'),
|
||||||
|
'<strong>' . esc_html($completion['applicant_email']) . '</strong>',
|
||||||
|
'<em>' . esc_html($completion['job_title'] ?: __('N/A', 'quiztech')) . '</em>'
|
||||||
|
); ?>
|
||||||
|
<?php /* <a href="<?php echo esc_url(get_edit_post_link($completion['evaluation_id'])); ?>">(View)</a> */ ?>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e('No recent completions found.', 'quiztech'); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div> <!-- .quiztech-dashboard-widgets -->
|
||||||
|
|
||||||
</div><!-- .entry-content -->
|
</div><!-- .entry-content -->
|
||||||
|
|
||||||
</article><!-- #post-<?php the_ID(); ?> -->
|
</article><!-- #post-<?php the_ID(); ?> -->
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue