> ## Content Index
> Fetch the complete content index at: https://reactpractice.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Build the Linkedin "Add experience" form
- URL: https://reactpractice.dev/exercise/build-the-linkedin-add-experience-form/
- Published: 2025-04-10T13:05:16.000Z
- Updated: 2026-06-01T01:57:47.000Z
- Author: Corina Udrescu
- Tags: Working with forms, #corina-2, Exercises, #Import 2026-06-09 12:07

Build a dynamic form inspired from **Linkedin's "Add experience"** form.  
This is an **advanced challenge** where you get to practice building **dynamic forms** and using **Typescript**.

0:00 

/0:09 

1× 

The form should have the following fields:

- job title (required)
- employment type
- company (required)
- whether the job is current or not (checkbox)
- start date (required)
- end date (disabled if job is current, required otherwise)

Use Typescript for your solution. Use [react-hook-form](https://react-hook-form.com/?ref=reactpractice.dev) to build the form and [zod](https://zod.dev/?ref=reactpractice.dev) for validation.

The form should show the same error messages the Linkedin form shows.

![](https://storage.ghost.io/c/7c/fc/7cfc444f-a1c9-4dd3-a87e-8dcc2f1180be/content/images/2025/04/1-experiences-list-1.png)

![](https://storage.ghost.io/c/7c/fc/7cfc444f-a1c9-4dd3-a87e-8dcc2f1180be/content/images/2025/04/2-add-experience-modal-2.png)

![](https://storage.ghost.io/c/7c/fc/7cfc444f-a1c9-4dd3-a87e-8dcc2f1180be/content/images/2025/04/3-error-messages-1.png)

You can use this **sample data** to get started:

```
// sample-data.ts
import { JobExperience } from "./types";

export const sampleJobExperiences: JobExperience[] = [
  {
    job_title: "Software Engineer",
    employment_type: "Full-time",
    company: "TechCorp Inc.",
    is_current: true,
    start_date: { month: "June", year: "2020" },
  },
  {
    job_title: "Frontend Developer",
    employment_type: "Contract",
    company: "Creative Solutions Ltd.",
    is_current: false,
    start_date: { month: "January", year: "2018" },
    end_date: { month: "May", year: "2020" },
  },
];

```

Also, since the **modal** and **showing the list of job experiences** is not the main focus of this challenge (building the form is 😄), you can copy the code for them if you want. You will be left with implementing the `JobExperience` type and the `AddExperienceForm` component.

```jsx
// App.tsx
import { useState } from "react";
import { JobExperience } from "./types";
import AddExperienceForm from "./components/AddExperienceForm";
import { sampleJobExperiences } from "./sample-data";

function App() {
  const [experienceList, setExperienceList] =
    useState<JobExperience[]>(sampleJobExperiences);
  const [showAddExperienceForm, setShowAddExperienceForm] = useState(false);
  return (
    <div className="bg-gray-300 min-h-screen p-4">
      <div className="container mx-auto p-4 max-w-4xl border-1 border-gray-400 rounded-xl bg-white shadow-lg">
        <h1 className="text-3xl font-bold mb-6">My Linkedin Profile</h1>
        <div className="flex items-center justify-between p-4 bg-gray-200">
          <h1 className="text-2xl font-bold">Experience</h1>
          <button
            onClick={() => setShowAddExperienceForm(true)}
            className="cursor-pointer hover:bg-gray-100 p-2 rounded-2xl"
          >
            Add
          </button>
        </div>
        {experienceList.length === 0 && (
          <div className="flex items-center justify-center h-64">
            <p className="text-gray-500">No experience added yet.</p>
          </div>
        )}
        {experienceList.map((jobExperience) => (
          <div className="p-4" key={jobExperience.job_title}>
            <h2 className="text-xl font-semibold">{jobExperience.job_title}</h2>
            <p>{jobExperience.company}</p>
            <p className="text-gray-500">
              {jobExperience.start_date.month} {jobExperience.start_date.year}
              {jobExperience.is_current
                ? " - Present"
                : ` - ${jobExperience.end_date?.month} ${jobExperience.end_date?.year}`}
            </p>
          </div>
        ))}
        {showAddExperienceForm && (
          <dialog className="fixed inset-0 bg-black/60 flex items-baseline pt-10 justify-center w-full h-full">
            <div className="bg-white rounded shadow-lg container w-3xl">
              <AddExperienceForm
                onSubmit={(newExperience) => {
                  setExperienceList((prev) => [newExperience, ...prev]);
                  setShowAddExperienceForm(false);
                }}
                onCancel={() => {
                  setShowAddExperienceForm(false);
                }}
              />
            </div>
          </dialog>
        )}
      </div>
    </div>
  );
}

export default App;
```

💡

Ready to check your work?  
[Become a member](https://reactpractice.dev/become-a-member/) and get access to the [official solution](https://reactpractice.dev/solution/tutorial-build-the-linkedin-add-experience-form/) and the comments section for feedback and discussion.