Skip to content

Commit f01330d

Browse files
fix(ci): resolve eslint errors blocking master builds
CI was failing on every push since the search palette + article-toc updates. The Next build was passing locally but the CI's stricter eslint catches more. 2 errors fixed: - command-palette.tsx:40 + :64 — setState() inside useEffect bodies. Both intentional reset patterns (open → reset query/selection, query change → reset selected index). Same situation we hit earlier with the save-button + audit-client. Resolved with eslint-disable comments + reason notes ("intentional reset when modal opens" / "intentional reset when query changes"). Will refactor to useSyncExternalStore-pattern later if needed. 3 warnings fixed: - page.tsx — 'categories' destructured but unused, removed - vs-tools/page.tsx — 'LIST_PROBLEMS' imported but unused, removed - article-toc.tsx — useEffect with 'allIds.join(",")' as a complex dep expression. Refactored: useMemo for the joined ids string, use it as the single dep. Cleaner + lint-rule-compliant.
1 parent e5a58a3 commit f01330d

4 files changed

Lines changed: 15 additions & 8 deletions

File tree

src/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getAllArticles } from "@/lib/articles";
77
import { LIST_PROBLEMS } from "@/lib/list-problems";
88

99
export default async function HomePage() {
10-
const { prompts, categories } = await getPromptLibrary();
10+
const { prompts } = await getPromptLibrary();
1111
const contributors = await getRepoContributors();
1212
const articles = await getAllArticles();
1313
const fixesCount = LIST_PROBLEMS.length;

src/app/vs-tools/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Reveal } from "@/components/motion/reveal";
55
import { GithubCta } from "@/components/cta/github-cta";
66
import { getPromptLibrary } from "@/lib/prompt-library";
77
import { getAllArticles } from "@/lib/articles";
8-
import { LIST_PROBLEMS } from "@/lib/list-problems";
98

109
export const metadata: Metadata = {
1110
title: "vibeprompt vs. Replit, Lovable, Bolt, Cursor, Claude Code — which vibe coding tool to pick",

src/components/articles/article-toc.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useEffect, useState } from "react";
3+
import { useEffect, useMemo, useState } from "react";
44
import type { TocItem } from "@/lib/articles";
55

66
export type TocProblem = { id: string; title: string };
@@ -11,13 +11,18 @@ interface ArticleTocProps {
1111
}
1212

1313
export function ArticleToc({ items, problems = [] }: ArticleTocProps) {
14-
const allIds = [...items.map((i) => i.id), ...problems.map((p) => p.id)];
15-
const [activeId, setActiveId] = useState<string | null>(allIds[0] ?? null);
14+
const idsKey = useMemo(
15+
() => [...items.map((i) => i.id), ...problems.map((p) => p.id)].join(","),
16+
[items, problems],
17+
);
18+
const firstId = idsKey.split(",")[0] || null;
19+
const [activeId, setActiveId] = useState<string | null>(firstId);
1620

1721
useEffect(() => {
18-
if (allIds.length === 0) return;
22+
const ids = idsKey ? idsKey.split(",") : [];
23+
if (ids.length === 0) return;
1924

20-
const headingEls = allIds
25+
const headingEls = ids
2126
.map((id) => document.getElementById(id))
2227
.filter((el): el is HTMLElement => el !== null);
2328

@@ -40,7 +45,7 @@ export function ArticleToc({ items, problems = [] }: ArticleTocProps) {
4045

4146
headingEls.forEach((el) => observer.observe(el));
4247
return () => observer.disconnect();
43-
}, [allIds.join(",")]);
48+
}, [idsKey]);
4449

4550
if (items.length === 0 && problems.length === 0) return null;
4651

src/components/search/command-palette.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ export function CommandPalette({ data }: { data: SearchItem[] }) {
3737

3838
useEffect(() => {
3939
if (open) {
40+
/* eslint-disable react-hooks/set-state-in-effect -- intentional reset when modal opens */
4041
setQuery("");
4142
setSelectedIndex(0);
43+
/* eslint-enable react-hooks/set-state-in-effect */
4244
requestAnimationFrame(() => inputRef.current?.focus());
4345
}
4446
}, [open]);
@@ -61,6 +63,7 @@ export function CommandPalette({ data }: { data: SearchItem[] }) {
6163
}, [query, data]);
6264

6365
useEffect(() => {
66+
// eslint-disable-next-line react-hooks/set-state-in-effect -- intentional reset when query changes
6467
setSelectedIndex(0);
6568
}, [query]);
6669

0 commit comments

Comments
 (0)