Download src/components/CreateCaseForm.tsx from sgfw/wz: direct link, hf CLI and curl.
- Browser
- Download file 9.07 kB
-
https://huggingface.co/spaces/sgfw/wz/resolve/main/src/components/CreateCaseForm.tsx
- Command line
-
hf download hf://spaces/sgfw/wz/src/components/CreateCaseForm.tsx
-
curl -L -o CreateCaseForm.tsx https://huggingface.co/spaces/sgfw/wz/resolve/main/src/components/CreateCaseForm.tsx
9.07 kB
| /** | |
| * @license | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import React, { useState } from 'react'; | |
| import { AccountabilityCase, CaseCategory, CreateCaseInput } from '../types'; | |
| import { FilePlus2, X, Plus, AlertCircle } from 'lucide-react'; | |
| interface CreateCaseFormProps { | |
| onClose: () => void; | |
| onSubmit: (newCase: CreateCaseInput) => void; | |
| } | |
| export default function CreateCaseForm({ onClose, onSubmit }: CreateCaseFormProps) { | |
| const [title, setTitle] = useState(''); | |
| const [category, setCategory] = useState<CaseCategory>('asset'); | |
| const [accusedName, setAccusedName] = useState(''); | |
| const [accusedDept, setAccusedDept] = useState(''); | |
| const [accusedPost, setAccusedPost] = useState(''); | |
| const [incidentAmount, setIncidentAmount] = useState<number>(0); | |
| const [description, setDescription] = useState(''); | |
| const [investigationTeamInput, setInvestigationTeamInput] = useState(''); | |
| const [error, setError] = useState(''); | |
| const handleSubmit = (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| if (!title.trim()) return setError('请输入案件名称'); | |
| if (!accusedName.trim()) return setError('请输入被问责人姓名'); | |
| if (!accusedDept.trim()) return setError('请输入被问责人部门'); | |
| if (!accusedPost.trim()) return setError('请输入被问责人职务'); | |
| if (!description.trim()) return setError('请输入违规事实描述'); | |
| const team = investigationTeamInput.split(/[,,\s]+/).filter(Boolean); | |
| if (team.length === 0) { | |
| team.push('王严明', '陈调查'); // 默认调查人 | |
| } | |
| onSubmit({ | |
| title, | |
| category, | |
| accusedName, | |
| accusedDept, | |
| accusedPost, | |
| incidentAmount, | |
| description, | |
| investigationTeam: team, | |
| }); | |
| }; | |
| return ( | |
| <div className="fixed inset-0 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4 z-50 animate-fade-in" id="create-case-modal"> | |
| <div className="bg-white rounded-xl shadow-xl border border-slate-200 w-full max-w-xl overflow-hidden flex flex-col max-h-[90vh]"> | |
| {/* 头部 */} | |
| <div className="bg-slate-900 text-white p-4 flex justify-between items-center"> | |
| <div className="flex items-center gap-2"> | |
| <FilePlus2 className="w-5 h-5 text-blue-400" /> | |
| <h3 className="text-sm font-bold">发起银行内部问责立案</h3> | |
| </div> | |
| <button onClick={onClose} className="text-slate-400 hover:text-white transition-colors cursor-pointer"> | |
| <X className="w-5 h-5" /> | |
| </button> | |
| </div> | |
| {/* 表单体 */} | |
| <form onSubmit={handleSubmit} className="p-6 space-y-4 overflow-y-auto flex-1 text-slate-700 text-xs"> | |
| {error && ( | |
| <div className="bg-red-50 border border-red-200 text-red-700 p-2.5 rounded-lg flex items-center gap-2"> | |
| <AlertCircle className="w-4 h-4 text-red-500 shrink-0" /> | |
| <span>{error}</span> | |
| </div> | |
| )} | |
| {/* 案件基本信息 */} | |
| <div className="space-y-3"> | |
| <div> | |
| <label className="block text-[11px] font-bold text-slate-600 mb-1">案件/违规事由名称 *</label> | |
| <input | |
| type="text" | |
| placeholder="例如:关于某分行违规发放流贷造成损失责任问责案" | |
| value={title} | |
| onChange={(e) => setTitle(e.target.value)} | |
| className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500" | |
| /> | |
| </div> | |
| <div className="grid grid-cols-2 gap-3"> | |
| <div> | |
| <label className="block text-[11px] font-bold text-slate-600 mb-1">案件分类 *</label> | |
| <select | |
| value={category} | |
| onChange={(e) => setCategory(e.target.value as CaseCategory)} | |
| className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg bg-white focus:outline-none focus:border-blue-500" | |
| > | |
| <option value="asset">问题资产问责案 (时限90天)</option> | |
| <option value="non-asset">非问题资产问责案 (时限30工作日)</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label className="block text-[11px] font-bold text-slate-600 mb-1">涉案/事件涉及金额 (万元)</label> | |
| <input | |
| type="number" | |
| placeholder="例如:1200" | |
| value={incidentAmount || ''} | |
| onChange={(e) => setIncidentAmount(Number(e.target.value))} | |
| className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500" | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| {/* 被问责人信息 */} | |
| <div className="bg-slate-50 p-3 rounded-lg border border-slate-100 space-y-3"> | |
| <h4 className="font-bold text-slate-800 border-b border-slate-200 pb-1 flex items-center gap-1"> | |
| 被问责人(责任人)档案信息 | |
| </h4> | |
| <div className="grid grid-cols-3 gap-2"> | |
| <div> | |
| <label className="block text-[10px] text-slate-500 mb-1">姓名 *</label> | |
| <input | |
| type="text" | |
| placeholder="张建国" | |
| value={accusedName} | |
| onChange={(e) => setAccusedName(e.target.value)} | |
| className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-[10px] text-slate-500 mb-1">部门 *</label> | |
| <input | |
| type="text" | |
| placeholder="普惠金融部" | |
| value={accusedDept} | |
| onChange={(e) => setAccusedDept(e.target.value)} | |
| className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500" | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-[10px] text-slate-500 mb-1">职务 *</label> | |
| <input | |
| type="text" | |
| placeholder="高级客户经理" | |
| value={accusedPost} | |
| onChange={(e) => setAccusedPost(e.target.value)} | |
| className="w-full text-xs px-2.5 py-1.5 border border-slate-200 bg-white rounded-md focus:outline-none focus:border-blue-500" | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| {/* 调查组指定 */} | |
| <div> | |
| <label className="block text-[11px] font-bold text-slate-600 mb-1">指定问责调查组成员</label> | |
| <input | |
| type="text" | |
| placeholder="请输入调查人名字,用逗号或空格分隔,例如:王严明, 陈调查" | |
| value={investigationTeamInput} | |
| onChange={(e) => setInvestigationTeamInput(e.target.value)} | |
| className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500" | |
| /> | |
| <p className="text-[10px] text-slate-400 mt-1"> | |
| 留空将自动指定系统合规调查处的资深调查专家:【王严明】、【陈调查】。 | |
| </p> | |
| </div> | |
| {/* 违规事实描述 */} | |
| <div> | |
| <label className="block text-[11px] font-bold text-slate-600 mb-1">违规基本事实与立案审查意见 *</label> | |
| <textarea | |
| rows={4} | |
| placeholder="请详尽输入经审计/风险条线核查出的员工违规操作基本事实。这将被归档入原始立案证据并在后续事实见面、申辩、审理中作为基础依据..." | |
| value={description} | |
| onChange={(e) => setDescription(e.target.value)} | |
| className="w-full text-xs px-3 py-2 border border-slate-200 rounded-lg focus:outline-none focus:border-blue-500 font-sans" | |
| /> | |
| </div> | |
| {/* 底栏按钮 */} | |
| <div className="flex justify-end gap-2 pt-4 border-t border-slate-100"> | |
| <button | |
| type="button" | |
| onClick={onClose} | |
| className="px-4 py-2 border border-slate-200 hover:bg-slate-50 text-slate-700 rounded-lg font-semibold cursor-pointer" | |
| > | |
| 取消 | |
| </button> | |
| <button | |
| type="submit" | |
| className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold shadow-sm flex items-center gap-1.5 cursor-pointer" | |
| > | |
| <Plus className="w-4 h-4" /> | |
| 确认立案并成立调查组 | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| ); | |
| } | |