Files
GNX-WEB/gnx-react/components/pages/support/TicketStatusCheck.tsx
Iliyan Angelov d48c54e2c5 update
2025-10-07 22:10:27 +03:00

198 lines
7.3 KiB
TypeScript

"use client";
import { useState, FormEvent } from 'react';
import { checkTicketStatus, SupportTicket } from '@/lib/api/supportService';
const TicketStatusCheck = () => {
const [ticketNumber, setTicketNumber] = useState('');
const [isSearching, setIsSearching] = useState(false);
const [searchError, setSearchError] = useState<string | null>(null);
const [ticket, setTicket] = useState<SupportTicket | null>(null);
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsSearching(true);
setSearchError(null);
setTicket(null);
try {
const response = await checkTicketStatus(ticketNumber);
setTicket(response);
} catch (error: any) {
if (error.message === 'Ticket not found') {
setSearchError('Ticket not found. Please check your ticket number and try again.');
} else {
setSearchError('An error occurred while searching. Please try again.');
}
} finally {
setIsSearching(false);
}
};
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
};
return (
<div className="ticket-status-check">
<div className="row justify-content-center">
<div className="col-12 col-lg-8">
<div className="form-header text-center">
<h2>Check Ticket Status</h2>
<p>Enter your ticket number to view the current status and details of your support request.</p>
</div>
<form onSubmit={handleSubmit} className="status-search-form">
<div className="search-input-group">
<input
type="text"
value={ticketNumber}
onChange={(e) => setTicketNumber(e.target.value)}
placeholder="Enter your ticket number (e.g., TKT-20231015-ABCDE)"
required
className="form-control"
/>
<button
type="submit"
className="btn btn-primary"
disabled={isSearching}
>
{isSearching ? (
<>
<span className="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
Searching...
</>
) : (
<>
<i className="fa-solid fa-search me-2"></i>
Check Status
</>
)}
</button>
</div>
</form>
{searchError && (
<div className="alert alert-danger mt-4" role="alert">
<i className="fa-solid fa-triangle-exclamation me-2"></i>
{searchError}
</div>
)}
{ticket && (
<div className="ticket-details">
<div className="ticket-header">
<div className="ticket-number">
<i className="fa-solid fa-ticket me-2"></i>
{ticket.ticket_number}
</div>
<div
className="ticket-status-badge"
style={{ backgroundColor: ticket.status_color }}
>
{ticket.status_name}
</div>
</div>
<div className="ticket-info">
<h3>{ticket.title}</h3>
<div className="ticket-meta">
<div className="meta-item">
<i className="fa-solid fa-calendar me-2"></i>
<strong>Created:</strong> {formatDate(ticket.created_at)}
</div>
<div className="meta-item">
<i className="fa-solid fa-clock me-2"></i>
<strong>Last Updated:</strong> {formatDate(ticket.updated_at)}
</div>
{ticket.priority_name && (
<div className="meta-item">
<i className="fa-solid fa-flag me-2"></i>
<strong>Priority:</strong>
<span
className="priority-badge ms-2"
style={{ backgroundColor: ticket.priority_color }}
>
{ticket.priority_name}
</span>
</div>
)}
{ticket.category_name && (
<div className="meta-item">
<i className="fa-solid fa-folder me-2"></i>
<strong>Category:</strong> {ticket.category_name}
</div>
)}
</div>
<div className="ticket-description">
<h4>Description</h4>
<p>{ticket.description}</p>
</div>
{ticket.messages && ticket.messages.length > 0 && (
<div className="ticket-messages">
<h4>Messages ({ticket.messages.length})</h4>
<div className="messages-list">
{ticket.messages
.filter(msg => !msg.is_internal)
.map((message, index) => (
<div key={message.id} className="message-item">
<div className="message-header">
<div className="message-author">
<i className="fa-solid fa-user-circle me-2"></i>
{message.author_name || message.author_email}
</div>
<div className="message-date">
{formatDate(message.created_at)}
</div>
</div>
<div className="message-content">
{message.content}
</div>
</div>
))}
</div>
</div>
)}
{ticket.activities && ticket.activities.length > 0 && (
<div className="ticket-timeline">
<h4>Activity Timeline</h4>
<div className="timeline-list">
{ticket.activities.slice(0, 5).map((activity, index) => (
<div key={activity.id} className="timeline-item">
<div className="timeline-icon">
<i className="fa-solid fa-circle"></i>
</div>
<div className="timeline-content">
<div className="timeline-description">
{activity.description}
</div>
<div className="timeline-date">
{formatDate(activity.created_at)}
</div>
</div>
</div>
))}
</div>
</div>
)}
</div>
</div>
)}
</div>
</div>
</div>
);
};
export default TicketStatusCheck;