fix
This commit is contained in:
66
src/services/agent-types.service.ts
Normal file
66
src/services/agent-types.service.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import api, { ApiResponse } from './api';
|
||||
|
||||
// Types
|
||||
export interface AgentType {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
icon: string | null;
|
||||
isActive: boolean;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
_count?: {
|
||||
agents: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateAgentTypeDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
isActive?: boolean;
|
||||
sortOrder?: number;
|
||||
}
|
||||
|
||||
export interface UpdateAgentTypeDto {
|
||||
name?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
isActive?: boolean;
|
||||
sortOrder?: number;
|
||||
}
|
||||
|
||||
// Agent Types Service
|
||||
class AgentTypesService {
|
||||
private basePath = '/agent-types';
|
||||
|
||||
async getAll(includeInactive = false): Promise<AgentType[]> {
|
||||
const url = includeInactive
|
||||
? `${this.basePath}?includeInactive=true`
|
||||
: this.basePath;
|
||||
const response = await api.get<ApiResponse<AgentType[]>>(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<AgentType> {
|
||||
const response = await api.get<ApiResponse<AgentType>>(`${this.basePath}/${id}`);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async create(data: CreateAgentTypeDto): Promise<AgentType> {
|
||||
const response = await api.post<ApiResponse<AgentType>>(this.basePath, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateAgentTypeDto): Promise<AgentType> {
|
||||
const response = await api.patch<ApiResponse<AgentType>>(`${this.basePath}/${id}`, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${this.basePath}/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const agentTypesService = new AgentTypesService();
|
||||
@@ -19,3 +19,35 @@ export type {
|
||||
UsersListResponse,
|
||||
UserFilters,
|
||||
} from './users.service';
|
||||
|
||||
// Agent Types Service
|
||||
export { agentTypesService } from './agent-types.service';
|
||||
export type {
|
||||
AgentType,
|
||||
CreateAgentTypeDto,
|
||||
UpdateAgentTypeDto,
|
||||
} from './agent-types.service';
|
||||
|
||||
// Profile Sections Service
|
||||
export { profileSectionsService } from './profile-sections.service';
|
||||
export type {
|
||||
ProfileSection,
|
||||
AgentTypeSection,
|
||||
CreateSectionDto,
|
||||
UpdateSectionDto,
|
||||
AssignSectionDto,
|
||||
UpdateAssignmentDto,
|
||||
} from './profile-sections.service';
|
||||
|
||||
// Profile Fields Service
|
||||
export { profileFieldsService, FIELD_TYPES } from './profile-fields.service';
|
||||
export type {
|
||||
ProfileField,
|
||||
FieldType,
|
||||
FieldOption,
|
||||
RangeConfig,
|
||||
FieldValidation,
|
||||
FieldUiConfig,
|
||||
CreateFieldDto,
|
||||
UpdateFieldDto,
|
||||
} from './profile-fields.service';
|
||||
|
||||
166
src/services/profile-fields.service.ts
Normal file
166
src/services/profile-fields.service.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
import api, { ApiResponse } from './api';
|
||||
|
||||
// Field Types - matching backend enum
|
||||
export type FieldType =
|
||||
| 'TEXT'
|
||||
| 'TEXTAREA'
|
||||
| 'CHECKBOX'
|
||||
| 'CHECKBOX_GROUP'
|
||||
| 'RADIO'
|
||||
| 'SELECT'
|
||||
| 'MULTI_SELECT'
|
||||
| 'RANGE'
|
||||
| 'NUMBER'
|
||||
| 'DATE'
|
||||
| 'TAG_INPUT';
|
||||
|
||||
export const FIELD_TYPES: { value: FieldType; label: string; description: string }[] = [
|
||||
{ value: 'TEXT', label: 'Text', description: 'Single line text input' },
|
||||
{ value: 'TEXTAREA', label: 'Textarea', description: 'Multi-line text input' },
|
||||
{ value: 'NUMBER', label: 'Number', description: 'Numeric input' },
|
||||
{ value: 'DATE', label: 'Date', description: 'Date picker' },
|
||||
{ value: 'CHECKBOX', label: 'Checkbox', description: 'Single Yes/No checkbox' },
|
||||
{ value: 'CHECKBOX_GROUP', label: 'Checkbox Group', description: 'Multiple checkboxes in grid' },
|
||||
{ value: 'RADIO', label: 'Radio', description: 'Single choice radio buttons' },
|
||||
{ value: 'SELECT', label: 'Select', description: 'Dropdown (select one)' },
|
||||
{ value: 'MULTI_SELECT', label: 'Multi Select', description: 'Dropdown (select multiple)' },
|
||||
{ value: 'RANGE', label: 'Range', description: 'Range slider (min/max values)' },
|
||||
{ value: 'TAG_INPUT', label: 'Tag Input', description: 'Multiple free-form tags' },
|
||||
];
|
||||
|
||||
// Types
|
||||
export interface FieldOption {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface RangeConfig {
|
||||
min: number;
|
||||
max: number;
|
||||
step?: number;
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
export interface FieldValidation {
|
||||
min?: number;
|
||||
max?: number;
|
||||
minLength?: number;
|
||||
maxLength?: number;
|
||||
pattern?: string;
|
||||
}
|
||||
|
||||
export interface FieldUiConfig {
|
||||
columns?: number;
|
||||
showInPreview?: boolean;
|
||||
helpText?: string;
|
||||
}
|
||||
|
||||
export interface ProfileField {
|
||||
id: string;
|
||||
sectionId: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
fieldType: FieldType;
|
||||
description: string | null;
|
||||
placeholder: string | null;
|
||||
defaultValue: string | null;
|
||||
sortOrder: number;
|
||||
isActive: boolean;
|
||||
isRequired: boolean;
|
||||
validation: FieldValidation | null;
|
||||
options: FieldOption[] | null;
|
||||
rangeConfig: RangeConfig | null;
|
||||
uiConfig: FieldUiConfig | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
section?: {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateFieldDto {
|
||||
sectionId: string;
|
||||
name: string;
|
||||
fieldType: FieldType;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
defaultValue?: string;
|
||||
sortOrder?: number;
|
||||
isActive?: boolean;
|
||||
isRequired?: boolean;
|
||||
validation?: FieldValidation;
|
||||
options?: FieldOption[];
|
||||
rangeConfig?: RangeConfig;
|
||||
uiConfig?: FieldUiConfig;
|
||||
}
|
||||
|
||||
export interface UpdateFieldDto {
|
||||
name?: string;
|
||||
fieldType?: FieldType;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
defaultValue?: string;
|
||||
sortOrder?: number;
|
||||
isActive?: boolean;
|
||||
isRequired?: boolean;
|
||||
validation?: FieldValidation;
|
||||
options?: FieldOption[];
|
||||
rangeConfig?: RangeConfig;
|
||||
uiConfig?: FieldUiConfig;
|
||||
}
|
||||
|
||||
// Profile Fields Service
|
||||
class ProfileFieldsService {
|
||||
private basePath = '/profile-fields';
|
||||
|
||||
async getAll(sectionId?: string, includeInactive = false): Promise<ProfileField[]> {
|
||||
const params = new URLSearchParams();
|
||||
if (sectionId) params.append('sectionId', sectionId);
|
||||
if (includeInactive) params.append('includeInactive', 'true');
|
||||
|
||||
const url = params.toString()
|
||||
? `${this.basePath}?${params.toString()}`
|
||||
: this.basePath;
|
||||
const response = await api.get<ApiResponse<ProfileField[]>>(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<ProfileField> {
|
||||
const response = await api.get<ApiResponse<ProfileField>>(`${this.basePath}/${id}`);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async create(data: CreateFieldDto): Promise<ProfileField> {
|
||||
const response = await api.post<ApiResponse<ProfileField>>(this.basePath, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateFieldDto): Promise<ProfileField> {
|
||||
const response = await api.patch<ApiResponse<ProfileField>>(`${this.basePath}/${id}`, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${this.basePath}/${id}`);
|
||||
}
|
||||
|
||||
async reorderFields(sectionId: string, fieldIds: string[]): Promise<ProfileField[]> {
|
||||
const response = await api.patch<ApiResponse<ProfileField[]>>(
|
||||
`${this.basePath}/section/${sectionId}/reorder`,
|
||||
{ fieldIds }
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async bulkUpdateOrder(updates: { id: string; sortOrder: number }[]): Promise<{ success: boolean; updated: number }> {
|
||||
const response = await api.patch<ApiResponse<{ success: boolean; updated: number }>>(
|
||||
`${this.basePath}/bulk/order`,
|
||||
{ updates }
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const profileFieldsService = new ProfileFieldsService();
|
||||
125
src/services/profile-sections.service.ts
Normal file
125
src/services/profile-sections.service.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import api, { ApiResponse } from './api';
|
||||
import { ProfileField } from './profile-fields.service';
|
||||
|
||||
// Types
|
||||
export interface ProfileSection {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
description: string | null;
|
||||
icon: string | null;
|
||||
sortOrder: number;
|
||||
isActive: boolean;
|
||||
isGlobal: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
fields?: ProfileField[];
|
||||
agentTypeSections?: AgentTypeSection[];
|
||||
_count?: {
|
||||
fields: number;
|
||||
agentTypeSections: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AgentTypeSection {
|
||||
id: string;
|
||||
agentTypeId: string;
|
||||
sectionId: string;
|
||||
sortOrder: number;
|
||||
isRequired: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
agentType?: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
section?: ProfileSection;
|
||||
}
|
||||
|
||||
export interface CreateSectionDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
sortOrder?: number;
|
||||
isActive?: boolean;
|
||||
isGlobal?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateSectionDto {
|
||||
name?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
sortOrder?: number;
|
||||
isActive?: boolean;
|
||||
isGlobal?: boolean;
|
||||
}
|
||||
|
||||
export interface AssignSectionDto {
|
||||
agentTypeId: string;
|
||||
sortOrder?: number;
|
||||
isRequired?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateAssignmentDto {
|
||||
sortOrder?: number;
|
||||
isRequired?: boolean;
|
||||
}
|
||||
|
||||
// Profile Sections Service
|
||||
class ProfileSectionsService {
|
||||
private basePath = '/profile-sections';
|
||||
|
||||
async getAll(includeInactive = false): Promise<ProfileSection[]> {
|
||||
const url = includeInactive
|
||||
? `${this.basePath}?includeInactive=true`
|
||||
: this.basePath;
|
||||
const response = await api.get<ApiResponse<ProfileSection[]>>(url);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<ProfileSection> {
|
||||
const response = await api.get<ApiResponse<ProfileSection>>(`${this.basePath}/${id}`);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async create(data: CreateSectionDto): Promise<ProfileSection> {
|
||||
const response = await api.post<ApiResponse<ProfileSection>>(this.basePath, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateSectionDto): Promise<ProfileSection> {
|
||||
const response = await api.patch<ApiResponse<ProfileSection>>(`${this.basePath}/${id}`, data);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await api.delete(`${this.basePath}/${id}`);
|
||||
}
|
||||
|
||||
// Assignment methods
|
||||
async assignToAgentType(sectionId: string, data: AssignSectionDto): Promise<AgentTypeSection> {
|
||||
const response = await api.post<ApiResponse<AgentTypeSection>>(
|
||||
`${this.basePath}/${sectionId}/assign`,
|
||||
data
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async updateAssignment(
|
||||
sectionId: string,
|
||||
agentTypeId: string,
|
||||
data: UpdateAssignmentDto
|
||||
): Promise<AgentTypeSection> {
|
||||
const response = await api.patch<ApiResponse<AgentTypeSection>>(
|
||||
`${this.basePath}/${sectionId}/assignment/${agentTypeId}`,
|
||||
data
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
async removeFromAgentType(sectionId: string, agentTypeId: string): Promise<void> {
|
||||
await api.delete(`${this.basePath}/${sectionId}/assignment/${agentTypeId}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const profileSectionsService = new ProfileSectionsService();
|
||||
Reference in New Issue
Block a user