126 lines
4.4 KiB
TypeScript
126 lines
4.4 KiB
TypeScript
|
|
import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||
|
|
import UsernameAutocomplete from './UsernameAutocomplete';
|
||
|
|
|
||
|
|
interface SubmissionFormProps {
|
||
|
|
username: string;
|
||
|
|
setUsername: (value: string) => void;
|
||
|
|
geIdAndLang: string;
|
||
|
|
setGeIdAndLang: (value: string) => void;
|
||
|
|
handleSubmit: (e: React.FormEvent) => void;
|
||
|
|
onManageUserClick: () => void;
|
||
|
|
onViewInfoClick?: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
const SubmissionForm: React.FC<SubmissionFormProps> = ({
|
||
|
|
username,
|
||
|
|
setUsername,
|
||
|
|
geIdAndLang,
|
||
|
|
setGeIdAndLang,
|
||
|
|
handleSubmit,
|
||
|
|
onManageUserClick,
|
||
|
|
onViewInfoClick,
|
||
|
|
}) => {
|
||
|
|
const geIdAndLangRef = useRef<HTMLTextAreaElement>(null);
|
||
|
|
const [usernameHeight, setUsernameHeight] = useState<number | null>(null);
|
||
|
|
|
||
|
|
// Memoize callbacks to prevent unnecessary re-renders
|
||
|
|
const handleUsernameChange = useCallback((value: string) => {
|
||
|
|
setUsername(value);
|
||
|
|
}, [setUsername]);
|
||
|
|
|
||
|
|
const handleUserSelect = useCallback((user: string) => {
|
||
|
|
setUsername(user);
|
||
|
|
}, [setUsername]);
|
||
|
|
|
||
|
|
const handleHeightChange = useCallback((h: number) => {
|
||
|
|
setUsernameHeight(h);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const handleGeIdAndLangChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||
|
|
setGeIdAndLang(e.target.value);
|
||
|
|
}, [setGeIdAndLang]);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const geIdAndLangEl = geIdAndLangRef.current;
|
||
|
|
|
||
|
|
if (!geIdAndLangEl) return;
|
||
|
|
|
||
|
|
const observer = new ResizeObserver(entries => {
|
||
|
|
window.requestAnimationFrame(() => {
|
||
|
|
if (!entries.length) return;
|
||
|
|
|
||
|
|
const newHeightPx = `${(entries[0].target as HTMLElement).offsetHeight}px`;
|
||
|
|
|
||
|
|
if (geIdAndLangEl.style.height !== newHeightPx) {
|
||
|
|
geIdAndLangEl.style.height = newHeightPx;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
observer.observe(geIdAndLangEl);
|
||
|
|
|
||
|
|
return () => observer.disconnect();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<form onSubmit={handleSubmit}>
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
||
|
|
<div>
|
||
|
|
<UsernameAutocomplete
|
||
|
|
value={username}
|
||
|
|
onChange={handleUsernameChange}
|
||
|
|
onUserSelect={handleUserSelect}
|
||
|
|
disabled={false}
|
||
|
|
placeholder="DKI_공통_PTrinh(L)
|
||
|
|
DKI_공통_Amii(DM)"
|
||
|
|
rows={5}
|
||
|
|
onHeightChange={handleHeightChange}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<textarea
|
||
|
|
ref={geIdAndLangRef}
|
||
|
|
id="geIdAndLang"
|
||
|
|
value={geIdAndLang}
|
||
|
|
onChange={handleGeIdAndLangChange}
|
||
|
|
className="bg-slate-900/50 border border-slate-700 text-slate-100 text-sm rounded-lg focus:ring-indigo-500 focus:border-indigo-500 block w-full p-2.5 transition-colors duration-200 resize-y min-h-32"
|
||
|
|
placeholder="1000 de
|
||
|
|
696 us f"
|
||
|
|
rows={5}
|
||
|
|
style={usernameHeight ? { height: `${usernameHeight}px` } : undefined}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div className="flex justify-between items-center">
|
||
|
|
<div className="flex items-center gap-4">
|
||
|
|
<button
|
||
|
|
type="submit"
|
||
|
|
className="flex justify-center items-center text-white bg-indigo-600 hover:bg-indigo-700 focus:ring-4 focus:outline-none focus:ring-indigo-800 font-medium rounded-lg text-sm px-5 py-3 text-center transition-all duration-200"
|
||
|
|
>
|
||
|
|
Cấp quyền
|
||
|
|
</button>
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
onClick={onManageUserClick}
|
||
|
|
className="text-white bg-slate-600 hover:bg-slate-700 focus:ring-4 focus:outline-none focus:ring-slate-800 font-medium rounded-lg text-sm px-5 py-3 text-center transition-all duration-200"
|
||
|
|
>
|
||
|
|
Quản lý người dùng
|
||
|
|
</button>
|
||
|
|
{onViewInfoClick && (
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
disabled={!geIdAndLang.trim()}
|
||
|
|
onClick={onViewInfoClick}
|
||
|
|
className="text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-800 font-medium rounded-lg text-sm px-5 py-3 text-center transition-all duration-200 disabled:bg-emerald-900 disabled:text-slate-500 disabled:cursor-not-allowed"
|
||
|
|
title={!geIdAndLang.trim() ? 'Vui lòng nhập GE ID & Lang' : 'Xem thông tin project TMS'}
|
||
|
|
>
|
||
|
|
Xem thông tin
|
||
|
|
</button>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default SubmissionForm;
|