Files
moalem-shop/src/lib/loanMethods.ts
T
Alireza HassaniandCursor e625354dc9 Add installment calculator and Latin digits in English product text.
Wire the product CTA to store-loan-methods calculate so shoppers can pick a term and see the plan, and render English model runs under Montserrat so fanum fonts stop painting 0-9 as Persian digits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-25 00:21:40 +03:30

54 lines
1.6 KiB
TypeScript

import { API_BASE, SITE_DOMAIN } from "./config";
import type { StoreLoanCalculateResponse, StoreLoanMethodsResponse } from "./types";
const base = `${API_BASE}/tenants/${SITE_DOMAIN}/store-loan-methods`;
/** Browser-side list — same contract as GET .../store-loan-methods. */
export async function fetchStoreLoanMethods(
signal?: AbortSignal,
): Promise<StoreLoanMethodsResponse> {
const res = await fetch(base, { signal });
if (!res.ok) throw new Error(`loan methods failed (${res.status})`);
return res.json() as Promise<StoreLoanMethodsResponse>;
}
/** Browser-side calculate — POST .../store-loan-methods/calculate. */
export async function fetchStoreLoanPlan(
input: {
methodId: string;
totalValue: number;
creditAmount: number;
months: number;
},
signal?: AbortSignal,
): Promise<StoreLoanCalculateResponse> {
const res = await fetch(`${base}/calculate`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(input),
signal,
});
if (!res.ok) {
let message = `calculate failed (${res.status})`;
try {
const body = (await res.json()) as { message?: string };
if (body.message) message = body.message;
} catch {
/* ignore */
}
throw new Error(message);
}
return res.json() as Promise<StoreLoanCalculateResponse>;
}
export function clampCreditAmount(
value: number,
totalValue: number,
minAmount: number,
maxAmount: number,
): number {
const upper = Math.min(Math.round(maxAmount), Math.round(totalValue));
const lower = Math.min(Math.round(minAmount), upper);
return Math.min(upper, Math.max(lower, Math.round(value)));
}