5000) { $error_message = 'Reply must be 5000 characters or less.'; } else { try { $stmt = $panelPdo->prepare("SELECT id, status FROM support_tickets WHERE id = ? AND sender_type = 'client' AND sender_id = ?"); $stmt->execute([$replyTicketId, $client_id]); $ticket = $stmt->fetch(); if (!$ticket) { $error_message = 'Ticket not found or access denied.'; } elseif ($ticket['status'] === 'closed') { $error_message = 'Cannot reply to a closed ticket.'; } else { $stmt = $panelPdo->prepare("INSERT INTO support_messages (ticket_id, sender_type, sender_id, message, is_internal) VALUES (?, 'user', ?, ?, 0)"); $stmt->execute([$replyTicketId, $client_id, $replyMessage]); $messageId = $panelPdo->lastInsertId(); // Handle file attachments if ($supportHelperLoaded && !empty($_FILES['attachments']['name'][0])) { handleSupportAttachments($panelPdo, $messageId, $_FILES['attachments']); } // Reopen ticket if resolved/pending if (in_array($ticket['status'], ['resolved', 'pending'])) { $panelPdo->prepare("UPDATE support_tickets SET status = 'open', updated_at = NOW() WHERE id = ?")->execute([$replyTicketId]); } else { $panelPdo->prepare("UPDATE support_tickets SET updated_at = NOW() WHERE id = ?")->execute([$replyTicketId]); } $success_message = 'Reply sent successfully!'; $viewTicketId = $replyTicketId; } } catch (Exception $e) { error_log("Client ticket reply error: " . $e->getMessage()); $error_message = 'Failed to send reply. Please try again.'; } } } // -- Handle ticket creation -- if ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['reply_ticket_id'])) { $subject = isset($_POST['subject']) ? trim($_POST['subject']) : ''; $message = isset($_POST['message']) ? trim($_POST['message']) : ''; $priority = isset($_POST['priority']) ? $_POST['priority'] : 'medium'; if (empty($subject) || empty($message)) { $error_message = 'Subject and message are required.'; } elseif (strlen($subject) > 255) { $error_message = 'Subject must be 255 characters or less.'; } elseif (strlen($message) > 5000) { $error_message = 'Message must be 5000 characters or less.'; } else { try { $panelPdo->beginTransaction(); $ticketNumber = 'TKT-' . date('Ymd') . '-' . strtoupper(substr(bin2hex(random_bytes(4)), 0, 6)); $stmt = $panelPdo->prepare("INSERT INTO support_tickets (ticket_number, user_id, sender_type, sender_id, subject, status, priority) VALUES (?, NULL, 'client', ?, ?, 'open', ?)"); $stmt->execute([$ticketNumber, $client_id, $subject, $priority]); $ticketId = $panelPdo->lastInsertId(); $stmt = $panelPdo->prepare("INSERT INTO support_messages (ticket_id, sender_type, sender_id, message, is_internal) VALUES (?, 'user', ?, ?, 0)"); $stmt->execute([$ticketId, $client_id, $message]); $messageId = $panelPdo->lastInsertId(); $panelPdo->commit(); // Handle file attachments if ($supportHelperLoaded && !empty($_FILES['attachments']['name'][0])) { handleSupportAttachments($panelPdo, $messageId, $_FILES['attachments']); } $success_message = "Support ticket created successfully! Ticket Number: $ticketNumber
We will respond to your query shortly."; $_POST = []; } catch (Exception $e) { if ($panelPdo->inTransaction()) $panelPdo->rollBack(); error_log("Client ticket creation error: " . $e->getMessage()); $error_message = 'Failed to create support ticket. Please try again.'; } } } // -- Load ticket detail if viewing -- if ($viewTicketId) { try { $stmt = $panelPdo->prepare(" SELECT st.*, au.full_name as assigned_to_name FROM support_tickets st LEFT JOIN admin_users au ON st.assigned_to = au.id WHERE st.id = ? AND st.sender_type = 'client' AND st.sender_id = ? "); $stmt->execute([$viewTicketId, $client_id]); $viewTicket = $stmt->fetch(); if ($viewTicket) { $stmt = $panelPdo->prepare(" SELECT sm.*, CASE WHEN sm.sender_type = 'admin' THEN COALESCE((SELECT full_name FROM admin_users WHERE id = sm.sender_id), 'Support Team') ELSE ? END as sender_name FROM support_messages sm WHERE sm.ticket_id = ? AND sm.is_internal = 0 ORDER BY sm.created_at ASC "); $stmt->execute([$client_name, $viewTicketId]); $ticketMessages = $stmt->fetchAll(); // Load attachments for all messages if ($supportHelperLoaded && function_exists('getAttachmentsForMessages') && !empty($ticketMessages)) { $msgIds = array_column($ticketMessages, 'id'); $messageAttachments = getAttachmentsForMessages($panelPdo, $msgIds); } } } catch (Exception $e) { error_log("Client ticket load error: " . $e->getMessage()); } } // -- Load tickets list -- try { $stmt = $panelPdo->prepare(" SELECT st.*, au.full_name as assigned_to_name, (SELECT COUNT(*) FROM support_messages WHERE ticket_id = st.id AND is_internal = 0) as message_count FROM support_tickets st LEFT JOIN admin_users au ON st.assigned_to = au.id WHERE st.sender_type = 'client' AND st.sender_id = ? ORDER BY st.updated_at DESC "); $stmt->execute([$client_id]); $tickets = $stmt->fetchAll(); } catch (Exception $e) { error_log("Client ticket list error: " . $e->getMessage()); $tickets = []; } // Helper: get file icon class function getClientFileIcon($type, $name) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (in_array($ext, ['jpg','jpeg','png','gif','webp'])) return 'fa-file-image'; if ($ext === 'pdf') return 'fa-file-pdf'; if (in_array($ext, ['doc','docx'])) return 'fa-file-word'; if (in_array($ext, ['xls','xlsx','csv'])) return 'fa-file-excel'; return 'fa-file-alt'; } // Ticket counts by status $statusCounts = ['open' => 0, 'pending' => 0, 'resolved' => 0, 'closed' => 0]; foreach ($tickets as $t) { if (isset($statusCounts[$t['status']])) $statusCounts[$t['status']]++; } $page_title = 'Support'; include 'client-portal-header.php'; ?>

Support Center

Create and manage support tickets. Logged in as:

Back to All Tickets

Conversation

No messages yet.

' : ' '; ?>
'; foreach ($messageAttachments[$msg['id']] as $att) { $icon = getClientFileIcon($att['file_type'], $att['original_name']); $sizeMB = number_format(($att['file_size'] ?? 0) / 1024 / 1024, 1); echo ' ' . htmlspecialchars($att['original_name']) . ' (' . $sizeMB . ' MB)'; } echo '
'; } ?>
Send Reply
Max 3 files, 5MB each.
This ticket is closed. If you need further help, please create a new ticket.
Total
Open
Pending
Resolved
Closed

Create New Support Ticket

Maximum 5000 characters
Max 3 files, 5MB each. Accepted: Images, PDF, Word, Excel, Text.

Your Support Tickets ()

No tickets yet

You haven't created any support tickets. Create one above if you need assistance.