add a space between the label and the value in ticket detailes, currently its too clode to ech other that makes it unreadle
<?php
// Start session for custom authentication
session_start();
date_default_timezone_set('Asia/Manila');
// Database connection
$host = 'localhost';
$dbname = 'helpdesk';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Custom security check
if (empty($_SESSION['user_id'])) {
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Get current user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$current_user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_user) {
session_destroy();
header("Location: http://localhost/helpdesk/?page_id=50");
exit;
}
// Base URL for ticket system
$base_url = 'http://localhost/helpdesk/?page_id=70';
// Check if viewing/editing ticket
$viewing_ticket = isset($_GET['ticket_id']);
$editing_ticket = $viewing_ticket && isset($_GET['action']) && $_GET['action'] === 'edit';
$ticket_id = $viewing_ticket ? (int)$_GET['ticket_id'] : 0;
// Handle form submissions
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['create_ticket'])) {
$subject = htmlspecialchars($_POST['subject']);
$description = htmlspecialchars($_POST['description']);
$priority = htmlspecialchars($_POST['priority']);
$department_id = (int)$_POST['department_id'];
try {
// Start transaction
$pdo->beginTransaction();
$ticket_number = 'TKT-' . date('Ymd-His');
$stmt = $pdo->prepare("INSERT INTO tickets
(ticket_number, subject, description, priority, department_id, created_by, status, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, 'open', NOW(), NOW())");
$stmt->execute([
$ticket_number,
$subject,
$description,
$priority,
$department_id,
$current_user['id']
]);
$ticket_id = $pdo->lastInsertId();
// For initial message, set recipient to admin (or any default user)
// Here we'll get the first admin user as recipient
$stmt = $pdo->prepare("SELECT id FROM users WHERE role = 'admin' LIMIT 1");
$stmt->execute();
$admin = $stmt->fetch();
$recipient_id = $admin['id'] ?? $current_user['id']; // Fallback to current user if no admin found
// Add initial message with valid recipient_id
$stmt = $pdo->prepare("INSERT INTO messages
(ticket_id, sender_id, recipient_id, message, is_read, created_at)
VALUES (?, ?, ?, ?, 0, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$recipient_id,
$description
]);
// Commit transaction
$pdo->commit();
// Redirect to prevent form resubmission
header("Location: $base_url&ticket_id=$ticket_id");
exit;
} catch (PDOException $e) {
$pdo->rollBack();
$message = 'Error creating ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['update_status'])) {
$ticket_id = (int)$_POST['ticket_id'];
$status = htmlspecialchars($_POST['status']);
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE tickets SET status = ?, updated_at = NOW() WHERE id = ?");
$stmt->execute([$status, $ticket_id]);
// Get the assigned staff for this ticket to set as recipient
$stmt = $pdo->prepare("SELECT assigned_to FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch();
$recipient_id = $ticket['assigned_to'] ?? $current_user['id']; // Fallback to current user if not assigned
// Add status change message with valid recipient_id
$stmt = $pdo->prepare("INSERT INTO messages
(ticket_id, sender_id, recipient_id, message, is_read, created_at)
VALUES (?, ?, ?, ?, 0, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$recipient_id,
"Status changed to: " . ucfirst($status)
]);
$pdo->commit();
// Redirect to prevent form resubmission
header("Location: $base_url&ticket_id=$ticket_id");
exit;
} catch (PDOException $e) {
$pdo->rollBack();
$message = 'Error updating ticket status: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['assign_ticket'])) {
$ticket_id = (int)$_POST['ticket_id'];
$assign_to = (int)$_POST['assign_to'];
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE tickets SET assigned_to = ?, status = 'assigned', updated_at = NOW() WHERE id = ?");
$stmt->execute([$assign_to, $ticket_id]);
// Add assignment message with valid recipient_id
$stmt = $pdo->prepare("INSERT INTO messages
(ticket_id, sender_id, recipient_id, message, is_read, created_at)
VALUES (?, ?, ?, ?, 0, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$assign_to, // Recipient is the assigned staff
"Ticket assigned to support for resolution."
]);
$pdo->commit();
// Redirect to prevent form resubmission
header("Location: $base_url&ticket_id=$ticket_id");
exit;
} catch (PDOException $e) {
$pdo->rollBack();
$message = 'Error assigning ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
elseif (isset($_POST['add_message'])) {
$ticket_id = (int)$_POST['ticket_id'];
$message_text = htmlspecialchars($_POST['message']);
try {
$pdo->beginTransaction();
// Get the assigned staff for this ticket to set as recipient
$stmt = $pdo->prepare("SELECT assigned_to FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch();
$recipient_id = $ticket['assigned_to'] ?? $current_user['id']; // Fallback to current user if not assigned
// Add message with valid recipient_id
$stmt = $pdo->prepare("INSERT INTO messages
(ticket_id, sender_id, recipient_id, message, is_read, created_at)
VALUES (?, ?, ?, ?, 0, NOW())");
$stmt->execute([
$ticket_id,
$current_user['id'],
$recipient_id,
$message_text
]);
// Update ticket's updated_at
$stmt = $pdo->prepare("UPDATE tickets SET updated_at = NOW() WHERE id = ?");
$stmt->execute([$ticket_id]);
$pdo->commit();
// Redirect to prevent form resubmission
header("Location: $base_url&ticket_id=$ticket_id");
exit;
} catch (PDOException $e) {
$pdo->rollBack();
$message = 'Error adding message: ' . $e->getMessage();
$message_type = 'error';
}
}
}
// Handle ticket deletion (GET request)
if (isset($_GET['delete_ticket'])) {
$ticket_id_to_delete = (int)$_GET['delete_ticket'];
try {
// Verify user has permission to delete
$stmt = $pdo->prepare("SELECT created_by FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id_to_delete]);
$ticket = $stmt->fetch();
$is_admin = in_array($current_user['role'], ['admin', 'staff']);
$is_creator = ($ticket['created_by'] ?? null) == $current_user['id'];
if (!$ticket || (!$is_creator && !$is_admin)) {
$message = 'You do not have permission to delete this ticket';
$message_type = 'error';
} else {
$pdo->beginTransaction();
// First delete messages
$stmt = $pdo->prepare("DELETE FROM messages WHERE ticket_id = ?");
$stmt->execute([$ticket_id_to_delete]);
// Then delete the ticket
$stmt = $pdo->prepare("DELETE FROM tickets WHERE id = ?");
$stmt->execute([$ticket_id_to_delete]);
$pdo->commit();
// Redirect to prevent refresh from deleting again
header("Location: $base_url&deleted=1");
exit;
}
} catch (PDOException $e) {
$pdo->rollBack();
$message = 'Error deleting ticket: ' . $e->getMessage();
$message_type = 'error';
}
}
// Handle deletion success message from redirect
if (isset($_GET['deleted'])) {
$message = 'Ticket deleted successfully!';
$message_type = 'success';
}
// Get ticket details if viewing a ticket
if ($viewing_ticket) {
// Get ticket details
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.id = ?
");
$stmt->execute([$ticket_id]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if ticket exists and user has permission
if (!$ticket) {
die("Ticket not found");
}
if ($current_user['role'] === 'user' && $ticket['created_by'] != $current_user['id']) {
die("You don't have permission to view this ticket");
}
// Get ticket messages with correct column names
$stmt = $pdo->prepare("
SELECT m.*,
CONCAT(s.first_name, ' ', s.last_name) as sender_name,
s.role as sender_role,
CONCAT(r.first_name, ' ', r.last_name) as recipient_name
FROM messages m
LEFT JOIN users s ON m.sender_id = s.id
LEFT JOIN users r ON m.recipient_id = r.id
WHERE m.ticket_id = ?
ORDER BY m.created_at ASC
");
$stmt->execute([$ticket_id]);
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get all necessary data for ticket list
if (!$viewing_ticket) {
try {
// Get tickets based on role
if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') {
$tickets = $pdo->query("
SELECT t.*, d.name as department_name,
CONCAT(u.first_name, ' ', u.last_name) as creator_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users u ON t.created_by = u.id
LEFT JOIN users a ON t.assigned_to = a.id
ORDER BY t.created_at DESC
")->fetchAll(PDO::FETCH_ASSOC);
} else {
$stmt = $pdo->prepare("
SELECT t.*, d.name as department_name,
CONCAT(a.first_name, ' ', a.last_name) as assigned_name
FROM tickets t
LEFT JOIN departments d ON t.department_id = d.id
LEFT JOIN users a ON t.assigned_to = a.id
WHERE t.created_by = ?
ORDER BY t.created_at DESC
");
$stmt->execute([$current_user['id']]);
$tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get departments for dropdown
$departments = $pdo->query("SELECT * FROM departments")->fetchAll(PDO::FETCH_ASSOC);
// Get staff for assignment dropdown
$staff_members = $pdo->query("
SELECT id, CONCAT(first_name, ' ', last_name) as name
FROM users
WHERE role IN ('staff', 'admin')
")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching data: " . $e->getMessage());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $viewing_ticket ? 'Ticket Details' : 'Ticket System' ?></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f7f9;
color: #333;
}
.dashboard-container {
display: flex;
}
.sidebar {
width: 240px;
background-color: #c1d8f0;
color: #000;
height: 100vh;
position: fixed;
left: 0;
top: 0;
overflow-y: auto;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.sidebar-header {
padding: 20px;
text-align: center;
}
.sidebar-header .inventory-name {
font-size: 17px;
font-weight: bold;
color: #000;
}
.sidebar-menu {
padding: 0;
}
.sidebar-menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.sidebar-menu li a {
display: flex;
align-items: center;
padding: 12px 20px;
text-decoration: none;
color: #000;
transition: 0.3s;
font-size: 16px;
}
.sidebar-menu li a i {
margin-right: 12px;
width: 20px;
text-align: center;
}
.sidebar-menu li a:hover {
background-color: #ffffff;
color: #000;
}
.main-content {
margin-left: 240px;
padding: 25px;
flex-grow: 1;
}
.header {
position: fixed;
top: 0;
left: 240px;
right: 0;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #4663ac;
padding: 10px 30px;
height: 60px; /* Fixed height */
z-index: 999;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
h1 {
margin-top: 0;
padding-top: 0;
}
.header-left .date-time {
font-size: 15px; /* Slightly smaller */
color: #fff; /* Darker color */
font-weight: 500; /* Slightly bolder */
}
.header-right {
display: flex;
align-items: center;
/* Removed gap here, gap is now on .user-info */
font-size: 16px; /* Slightly smaller */
color: #ffffff;
}
/* New style for user info container */
.header-right .user-info {
display: flex;
align-items: center; /* Center items horizontally */
gap: 1px; /* Small gap between icon and text */
}
.user-dropdown {
position: relative;
display: inline-block;
cursor: pointer;
}
.user-dropdown-content {
display: none;
position: absolute;
right: 0;
background-color: #D1B48C;
min-width: 100px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border-radius: 4px;
}
.user-dropdown-header {
padding: 8px 12px;
background-color: ; #D1B48C
border-bottom: 1px solid #e9ecef;
display: flex;
align-items: center;
gap: 8px;
}
.user-dropdown-header i {
font-size: 20px;
color: #000000;
}
.user-dropdown-content.user-info {
display: flex;
align-items: right;
gap: 1px;
color: #000000;
}
.user-dropdown-content a {
display: flex;
padding: 8px 15px;
align-items: center;
color: #000000;
text-decoration: none;
font-size: 16px;
transition: all 0.2s;
}
.user-dropdown-content a i {
font-size: 16px; /* Adjust logout icon size separately */
margin-right: 8px; /* Space between icon and text */
}
.user-dropdown-content a:hover {
text-decoration: underline;
color: #000000;
}
.user-dropdown:hover .user-dropdown-content {
display: block;
}
.user-dropdown-content.user-info i {
font-size: 16px;
align-items: center;
}
.header-right i {
color: #ffffff; /* Icon color */
font-size:40px; /* Larger icon */
/* Remove margin-right when stacked */
}
.header-right span {
font-size: 15px; /* Smaller font for username */
color: #ffffff;
}
.main-content {
margin-left: 240px;
padding: 80px 20px 20px 20px;
flex-grow: 1;
}
.ticket-management {
display: flex;
flex-wrap: wrap; /* Enables wrapping on smaller screens */
justify-content: space-between;
gap: 20px; /* Adds gap between form and table */
}
.form-container, .table-container {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 15px;
margin: 10px;
width: 48%; /* Set width for each column */
}
h3 {
margin: 0 0 15px 0;
color: #2f4050;
font-size: 1.5em;
}
input[type="text"], input[type="password"], input[type="email"], select, textarea {
width: calc(100% - 22px);
padding: 10px;
margin-bottom: 15px; /* Space between inputs */
border: 1px solid #ddd;
border-radius: 4px;
}
textarea {
min-height: 150px;
}
button {
padding: 10px 15px;
border: none;
background-color: #D1B48C;
color: white;
border-radius: 4px;
cursor: pointer;
margin-top: 10px; /** Space above button */
}
.table-container{ flex: 1;}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
th {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f5f5f5;
}
.notice-container {
width: 100%;
margin-bottom: 20px;
background-color: #f9f9f9;
}
.notice {
padding: 15px;
margin: 0 10px 20px 10px;
border-radius: 4px;
border-left: 4px solid;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
display: flex;
align-items: center;
}
.notice p {
margin: 0;
padding: 0;
font-size: 16px;
}
.notice-success {
background-color: #f0fff4;
border-color: #38a169;
color: #2f855a;
}
.notice-error {
background-color: #fff5f5;
border-color: #e53e3e;
color: #c53030;
}
.notice i {
margin-right: 10px;
font-size: 18px;
}
.notice-success i {
color: #38a169;
}
.notice-error i {
color: #e53e3e;
}
/* Status Badges */
.status-badge {
display: inline-block;
padding: 5px 10px;
border-radius: 15px;
font-size: 13px;
font-weight: bold;
text-transform: uppercase;
}
.status-open { background-color: #e3f2fd; color: #1976d2; }
.status-assigned { background-color: #fff8e1; color: #ff8f00; }
.status-pending { background-color: #ffebee; color: #d32f2f; }
.status-solved { background-color: #e8f5e9; color: #388e3c; }
.status-closed { background-color: #f5f5f5; color: #616161; }
/* Priority Indicators */
.priority-high { color: #d32f2f; font-weight: bold; }
.priority-medium { color: #ffa000; }
.priority-low { color: #388e3c; }
/* Ticket Details View */
.ticket-details {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
margin-bottom: 30px;
font-size: 16px;
}
.ticket-header {
border-bottom: 1px solid #eee;
padding-bottom: 20px;
margin-bottom: 20px;
}
.ticket-body {
display: flex;
gap: 30px;
}
.ticket-description {
flex: 2;
}
.ticket-meta-details {
flex: 1;
background-color: #f9f9f9;
padding: 20px;
border-radius: 6px;
}
.meta-row {
margin-bottom: 15px;
}
.meta-label {
font-weight: bold;
display: inline-block;
width: 120px;
font-size: 20px;
}
/* Messages */
.ticket-messages {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.message {
padding: 15px;
border-bottom: 1px solid #eee;
}
.message-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.ticket-meta-row {
display: flex;
margin-bottom: 15px;
align-items: center;
font-size: 16px; /* Increased base font size */
}
.ticket-meta-label {
font-weight: bold;
min-width: 150px; /* Slightly wider for larger text */
font-size: 18px; /* Larger font size for labels */
color: #333; /* Darker color for better contrast */
}
.ticket-meta-value {
flex: 1;
font-size: 16px; /* Increased font size for values */
padding-left: 10px;
}
.back-to-tickets {
display: inline-block;
margin-bottom: 25px;
color: #4663ac;
text-decoration: none;
font-weight: bold;
font-size: 16px;
}
.back-to-tickets:hover {
text-decoration: underline;
}
/* Status badges with larger text */
.status-badge {
font-size: 14px;
padding: 6px 12px;
}
/* Make sure priority text is also larger */
.priority-high,
.priority-medium,
.priority-low {
font-size: 16px;
}
.add-message {
margin-top: 20px;
padding: 15px;
background-color: #f9f9f9;
border-radius: 5px;
width: 50%; /* Set container to half width */
max-width: 400px; /* Optional: Set maximum width */
}
.add-message h4 {
margin-bottom: 10px;
font-size: 16px;
}
.add-message textarea {
width: 100%; /* Will now be 50% of parent container */
min-height: 100px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
resize: vertical;
}
.add-message button {
padding: 8px 12px;
font-size: 14px;
background-color: #D1B48C;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 8px;
}
</style>
</head>
<body>
<div class="dashboard-container">
<aside class="sidebar">
<div class="sidebar-header">
<div class="inventory-name">RJL DeskTrack</div>
</div>
<div class="sidebar-menu">
<ul>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="http://localhost/helpdesk/?page_id=57"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
<li><a href="http://localhost/helpdesk/?page_id=62"><i class="fas fa-users-cog"></i> Users</a></li>
<li><a href="http://localhost/helpdesk/?page_id=66"><i class="fas fa-building"></i> Departments</a></li>
<?php endif; ?>
<li><a href="http://localhost/helpdesk/?page_id=70"><i class="fas fa-ticket-alt"></i> Tickets</a></li>
<li><a href="http://localhost/helpdesk/?page_id=74"><i class="fas fa-envelope"></i> Messages</a></li>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<li><a href="<?= home_url('/reports') ?>"><i class="fas fa-chart-bar"></i> Reports</a></li>
<?php endif; ?>
</ul>
</div>
</aside>
<main class="main-content">
<header class="header">
<div class="header-left">
<span class="date-time" id="current-date-time"></span>
</div>
<div class="header-right">
<div class="user-dropdown">
<div class="user-info">
<span id="current-username-header">
<?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?>
<i class="fas fa-user-circle"></i>
</span>
</div>
<div class="user-dropdown-content">
<div class="user-dropdown-header">
<i class="fas fa-user-circle" style="color:#000000;"></i>
<span style="color:#000000;">
<?= htmlspecialchars($current_user['first_name'] . ' ' . $current_user['last_name']) ?>
</span>
</div>
<a href="#" onclick="return confirm('Are you sure you want to log out?');">
<i class="fas fa-sign-out-alt" style="font-size: 16px; color:#000000;"></i>Logout
</a>
</div>
</div>
</div>
</header>
<h1>Ticket Management</h1>
<div class="notice-container">
<?php if ($message): ?>
<div class="notice notice-<?php echo $message_type === 'success' ? 'success' : 'error'; ?>">
<p><?php echo htmlspecialchars($message); ?></p>
</div>
<?php endif; ?>
</div>
<?php if ($viewing_ticket): ?>
<!-- Updated Ticket Details View -->
<div class="ticket-details">
<a href="<?= $base_url ?>" class="back-to-tickets">
<i class="fas fa-arrow-left"></i> Back to Tickets
</a>
<div class="ticket-info">
<div class="ticket-header">
<div class="ticket-meta-row">
<span class="ticket-meta-label">Subject: </span>
<span class="ticket-meta-value"><strong><?= htmlspecialchars($ticket['subject']) ?></strong></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Ticket #: </span>
<span class="ticket-meta-value"><?= htmlspecialchars($ticket['ticket_number']) ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Status: </span>
<span class="ticket-meta-value">
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>"><?= ucfirst($ticket['status']) ?>
</span>
</span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Priority: </span>
<span class="ticket-meta-value">
<span class="priority-<?= htmlspecialchars($ticket['priority']) ?>"><?= ucfirst($ticket['priority']) ?>
</span>
</span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Description: </span>
<span class="ticket-meta-value"><?= nl2br(htmlspecialchars($ticket['description'])) ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Created By: </span>
<span class="ticket-meta-value"><?= htmlspecialchars($ticket['creator_name']) ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Department: </span>
<span class="ticket-meta-value"><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Assigned To: </span>
<span class="ticket-meta-value"><?= htmlspecialchars($ticket['assigned_name'] ?? 'Unassigned') ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Created At: </span>
<span class="ticket-meta-value"><?= date('M j, Y g:i A', strtotime($ticket['created_at'])) ?></span>
</div>
<div class="ticket-meta-row">
<span class="ticket-meta-label">Updated At: </span>
<span class="ticket-meta-value"><?= date('M j, Y g:i A', strtotime($ticket['updated_at'])) ?></span>
</div>
</div>
<div class="add-message">
<h4>Add Message</h4>
<form method="POST">
<input type="hidden" name="ticket_id" value="<?= $ticket_id ?>">
<div class="form-group">
<textarea name="message" required placeholder="Type your message here..."></textarea>
</div>
<button type="submit" name="add_message">Send Message</button>
</form>
</div>
</div>
<?php else: ?>
<!-- Ticket List View -->
<div class="ticket-management">
<?php if ($current_user['role'] === 'user'): ?>
<div class="form-container">
<h3>Create New Ticket</h3>
<form method="POST">
<div class="form-group">
<input type="text" name="subject" placeholder="Subject" required>
</div>
<div class="form-group">
<textarea name="description" placeholder="Description" required></textarea>
</div>
<div class="form-group">
<select name="priority" required>
<option value="low">Low</option>
<option value="medium" selected>Medium</option>
<option value="high">High</option>
</select>
</div>
<div class="form-group">
<select name="department_id" required>
<?php foreach ($departments as $dept): ?>
<option value="<?= $dept['id'] ?>"><?= htmlspecialchars($dept['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" name="create_ticket">Create Ticket</button>
</form>
</div>
<?php endif; ?>
<div class="table-container">
<h3><?= ($current_user['role'] === 'admin' || $current_user['role'] === 'staff') ? 'All Tickets' : 'My Tickets' ?></h3>
<?php if (empty($tickets)): ?>
<p>No tickets found.</p>
<?php else: ?>
<table>
<thead>
<tr>
<th>Ticket #</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Created By</th>
<?php endif; ?>
<th>Subject</th>
<th>Status</th>
<th>Priority</th>
<th>Department</th>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<th>Assigned To</th>
<?php endif; ?>
<th>Created At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($tickets as $ticket): ?>
<tr>
<td><?= htmlspecialchars($ticket['ticket_number']) ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td><?= htmlspecialchars($ticket['creator_name'] ?? 'N/A') ?></td>
<?php endif; ?>
<td><?= htmlspecialchars($ticket['subject']) ?></td>
<td>
<span class="status-badge status-<?= htmlspecialchars($ticket['status']) ?>">
<?= ucfirst($ticket['status']) ?>
</span>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<form method="POST" class="status-update-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="status" onchange="this.form.submit()">
<option value="open" <?= $ticket['status'] === 'open' ? 'selected' : '' ?>>Open</option>
<option value="assigned" <?= $ticket['status'] === 'assigned' ? 'selected' : '' ?>>Assigned</option>
<option value="pending" <?= $ticket['status'] === 'pending' ? 'selected' : '' ?>>Pending</option>
<option value="solved" <?= $ticket['status'] === 'solved' ? 'selected' : '' ?>>Solved</option>
<option value="closed" <?= $ticket['status'] === 'closed' ? 'selected' : '' ?>>Closed</option>
</select>
<input type="hidden" name="update_status" value="1">
</form>
<?php endif; ?>
</td>
<td class="priority-<?= htmlspecialchars($ticket['priority']) ?>">
<?= ucfirst($ticket['priority']) ?>
</td>
<td><?= htmlspecialchars($ticket['department_name'] ?? 'None') ?></td>
<?php if ($current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<td>
<?php if ($ticket['assigned_to']): ?>
<?= htmlspecialchars($ticket['assigned_name'] ?? 'N/A') ?>
<?php else: ?>
<form method="POST" class="assign-form">
<input type="hidden" name="ticket_id" value="<?= $ticket['id'] ?>">
<select name="assign_to" onchange="this.form.submit()">
<option value="">Assign to...</option>
<?php foreach ($staff_members as $staff): ?>
<option value="<?= $staff['id'] ?>"><?= htmlspecialchars($staff['name']) ?></option>
<?php endforeach; ?>
</select>
<input type="hidden" name="assign_ticket" value="1">
</form>
<?php endif; ?>
</td>
<?php endif; ?>
<td><?= date('M j, Y', strtotime($ticket['created_at'])) ?></td>
<td>
<a href="<?= $base_url ?>&ticket_id=<?= $ticket['id'] ?>" class="button">View</a>
<?php if ($ticket['created_by'] == $current_user['id'] || $current_user['role'] === 'admin' || $current_user['role'] === 'staff'): ?>
<a href="<?= $base_url ?>&delete_ticket=<?= $ticket['id'] ?>"
class="button"
onclick="return confirm('Are you sure you want to delete this ticket?')">
Delete
</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</main>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Update date time in header
function updateDateTime() {
const now = new Date();
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
document.getElementById("current-date-time").textContent = now.toLocaleDateString('en-US', options);
}
setInterval(updateDateTime, 1000);
updateDateTime();
// AJAX form submissions
document.querySelectorAll('.status-update-form select, .assign-form select').forEach(select => {
select.addEventListener('change', function() {
const form = this.closest('form');
fetch('', {
method: 'POST',
body: new FormData(form)
})
.then(response => {
if (response.ok) {
window.location.reload();
} else {
alert('Error updating ticket');
}
})
.catch(error => {
console.error('Error:', error);
alert('Error updating ticket');
});
});
});
});
</script>
<script>
// Update date time
function updateDateTime() {
const now = new Date();
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
document.getElementById("current-date-time").textContent = now.toLocaleDateString('en-US', options);
}
setInterval(updateDateTime, 1000);
updateDateTime();
</script>
</body>
</html>