Files
igny8/frontend/src/pages/Sites/Builder/steps/BusinessDetailsStep.tsx
2025-11-19 21:56:03 +05:00

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>
);
}