This commit is contained in:
pradeepkumar
2026-01-24 03:33:48 +05:30
parent 7b8b43f998
commit 909c22dc45
11 changed files with 2246 additions and 7 deletions

View 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();

View File

@@ -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';

View 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();

View 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();