Files
igny8/site-builder/src/state/builderStore.ts
IGNY8 VPS (Salman) 5a36686844 Add site builder service to Docker Compose and remove obsolete scripts
- Introduced a new service `igny8_site_builder` in `docker-compose.app.yml` for site building functionality, including environment variables and volume mappings.
- Deleted several outdated scripts: `create_test_users.py`, `test_image_write_access.py`, `update_free_plan.py`, and the database file `db.sqlite3` to clean up the backend.
- Updated Django settings and URL configurations to integrate the new site builder module.
2025-11-17 16:08:51 +00:00

157 lines
4.3 KiB
TypeScript

import { create } from 'zustand';
import { builderApi } from '../api/builder.api';
import type {
BuilderFormData,
PageBlueprint,
SiteBlueprint,
StylePreferences,
} from '../types/siteBuilder';
import { useSiteDefinitionStore } from './siteDefinitionStore';
const defaultStyle: StylePreferences = {
palette: 'Vibrant modern palette with rich accent color',
typography: 'Sans-serif display for headings, humanist body font',
personality: 'Confident, energetic, optimistic',
heroImagery: 'Real people interacting with the product/service',
};
const defaultForm: BuilderFormData = {
siteId: null,
sectorId: null,
siteName: '',
businessType: '',
industry: '',
targetAudience: '',
hostingType: 'igny8_sites',
businessBrief: '',
objectives: ['Launch a conversion-focused marketing site'],
style: defaultStyle,
};
interface BuilderState {
form: BuilderFormData;
currentStep: number;
isSubmitting: boolean;
error?: string;
activeBlueprint?: SiteBlueprint;
pages: PageBlueprint[];
setField: <K extends keyof BuilderFormData>(key: K, value: BuilderFormData[K]) => void;
updateStyle: (partial: Partial<StylePreferences>) => void;
addObjective: (value: string) => void;
removeObjective: (index: number) => void;
setStep: (step: number) => void;
nextStep: () => void;
previousStep: () => void;
reset: () => void;
submitWizard: () => Promise<void>;
refreshPages: (blueprintId: number) => Promise<void>;
}
export const useBuilderStore = create<BuilderState>((set, get) => ({
form: defaultForm,
currentStep: 0,
isSubmitting: false,
pages: [],
setField: (key, value) =>
set((state) => ({
form: { ...state.form, [key]: value },
})),
updateStyle: (partial) =>
set((state) => ({
form: { ...state.form, style: { ...state.form.style, ...partial } },
})),
addObjective: (value) =>
set((state) => ({
form: { ...state.form, objectives: [...state.form.objectives, value] },
})),
removeObjective: (index) =>
set((state) => ({
form: {
...state.form,
objectives: state.form.objectives.filter((_, idx) => idx !== index),
},
})),
setStep: (step) => set({ currentStep: step }),
nextStep: () =>
set((state) => ({
currentStep: Math.min(state.currentStep + 1, 3),
})),
previousStep: () =>
set((state) => ({
currentStep: Math.max(state.currentStep - 1, 0),
})),
reset: () =>
set({
form: defaultForm,
currentStep: 0,
isSubmitting: false,
error: undefined,
activeBlueprint: undefined,
pages: [],
}),
submitWizard: async () => {
const { form } = get();
if (!form.siteId || !form.sectorId) {
set({ error: 'Site and sector are required to generate a blueprint.' });
return;
}
set({ isSubmitting: true, error: undefined });
try {
const payload = {
name: form.siteName || `Site Blueprint (${form.industry || 'New'})`,
description: `${form.businessType} for ${form.targetAudience}`,
site_id: form.siteId,
sector_id: form.sectorId,
hosting_type: form.hostingType,
config_json: {
business_type: form.businessType,
industry: form.industry,
target_audience: form.targetAudience,
},
};
const blueprint = await builderApi.createBlueprint(payload);
set({ activeBlueprint: blueprint });
const generation = await builderApi.generateStructure(blueprint.id, {
business_brief: form.businessBrief,
objectives: form.objectives,
style: form.style,
metadata: { targetAudience: form.targetAudience },
});
if (generation?.structure) {
useSiteDefinitionStore.getState().setStructure(generation.structure);
}
await get().refreshPages(blueprint.id);
} catch (error) {
set({ error: error instanceof Error ? error.message : 'Unexpected error' });
} finally {
set({ isSubmitting: false });
}
},
refreshPages: async (blueprintId: number) => {
try {
const pages = await builderApi.listPages(blueprintId);
set({ pages });
useSiteDefinitionStore.getState().setPages(pages);
} catch (error) {
set({ error: error instanceof Error ? error.message : 'Unable to load pages' });
}
},
}));