"use client"; import { useState, useEffect } from "react"; import { Input } from "antd"; import { Button } from "@/components/ui/button"; import { CheckOutlined, InfoCircleOutlined } from "@ant-design/icons"; import { Tooltip } from "antd"; import { toast } from "sonner"; interface EditableCellProps { value: number; isEditing: boolean; onEdit: () => void; onSubmit: (value: number) => Promise; onCancel: () => void; t: (key: string, options?: { max?: number }) => string; disabled?: boolean; tooltipText?: string; placeholder?: string; validateValue?: (value: number) => { isValid: boolean; errorMessage?: string; maxValue?: number; }; isPerMsgPrice?: boolean; } export function EditableCell({ value, isEditing, onEdit, onSubmit, onCancel, t, disabled = false, tooltipText, placeholder, validateValue = (value) => ({ isValid: true }), isPerMsgPrice = false, }: EditableCellProps) { const numericValue = typeof value === "number" ? value : Number(value); const originalValue = numericValue >= 0 ? numericValue.toFixed(4) : ""; const [inputValue, setInputValue] = useState(originalValue); const [isSaving, setIsSaving] = useState(false); useEffect(() => { if (isEditing) { setInputValue(originalValue); } }, [isEditing, originalValue]); useEffect(() => { if (isEditing) { const handleClickOutside = (e: MouseEvent) => { const target = e.target as HTMLElement; if (!target.closest(".editable-cell-input")) { onCancel(); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; } }, [isEditing, onCancel]); const handleSubmit = async () => { try { setIsSaving(true); const numValue = Number(inputValue); const validation = validateValue(numValue); if (!validation.isValid) { toast.error(validation.errorMessage || t("error.invalidInput")); return; } if (validation.maxValue !== undefined && numValue > validation.maxValue) { toast.error(t("error.exceedsMaxValue", { max: validation.maxValue })); return; } await onSubmit(numValue); } catch (err) { } finally { setIsSaving(false); } }; return (
{isEditing ? (
setInputValue(e.target.value)} className=" !w-[calc(100%-32px)] !border !border-slate-200 focus:!border-slate-300 !bg-white !shadow-sm hover:!shadow focus:!shadow-md !px-2 !py-1 !h-7 flex-1 !rounded-lg !text-slate-600 !text-sm !font-medium placeholder:!text-slate-400/70 transition-all duration-200 focus:!ring-2 focus:!ring-slate-200/50 focus:!ring-offset-0 " placeholder={placeholder || t("common.enterValue")} onPressEnter={handleSubmit} autoFocus disabled={isSaving} />
) : (
{isPerMsgPrice && numericValue < 0 ? ( {t("common.notSet")} ) : ( <> {numericValue.toFixed(4)} {tooltipText && ( )} )}
)}
); }