107 lines
3.0 KiB
TypeScript
107 lines
3.0 KiB
TypeScript
import { fetchWithAuth } from "./client";
|
|
|
|
function buildQuery(params: Record<string, string | number | boolean | undefined>): string {
|
|
const qs = Object.entries(params)
|
|
.filter(([, v]) => v !== undefined)
|
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
|
|
.join("&");
|
|
return qs ? `?${qs}` : "";
|
|
}
|
|
|
|
export interface Competitor {
|
|
id: string;
|
|
brand_id: string;
|
|
name: string;
|
|
aliases?: string[];
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface CompetitorListResponse {
|
|
items: Competitor[];
|
|
total: number;
|
|
}
|
|
|
|
export interface AddCompetitorRequest {
|
|
name: string;
|
|
}
|
|
|
|
export interface CompetitorRecommendation {
|
|
id: string;
|
|
name: string;
|
|
reason: string;
|
|
}
|
|
|
|
export interface CompetitorAnalysisRequest {
|
|
brand_id: string;
|
|
competitor_id: string;
|
|
analysis_type: string;
|
|
}
|
|
|
|
export interface CompetitorInsight {
|
|
id: string;
|
|
brand_id: string;
|
|
insight_type: string;
|
|
competitor_name: string | null;
|
|
data: Record<string, unknown>;
|
|
recommendations: string[] | null;
|
|
period_start: string | null;
|
|
period_end: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface CompetitorInsightList {
|
|
items: CompetitorInsight[];
|
|
total: number;
|
|
}
|
|
|
|
export interface CompetitorInsightDetail extends CompetitorInsight {}
|
|
|
|
export interface CompetitorGapSummary {
|
|
competitor_name: string;
|
|
gap_score: number;
|
|
dimensions: Record<string, unknown>;
|
|
}
|
|
|
|
export const competitorApi = {
|
|
list: (token: string, brandId: string, params?: { skip?: number; limit?: number }) =>
|
|
fetchWithAuth(
|
|
`/api/v1/brands/${brandId}/competitors/${buildQuery(params || {})}`,
|
|
{},
|
|
token
|
|
) as Promise<CompetitorListResponse>,
|
|
|
|
add: (token: string, brandId: string, data: AddCompetitorRequest) =>
|
|
fetchWithAuth(`/api/v1/brands/${brandId}/competitors/`, {
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
}, token) as Promise<Competitor>,
|
|
|
|
delete: (token: string, brandId: string, competitorId: string) =>
|
|
fetchWithAuth(`/api/v1/brands/${brandId}/competitors/${competitorId}/`, {
|
|
method: "DELETE",
|
|
}, token) as Promise<void>,
|
|
|
|
getRecommendations: (token: string, brandId: string) =>
|
|
fetchWithAuth(`/api/v1/brands/${brandId}/competitors/recommendations/`, {}, token) as Promise<CompetitorRecommendation[]>,
|
|
|
|
analyze: (token: string, data: CompetitorAnalysisRequest) =>
|
|
fetchWithAuth("/api/v1/competitor/analyze", {
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
}, token) as Promise<CompetitorInsightList>,
|
|
|
|
getBrandInsights: (token: string, brandId: string, params?: { skip?: number; limit?: number }) =>
|
|
fetchWithAuth(
|
|
`/api/v1/competitor/brand/${brandId}${buildQuery(params || {})}`,
|
|
{},
|
|
token
|
|
) as Promise<CompetitorInsightList>,
|
|
|
|
getInsight: (token: string, insightId: string) =>
|
|
fetchWithAuth(`/api/v1/competitor/${insightId}`, {}, token) as Promise<CompetitorInsightDetail>,
|
|
|
|
getGapSummary: (token: string, brandId: string) =>
|
|
fetchWithAuth(`/api/v1/competitor/brand/${brandId}/gap-summary`, {}, token) as Promise<CompetitorGapSummary[]>,
|
|
};
|