This commit is contained in:
2026-04-07 06:32:40 +03:00
parent 24a44481a0
commit 11db1e6941
101 changed files with 54585 additions and 39160 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+16 -2
View File
@@ -16,14 +16,20 @@ import { InspectionsClient } from "./clients/inspections"
import { LabelsClient } from "./clients/labels"
import { InsuranceTypesClient } from "./clients/insurance-types"
import { EstimatesClient } from "./clients/estimates"
import { QuickRemarksClient } from "./clients/quick-remarks"
import { QuickNotesClient } from "./clients/quick-notes"
import { ShopRecommendationsClient } from "./clients/shop-recommendations"
import { JobCardsClient } from "./clients/job-cards"
import { PaymentsClient } from "./clients/payments"
import { PaymentModesClient } from "./clients/payment-modes"
import { PaymentReceivedClient } from "./clients/payment-received"
import { PartsClient } from "./clients/parts"
import { PurchaseOrdersClient } from "./clients/purchase-orders"
import { ServicesClient } from "./clients/services"
import { ServiceGroupsClient } from "./clients/service-groups"
import { ExpensesClient } from "./clients/expenses"
import { TasksClient } from "./clients/tasks"
import { TaskTypesClient } from "./clients/task-types"
import { TaskSectionsClient } from "./clients/task-sections"
import { AppointmentsClient } from "./clients/appointments"
import { ShopTimingsClient } from "./clients/shop-timings"
import { ShopCalendarsClient } from "./clients/shop-calendars"
@@ -47,6 +53,7 @@ import { ServiceGroupServicesClient } from "./clients/service-group-services"
import { ServiceGroupPartsClient } from "./clients/service-group-parts"
import { SettingsClient } from "./clients/settings"
import { ConfigurationsClient } from "./clients/configurations"
import { AutoGenerateClient } from "./clients/auto-generate"
export function createApi(options?: ApiClientOptions) {
return {
@@ -67,14 +74,20 @@ export function createApi(options?: ApiClientOptions) {
labels: new LabelsClient(undefined, options),
insuranceTypes: new InsuranceTypesClient(undefined, options),
estimates: new EstimatesClient(undefined, options),
quickRemarks: new QuickRemarksClient(undefined, options),
quickNotes: new QuickNotesClient(undefined, options),
shopRecommendations: new ShopRecommendationsClient(undefined, options),
jobCards: new JobCardsClient(undefined, options),
payments: new PaymentsClient(undefined, options),
paymentModes: new PaymentModesClient(undefined, options),
paymentReceived: new PaymentReceivedClient(undefined, options),
parts: new PartsClient(undefined, options),
purchaseOrders: new PurchaseOrdersClient(undefined, options),
services: new ServicesClient(undefined, options),
serviceGroups: new ServiceGroupsClient(undefined, options),
expenses: new ExpensesClient(undefined, options),
tasks: new TasksClient(undefined, options),
taskTypes: new TaskTypesClient(undefined, options),
taskSections: new TaskSectionsClient(undefined, options),
appointments: new AppointmentsClient(undefined, options),
shopTimings: new ShopTimingsClient(undefined, options),
shopCalendars: new ShopCalendarsClient(undefined, options),
@@ -98,6 +111,7 @@ export function createApi(options?: ApiClientOptions) {
serviceGroupParts: new ServiceGroupPartsClient(undefined, options),
settings: new SettingsClient(undefined, options),
configurations: new ConfigurationsClient(undefined, options),
autoGenerate: new AutoGenerateClient(undefined, options),
}
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const APPOINTMENT_ROUTES = {
INDEX: "/api/appointments",
@@ -9,25 +9,12 @@ export const APPOINTMENT_ROUTES = {
CHANGE_STATUS: "/api/appointments/{id}/change-status",
} as const satisfies Record<string, ApiPath>
export class AppointmentsClient extends ApiClient {
export class AppointmentsClient extends CrudClient<
typeof APPOINTMENT_ROUTES.INDEX,
typeof APPOINTMENT_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(APPOINTMENT_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof APPOINTMENT_ROUTES.INDEX, "post">) {
return this.post(APPOINTMENT_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof APPOINTMENT_ROUTES.BY_ID, "put">) {
return this.put(APPOINTMENT_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(APPOINTMENT_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, APPOINTMENT_ROUTES.INDEX, APPOINTMENT_ROUTES.BY_ID)
}
async unlinkJobCard(id: string, payload: ApiRequestBody<typeof APPOINTMENT_ROUTES.UNLINK_JOB_CARD, "post">) {
+14
View File
@@ -0,0 +1,14 @@
import type { ApiPath } from "../infra/types"
import { ApiClient } from "../infra/client"
export const AUTO_GENERATE_ROUTES = {
BY_TABLE: "/api/auto-generate/{table}",
} as const satisfies Record<string, ApiPath>
export class AutoGenerateClient extends ApiClient {
async generate(table: string) {
return this.get(AUTO_GENERATE_ROUTES.BY_TABLE, {
params: { table },
} as never)
}
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const DEPARTMENT_ROUTES = {
INDEX: "/api/departments",
@@ -9,25 +9,12 @@ export const DEPARTMENT_ROUTES = {
REMOVE_FAVORITE: "/api/remove-favorite-department",
} as const satisfies Record<string, ApiPath>
export class DepartmentsClient extends ApiClient {
export class DepartmentsClient extends CrudClient<
typeof DEPARTMENT_ROUTES.INDEX,
typeof DEPARTMENT_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(DEPARTMENT_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof DEPARTMENT_ROUTES.INDEX, "post">) {
return this.post(DEPARTMENT_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof DEPARTMENT_ROUTES.BY_ID, "put">) {
return this.put(DEPARTMENT_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(DEPARTMENT_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, DEPARTMENT_ROUTES.INDEX, DEPARTMENT_ROUTES.BY_ID)
}
async setFavorite(payload: ApiRequestBody<typeof DEPARTMENT_ROUTES.SET_FAVORITE, "post">) {
+8 -60
View File
@@ -1,24 +1,18 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const ESTIMATE_ROUTES = {
INDEX: "/api/estimates",
BY_ID: "/api/estimates/{id}",
QUICK_REMARKS: "/api/quick-remark",
QUICK_REMARK_BY_ID: "/api/quick-remark/{id}",
QUICK_NOTES: "/api/quick-notes",
QUICK_NOTE_BY_ID: "/api/quick-notes/{id}",
} as const satisfies Record<string, ApiPath>
export class EstimatesClient extends ApiClient {
export class EstimatesClient extends CrudClient<
typeof ESTIMATE_ROUTES.INDEX,
typeof ESTIMATE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Estimates ──
async list(query?: ApiListQueryParams) {
return this.get(ESTIMATE_ROUTES.INDEX, query ? { query } as never : undefined)
super(baseUrl, defaultOptions, ESTIMATE_ROUTES.INDEX, ESTIMATE_ROUTES.BY_ID)
}
// Note: GET /api/estimates/{id} is not in the OpenAPI schema.
@@ -27,50 +21,4 @@ export class EstimatesClient extends ApiClient {
const data = await this.get(ESTIMATE_ROUTES.INDEX, { query: { id } } as never)
return {...data, data: (data as any)?.data?.[0] ?? null }
}
async create(payload: ApiRequestBody<typeof ESTIMATE_ROUTES.INDEX, "post">) {
return this.post(ESTIMATE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof ESTIMATE_ROUTES.BY_ID, "put">) {
return this.put(ESTIMATE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(ESTIMATE_ROUTES.BY_ID, { params: { id } })
}
// ── Quick Remarks ──
async listQuickRemarks(query?: ApiListQueryParams) {
return this.get(ESTIMATE_ROUTES.QUICK_REMARKS, query ? { query } as never : undefined)
}
async createQuickRemark(payload: ApiRequestBody<typeof ESTIMATE_ROUTES.QUICK_REMARKS, "post">) {
return this.post(ESTIMATE_ROUTES.QUICK_REMARKS, payload)
}
async updateQuickRemark(id: string, payload: ApiRequestBody<typeof ESTIMATE_ROUTES.QUICK_REMARK_BY_ID, "put">) {
return this.put(ESTIMATE_ROUTES.QUICK_REMARK_BY_ID, payload, { params: { id } })
}
async destroyQuickRemark(id: string) {
return this.delete(ESTIMATE_ROUTES.QUICK_REMARK_BY_ID, { params: { id } })
}
// ── Quick Notes ──
async listQuickNotes(query?: ApiListQueryParams) {
return this.get(ESTIMATE_ROUTES.QUICK_NOTES, query ? { query } as never : undefined)
}
async createQuickNote(payload: ApiRequestBody<typeof ESTIMATE_ROUTES.QUICK_NOTES, "post">) {
return this.post(ESTIMATE_ROUTES.QUICK_NOTES, payload)
}
async updateQuickNote(id: string, payload: ApiRequestBody<typeof ESTIMATE_ROUTES.QUICK_NOTE_BY_ID, "put">) {
return this.put(ESTIMATE_ROUTES.QUICK_NOTE_BY_ID, payload, { params: { id } })
}
async destroyQuickNote(id: string) {
return this.delete(ESTIMATE_ROUTES.QUICK_NOTE_BY_ID, { params: { id } })
}
}
+11 -24
View File
@@ -1,4 +1,5 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
@@ -14,9 +15,12 @@ export const EXPENSE_ROUTES = {
EXPENSE_BY_ID: "/api/expenses/{id}",
} as const satisfies Record<string, ApiPath>
export class ExpensesClient extends ApiClient {
export class ExpensesClient extends CrudClient<
typeof EXPENSE_ROUTES.EXPENSES,
typeof EXPENSE_ROUTES.EXPENSE_BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
super(baseUrl, defaultOptions, EXPENSE_ROUTES.EXPENSES, EXPENSE_ROUTES.EXPENSE_BY_ID)
}
// ── Expense Items ──
@@ -59,35 +63,18 @@ export class ExpensesClient extends ApiClient {
// ── Expenses ──
async listExpenses(query?: ApiListQueryParams) {
return this.get(EXPENSE_ROUTES.EXPENSES, query ? { query } as never : undefined)
return this.list(query)
}
async createExpense(payload: ApiRequestBody<typeof EXPENSE_ROUTES.EXPENSES, "post">) {
return this.post(EXPENSE_ROUTES.EXPENSES, payload)
return this.create(payload)
}
async updateExpense(id: string, payload: ApiRequestBody<typeof EXPENSE_ROUTES.EXPENSE_BY_ID, "put">) {
return this.put(EXPENSE_ROUTES.EXPENSE_BY_ID, payload, { params: { id } })
return this.update(id, payload)
}
async destroyExpense(id: string) {
return this.delete(EXPENSE_ROUTES.EXPENSE_BY_ID, { params: { id } })
}
// ── Standard CRUD aliases (for ResourcePage compatibility) ──
async list(query?: ApiListQueryParams) {
return this.listExpenses(query)
}
async create(payload: ApiRequestBody<typeof EXPENSE_ROUTES.EXPENSES, "post">) {
return this.createExpense(payload)
}
async update(id: string, payload: ApiRequestBody<typeof EXPENSE_ROUTES.EXPENSE_BY_ID, "put">) {
return this.updateExpense(id, payload)
}
async destroy(id: string) {
return this.destroyExpense(id)
return this.destroy(id)
}
}
+8 -1
View File
@@ -15,14 +15,20 @@ export { InspectionsClient, INSPECTION_ROUTES } from "./inspections"
export { LabelsClient, LABEL_ROUTES } from "./labels"
export { InsuranceTypesClient, INSURANCE_TYPE_ROUTES } from "./insurance-types"
export { EstimatesClient, ESTIMATE_ROUTES } from "./estimates"
export { QuickRemarksClient, QUICK_REMARK_ROUTES } from "./quick-remarks"
export { QuickNotesClient, QUICK_NOTE_ROUTES } from "./quick-notes"
export { ShopRecommendationsClient, SHOP_RECOMMENDATION_ROUTES } from "./shop-recommendations"
export { JobCardsClient, JOB_CARD_ROUTES } from "./job-cards"
export { PaymentsClient, PAYMENT_ROUTES } from "./payments"
export { PaymentModesClient, PAYMENT_MODE_ROUTES } from "./payment-modes"
export { PaymentReceivedClient, PAYMENT_RECEIVED_ROUTES } from "./payment-received"
export { PartsClient, PARTS_ROUTES } from "./parts"
export { PurchaseOrdersClient, PURCHASE_ORDER_ROUTES } from "./purchase-orders"
export { ServicesClient, SERVICE_ROUTES } from "./services"
export { ServiceGroupsClient, SERVICE_GROUP_ROUTES } from "./service-groups"
export { ExpensesClient, EXPENSE_ROUTES } from "./expenses"
export { TasksClient, TASK_ROUTES } from "./tasks"
export { TaskTypesClient, TASK_TYPE_ROUTES } from "./task-types"
export { TaskSectionsClient, TASK_SECTION_ROUTES } from "./task-sections"
export { AppointmentsClient, APPOINTMENT_ROUTES } from "./appointments"
export { ShopTimingsClient, SHOP_TIMING_ROUTES } from "./shop-timings"
export { ShopCalendarsClient, SHOP_CALENDAR_ROUTES } from "./shop-calendars"
@@ -46,3 +52,4 @@ export { ServiceGroupServicesClient, SERVICE_GROUP_SERVICE_ROUTES } from "./serv
export { ServiceGroupPartsClient, SERVICE_GROUP_PART_ROUTES } from "./service-group-parts"
export { SettingsClient, SETTINGS_ROUTES } from "./settings"
export { ConfigurationsClient, CONFIGURATION_ROUTES } from "./configurations"
export { AutoGenerateClient, AUTO_GENERATE_ROUTES } from "./auto-generate"
+8 -21
View File
@@ -1,4 +1,5 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
@@ -19,9 +20,12 @@ export const INSPECTION_ROUTES = {
CHECKPOINT_MEDIA: "/api/inspection-check-points/{id}/media",
} as const satisfies Record<string, ApiPath>
export class InspectionsClient extends ApiClient {
export class InspectionsClient extends CrudClient<
typeof INSPECTION_ROUTES.INDEX,
typeof INSPECTION_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
super(baseUrl, defaultOptions, INSPECTION_ROUTES.INDEX, INSPECTION_ROUTES.BY_ID)
}
// ── Categories ──
@@ -41,28 +45,11 @@ export class InspectionsClient extends ApiClient {
return this.delete(INSPECTION_ROUTES.CATEGORY_BY_ID, { params: { id } })
}
// ── Inspections ──
async list(query?: ApiListQueryParams) {
return this.get(INSPECTION_ROUTES.INDEX, query ? { query } as never : undefined)
}
async getById(id: string) {
const res = await this.list({ query: { id } } as never)
const res = await super.list({ query: { id } } as never)
return {...res, data: res.data[0] }
}
async create(payload: ApiRequestBody<typeof INSPECTION_ROUTES.INDEX, "post">) {
return this.post(INSPECTION_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof INSPECTION_ROUTES.BY_ID, "put">) {
return this.put(INSPECTION_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(INSPECTION_ROUTES.BY_ID, { params: { id } })
}
async changeStatus(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHANGE_STATUS, "post">) {
return this.post(INSPECTION_ROUTES.CHANGE_STATUS, payload)
}
+8 -21
View File
@@ -1,30 +1,17 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const INSURANCE_TYPE_ROUTES = {
INDEX: "/api/insurance-types",
BY_ID: "/api/insurance-types/{id}",
} as const satisfies Record<string, ApiPath>
export class InsuranceTypesClient extends ApiClient {
export class InsuranceTypesClient extends CrudClient<
typeof INSURANCE_TYPE_ROUTES.INDEX,
typeof INSURANCE_TYPE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(INSURANCE_TYPE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof INSURANCE_TYPE_ROUTES.INDEX, "post">) {
return this.post(INSURANCE_TYPE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof INSURANCE_TYPE_ROUTES.BY_ID, "put">) {
return this.put(INSURANCE_TYPE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(INSURANCE_TYPE_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, INSURANCE_TYPE_ROUTES.INDEX, INSURANCE_TYPE_ROUTES.BY_ID)
}
}
+6 -24
View File
@@ -1,5 +1,5 @@
import { CrudClient } from "../infra/crud-client"
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
@@ -16,30 +16,12 @@ export const INVOICE_ROUTES = {
LABEL_BY_ID: "/api/invoice-labels/{id}",
} as const satisfies Record<string, ApiPath>
export class InvoicesClient extends ApiClient {
export class InvoicesClient extends CrudClient<
typeof INVOICE_ROUTES.INDEX,
typeof INVOICE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Invoices ──
async list(query?: ApiListQueryParams) {
return this.get(INVOICE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async show(id: string) {
return this.get(INVOICE_ROUTES.BY_ID, { params: { id } } as never)
}
async create(payload: ApiRequestBody<typeof INVOICE_ROUTES.INDEX, "post">) {
return this.post(INVOICE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof INVOICE_ROUTES.BY_ID, "put">) {
return this.put(INVOICE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(INVOICE_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, INVOICE_ROUTES.INDEX, INVOICE_ROUTES.BY_ID)
}
// ── Attachments ──
+46 -30
View File
@@ -1,6 +1,7 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiOperationResponse, ApiPath, ApiRequestBody, ApiResponse } from "../infra/types"
import { ApiBaseResponse } from "src/contracts/types"
export const JOB_CARD_ROUTES = {
INDEX: "/api/job-cards",
@@ -17,32 +18,31 @@ export const JOB_CARD_ROUTES = {
DELETE_ATTACHMENT: "/api/job-cards/{id}/delete-attachment",
CHANGE_SERVICE_WRITER: "/api/job-cards/{id}/change-service-writer-id",
CHANGE_SALES_PERSON: "/api/job-cards/{id}/change-sales-person-id",
GET_PARTS: "/api/job-cards/{id}/get-parts",
ADD_PART: "/api/job-cards/{id}/add-part",
UPDATE_PART: "/api/job-cards/{id}/update-part",
DELETE_PART: "/api/job-cards/{id}/delete-part",
} as const satisfies Record<string, ApiPath>
export class JobCardsClient extends ApiClient {
export type JobCardShowData = ApiResponse<typeof JOB_CARD_ROUTES.BY_ID, "get">['data'] & {
purchase_orders_count: number
bills_count: number
expenses_count: number
tasks_count: number
appointments_count: number
parts_count: number
}
export class JobCardsClient extends CrudClient<
typeof JOB_CARD_ROUTES.INDEX,
typeof JOB_CARD_ROUTES.BY_ID,
{
showResponse: ApiBaseResponse<JobCardShowData>
}
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(JOB_CARD_ROUTES.INDEX, query ? { query } as never : undefined)
}
async show(id: string) {
const res = await this.get(JOB_CARD_ROUTES.INDEX, { params: { id }, query: { id } } as never)
return { ...res, data: res.data?.[0] ?? null, }
}
async create(payload: ApiRequestBody<typeof JOB_CARD_ROUTES.INDEX, "post">) {
return this.post(JOB_CARD_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.BY_ID, "put">) {
return this.put(JOB_CARD_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(JOB_CARD_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, JOB_CARD_ROUTES.INDEX, JOB_CARD_ROUTES.BY_ID)
}
async changeDate(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.CHANGE_DATE, "post">) {
@@ -61,8 +61,8 @@ export class JobCardsClient extends ApiClient {
return this.post(JOB_CARD_ROUTES.EDIT_CUSTOMER_REMARK, payload, { params: { id } })
}
async deleteCustomerRemark(id: string) {
return this.delete(JOB_CARD_ROUTES.DELETE_CUSTOMER_REMARK, { params: { id } })
async deleteCustomerRemark(id: string, customerRemarkId: number) {
return this.delete(JOB_CARD_ROUTES.DELETE_CUSTOMER_REMARK, { params: { id }, body: { customer_remark_id: customerRemarkId } } as never)
}
async addShopRecommendation(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.ADD_SHOP_RECOMMENDATION, "post">) {
@@ -73,8 +73,8 @@ export class JobCardsClient extends ApiClient {
return this.post(JOB_CARD_ROUTES.EDIT_SHOP_RECOMMENDATION, payload, { params: { id } })
}
async deleteShopRecommendation(id: string) {
return this.delete(JOB_CARD_ROUTES.DELETE_SHOP_RECOMMENDATION, { params: { id } })
async deleteShopRecommendation(id: string, shopRecommendationId: number) {
return this.delete(JOB_CARD_ROUTES.DELETE_SHOP_RECOMMENDATION, { params: { id }, body: { shop_recommendation_id: shopRecommendationId } } as never)
}
async addAttachment(id: string, files: File[]) {
@@ -96,4 +96,20 @@ export class JobCardsClient extends ApiClient {
async changeSalesPerson(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.CHANGE_SALES_PERSON, "post">) {
return this.post(JOB_CARD_ROUTES.CHANGE_SALES_PERSON, payload, { params: { id } })
}
async getParts(id: string, params?: Record<string, unknown>) {
return this.get(JOB_CARD_ROUTES.GET_PARTS, { params: { id }, query: params as any })
}
async addPart(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.ADD_PART, "post">) {
return this.post(JOB_CARD_ROUTES.ADD_PART, payload, { params: { id } })
}
async updatePart(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.UPDATE_PART, "put">) {
return this.put(JOB_CARD_ROUTES.UPDATE_PART, payload, { params: { id } })
}
async deletePart(id: string, jobCardPartId: number) {
return this.delete(JOB_CARD_ROUTES.DELETE_PART, { params: { id }, body: { job_card_part_id: jobCardPartId } } as never)
}
}
+8 -21
View File
@@ -1,30 +1,17 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const LABEL_ROUTES = {
INDEX: "/api/labels",
BY_ID: "/api/labels/{id}",
} as const satisfies Record<string, ApiPath>
export class LabelsClient extends ApiClient {
export class LabelsClient extends CrudClient<
typeof LABEL_ROUTES.INDEX,
typeof LABEL_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(LABEL_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof LABEL_ROUTES.INDEX, "post">) {
return this.post(LABEL_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof LABEL_ROUTES.BY_ID, "put">) {
return this.put(LABEL_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(LABEL_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, LABEL_ROUTES.INDEX, LABEL_ROUTES.BY_ID)
}
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const PARTS_ROUTES = {
INDEX: "/api/parts",
@@ -10,25 +10,12 @@ export const PARTS_ROUTES = {
TOGGLE_STATUS: "/api/toggle-part-status",
} as const satisfies Record<string, ApiPath>
export class PartsClient extends ApiClient {
export class PartsClient extends CrudClient<
typeof PARTS_ROUTES.INDEX,
typeof PARTS_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(PARTS_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof PARTS_ROUTES.INDEX, "post">) {
return this.post(PARTS_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof PARTS_ROUTES.BY_ID, "put">) {
return this.put(PARTS_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(PARTS_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, PARTS_ROUTES.INDEX, PARTS_ROUTES.BY_ID)
}
async import(payload: ApiRequestBody<typeof PARTS_ROUTES.IMPORT, "post">) {
+17
View File
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const PAYMENT_MODE_ROUTES = {
INDEX: "/api/payment-mode",
BY_ID: "/api/payment-mode/{id}",
} as const satisfies Record<string, ApiPath>
export class PaymentModesClient extends CrudClient<
typeof PAYMENT_MODE_ROUTES.INDEX,
typeof PAYMENT_MODE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, PAYMENT_MODE_ROUTES.INDEX, PAYMENT_MODE_ROUTES.BY_ID)
}
}
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const PAYMENT_RECEIVED_ROUTES = {
INDEX: "/api/payment-recieved",
BY_ID: "/api/payment-recieved/{id}",
} as const satisfies Record<string, ApiPath>
export class PaymentReceivedClient extends CrudClient<
typeof PAYMENT_RECEIVED_ROUTES.INDEX,
typeof PAYMENT_RECEIVED_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, PAYMENT_RECEIVED_ROUTES.INDEX, PAYMENT_RECEIVED_ROUTES.BY_ID)
}
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const PAYMENT_TERM_ROUTES = {
INDEX: "/api/payment-terms",
@@ -8,25 +8,12 @@ export const PAYMENT_TERM_ROUTES = {
SET_DEFAULT: "/api/set-default-payment-term",
} as const satisfies Record<string, ApiPath>
export class PaymentTermsClient extends ApiClient {
export class PaymentTermsClient extends CrudClient<
typeof PAYMENT_TERM_ROUTES.INDEX,
typeof PAYMENT_TERM_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(PAYMENT_TERM_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof PAYMENT_TERM_ROUTES.INDEX, "post">) {
return this.post(PAYMENT_TERM_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof PAYMENT_TERM_ROUTES.BY_ID, "put">) {
return this.put(PAYMENT_TERM_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(PAYMENT_TERM_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, PAYMENT_TERM_ROUTES.INDEX, PAYMENT_TERM_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof PAYMENT_TERM_ROUTES.SET_DEFAULT, "post">) {
+3 -50
View File
@@ -1,50 +1,3 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const PAYMENT_ROUTES = {
MODES: "/api/payment-mode",
MODE_BY_ID: "/api/payment-mode/{id}",
RECEIVED: "/api/payment-recieved",
RECEIVED_BY_ID: "/api/payment-recieved/{id}",
} as const satisfies Record<string, ApiPath>
export class PaymentsClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Payment Modes ──
async listModes(query?: ApiListQueryParams) {
return this.get(PAYMENT_ROUTES.MODES, query ? { query } as never : undefined)
}
async createMode(payload: ApiRequestBody<typeof PAYMENT_ROUTES.MODES, "post">) {
return this.post(PAYMENT_ROUTES.MODES, payload)
}
async updateMode(id: string, payload: ApiRequestBody<typeof PAYMENT_ROUTES.MODE_BY_ID, "put">) {
return this.put(PAYMENT_ROUTES.MODE_BY_ID, payload, { params: { id } })
}
async destroyMode(id: string) {
return this.delete(PAYMENT_ROUTES.MODE_BY_ID, { params: { id } })
}
// ── Payment Received ──
async listReceived(query?: ApiListQueryParams) {
return this.get(PAYMENT_ROUTES.RECEIVED, query ? { query } as never : undefined)
}
async createReceived(payload: ApiRequestBody<typeof PAYMENT_ROUTES.RECEIVED, "post">) {
return this.post(PAYMENT_ROUTES.RECEIVED, payload)
}
async updateReceived(id: string, payload: ApiRequestBody<typeof PAYMENT_ROUTES.RECEIVED_BY_ID, "post">) {
return this.post(PAYMENT_ROUTES.RECEIVED_BY_ID, payload, { params: { id } })
}
async destroyReceived(id: string) {
return this.delete(PAYMENT_ROUTES.RECEIVED_BY_ID, { params: { id } })
}
}
// Re-exports for backward compatibility
export { PaymentModesClient, PAYMENT_MODE_ROUTES } from "./payment-modes"
export { PaymentReceivedClient, PAYMENT_RECEIVED_ROUTES } from "./payment-received"
+17
View File
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const QUICK_NOTE_ROUTES = {
INDEX: "/api/quick-notes",
BY_ID: "/api/quick-notes/{id}",
} as const satisfies Record<string, ApiPath>
export class QuickNotesClient extends CrudClient<
typeof QUICK_NOTE_ROUTES.INDEX,
typeof QUICK_NOTE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, QUICK_NOTE_ROUTES.INDEX, QUICK_NOTE_ROUTES.BY_ID)
}
}
+17
View File
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const QUICK_REMARK_ROUTES = {
INDEX: "/api/quick-remark",
BY_ID: "/api/quick-remark/{id}",
} as const satisfies Record<string, ApiPath>
export class QuickRemarksClient extends CrudClient<
typeof QUICK_REMARK_ROUTES.INDEX,
typeof QUICK_REMARK_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, QUICK_REMARK_ROUTES.INDEX, QUICK_REMARK_ROUTES.BY_ID)
}
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const REFERRAL_SOURCE_ROUTES = {
INDEX: "/api/referral-sources",
@@ -8,25 +8,12 @@ export const REFERRAL_SOURCE_ROUTES = {
SET_DEFAULT: "/api/set-default-referral-source",
} as const satisfies Record<string, ApiPath>
export class ReferralSourcesClient extends ApiClient {
export class ReferralSourcesClient extends CrudClient<
typeof REFERRAL_SOURCE_ROUTES.INDEX,
typeof REFERRAL_SOURCE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(REFERRAL_SOURCE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof REFERRAL_SOURCE_ROUTES.INDEX, "post">) {
return this.post(REFERRAL_SOURCE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof REFERRAL_SOURCE_ROUTES.BY_ID, "put">) {
return this.put(REFERRAL_SOURCE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(REFERRAL_SOURCE_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, REFERRAL_SOURCE_ROUTES.INDEX, REFERRAL_SOURCE_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof REFERRAL_SOURCE_ROUTES.SET_DEFAULT, "post">) {
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const SERVICE_ROUTES = {
INDEX: "/api/services",
@@ -9,25 +9,12 @@ export const SERVICE_ROUTES = {
EXPORT: "/api/export-services",
} as const satisfies Record<string, ApiPath>
export class ServicesClient extends ApiClient {
export class ServicesClient extends CrudClient<
typeof SERVICE_ROUTES.INDEX,
typeof SERVICE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(SERVICE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof SERVICE_ROUTES.INDEX, "post">) {
return this.post(SERVICE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof SERVICE_ROUTES.BY_ID, "put">) {
return this.put(SERVICE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(SERVICE_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, SERVICE_ROUTES.INDEX, SERVICE_ROUTES.BY_ID)
}
async import(payload: ApiRequestBody<typeof SERVICE_ROUTES.IMPORT, "post">) {
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const SHOP_RECOMMENDATION_ROUTES = {
INDEX: "/api/shop-recommendations",
BY_ID: "/api/shop-recommendations/{id}",
} as const satisfies Record<string, ApiPath>
export class ShopRecommendationsClient extends CrudClient<
typeof SHOP_RECOMMENDATION_ROUTES.INDEX,
typeof SHOP_RECOMMENDATION_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, SHOP_RECOMMENDATION_ROUTES.INDEX, SHOP_RECOMMENDATION_ROUTES.BY_ID)
}
}
+7 -11
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const SHOP_TYPE_ROUTES = {
INDEX: "/api/shop-types",
@@ -31,13 +31,12 @@ function buildShopTypeFormData(payload: ShopTypeCreatePayload | ShopTypeUpdatePa
return fd
}
export class ShopTypesClient extends ApiClient {
export class ShopTypesClient extends CrudClient<
typeof SHOP_TYPE_ROUTES.INDEX,
typeof SHOP_TYPE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(SHOP_TYPE_ROUTES.INDEX, query ? { query } as never : undefined)
super(baseUrl, defaultOptions, SHOP_TYPE_ROUTES.INDEX, SHOP_TYPE_ROUTES.BY_ID)
}
async create(payload: ShopTypeCreatePayload) {
@@ -52,9 +51,6 @@ export class ShopTypesClient extends ApiClient {
return this.postFormData(url, fd)
}
async destroy(id: string) {
return this.delete(SHOP_TYPE_ROUTES.BY_ID, { params: { id } })
}
}
+32
View File
@@ -0,0 +1,32 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
export const TASK_SECTION_ROUTES = {
INDEX: "/api/task-sections",
BY_ID: "/api/task-sections/{id}",
SET_DEFAULT: "/api/set-default-task-section",
REMOVE_DEFAULT: "/api/remove-default-task-section",
CHANGE_ARRANGEMENT: "/api/change-task-section-arrangement",
} as const satisfies Record<string, ApiPath>
export class TaskSectionsClient extends CrudClient<
typeof TASK_SECTION_ROUTES.INDEX,
typeof TASK_SECTION_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, TASK_SECTION_ROUTES.INDEX, TASK_SECTION_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof TASK_SECTION_ROUTES.SET_DEFAULT, "post">) {
return this.post(TASK_SECTION_ROUTES.SET_DEFAULT, payload)
}
async removeDefault(payload: ApiRequestBody<typeof TASK_SECTION_ROUTES.REMOVE_DEFAULT, "post">) {
return this.post(TASK_SECTION_ROUTES.REMOVE_DEFAULT, payload)
}
async changeSectionArrangement(payload: ApiRequestBody<typeof TASK_SECTION_ROUTES.CHANGE_ARRANGEMENT, "post">) {
return this.post(TASK_SECTION_ROUTES.CHANGE_ARRANGEMENT, payload)
}
}
+27
View File
@@ -0,0 +1,27 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
export const TASK_TYPE_ROUTES = {
INDEX: "/api/task-types",
BY_ID: "/api/task-types/{id}",
SET_DEFAULT: "/api/set-default-task-type",
REMOVE_DEFAULT: "/api/remove-default-task-type",
} as const satisfies Record<string, ApiPath>
export class TaskTypesClient extends CrudClient<
typeof TASK_TYPE_ROUTES.INDEX,
typeof TASK_TYPE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, TASK_TYPE_ROUTES.INDEX, TASK_TYPE_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof TASK_TYPE_ROUTES.SET_DEFAULT, "post">) {
return this.post(TASK_TYPE_ROUTES.SET_DEFAULT, payload)
}
async removeDefault(payload: ApiRequestBody<typeof TASK_TYPE_ROUTES.REMOVE_DEFAULT, "post">) {
return this.post(TASK_TYPE_ROUTES.REMOVE_DEFAULT, payload)
}
}
+9 -86
View File
@@ -1,96 +1,19 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const TASK_ROUTES = {
TYPES: "/api/task-types",
TYPE_BY_ID: "/api/task-types/{id}",
SET_DEFAULT_TYPE: "/api/set-default-task-type",
REMOVE_DEFAULT_TYPE: "/api/remove-default-task-type",
SECTIONS: "/api/task-sections",
SECTION_BY_ID: "/api/task-sections/{id}",
SET_DEFAULT_SECTION: "/api/set-default-task-section",
REMOVE_DEFAULT_SECTION: "/api/remove-default-task-section",
CHANGE_SECTION_ARRANGEMENT: "/api/change-task-section-arrangement",
TASKS: "/api/tasks",
TASK_BY_ID: "/api/tasks/{id}",
INDEX: "/api/tasks",
BY_ID: "/api/tasks/{id}",
COMPLETE: "/api/tasks/{id}/complete",
} as const satisfies Record<string, ApiPath>
export class TasksClient extends ApiClient {
export class TasksClient extends CrudClient<
typeof TASK_ROUTES.INDEX,
typeof TASK_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Task Types ──
async listTypes(query?: ApiListQueryParams) {
return this.get(TASK_ROUTES.TYPES, query ? { query } as never : undefined)
}
async createType(payload: ApiRequestBody<typeof TASK_ROUTES.TYPES, "post">) {
return this.post(TASK_ROUTES.TYPES, payload)
}
async updateType(id: string, payload: ApiRequestBody<typeof TASK_ROUTES.TYPE_BY_ID, "put">) {
return this.put(TASK_ROUTES.TYPE_BY_ID, payload, { params: { id } })
}
async destroyType(id: string) {
return this.delete(TASK_ROUTES.TYPE_BY_ID, { params: { id } })
}
async setDefaultType(payload: ApiRequestBody<typeof TASK_ROUTES.SET_DEFAULT_TYPE, "post">) {
return this.post(TASK_ROUTES.SET_DEFAULT_TYPE, payload)
}
async removeDefaultType(payload: ApiRequestBody<typeof TASK_ROUTES.REMOVE_DEFAULT_TYPE, "post">) {
return this.post(TASK_ROUTES.REMOVE_DEFAULT_TYPE, payload)
}
// ── Task Sections ──
async listSections(query?: ApiListQueryParams) {
return this.get(TASK_ROUTES.SECTIONS, query ? { query } as never : undefined)
}
async createSection(payload: ApiRequestBody<typeof TASK_ROUTES.SECTIONS, "post">) {
return this.post(TASK_ROUTES.SECTIONS, payload)
}
async updateSection(id: string, payload: ApiRequestBody<typeof TASK_ROUTES.SECTION_BY_ID, "put">) {
return this.put(TASK_ROUTES.SECTION_BY_ID, payload, { params: { id } })
}
async destroySection(id: string) {
return this.delete(TASK_ROUTES.SECTION_BY_ID, { params: { id } })
}
async setDefaultSection(payload: ApiRequestBody<typeof TASK_ROUTES.SET_DEFAULT_SECTION, "post">) {
return this.post(TASK_ROUTES.SET_DEFAULT_SECTION, payload)
}
async removeDefaultSection(payload: ApiRequestBody<typeof TASK_ROUTES.REMOVE_DEFAULT_SECTION, "post">) {
return this.post(TASK_ROUTES.REMOVE_DEFAULT_SECTION, payload)
}
async changeSectionArrangement(payload: ApiRequestBody<typeof TASK_ROUTES.CHANGE_SECTION_ARRANGEMENT, "post">) {
return this.post(TASK_ROUTES.CHANGE_SECTION_ARRANGEMENT, payload)
}
// ── Tasks ──
async list(query?: ApiListQueryParams) {
return this.get(TASK_ROUTES.TASKS, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof TASK_ROUTES.TASKS, "post">) {
return this.post(TASK_ROUTES.TASKS, payload)
}
async update(id: string, payload: ApiRequestBody<typeof TASK_ROUTES.TASK_BY_ID, "put">) {
return this.put(TASK_ROUTES.TASK_BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(TASK_ROUTES.TASK_BY_ID, { params: { id } })
super(baseUrl, defaultOptions, TASK_ROUTES.INDEX, TASK_ROUTES.BY_ID)
}
async complete(id: string, payload: ApiRequestBody<typeof TASK_ROUTES.COMPLETE, "post">) {
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const TAX_ROUTES = {
INDEX: "/api/taxes",
@@ -9,25 +9,12 @@ export const TAX_ROUTES = {
REMOVE_DEFAULT: "/api/remove-default-tax",
} as const satisfies Record<string, ApiPath>
export class TaxesClient extends ApiClient {
export class TaxesClient extends CrudClient<
typeof TAX_ROUTES.INDEX,
typeof TAX_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(TAX_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof TAX_ROUTES.INDEX, "post">) {
return this.post(TAX_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof TAX_ROUTES.BY_ID, "put">) {
return this.put(TAX_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(TAX_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, TAX_ROUTES.INDEX, TAX_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof TAX_ROUTES.SET_DEFAULT, "post">) {
+7 -11
View File
@@ -1,4 +1,5 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
@@ -25,13 +26,12 @@ function buildVehicleFormData(payload: Record<string, any>): FormData {
return fd
}
export class VehiclesClient extends ApiClient {
export class VehiclesClient extends CrudClient<
typeof VEHICLE_ROUTES.INDEX,
typeof VEHICLE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(VEHICLE_ROUTES.INDEX, query ? { query } as never : undefined)
super(baseUrl, defaultOptions, VEHICLE_ROUTES.INDEX, VEHICLE_ROUTES.BY_ID)
}
@@ -53,10 +53,6 @@ export class VehiclesClient extends ApiClient {
return this.postFormData(url, fd)
}
async destroy(id: string) {
return this.delete(VEHICLE_ROUTES.BY_ID, { params: { id } })
}
async export() {
return this.get(VEHICLE_ROUTES.EXPORT)
}
+7 -20
View File
@@ -1,6 +1,6 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const VENDOR_ROUTES = {
INDEX: "/api/vendors",
@@ -10,25 +10,12 @@ export const VENDOR_ROUTES = {
ADDRESS_BY_ID: "/api/vendor-address/{id}",
} as const satisfies Record<string, ApiPath>
export class VendorsClient extends ApiClient {
export class VendorsClient extends CrudClient<
typeof VENDOR_ROUTES.INDEX,
typeof VENDOR_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(VENDOR_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof VENDOR_ROUTES.INDEX, "post">) {
return this.post(VENDOR_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof VENDOR_ROUTES.BY_ID, "put">) {
return this.put(VENDOR_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(VENDOR_ROUTES.BY_ID, { params: { id } })
super(baseUrl, defaultOptions, VENDOR_ROUTES.INDEX, VENDOR_ROUTES.BY_ID)
}
async toggleStatus(payload: ApiRequestBody<typeof VENDOR_ROUTES.TOGGLE_STATUS, "post">) {
+3
View File
@@ -59,6 +59,9 @@ export type ExpenseStatus = (typeof ExpenseStatus)[number];
export const TaskStatus = ['pending', 'completed'] as const;
export type TaskStatus = (typeof TaskStatus)[number];
export const TaskPriority = ['low', 'medium', 'high'] as const;
export type TaskPriority = (typeof TaskPriority)[number];
// 📅 Appointments
export const AppointmentStatus = ['requested', 'confirmed', 'no_show', 'cancelled', 'completed'] as const;
export type AppointmentStatus = (typeof AppointmentStatus)[number];
-2
View File
@@ -10,5 +10,3 @@ export * from "./clients/index"
// ── Factory ──
export { createApi, api } from "./api"
export * from "./types"
+23 -10
View File
@@ -7,9 +7,22 @@ export const DEFAULT_PER_PAGE = 10
type CrudIndexRoute = ApiPathByMethod<"get"> & ApiPathByMethod<"post">
type CrudByIdRoute = ApiPathByMethod<"put"> & ApiPathByMethod<"delete">
export type CrudTypeOverrides = {
listResponse?: unknown
showResponse?: unknown
createPayload?: unknown
createResponse?: unknown
updatePayload?: unknown
updateResponse?: unknown
destroyResponse?: unknown
}
type Resolve<T, K extends string, Default> = T extends Record<K, infer V> ? V : Default
export abstract class CrudClient<
IndexRoute extends CrudIndexRoute,
ByIdRoute extends CrudByIdRoute,
Overrides extends CrudTypeOverrides = {},
> extends ApiClient {
@@ -22,24 +35,24 @@ export abstract class CrudClient<
}
async list(query?: ApiListQueryParams): Promise<ApiResponse<IndexRoute, "get">> {
return this.get(this.indexRoute as IndexRoute, query ? { query } as never : undefined)
async list(query?: ApiListQueryParams): Promise<Resolve<Overrides, 'listResponse', ApiResponse<IndexRoute, "get">>> {
return this.get(this.indexRoute as IndexRoute, query ? { query } as never : undefined) as never
}
async show(id: string) {
return this.get(this.byIdRoute as ByIdRoute & ApiPathByMethod<"get">, { params: { id } } as never)
async show(id: string): Promise<Resolve<Overrides, 'showResponse', ApiResponse<ByIdRoute & ApiPathByMethod<"get">, "get">>> {
return this.get(this.byIdRoute as ByIdRoute & ApiPathByMethod<"get">, { params: { id } } as never) as never
}
async create(payload: ApiRequestBody<IndexRoute, "post">) {
return this.post<IndexRoute>(this.indexRoute as IndexRoute, payload as never)
async create(payload: Resolve<Overrides, 'createPayload', ApiRequestBody<IndexRoute, "post">>): Promise<Resolve<Overrides, 'createResponse', ApiResponse<IndexRoute, "post">>> {
return this.post<IndexRoute>(this.indexRoute as IndexRoute, payload as never) as never
}
async update(id: string, payload: ApiRequestBody<ByIdRoute, "put">) {
return this.put<ByIdRoute>(this.byIdRoute as ByIdRoute, payload as never, { params: { id } } as never)
async update(id: string, payload: Resolve<Overrides, 'updatePayload', ApiRequestBody<ByIdRoute, "put">>): Promise<Resolve<Overrides, 'updateResponse', ApiResponse<ByIdRoute, "put">>> {
return this.put<ByIdRoute>(this.byIdRoute as ByIdRoute, payload as never, { params: { id } } as never) as never
}
async destroy(id: string) {
return this.delete<ByIdRoute>(this.byIdRoute as ByIdRoute, { params: { id } } as never)
async destroy(id: string): Promise<Resolve<Overrides, 'destroyResponse', ApiResponse<ByIdRoute, "delete">>> {
return this.delete<ByIdRoute>(this.byIdRoute as ByIdRoute, { params: { id } } as never) as never
}
}
+3
View File
@@ -110,3 +110,6 @@ export type ApiOperationResponse<OperationId extends ApiOperationId> =
>
>
>
-1
View File
@@ -1 +0,0 @@
export * from './job-cards'
-4
View File
@@ -1,4 +0,0 @@
import { JOB_CARD_ROUTES } from "../clients";
import { ApiResponse } from "../infra";
export type JobCardResponseData = NonNullable<ApiResponse<typeof JOB_CARD_ROUTES['INDEX'], 'get'>['data']>[number]
+3910 -667
View File
File diff suppressed because it is too large Load Diff