Files
Client_Fe/src/lib/models/customer.ts
T
Dhananjaya99 a1b870fa8a first commit
2026-09-28 11:48:14 +05:30

172 lines
5.1 KiB
TypeScript

import type { GymPlan } from "@/lib/models/gym-plan"
import type { PaymentStatus, SubscriptionSummary } from "@/lib/models/subscription"
/** One weekly weigh-in (CusWeightLossProgress). */
export interface WeightProgressPoint {
weeklyProgressId: string
weight?: number | null
recordedAt: string
}
/** A member's goal/measurements (CustomerTarget) with their weight history. */
export interface CustomerTarget {
customerTargetId: string
currentWeight?: number | null
currentHeight?: number | null
targetWeight?: number | null
goal?: string | null
timePeriod?: string | null
weeklyProgresses?: WeightProgressPoint[] | null
}
/** Customer entity as serialized by the backend (camelCase of the EF model). */
export interface MemberProfile {
cusId: string
cusName?: string | null
gender?: string | null
/** Date of birth, "yyyy-MM-dd". Backend property is BoD. */
boD?: string | null
primaryPH?: string | null
secondaryPH?: string | null
email?: string | null
nic?: string | null
address?: string | null
fkUserId?: string
isActive: boolean
createdAt: string
isLocked?: boolean
lockReason?: string | null
lockedAt?: string | null
customerTargets?: CustomerTarget[] | null
user?: {
userId: string
userName?: string | null
email?: string | null
phoneNumber?: string | null
} | null
}
/** A workout/meal plan the member is assigned to. */
export interface FollowedPlan {
planId: string
name?: string | null
isFollowing: boolean
completedDate?: string | null
}
/** GET client/customers/{id}/full — the "More Info" aggregate. */
export interface MemberFullDetail {
customer: MemberProfile
subscriptions?: SubscriptionSummary[]
workoutPlans: FollowedPlan[]
mealPlans: FollowedPlan[]
}
/** POST client/customers/{id}/medical (password-gated). */
export interface MedicalDetails {
bloodGroup?: string | null
disabilities?: string | null
}
/**
* Row shape of GET client/customers (MemberListRowDto): one row per member.
* Group members each get a row pointing at their shared subscription.
*/
export interface MemberSubscription {
subscriptionId: string
fkCustomerPlanId: string
fkCustomerId: string
onboardDate: string
/** Frozen at creation, never changes again -- use renewalDate for current status/listing. */
expiryDate?: string | null
renewalDate?: string | null
isActive: boolean
createdAt: string
customer?: MemberProfile | null
isPrimary: boolean
/** False when unassigned from the plan but still a member of the gym — re-assignable. */
isPlanAssigned?: boolean
planName?: string | null
/** "None" means this member was created without a plan yet — assign one to make them active. */
planScope?: "Individual" | "Group" | "None"
memberCount?: number
memberLimit?: number
invoiceAmount?: number
paidAmount?: number
balance?: number
paymentStatus?: PaymentStatus
allowSplitPayments?: boolean
fingerprintId?: number | null
fingerprintName?: string | null
accessProfileId?: number | null
accessNumber?: string | null
accessProvisionStatus?: "NotConfigured" | "NoDevice" | "Pending" | "Synced" | "Failed"
actualAccessState?: "Unknown" | "Enabled" | "Disabled" | "Mixed"
desiredAccessState?: "Enabled" | "Disabled"
fingerprintCount?: number
accessLastError?: string | null
isLocked?: boolean
lockReason?: string | null
/** Face-photo enrolment on the gym's access terminals. */
hasFacePhoto?: boolean
facePhotoStatus?: "None" | "Pending" | "Synced" | "Failed"
facePhotoError?: string | null
}
/** GET client/customers/unlinked-fingerprints — a device enrollment not yet linked to a Customer. */
export interface UnlinkedFingerprint {
id: string
deviceUserId: number
deviceEmployeeNo: string
deviceReportedName?: string | null
deviceUserType?: string | null
fingerprintCount: number
deviceId: string
deviceName?: string | null
discoveredAt: string
}
export interface AccessCommandStatus {
accessProfileId: number
accessNumber: string
personType: "Customer" | "Staff"
desiredAccessState: "Enabled" | "Disabled"
provisionStatus: "NoDevice" | "Pending" | "Synced" | "Failed"
actualAccessState: "Unknown" | "Enabled" | "Disabled" | "Mixed"
fingerprintCount: number
lastError?: string | null
lastSyncedAt?: string | null
deviceCount: number
syncedDeviceCount: number
}
/** GET client/customers/{id} response. */
export interface MemberDetail {
customer: MemberProfile
plans: GymPlan[]
subscriptions?: SubscriptionSummary[]
}
export interface MemberInput {
fullname: string
userName: string
email: string
mobileNumber: string
gender: string
/** "yyyy-MM-dd" */
birthday: string
nic?: string
customerPlanId?: string
workoutPlanIds?: string[]
mealPlanIds?: string[]
/** ISO datetime. Only meaningful alongside customerPlanId. */
onboardDate?: string
/** false bills the plan at Rs. 0.00 and skips the automatic payment link. */
chargePayment?: boolean
discountType?: "Percentage" | "Flat"
discountValue?: number
/** Set true only on the resubmit after staff has confirmed linking an existing platform
* customer to this gym (see CreateMemberResult.requiresConfirmation). */
confirmLink?: boolean
}