DEV Community

Voke
Voke

Posted on

Building in Public: CV Analyzer -Act 4 · Scene 1: The Analysis Component

This post shows how to fix broken navigation in a React app by wiring a real feature page into React Router v6.4+, turning a missing route into a working product flow.

Click here for Act 3 · Scene 2

Table of Contents

Act 4 · Scene 1: The Analysis Component

In this scene, I build and render the AnalysisFormPage, properly integrating it into the React Router route tree so the application’s main feature becomes accessible through navigation.

Overview

Auth was fixed in the last act. By the end of the previous act, authentication routes were fully wired into the application. Before that, clicking navigation links like Auth or Analyze Candidate resulted in an error boundary and the familiar message:

  • No routes matched this location.

Auth has now been resolved. But the same issue still exists for Analyze Candidate, and this scene focuses on fixing that properly.

This scene focuses on:

  • Introducing the AnalysisFormPage
  • Rendering it correctly through the router
  • Completing the navigation flow without errors

What the AnalysisForm Is Really About

This is where CVs and job descriptions enter the system.
Where raw text becomes something useful.
Where AI Talent Profile Analyzer stops being a name and starts becoming a tool.

For now, I am not after logic. I am just building the structure. Putting it together like a freaking LEGO block.

Here’s the initial JSX structure of the component:

return (
  <div className={classes["analysis-form-container"]}>
    <div className={classes.heading}>
      <h1>Analyze a Candidate</h1>
    </div>

    <div className={classes.body}>
      <form>
        <Card className={classes.cardClass}>
          <h2>Upload CV</h2>

          <div className={classes.actions}>
            <label className={classes.uploadButton}>
              Upload PDF or Text Files
              <input
                type="file"
                accept=".pdf,.txt"
                onChange={fileChangeHandler}
                hidden
              />
            </label>

            <button
              type="button"
              className={classes.secondaryButton}
              onClick={() => setShowPasteCv(true)}
            >
              Paste CV Text
            </button>

            <p>OR</p>

            <textarea
              placeholder="Paste CV text here..."
              value={cvText}
              onChange={cvTextChangeHandler}
            />
          </div>

          <div className={classes["lower-part"]}>
            <h2>Paste Job Description</h2>

            <textarea placeholder="Paste the job description here..." />

            <Button type="submit" className={classes.button3}>
              Run AI Analysis
            </Button>
          </div>
        </Card>
      </form>
    </div>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

The JavaScript behavior will be refined later. For now, this establishes the UI structure.

Why the AnalysisFormPage Exists: And Why I Didn’t Route the Component Directly

I don’t usually route components directly. I prefer that:

  • Pages should handle routing.
  • Components should handle UI.

So, I created AnalysisFormPage, imported the AnalysisForm component, and let it do its thing.

Code right here:

const AnalysisFormPage = () => {
  return <AnalysisForm />;
};
Enter fullscreen mode Exit fullscreen mode

Then I wired it into the router.

children: [
  { path: "/", element: <HomePage /> },
  { path: "/auth", element: <AuthPage /> },
  { path: "/analysis-form", element: <AnalysisFormPage /> },
];
Enter fullscreen mode Exit fullscreen mode

After saving and reloading, navigating to Analyze Candidate rendered the form successfully.

No error boundary. No warnings. Just a clean render.

See image below:

Mental Model

At this stage:

  • Routes map cleanly to pages. Yep! all pages
  • Pages handle routing
  • Components handle UI and interaction
  • Navigation reflects the actual application state

Why This Scene Matters

This scene shows that I:

  • Treat routing as application architecture, not an afterthought
  • Separate pages from components intentionally
  • Expect and resolve incomplete states during development

Thanks for reading.
Let’s move on to the Next Scene.

We in the Building…
Building in Progress…

Top comments (0)