299 lines
8.4 KiB
TypeScript
299 lines
8.4 KiB
TypeScript
import apiClient from '../../../shared/services/apiClient';
|
|
|
|
export interface LoyaltyTier {
|
|
id: number;
|
|
level: 'bronze' | 'silver' | 'gold' | 'platinum';
|
|
name: string;
|
|
description: string;
|
|
min_points: number;
|
|
points_earn_rate: number;
|
|
discount_percentage: number;
|
|
benefits: string;
|
|
icon?: string;
|
|
color?: string;
|
|
is_active?: boolean;
|
|
}
|
|
|
|
export interface UserLoyaltyStatus {
|
|
total_points: number;
|
|
lifetime_points: number;
|
|
available_points: number;
|
|
expired_points: number;
|
|
referral_code: string;
|
|
referral_count: number;
|
|
birthday?: string;
|
|
anniversary_date?: string;
|
|
tier: LoyaltyTier;
|
|
next_tier?: {
|
|
id: number;
|
|
level: string;
|
|
name: string;
|
|
min_points: number;
|
|
points_earn_rate: number;
|
|
discount_percentage: number;
|
|
points_needed: number;
|
|
};
|
|
points_needed_for_next_tier?: number;
|
|
tier_started_date?: string;
|
|
}
|
|
|
|
export interface PointsTransaction {
|
|
id: number;
|
|
transaction_type: 'earned' | 'redeemed' | 'expired' | 'bonus' | 'adjustment';
|
|
source: 'booking' | 'referral' | 'birthday' | 'anniversary' | 'redemption' | 'promotion' | 'manual';
|
|
points: number;
|
|
description: string;
|
|
reference_number?: string;
|
|
expires_at?: string;
|
|
created_at: string;
|
|
booking_id?: number;
|
|
}
|
|
|
|
export interface LoyaltyReward {
|
|
id: number;
|
|
name: string;
|
|
description: string;
|
|
reward_type: 'discount' | 'room_upgrade' | 'amenity' | 'cashback' | 'voucher';
|
|
points_cost: number;
|
|
discount_percentage?: number;
|
|
discount_amount?: number;
|
|
max_discount_amount?: number;
|
|
min_booking_amount?: number;
|
|
icon?: string;
|
|
image?: string;
|
|
is_available: boolean;
|
|
can_afford: boolean;
|
|
stock_remaining?: number;
|
|
stock_quantity?: number;
|
|
redeemed_count?: number;
|
|
applicable_tier_id?: number;
|
|
is_active?: boolean;
|
|
valid_from?: string;
|
|
valid_until?: string;
|
|
}
|
|
|
|
export interface RewardRedemption {
|
|
id: number;
|
|
reward: LoyaltyReward;
|
|
points_used: number;
|
|
status: 'pending' | 'active' | 'used' | 'expired' | 'cancelled';
|
|
code?: string;
|
|
booking_id?: number;
|
|
expires_at?: string;
|
|
used_at?: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface Referral {
|
|
id: number;
|
|
referred_user?: {
|
|
id: number;
|
|
name: string;
|
|
email: string;
|
|
};
|
|
referral_code: string;
|
|
status: 'pending' | 'completed' | 'rewarded';
|
|
referrer_points_earned: number;
|
|
referred_points_earned: number;
|
|
completed_at?: string;
|
|
rewarded_at?: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface LoyaltyStatusResponse {
|
|
status: string;
|
|
data: UserLoyaltyStatus;
|
|
}
|
|
|
|
export interface PointsHistoryResponse {
|
|
status: string;
|
|
data: {
|
|
transactions: PointsTransaction[];
|
|
pagination: {
|
|
total: number;
|
|
page: number;
|
|
limit: number;
|
|
totalPages: number;
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface RewardsResponse {
|
|
status: string;
|
|
data: {
|
|
rewards: LoyaltyReward[];
|
|
available_points: number;
|
|
};
|
|
}
|
|
|
|
export interface RedemptionsResponse {
|
|
status: string;
|
|
data: {
|
|
redemptions: RewardRedemption[];
|
|
};
|
|
}
|
|
|
|
export interface ReferralsResponse {
|
|
status: string;
|
|
data: {
|
|
referrals: Referral[];
|
|
total_referrals: number;
|
|
total_points_earned: number;
|
|
};
|
|
}
|
|
|
|
const loyaltyService = {
|
|
getMyStatus: async (): Promise<LoyaltyStatusResponse> => {
|
|
const response = await apiClient.get('/api/loyalty/my-status');
|
|
return response.data;
|
|
},
|
|
|
|
getPointsHistory: async (
|
|
page: number = 1,
|
|
limit: number = 20,
|
|
transactionType?: string
|
|
): Promise<PointsHistoryResponse> => {
|
|
const params: any = { page, limit };
|
|
if (transactionType) {
|
|
params.transaction_type = transactionType;
|
|
}
|
|
const response = await apiClient.get('/api/loyalty/points/history', { params });
|
|
return response.data;
|
|
},
|
|
|
|
updateMyStatus: async (data: { birthday?: string; anniversary_date?: string }): Promise<{ status: string; message: string }> => {
|
|
const response = await apiClient.put('/api/loyalty/my-status', data);
|
|
return response.data;
|
|
},
|
|
|
|
getAvailableRewards: async (): Promise<RewardsResponse> => {
|
|
const response = await apiClient.get('/api/loyalty/rewards');
|
|
return response.data;
|
|
},
|
|
|
|
redeemReward: async (rewardId: number, bookingId?: number): Promise<{ status: string; message: string; data: any }> => {
|
|
const response = await apiClient.post('/api/loyalty/rewards/redeem', {
|
|
reward_id: rewardId,
|
|
booking_id: bookingId,
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
getMyRedemptions: async (statusFilter?: string): Promise<RedemptionsResponse> => {
|
|
const params: any = {};
|
|
if (statusFilter) {
|
|
params.status_filter = statusFilter;
|
|
}
|
|
const response = await apiClient.get('/api/loyalty/rewards/my-redemptions', { params });
|
|
return response.data;
|
|
},
|
|
|
|
applyReferralCode: async (referralCode: string): Promise<{ status: string; message: string }> => {
|
|
const response = await apiClient.post('/api/loyalty/referral/apply', {
|
|
referral_code: referralCode,
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
getMyReferrals: async (): Promise<ReferralsResponse> => {
|
|
const response = await apiClient.get('/api/loyalty/referral/my-referrals');
|
|
return response.data;
|
|
},
|
|
|
|
getAllTiers: async (): Promise<{ status: string; data: { tiers: LoyaltyTier[] } }> => {
|
|
const response = await apiClient.get('/api/loyalty/admin/tiers');
|
|
return response.data;
|
|
},
|
|
|
|
getUsersLoyaltyStatus: async (
|
|
search?: string,
|
|
tierId?: number,
|
|
page: number = 1,
|
|
limit: number = 20
|
|
): Promise<{
|
|
status: string;
|
|
data: {
|
|
users: Array<{
|
|
user_id: number;
|
|
user_name: string;
|
|
user_email: string;
|
|
tier: LoyaltyTier;
|
|
total_points: number;
|
|
lifetime_points: number;
|
|
available_points: number;
|
|
referral_count: number;
|
|
tier_started_date?: string;
|
|
}>;
|
|
pagination: {
|
|
total: number;
|
|
page: number;
|
|
limit: number;
|
|
totalPages: number;
|
|
};
|
|
};
|
|
}> => {
|
|
const params: any = { page, limit };
|
|
if (search) params.search = search;
|
|
if (tierId) params.tier_id = tierId;
|
|
const response = await apiClient.get('/api/loyalty/admin/users', { params });
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Get loyalty program status
|
|
getProgramStatus: async (): Promise<{ status: string; data: { enabled: boolean; updated_at?: string; updated_by?: string } }> => {
|
|
const response = await apiClient.get('/api/loyalty/admin/status');
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Update loyalty program status
|
|
updateProgramStatus: async (enabled: boolean): Promise<{ status: string; message: string; data: { enabled: boolean } }> => {
|
|
const response = await apiClient.put('/api/loyalty/admin/status', { enabled });
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Create tier
|
|
createTier: async (tierData: Partial<LoyaltyTier>): Promise<{ status: string; message: string; data: any }> => {
|
|
const response = await apiClient.post('/api/loyalty/admin/tiers', tierData);
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Update tier
|
|
updateTier: async (tierId: number, tierData: Partial<LoyaltyTier>): Promise<{ status: string; message: string; data: any }> => {
|
|
const response = await apiClient.put(`/api/loyalty/admin/tiers/${tierId}`, tierData);
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Delete tier
|
|
deleteTier: async (tierId: number): Promise<{ status: string; message: string }> => {
|
|
const response = await apiClient.delete(`/api/loyalty/admin/tiers/${tierId}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Get all rewards (admin view)
|
|
getAllRewardsAdmin: async (): Promise<RewardsResponse> => {
|
|
const response = await apiClient.get('/api/loyalty/admin/rewards');
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Create reward
|
|
createReward: async (rewardData: Partial<LoyaltyReward>): Promise<{ status: string; message: string; data: any }> => {
|
|
const response = await apiClient.post('/api/loyalty/admin/rewards', rewardData);
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Update reward
|
|
updateReward: async (rewardId: number, rewardData: Partial<LoyaltyReward>): Promise<{ status: string; message: string; data: any }> => {
|
|
const response = await apiClient.put(`/api/loyalty/admin/rewards/${rewardId}`, rewardData);
|
|
return response.data;
|
|
},
|
|
|
|
// Admin: Delete reward
|
|
deleteReward: async (rewardId: number): Promise<{ status: string; message: string }> => {
|
|
const response = await apiClient.delete(`/api/loyalty/admin/rewards/${rewardId}`);
|
|
return response.data;
|
|
},
|
|
};
|
|
|
|
export default loyaltyService;
|
|
|