- Add all new Frontend source files (pages, components, hooks, utils) - Add selenium_MHBatchPaymentCheckWorker.py and MHSinglePaymentCheckWorker.py - Add install-steps-5-13.sh setup script - Update .gitignore to exclude runtime/sensitive data (backups, uploads, chat-history, keys, downloads, generated .d.ts files) while keeping folders - Add .gitkeep to preserve empty runtime folders in git Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
59 lines
2.3 KiB
React
59 lines
2.3 KiB
React
import React from "react";
|
||
import { Input } from "@/components/ui/input";
|
||
export function RemarksField({ value, onChange, debounceMs = 250, // tweak (150–300) if you like
|
||
}) {
|
||
const [local, setLocal] = React.useState(() => value);
|
||
// Track last prop we saw to detect true external changes
|
||
const lastPropRef = React.useRef(value);
|
||
React.useEffect(() => {
|
||
if (value !== lastPropRef.current && value !== local) {
|
||
// Only sync when parent changed from elsewhere
|
||
setLocal(value);
|
||
}
|
||
lastPropRef.current = value;
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, [value]); // (intentionally ignoring `local` in deps)
|
||
// Debounce: call parent onChange after user pauses typing
|
||
const timerRef = React.useRef(null);
|
||
const schedulePush = React.useCallback((next) => {
|
||
if (timerRef.current) {
|
||
clearTimeout(timerRef.current);
|
||
timerRef.current = null;
|
||
}
|
||
timerRef.current = window.setTimeout(() => {
|
||
timerRef.current = null;
|
||
onChange(next);
|
||
// update lastPropRef so the next parent echo won't resync over local
|
||
lastPropRef.current = next;
|
||
}, debounceMs);
|
||
}, [onChange, debounceMs]);
|
||
// Flush on unmount to avoid losing the last input
|
||
React.useEffect(() => {
|
||
return () => {
|
||
if (timerRef.current) {
|
||
clearTimeout(timerRef.current);
|
||
timerRef.current = null;
|
||
onChange(local);
|
||
}
|
||
};
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, []);
|
||
return (<div className="space-y-2">
|
||
<Input id="remarks" placeholder="Paste clinical notes here" autoComplete="off" spellCheck={false} value={local} onChange={(e) => {
|
||
const next = e.target.value;
|
||
setLocal(next); // instant local update (no lag)
|
||
schedulePush(next); // debounced parent update
|
||
}} onBlur={() => {
|
||
// ensure latest text is pushed when the field loses focus
|
||
if (timerRef.current) {
|
||
clearTimeout(timerRef.current);
|
||
timerRef.current = null;
|
||
}
|
||
if (local !== lastPropRef.current) {
|
||
onChange(local);
|
||
lastPropRef.current = local;
|
||
}
|
||
}}/>
|
||
</div>);
|
||
}
|