Skip to content

MidasVE/multi-step-form

Repository files navigation

Frontend Mentor - Multi-step form solution

This is a solution to the Multi-step form challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Users should be able to:

  • Complete each step of the sequence
  • Go back to a previous step to update their selections
  • See a summary of their selections on the final step and confirm their order
  • View the optimal layout for the interface depending on their device's screen size
  • See hover and focus states for all interactive elements on the page
  • Receive form validation messages if:
    • A field has been missed
    • The email address is not formatted correctly
    • A step is submitted, but no selection has been made

Screenshot

2023-06-24 09 38 30 multi-step-form-mauve-three vercel app 58c5cdaa6e39

Links

My process

Built with

What I learned

For certain fields, I had to create a field with multiple options. First, I just added these in the jsx manually, but I learned quickly that I had to do it differently if I wanted to keep the code maintainable. So I created Map and learned how to loop over it:

export const planPricing = new Map([
  [
    "arcade",
    {
      name: "Arcade",
      price: {
        monthly: 9,
        yearly: 90,
      },
    },
  ],
  [
    "advanced",
    {
      name: "Advanced",
      price: {
        monthly: 12,
        yearly: 120,
      },
    },
  ],
  [
    "pro",
    {
      name: "Pro",
      price: {
        monthly: 15,
        yearly: 150,
      },
    },
  ],
] as const)
{Array.from(planPricing.entries()).map(([key, value]) => (
                    <FormItem key={key}>
                      <FormLabel htmlFor={key}>
                        <FormControl>
                          <RadioGroupItem
                            className="sr-only"
                            value={key}
                            id={key}
                          />
                        </FormControl>
                        <Card className="cursor-pointer border hover:border-primary">
                          <CardContent className="flex gap-4 p-4 lg:flex-col lg:gap-8">
                            <Image
                              src={`/icon-${key}.svg`}
                              width={40}
                              height={40}
                              alt={key}
                            />
                            <div className="flex flex-col gap-2">
                              <span className="font-bold">{value.name}</span>
                              {yearlyBillingValue ? (
                                <>
                                  <span className="text-muted">
                                    {value.price.yearly}/yr
                                  </span>
                                  <span>2 months free</span>
                                </>
                              ) : (
                                <span className="text-muted">
                                  {value.price.monthly}/mo
                                </span>
                              )}
                            </div>
                          </CardContent>
                        </Card>
                      </FormLabel>
                    </FormItem>
                  ))}

Author