157 lines
4.9 KiB
TypeScript
157 lines
4.9 KiB
TypeScript
/**
|
|
* Step 1: Business Details
|
|
* Site type selection, hosting detection, brand inputs
|
|
*/
|
|
import { useState, useEffect } from 'react';
|
|
import { useBuilderWorkflowStore } from '../../../../store/builderWorkflowStore';
|
|
import { fetchSiteBlueprintById, updateSiteBlueprint, SiteBlueprint } from '../../../../services/api';
|
|
import { Card, CardDescription, CardTitle } from '../../../../components/ui/card';
|
|
import ButtonWithTooltip from '../../../../components/ui/button/ButtonWithTooltip';
|
|
import Input from '../../../../components/ui/input/Input';
|
|
import Alert from '../../../../components/ui/alert/Alert';
|
|
import { Loader2 } from 'lucide-react';
|
|
|
|
interface BusinessDetailsStepProps {
|
|
blueprintId: number;
|
|
}
|
|
|
|
export default function BusinessDetailsStep({ blueprintId }: BusinessDetailsStepProps) {
|
|
const { context, completeStep, loading } = useBuilderWorkflowStore();
|
|
const [blueprint, setBlueprint] = useState<SiteBlueprint | null>(null);
|
|
const [formData, setFormData] = useState({
|
|
name: '',
|
|
description: '',
|
|
hosting_type: 'igny8_sites' as const,
|
|
business_type: '',
|
|
});
|
|
const [saving, setSaving] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
// Load blueprint data
|
|
fetchSiteBlueprintById(blueprintId)
|
|
.then(setBlueprint)
|
|
.catch(err => setError(err.message));
|
|
}, [blueprintId]);
|
|
|
|
useEffect(() => {
|
|
if (blueprint) {
|
|
setFormData({
|
|
name: blueprint.name || '',
|
|
description: blueprint.description || '',
|
|
hosting_type: (blueprint.hosting_type as any) || 'igny8_sites',
|
|
business_type: blueprint.config_json?.business_type || '',
|
|
});
|
|
}
|
|
}, [blueprint]);
|
|
|
|
const handleSave = async () => {
|
|
setSaving(true);
|
|
setError(null);
|
|
try {
|
|
const updated = await updateSiteBlueprint(blueprintId, {
|
|
name: formData.name,
|
|
description: formData.description,
|
|
hosting_type: formData.hosting_type,
|
|
config_json: {
|
|
...blueprint?.config_json,
|
|
business_type: formData.business_type,
|
|
},
|
|
});
|
|
setBlueprint(updated);
|
|
|
|
// Mark step as complete
|
|
await completeStep('business_details', {
|
|
blueprint_name: formData.name,
|
|
hosting_type: formData.hosting_type,
|
|
});
|
|
} catch (err: any) {
|
|
setError(err.message || 'Failed to save business details');
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
const canProceed = formData.name.trim().length > 0;
|
|
|
|
return (
|
|
<Card className="p-6">
|
|
<CardTitle>Business Details</CardTitle>
|
|
<CardDescription>
|
|
Tell us about your business and site type to get started.
|
|
</CardDescription>
|
|
|
|
{error && (
|
|
<Alert variant="error" className="mt-4">
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
<div className="mt-6 space-y-4">
|
|
<div>
|
|
<label className="block text-sm font-medium mb-2">Site Name *</label>
|
|
<Input
|
|
value={formData.name}
|
|
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
placeholder="My Awesome Site"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium mb-2">Description</label>
|
|
<textarea
|
|
value={formData.description}
|
|
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
|
className="w-full px-3 py-2 border rounded-md"
|
|
rows={3}
|
|
placeholder="Brief description of your site..."
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium mb-2">Hosting Type</label>
|
|
<select
|
|
value={formData.hosting_type}
|
|
onChange={(e) => setFormData({ ...formData, hosting_type: e.target.value as any })}
|
|
className="w-full px-3 py-2 border rounded-md"
|
|
>
|
|
<option value="igny8_sites">IGNY8 Sites</option>
|
|
<option value="wordpress">WordPress</option>
|
|
<option value="shopify">Shopify</option>
|
|
<option value="multi">Multiple Destinations</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-6 flex justify-end">
|
|
<ButtonWithTooltip
|
|
onClick={handleSave}
|
|
disabled={!canProceed || saving || loading}
|
|
variant="primary"
|
|
tooltip={
|
|
!canProceed ? 'Please provide a site name to continue' :
|
|
saving ? 'Saving...' :
|
|
loading ? 'Loading...' : undefined
|
|
}
|
|
>
|
|
{saving ? (
|
|
<>
|
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
Saving...
|
|
</>
|
|
) : (
|
|
'Save & Continue'
|
|
)}
|
|
</ButtonWithTooltip>
|
|
</div>
|
|
|
|
{!canProceed && (
|
|
<Alert variant="warning" className="mt-4">
|
|
Please provide a site name to continue.
|
|
</Alert>
|
|
)}
|
|
</Card>
|
|
);
|
|
}
|