ankitbisen28 / Atelier

Letest web app for custom clothing, Using React vite and Nodejs
https://atelier-client.vercel.app/
0 stars 1 forks source link

Feature Request: Multi-Step Registration Form #17

Open ankitbisen28 opened 3 months ago

ankitbisen28 commented 3 months ago

Description

Implement a multi-step registration form for new users. The form should guide users through several steps to collect all necessary information as per the user schema.

Requirements

  1. Step 1: Account Information:

    • Collect username
    • Collect email
    • Collect password
  2. Step 2: Role Selection:

    • Select role (Consumer or Maker)
  3. Step 3: Profile Information:

    • Collect fullName
    • Collect address
    • Collect phoneNumber
    • Collect profilePicture (file upload)
    • Collect country
  4. Step 4: Confirmation:

    • Display a summary of all entered information.
    • Provide a "Submit" button to finalize registration.
    • Option to go back and edit information before final submission.
  5. Form Validation:

    • Ensure all required fields are filled.
    • Validate email format and uniqueness.
    • Validate password strength.
    • Ensure username is unique.
  6. Error Handling:

    • Display appropriate error messages for invalid inputs.
    • Handle server-side validation errors and display messages to the user.

Acceptance Criteria

Additional Information

Mockups / Examples

Provide any mockups or examples of the desired component if available.

Technical Requirements

Steps to Implement

  1. Create Form Component:

    • Create a multi-step form component with the specified steps.
    import React, { useState } from 'react';
    import axios from 'axios';
    
    const RegistrationForm = () => {
        const [step, setStep] = useState(1);
        const [formData, setFormData] = useState({
            username: '',
            email: '',
            password: '',
            role: '',
            fullName: '',
            address: '',
            phoneNumber: '',
            profilePicture: '',
            country: ''
        });
    
        const handleChange = (e) => {
            const { name, value } = e.target;
            setFormData({
                ...formData,
            });
        };
    
        const handleFileChange = (e) => {
            setFormData({
                ...formData,
                profilePicture: e.target.files[0]
            });
        };
    
        const nextStep = () => {
            setStep(step + 1);
        };
    
        const prevStep = () => {
            setStep(step - 1);
        };
    
        const handleSubmit = async (e) => {
            e.preventDefault();
            try {
                const formDataCopy = { ...formData };
                delete formDataCopy.profilePicture;
    
                const res = await axios.post('/api/register', formDataCopy);
    
                if (formData.profilePicture) {
                    const formDataUpload = new FormData();
                    formDataUpload.append('file', formData.profilePicture);
                    await axios.post(`/api/upload-profile-picture/${res.data.userId}`, formDataUpload);
                }
    
                // Redirect or show success message
            } catch (error) {
                console.error('Registration failed', error);
                // Display error message
            }
        };
    
        switch (step) {
            case 1:
                return (
                    <div>
                        <h2>Step 1: Account Information</h2>
                        <input type="text" name="username" value={formData.username} onChange={handleChange} placeholder="Username" required />
                        <input type="email" name="email" value={formData.email} onChange={handleChange} placeholder="Email" required />
                        <input type="password" name="password" value={formData.password} onChange={handleChange} placeholder="Password" required />
                        <button onClick={nextStep}>Next</button>
                    </div>
                );
            case 2:
                return (
                    <div>
                        <h2>Step 2: Role Selection</h2>
                        <select name="role" value={formData.role} onChange={handleChange} required>
                            <option value="">Select Role</option>
                            <option value="Consumer">Consumer</option>
                            <option value="Maker">Maker</option>
                        </select>
                        <button onClick={prevStep}>Back</button>
                        <button onClick={nextStep}>Next</button>
                    </div>
                );
            case 3:
                return (
                    <div>
                        <h2>Step 3: Profile Information</h2>
                        <input type="text" name="fullName" value={formData.fullName} onChange={handleChange} placeholder="Full Name" required />
                        <input type="text" name="address" value={formData.address} onChange={handleChange} placeholder="Address" />
                        <input type="text" name="phoneNumber" value={formData.phoneNumber} onChange={handleChange} placeholder="Phone Number" />
                        <input type="file" name="profilePicture" onChange={handleFileChange} />
                        <input type="text" name="country" value={formData.country} onChange={handleChange} placeholder="Country" />
                        <button onClick={prevStep}>Back</button>
                        <button onClick={nextStep}>Next</button>
                    </div>
                );
            case 4:
                return (
                    <div>
                        <h2>Step 4: Confirmation</h2>
                        <p>Username: {formData.username}</p>
                        <p>Email: {formData.email}</p>
                        <p>Role: {formData.role}</p>
                        <p>Full Name: {formData.fullName}</p>
                        <p>Address: {formData.address}</p>
                        <p>Phone Number: {formData.phoneNumber}</p>
                        <p>Country: {formData.country}</p>
                        {/* Display profile picture preview if needed */}
                        <button onClick={prevStep}>Back</button>
                        <button onClick={handleSubmit}>Submit</button>
                    </div>
                );
            default:
                return null;
        }
    };
    
    export default RegistrationForm;
  2. Backend: Handle Registration:

    • Create an endpoint to handle user registration and upload profile pictures.
    const express = require('express');
    const router = express.Router();
    const User = require('../models/user');
    const multer = require('multer');
    const upload = multer({ dest: 'uploads/' });
    
    router.post('/register', async (req, res) => {
        try {
            const { username, email, password, role, profile } = req.body;
            const newUser = new User({ username, email, password, role, profile });
            await newUser.save();
            res.status(201).json({ userId: newUser._id });
        } catch (error) {
            res.status(500).json({ message: 'Registration failed', error });
        }
    });
    
    router.post('/upload-profile-picture/:userId', upload.single('file'), async (req, res) => {
        try {
            const user = await User.findById(req.params.userId);
            if (!user) {
                return res.status(404).json({ message: 'User not found' });
            }
            user.profile.profilePicture = req.file.path;
            await user.save();
            res.status(200).json({ message: 'Profile picture uploaded' });
        } catch (error) {
            res.status(500).json({ message: 'Upload failed', error });
        }
    });
    
    module.exports = router;
  3. Integrate and Test:

    • Ensure the frontend and backend components are integrated correctly.
    • Test the multi-step registration form thoroughly to ensure it works as expected.

Tasks