Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found

Submitted

Responsive Multi Step Form (React + TS and SCSS)

#react#react-router#sass/scss#typescript#vite
Cipi• 190

@CipiVlad

Desktop design screenshot for the Multi-step form coding challenge

This is a solution for...

  • HTML
  • CSS
  • JS
4advanced
View challenge

Design comparison


SolutionDesign

Solution retrospective


What are you most proud of, and what would you do differently next time?

I like the folder-structure. I enjoyed separating content in "data" modules from rendering "components" on"pages", as well as having my stylesheets in "scss" files. It seems to me well structured and clean. I didn't face any problems losing myself in my own code.

I decided to combine "localStorage" with the "useContext - Hook" for user input storage. Simply because 'till now I either worked with JSON-Server or MongoDB. Since I haven't used localStorage for a while now, I thought it'd be a great chance for this project. Then I added the useContext - Hook for sharing the input data between the routes and passing it either forward towards the finishing site, or for going back and updating data. You can look up the browser dev tools "application" for what has been stored inside Local storage. This also hepled me for dev - purposes, so that there's no need to uncommend the required fields of the first page when jumping back to it.

I really enjoyed getting my styles done with sass variables.

***Start with the mobile-first workflow and style the app first, rather than getting both, logic and styles done at the same time. ***Dockerizing my web app. Found a helpful post on dev.to by Lester Diaz Perez

What challenges did you encounter, and how did you overcome them?

styling

I found it somehow cumbersome to adapt the container size styling on mobile / desktop version, when i.e. toggling between monthly or yearly plans. Working here and there with fixed widths and browser Inspect tool worked for me. I found working from time to time with the tsx inline styling and ternary operator is a great thing, i.e. toggling between active - inactive classes.

logic

working with ts and localStorage has also led to irritation for me. For example, on the finishing page I get my object saved in localStorage: name: ['Customisable profile']. I had previously selected this on the addons page and it is saved in localStorage with setItem.

When I call getItem on the following finishing page in console.log(typeof getItem("addons")), I get: "object".

If I log console.log(getItem("addons")) I get: {price: Array(1), name: Array(1)} name: ['Customisable profile'] price: ['$2/mo']

In order to be able to use it type-safe in my children component and pass it to my parent component, I call the following in my FinishCard, for example:

type FinishCardProps = { getItem: string[] } But I get the following message in vscode: This expression cannot be called. The type "string[]" has no call signatures.ts(2349)

So I continued working with "any" as a transition, but that misses the point of TS, doesn't it? Because getItem is defined as an array of strings in the FinishCardProps type, but I'm trying to use it as a function by calling getItem("addon"), I need to set it to a function in FinishCardProps. But it's still not working with "getItem: (item: string) => void". I'm missing some crucial point...

What specific areas of your project would you like help with?

  1. Actually I wanted to test my web app with jest / react-testing-library, but I think my vite config wasn't setup right. Has someone found a nice article or some other content?
  2. I'd really like to read some thoughts/advice on how to use TS in this app efficiently.

Community feedback

P
markus• 1,430

@markuslewin

Posted

Regarding the types, I think Fully Typed Web Apps does a great job explaining some approaches to these types of problems! The TLDR is that you can use a validation library (like zod) to parse objects you can't know the shape of:

// zod schema
const personInfoSchema = z.object({
  name: z.string(),
  email: z.string(),
  phone: z.string(),
});

const PersonalInfoCard = () => {
  // Read initial state from localStorage
  const [inputs, setInputs] = useState(() => {
    try {
      // Parse string
      const rawPersonInfo = JSON.parse(localStorage.getItem("person")!);
      // Parse object
      const personInfo = personInfoSchema.parse(rawPersonInfo);
      // const personInfo: {
      //   name: string;
      //   email: string;
      //   phone: string;
      // };
      return personInfo;
    } catch (error) {
      console.error("Error setting localStorage:", error);
      // Default values
      return { name: "", email: "", phone: "" };
    }
  });
};

Marked as helpful

1

Cipi• 190

@CipiVlad

Posted

Thanks a lot @markuslewin this is a great piece of advice! And the link you shared is really well. You're my mentor of the week :)

1

Please log in to post a comment

Log in with GitHub
Discord logo

Join our Discord community

Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!

Join our Discord