'use client' import { useState } from 'react' import { DINGTALK_APPROVAL_NO_MAX_LENGTH, getDingtalkApprovalNoError, } from '@/lib/dingtalk-approval-no' interface TaskReferenceFieldsProps { idPrefix: string taskNo: string onTaskNoChange: (value: string) => void dingtalkApprovalNo: string onDingtalkApprovalNoChange: (value: string) => void taskNoRequired?: boolean disabled?: boolean } function getTaskNoError(value: string): string | null { const normalized = value.trim().toUpperCase() if (!normalized) { return null } return /^TASK\d{12,18}(-\d{2})*$/.test(normalized) ? null : '任务号格式错误' } export default function TaskReferenceFields({ idPrefix, taskNo, onTaskNoChange, dingtalkApprovalNo, onDingtalkApprovalNoChange, taskNoRequired = false, disabled = false, }: TaskReferenceFieldsProps) { const [taskNoTouched, setTaskNoTouched] = useState(false) const [approvalNoTouched, setApprovalNoTouched] = useState(false) const taskNoId = `${idPrefix}-task-no` const taskNoErrorId = `${taskNoId}-error` const approvalNoId = `${idPrefix}-dingtalk-approval-no` const approvalNoErrorId = `${approvalNoId}-error` const taskNoError = getTaskNoError(taskNo) const approvalNoError = getDingtalkApprovalNoError(dingtalkApprovalNo) const visibleTaskNoError = taskNoTouched ? taskNoError : null const visibleApprovalNoError = approvalNoTouched ? approvalNoError : null const inputClassName = 'w-full rounded-apple border border-gray-300 px-4 py-2 outline-none focus:border-gray-900 focus:ring-2 focus:ring-gray-200 disabled:cursor-not-allowed disabled:opacity-60 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:focus:border-gray-400 dark:focus:ring-gray-600' return (
onTaskNoChange(event.target.value.toUpperCase())} onBlur={() => setTaskNoTouched(true)} placeholder="例如:TASK202601030184" className={inputClassName} disabled={disabled} required={taskNoRequired} aria-invalid={Boolean(visibleTaskNoError)} aria-describedby={visibleTaskNoError ? taskNoErrorId : undefined} /> {visibleTaskNoError && (

{visibleTaskNoError}

)}
onDingtalkApprovalNoChange(event.target.value)} onBlur={() => setApprovalNoTouched(true)} placeholder="例如:202508211445000157693" className={inputClassName} disabled={disabled} aria-invalid={Boolean(visibleApprovalNoError)} aria-describedby={visibleApprovalNoError ? approvalNoErrorId : undefined} /> {visibleApprovalNoError && (

{visibleApprovalNoError}

)}
) }