import type { UserData } from './types'; import React, { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import apiClient from '../../utils/apiClient'; interface Ticket { id: number; title: string; message: string; status: string; priority: string; category: string; createdAt: string; updatedAt: string; responses?: Response[]; assignedTo?: number; closedAt?: string; } interface Response { id: number; message: string; isInternal: boolean; createdAt: string; userId: number; user: { username: string; operator: boolean; }; } type TicketsPageProps = { setUserData: (data: UserData) => void; }; const TicketsPage: React.FC = () => { const navigate = useNavigate(); const [tickets, setTickets] = useState([]); const [loading, setLoading] = useState(true); const [filters, setFilters] = useState({ status: 'all', category: 'all', priority: 'all' }); useEffect(() => { fetchTickets(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [filters]); const fetchTickets = async () => { try { const params: Record = {}; if (filters.status !== 'all') params.status = filters.status; if (filters.category !== 'all') params.category = filters.category; if (filters.priority !== 'all') params.priority = filters.priority; const response = await apiClient.get('/api/ticket', { params }); setTickets(response.data.tickets || response.data || []); setLoading(false); } catch (error) { console.error('Ошибка загрузки тикетов:', error); setTickets([]); setLoading(false); } }; const getStatusBadge = (status: string) => { const badges: Record = { open: { color: 'bg-green-100 text-green-800', text: 'Открыт' }, in_progress: { color: 'bg-blue-100 text-blue-800', text: 'В работе' }, awaiting_reply: { color: 'bg-yellow-100 text-yellow-800', text: 'Ожидает ответа' }, resolved: { color: 'bg-purple-100 text-purple-800', text: 'Решён' }, closed: { color: 'bg-gray-100 text-gray-800', text: 'Закрыт' } }; const badge = badges[status] || badges.open; return ( {badge.text} ); }; const getPriorityBadge = (priority: string) => { const badges: Record = { urgent: { color: 'bg-red-100 text-red-800 border-red-300', text: 'Срочно' }, high: { color: 'bg-orange-100 text-orange-800 border-orange-300', text: 'Высокий' }, normal: { color: 'bg-gray-100 text-gray-800 border-gray-300', text: 'Обычный' }, low: { color: 'bg-green-100 text-green-800 border-green-300', text: 'Низкий' } }; const badge = badges[priority] || badges.normal; return ( {badge.text} ); }; const getCategoryIcon = (category: string) => { const icons: Record = { general: '💬', technical: '⚙️', billing: '💰', other: '📝' }; return icons[category] || icons.general; }; const formatRelativeTime = (dateString: string) => { const date = new Date(dateString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMs / 3600000); const diffDays = Math.floor(diffMs / 86400000); if (diffMins < 1) return 'только что'; if (diffMins < 60) return `${diffMins} мин. назад`; if (diffHours < 24) return `${diffHours} ч. назад`; if (diffDays < 7) return `${diffDays} дн. назад`; return date.toLocaleDateString('ru-RU'); }; if (loading) { return (

Загрузка тикетов...

); } return (
{/* Header */}

Тикеты поддержки

Управляйте вашими обращениями в службу поддержки

{/* Filters */}
{/* Status Filter */}
{/* Category Filter */}
{/* Priority Filter */}
{/* Tickets Grid */} {tickets.length === 0 ? (

Нет тикетов

У вас пока нет открытых тикетов поддержки

) : (
{tickets.map((ticket) => (
{/* Header */}
{getCategoryIcon(ticket.category || 'general')}

{ticket.title}

{getPriorityBadge(ticket.priority || 'normal')}

{ticket.message.substring(0, 150)}...

{getStatusBadge(ticket.status)}
{/* Footer */}
{formatRelativeTime(ticket.updatedAt)} {ticket.responses?.length || 0} ответов {ticket.closedAt && ( Закрыт )}
Открыть →
))}
)}
); }; export default TicketsPage;