38682-vm/rate.php
2026-02-25 18:22:13 +00:00

504 lines
19 KiB
PHP

<?php
require_once 'db/config.php';
require_once 'includes/functions.php';
$companySettings = get_company_settings();
$companyName = $companySettings['company_name'] ?? 'Foody';
$logoUrl = $companySettings['logo_url'] ?? '';
// Handle rating submission
$success = false;
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$ratingType = $_POST['rating_type'] ?? 'staff'; // 'staff' or 'service'
$userId = $_POST['user_id'] ?? null;
$rating = $_POST['rating'] ?? null;
$comment = $_POST['comment'] ?? '';
if ($rating) {
try {
$pdo = db();
if ($ratingType === 'service') {
$stmt = $pdo->prepare("INSERT INTO service_ratings (rating, comment) VALUES (?, ?)");
$stmt->execute([$rating, $comment]);
$success = true;
} else if ($userId) {
$stmt = $pdo->prepare("INSERT INTO staff_ratings (user_id, rating, comment) VALUES (?, ?, ?)");
$stmt->execute([$userId, $rating, $comment]);
$success = true;
} else {
$error = "Please select a staff member.";
}
} catch (Exception $e) {
$error = "Error saving rating: " . $e->getMessage();
}
} else {
$error = "Please provide a rating.";
}
}
// Fetch active and ratable users with pictures
$pdo = db();
$stmt = $pdo->query("SELECT id, full_name, full_name_ar, username, profile_pic FROM users WHERE is_active = 1 AND is_ratable = 1 ORDER BY full_name ASC");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rate Our Service - <?= htmlspecialchars($companyName) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Noto+Sans+Arabic:wght@400;600;700&display=swap" rel="stylesheet">
<?php if ($success): ?>
<meta http-equiv="refresh" content="3;url=rate.php">
<?php endif; ?>
<style>
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--accent-color: #ffc107;
--bg-gradient: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
}
body {
font-family: 'Inter', sans-serif;
background: var(--bg-gradient);
min-height: 100vh;
color: #333;
transition: all 0.3s ease;
}
body.rtl {
font-family: 'Noto Sans Arabic', sans-serif;
direction: rtl;
}
.rating-container {
max-width: 900px;
margin: 40px auto;
padding: 20px;
}
.header {
text-align: center;
margin-bottom: 40px;
position: relative;
}
.lang-toggle {
position: absolute;
top: 0;
right: 0;
z-index: 100;
}
body.rtl .lang-toggle {
right: auto;
left: 0;
}
.logo {
max-height: 60px;
margin-bottom: 15px;
}
.staff-card, .service-card {
background: white;
border-radius: 15px;
border: none;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
transition: all 0.3s ease;
cursor: pointer;
text-align: center;
padding: 20px;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.service-card {
background: linear-gradient(135deg, #ffffff 0%, #f0f7ff 100%);
border: 1px solid #e0e0e0;
}
.staff-card:hover, .service-card:hover {
transform: translateY(-10px);
box-shadow: 0 15px 30px rgba(0,0,0,0.1);
border: 2px solid var(--primary-color);
}
.staff-pic {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
margin-bottom: 15px;
background: #eee;
border: 3px solid white;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.service-icon {
width: 100px;
height: 100px;
border-radius: 50%;
background: var(--primary-color);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
margin-bottom: 15px;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.staff-name, .service-name {
font-weight: 600;
font-size: 1.1rem;
margin-bottom: 5px;
}
.star-rating {
display: flex;
flex-direction: row-reverse;
justify-content: center;
gap: 5px;
margin: 20px 0;
}
.star-rating input {
display: none;
}
.star-rating label {
font-size: 2.5rem;
color: #ddd;
cursor: pointer;
transition: color 0.2s;
}
.star-rating label:hover,
.star-rating label:hover ~ label,
.star-rating input:checked ~ label {
color: var(--accent-color);
}
.btn-submit {
background: var(--primary-color);
border: none;
padding: 12px 30px;
border-radius: 30px;
font-weight: 600;
color: white;
transition: all 0.3s;
width: 100%;
margin-top: 20px;
}
.btn-submit:hover {
background: #0056b3;
transform: scale(1.02);
}
#rating-form {
display: none;
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 15px 40px rgba(0,0,0,0.1);
margin-top: 30px;
}
.success-animation {
text-align: center;
padding: 40px;
}
.success-icon {
font-size: 5rem;
color: #28a745;
margin-bottom: 20px;
}
/* Decorative shapes */
.shape {
position: fixed;
z-index: -1;
opacity: 0.5;
}
.shape-1 { top: 10%; left: 5%; width: 100px; height: 100px; background: #007bff22; border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; }
.shape-2 { bottom: 10%; right: 5%; width: 150px; height: 150px; background: #ffc10711; border-radius: 50%; }
.name-ar {
display: block;
font-size: 0.9rem;
color: var(--secondary-color);
margin-top: 2px;
}
</style>
</head>
<body>
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="container rating-container">
<div class="header">
<div class="lang-toggle">
<button class="btn btn-sm btn-outline-primary rounded-pill px-3 fw-bold" onclick="toggleLanguage()">
<i class="bi bi-translate me-1"></i> <span id="lang-btn-text">العربية</span>
</button>
</div>
<?php if ($logoUrl): ?>
<img src="<?= get_base_url() . htmlspecialchars($logoUrl) ?>?v=<?= time() ?>" alt="Logo" class="logo">
<?php else: ?>
<h1 class="fw-bold"><?= htmlspecialchars($companyName) ?></h1>
<?php endif; ?>
<p class="text-muted" id="main-instruction" data-t="main_instruction">We value your feedback! What would you like to rate?</p>
</div>
<?php if ($success): ?>
<div class="success-animation card border-0 shadow-sm rounded-4">
<div class="card-body">
<i class="bi bi-check-circle-fill success-icon"></i>
<h2 data-t="thank_you">Thank You!</h2>
<p data-t="success_msg">Your rating has been submitted successfully.</p>
<a href="rate.php" class="btn btn-outline-primary rounded-pill px-4 mt-3" data-t="back_home">Rate Again</a>
</div>
</div>
<?php else: ?>
<?php if ($error): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?= htmlspecialchars($error) ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row g-4" id="staff-list">
<!-- Rate Us Card -->
<div class="col-12 col-md-6 offset-md-3 mb-3">
<div class="service-card" onclick="selectService()">
<div class="service-icon">
<i class="bi bi-shop"></i>
</div>
<div class="service-name fs-4" data-t="rate_services">Rate Our Services</div>
<p class="text-muted small" data-t="service_subtitle">How was your overall experience with us?</p>
</div>
</div>
<div class="col-12 text-center mt-5 mb-2">
<h5 class="fw-bold text-muted" data-t="or_rate_staff">OR RATE OUR STAFF</h5>
</div>
<?php if (empty($users)): ?>
<div class="col-12 text-center">
<p class="text-muted" data-t="no_staff">No staff members are currently available for rating.</p>
</div>
<?php else: ?>
<?php foreach ($users as $user): ?>
<div class="col-6 col-md-3">
<div class="staff-card" onclick="selectStaff(<?= $user['id'] ?>, '<?= htmlspecialchars($user['full_name']) ?>', '<?= htmlspecialchars($user['full_name_ar'] ?: $user['full_name']) ?>', this)">
<?php if ($user['profile_pic']): ?>
<img src="<?= htmlspecialchars($user['profile_pic']) ?>" alt="<?= htmlspecialchars($user['full_name']) ?>" class="staff-pic">
<?php else: ?>
<div class="staff-pic d-flex align-items-center justify-content-center bg-primary text-white fs-2 fw-bold">
<?= strtoupper(substr($user['full_name'] ?: $user['username'], 0, 1)) ?>
</div>
<?php endif; ?>
<div class="staff-name">
<span class="name-en"><?= htmlspecialchars($user['full_name'] ?: $user['username']) ?></span>
<?php if ($user['full_name_ar']): ?>
<span class="name-ar"><?= htmlspecialchars($user['full_name_ar']) ?></span>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<form id="rating-form" method="POST">
<input type="hidden" name="rating_type" id="rating-type" value="staff">
<input type="hidden" name="user_id" id="selected-user-id">
<div class="text-center mb-4">
<h4 id="rating-title" class="fw-bold mb-0"><span data-t="rate">Rate</span> <span id="staff-display-name"></span></h4>
<p id="rating-subtitle" class="text-muted"></p>
<div class="star-rating">
<input type="radio" id="star5" name="rating" value="5" required /><label for="star5" title="5 stars"><i class="bi bi-star-fill"></i></label>
<input type="radio" id="star4" name="rating" value="4" /><label for="star4" title="4 stars"><i class="bi bi-star-fill"></i></label>
<input type="radio" id="star3" name="rating" value="3" /><label for="star3" title="3 stars"><i class="bi bi-star-fill"></i></label>
<input type="radio" id="star2" name="rating" value="2" /><label for="star2" title="2 stars"><i class="bi bi-star-fill"></i></label>
<input type="radio" id="star1" name="rating" value="1" /><label for="star1" title="1 star"><i class="bi bi-star-fill"></i></label>
</div>
</div>
<div class="mb-3">
<label for="comment" class="form-label fw-semibold" id="comment-label" data-t="comments_label">Any additional comments?</label>
<textarea class="form-control rounded-4 shadow-sm border-0 bg-light" name="comment" id="comment" rows="3" placeholder="Tell us about your experience..." data-tp="comment_placeholder"></textarea>
</div>
<div class="row g-3">
<div class="col-6">
<button type="button" class="btn btn-light w-100 rounded-pill py-3 fw-bold" onclick="cancelSelection()" data-t="cancel">Cancel</button>
</div>
<div class="col-6">
<button type="submit" class="btn btn-primary btn-submit m-0 py-3 fw-bold" data-t="submit">Submit Rating</button>
</div>
</div>
</form>
<?php endif; ?>
</div>
<script>
const translations = {
en: {
main_instruction: "We value your feedback! What would you like to rate?",
thank_you: "Thank You!",
success_msg: "Your rating has been submitted successfully.",
back_home: "Rate Again",
rate_services: "Rate Our Services",
service_subtitle: "How was your overall experience with us?",
or_rate_staff: "OR RATE OUR STAFF",
no_staff: "No staff members are currently available for rating.",
rate: "Rate",
rate_staff_subtitle: "Rate the service provided by this staff member.",
rate_service_subtitle: "We would love to hear how we are doing overall.",
comments_label: "Any additional comments?",
comment_placeholder: "Tell us about your experience...",
improve_label: "What can we improve?",
specific_feedback: "Any specific feedback for {name}?",
cancel: "Cancel",
submit: "Submit Rating",
lang_btn: "العربية",
our_services: "Our Services"
},
ar: {
main_instruction: "نحن نقدر رأيك! ما الذي تود تقييمه؟",
thank_you: "شكراً لك!",
success_msg: "تم إرسال تقييمك بنجاح.",
back_home: "تقييم مرة أخرى",
rate_services: "قيم خدماتنا",
service_subtitle: "كيف كانت تجربتك العامة معنا؟",
or_rate_staff: "أو قيم موظفينا",
no_staff: "لا يوجد موظفون متاحون للتقييم حالياً.",
rate: "تقييم",
rate_staff_subtitle: "قيم الخدمة المقدمة من قبل هذا الموظف.",
rate_service_subtitle: "نود معرفة رأيك في أدائنا العام.",
comments_label: "أي تعليقات إضافية؟",
comment_placeholder: "أخبرنا عن تجربتك...",
improve_label: "ما الذي يمكننا تحسينه؟",
specific_feedback: "أي ملاحظات محددة لـ {name}؟",
cancel: "إلغاء",
submit: "إرسال التقييم",
lang_btn: "English",
our_services: "خدماتنا"
}
};
let currentLang = localStorage.getItem('rate_lang') || 'en';
let currentStaffName = { en: '', ar: '' };
let currentMode = 'list'; // 'list' or 'form'
let currentRatingType = 'staff';
function updateUI() {
const t = translations[currentLang];
document.body.classList.toggle('rtl', currentLang === 'ar');
document.getElementById('lang-btn-text').innerText = t.lang_btn;
document.querySelectorAll('[data-t]').forEach(el => {
const key = el.getAttribute('data-t');
if (t[key]) el.innerText = t[key];
});
document.querySelectorAll('[data-tp]').forEach(el => {
const key = el.getAttribute('data-tp');
if (t[key]) el.placeholder = t[key];
});
if (currentMode === 'form') {
if (currentRatingType === 'service') {
document.getElementById('staff-display-name').innerText = t.our_services;
document.getElementById('rating-subtitle').innerText = t.rate_service_subtitle;
document.getElementById('comment-label').innerText = t.improve_label;
} else {
const name = currentLang === 'ar' ? currentStaffName.ar : currentStaffName.en;
document.getElementById('staff-display-name').innerText = name;
document.getElementById('rating-subtitle').innerText = t.rate_staff_subtitle;
document.getElementById('comment-label').innerText = t.specific_feedback.replace('{name}', name);
}
}
}
function toggleLanguage() {
currentLang = currentLang === 'en' ? 'ar' : 'en';
localStorage.setItem('rate_lang', currentLang);
updateUI();
}
function selectService() {
currentMode = 'form';
currentRatingType = 'service';
// Hide staff list
document.getElementById('staff-list').style.display = 'none';
document.getElementById('main-instruction').style.display = 'none';
// Set type to service
document.getElementById('rating-type').value = 'service';
document.getElementById('selected-user-id').value = '';
// Show rating form
document.getElementById('rating-form').style.display = 'block';
updateUI();
window.scrollTo({ top: 0, behavior: 'smooth' });
}
function selectStaff(id, nameEn, nameAr, element) {
currentMode = 'form';
currentRatingType = 'staff';
currentStaffName = { en: nameEn, ar: nameAr };
// Hide staff list
document.getElementById('staff-list').style.display = 'none';
document.getElementById('main-instruction').style.display = 'none';
// Set type to staff
document.getElementById('rating-type').value = 'staff';
document.getElementById('selected-user-id').value = id;
// Show rating form
document.getElementById('rating-form').style.display = 'block';
updateUI();
window.scrollTo({ top: 0, behavior: 'smooth' });
}
function cancelSelection() {
currentMode = 'list';
document.getElementById('rating-form').style.display = 'none';
document.getElementById('staff-list').style.display = 'flex';
document.getElementById('main-instruction').style.display = 'block';
// Clear form
document.getElementById('comment').value = '';
const radios = document.getElementsByName('rating');
for(let i=0; i<radios.length; i++) radios[i].checked = false;
updateUI();
}
// Initial UI update
updateUI();
</script>
</body>
</html>