Files
smoothschedule/frontend/src/api/tickets.ts
poduck ae74b4c2ed feat: Multi-email ticketing system with platform email addresses
- Add PlatformEmailAddress model for managing platform-level email addresses
- Add TicketEmailAddress model for tenant-level email addresses
- Create MailServerService for IMAP integration with mail.talova.net
- Implement PlatformEmailReceiver for processing incoming platform emails
- Add email autoconfiguration for Mozilla, Microsoft, and Apple clients
- Add configurable email polling interval in platform settings
- Add "Check Emails" button on support page for manual refresh
- Add ticket counts to status tabs on support page
- Add platform email addresses management page
- Add Privacy Policy and Terms of Service pages
- Add robots.txt for SEO
- Restrict email addresses to smoothschedule.com domain only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 17:49:09 -05:00

89 lines
3.0 KiB
TypeScript

import apiClient from './client';
import { Ticket, TicketComment, TicketTemplate, CannedResponse, TicketStatus, TicketPriority, TicketCategory, TicketType } from '../types';
export interface TicketFilters {
status?: TicketStatus;
priority?: TicketPriority;
category?: TicketCategory;
ticketType?: TicketType;
assignee?: string;
}
export const getTickets = async (filters?: TicketFilters): Promise<Ticket[]> => {
const params = new URLSearchParams();
if (filters?.status) params.append('status', filters.status);
if (filters?.priority) params.append('priority', filters.priority);
if (filters?.category) params.append('category', filters.category);
if (filters?.ticketType) params.append('ticket_type', filters.ticketType);
if (filters?.assignee) params.append('assignee', filters.assignee);
const response = await apiClient.get(`/tickets/${params.toString() ? `?${params.toString()}` : ''}`);
return response.data;
};
export const getTicket = async (id: string): Promise<Ticket> => {
const response = await apiClient.get(`/tickets/${id}/`);
return response.data;
};
export const createTicket = async (data: Partial<Ticket>): Promise<Ticket> => {
const response = await apiClient.post('/tickets/', data);
return response.data;
};
export const updateTicket = async (id: string, data: Partial<Ticket>): Promise<Ticket> => {
const response = await apiClient.patch(`/tickets/${id}/`, data);
return response.data;
};
export const deleteTicket = async (id: string): Promise<void> => {
await apiClient.delete(`/tickets/${id}/`);
};
export const getTicketComments = async (ticketId: string): Promise<TicketComment[]> => {
const response = await apiClient.get(`/tickets/${ticketId}/comments/`);
return response.data;
};
export const createTicketComment = async (ticketId: string, data: Partial<TicketComment>): Promise<TicketComment> => {
const response = await apiClient.post(`/tickets/${ticketId}/comments/`, data);
return response.data;
};
// Ticket Templates
export const getTicketTemplates = async (): Promise<TicketTemplate[]> => {
const response = await apiClient.get('/tickets/templates/');
return response.data;
};
export const getTicketTemplate = async (id: string): Promise<TicketTemplate> => {
const response = await apiClient.get(`/tickets/templates/${id}/`);
return response.data;
};
// Canned Responses
export const getCannedResponses = async (): Promise<CannedResponse[]> => {
const response = await apiClient.get('/tickets/canned-responses/');
return response.data;
};
// Refresh emails manually
export interface RefreshEmailsResult {
success: boolean;
processed: number;
results: {
address: string | null;
display_name?: string;
processed?: number;
status: string;
error?: string;
message?: string;
last_check_at?: string;
}[];
}
export const refreshTicketEmails = async (): Promise<RefreshEmailsResult> => {
const response = await apiClient.post('/tickets/refresh-emails/');
return response.data;
};