feat: Add SMTP settings and collapsible email configuration UI
- Add SMTP fields to TicketEmailSettings model (host, port, TLS/SSL, credentials, from email/name) - Update serializers with SMTP fields and is_smtp_configured flag - Add TicketEmailTestSmtpView for testing SMTP connections - Update frontend API types and hooks for SMTP settings - Add collapsible IMAP and SMTP configuration sections with "Configured" badges - Fix TypeScript errors in mockData.ts (missing required fields, type mismatches) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
106
frontend/src/hooks/useTicketEmailSettings.ts
Normal file
106
frontend/src/hooks/useTicketEmailSettings.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* React Query hooks for ticket email settings
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import {
|
||||
getTicketEmailSettings,
|
||||
updateTicketEmailSettings,
|
||||
testImapConnection,
|
||||
testSmtpConnection,
|
||||
fetchEmailsNow,
|
||||
getIncomingEmails,
|
||||
reprocessIncomingEmail,
|
||||
TicketEmailSettings,
|
||||
TicketEmailSettingsUpdate,
|
||||
IncomingTicketEmail,
|
||||
} from '../api/ticketEmailSettings';
|
||||
|
||||
const QUERY_KEY = 'ticketEmailSettings';
|
||||
const INCOMING_EMAILS_KEY = 'incomingTicketEmails';
|
||||
|
||||
/**
|
||||
* Hook to fetch ticket email settings
|
||||
*/
|
||||
export const useTicketEmailSettings = () => {
|
||||
return useQuery<TicketEmailSettings>({
|
||||
queryKey: [QUERY_KEY],
|
||||
queryFn: getTicketEmailSettings,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to update ticket email settings
|
||||
*/
|
||||
export const useUpdateTicketEmailSettings = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (data: TicketEmailSettingsUpdate) => updateTicketEmailSettings(data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to test IMAP connection
|
||||
*/
|
||||
export const useTestImapConnection = () => {
|
||||
return useMutation({
|
||||
mutationFn: testImapConnection,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to test SMTP connection
|
||||
*/
|
||||
export const useTestSmtpConnection = () => {
|
||||
return useMutation({
|
||||
mutationFn: testSmtpConnection,
|
||||
});
|
||||
};
|
||||
|
||||
// Legacy alias
|
||||
export const useTestEmailConnection = useTestImapConnection;
|
||||
|
||||
/**
|
||||
* Hook to manually fetch emails
|
||||
*/
|
||||
export const useFetchEmailsNow = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: fetchEmailsNow,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });
|
||||
queryClient.invalidateQueries({ queryKey: [INCOMING_EMAILS_KEY] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to fetch incoming email audit log
|
||||
*/
|
||||
export const useIncomingEmails = (params?: { status?: string; ticket?: number }) => {
|
||||
return useQuery<IncomingTicketEmail[]>({
|
||||
queryKey: [INCOMING_EMAILS_KEY, params],
|
||||
queryFn: () => getIncomingEmails(params),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to reprocess a failed incoming email
|
||||
*/
|
||||
export const useReprocessIncomingEmail = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => reprocessIncomingEmail(id),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [INCOMING_EMAILS_KEY] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export type { TicketEmailSettings, TicketEmailSettingsUpdate, IncomingTicketEmail };
|
||||
@@ -46,6 +46,29 @@ export const useStaffForAssignment = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to fetch platform staff members for ticket assignment.
|
||||
* Returns platform admins (superuser, platform_manager, platform_support) formatted for dropdown use.
|
||||
*/
|
||||
export const usePlatformStaffForAssignment = () => {
|
||||
return useQuery<{ id: string; name: string; email: string; role: string }[]>({
|
||||
queryKey: ['platformStaffForAssignment'],
|
||||
queryFn: async () => {
|
||||
const response = await apiClient.get('/api/platform/users/');
|
||||
// Filter to only platform-level roles and format for dropdown
|
||||
const platformRoles = ['superuser', 'platform_manager', 'platform_support'];
|
||||
return response.data
|
||||
.filter((user: { role: string }) => platformRoles.includes(user.role))
|
||||
.map((user: { id: number; name?: string; email: string; role: string }) => ({
|
||||
id: String(user.id),
|
||||
name: user.name || user.email,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
}));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to update a staff member's permissions
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user