adding rating system

This commit is contained in:
Flatlogic Bot 2026-02-23 17:32:54 +00:00
parent 54fe86501d
commit 5914657321
13 changed files with 1046 additions and 201 deletions

88
INSTALL.md Normal file
View File

@ -0,0 +1,88 @@
# Installation Guide
Follow these steps to set up the application on your server.
## 1. Requirements
Before you begin, ensure your server meets the following requirements:
* **Operating System:** Linux, Windows, or macOS.
* **Web Server:** Apache 2.4+ (with `mod_rewrite` enabled).
* **PHP:** Version 8.0 or higher.
* **Database:** MariaDB 10.4+ or MySQL 5.7+.
* **PHP Extensions:**
* `pdo_mysql`
* `curl`
* `gd` (for image processing)
* `mbstring`
* `json`
## 2. Database Setup
1. **Create a Database:** Create a new MySQL/MariaDB database (e.g., `pos_system`).
2. **Configure Connection:** Rename `db/config.php.example` to `db/config.php` (if not already present) and update the database credentials:
```php
define('DB_HOST', 'localhost');
define('DB_NAME', 'your_database_name');
define('DB_USER', 'your_username');
define('DB_PASS', 'your_password');
```
3. **Import Schema:** Import the base schema from `db/schema.sql` into your database.
4. **Run Migrations:** Import all SQL files located in `db/migrations/` in sequential order (001, 002, etc.).
5. **Initialize Data:** Run the initialization script by visiting `http://your-domain.com/db/init.php` in your browser. This will seed categories, products, and outlets.
## 3. Creating a Super Admin
Since the initial setup does not include a default user for security reasons, you must create the first Administrator account.
### Option A: Using the Setup Script (Recommended)
Create a temporary file named `setup_admin.php` in the root directory with the following content:
```php
<?php
require_once 'db/config.php';
require_once 'includes/functions.php';
$pdo = db();
$username = 'admin';
$password = password_hash('admin123', PASSWORD_DEFAULT);
$full_name = 'Super Admin';
$email = 'admin@example.com';
// Ensure the Administrator group exists
$stmt = $pdo->prepare("SELECT id FROM user_groups WHERE name = 'Administrator' LIMIT 1");
$stmt->execute();
$group_id = $stmt->fetchColumn();
if (!$group_id) {
$pdo->exec("INSERT INTO user_groups (name, permissions) VALUES ('Administrator', 'all')");
$group_id = $pdo->lastInsertId();
}
// Create the user
try {
$stmt = $pdo->prepare("INSERT INTO users (group_id, username, password, full_name, email, is_active) VALUES (?, ?, ?, ?, ?, 1)");
$stmt->execute([$group_id, $username, $password, $full_name, $email]);
echo "Super Admin created successfully!<br>Username: admin<br>Password: admin123<br><b>Please delete this file immediately!</b>";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
```
Visit `http://your-domain.com/setup_admin.php` and then **delete the file**.
### Option B: Manual SQL
If you prefer SQL, run the following (replace the password hash with one generated via `password_hash()` in PHP):
```sql
INSERT INTO users (group_id, username, password, full_name, email, is_active)
VALUES (1, 'admin', 'REPLACE_WITH_HASH', 'Super Admin', 'admin@example.com', 1);
```
## 4. Final Steps
1. **File Permissions:** Ensure the `assets/images/` directory is writable by the web server for uploading product and ad images.
2. **Login:** Go to `http://your-domain.com/login.php` and log in with your new credentials.
3. **Company Settings:** Navigate to **Admin -> Company Settings** to configure your restaurant name, address, and currency.
---
**Security Note:** Always ensure your `db/config.php` and `.env` files are not accessible from the public web.

View File

@ -457,7 +457,7 @@ function can_view($module) {
<?php endif; ?>
<?php
$userGroupPages = ['users.php', 'user_edit.php', 'user_groups.php', 'user_group_edit.php', 'attendance.php'];
$userGroupPages = [ 'ratings.php','users.php', 'user_edit.php', 'user_groups.php', 'user_group_edit.php', 'attendance.php'];
$canViewUserGroup = can_view('users') || can_view('user_groups');
if ($canViewUserGroup):
?>
@ -488,6 +488,11 @@ function can_view($module) {
<i class="bi bi-calendar-check me-2"></i> Attendance
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= isActive('ratings.php') ?>" href="ratings.php">
<i class="bi bi-star me-2"></i> Staff Ratings
</a>
</li>
</ul>
</div>
</div>

3
admin/rating.php Normal file
View File

@ -0,0 +1,3 @@
<?php
header('Location: ratings.php');
exit;

227
admin/ratings.php Normal file
View File

@ -0,0 +1,227 @@
<?php
require_once 'includes/header.php';
// Check permission
if (function_exists('require_permission')) {
require_permission('users_view'); // Reuse user view permission for ratings
}
$pdo = db();
$tab = $_GET['tab'] ?? 'staff';
// Fetch Staff summary stats
$summaryStmt = $pdo->query("
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
GROUP BY u.id
ORDER BY avg_rating DESC
");
$summaries = $summaryStmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch Service summary stats
$serviceSummaryStmt = $pdo->query("
SELECT AVG(rating) as avg_rating, COUNT(id) as total_ratings FROM service_ratings
");
$serviceSummary = $serviceSummaryStmt->fetch(PDO::FETCH_ASSOC);
if ($tab === 'service') {
$query = "SELECT * FROM service_ratings ORDER BY created_at DESC";
} else {
$query = "
SELECT r.*, u.full_name, u.username, u.profile_pic
FROM staff_ratings r
JOIN users u ON r.user_id = u.id
ORDER BY r.created_at DESC
";
}
$pagination = paginate_query($pdo, $query);
$ratings = $pagination['data'];
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="h3 mb-0 text-gray-800">Ratings & Feedback</h2>
<div class="d-flex gap-2">
<button class="btn btn-warning btn-sm rounded-pill" onclick="showRatingQR()">
<i class="bi bi-qr-code"></i> Share Rating QR
</button>
<a href="../rate.php" target="_blank" class="btn btn-outline-primary btn-sm rounded-pill">
<i class="bi bi-box-arrow-up-right"></i> Open Public Rating Page
</a>
</div>
</div>
<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>
<?php if ($tab === 'staff'): ?>
<!-- Staff Summary Cards -->
<?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 ($summary['profile_pic']): ?>
<img src="../<?= htmlspecialchars($summary['profile_pic']) ?>" alt="Staff" class="rounded-circle mb-3" style="width: 64px; height: 64px; object-fit: cover;">
<?php else: ?>
<div class="rounded-circle bg-light d-inline-flex align-items-center justify-content-center mb-3" style="width: 64px; height: 64px;">
<i class="bi bi-person fs-2 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">
<?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">(<?= number_format($summary['avg_rating'], 1) ?>)</span>
</div>
<p class="text-muted small mb-0"><?= $summary['total_ratings'] ?> total ratings</p>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php else: ?>
<!-- Service Summary Card -->
<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">
Based on <?= $serviceSummary['total_ratings'] ?> customer reviews
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<!-- Detailed List -->
<div class="card border-0 shadow-sm rounded-4">
<div class="card-header bg-white py-3">
<h5 class="card-title mb-0"><?= $tab === 'service' ? 'Service Feedback' : 'Staff Feedback' ?></h5>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th>Date</th>
<?php if ($tab === 'staff'): ?><th>Staff Member</th><?php endif; ?>
<th>Rating</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<?php if (empty($ratings)): ?>
<tr>
<td colspan="<?= $tab === 'staff' ? 4 : 3 ?>" class="text-center py-4 text-muted">No ratings found yet.</td>
</tr>
<?php else: ?>
<?php foreach ($ratings as $rating): ?>
<tr>
<td class="small text-muted">
<?= date('M d, Y H:i', strtotime($rating['created_at'])) ?>
</td>
<?php if ($tab === 'staff'): ?>
<td>
<div class="d-flex align-items-center">
<?php if ($rating['profile_pic']): ?>
<img src="../<?= htmlspecialchars($rating['profile_pic']) ?>" class="rounded-circle me-2" style="width: 32px; height: 32px; object-fit: cover;">
<?php endif; ?>
<span><?= htmlspecialchars($rating['full_name'] ?: $rating['username']) ?></span>
</div>
</td>
<?php endif; ?>
<td>
<div class="text-warning">
<?php
for ($i = 1; $i <= 5; $i++) {
echo $i <= $rating['rating'] ? '<i class="bi bi-star-fill"></i>' : '<i class="bi bi-star text-muted"></i>';
}
?>
</div>
</td>
<td>
<span class="text-muted small"><?= htmlspecialchars($rating['comment'] ?: '-') ?></span>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="card-footer bg-white">
<?php render_pagination_controls($pagination); ?>
</div>
</div>
<!-- Rating QR Modal -->
<div class="modal fade" id="ratingQRModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header bg-warning">
<h5 class="modal-title fw-bold text-dark"><i class="bi bi-star-fill me-2"></i> Customer Rating QR</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center py-4">
<p class="text-muted mb-4">Show this QR code to the customer to rate our staff and service.</p>
<div class="mb-4">
<img id="rating-qr-img" src="" alt="Rating QR Code" class="img-fluid border p-3 bg-white shadow-sm" style="max-width: 250px;">
</div>
<div class="alert alert-light border small text-break text-center mb-0" id="rating-url-text"></div>
</div>
<div class="modal-footer border-top-0 justify-content-center pb-4">
<button class="btn btn-primary px-4 fw-bold" onclick="window.print()">
<i class="bi bi-printer me-2"></i> Print QR Code
</button>
</div>
</div>
</div>
</div>
<script>
const BASE_URL = '<?= get_base_url() ?>';
function showRatingQR() {
const ratingUrl = BASE_URL + 'rate.php';
document.getElementById('rating-qr-img').src = 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' + encodeURIComponent(ratingUrl);
document.getElementById('rating-url-text').textContent = ratingUrl;
const modal = new bootstrap.Modal(document.getElementById('ratingQRModal'));
modal.show();
}
</script>
<?php require_once 'includes/footer.php'; ?>

View File

@ -26,6 +26,7 @@ if ($id) {
'group_id' => '',
'employee_id' => '',
'is_active' => 1,
'is_ratable' => 0,
'profile_pic' => '',
'created_at' => date('Y-m-d H:i:s')
];
@ -40,6 +41,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$group_id = $_POST['group_id'];
$employee_id = $_POST['employee_id'] ?? null;
$is_active = isset($_POST['is_active']) ? 1 : 0;
$is_ratable = isset($_POST['is_ratable']) ? 1 : 0;
$assigned_outlets = $_POST['outlets'] ?? [];
$password = $_POST['password'] ?? '';
@ -60,8 +62,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
if ($id) {
// Update
$sql = "UPDATE users SET full_name = ?, username = ?, email = ?, group_id = ?, is_active = ?, employee_id = ? WHERE id = ?";
$params = [$full_name, $username, $email, $group_id, $is_active, $employee_id, $id];
$sql = "UPDATE users SET full_name = ?, username = ?, email = ?, group_id = ?, is_active = ?, is_ratable = ?, employee_id = ? WHERE id = ?";
$params = [$full_name, $username, $email, $group_id, $is_active, $is_ratable, $employee_id, $id];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
@ -73,8 +75,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
// Insert
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO users (full_name, username, email, group_id, is_active, employee_id, password) VALUES (?, ?, ?, ?, ?, ?, ?)";
$params = [$full_name, $username, $email, $group_id, $is_active, $employee_id, $hashed_password];
$sql = "INSERT INTO users (full_name, username, email, group_id, is_active, is_ratable, employee_id, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$params = [$full_name, $username, $email, $group_id, $is_active, $is_ratable, $employee_id, $hashed_password];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$user_id = $pdo->lastInsertId();
@ -237,12 +239,21 @@ include 'includes/header.php';
<div class="form-text mt-1">Assign one or more outlets to this user.</div>
</div>
<div class="mb-4">
<div class="row mb-4">
<div class="col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="is_active" id="isActiveSwitch" <?= $user['is_active'] ? 'checked' : '' ?>>
<label class="form-check-label fw-bold text-muted small" for="isActiveSwitch">ACTIVE ACCOUNT</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="is_ratable" id="isRatableSwitch" <?= $user['is_ratable'] ? 'checked' : '' ?>>
<label class="form-check-label fw-bold text-muted small" for="isRatableSwitch">DISPLAY IN STAFF RATINGS</label>
</div>
<div class="form-text small mt-1">Enable this to allow customers to rate this staff member in the public rating page.</div>
</div>
</div>
<hr class="my-4">

View File

@ -74,8 +74,9 @@ include 'includes/header.php';
<tr>
<th class="ps-4">User</th>
<th>Role / Group</th>
<th>Employee ID</th>
<th>Emp. ID</th>
<th>Email</th>
<th>Ratable</th>
<th>Status</th>
<th>Joined</th>
<th class="text-end pe-4">Actions</th>
@ -104,7 +105,15 @@ include 'includes/header.php';
<?= htmlspecialchars($user['group_name'] ?: 'No Group') ?>
</span>
</td>
<td><?= htmlspecialchars($user['employee_id'] ?: '-') ?></td>
<td><?= htmlspecialchars($user['email'] ?: '-') ?></td>
<td>
<?php if ($user['is_ratable']): ?>
<span class="badge bg-warning bg-opacity-10 text-warning border border-warning border-opacity-25 px-2 rounded-pill"><i class="bi bi-star-fill small"></i> Yes</span>
<?php else: ?>
<span class="badge bg-secondary bg-opacity-10 text-secondary border border-secondary border-opacity-25 px-2 rounded-pill">No</span>
<?php endif; ?>
</td>
<td>
<?php if ($user['is_active']): ?>
<span class="badge bg-success bg-opacity-10 text-success border border-success border-opacity-25 px-3 rounded-pill">Active</span>

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS staff_ratings (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
rating INT NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

View File

@ -0,0 +1,5 @@
-- Migration: Add is_ratable to users table
-- Description: Allows choosing specific staff members to be rated by customers.
-- Date: 2026-02-23
ALTER TABLE users ADD COLUMN is_ratable TINYINT(1) DEFAULT 0;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS service_ratings (
id INT AUTO_INCREMENT PRIMARY KEY,
rating INT NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -289,3 +289,19 @@ function require_permission($permission) {
exit;
}
}
/**
* Get the base URL of the application.
*
* @return string The base URL.
*/
function get_base_url() {
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$domainName = $_SERVER['HTTP_HOST'];
// Remove admin/ if we are in it
$script_dir = dirname($_SERVER['SCRIPT_NAME']);
$script_dir = str_replace(['/admin', '/api'], '', $script_dir);
if ($script_dir === '/') $script_dir = '';
return $protocol . $domainName . $script_dir . '/';
}

255
index.php
View File

@ -9,6 +9,7 @@ $settings = get_company_settings();
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($settings['company_name']) ?> - Welcome</title>
<meta name="description" content="Welcome to <?= htmlspecialchars($settings['company_name']) ?> POS System. Manage your business efficiently.">
<?php if (!empty($settings['favicon_url'])): ?>
<link rel="icon" href="<?= htmlspecialchars($settings['favicon_url']) ?>">
<?php endif; ?>
@ -17,127 +18,225 @@ $settings = get_company_settings();
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
<style>
:root {
--primary-gradient: linear-gradient(135deg, #6366f1 0%, #a855f7 100%);
--accent-color: #f43f5e;
--bg-soft: #f8fafc;
--card-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
body {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
font-family: 'Inter', sans-serif;
background-color: var(--bg-soft);
color: #1e293b;
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
overflow-x: hidden;
}
/* Background Decorations */
.shape {
position: absolute;
z-index: -1;
filter: blur(80px);
opacity: 0.4;
border-radius: 50%;
}
.shape-1 {
width: 400px;
height: 400px;
background: #6366f1;
top: -100px;
right: -100px;
}
.shape-2 {
width: 300px;
height: 300px;
background: #a855f7;
bottom: -50px;
left: -50px;
}
.main-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
.hero-card {
background: rgba(255, 255, 255, 0.9);
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(12px);
border-radius: 32px;
border: 1px solid rgba(255, 255, 255, 0.5);
box-shadow: var(--card-shadow);
padding: 3rem;
max-width: 1000px;
width: 100%;
text-align: center;
}
.company-logo {
max-height: 100px;
margin-bottom: 1.5rem;
filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
}
.welcome-title {
font-weight: 800;
font-size: 2.5rem;
margin-bottom: 1rem;
background: var(--primary-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.welcome-subtitle {
font-size: 1.1rem;
color: #64748b;
margin-bottom: 3rem;
}
.portal-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
}
.portal-card {
background: #ffffff;
border-radius: 24px;
box-shadow: 0 10px 40px rgba(0,0,0,0.08);
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.5);
transition: transform 0.3s ease;
}
.hero-card:hover {
transform: translateY(-5px);
}
.action-btn {
height: 120px;
padding: 2.5rem;
text-decoration: none;
color: inherit;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid #f1f5f9;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 16px;
font-weight: 600;
font-size: 1.2rem;
transition: all 0.2s ease;
border: 2px solid transparent;
position: relative;
overflow: hidden;
}
.action-btn i {
font-size: 2.5rem;
margin-bottom: 10px;
.portal-card:hover {
transform: translateY(-10px);
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.15);
border-color: #e2e8f0;
}
.btn-dine-in {
background-color: #e3f2fd;
color: #0d6efd;
border-color: #bbdefb;
.portal-card i {
font-size: 3.5rem;
margin-bottom: 1.5rem;
transition: transform 0.3s ease;
}
.btn-dine-in:hover {
background-color: #bbdefb;
color: #0b5ed7;
.portal-card:hover i {
transform: scale(1.1) rotate(5deg);
}
.btn-online {
background-color: #e8f5e9;
color: #198754;
border-color: #c8e6c9;
.portal-card.pos i { color: #6366f1; }
.portal-card.admin i { color: #ec4899; }
.portal-card.feedback i { color: #f59e0b; }
.portal-card h3 {
font-weight: 700;
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.btn-online:hover {
background-color: #c8e6c9;
color: #146c43;
}
.company-logo {
max-height: 80px;
width: auto;
margin-bottom: 20px;
.portal-card p {
font-size: 0.9rem;
color: #64748b;
margin-bottom: 0;
}
.footer {
margin-top: 40px;
padding: 2rem;
text-align: center;
color: #6c757d;
font-size: 0.85rem;
color: #94a3b8;
font-size: 0.875rem;
}
.floating-object {
position: absolute;
width: 40px;
height: 40px;
background: var(--primary-gradient);
border-radius: 8px;
opacity: 0.1;
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0); }
50% { transform: translateY(-20px) rotate(15deg); }
}
@media (max-width: 768px) {
.hero-card { padding: 2rem 1.5rem; }
.welcome-title { font-size: 2rem; }
}
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<div class="hero-card p-5 text-center">
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="main-container">
<div class="hero-card">
<?php if (!empty($settings['logo_url'])): ?>
<img src="<?= htmlspecialchars($settings['logo_url']) ?>" alt="Logo" class="company-logo">
<?php else: ?>
<div class="mb-4">
<i class="bi bi-shop fs-1 text-primary"></i>
<i class="bi bi-grid-1x2-fill fs-1 text-primary"></i>
</div>
<?php endif; ?>
<h1 class="fw-bold mb-2"><?= htmlspecialchars($settings['company_name']) ?></h1>
<p class="text-muted mb-5">Welcome! How would you like to order?</p>
<h1 class="welcome-title"><?= htmlspecialchars($settings['company_name']) ?></h1>
<p class="welcome-subtitle">Your all-in-one business management solution.</p>
<div class="row g-3">
<div class="col-6">
<a href="pos.php?order_type=dine-in" class="text-decoration-none">
<div class="action-btn btn-dine-in">
<i class="bi bi-qr-code-scan"></i>
<span>Dine In / QR</span>
</div>
<div class="portal-grid">
<!-- POS Terminal -->
<a href="pos.php" class="portal-card pos">
<div class="floating-object" style="top: 10%; right: 10%;"></div>
<i class="bi bi-pc-display-horizontal"></i>
<h3>POS Terminal</h3>
<p>Process sales, manage orders, and handle payments.</p>
</a>
</div>
<div class="col-6">
<a href="pos.php?order_type=takeaway" class="text-decoration-none">
<div class="action-btn btn-online">
<i class="bi bi-bag-check"></i>
<span>Online Order</span>
</div>
</a>
</div>
</div>
<div class="mt-5 pt-4 border-top">
<a href="admin/" class="text-muted small text-decoration-none">
<i class="bi bi-shield-lock me-1"></i> Staff Login
<!-- Management Console -->
<a href="admin/" class="portal-card admin">
<div class="floating-object" style="bottom: 10%; left: 10%; animation-delay: 2s; background: linear-gradient(135deg, #ec4899 0%, #f43f5e 100%);"></div>
<i class="bi bi-speedometer2"></i>
<h3>Admin Dashboard</h3>
<p>Inventory, reports, staff management, and settings.</p>
</a>
<a href="kitchen.php" class="text-muted small text-decoration-none ms-3">
<i class="bi bi-egg-fried me-1"></i> Kitchen Display
<!-- Customer Feedback -->
<a href="rate.php" class="portal-card feedback">
<div class="floating-object" style="top: 20%; left: 20%; animation-delay: 1s; background: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%);"></div>
<i class="bi bi-star"></i>
<h3>Rate Our Service</h3>
<p>Tell us about your experience and rate our staff.</p>
</a>
</div>
<div class="mt-5 pt-4">
<p class="text-muted small">
<i class="bi bi-info-circle me-1"></i> Authorized staff access only.
</p>
</div>
</div>
</div>
<div class="footer">
<p>&copy; <?= date('Y') ?> <?= htmlspecialchars($settings['company_name']) ?>. All rights reserved.</p>
<p>Powered By Abidarcafe @2026</p>
</div>
</div>
</div>
<p class="mb-1">&copy; <?= date('Y') ?> <?= htmlspecialchars($settings['company_name']) ?>. All rights reserved.</p>
<p class="mb-0">Powered By Flatlogic POS Solution</p>
</div>
</body>

163
pos.php
View File

@ -110,7 +110,7 @@ if (!$loyalty_settings) {
<span class="fw-bold d-none d-md-block"><?= htmlspecialchars($settings['company_name']) ?></span>
</a>
<div class="d-flex align-items-center gap-3">
<div class="d-flex align-items-center gap-2">
<?php if (has_permission('kitchen_view')): ?>
<a href="kitchen.php" class="btn btn-sm btn-outline-secondary">Kitchen View</a>
<?php endif; ?>
@ -125,8 +125,12 @@ if (!$loyalty_settings) {
<a href="admin/orders.php" class="btn btn-sm btn-outline-secondary">Current Orders</a>
<?php endif; ?>
<button class="btn btn-sm btn-outline-warning" onclick="showRatingQR()">
<i class="bi bi-qr-code"></i> Rating QR
</button>
<div id="current-table-display" class="badge bg-light text-dark border px-3 py-2" style="display: none; font-size: 0.9rem;">
Table <?= htmlspecialchars($table_id) ?>
Table <?= htmlspecialchars((string)$table_id) ?>
</div>
<div class="dropdown">
@ -248,107 +252,65 @@ if (!$loyalty_settings) {
</div>
</div>
<!-- Right: Cart & Order Info -->
<div class="col-md-3 col-12 cart-sidebar">
<!-- Top Section: Customer & Type -->
<div class="p-3 border-bottom bg-white">
<!-- Order Type -->
<div class="btn-group w-100 mb-3" role="group">
<input type="radio" class="btn-check" name="order_type" id="ot-takeaway" value="takeaway" <?= $order_type === 'takeaway' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-takeaway">Takeaway</label>
<input type="radio" class="btn-check" name="order_type" id="ot-dine-in" value="dine-in" <?= $order_type === 'dine-in' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-dine-in">Dine-In</label>
<input type="radio" class="btn-check" name="order_type" id="ot-delivery" value="delivery" <?= $order_type === 'delivery' ? 'checked' : '' ?>>
<label class="btn btn-outline-primary btn-sm" for="ot-delivery">Delivery</label>
<!-- Right Sidebar: Cart -->
<div class="col-md-3 d-none d-md-flex cart-sidebar p-0">
<div class="p-3 border-bottom d-flex justify-content-between align-items-center">
<h6 class="fw-bold mb-0">Current Order</h6>
<span class="badge bg-primary rounded-pill" id="cart-count">0 items</span>
</div>
<!-- Customer Search -->
<div class="position-relative">
<div class="input-group">
<span class="input-group-text bg-white border-end-0"><i class="bi bi-person"></i></span>
<input type="text" class="form-control border-start-0 ps-0" id="customer-search" placeholder="Search Customer..." autocomplete="off">
<button class="btn btn-outline-secondary d-none" type="button" id="clear-customer"><i class="bi bi-x"></i></button>
<button class="btn btn-outline-primary" type="button" id="add-customer-btn" title="Add New Customer">
<i class="bi bi-plus-lg"></i>
<!-- Customer Selection -->
<div class="p-2 border-bottom bg-light">
<div class="input-group input-group-sm mb-1 position-relative">
<span class="input-group-text bg-white"><i class="bi bi-person"></i></span>
<input type="text" id="customer-search" class="form-control" placeholder="Search customer (Name/Phone)..." autocomplete="off">
<button class="btn btn-outline-secondary" type="button" data-bs-toggle="modal" data-bs-target="#addCustomerModal" title="Add New Customer">
<i class="bi bi-person-plus"></i>
</button>
<div id="customer-dropdown" class="list-group shadow-sm position-absolute w-100" style="top: 100%; z-index: 1050; display: none; max-height: 200px; overflow-y: auto;"></div>
</div>
<div class="list-group shadow-sm search-dropdown" id="customer-results"></div>
<input type="hidden" id="selected-customer-id">
<div id="customer-info" class="small text-success mt-1 d-none">
<i class="bi bi-check-circle-fill me-1"></i> <span id="customer-name-display"></span>
</div>
<!-- Loyalty Section (Hidden if disabled) -->
<?php if ($loyalty_settings['is_enabled']): ?>
<div id="loyalty-section" class="d-none mt-2 p-2 bg-warning-subtle rounded border border-warning">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="d-block fw-bold small text-warning-emphasis">Loyalty Points</span>
<span id="loyalty-points-display" class="fw-bold fs-5">0</span>
</div>
<button id="redeem-loyalty-btn" class="btn btn-sm btn-success shadow-sm" disabled>
<i class="bi bi-gift-fill me-1"></i> Redeem Meal
</button>
</div>
<div id="loyalty-message" class="small text-muted mt-1 fst-italic" style="font-size: 0.75rem;"></div>
</div>
<?php endif; ?>
<div id="selected-customer-display" class="d-none alert alert-info p-1 mb-0 mt-1 d-flex justify-content-between align-items-center" style="font-size: 0.8rem;">
<span><i class="bi bi-person-check-fill me-1"></i> <strong id="selected-customer-name"></strong></span>
<button type="button" class="btn-close" style="font-size: 0.6rem;" onclick="clearSelectedCustomer()"></button>
</div>
</div>
<!-- Cart Items (Flex Grow) -->
<div class="flex-grow-1 overflow-auto p-3 bg-white" id="cart-items">
<div class="text-center text-muted mt-5">
<i class="bi bi-basket3 fs-1 text-light"></i>
<!-- Cart Items -->
<div class="scrollable-y flex-grow-1 p-3" id="cart-items">
<div class="text-center text-muted mt-5 py-5">
<i class="bi bi-cart3 fs-1 opacity-25"></i>
<p class="mt-2">Cart is empty</p>
</div>
</div>
<!-- Bottom: Totals & Action -->
<div class="p-3 border-top bg-light">
<div class="d-flex justify-content-between mb-2">
<!-- Cart Summary & Actions -->
<div class="p-3 border-top bg-white shadow-lg">
<div class="d-flex justify-content-between mb-1">
<span class="text-muted">Subtotal</span>
<span class="fw-bold" id="cart-subtotal"><?= format_currency(0) ?></span>
<span id="cart-subtotal">$0.00</span>
</div>
<div class="d-flex justify-content-between mb-1">
<span class="text-muted">VAT (<?= ($settings['vat_rate'] ?? 0) * 100 ?>%)</span>
<span id="cart-tax">$0.00</span>
</div>
<div class="d-flex justify-content-between mb-3 pt-2 border-top">
<h5 class="fw-bold mb-0">Total</h5>
<h5 class="fw-bold mb-0 text-primary" id="cart-total">$0.00</h5>
</div>
<!-- Discount Field -->
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-muted">Discount</span>
<div class="input-group input-group-sm w-50">
<span class="input-group-text bg-white border-end-0 text-muted">-</span>
<input type="number" id="cart-discount-input" class="form-control border-start-0 text-end" value="0" min="0" step="0.01">
</div>
</div>
<div class="d-flex justify-content-between mb-3">
<span class="fs-5 fw-bold">Total</span>
<span class="fs-4 fw-bold text-primary" id="cart-total-price"><?= format_currency(0) ?></span>
</div>
<?php if (has_permission('pos_add')): ?>
<div class="d-flex gap-2 w-100">
<button class="btn btn-primary w-50 btn-lg shadow-sm" id="quick-order-btn" disabled>
Quick Order <i class="bi bi-lightning-fill ms-2"></i>
</button>
<button class="btn btn-warning w-50 btn-lg shadow-sm text-white" id="place-order-btn" disabled>
Place Order <i class="bi bi-clock ms-2"></i>
<div class="row g-2">
<div class="col-6">
<button class="btn btn-outline-danger w-100 py-3 fw-bold" onclick="clearCart()">
<i class="bi bi-trash"></i> CLEAR
</button>
</div>
<div class="col-6">
<button class="btn btn-primary w-100 py-3 fw-bold" onclick="proceedToPayment()">
PAYMENT <i class="bi bi-arrow-right"></i>
</button>
</div>
<?php else: ?>
<div class="alert alert-warning small py-2 mb-0 text-center">
<i class="bi bi-info-circle me-1"></i> View Only Mode
</div>
<?php endif; ?>
<div class="text-center mt-3 text-muted small" style="font-size: 0.7rem;">
Powered By Abidarcafe @2026
</div>
</div>
</div>
</div>
@ -449,12 +411,43 @@ if (!$loyalty_settings) {
</div>
</div>
<!-- Rating QR Modal -->
<div class="modal fade" id="ratingQRModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-warning">
<h5 class="modal-title fw-bold text-dark"><i class="bi bi-star-fill me-2"></i> Customer Rating QR</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center py-4">
<p class="text-muted mb-4">Show this QR code to the customer to rate our staff and service.</p>
<div class="mb-4">
<img id="rating-qr-img" src="" alt="Rating QR Code" class="img-fluid border p-3 bg-white shadow-sm" style="max-width: 250px;">
</div>
<div class="alert alert-light border small text-break" id="rating-url-text"></div>
<button class="btn btn-primary w-100 mt-3" onclick="window.print()">
<i class="bi bi-printer me-2"></i> Print QR Code
</button>
</div>
</div>
</div>
</div>
<script>
const COMPANY_SETTINGS = <?= json_encode($settings) ?>;
const LOYALTY_SETTINGS = <?= json_encode($loyalty_settings) ?>;
const PRODUCT_VARIANTS = <?= json_encode($variants_by_product) ?>;
const PAYMENT_TYPES = <?= json_encode($payment_types) ?>;
const CURRENT_OUTLET = <?= json_encode(['id' => $outlet_id, 'name' => $current_outlet_name]) ?>;
const BASE_URL = '<?= get_base_url() ?>';
function showRatingQR() {
const ratingUrl = BASE_URL + 'rate.php';
document.getElementById('rating-qr-img').src = 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' + encodeURIComponent(ratingUrl);
document.getElementById('rating-url-text').textContent = ratingUrl;
const modal = new bootstrap.Modal(document.getElementById('ratingQRModal'));
modal.show();
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?= time() ?>"></script>

375
rate.php Normal file
View File

@ -0,0 +1,375 @@
<?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, 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&display=swap" rel="stylesheet">
<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;
}
.rating-container {
max-width: 900px;
margin: 40px auto;
padding: 20px;
}
.header {
text-align: center;
margin-bottom: 40px;
}
.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%; }
</style>
</head>
<body>
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="container rating-container">
<div class="header">
<?php if ($logoUrl): ?>
<img src="<?= htmlspecialchars($logoUrl) ?>" alt="Logo" class="logo">
<?php else: ?>
<h1 class="fw-bold"><?= htmlspecialchars($companyName) ?></h1>
<?php endif; ?>
<p class="text-muted" id="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>Thank You!</h2>
<p>Your rating has been submitted successfully.</p>
<a href="index.php" class="btn btn-outline-primary rounded-pill px-4 mt-3">Back to Home</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">Rate Our Services</div>
<p class="text-muted small">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">OR RATE OUR STAFF</h5>
</div>
<?php if (empty($users)): ?>
<div class="col-12 text-center">
<p class="text-muted">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']) ?>', 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"><?= htmlspecialchars($user['full_name'] ?: $user['username']) ?></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">Rate <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">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..."></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()">Cancel</button>
</div>
<div class="col-6">
<button type="submit" class="btn btn-primary btn-submit m-0 py-3 fw-bold">Submit Rating</button>
</div>
</div>
</form>
<?php endif; ?>
</div>
<script>
function selectService() {
// 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 = '';
// Set labels
document.getElementById('staff-display-name').innerText = 'Our Services';
document.getElementById('rating-subtitle').innerText = 'We would love to hear how we are doing overall.';
document.getElementById('comment-label').innerText = 'What can we improve?';
// Show rating form
document.getElementById('rating-form').style.display = 'block';
// Smooth scroll to form
window.scrollTo({ top: 0, behavior: 'smooth' });
}
function selectStaff(id, name, element) {
// 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;
// Set labels
document.getElementById('staff-display-name').innerText = name;
document.getElementById('rating-subtitle').innerText = 'Rate the service provided by this staff member.';
document.getElementById('comment-label').innerText = 'Any specific feedback for ' + name + '?';
// Show rating form
document.getElementById('rating-form').style.display = 'block';
// Smooth scroll to form
window.scrollTo({ top: 0, behavior: 'smooth' });
}
function cancelSelection() {
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;
}
</script>
</body>
</html>