Skip to content

Commit 356e5d8

Browse files
lucbrinkmanclaude
andcommitted
Fix ESLint errors and warnings
Fixed: - Replace <a> tag with Next.js Link component in auth error page - Add missing React Hook dependencies in DocumentPicker, Flowchart, and Node components All CI checks now pass (type-check, lint, build). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent c54c316 commit 356e5d8

File tree

5 files changed

+1605
-1004
lines changed

5 files changed

+1605
-1004
lines changed

app/auth/auth-code-error/page.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Link from "next/link";
2+
13
export default function AuthCodeError() {
24
return (
35
<div className="min-h-screen flex items-center justify-center bg-gray-50">
@@ -22,16 +24,17 @@ export default function AuthCodeError() {
2224
Authentication Error
2325
</h1>
2426
<p className="text-gray-600 mb-6">
25-
There was a problem confirming your email. The link may have expired or already been used.
27+
There was a problem confirming your email. The link may have expired
28+
or already been used.
2629
</p>
27-
<a
30+
<Link
2831
href="/"
2932
className="inline-block bg-purple-600 text-white px-6 py-2 rounded-md hover:bg-purple-700"
3033
>
3134
Return to Home
32-
</a>
35+
</Link>
3336
</div>
3437
</div>
3538
</div>
36-
)
39+
);
3740
}

components/DocumentPicker.tsx

Lines changed: 87 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
'use client'
2-
3-
import { useState, useEffect, useRef, useCallback } from 'react';
4-
import { Document } from '@/lib/types';
5-
import { getUserDocuments, deleteDocument, renameDocument } from '@/lib/actions/documents';
6-
import TemplateChoiceDialog from './TemplateChoiceDialog';
7-
import NewDocumentWarningDialog from './NewDocumentWarningDialog';
8-
import { ShareModal } from './ShareModal';
9-
import Tooltip from './Tooltip';
1+
"use client";
2+
3+
import { useState, useEffect, useRef, useCallback } from "react";
4+
import { Document } from "@/lib/types";
5+
import {
6+
getUserDocuments,
7+
deleteDocument,
8+
renameDocument,
9+
} from "@/lib/actions/documents";
10+
import TemplateChoiceDialog from "./TemplateChoiceDialog";
11+
import NewDocumentWarningDialog from "./NewDocumentWarningDialog";
12+
import { ShareModal } from "./ShareModal";
13+
import Tooltip from "./Tooltip";
1014

1115
interface DocumentPickerProps {
1216
currentDocumentId: string | null;
@@ -50,14 +54,17 @@ export default function DocumentPicker({
5054
// Close dropdown when clicking outside
5155
useEffect(() => {
5256
function handleClickOutside(event: MouseEvent) {
53-
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
57+
if (
58+
dropdownRef.current &&
59+
!dropdownRef.current.contains(event.target as Node)
60+
) {
5461
setIsOpen(false);
5562
setIsRenaming(false);
5663
}
5764
}
5865

59-
document.addEventListener('mousedown', handleClickOutside);
60-
return () => document.removeEventListener('mousedown', handleClickOutside);
66+
document.addEventListener("mousedown", handleClickOutside);
67+
return () => document.removeEventListener("mousedown", handleClickOutside);
6168
}, []);
6269

6370
// Focus rename input when renaming starts
@@ -87,7 +94,7 @@ export default function DocumentPicker({
8794
const handleDelete = async (documentId: string, e: React.MouseEvent) => {
8895
e.stopPropagation();
8996

90-
if (!confirm('Are you sure you want to delete this document?')) {
97+
if (!confirm("Are you sure you want to delete this document?")) {
9198
return;
9299
}
93100

@@ -120,15 +127,22 @@ export default function DocumentPicker({
120127

121128
// Check if name exists in loaded documents
122129
const nameExists = documents.some(
123-
doc => doc.name === trimmedValue && doc.id !== currentDocumentId
130+
(doc) => doc.name === trimmedValue && doc.id !== currentDocumentId
124131
);
125132

126133
if (nameExists) {
127-
setRenameError('A document with this name already exists');
134+
setRenameError("A document with this name already exists");
128135
} else {
129136
setRenameError(null);
130137
}
131-
}, [renameValue, isRenaming, isAuthenticated, documents, currentDocumentName, currentDocumentId]);
138+
}, [
139+
renameValue,
140+
isRenaming,
141+
isAuthenticated,
142+
documents,
143+
currentDocumentName,
144+
currentDocumentId,
145+
]);
132146

133147
const handleRenameSubmit = useCallback(async () => {
134148
const trimmedValue = renameValue.trim();
@@ -168,14 +182,25 @@ export default function DocumentPicker({
168182
setTimeout(() => {
169183
justRenamed.current = false;
170184
}, 300); // 300ms cooldown
171-
}, [renameValue, currentDocumentName, isAuthenticated, currentDocumentId, onRename, renameError, onEditorClose]);
185+
}, [
186+
renameValue,
187+
currentDocumentName,
188+
isAuthenticated,
189+
currentDocumentId,
190+
onRename,
191+
renameError,
192+
onEditorClose,
193+
]);
172194

173195
// Handle clicks outside when renaming to submit
174196
useEffect(() => {
175197
if (!isRenaming) return;
176198

177199
const handleClickOutside = (event: MouseEvent) => {
178-
if (renameInputRef.current && !renameInputRef.current.contains(event.target as Node)) {
200+
if (
201+
renameInputRef.current &&
202+
!renameInputRef.current.contains(event.target as Node)
203+
) {
179204
// Call onEditorClose FIRST to set the timestamp before any other handlers run
180205
onEditorClose?.();
181206

@@ -191,16 +216,22 @@ export default function DocumentPicker({
191216
};
192217

193218
// Use capture phase to ensure we catch the click before it's potentially stopped
194-
document.addEventListener('mousedown', handleClickOutside, true);
219+
document.addEventListener("mousedown", handleClickOutside, true);
195220
return () => {
196-
document.removeEventListener('mousedown', handleClickOutside, true);
221+
document.removeEventListener("mousedown", handleClickOutside, true);
197222
};
198-
}, [isRenaming, renameError, currentDocumentName, handleRenameSubmit]);
223+
}, [
224+
isRenaming,
225+
renameError,
226+
currentDocumentName,
227+
handleRenameSubmit,
228+
onEditorClose,
229+
]);
199230

200231
const handleRenameKeyDown = (e: React.KeyboardEvent) => {
201-
if (e.key === 'Enter') {
232+
if (e.key === "Enter") {
202233
handleRenameSubmit();
203-
} else if (e.key === 'Escape') {
234+
} else if (e.key === "Escape") {
204235
setRenameValue(currentDocumentName);
205236
setRenameError(null);
206237
setIsRenaming(false);
@@ -220,7 +251,7 @@ export default function DocumentPicker({
220251
onChange={(e) => setRenameValue(e.target.value)}
221252
onKeyDown={handleRenameKeyDown}
222253
className="px-2 py-1 bg-gray-800 border border-gray-600 rounded text-white text-sm"
223-
style={{ width: '200px' }}
254+
style={{ width: "200px" }}
224255
/>
225256
</div>
226257
);
@@ -230,7 +261,11 @@ export default function DocumentPicker({
230261
<>
231262
<div className="relative" ref={dropdownRef}>
232263
<div className="flex items-center gap-1 px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white text-sm">
233-
<Tooltip content="Rename" position="bottom" disabled={justRenamed.current}>
264+
<Tooltip
265+
content="Rename"
266+
position="bottom"
267+
disabled={justRenamed.current}
268+
>
234269
<span
235270
className="font-medium cursor-text px-1 py-0.5 rounded transition-all hover:border hover:border-gray-500 border border-transparent"
236271
onClick={() => setIsRenaming(true)}
@@ -243,12 +278,17 @@ export default function DocumentPicker({
243278
className="hover:bg-gray-700 p-1 rounded"
244279
>
245280
<svg
246-
className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`}
281+
className={`w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
247282
fill="none"
248283
stroke="currentColor"
249284
viewBox="0 0 24 24"
250285
>
251-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
286+
<path
287+
strokeLinecap="round"
288+
strokeLinejoin="round"
289+
strokeWidth={2}
290+
d="M19 9l-7 7-7-7"
291+
/>
252292
</svg>
253293
</button>
254294
</div>
@@ -321,17 +361,21 @@ export default function DocumentPicker({
321361
}}
322362
onKeyDown={handleRenameKeyDown}
323363
className={`px-3 py-2 bg-gray-800 border rounded text-white text-sm ${
324-
renameError ? 'border-red-500' : 'border-gray-600'
364+
renameError ? "border-red-500" : "border-gray-600"
325365
}`}
326-
style={{ width: '250px' }}
366+
style={{ width: "250px" }}
327367
/>
328368
{renameError && (
329369
<div className="text-xs text-red-400">{renameError}</div>
330370
)}
331371
</div>
332372
) : (
333373
<div className="flex items-center gap-1 px-3 py-2 bg-gray-800 border border-gray-600 rounded text-white text-sm">
334-
<Tooltip content="Rename" position="bottom" disabled={justRenamed.current}>
374+
<Tooltip
375+
content="Rename"
376+
position="bottom"
377+
disabled={justRenamed.current}
378+
>
335379
<span
336380
className="font-medium cursor-text px-1 py-0.5 rounded transition-all hover:border hover:border-gray-500 border border-transparent"
337381
onClick={() => setIsRenaming(true)}
@@ -344,12 +388,17 @@ export default function DocumentPicker({
344388
className="hover:bg-gray-700 p-1 rounded"
345389
>
346390
<svg
347-
className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`}
391+
className={`w-4 h-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
348392
fill="none"
349393
stroke="currentColor"
350394
viewBox="0 0 24 24"
351395
>
352-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
396+
<path
397+
strokeLinecap="round"
398+
strokeLinejoin="round"
399+
strokeWidth={2}
400+
d="M19 9l-7 7-7-7"
401+
/>
353402
</svg>
354403
</button>
355404
</div>
@@ -395,8 +444,8 @@ export default function DocumentPicker({
395444
disabled={!currentDocumentId}
396445
className={`w-full px-4 py-2 text-left text-sm border-b border-gray-600 ${
397446
currentDocumentId
398-
? 'text-white hover:bg-gray-700 cursor-pointer'
399-
: 'text-gray-500 cursor-not-allowed'
447+
? "text-white hover:bg-gray-700 cursor-pointer"
448+
: "text-gray-500 cursor-not-allowed"
400449
}`}
401450
>
402451
Share Current
@@ -407,14 +456,16 @@ export default function DocumentPicker({
407456
{loading ? (
408457
<div className="px-4 py-2 text-sm text-gray-400">Loading...</div>
409458
) : documents.length === 0 ? (
410-
<div className="px-4 py-2 text-sm text-gray-400">No documents yet</div>
459+
<div className="px-4 py-2 text-sm text-gray-400">
460+
No documents yet
461+
</div>
411462
) : (
412463
<div className="py-1">
413464
{documents.map((doc) => (
414465
<div
415466
key={doc.id}
416467
className={`flex items-center justify-between px-4 py-2 text-sm hover:bg-gray-700 ${
417-
doc.id === currentDocumentId ? 'bg-gray-700' : ''
468+
doc.id === currentDocumentId ? "bg-gray-700" : ""
418469
}`}
419470
>
420471
<button

0 commit comments

Comments
 (0)