feat: add backoffice API client with NEXT_PUBLIC_BACKOFFICE_URL env var
This commit is contained in:
parent
b7987dead9
commit
35d3032d52
2 changed files with 89 additions and 2 deletions
|
|
@ -10,11 +10,18 @@
|
|||
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8521
|
||||
|
||||
# Backoffice API URL (NestJS backend for Stripe, admin dashboard)
|
||||
# Examples:
|
||||
# Local: http://localhost:3001
|
||||
# Production: https://backoffice.gohorsejobs.com
|
||||
|
||||
NEXT_PUBLIC_BACKOFFICE_URL=http://localhost:3001
|
||||
|
||||
# Seeder API URL (for admin operations)
|
||||
NEXT_PUBLIC_SEEDER_API_URL=http://localhost:3001
|
||||
NEXT_PUBLIC_SEEDER_API_URL=http://localhost:3002
|
||||
|
||||
# Scraper API URL (for importing scraped jobs)
|
||||
NEXT_PUBLIC_SCRAPER_API_URL=http://localhost:3002
|
||||
NEXT_PUBLIC_SCRAPER_API_URL=http://localhost:3003
|
||||
|
||||
# Vercel Analytics (optional)
|
||||
NEXT_PUBLIC_VERCEL_ANALYTICS=false
|
||||
|
|
|
|||
|
|
@ -462,3 +462,83 @@ export const profileApi = {
|
|||
return res.json();
|
||||
}
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// BACKOFFICE API (Stripe, Admin Dashboard, etc.)
|
||||
// =============================================================================
|
||||
const BACKOFFICE_URL = process.env.NEXT_PUBLIC_BACKOFFICE_URL || "";
|
||||
|
||||
async function backofficeRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
||||
const token = localStorage.getItem("token");
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
const response = await fetch(`${BACKOFFICE_URL}${endpoint}`, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.message || `Request failed with status ${response.status}`);
|
||||
}
|
||||
|
||||
if (response.status === 204) {
|
||||
return {} as T;
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export interface DashboardStats {
|
||||
totalCompanies: number;
|
||||
activeSubscriptions: number;
|
||||
monthlyRevenue: number;
|
||||
newCompaniesThisMonth: number;
|
||||
}
|
||||
|
||||
export interface RevenueByMonth {
|
||||
month: string;
|
||||
revenue: number;
|
||||
}
|
||||
|
||||
export interface SubscriptionsByPlan {
|
||||
plan: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface CheckoutSessionRequest {
|
||||
priceId: string;
|
||||
successUrl: string;
|
||||
cancelUrl: string;
|
||||
}
|
||||
|
||||
export interface CheckoutSessionResponse {
|
||||
url: string;
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export const backofficeApi = {
|
||||
// Admin Dashboard
|
||||
admin: {
|
||||
getStats: () => backofficeRequest<DashboardStats>("/admin/stats"),
|
||||
getRevenue: () => backofficeRequest<RevenueByMonth[]>("/admin/revenue"),
|
||||
getSubscriptionsByPlan: () => backofficeRequest<SubscriptionsByPlan[]>("/admin/subscriptions-by-plan"),
|
||||
},
|
||||
// Stripe
|
||||
stripe: {
|
||||
createCheckoutSession: (data: CheckoutSessionRequest) =>
|
||||
backofficeRequest<CheckoutSessionResponse>("/stripe/checkout", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
}),
|
||||
createBillingPortal: (returnUrl: string) =>
|
||||
backofficeRequest<{ url: string }>("/stripe/portal", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ returnUrl }),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue