feat(review): add draftCommentText state and double-submit guard

This commit is contained in:
Hiren Kangad
2026-03-12 22:09:12 +05:30
parent 6e1d9df7f0
commit cf879b34d5
+10 -2
View File
@@ -109,6 +109,8 @@ export default function Editor({ isPublicView }: EditorProps) {
const [draftPin, setDraftPin] = useState<DraftPin | null>(null); const [draftPin, setDraftPin] = useState<DraftPin | null>(null);
const [openThreadDetailId, setOpenThreadDetailId] = useState<string | null>(null); const [openThreadDetailId, setOpenThreadDetailId] = useState<string | null>(null);
const expandSeqRef = useRef(0); const expandSeqRef = useRef(0);
const [draftCommentText, setDraftCommentText] = useState('');
const [creatingPointThread, setCreatingPointThread] = useState(false);
const [focusMode, setFocusMode] = useState(false); const [focusMode, setFocusMode] = useState(false);
const [layerList, setLayerList] = useState<any[]>([]); const [layerList, setLayerList] = useState<any[]>([]);
const [selectedLayerIds, setSelectedLayerIds] = useState<string[]>([]); const [selectedLayerIds, setSelectedLayerIds] = useState<string[]>([]);
@@ -320,6 +322,7 @@ export default function Editor({ isPublicView }: EditorProps) {
if (draftPin) { if (draftPin) {
e.preventDefault(); e.preventDefault();
setDraftPin(null); setDraftPin(null);
setDraftCommentText('');
return; return;
} }
if (openThreadDetailId) { if (openThreadDetailId) {
@@ -345,9 +348,10 @@ export default function Editor({ isPublicView }: EditorProps) {
// Create point-pinned thread via REST // Create point-pinned thread via REST
const handleCreatePointThread = useCallback(async (draft: DraftPin, content: string) => { const handleCreatePointThread = useCallback(async (draft: DraftPin, content: string) => {
if (!resolvedBoardId) return; if (!resolvedBoardId || creatingPointThread) return;
const token = localStorage.getItem('refboard_token'); const token = localStorage.getItem('refboard_token');
if (!token) return; if (!token) return;
setCreatingPointThread(true);
try { try {
const res = await fetch(`/api/boards/${resolvedBoardId}/threads`, { const res = await fetch(`/api/boards/${resolvedBoardId}/threads`, {
method: 'POST', method: 'POST',
@@ -368,18 +372,22 @@ export default function Editor({ isPublicView }: EditorProps) {
const data = await res.json(); const data = await res.json();
// Clear draft, pre-focus the new thread // Clear draft, pre-focus the new thread
setDraftPin(null); setDraftPin(null);
setDraftCommentText('');
setFocusedThreadId(data.thread.id); setFocusedThreadId(data.thread.id);
expandSeqRef.current += 1; expandSeqRef.current += 1;
setExpandRequest({ threadId: data.thread.id, seq: expandSeqRef.current }); setExpandRequest({ threadId: data.thread.id, seq: expandSeqRef.current });
} catch (err: any) { } catch (err: any) {
showToast('Failed to create comment: ' + (err.message || 'network error')); showToast('Failed to create comment: ' + (err.message || 'network error'));
} finally {
setCreatingPointThread(false);
} }
}, [resolvedBoardId, showToast]); }, [resolvedBoardId, showToast, creatingPointThread]);
// Clear draft and focus when exiting review mode // Clear draft and focus when exiting review mode
useEffect(() => { useEffect(() => {
if (!reviewMode) { if (!reviewMode) {
setDraftPin(null); setDraftPin(null);
setDraftCommentText('');
setFocusedThreadId(null); setFocusedThreadId(null);
setExpandRequest(null); setExpandRequest(null);
} }