// base-api.service.ts import type { TableState } from "~/components/core/data-table"; import { removeUndefinedValues } from "~/features/remove-falsy-values"; import { mapTableStateToPaginationQueryDSL } from "~/features/table"; import type { DeepPartial } from "react-hook-form"; import { handleError, handleSuccess } from "."; import axios from "../lib/axios"; export interface IAPIOption { toast_success: boolean; } export class BaseApiService { constructor(protected readonly resourceUrl: string) {} async index(values?: DeepPartial> | undefined) { const params = values ? mapTableStateToPaginationQueryDSL(values as TableState) : {}; const response = await axios({ url: this.resourceUrl, params: params, // withCredentials: true, method: "GET", }); return response.data; } async get(id: T["id"], options: IAPIOption = { toast_success: false }) { try { const response = await axios({ url: this.resourceUrl + "/" + id, // withCredentials: true, method: "GET", }); if (options.toast_success) { handleSuccess(response.data, this.resourceUrl); } return response.data; } catch (error) { handleError(error); } } async create( data: Partial>, options: IAPIOption = { toast_success: true } ) { try { const newData = removeUndefinedValues(data); const { data: result } = await axios({ url: this.resourceUrl, // withCredentials: true, method: "POST", data: newData, }); if (options.toast_success) { handleSuccess(result, this.resourceUrl); } return result; } catch (error) { handleError(error); } } async update( id: T["id"], data: Partial, options: IAPIOption = { toast_success: false } ) { try { const cleaned = removeUndefinedValues(data); const { data: result } = await axios({ url: `${this.resourceUrl}/${id}`, // withCredentials: true, method: "PUT", data: cleaned, }); if (options.toast_success) { handleSuccess(result, this.resourceUrl); } return result; } catch (error) { handleError(error); } } async delete(entity: T, options: IAPIOption = { toast_success: false }) { try { const { data } = await axios({ url: `${this.resourceUrl}/${entity.id}`, // withCredentials: true, method: "DELETE", }); if (options.toast_success) { handleSuccess(data, this.resourceUrl); } return data; } catch (error) { handleError(error); } } async bulkDelete( entities: T[], options: IAPIOption = { toast_success: false } ) { const ids = entities.map((e) => e.id); try { const { data } = await axios({ url: `${this.resourceUrl}/bulk-delete`, // withCredentials: true, method: "DELETE", data: { ids }, }); if (options.toast_success) { handleSuccess(data, this.resourceUrl); } return data; } catch (error) { handleError(error); } } async bulkUpdate( entities: T[], options: IAPIOption = { toast_success: false } ) { try { const { data } = await axios({ url: `${this.resourceUrl}/bulk-update`, // withCredentials: true, method: "PUT", data: entities, }); if (options.toast_success) { handleSuccess(data, this.resourceUrl); } return data; } catch (error) { handleError(error); } } // Optional: override this in subclass if needed async customAction( id: number, endpoint: string, payload?: Record, method?: string, options: IAPIOption = { toast_success: false } ) { try { const { data } = await axios({ url: `${this.resourceUrl}/${endpoint}/${id}`, method: method || "POST", data: removeUndefinedValues(payload || {}), // withCredentials: true, }); if (options.toast_success) { handleSuccess(data, this.resourceUrl); } return data; } catch (error) { handleError(error); } } }