diff --git a/src/pages/WizardPage.tsx b/src/pages/WizardPage.tsx
index b1573c2..5270e10 100644
--- a/src/pages/WizardPage.tsx
+++ b/src/pages/WizardPage.tsx
@@ -10,7 +10,6 @@ import {
Card,
Table,
Select,
- DatePicker,
Tag,
} from '@arco-design/web-react';
import '@arco-design/web-react/dist/css/arco.css';
@@ -18,7 +17,6 @@ import '@arco-design/web-react/dist/css/arco.css';
const { Title, Text } = Typography;
const { TextArea } = Input;
-// Step definitions
const STEPS = [
{ title: '基本信息', description: '项目名称和目标' },
{ title: '章程信息', description: '范围与约束' },
@@ -27,7 +25,6 @@ const STEPS = [
{ title: '完成', description: '确认创建' },
];
-// Types
interface Stakeholder {
key: string;
name: string;
@@ -66,6 +63,123 @@ const createEmptyProject = (): ProjectData => ({
milestones: [],
});
+// --- Extracted sub-components (hooks rules compliant) ---
+
+const StakeholderStep: React.FC<{
+ stakeholders: Stakeholder[];
+ onChange: (s: Stakeholder[]) => void;
+}> = ({ stakeholders, onChange }) => {
+ const [newName, setNewName] = useState('');
+ const [newRole, setNewRole] = useState('');
+ const [newPower, setNewPower] = useState<'高' | '中' | '低'>('中');
+ const [newInterest, setNewInterest] = useState<'高' | '中' | '低'>('中');
+
+ const addStakeholder = () => {
+ if (!newName || !newRole) return;
+ const strategy =
+ newPower === '高' && newInterest === '高'
+ ? '重点管理'
+ : newPower === '低' && newInterest === '高'
+ ? '保持满意'
+ : newPower === '高' && newInterest === '低'
+ ? '随时告知'
+ : '监督';
+ onChange([
+ ...stakeholders,
+ { key: Date.now().toString(), name: newName, role: newRole, power: newPower, interest: newInterest, strategy },
+ ]);
+ setNewName('');
+ setNewRole('');
+ };
+
+ const columns = [
+ { title: '姓名', dataIndex: 'name', key: 'name' },
+ { title: '角色', dataIndex: 'role', key: 'role' },
+ {
+ title: '权力',
+ dataIndex: 'power',
+ key: 'power',
+ render: (val: string) => (
+ {val}
+ ),
+ },
+ {
+ title: '利益/关注度',
+ dataIndex: 'interest',
+ key: 'interest',
+ render: (val: string) => (
+ {val}
+ ),
+ },
+ { title: '参与策略', dataIndex: 'strategy', key: 'strategy' },
+ ];
+
+ return (
+
+ );
+};
+
+const MilestoneStep: React.FC<{
+ milestones: Milestone[];
+ onChange: (m: Milestone[]) => void;
+}> = ({ milestones, onChange }) => {
+ const [newName, setNewName] = useState('');
+ const [newDate, setNewDate] = useState('');
+ const [newDeliverable, setNewDeliverable] = useState('');
+
+ const addMilestone = () => {
+ if (!newName) return;
+ onChange([
+ ...milestones,
+ { key: Date.now().toString(), name: newName, targetDate: newDate, deliverable: newDeliverable },
+ ]);
+ setNewName('');
+ setNewDate('');
+ setNewDeliverable('');
+ };
+
+ const columns = [
+ { title: '里程碑', dataIndex: 'name', key: 'name' },
+ { title: '目标日期', dataIndex: 'targetDate', key: 'targetDate' },
+ { title: '交付物', dataIndex: 'deliverable', key: 'deliverable' },
+ ];
+
+ return (
+
+ );
+};
+
+// --- Main Wizard ---
+
const WizardPage: React.FC = () => {
const [current, setCurrent] = useState(0);
const [project, setProject] = useState(createEmptyProject());
@@ -80,211 +194,114 @@ const WizardPage: React.FC = () => {
console.log('Project created:', project);
};
- // ---- Step 1: Basic Info ----
- const renderBasicInfo = () => (
-
- setProject({ ...project, name: val })}
- />
-
-
-
-
- );
-
- // ---- Step 2: Charter ----
- const renderCharter = () => (
-
-
-
-
-
- setProject({ ...project, constraints: val })}
- />
-
-
- setProject({ ...project, assumptions: val })}
- />
-
-
- );
-
- // ---- Step 3: Stakeholders ----
- const renderStakeholders = () => {
- const columns = [
- { title: '姓名', dataIndex: 'name', key: 'name' },
- { title: '角色', dataIndex: 'role', key: 'role' },
- {
- title: '权力',
- dataIndex: 'power',
- key: 'power',
- render: (val: string) => (
- {val}
- ),
- },
- {
- title: '利益/关注度',
- dataIndex: 'interest',
- key: 'interest',
- render: (val: string) => (
- {val}
- ),
- },
- { title: '参与策略', dataIndex: 'strategy', key: 'strategy' },
- ];
-
- const [newName, setNewName] = useState('');
- const [newRole, setNewRole] = useState('');
- const [newPower, setNewPower] = useState<'高' | '中' | '低'>('中');
- const [newInterest, setNewInterest] = useState<'高' | '中' | '低'>('中');
-
- const addStakeholder = () => {
- if (!newName || !newRole) return;
- const strategy =
- newPower === '高' && newInterest === '高'
- ? '重点管理'
- : newPower === '低' && newInterest === '高'
- ? '保持满意'
- : newPower === '高' && newInterest === '低'
- ? '随时告知'
- : '监督';
- setProject({
- ...project,
- stakeholders: [
- ...project.stakeholders,
- { key: Date.now().toString(), name: newName, role: newRole, power: newPower, interest: newInterest, strategy },
- ],
- });
- setNewName('');
- setNewRole('');
- };
-
- return (
-
- );
+ const renderStep = () => {
+ switch (current) {
+ case 0:
+ return (
+
+ setProject({ ...project, name: val })}
+ />
+
+
+
+
+ );
+ case 1:
+ return (
+
+
+
+
+
+ setProject({ ...project, constraints: val })}
+ />
+
+
+ setProject({ ...project, assumptions: val })}
+ />
+
+
+ );
+ case 2:
+ return (
+ setProject({ ...project, stakeholders: s })}
+ />
+ );
+ case 3:
+ return (
+ setProject({ ...project, milestones: m })}
+ />
+ );
+ case 4:
+ return (
+
+
+
+ 项目名称:
+ {project.name}
+
+
+ 项目目标:
+ {project.goal}
+
+
+ 包含范围:
+ {project.scopeIn}
+
+
+ 干系人数量:
+ {project.stakeholders.length}
+
+
+ 里程碑数量:
+ {project.milestones.length}
+
+ {(!project.name || !project.goal) && (
+
+ ⚠️ 项目名称和目标为必填项
+
+ )}
+
+
+ );
+ default:
+ return null;
+ }
};
- // ---- Step 4: Milestones ----
- const renderMilestones = () => {
- const columns = [
- { title: '里程碑', dataIndex: 'name', key: 'name' },
- { title: '目标日期', dataIndex: 'targetDate', key: 'targetDate' },
- { title: '交付物', dataIndex: 'deliverable', key: 'deliverable' },
- ];
-
- const [newName, setNewName] = useState('');
- const [newDate, setNewDate] = useState('');
- const [newDeliverable, setNewDeliverable] = useState('');
-
- const addMilestone = () => {
- if (!newName) return;
- setProject({
- ...project,
- milestones: [
- ...project.milestones,
- { key: Date.now().toString(), name: newName, targetDate: newDate, deliverable: newDeliverable },
- ],
- });
- setNewName('');
- setNewDate('');
- setNewDeliverable('');
- };
-
- return (
-
- );
- };
-
- // ---- Step 5: Confirm ----
- const renderConfirm = () => (
-
-
-
- 项目名称:
- {project.name}
-
-
- 项目目标:
- {project.goal}
-
-
- 包含范围:
- {project.scopeIn}
-
-
- 干系人数量:
- {project.stakeholders.length}
-
-
- 里程碑数量:
- {project.milestones.length}
-
- {(!project.name || !project.goal) && (
- ⚠️ 项目名称和目标为必填项
- )}
-
-
- );
-
- const stepRenderers = [renderBasicInfo, renderCharter, renderStakeholders, renderMilestones, renderConfirm];
-
return (
@@ -296,7 +313,7 @@ const WizardPage: React.FC = () => {
))}
- {stepRenderers[current]()}
+ {renderStep()}