This commit is contained in:
2026-03-27 16:20:46 +03:00
commit 13b56d4960
260 changed files with 111131 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
import { ApiClient, 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",
BY_ID: "/api/appointments/{id}",
UNLINK_JOB_CARD: "/api/appointments/{id}/un-link-job-card",
} as const satisfies Record<string, ApiPath>
export class AppointmentsClient extends ApiClient {
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 } })
}
async unlinkJobCard(id: string, payload: ApiRequestBody<typeof APPOINTMENT_ROUTES.UNLINK_JOB_CARD, "post">) {
return this.post(APPOINTMENT_ROUTES.UNLINK_JOB_CARD, payload, { params: { id } })
}
}
+26
View File
@@ -0,0 +1,26 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
export const AUTH_ROUTES = {
LOGIN: "/api/login",
PROFILE: "/api/profile",
LOGOUT: "/api/logout",
} as const satisfies Record<string, ApiPath>
export class AuthClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async login(payload: ApiRequestBody<typeof AUTH_ROUTES.LOGIN, "post">) {
return this.post(AUTH_ROUTES.LOGIN, payload)
}
async profile() {
return this.get(AUTH_ROUTES.PROFILE)
}
async logout() {
return this.post(AUTH_ROUTES.LOGOUT, undefined)
}
}
+32
View File
@@ -0,0 +1,32 @@
import { CrudClient } from "../infra/crud-client"
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const CUSTOMER_ROUTES = {
INDEX: "/api/customers",
BY_ID: "/api/customers/{id}",
EXPORT: "/api/customers/export",
IMPORT: "/api/customers/import",
CUSTOMER_TYPES: "/api/customer-types",
} as const satisfies Record<string, ApiPath>
export class CustomersClient extends CrudClient<typeof CUSTOMER_ROUTES.INDEX, typeof CUSTOMER_ROUTES.BY_ID> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, CUSTOMER_ROUTES.INDEX, CUSTOMER_ROUTES.BY_ID)
}
async listCustomerTypes(query?: ApiListQueryParams) {
return this.get(CUSTOMER_ROUTES.CUSTOMER_TYPES, query ? { query } as never : undefined)
}
async export() {
return this.get(CUSTOMER_ROUTES.EXPORT)
}
async import(payload: ApiRequestBody<typeof CUSTOMER_ROUTES.IMPORT, "post">) {
return this.post(CUSTOMER_ROUTES.IMPORT, payload)
}
}
+40
View File
@@ -0,0 +1,40 @@
import { ApiClient, 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",
BY_ID: "/api/departments/{id}",
SET_FAVORITE: "/api/set-favorite-department",
REMOVE_FAVORITE: "/api/remove-favorite-department",
} as const satisfies Record<string, ApiPath>
export class DepartmentsClient extends ApiClient {
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 } })
}
async setFavorite(payload: ApiRequestBody<typeof DEPARTMENT_ROUTES.SET_FAVORITE, "post">) {
return this.post(DEPARTMENT_ROUTES.SET_FAVORITE, payload)
}
async removeFavorite(payload: ApiRequestBody<typeof DEPARTMENT_ROUTES.REMOVE_FAVORITE, "post">) {
return this.post(DEPARTMENT_ROUTES.REMOVE_FAVORITE, payload)
}
}
+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 EMPLOYEE_ROUTES = {
INDEX: "/api/employees",
BY_ID: "/api/employees/{id}",
} as const satisfies Record<string, ApiPath>
export class EmployeesClient extends CrudClient<
typeof EMPLOYEE_ROUTES.INDEX,
typeof EMPLOYEE_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, EMPLOYEE_ROUTES.INDEX, EMPLOYEE_ROUTES.BY_ID)
}
}
+69
View File
@@ -0,0 +1,69 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/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 {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Estimates ──
async list(query?: ApiListQueryParams) {
return this.get(ESTIMATE_ROUTES.INDEX, query ? { query } as never : undefined)
}
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 } })
}
}
+74
View File
@@ -0,0 +1,74 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const EXPENSE_ROUTES = {
ITEMS: "/api/expense-items",
ITEM_BY_ID: "/api/expense-items/{id}",
TOGGLE_ITEM_STATUS: "/api/toggle-expense-item-status",
BILLS: "/api/bills",
BILL_BY_ID: "/api/bills/{id}",
EXPENSES: "/api/expenses",
EXPENSE_BY_ID: "/api/expenses/{id}",
} as const satisfies Record<string, ApiPath>
export class ExpensesClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Expense Items ──
async listItems(query?: ApiListQueryParams) {
return this.get(EXPENSE_ROUTES.ITEMS, query ? { query } as never : undefined)
}
async createItem(payload: ApiRequestBody<typeof EXPENSE_ROUTES.ITEMS, "post">) {
return this.post(EXPENSE_ROUTES.ITEMS, payload)
}
async updateItem(id: string, payload: ApiRequestBody<typeof EXPENSE_ROUTES.ITEM_BY_ID, "put">) {
return this.put(EXPENSE_ROUTES.ITEM_BY_ID, payload, { params: { id } })
}
async destroyItem(id: string) {
return this.delete(EXPENSE_ROUTES.ITEM_BY_ID, { params: { id } })
}
async toggleItemStatus(payload: ApiRequestBody<typeof EXPENSE_ROUTES.TOGGLE_ITEM_STATUS, "post">) {
return this.post(EXPENSE_ROUTES.TOGGLE_ITEM_STATUS, payload)
}
// ── Bills ──
async listBills(query?: ApiListQueryParams) {
return this.get(EXPENSE_ROUTES.BILLS, query ? { query } as never : undefined)
}
async createBill(payload: ApiRequestBody<typeof EXPENSE_ROUTES.BILLS, "post">) {
return this.post(EXPENSE_ROUTES.BILLS, payload)
}
async updateBill(id: string, payload: ApiRequestBody<typeof EXPENSE_ROUTES.BILL_BY_ID, "put">) {
return this.put(EXPENSE_ROUTES.BILL_BY_ID, payload, { params: { id } })
}
async destroyBill(id: string) {
return this.delete(EXPENSE_ROUTES.BILL_BY_ID, { params: { id } })
}
// ── Expenses ──
async listExpenses(query?: ApiListQueryParams) {
return this.get(EXPENSE_ROUTES.EXPENSES, query ? { query } as never : undefined)
}
async createExpense(payload: ApiRequestBody<typeof EXPENSE_ROUTES.EXPENSES, "post">) {
return this.post(EXPENSE_ROUTES.EXPENSES, 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 } })
}
async destroyExpense(id: string) {
return this.delete(EXPENSE_ROUTES.EXPENSE_BY_ID, { params: { id } })
}
}
+21
View File
@@ -0,0 +1,21 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const GEO_ROUTES = {
COUNTRIES: "/api/countries",
STATES: "/api/states",
} as const satisfies Record<string, ApiPath>
export class GeoClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async countries() {
return this.get(GEO_ROUTES.COUNTRIES)
}
async states() {
return this.get(GEO_ROUTES.STATES)
}
}
+28
View File
@@ -0,0 +1,28 @@
export { AuthClient, AUTH_ROUTES } from "./auth"
export { CustomersClient, CUSTOMER_ROUTES } from "./customers"
export { ReferralSourcesClient, REFERRAL_SOURCE_ROUTES } from "./referral-sources"
export { VehiclesClient, VEHICLE_ROUTES } from "./vehicles"
export { VehicleAttributesClient, VEHICLE_ATTRIBUTE_ROUTES } from "./vehicle-attributes"
export { VehicleDocumentsClient, VEHICLE_DOCUMENT_ROUTES } from "./vehicle-documents"
export { DepartmentsClient, DEPARTMENT_ROUTES } from "./departments"
export { EmployeesClient, EMPLOYEE_ROUTES } from "./employees"
export { GeoClient, GEO_ROUTES } from "./geo"
export { PaymentTermsClient, PAYMENT_TERM_ROUTES } from "./payment-terms"
export { ShopTypesClient, SHOP_TYPE_ROUTES, type ShopTypeCreatePayload, type ShopTypeUpdatePayload } from "./shop-types"
export { InventoryClient, INVENTORY_ROUTES } from "./inventory"
export { VendorsClient, VENDOR_ROUTES } from "./vendors"
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 { JobCardsClient, JOB_CARD_ROUTES } from "./job-cards"
export { PaymentsClient, PAYMENT_ROUTES } from "./payments"
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 { AppointmentsClient, APPOINTMENT_ROUTES } from "./appointments"
export { ShopTimingsClient, SHOP_TIMING_ROUTES } from "./shop-timings"
export { ShopCalendarsClient, SHOP_CALENDAR_ROUTES } from "./shop-calendars"
+118
View File
@@ -0,0 +1,118 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const INSPECTION_ROUTES = {
CATEGORIES: "/api/inspection-categories",
CATEGORY_BY_ID: "/api/inspection-categories/{id}",
INDEX: "/api/inspections",
BY_ID: "/api/inspections/{id}",
CHANGE_STATUS: "/api/change-inspection-status",
CHECKPOINT_LABELS: "/api/check-point-label",
CHECKPOINT_LABEL_BY_ID: "/api/check-point-label/{id}",
CHECKPOINTS: "/api/inspection-check-points",
CHECKPOINT_BY_ID: "/api/inspection-check-points/{id}",
TOGGLE_LABEL_TO_CHECKPOINT: "/api/toggle-label-to-checkpoint",
CHECKPOINT_CHANGE_STATUS: "/api/inspection-check-points/change-status",
CHECKPOINT_ADD_ATTACHMENT: "/api/inspection-check-points/add-attachment",
CHECKPOINT_UPLOAD_MEDIA: "/api/inspection-check-points/{id}/upload-media",
CHECKPOINT_MEDIA: "/api/inspection-check-points/{id}/media",
} as const satisfies Record<string, ApiPath>
export class InspectionsClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Categories ──
async listCategories(query?: ApiListQueryParams) {
return this.get(INSPECTION_ROUTES.CATEGORIES, query ? { query } as never : undefined)
}
async createCategory(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CATEGORIES, "post">) {
return this.post(INSPECTION_ROUTES.CATEGORIES, payload)
}
async updateCategory(id: string, payload: ApiRequestBody<typeof INSPECTION_ROUTES.CATEGORY_BY_ID, "put">) {
return this.put(INSPECTION_ROUTES.CATEGORY_BY_ID, payload, { params: { id } })
}
async destroyCategory(id: string) {
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 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)
}
// ── Checkpoint Labels ──
async listCheckpointLabels(query?: ApiListQueryParams) {
return this.get(INSPECTION_ROUTES.CHECKPOINT_LABELS, query ? { query } as never : undefined)
}
async createCheckpointLabel(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_LABELS, "post">) {
return this.post(INSPECTION_ROUTES.CHECKPOINT_LABELS, payload)
}
async updateCheckpointLabel(id: string, payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_LABEL_BY_ID, "put">) {
return this.put(INSPECTION_ROUTES.CHECKPOINT_LABEL_BY_ID, payload, { params: { id } })
}
async destroyCheckpointLabel(id: string) {
return this.delete(INSPECTION_ROUTES.CHECKPOINT_LABEL_BY_ID, { params: { id } })
}
// ── Checkpoints ──
async listCheckpoints(query?: ApiListQueryParams) {
return this.get(INSPECTION_ROUTES.CHECKPOINTS, query ? { query } as never : undefined)
}
async createCheckpoint(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINTS, "post">) {
return this.post(INSPECTION_ROUTES.CHECKPOINTS, payload)
}
async updateCheckpoint(id: string, payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_BY_ID, "put">) {
return this.put(INSPECTION_ROUTES.CHECKPOINT_BY_ID, payload, { params: { id } })
}
async destroyCheckpoint(id: string) {
return this.delete(INSPECTION_ROUTES.CHECKPOINT_BY_ID, { params: { id } })
}
async toggleLabelToCheckpoint(payload: ApiRequestBody<typeof INSPECTION_ROUTES.TOGGLE_LABEL_TO_CHECKPOINT, "post">) {
return this.post(INSPECTION_ROUTES.TOGGLE_LABEL_TO_CHECKPOINT, payload)
}
async changeCheckpointStatus(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_CHANGE_STATUS, "post">) {
return this.post(INSPECTION_ROUTES.CHECKPOINT_CHANGE_STATUS, payload)
}
async addCheckpointAttachment(payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_ADD_ATTACHMENT, "post">) {
return this.post(INSPECTION_ROUTES.CHECKPOINT_ADD_ATTACHMENT, payload)
}
async uploadCheckpointMedia(id: string, payload: ApiRequestBody<typeof INSPECTION_ROUTES.CHECKPOINT_UPLOAD_MEDIA, "post">) {
return this.post(INSPECTION_ROUTES.CHECKPOINT_UPLOAD_MEDIA, payload, { params: { id } })
}
async deleteCheckpointMedia(id: string) {
return this.delete(INSPECTION_ROUTES.CHECKPOINT_MEDIA, { params: { id } })
}
}
@@ -0,0 +1,30 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/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 {
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 } })
}
}
+99
View File
@@ -0,0 +1,99 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const INVENTORY_ROUTES = {
UNIT_TYPES: "/api/unit-types",
UNIT_TYPE_BY_ID: "/api/unit-types/{id}",
SET_FAVORITE_UNIT_TYPE: "/api/set-favorite-unit-type",
REMOVE_FAVORITE_UNIT_TYPE: "/api/remove-favorite-unit-type",
CATEGORIES: "/api/inventory-categories",
CATEGORY_BY_ID: "/api/inventory-categories/{id}",
SET_FAVORITE_CATEGORY: "/api/set-favorite-inventory-category",
REMOVE_FAVORITE_CATEGORY: "/api/remove-favorite-inventory-category",
LABOR_RATES: "/api/labor-rates",
LABOR_RATE_BY_ID: "/api/labor-rates/{id}",
SET_FAVORITE_LABOR_RATE: "/api/set-favorite-labor-rate",
REMOVE_FAVORITE_LABOR_RATE: "/api/remove-favorite-labor-rate",
} as const satisfies Record<string, ApiPath>
export class InventoryClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Unit Types ──
async listUnitTypes(query?: ApiListQueryParams) {
return this.get(INVENTORY_ROUTES.UNIT_TYPES, query ? { query } as never : undefined)
}
async createUnitType(payload: ApiRequestBody<typeof INVENTORY_ROUTES.UNIT_TYPES, "post">) {
return this.post(INVENTORY_ROUTES.UNIT_TYPES, payload)
}
async updateUnitType(id: string, payload: ApiRequestBody<typeof INVENTORY_ROUTES.UNIT_TYPE_BY_ID, "put">) {
return this.put(INVENTORY_ROUTES.UNIT_TYPE_BY_ID, payload, { params: { id } })
}
async destroyUnitType(id: string) {
return this.delete(INVENTORY_ROUTES.UNIT_TYPE_BY_ID, { params: { id } })
}
async setFavoriteUnitType(payload: ApiRequestBody<typeof INVENTORY_ROUTES.SET_FAVORITE_UNIT_TYPE, "post">) {
return this.post(INVENTORY_ROUTES.SET_FAVORITE_UNIT_TYPE, payload)
}
async removeFavoriteUnitType(payload: ApiRequestBody<typeof INVENTORY_ROUTES.REMOVE_FAVORITE_UNIT_TYPE, "post">) {
return this.post(INVENTORY_ROUTES.REMOVE_FAVORITE_UNIT_TYPE, payload)
}
// ── Inventory Categories ──
async listCategories(query?: ApiListQueryParams) {
return this.get(INVENTORY_ROUTES.CATEGORIES, query ? { query } as never : undefined)
}
async createCategory(payload: ApiRequestBody<typeof INVENTORY_ROUTES.CATEGORIES, "post">) {
return this.post(INVENTORY_ROUTES.CATEGORIES, payload)
}
async updateCategory(id: string, payload: ApiRequestBody<typeof INVENTORY_ROUTES.CATEGORY_BY_ID, "put">) {
return this.put(INVENTORY_ROUTES.CATEGORY_BY_ID, payload, { params: { id } })
}
async destroyCategory(id: string) {
return this.delete(INVENTORY_ROUTES.CATEGORY_BY_ID, { params: { id } })
}
async setFavoriteCategory(payload: ApiRequestBody<typeof INVENTORY_ROUTES.SET_FAVORITE_CATEGORY, "post">) {
return this.post(INVENTORY_ROUTES.SET_FAVORITE_CATEGORY, payload)
}
async removeFavoriteCategory(payload: ApiRequestBody<typeof INVENTORY_ROUTES.REMOVE_FAVORITE_CATEGORY, "post">) {
return this.post(INVENTORY_ROUTES.REMOVE_FAVORITE_CATEGORY, payload)
}
// ── Labor Rates ──
async listLaborRates(query?: ApiListQueryParams) {
return this.get(INVENTORY_ROUTES.LABOR_RATES, query ? { query } as never : undefined)
}
async createLaborRate(payload: ApiRequestBody<typeof INVENTORY_ROUTES.LABOR_RATES, "post">) {
return this.post(INVENTORY_ROUTES.LABOR_RATES, payload)
}
async updateLaborRate(id: string, payload: ApiRequestBody<typeof INVENTORY_ROUTES.LABOR_RATE_BY_ID, "put">) {
return this.put(INVENTORY_ROUTES.LABOR_RATE_BY_ID, payload, { params: { id } })
}
async destroyLaborRate(id: string) {
return this.delete(INVENTORY_ROUTES.LABOR_RATE_BY_ID, { params: { id } })
}
async setFavoriteLaborRate(payload: ApiRequestBody<typeof INVENTORY_ROUTES.SET_FAVORITE_LABOR_RATE, "post">) {
return this.post(INVENTORY_ROUTES.SET_FAVORITE_LABOR_RATE, payload)
}
async removeFavoriteLaborRate(payload: ApiRequestBody<typeof INVENTORY_ROUTES.REMOVE_FAVORITE_LABOR_RATE, "post">) {
return this.post(INVENTORY_ROUTES.REMOVE_FAVORITE_LABOR_RATE, payload)
}
}
+90
View File
@@ -0,0 +1,90 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const JOB_CARD_ROUTES = {
INDEX: "/api/job-cards",
BY_ID: "/api/job-cards/{id}",
CHANGE_DATE: "/api/job-cards/{id}/change-date",
CHANGE_STATUS: "/api/job-cards/{id}/change-status",
ADD_CUSTOMER_REMARK: "/api/job-cards/{id}/add-customer-remark",
EDIT_CUSTOMER_REMARK: "/api/job-cards/{id}/edit-customer-remark",
DELETE_CUSTOMER_REMARK: "/api/job-cards/{id}/delete-customer-remark",
ADD_SHOP_RECOMMENDATION: "/api/job-cards/{id}/add-shop-recommendation",
EDIT_SHOP_RECOMMENDATION: "/api/job-cards/{id}/edit-shop-recommendation",
DELETE_SHOP_RECOMMENDATION: "/api/job-cards/{id}/delete-shop-recommendation",
ADD_ATTACHMENT: "/api/job-cards/{id}/add-attachment",
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",
} as const satisfies Record<string, ApiPath>
export class JobCardsClient extends ApiClient {
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 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 } })
}
async changeDate(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.CHANGE_DATE, "post">) {
return this.post(JOB_CARD_ROUTES.CHANGE_DATE, payload, { params: { id } })
}
async changeStatus(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.CHANGE_STATUS, "post">) {
return this.post(JOB_CARD_ROUTES.CHANGE_STATUS, payload, { params: { id } })
}
async addCustomerRemark(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.ADD_CUSTOMER_REMARK, "post">) {
return this.post(JOB_CARD_ROUTES.ADD_CUSTOMER_REMARK, payload, { params: { id } })
}
async editCustomerRemark(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.EDIT_CUSTOMER_REMARK, "post">) {
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 addShopRecommendation(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.ADD_SHOP_RECOMMENDATION, "post">) {
return this.post(JOB_CARD_ROUTES.ADD_SHOP_RECOMMENDATION, payload, { params: { id } })
}
async editShopRecommendation(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.EDIT_SHOP_RECOMMENDATION, "post">) {
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 addAttachment(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.ADD_ATTACHMENT, "post">) {
return this.post(JOB_CARD_ROUTES.ADD_ATTACHMENT, payload, { params: { id } })
}
async deleteAttachment(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.DELETE_ATTACHMENT, "post">) {
return this.post(JOB_CARD_ROUTES.DELETE_ATTACHMENT, payload, { params: { id } })
}
async changeServiceWriter(id: string, payload: ApiRequestBody<typeof JOB_CARD_ROUTES.CHANGE_SERVICE_WRITER, "post">) {
return this.post(JOB_CARD_ROUTES.CHANGE_SERVICE_WRITER, payload, { params: { id } })
}
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 } })
}
}
+30
View File
@@ -0,0 +1,30 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const LABEL_ROUTES = {
INDEX: "/api/labels",
BY_ID: "/api/labels/{id}",
} as const satisfies Record<string, ApiPath>
export class LabelsClient extends ApiClient {
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 } })
}
}
+45
View File
@@ -0,0 +1,45 @@
import { ApiClient, 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",
BY_ID: "/api/parts/{id}",
IMPORT: "/api/import-parts",
EXPORT: "/api/export-parts",
TOGGLE_STATUS: "/api/toggle-part-status",
} as const satisfies Record<string, ApiPath>
export class PartsClient extends ApiClient {
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 } })
}
async import(payload: ApiRequestBody<typeof PARTS_ROUTES.IMPORT, "post">) {
return this.post(PARTS_ROUTES.IMPORT, payload)
}
async export(payload: ApiRequestBody<typeof PARTS_ROUTES.EXPORT, "post">) {
return this.post(PARTS_ROUTES.EXPORT, payload)
}
async toggleStatus(payload: ApiRequestBody<typeof PARTS_ROUTES.TOGGLE_STATUS, "post">) {
return this.post(PARTS_ROUTES.TOGGLE_STATUS, payload)
}
}
+35
View File
@@ -0,0 +1,35 @@
import { ApiClient, 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",
BY_ID: "/api/payment-terms/{id}",
SET_DEFAULT: "/api/set-default-payment-term",
} as const satisfies Record<string, ApiPath>
export class PaymentTermsClient extends ApiClient {
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 } })
}
async setDefault(payload: ApiRequestBody<typeof PAYMENT_TERM_ROUTES.SET_DEFAULT, "post">) {
return this.post(PAYMENT_TERM_ROUTES.SET_DEFAULT, payload)
}
}
+50
View File
@@ -0,0 +1,50 @@
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 } })
}
}
@@ -0,0 +1,30 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const PURCHASE_ORDER_ROUTES = {
INDEX: "/api/purchase-orders",
BY_ID: "/api/purchase-orders/{id}",
} as const satisfies Record<string, ApiPath>
export class PurchaseOrdersClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(PURCHASE_ORDER_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof PURCHASE_ORDER_ROUTES.INDEX, "post">) {
return this.post(PURCHASE_ORDER_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof PURCHASE_ORDER_ROUTES.BY_ID, "put">) {
return this.put(PURCHASE_ORDER_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(PURCHASE_ORDER_ROUTES.BY_ID, { params: { id } })
}
}
@@ -0,0 +1,35 @@
import { ApiClient, 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",
BY_ID: "/api/referral-sources/{id}",
SET_DEFAULT: "/api/set-default-referral-source",
} as const satisfies Record<string, ApiPath>
export class ReferralSourcesClient extends ApiClient {
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 } })
}
async setDefault(payload: ApiRequestBody<typeof REFERRAL_SOURCE_ROUTES.SET_DEFAULT, "post">) {
return this.post(REFERRAL_SOURCE_ROUTES.SET_DEFAULT, payload)
}
}
@@ -0,0 +1,17 @@
import { CrudClient } from "../infra/crud-client"
import type { ApiClientOptions } from "../infra/client"
import type { ApiPath } from "../infra/types"
export const SERVICE_GROUP_ROUTES = {
INDEX: "/api/service-groups",
BY_ID: "/api/service-groups/{id}",
} as const satisfies Record<string, ApiPath>
export class ServiceGroupsClient extends CrudClient<
typeof SERVICE_GROUP_ROUTES.INDEX,
typeof SERVICE_GROUP_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, SERVICE_GROUP_ROUTES.INDEX, SERVICE_GROUP_ROUTES.BY_ID)
}
}
+40
View File
@@ -0,0 +1,40 @@
import { ApiClient, 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",
BY_ID: "/api/services/{id}",
IMPORT: "/api/import-services",
EXPORT: "/api/export-services",
} as const satisfies Record<string, ApiPath>
export class ServicesClient extends ApiClient {
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 } })
}
async import(payload: ApiRequestBody<typeof SERVICE_ROUTES.IMPORT, "post">) {
return this.post(SERVICE_ROUTES.IMPORT, payload)
}
async export(payload: ApiRequestBody<typeof SERVICE_ROUTES.EXPORT, "post">) {
return this.post(SERVICE_ROUTES.EXPORT, payload)
}
}
@@ -0,0 +1,41 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const SHOP_CALENDAR_ROUTES = {
INDEX: "/api/shop-calenders",
BY_ID: "/api/shop-calenders/{id}",
SET_DEFAULT: "/api/set-default-shop-calender",
REMOVE_DEFAULT: "/api/remove-default-shop-calender",
UPDATE_DAY_TYPE: "/api/shop-calenders/{id}/update-day-type",
} as const satisfies Record<string, ApiPath>
export class ShopCalendarsClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(SHOP_CALENDAR_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof SHOP_CALENDAR_ROUTES.INDEX, "post">) {
return this.post(SHOP_CALENDAR_ROUTES.INDEX, payload)
}
async destroy(id: string) {
return this.delete(SHOP_CALENDAR_ROUTES.BY_ID, { params: { id } })
}
async setDefault(payload: ApiRequestBody<typeof SHOP_CALENDAR_ROUTES.SET_DEFAULT, "post">) {
return this.post(SHOP_CALENDAR_ROUTES.SET_DEFAULT, payload)
}
async removeDefault(payload: ApiRequestBody<typeof SHOP_CALENDAR_ROUTES.REMOVE_DEFAULT, "post">) {
return this.post(SHOP_CALENDAR_ROUTES.REMOVE_DEFAULT, payload)
}
async updateDayType(id: string, payload: ApiRequestBody<typeof SHOP_CALENDAR_ROUTES.UPDATE_DAY_TYPE, "post">) {
return this.post(SHOP_CALENDAR_ROUTES.UPDATE_DAY_TYPE, payload, { params: { id } } as never)
}
}
+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 SHOP_TIMING_ROUTES = {
INDEX: "/api/shop-timings",
BY_ID: "/api/shop-timings/{id}",
SET_DEFAULT: "/api/set-default-shop-timing",
REMOVE_DEFAULT: "/api/remove-default-shop-timing",
} as const satisfies Record<string, ApiPath>
export class ShopTimingsClient extends CrudClient<
typeof SHOP_TIMING_ROUTES.INDEX,
typeof SHOP_TIMING_ROUTES.BY_ID
> {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions, SHOP_TIMING_ROUTES.INDEX, SHOP_TIMING_ROUTES.BY_ID)
}
async setDefault(payload: ApiRequestBody<typeof SHOP_TIMING_ROUTES.SET_DEFAULT, "post">) {
return this.post(SHOP_TIMING_ROUTES.SET_DEFAULT, payload)
}
async removeDefault(payload: ApiRequestBody<typeof SHOP_TIMING_ROUTES.REMOVE_DEFAULT, "post">) {
return this.post(SHOP_TIMING_ROUTES.REMOVE_DEFAULT, payload)
}
}
+60
View File
@@ -0,0 +1,60 @@
import { ApiClient, 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",
BY_ID: "/api/shop-types/{id}",
} as const satisfies Record<string, ApiPath>
export type ShopTypeCreatePayload = {
title: string
shop_type?: string
note?: string
is_default?: boolean
inspection?: File | null
image?: File | null
}
export type ShopTypeUpdatePayload = Partial<Omit<ShopTypeCreatePayload, "title">> & {
title?: string
}
function buildShopTypeFormData(payload: ShopTypeCreatePayload | ShopTypeUpdatePayload): FormData {
const fd = new FormData()
if (payload.title) fd.append("title", payload.title)
if (payload.shop_type) fd.append("shop_type", payload.shop_type)
if (payload.note) fd.append("note", payload.note)
if (payload.is_default != null) fd.append("is_default", String(Number(payload.is_default)))
if (payload.inspection instanceof File) fd.append("inspection", payload.inspection)
if (payload.image instanceof File) fd.append("image", payload.image)
return fd
}
export class ShopTypesClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(SHOP_TYPE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ShopTypeCreatePayload) {
const fd = buildShopTypeFormData(payload)
return this.postFormData(SHOP_TYPE_ROUTES.INDEX, fd)
}
async update(id: string, payload: ShopTypeUpdatePayload) {
const fd = buildShopTypeFormData(payload)
fd.append("_method", "PUT")
const url = SHOP_TYPE_ROUTES.BY_ID.replace("{id}", id)
return this.postFormData(url, fd)
}
async destroy(id: string) {
return this.delete(SHOP_TYPE_ROUTES.BY_ID, { params: { id } })
}
}
+99
View File
@@ -0,0 +1,99 @@
import { ApiClient, 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}",
COMPLETE: "/api/tasks/{id}/complete",
} as const satisfies Record<string, ApiPath>
export class TasksClient extends ApiClient {
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 } })
}
async complete(id: string, payload: ApiRequestBody<typeof TASK_ROUTES.COMPLETE, "post">) {
return this.post(TASK_ROUTES.COMPLETE, payload, { params: { id } })
}
}
@@ -0,0 +1,88 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const VEHICLE_ATTRIBUTE_ROUTES = {
BODY_TYPES: "/api/vehicle-body-types",
BODY_TYPE_BY_ID: "/api/vehicle-body-types/{id}",
FUEL_TYPES: "/api/vehicle-fuel-types",
FUEL_TYPE_BY_ID: "/api/vehicle-fuel-types/{id}",
TRANSMISSIONS: "/api/vehicle-transmissions",
TRANSMISSION_BY_ID: "/api/vehicle-transmissions/{id}",
COLORS: "/api/vehicle-colors",
COLOR_BY_ID: "/api/vehicle-colors/{id}",
} as const satisfies Record<string, ApiPath>
export class VehicleAttributesClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Body Types ──
async listBodyTypes(query?: ApiListQueryParams) {
return this.get(VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPES, query ? { query } as never : undefined)
}
async createBodyType(payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPES, "post">) {
return this.post(VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPES, payload)
}
async updateBodyType(id: string, payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPE_BY_ID, "put">) {
return this.put(VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPE_BY_ID, payload, { params: { id } })
}
async destroyBodyType(id: string) {
return this.delete(VEHICLE_ATTRIBUTE_ROUTES.BODY_TYPE_BY_ID, { params: { id } })
}
// ── Fuel Types ──
async listFuelTypes(query?: ApiListQueryParams) {
return this.get(VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPES, query ? { query } as never : undefined)
}
async createFuelType(payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPES, "post">) {
return this.post(VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPES, payload)
}
async updateFuelType(id: string, payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPE_BY_ID, "put">) {
return this.put(VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPE_BY_ID, payload, { params: { id } })
}
async destroyFuelType(id: string) {
return this.delete(VEHICLE_ATTRIBUTE_ROUTES.FUEL_TYPE_BY_ID, { params: { id } })
}
// ── Transmissions ──
async listTransmissions(query?: ApiListQueryParams) {
return this.get(VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSIONS, query ? { query } as never : undefined)
}
async createTransmission(payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSIONS, "post">) {
return this.post(VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSIONS, payload)
}
async updateTransmission(id: string, payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSION_BY_ID, "put">) {
return this.put(VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSION_BY_ID, payload, { params: { id } })
}
async destroyTransmission(id: string) {
return this.delete(VEHICLE_ATTRIBUTE_ROUTES.TRANSMISSION_BY_ID, { params: { id } })
}
// ── Colors ──
async listColors(query?: ApiListQueryParams) {
return this.get(VEHICLE_ATTRIBUTE_ROUTES.COLORS, query ? { query } as never : undefined)
}
async createColor(payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.COLORS, "post">) {
return this.post(VEHICLE_ATTRIBUTE_ROUTES.COLORS, payload)
}
async updateColor(id: string, payload: ApiRequestBody<typeof VEHICLE_ATTRIBUTE_ROUTES.COLOR_BY_ID, "put">) {
return this.put(VEHICLE_ATTRIBUTE_ROUTES.COLOR_BY_ID, payload, { params: { id } })
}
async destroyColor(id: string) {
return this.delete(VEHICLE_ATTRIBUTE_ROUTES.COLOR_BY_ID, { params: { id } })
}
}
@@ -0,0 +1,69 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const VEHICLE_DOCUMENT_ROUTES = {
DOCUMENT_TYPES: "/api/document-types",
DOCUMENT_TYPE_BY_ID: "/api/document-types/{id}",
DOCUMENTS: "/api/vehicle-documents",
DOCUMENT_BY_ID: "/api/vehicle-documents/{id}",
MILEAGE: "/api/vehicle-mile-and-kms",
MILEAGE_BY_ID: "/api/vehicle-mile-and-kms/{id}",
} as const satisfies Record<string, ApiPath>
export class VehicleDocumentsClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
// ── Document Types ──
async listDocumentTypes(query?: ApiListQueryParams) {
return this.get(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPES, query ? { query } as never : undefined)
}
async createDocumentType(payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPES, "post">) {
return this.post(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPES, payload)
}
async updateDocumentType(id: string, payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPE_BY_ID, "put">) {
return this.put(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPE_BY_ID, payload, { params: { id } })
}
async destroyDocumentType(id: string) {
return this.delete(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_TYPE_BY_ID, { params: { id } })
}
// ── Vehicle Documents ──
async listDocuments(query?: ApiListQueryParams) {
return this.get(VEHICLE_DOCUMENT_ROUTES.DOCUMENTS, query ? { query } as never : undefined)
}
async createDocument(payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.DOCUMENTS, "post">) {
return this.post(VEHICLE_DOCUMENT_ROUTES.DOCUMENTS, payload)
}
async updateDocument(id: string, payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.DOCUMENT_BY_ID, "put">) {
return this.put(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_BY_ID, payload, { params: { id } })
}
async destroyDocument(id: string) {
return this.delete(VEHICLE_DOCUMENT_ROUTES.DOCUMENT_BY_ID, { params: { id } })
}
// ── Mileage ──
async listMileage(query?: ApiListQueryParams) {
return this.get(VEHICLE_DOCUMENT_ROUTES.MILEAGE, query ? { query } as never : undefined)
}
async createMileage(payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.MILEAGE, "post">) {
return this.post(VEHICLE_DOCUMENT_ROUTES.MILEAGE, payload)
}
async updateMileage(id: string, payload: ApiRequestBody<typeof VEHICLE_DOCUMENT_ROUTES.MILEAGE_BY_ID, "put">) {
return this.put(VEHICLE_DOCUMENT_ROUTES.MILEAGE_BY_ID, payload, { params: { id } })
}
async destroyMileage(id: string) {
return this.delete(VEHICLE_DOCUMENT_ROUTES.MILEAGE_BY_ID, { params: { id } })
}
}
+55
View File
@@ -0,0 +1,55 @@
import { ApiClient, type ApiClientOptions } from "../infra/client"
import type { ApiPath, ApiRequestBody } from "../infra/types"
import type { ApiListQueryParams } from "../contracts/types"
export const VEHICLE_ROUTES = {
INDEX: "/api/vehicles",
BY_ID: "/api/vehicles/{id}",
EXPORT: "/api/vehicles/export",
IMPORT: "/api/vehicles/import",
GET_OWNERS: "/api/get-vehicle-owners",
LINK_CUSTOMER: "/api/link-customer-to-vehicle",
UNLINK_CUSTOMER: "/api/unlink-customer-from-vehicle",
} as const satisfies Record<string, ApiPath>
export class VehiclesClient extends ApiClient {
constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) {
super(baseUrl, defaultOptions)
}
async list(query?: ApiListQueryParams) {
return this.get(VEHICLE_ROUTES.INDEX, query ? { query } as never : undefined)
}
async create(payload: ApiRequestBody<typeof VEHICLE_ROUTES.INDEX, "post">) {
return this.post(VEHICLE_ROUTES.INDEX, payload)
}
async update(id: string, payload: ApiRequestBody<typeof VEHICLE_ROUTES.BY_ID, "put">) {
return this.put(VEHICLE_ROUTES.BY_ID, payload, { params: { id } })
}
async destroy(id: string) {
return this.delete(VEHICLE_ROUTES.BY_ID, { params: { id } })
}
async export() {
return this.get(VEHICLE_ROUTES.EXPORT)
}
async import(payload: ApiRequestBody<typeof VEHICLE_ROUTES.IMPORT, "post">) {
return this.post(VEHICLE_ROUTES.IMPORT, payload)
}
async getOwners() {
return this.get(VEHICLE_ROUTES.GET_OWNERS)
}
async linkCustomer(payload: ApiRequestBody<typeof VEHICLE_ROUTES.LINK_CUSTOMER, "post">) {
return this.post(VEHICLE_ROUTES.LINK_CUSTOMER, payload)
}
async unlinkCustomer(payload: ApiRequestBody<typeof VEHICLE_ROUTES.UNLINK_CUSTOMER, "post">) {
return this.post(VEHICLE_ROUTES.UNLINK_CUSTOMER, payload)
}
}
+45
View File
@@ -0,0 +1,45 @@
import { ApiClient, 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",
BY_ID: "/api/vendors/{id}",
TOGGLE_STATUS: "/api/toggle-vendor-status",
CREATE_ADDRESS: "/api/create-vendor-address",
ADDRESS_BY_ID: "/api/vendor-address/{id}",
} as const satisfies Record<string, ApiPath>
export class VendorsClient extends ApiClient {
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 } })
}
async toggleStatus(payload: ApiRequestBody<typeof VENDOR_ROUTES.TOGGLE_STATUS, "post">) {
return this.post(VENDOR_ROUTES.TOGGLE_STATUS, payload)
}
async createAddress(payload: ApiRequestBody<typeof VENDOR_ROUTES.CREATE_ADDRESS, "post">) {
return this.post(VENDOR_ROUTES.CREATE_ADDRESS, payload)
}
async getAddress(id: string) {
return this.get(VENDOR_ROUTES.ADDRESS_BY_ID, { params: { id } })
}
}