import { API_CONFIG } from '../config/api'; const BASE_URL = `${API_CONFIG.BASE_URL}/api/support`; // ==================== Types ==================== export interface TicketStatus { id: number; name: string; color: string; description: string; is_closed: boolean; display_order: number; } export interface TicketPriority { id: number; name: string; level: number; color: string; description: string; sla_hours: number; } export interface TicketCategory { id: number; name: string; description: string; color: string; icon: string; display_order: number; } export interface TicketMessage { id: number; ticket: number; message_type: string; content: string; author_name: string; author_email: string; is_internal: boolean; created_at: string; updated_at: string; attachments: string[]; is_read: boolean; } export interface TicketActivity { id: number; activity_type: string; description: string; user_name: string; old_value: string; new_value: string; created_at: string; } export interface SupportTicket { id: number; ticket_number: string; title: string; description: string; ticket_type: string; user_name: string; user_email: string; user_phone: string; company: string; category: number | null; category_name: string; priority: number | null; priority_name: string; priority_color: string; status: number | null; status_name: string; status_color: string; assigned_to: number | null; assigned_at: string | null; created_at: string; updated_at: string; closed_at: string | null; last_activity: string; first_response_at: string | null; sla_deadline: string | null; tags: string; is_escalated: boolean; escalation_reason: string; attachments: string[]; messages: TicketMessage[]; activities: TicketActivity[]; } export interface CreateTicketData { title: string; description: string; ticket_type: string; user_name: string; user_email: string; user_phone?: string; company?: string; category?: number; } export interface KnowledgeBaseCategory { id: number; name: string; slug: string; description: string; icon: string; color: string; display_order: number; article_count: number; } export interface KnowledgeBaseArticle { id: number; title: string; slug: string; category: number; category_name: string; category_slug: string; content?: string; summary: string; meta_description?: string; keywords?: string; is_featured: boolean; view_count: number; helpful_count: number; not_helpful_count: number; created_at: string; updated_at: string; published_at: string; } export interface SupportSettings { id: number; setting_name: string; setting_value: string; description: string; is_active: boolean; } // ==================== API Functions ==================== /** * Fetch all ticket categories */ export const getTicketCategories = async (): Promise => { try { const response = await fetch(`${BASE_URL}/categories/`); if (!response.ok) throw new Error('Failed to fetch ticket categories'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching ticket categories:', error); throw error; } }; /** * Fetch all ticket statuses */ export const getTicketStatuses = async (): Promise => { try { const response = await fetch(`${BASE_URL}/statuses/`); if (!response.ok) throw new Error('Failed to fetch ticket statuses'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching ticket statuses:', error); throw error; } }; /** * Fetch all ticket priorities */ export const getTicketPriorities = async (): Promise => { try { const response = await fetch(`${BASE_URL}/priorities/`); if (!response.ok) throw new Error('Failed to fetch ticket priorities'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching ticket priorities:', error); throw error; } }; /** * Create a new support ticket */ export const createTicket = async (data: CreateTicketData): Promise => { try { const response = await fetch(`${BASE_URL}/tickets/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); // Handle validation errors if (response.status === 400 && errorData.user_email) { throw new Error(errorData.user_email[0] || 'Email validation failed'); } throw new Error(errorData.detail || errorData.message || 'Failed to create ticket'); } return await response.json(); } catch (error) { console.error('Error creating ticket:', error); throw error; } }; /** * Check ticket status by ticket number */ export const checkTicketStatus = async (ticketNumber: string): Promise => { try { const response = await fetch(`${BASE_URL}/tickets/check-status/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ticket_number: ticketNumber }), }); if (!response.ok) { if (response.status === 404) { throw new Error('Ticket not found'); } throw new Error('Failed to check ticket status'); } return await response.json(); } catch (error) { console.error('Error checking ticket status:', error); throw error; } }; /** * Add a message to a ticket */ export const addTicketMessage = async ( ticketId: number, content: string, authorName: string, authorEmail: string ): Promise => { try { const response = await fetch(`${BASE_URL}/tickets/${ticketId}/add-message/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ content, author_name: authorName, author_email: authorEmail, }), }); if (!response.ok) throw new Error('Failed to add ticket message'); return await response.json(); } catch (error) { console.error('Error adding ticket message:', error); throw error; } }; /** * Fetch all knowledge base categories */ export const getKnowledgeBaseCategories = async (): Promise => { try { const response = await fetch(`${BASE_URL}/knowledge-base-categories/`); if (!response.ok) throw new Error('Failed to fetch knowledge base categories'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching knowledge base categories:', error); throw error; } }; /** * Fetch all knowledge base articles */ export const getKnowledgeBaseArticles = async (search?: string): Promise => { try { const url = search ? `${BASE_URL}/knowledge-base/?search=${encodeURIComponent(search)}` : `${BASE_URL}/knowledge-base/`; const response = await fetch(url); if (!response.ok) throw new Error('Failed to fetch knowledge base articles'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching knowledge base articles:', error); throw error; } }; /** * Fetch featured knowledge base articles */ export const getFeaturedArticles = async (): Promise => { try { const response = await fetch(`${BASE_URL}/knowledge-base/featured/`); if (!response.ok) throw new Error('Failed to fetch featured articles'); const data = await response.json(); // Handle both array and paginated responses return Array.isArray(data) ? data : (data.results || data); } catch (error) { console.error('Error fetching featured articles:', error); throw error; } }; /** * Fetch a single knowledge base article by slug */ export const getKnowledgeBaseArticle = async (slug: string): Promise => { try { const response = await fetch(`${BASE_URL}/knowledge-base/${slug}/`); if (!response.ok) throw new Error('Failed to fetch knowledge base article'); return await response.json(); } catch (error) { console.error('Error fetching knowledge base article:', error); throw error; } }; /** * Fetch articles by category */ export const getArticlesByCategory = async (categorySlug: string): Promise => { try { const response = await fetch(`${BASE_URL}/knowledge-base/by-category/${categorySlug}/`); if (!response.ok) throw new Error('Failed to fetch articles by category'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching articles by category:', error); throw error; } }; /** * Mark an article as helpful or not helpful */ export const markArticleHelpful = async (slug: string, helpful: boolean): Promise<{ helpful_count: number; not_helpful_count: number }> => { try { const response = await fetch(`${BASE_URL}/knowledge-base/${slug}/mark-helpful/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ helpful }), }); if (!response.ok) throw new Error('Failed to mark article helpful'); return await response.json(); } catch (error) { console.error('Error marking article helpful:', error); throw error; } }; /** * Fetch support settings */ export const getSupportSettings = async (): Promise => { try { const response = await fetch(`${BASE_URL}/settings/`); if (!response.ok) throw new Error('Failed to fetch support settings'); const data = await response.json(); // Handle paginated response return data.results || data; } catch (error) { console.error('Error fetching support settings:', error); throw error; } }; /** * Fetch a specific support setting by name */ export const getSupportSetting = async (settingName: string): Promise => { try { const response = await fetch(`${BASE_URL}/settings/${settingName}/`); if (!response.ok) throw new Error('Failed to fetch support setting'); return await response.json(); } catch (error) { console.error('Error fetching support setting:', error); throw error; } };