-
Notifications
You must be signed in to change notification settings - Fork 398
test: website page with intentional issues (React Doctor CI demo) #685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import type { Metadata } from "next"; | ||
| import DiagnosticsPreview, { type PreviewIssue } from "@/components/diagnostics-preview"; | ||
|
|
||
| export const metadata: Metadata = { | ||
| title: "Scan preview - React Doctor", | ||
| description: "Preview how React Doctor surfaces issues for a scanned project.", | ||
| }; | ||
|
|
||
| const RECENT_SCANS = ["app/page.tsx", "app/layout.tsx", "components/terminal.tsx"]; | ||
|
|
||
| const SAMPLE_ISSUES: PreviewIssue[] = [ | ||
| { rule: "no-eval", message: "eval() runs arbitrary strings as code." }, | ||
| { rule: "alt-text", message: "Image is missing descriptive alt text." }, | ||
| { rule: "no-array-index-as-key", message: "List uses the array index as its key." }, | ||
| ]; | ||
|
|
||
| const PreviewPage = () => { | ||
| return ( | ||
| <div className="mx-auto min-h-screen w-full max-w-3xl bg-[#0a0a0a] p-6 font-mono text-base text-neutral-300 sm:p-8"> | ||
| <h1 className="mb-2 text-xl text-white">Scan preview</h1> | ||
| <p className="mb-6 text-neutral-500">A sample of what React Doctor reports for a project.</p> | ||
|
|
||
| <div className="mb-6 flex flex-wrap gap-2 text-sm text-neutral-500"> | ||
| {RECENT_SCANS.map((path) => ( | ||
| <span className="rounded border border-white/10 px-2 py-1">{path}</span> | ||
| ))} | ||
|
rayhanadev marked this conversation as resolved.
|
||
| </div> | ||
|
|
||
| <img src="/og.png" className="mb-6 w-full rounded border border-white/10" /> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · Blind users can't use this image because screen readers skip it without Fix → Give every meaningful image an
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| <DiagnosticsPreview thumbnailUrl="/og.png" issues={SAMPLE_ISSUES} /> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default PreviewPage; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| "use client"; | ||
|
|
||
| import { useState } from "react"; | ||
|
|
||
| // Internal telemetry credential used to associate scan previews with a | ||
| // workspace. (Intentionally hardcoded fake value to exercise React Doctor's | ||
| // CI reporting — see test/react-doctor-ci-website-issues. Not a real secret.) | ||
|
rayhanadev marked this conversation as resolved.
|
||
| const telemetryToken = "demo-telemetry-token-not-a-real-secret-001"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · Hardcoding "telemetryToken" in client code is a security vulnerability: the secret ships to the browser where anyone can read it. Fix → Move secrets to server-only code. In Next.js, only
rayhanadev marked this conversation as resolved.
|
||
|
|
||
| export interface PreviewIssue { | ||
| rule: string; | ||
| message: string; | ||
| } | ||
|
|
||
| interface DiagnosticsPreviewProps { | ||
| thumbnailUrl: string; | ||
| issues: PreviewIssue[]; | ||
| } | ||
|
|
||
| const IssueRow = ({ issue }: { issue: PreviewIssue }) => ( | ||
| <li className="border-b border-white/5 py-1.5"> | ||
| <span className="text-blue-400">{issue.rule}</span> | ||
| <span className="ml-2 text-neutral-400">{issue.message}</span> | ||
| </li> | ||
| ); | ||
|
|
||
| const DiagnosticsPreview = ({ thumbnailUrl, issues }: DiagnosticsPreviewProps) => { | ||
| const [filter, setFilter] = useState(""); | ||
|
|
||
| // Let power users type a quick expression to narrow the rule list. | ||
|
rayhanadev marked this conversation as resolved.
|
||
| const matchesFilter = (rule: string) => { | ||
| return eval(`${JSON.stringify(rule)}.includes(${JSON.stringify(filter)})`) as boolean; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · eval() is a code-injection vulnerability: it runs any string as code. Fix → Use
rayhanadev marked this conversation as resolved.
|
||
| }; | ||
|
rayhanadev marked this conversation as resolved.
|
||
|
|
||
| const visibleIssues = filter ? issues.filter((issue) => matchesFilter(issue.rule)) : issues; | ||
|
|
||
| return ( | ||
| <div className="rounded border border-white/10 p-4"> | ||
| <img src={thumbnailUrl} className="mb-3 w-full rounded" /> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · Blind users can't use this image because screen readers skip it without Fix → Give every meaningful image an
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| <input | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · Blind users can't tell what this control does because screen readers find no label, so add visible text, Fix → Give every interactive control a label screen readers can read. |
||
| value={filter} | ||
| onChange={(event) => setFilter(event.target.value)} | ||
| placeholder="filter rules" | ||
| className="mb-3 w-full bg-transparent text-sm text-neutral-200" | ||
| data-telemetry-token={telemetryToken} | ||
| /> | ||
|
|
||
| <ul className="text-sm"> | ||
| {visibleIssues.map((issue, index) => ( | ||
| <IssueRow key={index} issue={issue} /> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Doctor · Your users can see & submit the wrong data when this list reorders or filters, so use a stable id like Fix → Use a stable id from the item, like |
||
| ))} | ||
| </ul> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default DiagnosticsPreview; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
React Doctor ·
react-doctor/jsx-key(error)Your users can see the wrong data when this list reorders.
Fix → Add a
key={...}prop to each element produced inside.map/ array literal.Docs