export interface ReferralClientOptions { baseUrl: string; productId: string; getAccessToken: () => string; } export interface ReferralStats { totalReferrals: number; successfulReferrals: number; pendingReferrals: number; rewardsEarned: number; referralCode: string; } export interface ReferralInfo { code: string; referrerEmail: string; status: string; } function joinUrl(base: string, path: string): string { const b = base.replace(/\/$/, ""); const p = path.startsWith("/") ? path : `/${path}`; return `${b}${p}`; } function headers(opts: ReferralClientOptions): HeadersInit { return { Authorization: `Bearer ${opts.getAccessToken()}`, "X-Product-Id": opts.productId, Accept: "application/json", }; } async function parseJson(res: Response): Promise { if (!res.ok) { const text = await res.text(); throw new Error(`HTTP ${res.status}: ${text || res.statusText}`); } return res.json() as Promise; } export function createReferralClient(opts: ReferralClientOptions) { const { baseUrl } = opts; return { async getReferralStats(): Promise { const res = await fetch(joinUrl(baseUrl, "/referrals/stats"), { method: "GET", headers: headers(opts), }); return parseJson(res); }, buildShareLink(code: string): string { const b = baseUrl.replace(/\/$/, ""); return `${b}/r/${code}`; }, buildShareMessage(code: string, productName: string): string { return `Try ${productName}! Use my referral code: ${code}`; }, async getByEmail(code: string): Promise { const res = await fetch( joinUrl(baseUrl, `/referrals/${encodeURIComponent(code)}`), { method: "GET", headers: headers(opts) } ); return parseJson(res); }, }; }