Site-imp1

This commit is contained in:
IGNY8 VPS (Salman)
2025-11-18 04:21:33 +00:00
parent 5552e698be
commit 856b40ed0b
21 changed files with 1110 additions and 1511 deletions

View File

@@ -0,0 +1,108 @@
/**
* Site Builder Blueprints
* Moved from site-builder container to main app
* TODO: Migrate full implementation from site-builder/src/pages/dashboard/
*/
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import PageMeta from '../../../components/common/PageMeta';
import { Card } from '../../../components/ui/card';
import Button from '../../../components/ui/button/Button';
import { useToast } from '../../../components/ui/toast/ToastContainer';
import { fetchAPI } from '../../../services/api';
import { FileText, Plus } from 'lucide-react';
export default function SiteBuilderBlueprints() {
const navigate = useNavigate();
const toast = useToast();
const [blueprints, setBlueprints] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadBlueprints();
}, []);
const loadBlueprints = async () => {
try {
setLoading(true);
const data = await fetchAPI('/v1/site-builder/blueprints/');
if (data?.results) {
setBlueprints(data.results);
} else if (Array.isArray(data)) {
setBlueprints(data);
}
} catch (error: any) {
toast.error(`Failed to load blueprints: ${error.message}`);
} finally {
setLoading(false);
}
};
return (
<div className="p-6">
<PageMeta title="Blueprints - IGNY8" />
<div className="mb-6 flex justify-between items-center">
<div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
Blueprints
</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
View and manage all site blueprints
</p>
</div>
<Button onClick={() => navigate('/sites/builder')} variant="primary">
<Plus className="w-4 h-4 mr-2" />
Create Blueprint
</Button>
</div>
{loading ? (
<div className="flex items-center justify-center h-64">
<div className="text-gray-500">Loading blueprints...</div>
</div>
) : blueprints.length === 0 ? (
<Card className="p-12 text-center">
<FileText className="w-16 h-16 mx-auto mb-4 text-gray-400" />
<p className="text-gray-600 dark:text-gray-400 mb-4">
No blueprints created yet
</p>
<Button onClick={() => navigate('/sites/builder')} variant="primary">
Create Your First Blueprint
</Button>
</Card>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{blueprints.map((blueprint) => (
<Card key={blueprint.id} className="p-4 hover:shadow-lg transition-shadow">
<div className="space-y-3">
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
{blueprint.name}
</h3>
{blueprint.description && (
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
{blueprint.description}
</p>
)}
</div>
<div className="flex items-center justify-between pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="text-xs text-gray-600 dark:text-gray-400">
Status: {blueprint.status}
</div>
<Button
variant="ghost"
size="sm"
onClick={() => navigate(`/sites/${blueprint.site}/editor`)}
>
View
</Button>
</div>
</div>
</Card>
))}
</div>
)}
</div>
);
}

View File

@@ -0,0 +1,44 @@
/**
* Site Builder Preview
* Moved from site-builder container to main app
* TODO: Migrate full implementation from site-builder/src/pages/preview/
*/
import React from 'react';
import { useNavigate } from 'react-router-dom';
import PageMeta from '../../../components/common/PageMeta';
import { Card } from '../../../components/ui/card';
import Button from '../../../components/ui/button/Button';
import { Eye } from 'lucide-react';
export default function SiteBuilderPreview() {
const navigate = useNavigate();
return (
<div className="p-6">
<PageMeta title="Site Preview - IGNY8" />
<div className="mb-6">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
Site Preview
</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
Preview your site during building
</p>
</div>
<Card className="p-12 text-center">
<Eye className="w-16 h-16 mx-auto mb-4 text-gray-400" />
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">
Site Preview
</h2>
<p className="text-gray-600 dark:text-gray-400 mb-6">
The Site Builder preview is being integrated into the main app.
Full implementation coming soon.
</p>
<Button onClick={() => navigate('/sites/builder')} variant="outline">
Back to Builder
</Button>
</Card>
</div>
);
}

View File

@@ -0,0 +1,44 @@
/**
* Site Builder Wizard
* Moved from site-builder container to main app
* TODO: Migrate full implementation from site-builder/src/pages/wizard/
*/
import React from 'react';
import { useNavigate } from 'react-router-dom';
import PageMeta from '../../../components/common/PageMeta';
import { Card } from '../../../components/ui/card';
import Button from '../../../components/ui/button/Button';
import { Wand2 } from 'lucide-react';
export default function SiteBuilderWizard() {
const navigate = useNavigate();
return (
<div className="p-6">
<PageMeta title="Site Builder - IGNY8" />
<div className="mb-6">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
Site Builder
</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
Create a new site using AI-powered wizard
</p>
</div>
<Card className="p-12 text-center">
<Wand2 className="w-16 h-16 mx-auto mb-4 text-gray-400" />
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">
Site Builder Wizard
</h2>
<p className="text-gray-600 dark:text-gray-400 mb-6">
The Site Builder wizard is being integrated into the main app.
Full implementation coming soon.
</p>
<Button onClick={() => navigate('/sites')} variant="outline">
Back to Sites
</Button>
</Card>
</div>
);
}

View File

@@ -114,7 +114,7 @@ export default function SiteContentEditor() {
<p className="text-gray-600 dark:text-gray-400 mb-4">
No site blueprints found for this site
</p>
<Button onClick={() => navigate('/site-builder')} variant="primary">
<Button onClick={() => navigate('/sites/builder')} variant="primary">
Create Site Blueprint
</Button>
</Card>

View File

@@ -5,13 +5,15 @@
*/
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { PlusIcon, EditIcon, SettingsIcon, EyeIcon, TrashIcon, FilterIcon, SearchIcon } from 'lucide-react';
import { PlusIcon, EditIcon, SettingsIcon, EyeIcon, TrashIcon, FilterIcon, SearchIcon, PlugIcon } from 'lucide-react';
import PageMeta from '../../components/common/PageMeta';
import { Card } from '../../components/ui/card';
import Button from '../../components/ui/button/Button';
import SelectDropdown from '../../components/form/SelectDropdown';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { fetchAPI } from '../../services/api';
import SiteTypeBadge from '../../components/sites/SiteTypeBadge';
import Badge from '../../components/ui/badge/Badge';
interface Site {
id: number;
@@ -25,6 +27,7 @@ interface Site {
updated_at: string;
page_count?: number;
integration_count?: number;
has_wordpress_integration?: boolean;
}
export default function SiteList() {
@@ -54,7 +57,24 @@ export default function SiteList() {
setLoading(true);
const data = await fetchAPI('/v1/auth/sites/');
if (data && Array.isArray(data)) {
setSites(data);
// Check for WordPress integrations
const sitesWithIntegrations = await Promise.all(
data.map(async (site: Site) => {
if (site.hosting_type === 'wordpress') {
try {
const integrations = await fetchAPI(`/v1/integration/integrations/?site=${site.id}&platform=wordpress`);
return {
...site,
has_wordpress_integration: integrations?.results?.length > 0 || integrations?.length > 0,
};
} catch {
return { ...site, has_wordpress_integration: false };
}
}
return site;
})
);
setSites(sitesWithIntegrations);
}
} catch (error: any) {
toast.error(`Failed to load sites: ${error.message}`);
@@ -107,7 +127,11 @@ export default function SiteList() {
};
const handleCreateSite = () => {
navigate('/site-builder');
navigate('/sites/builder');
};
const handleIntegration = (siteId: number) => {
navigate(`/sites/${siteId}/settings?tab=integrations`);
};
const handleEdit = (siteId: number) => {

View File

@@ -4,12 +4,14 @@
*/
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { PlusIcon, EditIcon, SettingsIcon, EyeIcon, TrashIcon } from 'lucide-react';
import { PlusIcon, EditIcon, SettingsIcon, EyeIcon, TrashIcon, PlugIcon } from 'lucide-react';
import PageMeta from '../../components/common/PageMeta';
import { Card } from '../../components/ui/card';
import Button from '../../components/ui/button/Button';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { fetchAPI } from '../../services/api';
import SiteTypeBadge from '../../components/sites/SiteTypeBadge';
import Badge from '../../components/ui/badge/Badge';
interface Site {
id: number;
@@ -23,6 +25,7 @@ interface Site {
updated_at: string;
page_count?: number;
integration_count?: number;
has_wordpress_integration?: boolean;
}
export default function SiteManagement() {
@@ -40,7 +43,24 @@ export default function SiteManagement() {
setLoading(true);
const data = await fetchAPI('/v1/auth/sites/');
if (data && Array.isArray(data)) {
setSites(data);
// Check for WordPress integrations
const sitesWithIntegrations = await Promise.all(
data.map(async (site: Site) => {
if (site.hosting_type === 'wordpress') {
try {
const integrations = await fetchAPI(`/v1/integration/integrations/?site=${site.id}&platform=wordpress`);
return {
...site,
has_wordpress_integration: integrations?.results?.length > 0 || integrations?.length > 0,
};
} catch {
return { ...site, has_wordpress_integration: false };
}
}
return site;
})
);
setSites(sitesWithIntegrations);
}
} catch (error: any) {
toast.error(`Failed to load sites: ${error.message}`);
@@ -49,8 +69,12 @@ export default function SiteManagement() {
}
};
const handleIntegration = (siteId: number) => {
navigate(`/sites/${siteId}/settings?tab=integrations`);
};
const handleCreateSite = () => {
navigate('/site-builder');
navigate('/sites/builder');
};
const handleEdit = (siteId: number) => {