87 lines
5.4 KiB
TypeScript
87 lines
5.4 KiB
TypeScript
import React, { useState } from 'react';
|
|
|
|
interface GoalInputFormProps {
|
|
onGeneratePlan: (goal: string, additionalInfo?: string) => void;
|
|
}
|
|
|
|
const GoalInputForm: React.FC<GoalInputFormProps> = ({ onGeneratePlan }) => {
|
|
const [goal, setGoal] = useState('');
|
|
const [additionalInfo, setAdditionalInfo] = useState('');
|
|
const [showAdditional, setShowAdditional] = useState(false);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (goal.trim()) {
|
|
onGeneratePlan(goal.trim(), additionalInfo.trim() || undefined);
|
|
}
|
|
};
|
|
|
|
const handleExampleClick = (exampleGoal: string) => {
|
|
setGoal(exampleGoal);
|
|
onGeneratePlan(exampleGoal);
|
|
};
|
|
|
|
return (
|
|
<div className="bg-white dark:bg-slate-800 p-8 rounded-xl shadow-lg border border-slate-200 dark:border-slate-700 text-center">
|
|
<h2 className="text-2xl font-bold text-slate-800 dark:text-slate-100 mb-2">What's Your Next Big Goal?</h2>
|
|
<p className="text-slate-600 dark:text-slate-400 mb-6">Describe what you want to accomplish, and we'll map out the steps.</p>
|
|
<form onSubmit={handleSubmit}>
|
|
<textarea
|
|
value={goal}
|
|
onChange={(e) => setGoal(e.target.value)}
|
|
placeholder="e.g., Launch a new personal blog about cooking"
|
|
className="w-full p-4 bg-white dark:bg-slate-700 text-slate-900 dark:text-slate-100 border border-slate-300 dark:border-slate-600 rounded-lg mb-2 focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-shadow text-lg placeholder:text-slate-400 dark:placeholder:text-slate-500"
|
|
rows={3}
|
|
/>
|
|
|
|
{/* Toggle additional info */}
|
|
<button
|
|
type="button"
|
|
onClick={() => setShowAdditional(!showAdditional)}
|
|
className="flex items-center gap-1.5 text-sm text-slate-500 dark:text-slate-400 hover:text-green-600 dark:hover:text-green-400 transition-colors mb-2 mx-auto"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" className={`h-4 w-4 transition-transform duration-200 ${showAdditional ? 'rotate-90' : ''}`} fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
|
</svg>
|
|
{showAdditional ? '收起' : 'Import Plan (Markdown)'}
|
|
</button>
|
|
|
|
{showAdditional && (
|
|
<div className="mb-4 animate-in fade-in duration-200">
|
|
<textarea
|
|
value={additionalInfo}
|
|
onChange={(e) => setAdditionalInfo(e.target.value)}
|
|
placeholder={'粘贴从其他 AI 或工具生成的任务计划(支持 Markdown),AI 将据此生成结构化任务列表。\n\n例如:\n## 阶段一:需求分析\n- 用户调研\n- 竞品分析\n\n## 阶段二:开发\n- 前端开发\n- 后端开发'}
|
|
className="w-full p-4 bg-slate-50 dark:bg-slate-700/50 text-slate-900 dark:text-slate-100 border border-slate-200 dark:border-slate-500 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-shadow text-sm placeholder:text-slate-400 dark:placeholder:text-slate-500 font-mono"
|
|
rows={8}
|
|
/>
|
|
{additionalInfo.trim() && (
|
|
<p className="text-xs text-green-600 dark:text-green-400 mt-1">
|
|
✅ Plan imported, AI will generate structured tasks based on it
|
|
</p>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
<button
|
|
type="submit"
|
|
disabled={!goal.trim()}
|
|
className="w-full bg-green-600 text-white font-semibold px-6 py-3 rounded-lg hover:bg-green-700 transition-colors disabled:bg-slate-400 dark:disabled:bg-slate-600 disabled:cursor-not-allowed"
|
|
>
|
|
Generate My Plan
|
|
</button>
|
|
</form>
|
|
<div className="mt-6">
|
|
<p className="text-sm text-slate-500 dark:text-slate-400">Or try an example:</p>
|
|
<div className="flex flex-wrap justify-center gap-2 mt-2">
|
|
<button onClick={() => handleExampleClick('Plan a 2-week backpacking trip through Southeast Asia')} className="text-xs bg-slate-100 dark:bg-slate-700 text-slate-700 dark:text-slate-300 px-3 py-1 rounded-full hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors">Plan a trip</button>
|
|
<button onClick={() => handleExampleClick('Learn to play the guitar in 3 months')} className="text-xs bg-slate-100 dark:bg-slate-700 text-slate-700 dark:text-slate-300 px-3 py-1 rounded-full hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors">Learn a skill</button>
|
|
<button onClick={() => handleExampleClick('Build and launch a simple SaaS product')} className="text-xs bg-slate-100 dark:bg-slate-700 text-slate-700 dark:text-slate-300 px-3 py-1 rounded-full hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors">Launch a product</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default GoalInputForm;
|