Files
route-commerce/src/app/api/referrals/route.ts
T
tyler 7dfaba6e3d feat: complete launch & marketing layer
- Add marketing pages: blog, changelog, roadmap, waitlist, security, maintenance
- Add GDPR cookie consent banner with preference modal
- Add referral system with API routes for code generation/tracking
- Add waitlist API with referral support
- Add PWA support: manifest, service worker, install prompt
- Add onboarding flow with 6-step guided tour
- Add in-app notification center with bell dropdown
- Add admin launch checklist (32 items across 8 categories)
- Update landing page with trust badges
- Add Open Graph image and favicon
- Configure ESLint for PWA install patterns
- Add LAUNCH_CHECKLIST.md with go-to-market guide

Supabase migrations for:
- blog_posts and blog_categories tables
- waitlist_signups table
- roadmap_items table
- launch_checklist_items table
2026-06-02 06:19:56 +00:00

169 lines
4.4 KiB
TypeScript

// Referrals API - Generate and track referral codes
import { NextRequest, NextResponse } from "next/server";
const REFERRAL_REWARD_PERCENTAGE = 20;
const MAX_USES_PER_CODE = 10;
interface ReferralCode {
code: string;
reward_type: "percentage" | "fixed";
reward_value: number;
uses: number;
max_uses: number;
created_at: string;
brand_id: string;
user_id: string;
}
// In-memory store for demo (replace with Supabase in production)
const referralCodes = new Map<string, ReferralCode>();
function generateReferralCode(): string {
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
let code = "";
for (let i = 0; i < 8; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const brandId = searchParams.get("brand_id");
const userId = searchParams.get("user_id");
if (!brandId || !userId) {
return NextResponse.json(
{ error: "brand_id and user_id are required" },
{ status: 400 }
);
}
// Get all codes for this user
const userCodes: ReferralCode[] = [];
for (const code of referralCodes.values()) {
if (code.brand_id === brandId && code.user_id === userId) {
userCodes.push(code);
}
}
// Calculate stats
const stats = {
total_referrals: userCodes.reduce((sum, code) => sum + code.uses, 0),
successful_conversions: userCodes.reduce((sum, code) => sum + code.uses, 0),
total_reward_value: userCodes.reduce(
(sum, code) => sum + code.uses * code.reward_value,
0
),
};
return NextResponse.json({
codes: userCodes,
stats,
});
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { action, brand_id, user_id } = body;
if (action === "generate") {
if (!brand_id || !user_id) {
return NextResponse.json(
{ error: "brand_id and user_id are required" },
{ status: 400 }
);
}
const code = generateReferralCode();
const referralCode: ReferralCode = {
code,
reward_type: "percentage",
reward_value: REFERRAL_REWARD_PERCENTAGE,
uses: 0,
max_uses: MAX_USES_PER_CODE,
created_at: new Date().toISOString(),
brand_id,
user_id,
};
referralCodes.set(code, referralCode);
return NextResponse.json({
success: true,
code: referralCode,
share_url: `${process.env.NEXT_PUBLIC_SITE_URL || "https://routecommerce.com"}/register?ref=${code}`,
});
}
if (action === "validate") {
const { code } = body;
if (!code) {
return NextResponse.json(
{ error: "code is required" },
{ status: 400 }
);
}
const referralCode = referralCodes.get(code);
if (!referralCode) {
return NextResponse.json({ valid: false, error: "Invalid code" });
}
if (referralCode.uses >= referralCode.max_uses) {
return NextResponse.json({
valid: false,
error: "This code has reached its maximum uses",
});
}
return NextResponse.json({
valid: true,
reward_type: referralCode.reward_type,
reward_value: referralCode.reward_value,
});
}
if (action === "use") {
const { code, new_user_id } = body;
if (!code || !new_user_id) {
return NextResponse.json(
{ error: "code and new_user_id are required" },
{ status: 400 }
);
}
const referralCode = referralCodes.get(code);
if (!referralCode) {
return NextResponse.json({ error: "Invalid code" }, { status: 404 });
}
if (referralCode.uses >= referralCode.max_uses) {
return NextResponse.json(
{ error: "Code has reached maximum uses" },
{ status: 400 }
);
}
// Increment usage
referralCode.uses += 1;
referralCodes.set(code, referralCode);
return NextResponse.json({
success: true,
reward_type: referralCode.reward_type,
reward_value: referralCode.reward_value,
discount: `${referralCode.reward_value}% off first month`,
});
}
return NextResponse.json({ error: "Unknown action" }, { status: 400 });
} catch (error) {
console.error("Referral API error:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}