Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Dev - #2

Merged
Retsomm merged 3 commits into
mainfrom
dev
Jul 10, 2026
Merged

Dev#2
Retsomm merged 3 commits into
mainfrom
dev

Conversation

@Retsomm

@RetsommRetsomm commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added four React learning chapters covering JSX, props, state and events, and Hooks.
    • Added chapter selection and level views with progress tracking, completion status, locking, and back navigation.
    • Added automated validation for JSX-based exercises, including rendered output checks.
  • Style

    • Updated the chapter map with card-based layouts, progress bars, status indicators, and improved visual hierarchy.
  • Documentation

    • Clarified verification guidance for React/JSX exercises and topics requiring manual review.

Retsommand others added 2 commits July 10, 2026 16:12
- validate-questions.mjs 新增 jsx check:esbuild(新增 devDependency)轉譯後以
renderToStaticMarkup 實際渲染比對
- react-1、react-2 共 12 題自動驗證通過;react-3、react-4 共 12 題屬互動行為,
標記 manual 待人工審(答案依 react.dev 對應文件撰寫)
- 全題庫 72 題:1183 項檢查通過、0 失敗
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercelBot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
easy-learnReadyReadyPreview, CommentJul 10, 2026 8:25am

@coderabbitai

coderabbitaiBot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in:47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1233bdaa-3c57-43cc-a80e-7d9ef14762a6

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1ef4 and b49ba0d.

📒 Files selected for processing (8)
  • index.html
  • src/components/Icons.jsx
  • src/components/QuestionCard.jsx
  • src/data/chapters.js
  • src/index.css
  • src/screens/ChapterMap.jsx
  • src/screens/Home.jsx
  • src/screens/Quiz.jsx
📝 Walkthrough

Walkthrough

Adds four React learning levels, JSX verification support, React chapter registration, and a two-step chapter/level navigation interface with progress and locking states.

Changes

React learning flow

Layer / File(s)Summary
JSX question validation
docs/question-format.md, package.json, scripts/validate-questions.mjs
Documents JSX checks and adds esbuild-based transpilation, temporary module execution, and output comparison support.
React question sets
src/data/questions/react-*.json
Adds lessons covering JSX, props, state and events, and hooks, with automated or manual verification details.
React chapter registration
src/data/chapters.js
Registers the four React lesson definitions in the React chapter.
Chapter and level navigation
src/screens/ChapterMap.jsx, src/index.css
Adds chapter selection, per-chapter progress, level locking and status indicators, back navigation, and card-based styling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
participant ChapterMap
participant ChapterList
participant LevelList
ChapterMap->>ChapterList: render chapter selection
ChapterList->>ChapterMap: select chapterId
ChapterMap->>LevelList: render selected chapter
LevelList-->>ChapterMap: clear chapterId on back
ChapterMap->>ChapterList: render chapter selection again
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe title is too generic to convey the main change in the pull request.Use a concise, specific title that summarizes the main update, such as adding React lessons and JSX validation support.
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/validate-questions.mjs`:
- Around line 26-38: Update runJsx to catch transformSync errors and return a
failed validation result instead of aborting the entire run. Move writeFileSync
into the existing try block so any created temporary file is always removed by
finally, including when JSX transformation or file writing fails.
In `@src/data/questions/react-4-hooks.json`:
- Around line 21-24: The useEffect explanation currently implies it always runs
after the browser paints. Update the explanation associated with the useEffect
question to say that React commits the rendered result first and then runs the
effect, without guaranteeing that the browser has painted; retain the examples
of post-commit work.
- Around line 34-46: 更新 react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React
直接報錯」改為描述違反 Rules of Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與
explanation 不變。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f7132944-56b4-44f7-839b-510cb1609a11

📥 Commits

Reviewing files that changed from the base of the PR and between e13d1e8 and 4dc1ef4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • docs/question-format.md
  • package.json
  • scripts/validate-questions.mjs
  • src/data/chapters.js
  • src/data/questions/react-1-jsx.json
  • src/data/questions/react-2-props.json
  • src/data/questions/react-3-state-events.json
  • src/data/questions/react-4-hooks.json
  • src/index.css
  • src/screens/ChapterMap.jsx

Comment on lines +26 to +38
function runJsx(code) {
// esbuild 轉譯 JSX → 臨時 .mjs 檔(放專案根目錄才解析得到 node_modules 的 react)
const js = transformSync(code, { loader: 'jsx', jsx: 'automatic', format: 'esm' }).code
const tmp = join(PROJECT_ROOT, `.validate-tmp-${process.pid}-${Math.random().toString(36).slice(2)}.mjs`)
writeFileSync(tmp, js)
try {
const res = spawnSync('node', [tmp], { encoding: 'utf8', timeout: 10000, cwd: PROJECT_ROOT })
return { stdout: (res.stdout || '').trim(), stderr: (res.stderr || '').trim(), status: res.status }
} finally {
rmSync(tmp, { force: true })
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash# Check surrounding context of the runJsx call at line 80
sed -n '70,90p' scripts/validate-questions.mjs
# Verify transformSync behavior on invalid JSX (run locally with esbuild installed)
node --input-type=module -e "import { transformSync } from 'esbuild'try { transformSync('const x = <div>', { loader: 'jsx', jsx: 'automatic', format: 'esm' }) console.log('transformSync did NOT throw')} catch (err) { console.log('transformSync threw:', err.message)}"

Repository: Retsomm/EasyLearn

Length of output: 2191


Catch JSX transform errors in scripts/validate-questions.mjs
transformSync can throw on invalid JSX and currently aborts the whole validation run; writeFileSync is also outside the cleanup guard. Wrap the transform in try/catch and move the file write inside the try so each question fails independently and temp files still get removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-questions.mjs` around lines 26 - 38, Update runJsx to catch
transformSync errors and return a failed validation result instead of aborting
the entire run. Move writeFileSync into the existing try block so any created
temporary file is always removed by finally, including when JSX transformation
or file writing fails.

Comment on lines +21 to +24
"explanation": "useEffect 的字面意思是「副作用」:React 先專心把畫面算完、畫到螢幕上(A),之後才回頭執行 effect(B)。所以 effect 裡拿得到已經存在的畫面,適合放「畫面好了之後才做」的事——抓資料、訂閱、操作 document。",
"verify": {
"checks": [],
"manual": "useEffect 在 SSR 不執行,需要瀏覽器環境;答案依 react.dev synchronizing-with-effects(effect 在 commit 後執行)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bashset -euo pipefail
# Inspect the referenced file and surrounding lines.
git ls-files src/data/questions/react-4-hooks.json
wc -l src/data/questions/react-4-hooks.json
sed -n '1,80p' src/data/questions/react-4-hooks.json
# Search for any other mentions of useEffect timing in the repo.
rg -n "useEffect|commit|paint|Strict Mode|effect" src/data/questions src -g '!**/*.map'

Repository: Retsomm/EasyLearn

Length of output: 19159


Describe useEffect as after commit, not after paint.src/data/questions/react-4-hooks.json:21-24 The explanation is a bit too absolute: useEffect runs after commit, but not always after the browser paints. Reword the line to avoid implying the screen is guaranteed visible first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 21 - 24, The useEffect
explanation currently implies it always runs after the browser paints. Update
the explanation associated with the useEffect question to say that React commits
the rendered result first and then runs the effect, without guaranteeing that
the browser has painted; retain the examples of post-commit work.

Comment on lines +34 to +46
"prompt": "想「有需要才建立 state」,結果 React 直接報錯。哪裡違規了?",
"code": "function Profile({ isVip }) {\n if (isVip) {\n const [badge, setBadge] = useState(\"⭐\"); // B 行\n }\n const [name, setName] = useState(\"小美\");\n return <p>{name}</p>;\n}",
"options": [
{ "id": "a", "text": "B 行把 useState 放進 if:Hook 必須每次渲染都以相同順序執行,不能寫在條件、迴圈裡" },
{ "id": "b", "text": "badge 的初始值不能是 emoji" },
{ "id": "c", "text": "一個元件最多只能有一個 useState" },
{ "id": "d", "text": "isVip 沒有預設值" }
],
"answer": "a",
"explanation": "React 記 state 靠的是「呼叫順序」:第一個 useState、第二個 useState……像便當店叫號。放進 if 之後,isVip 一變,叫號順序整個亂掉,React 就把別人的 state 發給你。所以鐵律:Hook 只能寫在元件最上層。想條件式地「用」state 可以,條件式地「宣告」不行。",
"verify": {
"checks": [],
"manual": "違規要在 isVip 改變的第二次渲染才爆發,需互動環境;答案依 react.dev rules-of-hooks"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' src/data/questions/react-4-hooks.json

Repository: Retsomm/EasyLearn

Length of output: 5299


把「直接報錯」改成條件式違反 Hooks 規則
這段確實違反 Rules of Hooks,但不是每次都會立刻炸;isVip 在不同渲染間切換時才會出現 hook 順序錯亂,lint 也能先抓到。題幹可改成「違反 Hook 規則,切換狀態時可能報錯」更準。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/data/questions/react-4-hooks.json` around lines 34 - 46, 更新
react-4-hooks.json 中 Profile 題目的 prompt,將「結果 React 直接報錯」改為描述違反 Rules of
Hooks,並指出在 isVip 於不同渲染間切換時可能因 Hook 順序錯亂而報錯;保留選項、答案與 explanation 不變。

- 配色改深紫灰底色系(color-scheme: dark),修正選項按鈕/進度條/徽章/
分隔線等硬編碼淺色造成的深色錯誤,主要按鈕文字改深色提升對比
- 新增 Icons.jsx 線型圖示集(lucide 路徑、stroke=currentColor、零依賴),
取代所有 emoji UI 圖示:關卡狀態、章節、題型徽章、回饋、導覽、匯出入
- 吉祥物皮皮保留 emoji(角色非圖示)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Retsomm