Yimaru-Admin/src/api/subscription-plans.api.ts
Yared Yemane 2c3f0da6f7 feat(admin): payments, settings tabs, theme, and navigation refresh
Add admin payments with status, provider, and plan category filters. Introduce app versions and subscription plan management in settings, change-password security flow, and dark theme support. Reorganize sidebar, improve activity log actor details, analytics, and related UI polish.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 06:54:58 -07:00

85 lines
2.7 KiB
TypeScript

import http from "./http"
import type {
CreateSubscriptionPlanPayload,
SubscriptionPlan,
SubscriptionPlanMutationResponse,
SubscriptionPlansListResponse,
UpdateSubscriptionPlanPayload,
} from "../types/subscription.types"
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value)
}
function normalizeSubscriptionPlan(raw: unknown): SubscriptionPlan | null {
if (!isRecord(raw)) return null
const id = Number(raw.id)
if (!Number.isFinite(id)) return null
return {
id,
name: String(raw.name ?? ""),
description: String(raw.description ?? ""),
category: String(raw.category ?? ""),
duration_value: Number(raw.duration_value ?? 0),
duration_unit: String(raw.duration_unit ?? "MONTH"),
price: Number(raw.price ?? 0),
currency: String(raw.currency ?? "ETB"),
is_active: Boolean(raw.is_active ?? true),
created_at: String(raw.created_at ?? ""),
}
}
export function parseSubscriptionPlansList(body: unknown): SubscriptionPlan[] {
if (Array.isArray(body)) {
return body.map(normalizeSubscriptionPlan).filter((p): p is SubscriptionPlan => p !== null)
}
if (isRecord(body) && Array.isArray(body.data)) {
return body.data
.map(normalizeSubscriptionPlan)
.filter((p): p is SubscriptionPlan => p !== null)
}
return []
}
export function parseSubscriptionPlanMutation(body: unknown): SubscriptionPlan | null {
if (isRecord(body) && body.data != null) {
return normalizeSubscriptionPlan(body.data)
}
return normalizeSubscriptionPlan(body)
}
export const getSubscriptionPlans = () =>
http.get<SubscriptionPlansListResponse | SubscriptionPlan[]>("/subscription-plans").then((res) => {
const plans = parseSubscriptionPlansList(res.data)
return {
...res,
data: plans,
}
})
function mutationResult(res: { data: unknown }) {
const plan = parseSubscriptionPlanMutation(res.data)
return {
...res,
data: plan,
message: isRecord(res.data) ? String(res.data.message ?? "") : undefined,
}
}
export const createSubscriptionPlan = (payload: CreateSubscriptionPlanPayload) =>
http
.post<SubscriptionPlanMutationResponse | SubscriptionPlan>("/subscription-plans", payload)
.then(mutationResult)
export const updateSubscriptionPlan = (id: number, payload: UpdateSubscriptionPlanPayload) =>
http
.put<SubscriptionPlanMutationResponse | SubscriptionPlan>(`/subscription-plans/${id}`, payload)
.then(mutationResult)
export const deleteSubscriptionPlan = (id: number) =>
http.delete<{ message?: string }>(`/subscription-plans/${id}`).then((res) => ({
...res,
message: isRecord(res.data) ? String(res.data.message ?? "") : undefined,
}))