当前位置: 首页 > news >正文

(sprint)第6天:前端页面开发(评估反馈详情和表单)

昨天的成就

  • 完成评估反馈列表页面
  • 实现搜索、筛选和分页功能
  • 创建评估反馈详情页面
  • 创建评估反馈表单组件
  • 实现问题记录的展示和编辑功能
  • 耗时 :3小时 | 剩余时间 :4天
    遇到的困难
  • 表单验证逻辑复杂
  • 问题记录的动态添加/删除
  • 严重程度的可视化展示
    今天的任务
  1. 开始应急预案列表页面开发
  2. 实现应急预案的搜索和筛选
  3. 创建应急预案表单组件
    代码签入
// app/evaluations/[id]/page.tsx
const EvaluationDetailPage = ({ params }: { params: { 
id: string } }) => {
  const [evaluation, setEvaluation] = 
  useState<EvaluationDetail | null>(null);
  const [problems, setProblems] = useState<Problem[]>
  ([]);  useEffect(() => {
    fetch(`/api/evaluations/${params.id}`)
      .then(res => res.json())
      .then(data => {
        setEvaluation(data.data);
        setProblems(data.data.problems || []);
      });
  }, [params.id]);  const handleAddProblem = () => {
    setProblems(prev => [...prev, { id: Date.now(), 
    description: '', location: '', severity: 
    'medium' }]);
  };  const handleUpdateProblem = (index: number, field: 
  string, value: string) => {
    setProblems(prev => prev.map((p, i) => i === index ? 
    { ...p, [field]: value } : p));
  };  const handleRemoveProblem = (index: number) => {
    setProblems(prev => prev.filter((_, i) => i !== 
    index));
  };  return (
    <div className="space-y-6">
      <div className="bg-card rounded-lg p-6">
        <div className="flex justify-between items-start 
        mb-4">
          <div>
            <h1 className="text-2xl font-bold">
            {evaluation?.plan_name}</h1>
            <p className="text-muted-foreground mt-1">演
            练评估详情</p>
          </div>
          <Badge variant={getStatusVariant(evaluation?.
          status || '')}>
            {getStatusLabel(evaluation?.status || '')}
          </Badge>
        </div>
        
        <div className="space-y-4">
          <div>
            <Label>问题描述</Label>
            <p className="mt-1 text-sm">{evaluation?.
            problem_description}</p>
          </div>
          <div className="grid grid-cols-2 gap-4">
            <div>
              <Label>严重程度</Label>
              <Badge className="mt-1" variant=
              {getSeverityVariant(evaluation?.
              severity || '')}>
                {getSeverityLabel(evaluation?.
                severity || '')}
              </Badge>
            </div>
            <div>
              <Label>创建时间</Label>
              <p className="mt-1 text-sm">{formatDate
              (evaluation?.created_at)}</p>
            </div>
          </div>
        </div>
      </div>      <div className="bg-card rounded-lg p-6">
        <div className="flex justify-between 
        items-center mb-4">
          <h2 className="text-lg font-semibold">问题记录</
          h2>
          <Button size="sm" onClick={handleAddProblem}>
            <Plus className="w-4 h-4" /> 添加问题
          </Button>
        </div>
        
        <div className="space-y-3">
          {problems.map((problem, index) => (
            <div key={problem.id} className="flex gap-4 
            p-4 bg-muted/50 rounded-lg">
              <div className="flex-1 space-y-2">
                <Input
                  placeholder="问题描述"
                  value={problem.description}
                  onChange={(e) => handleUpdateProblem
                  (index, 'description', e.target.value)}
                />
                <div className="grid grid-cols-2 gap-2">
                  <Input
                    placeholder="位置"
                    value={problem.location}
                    onChange={(e) => handleUpdateProblem
                    (index, 'location', e.target.value)}
                  />
                  <Select value={problem.severity} 
                  onChange={(value) => 
                  handleUpdateProblem(index, 'severity', 
                  value)}>
                    <SelectTrigger><SelectValue /></
                    SelectTrigger>
                    <SelectContent>
                      <SelectItem value="low">低</
                      SelectItem>
                      <SelectItem value="medium">中</
                      SelectItem>
                      <SelectItem value="high">高</
                      SelectItem>
                      <SelectItem value="critical">严重</
                      SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
              <Button variant="ghost" size="icon" 
              onClick={() => handleRemoveProblem(index)}>
                <Trash2 className="w-4 h-4" />
              </Button>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};
http://www.jsqmd.com/news/835418/

相关文章:

  • 2026年北美黑胡桃家具工厂,推荐一下北美黑胡桃家具厂,源头北美黑胡桃家具工厂 - 品牌推广大师
  • Claude Code快捷键+指令大全! 13大类速查不用背,从Ctrl+C到多Agent协作一次整理
  • C++ 容器常见问题:emplace_back、push_back、reserve、resize 的区别
  • 2026年论文降AI率教程:专家亲授的去AI痕迹技巧 - 降AI实验室
  • 5.13 项目进度
  • 天下熙熙,皆为利来-----中国是部金融史上读后感
  • OO 作业集 1-3 航班货物配载与载重平衡系统总结博客
  • 开源 WAF 雷池与商业云盾在防护 CC 攻击方面的区别对比?
  • 自主可控新纪元:2026 信创芯片产业全景图
  • 5.12 vue工程化
  • 跑了6家嵌入式培训机构,说说我的真实感受(2026年)
  • 变化检测“假阳性灾难”的突围之路:从 SCanNet v1 到 v6 的实战复盘
  • 2026年4月目前优质的电动葫芦公司推荐,铝合金KBK/安徽电动葫芦/刚性KBK,电动葫芦实力厂家选哪家 - 品牌推荐师
  • 2026年|知网AIGC率高怎么办?亲测6款降AI工具,这款真保住格式!(附对比图) - 降AI实验室
  • 2026年4月优秀的双组份密封胶厂商口碑推荐,聚乙烯闭孔泡沫板/聚硫密封胶/钢边止水带,双组份密封胶品牌口碑推荐 - 品牌推荐师
  • 99.鄂尔多斯报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • 97.桂林报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • 98.肇庆报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • 佛山:报考中质协六西格玛黑带和绿带指定报考机构推荐 - 众智商学院课程中心
  • 服务器感染挖矿病毒后如何彻底清理定时任务与隐藏进程?
  • 全自动太阳能清扫机器人 - GrowthUME
  • 96.阜阳报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • 推荐一个石家庄的旅行社 20年多的老旅行社了-石家庄燕赵旅行社 - 好物推荐官
  • 京郊顺义初夏|一树樱桃红,赴一场京郊田园甜蜜之约 - GrowthUME
  • Vue自定义指令实现点击事件权限拦截控制的npm插件
  • 国补政策2026年最新消息通知:5月第二批国补625亿申领中!618买手机空调电脑家电叠加国补领取入口操作流程一览 - 速递信息
  • 2026年台州黄金回收测评|铂悦名品卖金避坑指南,3家正规品牌实测推荐 - 天天生活分享日志
  • 2026年降AIGC必备指南:实测5款工具,高效降AI,将AI率降至5%以下! - 降AI实验室
  • 2026年榫卯结构家具公司推荐指南/榫卯结构家具生产厂,推荐榫卯结构家具供应,榫卯结构家具生产企业 - 品牌推广大师
  • 让数学公式自动推导