Files
igny8/frontend/src/services/siteBuilder.api.ts

174 lines
4.6 KiB
TypeScript

/**
* Site Builder API Service
* Uses fetchAPI pattern (not axios) - handles authentication automatically
*/
import { fetchAPI } from './api';
import type {
SiteBlueprint,
PageBlueprint,
SiteStructure,
BuilderFormData,
SiteBuilderMetadata,
} from '../types/siteBuilder';
export interface CreateBlueprintPayload {
name: string;
description?: string;
site_id: number;
sector_id: number;
hosting_type: BuilderFormData['hostingType'];
config_json: Record<string, unknown>;
}
export interface GenerateStructurePayload {
business_brief: string;
objectives: string[];
style: BuilderFormData['style'];
metadata?: Record<string, unknown>;
}
/**
* Site Builder API functions
*/
export const siteBuilderApi = {
/**
* List all site blueprints
*/
async listBlueprints(siteId?: number): Promise<SiteBlueprint[]> {
const params = siteId ? `?site=${siteId}` : '';
const response = await fetchAPI(`/v1/site-builder/blueprints/${params}`);
// Handle paginated response
if (response?.results) {
return response.results as SiteBlueprint[];
}
// Handle direct array response
return Array.isArray(response) ? response : [];
},
/**
* Get a single blueprint by ID
*/
async getBlueprint(id: number): Promise<SiteBlueprint> {
return fetchAPI(`/v1/site-builder/blueprints/${id}/`);
},
/**
* Create a new site blueprint
*/
async createBlueprint(payload: CreateBlueprintPayload): Promise<SiteBlueprint> {
return fetchAPI('/v1/site-builder/blueprints/', {
method: 'POST',
body: JSON.stringify(payload),
});
},
/**
* Generate site structure for a blueprint
*/
async generateStructure(
blueprintId: number,
payload: GenerateStructurePayload,
): Promise<{ task_id?: string; success?: boolean; structure?: SiteStructure }> {
return fetchAPI(`/v1/site-builder/blueprints/${blueprintId}/generate_structure/`, {
method: 'POST',
body: JSON.stringify(payload),
});
},
/**
* List pages for a blueprint
*/
async listPages(blueprintId: number): Promise<PageBlueprint[]> {
const response = await fetchAPI(`/v1/site-builder/pages/?site_blueprint=${blueprintId}`);
// Handle paginated response
if (response?.results) {
return response.results as PageBlueprint[];
}
// Handle direct array response
return Array.isArray(response) ? response : [];
},
/**
* Generate all pages for a blueprint
*/
async generateAllPages(
blueprintId: number,
options?: { pageIds?: number[]; force?: boolean },
): Promise<{ success: boolean; pages_queued: number; task_ids: number[]; celery_task_id?: string }> {
const response = await fetchAPI(`/v1/site-builder/blueprints/${blueprintId}/generate_all_pages/`, {
method: 'POST',
body: JSON.stringify({
page_ids: options?.pageIds,
force: options?.force || false,
}),
});
// Handle unified response format
return response?.data || response;
},
/**
* Create tasks for pages
*/
async createTasksForPages(
blueprintId: number,
pageIds?: number[],
): Promise<{ tasks: unknown[]; count: number }> {
const response = await fetchAPI(`/v1/site-builder/blueprints/${blueprintId}/create_tasks/`, {
method: 'POST',
body: JSON.stringify({
page_ids: pageIds,
}),
});
// Handle unified response format
return response?.data || response;
},
/**
* Load dropdown metadata for wizard fields
*/
async getMetadata(): Promise<SiteBuilderMetadata> {
return fetchAPI('/v1/site-builder/metadata/');
},
/**
* Delete a blueprint
*/
async deleteBlueprint(id: number): Promise<void> {
return fetchAPI(`/v1/site-builder/blueprints/${id}/`, {
method: 'DELETE',
});
},
/**
* Delete a page blueprint
*/
async deletePage(id: number): Promise<void> {
return fetchAPI(`/v1/site-builder/pages/${id}/`, {
method: 'DELETE',
});
},
/**
* Bulk delete blueprints
*/
async bulkDeleteBlueprints(ids: number[]): Promise<{ deleted_count: number }> {
return fetchAPI('/v1/site-builder/blueprints/bulk_delete/', {
method: 'POST',
body: JSON.stringify({ ids }),
});
},
/**
* Deploy a blueprint to Sites renderer
*/
async deployBlueprint(blueprintId: number): Promise<{ success: boolean; deployment_url?: string; deployment_id?: number }> {
// PublisherViewSet is now registered with empty prefix, so URL is /publisher/deploy/{id}/
const response = await fetchAPI(`/v1/publisher/deploy/${blueprintId}/`, {
method: 'POST',
});
// Handle unified response format
return response?.data || response;
},
};