editing admin/rating

This commit is contained in:
Flatlogic Bot 2026-03-10 07:51:01 +00:00
parent 9248543cfe
commit cbac17cdd4

View File

@ -2,24 +2,34 @@
require_once __DIR__ . "/../includes/functions.php"; require_once __DIR__ . "/../includes/functions.php";
require_once __DIR__ . "/../db/config.php"; require_once __DIR__ . "/../db/config.php";
require_permission("ratings_view"); require_permission("ratings_view");
require_once __DIR__ . '/../db/config.php';
$pdo = db(); $pdo = db();
$message = ''; $message = '';
$tab = $_GET['tab'] ?? 'staff';
// Handle Add Rating (Manual) // Handle Add Rating (Manual)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'add_rating') { if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'add_rating') {
$user_id = (int)$_POST['user_id'];
$order_id = !empty($_POST['order_id']) ? (int)$_POST['order_id'] : null;
$rating = (int)$_POST['rating']; $rating = (int)$_POST['rating'];
$comment = trim($_POST['comment']); $comment = trim($_POST['comment']);
$order_id = !empty($_POST['order_id']) ? (int)$_POST['order_id'] : null;
try { if ($tab === 'service') {
$stmt = $pdo->prepare("INSERT INTO staff_ratings (user_id, order_id, rating, comment) VALUES (?, ?, ?, ?)"); try {
$stmt->execute([$user_id, $order_id, $rating, $comment]); $stmt = $pdo->prepare("INSERT INTO service_ratings (rating, comment) VALUES (?, ?)");
$message = '<div class="alert alert-success">Rating added successfully!</div>'; $stmt->execute([$rating, $comment]);
} catch (PDOException $e) { $message = '<div class="alert alert-success">Service rating added successfully!</div>';
$message = '<div class="alert alert-danger">Database error: ' . $e->getMessage() . '</div>'; } catch (PDOException $e) {
$message = '<div class="alert alert-danger">Database error: ' . $e->getMessage() . '</div>';
}
} else {
$user_id = (int)$_POST['user_id'];
try {
$stmt = $pdo->prepare("INSERT INTO staff_ratings (user_id, order_id, rating, comment) VALUES (?, ?, ?, ?)");
$stmt->execute([$user_id, $order_id, $rating, $comment]);
$message = '<div class="alert alert-success">Rating added successfully!</div>';
} catch (PDOException $e) {
$message = '<div class="alert alert-danger">Database error: ' . $e->getMessage() . '</div>';
}
} }
} }
@ -30,8 +40,9 @@ if (isset($_GET['delete'])) {
} else { } else {
try { try {
$id = $_GET['delete']; $id = $_GET['delete'];
$pdo->prepare("DELETE FROM staff_ratings WHERE id = ?")->execute([$id]); $table = ($tab === 'service') ? 'service_ratings' : 'staff_ratings';
header("Location: ratings.php?deleted=1"); $pdo->prepare("DELETE FROM $table WHERE id = ?")->execute([$id]);
header("Location: ratings.php?tab=" . urlencode($tab) . "&deleted=1");
exit; exit;
} catch (PDOException $e) { } catch (PDOException $e) {
$message = '<div class="alert alert-danger">Error deleting rating: ' . $e->getMessage() . '</div>'; $message = '<div class="alert alert-danger">Error deleting rating: ' . $e->getMessage() . '</div>';
@ -45,40 +56,220 @@ if (isset($_GET['deleted'])) {
$staff = $pdo->query("SELECT id, full_name, username FROM users WHERE is_ratable = 1 ORDER BY full_name ASC")->fetchAll(); $staff = $pdo->query("SELECT id, full_name, username FROM users WHERE is_ratable = 1 ORDER BY full_name ASC")->fetchAll();
$query = "SELECT r.*, u.full_name as staff_name, u.username as staff_username // Fetch summaries
FROM staff_ratings r if ($tab === 'staff') {
JOIN users u ON r.user_id = u.id $whereParams = [];
ORDER BY r.created_at DESC"; $whereSql = "";
$ratings_pagination = paginate_query($pdo, $query); if ($filter_staff) {
$ratings = $ratings_pagination['data']; $whereSql .= " AND r.user_id = ?";
$whereParams[] = $filter_staff;
}
if ($filter_start) {
$whereSql .= " AND DATE(r.created_at) >= ?";
$whereParams[] = $filter_start;
}
if ($filter_end) {
$whereSql .= " AND DATE(r.created_at) <= ?";
$whereParams[] = $filter_end;
}
$summaryQuery = "
SELECT u.id, u.full_name, u.username, u.profile_pic,
AVG(r.rating) as avg_rating, COUNT(r.id) as total_ratings
FROM users u
JOIN staff_ratings r ON u.id = r.user_id
WHERE 1=1 $whereSql
GROUP BY u.id
ORDER BY avg_rating DESC
";
$stmt = $pdo->prepare($summaryQuery);
$stmt->execute($whereParams);
$summaries = $stmt->fetchAll(PDO::FETCH_ASSOC);
$query = "SELECT r.*, u.full_name as staff_name, u.username as staff_username, u.profile_pic
FROM staff_ratings r
JOIN users u ON r.user_id = u.id
WHERE 1=1 $whereSql
ORDER BY r.created_at DESC";
$ratings_pagination = paginate_query($pdo, $query, $whereParams);
$ratings = $ratings_pagination['data'];
} else {
$whereParams = [];
$whereSql = "";
if ($filter_start) {
$whereSql .= " AND DATE(created_at) >= ?";
$whereParams[] = $filter_start;
}
if ($filter_end) {
$whereSql .= " AND DATE(created_at) <= ?";
$whereParams[] = $filter_end;
}
$serviceSummaryQuery = "SELECT AVG(rating) as avg_rating, COUNT(id) as total_ratings FROM service_ratings WHERE 1=1 $whereSql";
$stmt = $pdo->prepare($serviceSummaryQuery);
$stmt->execute($whereParams);
$serviceSummary = $stmt->fetch(PDO::FETCH_ASSOC);
$query = "SELECT * FROM service_ratings WHERE 1=1 $whereSql ORDER BY created_at DESC";
$ratings_pagination = paginate_query($pdo, $query, $whereParams);
$ratings = $ratings_pagination['data'];
}
include 'includes/header.php'; include 'includes/header.php';
?> ?>
<div class="d-flex justify-content-between align-items-center mb-4"> <div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold mb-0">Staff Ratings</h2> <h2 class="fw-bold mb-0">Ratings & Feedback</h2>
<button class="btn btn-primary" onclick="openAddModal()"> <div class="d-flex gap-2">
<i class="bi bi-star"></i> Add Manual Rating <a href="../rate.php" target="_blank" class="btn btn-outline-primary">
</button> <i class="bi bi-box-arrow-up-right"></i> Open Public Rating Page
</a>
<button class="btn btn-primary" onclick="openAddModal()">
<i class="bi bi-star"></i> Add Manual Rating
</button>
</div>
</div> </div>
<?= $message ?> <?= $message ?>
<div class="card border-0 shadow-sm"> <ul class="nav nav-pills mb-4 bg-white p-2 rounded-4 shadow-sm d-inline-flex">
<li class="nav-item">
<a class="nav-link rounded-pill <?= $tab === 'staff' ? 'active' : '' ?>" href="?tab=staff">
<i class="bi bi-people me-1"></i> Staff Performance
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill <?= $tab === 'service' ? 'active' : '' ?>" href="?tab=service">
<i class="bi bi-shop me-1"></i> Restaurant Service
</a>
</li>
</ul>
<!-- Filters -->
<div class="card border-0 shadow-sm rounded-4 mb-4">
<div class="card-body">
<form method="GET" class="row g-3 align-items-end">
<input type="hidden" name="tab" value="<?= htmlspecialchars($tab) ?>">
<?php if ($tab === 'staff'): ?>
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">Staff Member</label>
<select name="staff_id" class="form-select">
<option value="">All Staff</option>
<?php foreach ($staff as $s): ?>
<option value="<?= $s['id'] ?>" <?= $filter_staff == $s['id'] ? 'selected' : '' ?> >
<?= htmlspecialchars($s['full_name'] ?: $s['username']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">Start Date</label>
<input type="date" name="start_date" class="form-control" value="<?= htmlspecialchars($filter_start) ?>">
</div>
<div class="col-md-3">
<label class="form-label small fw-bold text-muted">End Date</label>
<input type="date" name="end_date" class="form-control" value="<?= htmlspecialchars($filter_end) ?>">
</div>
<div class="col-md-3">
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-funnel"></i> Filter
</button>
<?php if ($filter_staff || $filter_start || $filter_end): ?>
<a href="?tab=<?= urlencode($tab) ?>" class="btn btn-outline-secondary px-3" title="Clear Filters">
<i class="bi bi-x-circle"></i>
</a>
<?php endif; ?>
</div>
</div>
</form>
</div>
</div>
<?php if ($tab === 'staff'): ?>
<?php if (empty($summaries)): ?>
<div class="alert alert-info border-0 shadow-sm rounded-4 text-center py-4 mb-5">
<i class="bi bi-info-circle fs-2 mb-2"></i>
<p class="mb-0">No staff members have been rated yet.</p>
</div>
<?php else: ?>
<div class="row g-4 mb-5">
<?php foreach ($summaries as $summary): ?>
<div class="col-md-3">
<div class="card border-0 shadow-sm rounded-4 h-100">
<div class="card-body text-center">
<?php if (!empty($summary['profile_pic'])): ?>
<img src="../<?= htmlspecialchars($summary['profile_pic']) ?>" alt="Staff" class="rounded-circle mb-3 shadow-sm" style="width: 56px; height: 56px; object-fit: cover;">
<?php else: ?>
<div class="rounded-circle bg-light d-inline-flex align-items-center justify-content-center mb-3 shadow-sm" style="width: 56px; height: 56px;">
<i class="bi bi-person fs-3 text-primary"></i>
</div>
<?php endif; ?>
<h5 class="card-title mb-1 small fw-bold text-truncate" title="<?= htmlspecialchars($summary['full_name'] ?: $summary['username']) ?>">
<?= htmlspecialchars($summary['full_name'] ?: $summary['username']) ?>
</h5>
<div class="text-warning mb-2" style="font-size: 0.8rem;">
<?php
$avg = round($summary['avg_rating']);
for ($i = 1; $i <= 5; $i++) {
echo $i <= $avg ? '<i class="bi bi-star-fill"></i>' : '<i class="bi bi-star"></i>';
}
?>
<span class="text-muted ms-1 small">(<?= number_format($summary['avg_rating'], 1) ?>)</span>
</div>
<p class="text-muted small mb-0"><?= $summary['total_ratings'] ?> ratings</p>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php else: ?>
<div class="row mb-5">
<div class="col-md-4">
<div class="card border-0 shadow-sm rounded-4 bg-primary text-white">
<div class="card-body text-center py-4">
<i class="bi bi-shop fs-1 mb-3"></i>
<h4 class="fw-bold mb-1">Overall Service</h4>
<div class="fs-2 fw-bold mb-2">
<?php if ($serviceSummary['total_ratings'] > 0): ?>
<?= number_format($serviceSummary['avg_rating'], 1) ?> / 5.0
<?php else: ?>
N/A
<?php endif; ?>
</div>
<div class="text-white-50 small">
Based on <?= $serviceSummary['total_ratings'] ?> reviews
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<div class="card border-0 shadow-sm rounded-4">
<div class="card-header bg-white py-3 border-bottom-0">
<h5 class="card-title mb-0 small fw-bold"><?= $tab === 'service' ? 'Service Feedback' : 'Staff Feedback' ?></h5>
</div>
<div class="card-body p-0"> <div class="card-body p-0">
<!-- Pagination Controls --> <!-- Pagination Controls -->
<div class="p-3 border-bottom bg-light"> <div class="p-3 border-bottom bg-light">
<?php render_pagination_controls($ratings_pagination); ?> <?php render_pagination_controls($ratings_pagination, ['tab' => $tab]); ?>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover align-middle mb-0"> <table class="table table-hover align-middle mb-0">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="ps-4">Date</th> <th class="ps-4">Date</th>
<th>Staff Member</th> <?php if ($tab === 'staff'): ?><th>Staff Member</th><?php endif; ?>
<th>Rating</th> <th>Rating</th>
<th>Comment</th> <th>Comment</th>
<th>Order ID</th> <?php if ($tab === 'staff'): ?><th>Order ID</th><?php endif; ?>
<th class="text-end pe-4">Actions</th> <th class="text-end pe-4">Actions</th>
</tr> </tr>
</thead> </thead>
@ -89,9 +280,20 @@ include 'includes/header.php';
<div class="fw-bold"><?= date('M d, Y', strtotime($r['created_at'])) ?></div> <div class="fw-bold"><?= date('M d, Y', strtotime($r['created_at'])) ?></div>
<small class="text-muted"><?= date('H:i', strtotime($r['created_at'])) ?></small> <small class="text-muted"><?= date('H:i', strtotime($r['created_at'])) ?></small>
</td> </td>
<?php if ($tab === 'staff'): ?>
<td> <td>
<div class="fw-bold text-dark"><?= htmlspecialchars($r['staff_name'] ?: $r['staff_username']) ?></div> <div class="d-flex align-items-center">
<?php if (!empty($r['profile_pic'])): ?>
<img src="../<?= htmlspecialchars($r['profile_pic']) ?>" class="rounded-circle me-2 shadow-sm" style="width: 24px; height: 24px; object-fit: cover;">
<?php else: ?>
<div class="rounded-circle bg-light d-flex align-items-center justify-content-center me-2 shadow-sm" style="width: 24px; height: 24px;">
<i class="bi bi-person text-primary" style="font-size: 0.7rem;"></i>
</div>
<?php endif; ?>
<span class="fw-medium text-dark"><?= htmlspecialchars($r['staff_name'] ?: $r['staff_username']) ?></span>
</div>
</td> </td>
<?php endif; ?>
<td> <td>
<div class="text-warning"> <div class="text-warning">
<?php for($i=1; $i<=5; $i++): ?> <?php for($i=1; $i<=5; $i++): ?>
@ -100,17 +302,19 @@ include 'includes/header.php';
</div> </div>
</td> </td>
<td><small><?= htmlspecialchars($r['comment'] ?: '-') ?></small></td> <td><small><?= htmlspecialchars($r['comment'] ?: '-') ?></small></td>
<td><?= $r['order_id'] ? '#' . $r['order_id'] : '-' ?></td> <?php if ($tab === 'staff'): ?>
<td><?= !empty($r['order_id']) ? '#' . $r['order_id'] : '-' ?></td>
<?php endif; ?>
<td class="text-end pe-4"> <td class="text-end pe-4">
<?php if (has_permission('settings')): ?> <?php if (has_permission('settings')): ?>
<a href="?delete=<?= $r['id'] ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Delete this rating?')"><i class="bi bi-trash"></i></a> <a href="?tab=<?= urlencode($tab) ?>&delete=<?= $r['id'] ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Delete this rating?')"><i class="bi bi-trash"></i></a>
<?php endif; ?> <?php endif; ?>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if (empty($ratings)): ?> <?php if (empty($ratings)): ?>
<tr> <tr>
<td colspan="6" class="text-center py-4 text-muted">No ratings found.</td> <td colspan="<?= $tab === 'staff' ? 6 : 4 ?>" class="text-center py-4 text-muted">No ratings found.</td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
</tbody> </tbody>
@ -118,7 +322,7 @@ include 'includes/header.php';
</div> </div>
<!-- Bottom Pagination --> <!-- Bottom Pagination -->
<div class="p-3 border-top bg-light"> <div class="p-3 border-top bg-light">
<?php render_pagination_controls($ratings_pagination); ?> <?php render_pagination_controls($ratings_pagination, ['tab' => $tab]); ?>
</div> </div>
</div> </div>
</div> </div>
@ -134,6 +338,7 @@ include 'includes/header.php';
<form method="POST" id="ratingForm"> <form method="POST" id="ratingForm">
<div class="modal-body"> <div class="modal-body">
<input type="hidden" name="action" value="add_rating"> <input type="hidden" name="action" value="add_rating">
<?php if ($tab === 'staff'): ?>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Staff Member <span class="text-danger">*</span></label> <label class="form-label">Staff Member <span class="text-danger">*</span></label>
<select name="user_id" class="form-select" required> <select name="user_id" class="form-select" required>
@ -147,6 +352,7 @@ include 'includes/header.php';
<label class="form-label">Order ID (Optional)</label> <label class="form-label">Order ID (Optional)</label>
<input type="number" name="order_id" class="form-control" placeholder="e.g. 1024"> <input type="number" name="order_id" class="form-control" placeholder="e.g. 1024">
</div> </div>
<?php endif; ?>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Rating <span class="text-danger">*</span></label> <label class="form-label">Rating <span class="text-danger">*</span></label>
<select name="rating" class="form-select" required> <select name="rating" class="form-select" required>