import { api as apiClient } from "@/auth/http"; import { URL_CONSTANTS } from "@/constants/URLS"; import type { Company, CompanyChangeRequest, CompanyListFilter, CompanyProfile, CompanyStats, CustomerBooking, CustomerDocument, CustomerPayment, PaginatedCompanies, ProfileStatus, ResetChannel, ResetPasswordResult, } from "@/types/customer"; const cleanParams = (params: object) => Object.fromEntries( Object.entries(params).filter( ([, value]) => value !== undefined && value !== "" && value !== null, ), ); /** Lift attributes JSONB into the flat contact/manager fields the UI reads. */ function mapCompany(dto: Record): Company { const attrs = (dto.attributes as Record | null) ?? {}; return { ...(dto as unknown as Company), companyProfiles: (dto.companyProfiles as Company["companyProfiles"]) ?? [], contactPersonName: (attrs.contactPersonName as string | null) ?? null, contactPersonPhone: (attrs.contactPersonPhone as string | null) ?? null, generalManagerName: (attrs.generalManagerName as string | null) ?? null, generalManagerEmail: (attrs.generalManagerEmail as string | null) ?? null, generalManagerPhone: (attrs.generalManagerPhone as string | null) ?? null, poaName: (attrs.poaName as string | null) ?? null, poaEmail: (attrs.poaEmail as string | null) ?? null, poaPhone: (attrs.poaPhone as string | null) ?? null, poaLocation: (attrs.poaLocation as string | null) ?? null, poaAddress: (attrs.poaAddress as string | null) ?? null, }; } export const customersService = { stats(): Promise { return apiClient .get(URL_CONSTANTS.COMPANIES.STATS) .then((r) => r.data); }, list(filter: CompanyListFilter): Promise { return apiClient .get<{ items: Record[]; total: number }>( URL_CONSTANTS.COMPANIES.BASE, { params: cleanParams(filter) }, ) .then((r) => ({ items: r.data.items.map(mapCompany), total: r.data.total, })); }, getById(id: string): Promise { return apiClient .get>(URL_CONSTANTS.COMPANIES.BY_ID(id)) .then((r) => mapCompany(r.data)); }, bookingsFor(companyId: string): Promise { return apiClient .get( URL_CONSTANTS.COMPANIES.BOOKINGS_CUSTOMER_VIEW(companyId), ) .then((r) => r.data); }, documentsFor(companyId: string): Promise { return apiClient .get(URL_CONSTANTS.COMPANIES.DOCUMENTS(companyId)) .then((r) => r.data); }, paymentsFor(companyId: string): Promise { return apiClient .get( URL_CONSTANTS.COMPANIES.PAYMENTS_CUSTOMER_VIEW(companyId), ) .then((r) => r.data); }, /** * Send a password-reset code to the company's primary contact. Staff never * receive a credential — the customer sets their own password from the code. */ resetPassword( companyId: string, channel: ResetChannel, ): Promise { return apiClient .post( URL_CONSTANTS.COMPANIES.RESET_PASSWORD(companyId), { channel }, ) .then((r) => r.data); }, setProfileStatus( profileId: string, status: ProfileStatus, note?: string, ): Promise { return apiClient .patch( URL_CONSTANTS.COMPANIES.PROFILE_STATUS(profileId), { status, note }, ) .then((r) => r.data); }, /** Approve / change a company's status (e.g. pending → active). */ setCompanyStatus(companyId: string, status: string): Promise { return apiClient .patch(URL_CONSTANTS.COMPANIES.BY_ID(companyId), { status }) .then((r) => r.data); }, /** List a company's profile-edit change requests (newest first). */ changeRequests(companyId: string): Promise { return apiClient .get( URL_CONSTANTS.COMPANIES.CHANGE_REQUESTS(companyId), ) .then((r) => r.data); }, /** Approve a pending change request — applies the proposed changes. */ approveChangeRequest(id: string): Promise { return apiClient .post( URL_CONSTANTS.COMPANIES.CHANGE_REQUEST_APPROVE(id), ) .then((r) => r.data); }, /** Reject a pending change request with a note. */ rejectChangeRequest(id: string, note: string): Promise { return apiClient .post( URL_CONSTANTS.COMPANIES.CHANGE_REQUEST_REJECT(id), { note }, ) .then((r) => r.data); }, };