forked from cardosofelipe/fast-next-template
fix(frontend): Update project wizard with realistic timelines and script shortcut
Per user feedback on #49: - Script: Minutes to 1-2 hours (was 1-2 days) - Simple: 2-3 days (was 1-2 weeks) - Medium: 2-3 weeks (was 1-3 months) - Complex: 2-3 months (was 3-12 months) Also added simplified flow for Scripts: - Scripts skip client mode and autonomy level steps - Go directly from complexity selection to agent chat - Auto-set sensible defaults (auto mode, autonomous) - Dynamic step indicator shows 4 steps for scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,32 +54,36 @@ const complexityOptions = [
|
|||||||
label: 'Script',
|
label: 'Script',
|
||||||
icon: FileCode,
|
icon: FileCode,
|
||||||
description: 'Single-file utilities, automation scripts, CLI tools',
|
description: 'Single-file utilities, automation scripts, CLI tools',
|
||||||
scope: '1-2 days, single file or small module',
|
scope: 'Minutes to 1-2 hours, single file or small module',
|
||||||
examples: 'Data migration script, API integration helper, Build tool plugin',
|
examples: 'Data migration script, API integration helper, Build tool plugin',
|
||||||
|
skipConfig: true, // Scripts skip client mode, autonomy, sprints - just chat with agent
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'simple' as const,
|
id: 'simple' as const,
|
||||||
label: 'Simple',
|
label: 'Simple',
|
||||||
icon: Folder,
|
icon: Folder,
|
||||||
description: 'Small applications with clear requirements',
|
description: 'Small applications with clear requirements',
|
||||||
scope: '1-2 weeks, handful of files/components',
|
scope: '2-3 days, handful of files/components',
|
||||||
examples: 'Landing page, REST API endpoint, Browser extension',
|
examples: 'Landing page, REST API endpoint, Browser extension',
|
||||||
|
skipConfig: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'medium' as const,
|
id: 'medium' as const,
|
||||||
label: 'Medium',
|
label: 'Medium',
|
||||||
icon: Layers,
|
icon: Layers,
|
||||||
description: 'Full applications with multiple features',
|
description: 'Full applications with multiple features',
|
||||||
scope: '1-3 months, multiple modules/services',
|
scope: '2-3 weeks, multiple modules/services',
|
||||||
examples: 'Admin dashboard, E-commerce store, Mobile app',
|
examples: 'Admin dashboard, E-commerce store, Mobile app',
|
||||||
|
skipConfig: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'complex' as const,
|
id: 'complex' as const,
|
||||||
label: 'Complex',
|
label: 'Complex',
|
||||||
icon: Building2,
|
icon: Building2,
|
||||||
description: 'Enterprise systems with many moving parts',
|
description: 'Enterprise systems with many moving parts',
|
||||||
scope: '3-12 months, distributed architecture',
|
scope: '2-3 months, distributed architecture',
|
||||||
examples: 'SaaS platform, Microservices ecosystem, Data pipeline',
|
examples: 'SaaS platform, Microservices ecosystem, Data pipeline',
|
||||||
|
skipConfig: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -157,22 +161,31 @@ const autonomyOptions = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Step indicator component
|
// Step indicator component - dynamic based on complexity
|
||||||
function StepIndicator({ currentStep, totalSteps }: { currentStep: number; totalSteps: number }) {
|
function StepIndicator({
|
||||||
const steps = [
|
currentStep,
|
||||||
'Basic Info',
|
isScriptMode
|
||||||
'Complexity',
|
}: {
|
||||||
'Client Mode',
|
currentStep: number;
|
||||||
'Autonomy',
|
isScriptMode: boolean;
|
||||||
'Agent Chat',
|
}) {
|
||||||
'Review',
|
// Scripts have a simplified 4-step flow
|
||||||
];
|
const scriptSteps = ['Basic Info', 'Complexity', 'Agent Chat', 'Review'];
|
||||||
|
const fullSteps = ['Basic Info', 'Complexity', 'Client Mode', 'Autonomy', 'Agent Chat', 'Review'];
|
||||||
|
|
||||||
|
const steps = isScriptMode ? scriptSteps : fullSteps;
|
||||||
|
const totalSteps = steps.length;
|
||||||
|
|
||||||
|
// Map display step to actual step for scripts
|
||||||
|
const displayStep = isScriptMode && currentStep > 2
|
||||||
|
? (currentStep === 5 ? 3 : currentStep === 6 ? 4 : currentStep)
|
||||||
|
: currentStep;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="mb-2 flex items-center justify-between text-sm text-muted-foreground">
|
<div className="mb-2 flex items-center justify-between text-sm text-muted-foreground">
|
||||||
<span>Step {currentStep} of {totalSteps}</span>
|
<span>Step {displayStep} of {totalSteps}</span>
|
||||||
<span>{steps[currentStep - 1]}</span>
|
<span>{steps[displayStep - 1]}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
{Array.from({ length: totalSteps }, (_, i) => (
|
{Array.from({ length: totalSteps }, (_, i) => (
|
||||||
@@ -180,9 +193,9 @@ function StepIndicator({ currentStep, totalSteps }: { currentStep: number; total
|
|||||||
key={i}
|
key={i}
|
||||||
className={cn(
|
className={cn(
|
||||||
'h-2 flex-1 rounded-full transition-colors',
|
'h-2 flex-1 rounded-full transition-colors',
|
||||||
i + 1 < currentStep
|
i + 1 < displayStep
|
||||||
? 'bg-primary'
|
? 'bg-primary'
|
||||||
: i + 1 === currentStep
|
: i + 1 === displayStep
|
||||||
? 'bg-primary/70'
|
? 'bg-primary/70'
|
||||||
: 'bg-muted'
|
: 'bg-muted'
|
||||||
)}
|
)}
|
||||||
@@ -329,6 +342,11 @@ function ComplexityStep({
|
|||||||
<p className="mt-1 text-muted-foreground">
|
<p className="mt-1 text-muted-foreground">
|
||||||
How complex is your project? This helps us assign the right resources.
|
How complex is your project? This helps us assign the right resources.
|
||||||
</p>
|
</p>
|
||||||
|
{state.complexity === 'script' && (
|
||||||
|
<p className="mt-2 text-sm text-primary">
|
||||||
|
Scripts use a simplified flow - you'll skip to agent chat directly.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-4 md:grid-cols-2">
|
<div className="grid gap-4 md:grid-cols-2">
|
||||||
@@ -861,7 +879,12 @@ export default function ProjectWizardPrototype() {
|
|||||||
const [isCreating, setIsCreating] = useState(false);
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
const [isCreated, setIsCreated] = useState(false);
|
const [isCreated, setIsCreated] = useState(false);
|
||||||
|
|
||||||
const totalSteps = 6;
|
// Check if script mode is active (simplified flow)
|
||||||
|
const isScriptMode = state.complexity === 'script';
|
||||||
|
|
||||||
|
// For scripts: steps are 1, 2, 5, 6 (skip 3 and 4)
|
||||||
|
// For others: steps are 1, 2, 3, 4, 5, 6
|
||||||
|
const getLastStep = () => (isScriptMode ? 6 : 6);
|
||||||
|
|
||||||
const updateState = (updates: Partial<WizardState>) => {
|
const updateState = (updates: Partial<WizardState>) => {
|
||||||
setState((prev) => ({ ...prev, ...updates }));
|
setState((prev) => ({ ...prev, ...updates }));
|
||||||
@@ -874,9 +897,9 @@ export default function ProjectWizardPrototype() {
|
|||||||
case 2:
|
case 2:
|
||||||
return state.complexity !== null;
|
return state.complexity !== null;
|
||||||
case 3:
|
case 3:
|
||||||
return state.clientMode !== null;
|
return isScriptMode || state.clientMode !== null;
|
||||||
case 4:
|
case 4:
|
||||||
return state.autonomyLevel !== null;
|
return isScriptMode || state.autonomyLevel !== null;
|
||||||
case 5:
|
case 5:
|
||||||
return true; // Agent chat is preview only
|
return true; // Agent chat is preview only
|
||||||
case 6:
|
case 6:
|
||||||
@@ -887,14 +910,37 @@ export default function ProjectWizardPrototype() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const goNext = () => {
|
const goNext = () => {
|
||||||
if (state.step < totalSteps && canProceed()) {
|
if (canProceed()) {
|
||||||
updateState({ step: state.step + 1 });
|
let nextStep = state.step + 1;
|
||||||
|
|
||||||
|
// For scripts, skip from step 2 directly to step 5 (agent chat)
|
||||||
|
if (isScriptMode && state.step === 2) {
|
||||||
|
nextStep = 5;
|
||||||
|
// Auto-set defaults for skipped steps
|
||||||
|
updateState({
|
||||||
|
step: nextStep,
|
||||||
|
clientMode: 'auto',
|
||||||
|
autonomyLevel: 'autonomous',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextStep <= getLastStep()) {
|
||||||
|
updateState({ step: nextStep });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
if (state.step > 1) {
|
if (state.step > 1) {
|
||||||
updateState({ step: state.step - 1 });
|
let prevStep = state.step - 1;
|
||||||
|
|
||||||
|
// For scripts, go from step 5 back to step 2
|
||||||
|
if (isScriptMode && state.step === 5) {
|
||||||
|
prevStep = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState({ step: prevStep });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -959,7 +1005,7 @@ export default function ProjectWizardPrototype() {
|
|||||||
<div className="mx-auto max-w-3xl">
|
<div className="mx-auto max-w-3xl">
|
||||||
{/* Step Indicator */}
|
{/* Step Indicator */}
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
<StepIndicator currentStep={state.step} totalSteps={totalSteps} />
|
<StepIndicator currentStep={state.step} isScriptMode={isScriptMode} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Step Content */}
|
{/* Step Content */}
|
||||||
@@ -987,7 +1033,7 @@ export default function ProjectWizardPrototype() {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{state.step < totalSteps ? (
|
{state.step < 6 ? (
|
||||||
<Button onClick={goNext} disabled={!canProceed()}>
|
<Button onClick={goNext} disabled={!canProceed()}>
|
||||||
Next
|
Next
|
||||||
<ArrowRight className="ml-2 h-4 w-4" />
|
<ArrowRight className="ml-2 h-4 w-4" />
|
||||||
|
|||||||
Reference in New Issue
Block a user