feat: add refferal feature

This commit is contained in:
2026-06-06 13:50:06 +03:30
parent 577d8afb53
commit 754c1c3178
10 changed files with 526 additions and 4 deletions
+25
View File
@@ -0,0 +1,25 @@
import { apiClient } from './client';
import { PendingReferralRewardsResponse, FulfillReferralRewardResponse } from '@/types/referral';
export const referralApi = {
// List users who reached the invite target and have not been granted the free month yet
getPendingRewards: async (token: string): Promise<PendingReferralRewardsResponse> => {
return apiClient.get<PendingReferralRewardsResponse>('/admin/referral-rewards', token);
},
// Grant the free month to a user. product_id is optional: omit it to
// auto-grant the meditation package's monthly product.
fulfillReward: async (
userId: number,
token: string,
productId?: number
): Promise<FulfillReferralRewardResponse> => {
const data = productId ? { product_id: productId } : {};
return apiClient.post<FulfillReferralRewardResponse>(
`/admin/referral-rewards/${userId}/fulfill`,
data,
token
);
}
};
+27 -1
View File
@@ -1,5 +1,5 @@
import { apiClient } from './client';
import { User, Product, ApiResponse } from '@/types/user';
import { User, Product, ApiResponse, UpdateUserProfileData } from '@/types/user';
export const usersApi = {
// Get user status by email or mobile - package name is now a parameter
@@ -47,5 +47,31 @@ export const usersApi = {
// Get products for a specific package
getProductsByPackage: async (packageName: string, token: string): Promise<Product[]> => {
return apiClient.get<Product[]>(`/package-names/${packageName}/products`, token);
},
// Update a user's profile (admin). Uses FormData because avatar may be an image file.
updateUserProfile: async (
identifier: string,
data: UpdateUserProfileData,
token: string
): Promise<ApiResponse<any>> => {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => {
if (value !== null && value !== undefined && value !== '') {
if (key === 'avatar' && value instanceof File) {
formData.append('avatar', value);
} else if (key !== 'avatar') {
formData.append(key, String(value));
}
}
});
return apiClient.post<ApiResponse<any>>(`/admin/users/${identifier}/profile`, formData, token);
},
// Delete a user (admin)
deleteUser: async (identifier: string, token: string): Promise<ApiResponse<any>> => {
return apiClient.delete<ApiResponse<any>>(`/admin/users/${identifier}`, undefined, token);
}
};