first commit
This commit is contained in:
@@ -0,0 +1,773 @@
|
||||
import axios from 'axios';
|
||||
import type { ApiResponse, Customer, Contract, ContractTask, ContractTaskSubtask, ContractTaskStatus, SalesPlatform, CancellationPeriod, ContractDuration, ContractCategory, Provider, Tariff, User, Address, BankCard, IdentityDocument, Meter, MeterReading, Role, PortalSettings, CustomerRepresentative, CustomerSummary } from '../types';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// Add auth token to requests
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// Handle auth errors and extract error messages
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
// Bei 401 nur dann zur Login-Seite umleiten, wenn wir NICHT gerade auf der Login-Seite sind
|
||||
// Login-Endpunkte ausschließen, da 401 dort "falsches Passwort" bedeutet
|
||||
const isLoginEndpoint = error.config?.url?.includes('/auth/login') ||
|
||||
error.config?.url?.includes('/auth/customer-login');
|
||||
|
||||
if (error.response?.status === 401 && !isLoginEndpoint) {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('user');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
// Extract error message from response
|
||||
const message = error.response?.data?.error || error.message || 'Ein Fehler ist aufgetreten';
|
||||
const enhancedError = new Error(message);
|
||||
return Promise.reject(enhancedError);
|
||||
}
|
||||
);
|
||||
|
||||
// Auth
|
||||
export const authApi = {
|
||||
login: async (email: string, password: string) => {
|
||||
const res = await api.post<ApiResponse<{ token: string; user: User }>>('/auth/login', { email, password });
|
||||
return res.data;
|
||||
},
|
||||
customerLogin: async (email: string, password: string) => {
|
||||
const res = await api.post<ApiResponse<{ token: string; user: User }>>('/auth/customer-login', { email, password });
|
||||
return res.data;
|
||||
},
|
||||
me: async () => {
|
||||
const res = await api.get<ApiResponse<User>>('/auth/me');
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Customers
|
||||
export const customerApi = {
|
||||
getAll: async (params?: { search?: string; type?: string; page?: number; limit?: number }) => {
|
||||
const res = await api.get<ApiResponse<Customer[]>>('/customers', { params });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<Customer>>(`/customers/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<Customer>) => {
|
||||
const res = await api.post<ApiResponse<Customer>>('/customers', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Customer>) => {
|
||||
const res = await api.put<ApiResponse<Customer>>(`/customers/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/customers/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
// Portal-Einstellungen
|
||||
getPortalSettings: async (customerId: number) => {
|
||||
const res = await api.get<ApiResponse<PortalSettings>>(`/customers/${customerId}/portal`);
|
||||
return res.data;
|
||||
},
|
||||
updatePortalSettings: async (customerId: number, data: { portalEnabled?: boolean; portalEmail?: string | null }) => {
|
||||
const res = await api.put<ApiResponse<PortalSettings>>(`/customers/${customerId}/portal`, data);
|
||||
return res.data;
|
||||
},
|
||||
setPortalPassword: async (customerId: number, password: string) => {
|
||||
const res = await api.post<ApiResponse<void>>(`/customers/${customerId}/portal/password`, { password });
|
||||
return res.data;
|
||||
},
|
||||
getPortalPassword: async (customerId: number) => {
|
||||
const res = await api.get<ApiResponse<{ password: string | null }>>(`/customers/${customerId}/portal/password`);
|
||||
return res.data;
|
||||
},
|
||||
// Vertreter-Verwaltung
|
||||
getRepresentatives: async (customerId: number) => {
|
||||
const res = await api.get<ApiResponse<CustomerRepresentative[]>>(`/customers/${customerId}/representatives`);
|
||||
return res.data;
|
||||
},
|
||||
addRepresentative: async (customerId: number, representativeId: number, notes?: string) => {
|
||||
const res = await api.post<ApiResponse<CustomerRepresentative>>(`/customers/${customerId}/representatives`, { representativeId, notes });
|
||||
return res.data;
|
||||
},
|
||||
removeRepresentative: async (customerId: number, representativeId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/customers/${customerId}/representatives/${representativeId}`);
|
||||
return res.data;
|
||||
},
|
||||
searchForRepresentative: async (customerId: number, search: string) => {
|
||||
const res = await api.get<ApiResponse<CustomerSummary[]>>(`/customers/${customerId}/representatives/search`, { params: { search } });
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Addresses
|
||||
export const addressApi = {
|
||||
getByCustomer: async (customerId: number) => {
|
||||
const res = await api.get<ApiResponse<Address[]>>(`/customers/${customerId}/addresses`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (customerId: number, data: Partial<Address>) => {
|
||||
const res = await api.post<ApiResponse<Address>>(`/customers/${customerId}/addresses`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Address>) => {
|
||||
const res = await api.put<ApiResponse<Address>>(`/addresses/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/addresses/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Bank Cards
|
||||
export const bankCardApi = {
|
||||
getByCustomer: async (customerId: number, showInactive = false) => {
|
||||
const res = await api.get<ApiResponse<BankCard[]>>(`/customers/${customerId}/bank-cards`, { params: { showInactive } });
|
||||
return res.data;
|
||||
},
|
||||
create: async (customerId: number, data: Partial<BankCard>) => {
|
||||
const res = await api.post<ApiResponse<BankCard>>(`/customers/${customerId}/bank-cards`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<BankCard>) => {
|
||||
const res = await api.put<ApiResponse<BankCard>>(`/bank-cards/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/bank-cards/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Identity Documents
|
||||
export const documentApi = {
|
||||
getByCustomer: async (customerId: number, showInactive = false) => {
|
||||
const res = await api.get<ApiResponse<IdentityDocument[]>>(`/customers/${customerId}/documents`, { params: { showInactive } });
|
||||
return res.data;
|
||||
},
|
||||
create: async (customerId: number, data: Partial<IdentityDocument>) => {
|
||||
const res = await api.post<ApiResponse<IdentityDocument>>(`/customers/${customerId}/documents`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<IdentityDocument>) => {
|
||||
const res = await api.put<ApiResponse<IdentityDocument>>(`/documents/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/documents/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Meters
|
||||
export const meterApi = {
|
||||
getByCustomer: async (customerId: number, showInactive = false) => {
|
||||
const res = await api.get<ApiResponse<Meter[]>>(`/customers/${customerId}/meters`, { params: { showInactive } });
|
||||
return res.data;
|
||||
},
|
||||
create: async (customerId: number, data: Partial<Meter>) => {
|
||||
const res = await api.post<ApiResponse<Meter>>(`/customers/${customerId}/meters`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Meter>) => {
|
||||
const res = await api.put<ApiResponse<Meter>>(`/meters/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/meters/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
getReadings: async (meterId: number) => {
|
||||
const res = await api.get<ApiResponse<MeterReading[]>>(`/meters/${meterId}/readings`);
|
||||
return res.data;
|
||||
},
|
||||
addReading: async (meterId: number, data: Partial<MeterReading>) => {
|
||||
const res = await api.post<ApiResponse<MeterReading>>(`/meters/${meterId}/readings`, data);
|
||||
return res.data;
|
||||
},
|
||||
updateReading: async (meterId: number, readingId: number, data: Partial<MeterReading>) => {
|
||||
const res = await api.put<ApiResponse<MeterReading>>(`/meters/${meterId}/readings/${readingId}`, data);
|
||||
return res.data;
|
||||
},
|
||||
deleteReading: async (meterId: number, readingId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/meters/${meterId}/readings/${readingId}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Stressfrei-Wechseln E-Mail-Adressen
|
||||
export interface StressfreiEmail {
|
||||
id: number;
|
||||
customerId: number;
|
||||
email: string;
|
||||
platform?: string;
|
||||
notes?: string;
|
||||
isActive: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const stressfreiEmailApi = {
|
||||
getByCustomer: async (customerId: number, includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<StressfreiEmail[]>>(`/customers/${customerId}/stressfrei-emails`, { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
create: async (customerId: number, data: { email: string; platform?: string; notes?: string }) => {
|
||||
const res = await api.post<ApiResponse<StressfreiEmail>>(`/customers/${customerId}/stressfrei-emails`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<StressfreiEmail>) => {
|
||||
const res = await api.put<ApiResponse<StressfreiEmail>>(`/stressfrei-emails/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/stressfrei-emails/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Contracts
|
||||
export const contractApi = {
|
||||
getAll: async (params?: { customerId?: number; type?: string; status?: string; search?: string; page?: number; limit?: number }) => {
|
||||
const res = await api.get<ApiResponse<Contract[]>>('/contracts', { params });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<Contract>>(`/contracts/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<Contract> & { [key: string]: unknown }) => {
|
||||
const res = await api.post<ApiResponse<Contract>>('/contracts', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Contract> & { [key: string]: unknown }) => {
|
||||
const res = await api.put<ApiResponse<Contract>>(`/contracts/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/contracts/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
createFollowUp: async (id: number) => {
|
||||
const res = await api.post<ApiResponse<Contract>>(`/contracts/${id}/follow-up`);
|
||||
return res.data;
|
||||
},
|
||||
getPassword: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<{ password: string }>>(`/contracts/${id}/password`);
|
||||
return res.data;
|
||||
},
|
||||
getSimCardCredentials: async (simCardId: number) => {
|
||||
const res = await api.get<ApiResponse<{ pin: string | null; puk: string | null }>>(`/contracts/simcard/${simCardId}/credentials`);
|
||||
return res.data;
|
||||
},
|
||||
getInternetCredentials: async (contractId: number) => {
|
||||
const res = await api.get<ApiResponse<{ password: string | null }>>(`/contracts/${contractId}/internet-credentials`);
|
||||
return res.data;
|
||||
},
|
||||
getSipCredentials: async (phoneNumberId: number) => {
|
||||
const res = await api.get<ApiResponse<{ password: string | null }>>(`/contracts/phonenumber/${phoneNumberId}/sip-credentials`);
|
||||
return res.data;
|
||||
},
|
||||
// Vertrags-Cockpit
|
||||
getCockpit: async () => {
|
||||
const res = await api.get<ApiResponse<import('../types').CockpitResult>>('/contracts/cockpit');
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Contract Tasks (Aufgaben)
|
||||
export const contractTaskApi = {
|
||||
// Alle Tasks über alle Verträge (für Task-Liste & Dashboard)
|
||||
getAll: async (params?: { status?: ContractTaskStatus; customerId?: number }) => {
|
||||
const res = await api.get<ApiResponse<ContractTask[]>>('/tasks', { params });
|
||||
return res.data;
|
||||
},
|
||||
// Task-Statistik (offene Aufgaben)
|
||||
getStats: async () => {
|
||||
const res = await api.get<ApiResponse<{ openCount: number }>>('/tasks/stats');
|
||||
return res.data;
|
||||
},
|
||||
// Tasks für einen spezifischen Vertrag
|
||||
getByContract: async (contractId: number, status?: ContractTaskStatus) => {
|
||||
const res = await api.get<ApiResponse<ContractTask[]>>(`/contracts/${contractId}/tasks`, { params: { status } });
|
||||
return res.data;
|
||||
},
|
||||
create: async (contractId: number, data: { title: string; description?: string; visibleInPortal?: boolean }) => {
|
||||
const res = await api.post<ApiResponse<ContractTask>>(`/contracts/${contractId}/tasks`, data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (taskId: number, data: { title?: string; description?: string; visibleInPortal?: boolean }) => {
|
||||
const res = await api.put<ApiResponse<ContractTask>>(`/tasks/${taskId}`, data);
|
||||
return res.data;
|
||||
},
|
||||
complete: async (taskId: number) => {
|
||||
const res = await api.post<ApiResponse<ContractTask>>(`/tasks/${taskId}/complete`);
|
||||
return res.data;
|
||||
},
|
||||
reopen: async (taskId: number) => {
|
||||
const res = await api.post<ApiResponse<ContractTask>>(`/tasks/${taskId}/reopen`);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (taskId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/tasks/${taskId}`);
|
||||
return res.data;
|
||||
},
|
||||
// Subtasks
|
||||
createSubtask: async (taskId: number, title: string) => {
|
||||
const res = await api.post<ApiResponse<ContractTaskSubtask>>(`/tasks/${taskId}/subtasks`, { title });
|
||||
return res.data;
|
||||
},
|
||||
// Kundenportal: Antwort auf eigenes Ticket
|
||||
createReply: async (taskId: number, title: string) => {
|
||||
const res = await api.post<ApiResponse<ContractTaskSubtask>>(`/tasks/${taskId}/reply`, { title });
|
||||
return res.data;
|
||||
},
|
||||
updateSubtask: async (subtaskId: number, title: string) => {
|
||||
const res = await api.put<ApiResponse<ContractTaskSubtask>>(`/subtasks/${subtaskId}`, { title });
|
||||
return res.data;
|
||||
},
|
||||
completeSubtask: async (subtaskId: number) => {
|
||||
const res = await api.post<ApiResponse<ContractTaskSubtask>>(`/subtasks/${subtaskId}/complete`);
|
||||
return res.data;
|
||||
},
|
||||
reopenSubtask: async (subtaskId: number) => {
|
||||
const res = await api.post<ApiResponse<ContractTaskSubtask>>(`/subtasks/${subtaskId}/reopen`);
|
||||
return res.data;
|
||||
},
|
||||
deleteSubtask: async (subtaskId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/subtasks/${subtaskId}`);
|
||||
return res.data;
|
||||
},
|
||||
// Support-Ticket erstellen (für Kundenportal)
|
||||
createSupportTicket: async (contractId: number, data: { title: string; description?: string }) => {
|
||||
const res = await api.post<ApiResponse<ContractTask>>(`/contracts/${contractId}/support-ticket`, data);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// App Settings
|
||||
export const appSettingsApi = {
|
||||
getPublic: async () => {
|
||||
const res = await api.get<ApiResponse<Record<string, string>>>('/settings/public');
|
||||
return res.data;
|
||||
},
|
||||
getAll: async () => {
|
||||
const res = await api.get<ApiResponse<Record<string, string>>>('/settings');
|
||||
return res.data;
|
||||
},
|
||||
update: async (settings: Record<string, string>) => {
|
||||
const res = await api.put<ApiResponse<void>>('/settings', settings);
|
||||
return res.data;
|
||||
},
|
||||
updateOne: async (key: string, value: string) => {
|
||||
const res = await api.put<ApiResponse<void>>(`/settings/${key}`, { value });
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Platforms
|
||||
export const platformApi = {
|
||||
getAll: async (includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<SalesPlatform[]>>('/platforms', { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<SalesPlatform>>(`/platforms/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<SalesPlatform>) => {
|
||||
const res = await api.post<ApiResponse<SalesPlatform>>('/platforms', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<SalesPlatform>) => {
|
||||
const res = await api.put<ApiResponse<SalesPlatform>>(`/platforms/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/platforms/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Cancellation Periods
|
||||
export const cancellationPeriodApi = {
|
||||
getAll: async (includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<CancellationPeriod[]>>('/cancellation-periods', { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<CancellationPeriod>>(`/cancellation-periods/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<CancellationPeriod>) => {
|
||||
const res = await api.post<ApiResponse<CancellationPeriod>>('/cancellation-periods', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<CancellationPeriod>) => {
|
||||
const res = await api.put<ApiResponse<CancellationPeriod>>(`/cancellation-periods/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/cancellation-periods/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Contract Durations
|
||||
export const contractDurationApi = {
|
||||
getAll: async (includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<ContractDuration[]>>('/contract-durations', { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<ContractDuration>>(`/contract-durations/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<ContractDuration>) => {
|
||||
const res = await api.post<ApiResponse<ContractDuration>>('/contract-durations', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<ContractDuration>) => {
|
||||
const res = await api.put<ApiResponse<ContractDuration>>(`/contract-durations/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/contract-durations/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Contract Categories (Vertragstypen)
|
||||
export const contractCategoryApi = {
|
||||
getAll: async (includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<ContractCategory[]>>('/contract-categories', { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<ContractCategory>>(`/contract-categories/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<ContractCategory>) => {
|
||||
const res = await api.post<ApiResponse<ContractCategory>>('/contract-categories', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<ContractCategory>) => {
|
||||
const res = await api.put<ApiResponse<ContractCategory>>(`/contract-categories/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/contract-categories/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Providers (Anbieter)
|
||||
export const providerApi = {
|
||||
getAll: async (includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<Provider[]>>('/providers', { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<Provider>>(`/providers/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: Partial<Provider>) => {
|
||||
const res = await api.post<ApiResponse<Provider>>('/providers', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Provider>) => {
|
||||
const res = await api.put<ApiResponse<Provider>>(`/providers/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/providers/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
getTariffs: async (providerId: number, includeInactive = false) => {
|
||||
const res = await api.get<ApiResponse<Tariff[]>>(`/providers/${providerId}/tariffs`, { params: { includeInactive } });
|
||||
return res.data;
|
||||
},
|
||||
createTariff: async (providerId: number, data: Partial<Tariff>) => {
|
||||
const res = await api.post<ApiResponse<Tariff>>(`/providers/${providerId}/tariffs`, data);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Tariffs (Tarife)
|
||||
export const tariffApi = {
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<Tariff>>(`/tariffs/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<Tariff>) => {
|
||||
const res = await api.put<ApiResponse<Tariff>>(`/tariffs/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/tariffs/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Upload
|
||||
export const uploadApi = {
|
||||
uploadBankCardDocument: async (bankCardId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/bank-cards/${bankCardId}`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
uploadIdentityDocument: async (documentId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/documents/${documentId}`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteBankCardDocument: async (bankCardId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/bank-cards/${bankCardId}`);
|
||||
return res.data;
|
||||
},
|
||||
deleteIdentityDocument: async (documentId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/documents/${documentId}`);
|
||||
return res.data;
|
||||
},
|
||||
uploadBusinessRegistration: async (customerId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/customers/${customerId}/business-registration`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteBusinessRegistration: async (customerId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/customers/${customerId}/business-registration`);
|
||||
return res.data;
|
||||
},
|
||||
uploadCommercialRegister: async (customerId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/customers/${customerId}/commercial-register`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteCommercialRegister: async (customerId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/customers/${customerId}/commercial-register`);
|
||||
return res.data;
|
||||
},
|
||||
uploadPrivacyPolicy: async (customerId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/customers/${customerId}/privacy-policy`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deletePrivacyPolicy: async (customerId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/customers/${customerId}/privacy-policy`);
|
||||
return res.data;
|
||||
},
|
||||
// Contract Documents
|
||||
uploadCancellationLetter: async (contractId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-letter`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteCancellationLetter: async (contractId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-letter`);
|
||||
return res.data;
|
||||
},
|
||||
uploadCancellationConfirmation: async (contractId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-confirmation`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteCancellationConfirmation: async (contractId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-confirmation`);
|
||||
return res.data;
|
||||
},
|
||||
uploadCancellationLetterOptions: async (contractId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-letter-options`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteCancellationLetterOptions: async (contractId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-letter-options`);
|
||||
return res.data;
|
||||
},
|
||||
uploadCancellationConfirmationOptions: async (contractId: number, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('document', file);
|
||||
const res = await api.post<ApiResponse<{ path: string; filename: string }>>(`/upload/contracts/${contractId}/cancellation-confirmation-options`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
},
|
||||
deleteCancellationConfirmationOptions: async (contractId: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/upload/contracts/${contractId}/cancellation-confirmation-options`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Users
|
||||
export const userApi = {
|
||||
getAll: async (params?: { search?: string; isActive?: boolean; roleId?: number; page?: number; limit?: number }) => {
|
||||
const res = await api.get<ApiResponse<User[]>>('/users', { params });
|
||||
return res.data;
|
||||
},
|
||||
getById: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<User>>(`/users/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
create: async (data: { email: string; password: string; firstName: string; lastName: string; roleIds: number[]; customerId?: number }) => {
|
||||
const res = await api.post<ApiResponse<User>>('/users', data);
|
||||
return res.data;
|
||||
},
|
||||
update: async (id: number, data: Partial<User> & { password?: string; roleIds?: number[] }) => {
|
||||
const res = await api.put<ApiResponse<User>>(`/users/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/users/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
getRoles: async () => {
|
||||
const res = await api.get<ApiResponse<Role[]>>('/users/roles/list');
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Developer
|
||||
export const developerApi = {
|
||||
getSchema: async () => {
|
||||
const res = await api.get<ApiResponse<any[]>>('/developer/schema');
|
||||
return res.data;
|
||||
},
|
||||
getTableData: async (tableName: string, page = 1, limit = 50) => {
|
||||
const res = await api.get<ApiResponse<any[]>>(`/developer/table/${tableName}`, { params: { page, limit } });
|
||||
return res.data;
|
||||
},
|
||||
updateRow: async (tableName: string, id: string, data: Record<string, any>) => {
|
||||
const res = await api.put<ApiResponse<any>>(`/developer/table/${tableName}/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
deleteRow: async (tableName: string, id: string) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/developer/table/${tableName}/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
getReference: async (tableName: string) => {
|
||||
const res = await api.get<ApiResponse<any[]>>(`/developer/reference/${tableName}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
// Email Provider (für Stressfrei-Wechseln Provisionierung)
|
||||
export interface EmailProviderConfig {
|
||||
id: number;
|
||||
name: string;
|
||||
type: 'PLESK' | 'CPANEL' | 'DIRECTADMIN';
|
||||
apiUrl: string;
|
||||
apiKey?: string;
|
||||
username?: string;
|
||||
passwordEncrypted?: string;
|
||||
domain: string;
|
||||
defaultForwardEmail?: string;
|
||||
isActive: boolean;
|
||||
isDefault: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface EmailOperationResult {
|
||||
success: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const emailProviderApi = {
|
||||
// Config CRUD
|
||||
getConfigs: async () => {
|
||||
const res = await api.get<ApiResponse<EmailProviderConfig[]>>('/email-providers/configs');
|
||||
return res.data;
|
||||
},
|
||||
getConfig: async (id: number) => {
|
||||
const res = await api.get<ApiResponse<EmailProviderConfig>>(`/email-providers/configs/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
createConfig: async (data: Partial<EmailProviderConfig> & { password?: string }) => {
|
||||
const res = await api.post<ApiResponse<EmailProviderConfig>>('/email-providers/configs', data);
|
||||
return res.data;
|
||||
},
|
||||
updateConfig: async (id: number, data: Partial<EmailProviderConfig> & { password?: string }) => {
|
||||
const res = await api.put<ApiResponse<EmailProviderConfig>>(`/email-providers/configs/${id}`, data);
|
||||
return res.data;
|
||||
},
|
||||
deleteConfig: async (id: number) => {
|
||||
const res = await api.delete<ApiResponse<void>>(`/email-providers/configs/${id}`);
|
||||
return res.data;
|
||||
},
|
||||
// Email Operations
|
||||
testConnection: async (options?: {
|
||||
id?: number;
|
||||
testData?: {
|
||||
type: 'PLESK' | 'CPANEL' | 'DIRECTADMIN';
|
||||
apiUrl: string;
|
||||
apiKey?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
domain: string;
|
||||
};
|
||||
}) => {
|
||||
const body = options?.testData
|
||||
? { ...options.testData }
|
||||
: options?.id
|
||||
? { id: options.id }
|
||||
: {};
|
||||
const res = await api.post<ApiResponse<EmailOperationResult>>('/email-providers/test-connection', body);
|
||||
return res.data;
|
||||
},
|
||||
getDomain: async () => {
|
||||
const res = await api.get<ApiResponse<{ domain: string | null }>>('/email-providers/domain');
|
||||
return res.data;
|
||||
},
|
||||
checkEmailExists: async (localPart: string) => {
|
||||
const res = await api.get<ApiResponse<{ exists: boolean; email?: string }>>(`/email-providers/check/${localPart}`);
|
||||
return res.data;
|
||||
},
|
||||
provisionEmail: async (localPart: string, customerEmail: string) => {
|
||||
const res = await api.post<ApiResponse<EmailOperationResult>>('/email-providers/provision', { localPart, customerEmail });
|
||||
return res.data;
|
||||
},
|
||||
deprovisionEmail: async (localPart: string) => {
|
||||
const res = await api.delete<ApiResponse<EmailOperationResult>>(`/email-providers/deprovision/${localPart}`);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
export default api;
|
||||
Reference in New Issue
Block a user