Skip to content

Onboarding Page (pages/onboarding/index.tsx)

Overview

The Onboarding page guides new users through the initial setup process for their BidScript account. It collects essential company information, user preferences, and sets up the workspace for optimal use.

Features

  • Multi-step onboarding wizard
  • Company profile setup
  • User preference configuration
  • Document template selection
  • Guided tutorial for core features
  • Progress tracking and persistence
  • Quick start option for immediate access

URL Parameters

  • quick: Optional - Boolean flag to enable quick onboarding process

Implementation

State Management

// Form data state
const [companyFormData, setCompanyFormData] = useState<CompanyFormData>({
  companyName: "",
  tradingName: "",
  registeredCompanyNumber: "",
  vatNumber: "",
  dateOfIncorporation: "",
  businessAddress: "",
  registeredAddress: {
    street: "",
    city: "",
    county: "",
    postcode: "",
    country: "",
  },
  operatingAddress: {
    street: "",
    city: "",
    county: "",
    postcode: "",
    country: "",
  },
  contactDetails: {
    fullName: "",
    jobTitle: "",
    email: "",
    phone: "",
  },
  generalEmail: "",
  websiteUrl: "",
  companyProfile: {
    description: "",
    employeeCount: "",
    annualTurnover: "",
    sectors: [],
    geographicCoverage: "",
  },
  legalDetails: {
    entityType: "",
    parentCompany: "",
    accreditations: "",
    insurance: "",
  },
});

// Onboarding progress tracking
const [currentStep, setCurrentStep] = useState<number>(0);
const [completedSteps, setCompletedSteps] = useState<number[]>([]);
const [isQuickStart, setIsQuickStart] = useState<boolean>(false);

Methods

// Form navigation and validation
const handleNextStep = () =>
// Validates current step and advances to the next

const handlePreviousStep = () =>
// Returns to the previous onboarding step

const validateStep = (step: number) =>
// Validates the data for a specific step

// Data submission
const handleSubmitCompanyProfile = async () =>
// Submits the completed company profile data

const handleQuickStart = async () =>
// Skips full onboarding for a minimal setup

// Navigation
const completeOnboarding = () =>
// Finalises onboarding and redirects to dashboard

HTML Structure

<div className="onboarding-container min-h-screen flex flex-col bg-gradient-to-br from-blue-50 to-white">
  {/* Header */}
  <header className="py-6 px-8 flex justify-between items-center border-b">
    <div className="logo">
      <img src="/logo.svg" alt="BidScript Logo" className="h-10" />
    </div>
    {!isQuickStart && (
      <Button variant="ghost" onClick={handleQuickStart}>
        Quick Start
      </Button>
    )}
  </header>

  {/* Progress indicator */}
  <div className="progress-container px-8 py-4">
    <div className="flex justify-between items-center max-w-3xl mx-auto">
      {steps.map((step, index) => (
        <div key={index} className="flex flex-col items-center">
          <div
            className={`step-indicator h-10 w-10 rounded-full flex items-center justify-center ${
              completedSteps.includes(index)
                ? "bg-green-500 text-white"
                : currentStep === index
                ? "bg-blue-500 text-white"
                : "bg-gray-200 text-gray-500"
            }`}
          >
            {completedSteps.includes(index) ? (
              <CheckIcon className="h-5 w-5" />
            ) : (
              index + 1
            )}
          </div>
          <span className="text-sm mt-2">{step.title}</span>
        </div>
      ))}
    </div>
  </div>

  {/* Step content */}
  <div className="flex-grow flex items-center justify-center py-8">
    <div className="max-w-3xl w-full px-6">
      <AnimatePresence mode="wait">
        <motion.div
          key={currentStep}
          initial={{ opacity: 0, x: 20 }}
          animate={{ opacity: 1, x: 0 }}
          exit={{ opacity: 0, x: -20 }}
          transition={{ duration: 0.3 }}
        >
          {currentStep === 0 && (
            <CompanyInformationStep
              formData={companyFormData}
              updateFormData={updateCompanyFormData}
            />
          )}
          {currentStep === 1 && (
            <AddressInformationStep
              formData={companyFormData}
              updateFormData={updateCompanyFormData}
            />
          )}
          {currentStep === 2 && (
            <ContactInformationStep
              formData={companyFormData}
              updateFormData={updateCompanyFormData}
            />
          )}
          {currentStep === 3 && (
            <CompanyProfileStep
              formData={companyFormData}
              updateFormData={updateCompanyFormData}
            />
          )}
          {currentStep === 4 && (
            <LegalInformationStep
              formData={companyFormData}
              updateFormData={updateCompanyFormData}
            />
          )}
          {currentStep === 5 && (
            <ReviewAndSubmitStep
              formData={companyFormData}
              onSubmit={handleSubmitCompanyProfile}
            />
          )}
        </motion.div>
      </AnimatePresence>
    </div>
  </div>

  {/* Navigation buttons */}
  <div className="navigation-container border-t py-6 px-8">
    <div className="flex justify-between max-w-3xl mx-auto">
      <Button
        variant="outline"
        onClick={handlePreviousStep}
        disabled={currentStep === 0}
      >
        Previous
      </Button>
      <Button
        onClick={
          currentStep === steps.length - 1
            ? handleSubmitCompanyProfile
            : handleNextStep
        }
      >
        {currentStep === steps.length - 1 ? "Complete Setup" : "Next"}
      </Button>
    </div>
  </div>
</div>

Props

No props - page component

Components/API Routes Used

Components

API Routes

  • /api/onboarding/company - Saves company profile information
  • /api/onboarding/quickStart - Initiates quick start setup
  • /api/onboarding/progress - Tracks onboarding progress

Routes to Page

  • Direct: /onboarding
  • Quick start: /onboarding/quick
  • From: Sign-up completion redirect
  • From: First login redirect

Dependencies

import { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { motion, AnimatePresence } from "framer-motion";
import { ensureCompany, getApiPath } from "@/lib/apiUtils";

Notes

  • Automatically redirects authenticated users who have completed onboarding
  • Persists progress for users who exit onboarding midway
  • Provides optional quick start path for minimal setup
  • Implements form validation for each step
  • Features smooth animations between steps
  • Optimised for mobile and desktop devices