Add store installments module with calculator and public API docs.
Business dashboard can manage credit methods and preview plans; cropper and module flags support the new flow. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
ff419603bf
commit
e2950fa20e
@@ -0,0 +1,110 @@
|
||||
import { apiRequest } from '../lib/api'
|
||||
import { getActiveBusinessId } from '../lib/businessContext'
|
||||
import type {
|
||||
StoreLoanImageAspect,
|
||||
StoreLoanMethod,
|
||||
StoreLoanMethodApi,
|
||||
StoreLoanMethodFormPayload,
|
||||
StoreLoanMethodsListResponse,
|
||||
} from '../types/storeLoanMethod'
|
||||
|
||||
function businessPath(suffix = '') {
|
||||
const businessId = getActiveBusinessId()
|
||||
if (!businessId) {
|
||||
throw new Error('No active business selected. Please sign in again.')
|
||||
}
|
||||
return `/businesses/${businessId}/store-loan-methods${suffix}`
|
||||
}
|
||||
|
||||
function normalizeAspect(value: string | undefined | null): StoreLoanImageAspect {
|
||||
return value === '3:2' ? '3:2' : '1:1'
|
||||
}
|
||||
|
||||
export async function listStoreLoanMethods(
|
||||
page = 1,
|
||||
pageSize = 100,
|
||||
signal?: AbortSignal,
|
||||
) {
|
||||
const params = new URLSearchParams({
|
||||
page: String(page),
|
||||
pageSize: String(pageSize),
|
||||
})
|
||||
|
||||
return apiRequest<StoreLoanMethodsListResponse>(
|
||||
`${businessPath()}?${params.toString()}`,
|
||||
{ auth: true, signal },
|
||||
)
|
||||
}
|
||||
|
||||
export async function listAllStoreLoanMethods(signal?: AbortSignal) {
|
||||
const pageSize = 100
|
||||
let page = 1
|
||||
let items: StoreLoanMethodApi[] = []
|
||||
let total = Infinity
|
||||
|
||||
while (items.length < total) {
|
||||
const data = await listStoreLoanMethods(page, pageSize, signal)
|
||||
items = items.concat(data.items)
|
||||
total = data.total
|
||||
page += 1
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
export async function getStoreLoanMethod(methodId: string, signal?: AbortSignal) {
|
||||
return apiRequest<{ method: StoreLoanMethodApi }>(businessPath(`/${methodId}`), {
|
||||
auth: true,
|
||||
signal,
|
||||
})
|
||||
}
|
||||
|
||||
export async function createStoreLoanMethod(payload: StoreLoanMethodFormPayload) {
|
||||
return apiRequest<{ message: string; method: StoreLoanMethodApi }>(businessPath(), {
|
||||
method: 'POST',
|
||||
auth: true,
|
||||
body: payload,
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateStoreLoanMethod(
|
||||
methodId: string,
|
||||
payload: StoreLoanMethodFormPayload,
|
||||
) {
|
||||
return apiRequest<{ message: string; method: StoreLoanMethodApi }>(
|
||||
businessPath(`/${methodId}`),
|
||||
{
|
||||
method: 'PATCH',
|
||||
auth: true,
|
||||
body: payload,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function deleteStoreLoanMethod(methodId: string) {
|
||||
return apiRequest<{ message: string }>(businessPath(`/${methodId}`), {
|
||||
method: 'DELETE',
|
||||
auth: true,
|
||||
})
|
||||
}
|
||||
|
||||
export function mapStoreLoanMethodApiToUi(method: StoreLoanMethodApi): StoreLoanMethod {
|
||||
return {
|
||||
id: method.id,
|
||||
nameFa: method.nameFa,
|
||||
nameEn: method.nameEn,
|
||||
description: method.description ?? '',
|
||||
imageUrl: method.imageUrl,
|
||||
imageMediaId: method.imageMediaId,
|
||||
imageAspectRatio: normalizeAspect(method.imageAspectRatio),
|
||||
minShoppingAmount: method.minShoppingAmount,
|
||||
minAmount: method.minAmount,
|
||||
maxAmount: method.maxAmount,
|
||||
interest: method.interest,
|
||||
returnMonthsMin: method.returnMonthsMin,
|
||||
returnMonthsMax: method.returnMonthsMax,
|
||||
returnMonthsStep: method.returnMonthsStep,
|
||||
sortOrder: method.sortOrder,
|
||||
isActive: method.isActive,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user