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.
This commit is contained in:
156
site-builder/src/state/builderStore.ts
Normal file
156
site-builder/src/state/builderStore.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
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' });
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user