28295e346c
- Created a global TypeScript declaration for the txadmin interface on the Window object. - Implemented date formatting utilities using date-fns with Spanish locale support. - Added TypeScript configuration files for app, Electron, and Node environments. - Set up Vite configuration for React application.
406 lines
11 KiB
TypeScript
406 lines
11 KiB
TypeScript
const adminRequest = async <T = any>(route: string, body: unknown): Promise<T> => {
|
|
try {
|
|
return await window.txadmin.request<T>(route, body);
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
try {
|
|
const parsed = JSON.parse(error.message);
|
|
throw new Error(parsed.message || error.message);
|
|
} catch {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// User API Calls
|
|
export const fetchUsers = async (filters: any) => {
|
|
return adminRequest('users/paginate', filters);
|
|
};
|
|
|
|
export const updateUserProfile = async (data: any) => {
|
|
return adminRequest('users/update', data);
|
|
};
|
|
|
|
export const setVerifiedStatus = async (userId: string, isVerified: boolean) => {
|
|
return adminRequest('users/set-verified', { userId, isVerified });
|
|
};
|
|
|
|
export const deleteUser = async (userId: string) => {
|
|
return adminRequest('users/delete', { userId });
|
|
};
|
|
|
|
export const getOrganizationsStatus = async (userId: string) => {
|
|
return adminRequest('users/organizations-status', { userId });
|
|
};
|
|
|
|
export type RecalculatePlanUsageCycleResult = {
|
|
userId: string;
|
|
subscriptionId: string;
|
|
planId: string;
|
|
cycleStart: string;
|
|
cycleEnd: string;
|
|
organizationsCount: number;
|
|
employeesCount: number;
|
|
servicesCount: number;
|
|
clientsCount: number;
|
|
repeatsCount: number;
|
|
appointmentsCount: number;
|
|
};
|
|
|
|
export const recalculatePlanUsageCycle = async (userId: string): Promise<RecalculatePlanUsageCycleResult> => {
|
|
return adminRequest('users/recalculate-plan-usage-cycle', { userId });
|
|
};
|
|
|
|
export type UserSubscriptionDetails = {
|
|
userId: string;
|
|
currentSubscription: {
|
|
id: string;
|
|
plan: {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
price: number;
|
|
} | null;
|
|
startDate: string;
|
|
endDate: string;
|
|
isActive: boolean;
|
|
mpStatus?: string;
|
|
billingMonths?: number;
|
|
pendingPaymentType?: 'extension' | 'upgrade';
|
|
pendingPaymentPreferenceId?: string;
|
|
lastPaymentStatus?: string;
|
|
} | null;
|
|
payments: {
|
|
id: string;
|
|
subscriptionId: string;
|
|
amount: number;
|
|
paymentDate: string;
|
|
paymentMethod?: string;
|
|
status: string;
|
|
transactionId?: string;
|
|
}[];
|
|
};
|
|
|
|
export const getUserSubscriptionDetails = async (userId: string): Promise<UserSubscriptionDetails> => {
|
|
return adminRequest('users/subscription-details', { userId });
|
|
};
|
|
|
|
export type ExtendUserSubscriptionPayload = {
|
|
userId: string;
|
|
mode: 'add_months' | 'set_end_date';
|
|
months?: 1 | 2;
|
|
endDate?: string;
|
|
reason?: string;
|
|
};
|
|
|
|
export type ExtendUserSubscriptionResult = {
|
|
userId: string;
|
|
subscriptionId: string;
|
|
previousEndDate: string;
|
|
newEndDate: string;
|
|
paymentId: string;
|
|
transactionId?: string;
|
|
};
|
|
|
|
export const extendUserSubscription = async (data: ExtendUserSubscriptionPayload): Promise<ExtendUserSubscriptionResult> => {
|
|
return adminRequest('users/extend-subscription', data);
|
|
};
|
|
|
|
export type FinalizeUserSubscriptionPayload = {
|
|
userId: string;
|
|
reason?: string;
|
|
};
|
|
|
|
export type FinalizeUserSubscriptionResult = {
|
|
userId: string;
|
|
subscriptionId: string;
|
|
previousEndDate: string;
|
|
newEndDate: string;
|
|
};
|
|
|
|
export const finalizeUserSubscription = async (data: FinalizeUserSubscriptionPayload): Promise<FinalizeUserSubscriptionResult> => {
|
|
return adminRequest('users/finalize-subscription', data);
|
|
};
|
|
|
|
export type Plan = {
|
|
id?: string;
|
|
_id?: string;
|
|
name: string;
|
|
description: string;
|
|
features: string[];
|
|
code: string;
|
|
price: number;
|
|
annualPrice: number;
|
|
limitOrganizations: number;
|
|
limitEmployees: number;
|
|
limitServices: number;
|
|
limitAppointments: number;
|
|
limitClients: number;
|
|
limitRepeats: number;
|
|
mailNotifications: boolean;
|
|
smsNotifications: boolean;
|
|
wapNotifications: boolean;
|
|
payments: boolean;
|
|
bot: boolean;
|
|
active: boolean;
|
|
dateLimit: boolean;
|
|
discount3Months?: number;
|
|
discount6Months?: number;
|
|
discount12Months?: number;
|
|
featured?: boolean;
|
|
};
|
|
|
|
export type UpdatePlanPayload = Partial<Omit<Plan, 'id' | '_id'>> & {
|
|
planId: string;
|
|
};
|
|
|
|
export const fetchPlans = async (): Promise<Plan[]> => {
|
|
return adminRequest('plans/list', {});
|
|
};
|
|
|
|
export const updatePlan = async (data: UpdatePlanPayload) => {
|
|
return adminRequest('plans/update', data);
|
|
};
|
|
|
|
// Wap Servers API Calls
|
|
export const fetchWapServers = async (filters: any) => {
|
|
return adminRequest('wap/paginate', filters);
|
|
};
|
|
|
|
export type WapServer = {
|
|
id?: string;
|
|
_id?: string;
|
|
name?: string;
|
|
description?: string;
|
|
ipv4: string;
|
|
ipv6?: string;
|
|
countBots: number;
|
|
maxBots: number;
|
|
port: number;
|
|
active: boolean;
|
|
};
|
|
|
|
export type UpdateWapServerPayload = {
|
|
serverId: string;
|
|
name?: string;
|
|
ipv4?: string;
|
|
port?: number;
|
|
maxBots?: number;
|
|
active?: boolean;
|
|
};
|
|
|
|
export type CreateWapServerPayload = {
|
|
name: string;
|
|
ipv4: string;
|
|
port: number;
|
|
maxBots: number;
|
|
ipv6?: string;
|
|
description?: string;
|
|
active?: boolean;
|
|
};
|
|
|
|
export const createWapServer = async (data: CreateWapServerPayload): Promise<WapServer> => {
|
|
return adminRequest('wap/create', data);
|
|
};
|
|
|
|
export const updateWapServer = async (data: UpdateWapServerPayload): Promise<WapServer> => {
|
|
return adminRequest('wap/update', data);
|
|
};
|
|
|
|
export type WapAssignedOrganization = {
|
|
id: string;
|
|
name?: string;
|
|
};
|
|
|
|
export type WapContainerDto = {
|
|
id?: string;
|
|
name?: string;
|
|
organizationId?: string;
|
|
image?: string;
|
|
state?: string;
|
|
status?: string;
|
|
ports?: unknown[];
|
|
created?: number;
|
|
};
|
|
|
|
export type WapServerAuditResult = {
|
|
serverId: string;
|
|
assignedOrganizations: WapAssignedOrganization[];
|
|
detectedBots: WapContainerDto[];
|
|
validBots: WapContainerDto[];
|
|
ghostBots: WapContainerDto[];
|
|
missingBots: WapAssignedOrganization[];
|
|
expectedCountBots: number;
|
|
storedCountBots: number;
|
|
runtimeCountBots: number;
|
|
countMismatch: boolean;
|
|
};
|
|
|
|
export type WapServerRecalculateCountResult = {
|
|
serverId: string;
|
|
before: number;
|
|
after: number;
|
|
};
|
|
|
|
export type WapServerDeleteResult = {
|
|
serverId: string;
|
|
deleted: true;
|
|
force?: boolean;
|
|
detachedOrganizations?: number;
|
|
deletedRuntimeBots?: number;
|
|
skippedRuntimeBots?: number;
|
|
auditFailed?: boolean;
|
|
auditMessage?: string;
|
|
};
|
|
|
|
export type WapServerDeletePayload = {
|
|
serverId: string;
|
|
force?: boolean;
|
|
};
|
|
|
|
export type WapServerOrganizationActionPayload = {
|
|
serverId: string;
|
|
organizationId: string;
|
|
};
|
|
|
|
export type WapServerQrResult = WapServerOrganizationActionPayload & {
|
|
qr: string;
|
|
};
|
|
|
|
export type WapServerDetachResult = WapServerOrganizationActionPayload & {
|
|
botDeleted: boolean;
|
|
botAlreadyMissing: boolean;
|
|
before: number;
|
|
after: number;
|
|
};
|
|
|
|
export const auditWapServer = async (serverId: string): Promise<WapServerAuditResult> => {
|
|
return adminRequest('wap/audit', { serverId });
|
|
};
|
|
|
|
export const recalculateWapServerCount = async (serverId: string): Promise<WapServerRecalculateCountResult> => {
|
|
return adminRequest('wap/recalculate-count', { serverId });
|
|
};
|
|
|
|
export const deleteWapServer = async (data: WapServerDeletePayload): Promise<WapServerDeleteResult> => {
|
|
return adminRequest('wap/delete', data);
|
|
};
|
|
|
|
export const startWapBot = async (data: WapServerOrganizationActionPayload): Promise<void> => {
|
|
await adminRequest('wap/bot/start', data);
|
|
};
|
|
|
|
export const stopWapBot = async (data: WapServerOrganizationActionPayload): Promise<void> => {
|
|
await adminRequest('wap/bot/stop', data);
|
|
};
|
|
|
|
export const restartWapBot = async (data: WapServerOrganizationActionPayload): Promise<void> => {
|
|
await adminRequest('wap/bot/restart', data);
|
|
};
|
|
|
|
export const getWapBotQr = async (data: WapServerOrganizationActionPayload): Promise<WapServerQrResult> => {
|
|
return adminRequest('wap/bot/qr', data);
|
|
};
|
|
|
|
export const deleteWapBot = async (data: WapServerOrganizationActionPayload): Promise<void> => {
|
|
await adminRequest('wap/bot/delete', data);
|
|
};
|
|
|
|
export const detachWapOrganizationServer = async (data: WapServerOrganizationActionPayload): Promise<WapServerDetachResult> => {
|
|
return adminRequest('wap/bot/detach', data);
|
|
};
|
|
|
|
// Companies API Calls
|
|
export const fetchCompanies = async (filters: any) => {
|
|
return adminRequest('companies/paginate', filters);
|
|
};
|
|
|
|
export const updateCompany = async (data: any) => {
|
|
return adminRequest('companies/update', data);
|
|
};
|
|
|
|
export const setCompanyBanned = async (id: string, banned: boolean) => {
|
|
return adminRequest('companies/set-banned', { id, banned });
|
|
};
|
|
|
|
export type OrganizationInsights = {
|
|
organization: {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
description: string;
|
|
categoryId: number;
|
|
banned: boolean;
|
|
published?: string;
|
|
onboardingStep?: number;
|
|
onboardingCompleted?: boolean;
|
|
};
|
|
owner: {
|
|
id: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
email?: string;
|
|
verificated?: boolean;
|
|
phoneCountryCode?: string;
|
|
phoneAreaCode?: string;
|
|
phoneNumber?: string;
|
|
} | null;
|
|
collaborators: {
|
|
id: string;
|
|
userId?: string;
|
|
firstName?: string;
|
|
lastName?: string;
|
|
fullName?: string;
|
|
email?: string;
|
|
roles?: string[];
|
|
removed?: boolean;
|
|
active: boolean;
|
|
avatar?: string;
|
|
}[];
|
|
subscription: {
|
|
id: string;
|
|
startDate: string;
|
|
endDate: string;
|
|
isActive: boolean;
|
|
autoRenew: boolean;
|
|
mpStatus?: string;
|
|
pendingPaymentType?: 'extension' | 'upgrade';
|
|
plan: {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
price: number;
|
|
limitOrganizations: number;
|
|
limitEmployees: number;
|
|
limitServices: number;
|
|
limitAppointments: number;
|
|
limitClients: number;
|
|
} | null;
|
|
} | null;
|
|
stats: {
|
|
employeesCount: number;
|
|
activeEmployeesCount: number;
|
|
servicesCount: number;
|
|
activeServicesCount: number;
|
|
clientsCount: number;
|
|
activeClientsCount: number;
|
|
reservationsLast30Days: number;
|
|
};
|
|
};
|
|
|
|
export const fetchOrganizationInsights = async (companyId: string): Promise<OrganizationInsights> => {
|
|
return adminRequest('companies/insights', { companyId });
|
|
};
|
|
|
|
// Services API Calls
|
|
export const fetchServices = async (filters: any) => {
|
|
return adminRequest('services/paginate', filters);
|
|
};
|
|
|
|
export const setServiceBanned = async (id: string, banned: boolean) => {
|
|
return adminRequest('services/set-banned', { id, banned });
|
|
};
|