Refactor: Use existing API for support
This commit is contained in:
256
src/services/supportApi.ts
Normal file
256
src/services/supportApi.ts
Normal file
@@ -0,0 +1,256 @@
|
||||
import { API_BASE_URL } from './config';
|
||||
|
||||
export interface Ticket {
|
||||
id: string;
|
||||
subject: string;
|
||||
description: string;
|
||||
status: 'open' | 'in_progress' | 'resolved' | 'closed';
|
||||
priority: 'low' | 'medium' | 'high' | 'urgent';
|
||||
category: string;
|
||||
userId: string;
|
||||
assignedTo?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
responses: TicketResponse[];
|
||||
}
|
||||
|
||||
export interface TicketResponse {
|
||||
id: string;
|
||||
ticketId: string;
|
||||
userId: string;
|
||||
userName: string;
|
||||
message: string;
|
||||
isStaff: boolean;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface SupportMetrics {
|
||||
totalTickets: number;
|
||||
openTickets: number;
|
||||
resolvedTickets: number;
|
||||
averageResponseTime: number;
|
||||
customerSatisfaction: number;
|
||||
}
|
||||
|
||||
export interface KnowledgeBaseArticle {
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
category: string;
|
||||
tags: string[];
|
||||
views: number;
|
||||
helpful: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
class SupportApi {
|
||||
private getAuthHeaders() {
|
||||
const token = localStorage.getItem('authToken');
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': token ? `Bearer ${token}` : '',
|
||||
};
|
||||
}
|
||||
|
||||
// Tickets
|
||||
async getTickets(): Promise<Ticket[]> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/tickets`, {
|
||||
headers: this.getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch tickets');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error fetching tickets:', error);
|
||||
// Return mock data as fallback
|
||||
return this.getMockTickets();
|
||||
}
|
||||
}
|
||||
|
||||
async createTicket(ticket: Omit<Ticket, 'id' | 'createdAt' | 'updatedAt' | 'responses'>): Promise<Ticket> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/tickets`, {
|
||||
method: 'POST',
|
||||
headers: this.getAuthHeaders(),
|
||||
body: JSON.stringify(ticket),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to create ticket');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error creating ticket:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async updateTicketStatus(ticketId: string, status: Ticket['status']): Promise<Ticket> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/tickets/${ticketId}/status`, {
|
||||
method: 'PATCH',
|
||||
headers: this.getAuthHeaders(),
|
||||
body: JSON.stringify({ status }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update ticket');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error updating ticket:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async addTicketResponse(ticketId: string, message: string): Promise<TicketResponse> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/tickets/${ticketId}/responses`, {
|
||||
method: 'POST',
|
||||
headers: this.getAuthHeaders(),
|
||||
body: JSON.stringify({ message }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to add response');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error adding response:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics
|
||||
async getSupportMetrics(): Promise<SupportMetrics> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/metrics`, {
|
||||
headers: this.getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch metrics');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error fetching metrics:', error);
|
||||
return this.getMockMetrics();
|
||||
}
|
||||
}
|
||||
|
||||
// Knowledge Base
|
||||
async getKnowledgeBase(): Promise<KnowledgeBaseArticle[]> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/knowledge-base`, {
|
||||
headers: this.getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch knowledge base');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error fetching knowledge base:', error);
|
||||
return this.getMockKnowledgeBase();
|
||||
}
|
||||
}
|
||||
|
||||
// Live Chat
|
||||
async getChatSessions(): Promise<any[]> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/support/chat/sessions`, {
|
||||
headers: this.getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch chat sessions');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error fetching chat sessions:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Mock data methods
|
||||
private getMockTickets(): Ticket[] {
|
||||
return [
|
||||
{
|
||||
id: '1',
|
||||
subject: 'Problema con facturación',
|
||||
description: 'No puedo ver mis facturas en el sistema',
|
||||
status: 'open',
|
||||
priority: 'medium',
|
||||
category: 'billing',
|
||||
userId: 'user1',
|
||||
assignedTo: 'support1',
|
||||
createdAt: new Date(Date.now() - 86400000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 3600000).toISOString(),
|
||||
responses: []
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
subject: 'Error en reserva de servicios',
|
||||
description: 'La aplicación se cierra al intentar hacer una reserva',
|
||||
status: 'in_progress',
|
||||
priority: 'high',
|
||||
category: 'technical',
|
||||
userId: 'user2',
|
||||
assignedTo: 'support2',
|
||||
createdAt: new Date(Date.now() - 172800000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 1800000).toISOString(),
|
||||
responses: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private getMockMetrics(): SupportMetrics {
|
||||
return {
|
||||
totalTickets: 156,
|
||||
openTickets: 23,
|
||||
resolvedTickets: 133,
|
||||
averageResponseTime: 2.5,
|
||||
customerSatisfaction: 4.2
|
||||
};
|
||||
}
|
||||
|
||||
private getMockKnowledgeBase(): KnowledgeBaseArticle[] {
|
||||
return [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Cómo realizar una reserva',
|
||||
content: 'Para realizar una reserva sigue estos pasos...',
|
||||
category: 'bookings',
|
||||
tags: ['reserva', 'booking', 'tutorial'],
|
||||
views: 245,
|
||||
helpful: 32,
|
||||
createdAt: new Date(Date.now() - 2592000000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 86400000).toISOString()
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Problemas comunes de facturación',
|
||||
content: 'Si tienes problemas con tu facturación...',
|
||||
category: 'billing',
|
||||
tags: ['facturación', 'billing', 'pagos'],
|
||||
views: 189,
|
||||
helpful: 28,
|
||||
createdAt: new Date(Date.now() - 1814400000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 172800000).toISOString()
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export const supportApi = new SupportApi();
|
||||
Reference in New Issue
Block a user