Phase 6
This commit is contained in:
174
frontend/src/pages/Sites/Settings.tsx
Normal file
174
frontend/src/pages/Sites/Settings.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Site Settings
|
||||
* Phase 6: Site Integration & Multi-Destination Publishing
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams, 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 Label from '../../components/form/Label';
|
||||
import SelectDropdown from '../../components/form/SelectDropdown';
|
||||
import Checkbox from '../../components/form/input/Checkbox';
|
||||
import { useToast } from '../../components/ui/toast/ToastContainer';
|
||||
import { fetchAPI } from '../../services/api';
|
||||
|
||||
export default function SiteSettings() {
|
||||
const { siteId } = useParams<{ siteId: string }>();
|
||||
const navigate = useNavigate();
|
||||
const toast = useToast();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [site, setSite] = useState<any>(null);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
slug: '',
|
||||
site_type: 'marketing',
|
||||
hosting_type: 'igny8_sites',
|
||||
is_active: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (siteId) {
|
||||
loadSite();
|
||||
}
|
||||
}, [siteId]);
|
||||
|
||||
const loadSite = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await fetchAPI(`/v1/auth/sites/${siteId}/`);
|
||||
if (data) {
|
||||
setSite(data);
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
slug: data.slug || '',
|
||||
site_type: data.site_type || 'marketing',
|
||||
hosting_type: data.hosting_type || 'igny8_sites',
|
||||
is_active: data.is_active !== false,
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast.error(`Failed to load site: ${error.message}`);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
setSaving(true);
|
||||
await fetchAPI(`/v1/auth/sites/${siteId}/`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
toast.success('Site settings saved successfully');
|
||||
loadSite();
|
||||
} catch (error: any) {
|
||||
toast.error(`Failed to save settings: ${error.message}`);
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const SITE_TYPES = [
|
||||
{ value: 'marketing', label: 'Marketing Site' },
|
||||
{ value: 'ecommerce', label: 'Ecommerce Site' },
|
||||
{ value: 'blog', label: 'Blog' },
|
||||
{ value: 'portfolio', label: 'Portfolio' },
|
||||
{ value: 'corporate', label: 'Corporate' },
|
||||
];
|
||||
|
||||
const HOSTING_TYPES = [
|
||||
{ value: 'igny8_sites', label: 'IGNY8 Sites' },
|
||||
{ value: 'wordpress', label: 'WordPress' },
|
||||
{ value: 'shopify', label: 'Shopify' },
|
||||
{ value: 'multi', label: 'Multi-Destination' },
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<PageMeta title="Site Settings" />
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-gray-500">Loading site settings...</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<PageMeta title="Site Settings - IGNY8" />
|
||||
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
|
||||
Site Settings
|
||||
</h1>
|
||||
<p className="text-gray-600 dark:text-gray-400 mt-1">
|
||||
Configure site type, hosting, and other settings
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<Card className="p-6">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label>Site Name</Label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
className="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md dark:bg-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Slug</Label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData.slug}
|
||||
onChange={(e) => setFormData({ ...formData, slug: e.target.value })}
|
||||
className="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md dark:bg-gray-800 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Site Type</Label>
|
||||
<SelectDropdown
|
||||
options={SITE_TYPES}
|
||||
value={formData.site_type}
|
||||
onChange={(e) => setFormData({ ...formData, site_type: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Hosting Type</Label>
|
||||
<SelectDropdown
|
||||
options={HOSTING_TYPES}
|
||||
value={formData.hosting_type}
|
||||
onChange={(e) => setFormData({ ...formData, hosting_type: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Checkbox
|
||||
checked={formData.is_active}
|
||||
onChange={(e) => setFormData({ ...formData, is_active: e.target.checked })}
|
||||
label="Active"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button onClick={handleSave} variant="primary" disabled={saving}>
|
||||
{saving ? 'Saving...' : 'Save Settings'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user