diff --git a/backend/celerybeat-schedule b/backend/celerybeat-schedule
index f7b27e35..741a7355 100644
Binary files a/backend/celerybeat-schedule and b/backend/celerybeat-schedule differ
diff --git a/frontend/src/components/integration/PlatformSelector.tsx b/frontend/src/components/integration/PlatformSelector.tsx
index 8128fc59..85631413 100644
--- a/frontend/src/components/integration/PlatformSelector.tsx
+++ b/frontend/src/components/integration/PlatformSelector.tsx
@@ -22,7 +22,7 @@ export default function PlatformSelector({ value, onChange, disabled }: Platform
onChange(e.target.value)}
+ onChange={(optionValue) => onChange(optionValue)}
disabled={disabled}
placeholder="Select platform"
/>
diff --git a/frontend/src/components/publishing/PublishingRules.tsx b/frontend/src/components/publishing/PublishingRules.tsx
index a98da0fd..39a16777 100644
--- a/frontend/src/components/publishing/PublishingRules.tsx
+++ b/frontend/src/components/publishing/PublishingRules.tsx
@@ -142,8 +142,8 @@ export default function PublishingRules({ rules, onChange }: PublishingRulesProp
- handleUpdateRule(rule.id, 'content_type', e.target.value)
+ onChange={(value) =>
+ handleUpdateRule(rule.id, 'content_type', value)
}
/>
@@ -153,8 +153,8 @@ export default function PublishingRules({ rules, onChange }: PublishingRulesProp
- handleUpdateRule(rule.id, 'trigger', e.target.value)
+ onChange={(value) =>
+ handleUpdateRule(rule.id, 'trigger', value)
}
/>
diff --git a/frontend/src/components/sites/TemplateCustomizer.tsx b/frontend/src/components/sites/TemplateCustomizer.tsx
index 0d855a5e..4d74e571 100644
--- a/frontend/src/components/sites/TemplateCustomizer.tsx
+++ b/frontend/src/components/sites/TemplateCustomizer.tsx
@@ -133,7 +133,7 @@ export default function TemplateCustomizer({
{ value: 'fullwidth', label: 'Full Width' },
]}
value={customization.layout}
- onChange={(e) => updateCustomization({ layout: e.target.value })}
+ onChange={(value) => updateCustomization({ layout: value })}
/>
@@ -147,7 +147,7 @@ export default function TemplateCustomizer({
{ value: 'minimal', label: 'Minimal' },
]}
value={customization.headerStyle}
- onChange={(e) => updateCustomization({ headerStyle: e.target.value })}
+ onChange={(value) => updateCustomization({ headerStyle: value })}
/>
@@ -161,7 +161,7 @@ export default function TemplateCustomizer({
{ value: 'none', label: 'No Footer' },
]}
value={customization.footerStyle}
- onChange={(e) => updateCustomization({ footerStyle: e.target.value })}
+ onChange={(value) => updateCustomization({ footerStyle: value })}
/>
@@ -175,7 +175,7 @@ export default function TemplateCustomizer({
{ value: 'none', label: 'No Sidebar' },
]}
value={customization.sidebarPosition}
- onChange={(e) => updateCustomization({ sidebarPosition: e.target.value as 'left' | 'right' | 'none' })}
+ onChange={(value) => updateCustomization({ sidebarPosition: value as 'left' | 'right' | 'none' })}
/>
)}
@@ -196,7 +196,7 @@ export default function TemplateCustomizer({
{ value: 'auto', label: 'Auto (System)' },
]}
value={customization.colorScheme}
- onChange={(e) => updateCustomization({ colorScheme: e.target.value })}
+ onChange={(value) => updateCustomization({ colorScheme: value })}
/>
@@ -271,7 +271,7 @@ export default function TemplateCustomizer({
{ value: 'custom', label: 'Custom' },
]}
value={customization.typography}
- onChange={(e) => updateCustomization({ typography: e.target.value })}
+ onChange={(value) => updateCustomization({ typography: value })}
/>
@@ -285,9 +285,9 @@ export default function TemplateCustomizer({
{ value: 'xlarge', label: 'Extra Large' },
]}
value={customization.customStyles?.headingSize || 'medium'}
- onChange={(e) =>
+ onChange={(value) =>
updateCustomization({
- customStyles: { ...customization.customStyles, headingSize: e.target.value },
+ customStyles: { ...customization.customStyles, headingSize: value },
})
}
/>
@@ -302,9 +302,9 @@ export default function TemplateCustomizer({
{ value: 'large', label: 'Large (18px)' },
]}
value={customization.customStyles?.bodySize || 'medium'}
- onChange={(e) =>
+ onChange={(value) =>
updateCustomization({
- customStyles: { ...customization.customStyles, bodySize: e.target.value },
+ customStyles: { ...customization.customStyles, bodySize: value },
})
}
/>
@@ -327,7 +327,7 @@ export default function TemplateCustomizer({
{ value: 'spacious', label: 'Spacious' },
]}
value={customization.spacing}
- onChange={(e) => updateCustomization({ spacing: e.target.value })}
+ onChange={(value) => updateCustomization({ spacing: value })}
/>
@@ -341,9 +341,9 @@ export default function TemplateCustomizer({
{ value: 'large', label: 'Large' },
]}
value={customization.customStyles?.sectionPadding || 'medium'}
- onChange={(e) =>
+ onChange={(value) =>
updateCustomization({
- customStyles: { ...customization.customStyles, sectionPadding: e.target.value },
+ customStyles: { ...customization.customStyles, sectionPadding: value },
})
}
/>
@@ -360,9 +360,9 @@ export default function TemplateCustomizer({
{ value: 'full', label: 'Full Width' },
]}
value={customization.customStyles?.containerWidth || 'lg'}
- onChange={(e) =>
+ onChange={(value) =>
updateCustomization({
- customStyles: { ...customization.customStyles, containerWidth: e.target.value },
+ customStyles: { ...customization.customStyles, containerWidth: value },
})
}
/>
diff --git a/frontend/src/components/sites/WordPressIntegrationCard.tsx b/frontend/src/components/sites/WordPressIntegrationCard.tsx
index 04323f84..19991aee 100644
--- a/frontend/src/components/sites/WordPressIntegrationCard.tsx
+++ b/frontend/src/components/sites/WordPressIntegrationCard.tsx
@@ -17,8 +17,7 @@ interface WordPressIntegration {
sync_status: 'success' | 'failed' | 'pending';
last_sync_at?: string;
config_json?: {
- url?: string;
- username?: string;
+ site_url?: string;
};
}
@@ -75,7 +74,7 @@ export default function WordPressIntegrationCard({
WordPress Integration
- {integration.config_json?.url || 'WordPress Site'}
+ {integration.config_json?.site_url || 'WordPress Site'}
diff --git a/frontend/src/components/sites/WordPressIntegrationModal.tsx b/frontend/src/components/sites/WordPressIntegrationModal.tsx
index 46343c7e..8548f728 100644
--- a/frontend/src/components/sites/WordPressIntegrationModal.tsx
+++ b/frontend/src/components/sites/WordPressIntegrationModal.tsx
@@ -4,10 +4,10 @@
*/
import React, { useState } from 'react';
import { X, Globe, AlertCircle } from 'lucide-react';
-import Modal from '../ui/modal/Modal';
+import { Modal } from '../ui/modal';
import Button from '../ui/button/Button';
import Label from '../form/Label';
-import Input from '../form/input/Input';
+import Input from '../form/input/InputField';
import Checkbox from '../form/input/Checkbox';
import { useToast } from '../ui/toast/ToastContainer';
diff --git a/frontend/src/pages/Sites/Editor.tsx b/frontend/src/pages/Sites/Editor.tsx
index fd9f0cbd..a74a0b28 100644
--- a/frontend/src/pages/Sites/Editor.tsx
+++ b/frontend/src/pages/Sites/Editor.tsx
@@ -144,7 +144,7 @@ export default function SiteContentEditor() {
No pages found in this blueprint
-
-
navigate('/sites/manage')} variant="outline">
-
- Site Management
-
navigate('/sites/builder')} variant="outline">
Create with Builder
@@ -583,7 +579,7 @@ export default function SiteList() {
setSiteTypeFilter(e.target.value)}
+ onChange={(value) => setSiteTypeFilter(value)}
/>
@@ -595,7 +591,7 @@ export default function SiteList() {
setHostingTypeFilter(e.target.value)}
+ onChange={(value) => setHostingTypeFilter(value)}
/>
@@ -607,7 +603,7 @@ export default function SiteList() {
setStatusFilter(e.target.value)}
+ onChange={(value) => setStatusFilter(value)}
/>
@@ -619,7 +615,7 @@ export default function SiteList() {
setIntegrationFilter(e.target.value)}
+ onChange={(value) => setIntegrationFilter(value)}
/>
@@ -738,19 +734,21 @@ export default function SiteList() {
variant="outline"
size="sm"
onClick={() => handleSettings(site.id)}
- className="shadow-theme-xs inline-flex h-9 w-9 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400"
+ className="shadow-theme-xs inline-flex h-9 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400 px-3"
title="Configure Sectors"
>
-
+
+ Sectors
navigate(`/sites/${site.id}/settings`)}
- className="shadow-theme-xs inline-flex h-9 w-9 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400"
+ className="shadow-theme-xs inline-flex h-9 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400 px-3"
title="Site Settings"
>
-
+
+ Settings
setContent({ ...content, content_type: e.target.value })}
+ onChange={(value) => setContent({ ...content, content_type: value })}
/>
@@ -336,7 +336,7 @@ export default function PostEditor() {
setContent({ ...content, status: e.target.value })}
+ onChange={(value) => setContent({ ...content, status: value })}
/>
diff --git a/frontend/src/pages/Sites/Settings.tsx b/frontend/src/pages/Sites/Settings.tsx
index 0b910ab8..9a0ecd57 100644
--- a/frontend/src/pages/Sites/Settings.tsx
+++ b/frontend/src/pages/Sites/Settings.tsx
@@ -225,7 +225,10 @@ export default function SiteSettings() {
setActiveTab('general')}
+ onClick={() => {
+ setActiveTab('general');
+ navigate(`/sites/${siteId}/settings`, { replace: true });
+ }}
className={`px-4 py-2 font-medium border-b-2 transition-colors ${
activeTab === 'general'
? 'border-brand-500 text-brand-600 dark:text-brand-400'
@@ -237,7 +240,10 @@ export default function SiteSettings() {
setActiveTab('seo')}
+ onClick={() => {
+ setActiveTab('seo');
+ navigate(`/sites/${siteId}/settings?tab=seo`, { replace: true });
+ }}
className={`px-4 py-2 font-medium border-b-2 transition-colors ${
activeTab === 'seo'
? 'border-brand-500 text-brand-600 dark:text-brand-400'
@@ -249,7 +255,10 @@ export default function SiteSettings() {
setActiveTab('og')}
+ onClick={() => {
+ setActiveTab('og');
+ navigate(`/sites/${siteId}/settings?tab=og`, { replace: true });
+ }}
className={`px-4 py-2 font-medium border-b-2 transition-colors ${
activeTab === 'og'
? 'border-brand-500 text-brand-600 dark:text-brand-400'
@@ -261,7 +270,10 @@ export default function SiteSettings() {
setActiveTab('schema')}
+ onClick={() => {
+ setActiveTab('schema');
+ navigate(`/sites/${siteId}/settings?tab=schema`, { replace: true });
+ }}
className={`px-4 py-2 font-medium border-b-2 transition-colors ${
activeTab === 'schema'
? 'border-brand-500 text-brand-600 dark:text-brand-400'
@@ -273,7 +285,10 @@ export default function SiteSettings() {
setActiveTab('integrations')}
+ onClick={() => {
+ setActiveTab('integrations');
+ navigate(`/sites/${siteId}/settings?tab=integrations`, { replace: true });
+ }}
className={`px-4 py-2 font-medium border-b-2 transition-colors ${
activeTab === 'integrations'
? 'border-brand-500 text-brand-600 dark:text-brand-400'
@@ -316,7 +331,7 @@ export default function SiteSettings() {
setFormData({ ...formData, site_type: e.target.value })}
+ onChange={(value) => setFormData({ ...formData, site_type: value })}
/>
@@ -325,7 +340,7 @@ export default function SiteSettings() {
setFormData({ ...formData, hosting_type: e.target.value })}
+ onChange={(value) => setFormData({ ...formData, hosting_type: value })}
/>
@@ -572,8 +587,8 @@ export default function SiteSettings() {
initialData={
wordPressIntegration
? {
- url: wordPressIntegration.config_json?.url || '',
- username: wordPressIntegration.config_json?.username || '',
+ url: wordPressIntegration.config_json?.site_url || '',
+ username: wordPressIntegration.credentials_json?.username || '',
app_password: '', // Never show password
is_active: wordPressIntegration.is_active,
sync_enabled: wordPressIntegration.sync_enabled,
diff --git a/frontend/src/services/integration.api.ts b/frontend/src/services/integration.api.ts
index 4d64382b..5533a18f 100644
--- a/frontend/src/services/integration.api.ts
+++ b/frontend/src/services/integration.api.ts
@@ -10,6 +10,7 @@ export interface SiteIntegration {
platform: 'wordpress' | 'shopify' | 'custom';
platform_type: 'cms' | 'ecommerce' | 'custom_api';
config_json: Record;
+ credentials_json?: Record;
is_active: boolean;
sync_enabled: boolean;
last_sync_at?: string;
@@ -23,7 +24,7 @@ export interface CreateIntegrationData {
platform: 'wordpress' | 'shopify' | 'custom';
platform_type?: 'cms' | 'ecommerce' | 'custom_api';
config_json: Record;
- credentials?: Record;
+ credentials_json?: Record;
is_active?: boolean;
sync_enabled?: boolean;
}
@@ -126,10 +127,10 @@ export const integrationApi = {
platform: 'wordpress',
platform_type: 'cms',
config_json: {
- url: data.url,
- username: data.username,
+ site_url: data.url,
},
- credentials: {
+ credentials_json: {
+ username: data.username,
app_password: data.app_password,
},
is_active: data.is_active ?? true,
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 61507973..331232a5 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -120,6 +120,8 @@ export default defineConfig(({ mode, command }) => {
"zustand/middleware", // Required for persist middleware used in stores
// Include apexcharts for proper module resolution (skip during marketing-only build)
...(isMarketingBuild ? [] : ["apexcharts", "react-apexcharts"]),
+ // Force include fast-deep-equal for react-dnd compatibility
+ "fast-deep-equal",
],
// Exclude heavy dependencies that are only used in specific pages
// They will be lazy-loaded when needed
@@ -132,8 +134,6 @@ export default defineConfig(({ mode, command }) => {
"@fullcalendar/timegrid",
"@react-jvectormap/core",
"@react-jvectormap/world",
- "react-dnd",
- "react-dnd-html5-backend",
"swiper",
],
esbuildOptions: {