DEV Community

AjeaS
AjeaS

Posted on

Self-documentation of Hire +Plus: V1 (7)

What I cover

  • Updates

  • Sign up Form functionality

  • Sign up helper functions in firebase

  • Data structure & Trello


Updates

I changed my components return type from: React.FunctionalComponent => ReactElement. I don't think the previous was the correct one lol.

const Signup = (): ReactElement =>
Enter fullscreen mode Exit fullscreen mode

added function to reset form values after submission

Sign up Form functionality

I mostly copied the code from sign-in to the sign-up, as most of it is the same. I added additional form fields. The userChoice prop is passed down to handle the separation of creating an account for an employer vs employee. I will handle this within the helper function within firebase.
Note: I passed it to the sign-in component as well, to handle when a user uses the google sign-in method.

// ...other imports
const defaultFormFields = {
    displayName: '',
    email: '',
    password: '',
    confirmPassword: '',
};
type ChildProps = {
    userChoice: string;
};
const Signup = (props: ChildProps): ReactElement => {
    const { userChoice } = props;

    const [formFields, setFormFields] = useState(defaultFormFields);
    const { email, password, displayName, confirmPassword } = formFields;

    const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
        const { name, value } = event.target;
        setFormFields({ ...formFields, [name]: value });
    };
    const resetFormFields = () => {
        setFormFields(defaultFormFields);
    };
    const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        if (password !== confirmPassword) {
            // set error message
            return;
        }
        signUpEmailAndPassword({ email, password, displayName }, userChoice);
        resetFormFields();
    };
    return (
       <div>....</div>
    );
};

export default Signup;
Enter fullscreen mode Exit fullscreen mode

Sign up helper functions (Firebase)

I created 2 functions that will help in creating a user document after signing up.

  1. signUpEmailAndPassword() I sign up a user using the email and password with Firebase's createUserWithEmailAndPassword() helper method. After this, I create a user in the DB at the same time, hence my createUserBasedOnChoice() helper method. Lastly, this function will not run if the auth url params doesn't contain either of the choices from allowedChoices.
export const signUpEmailAndPassword = async (
    formFields: FormFields,
    userChoice: string
) => {
    const { email, password, displayName } = formFields;
    const allowedChoices = ['employees', 'employers'];
    if (!allowedChoices.includes(userChoice)) return;
    try {
        await createUserWithEmailAndPassword(auth, email, password);
        await createUserDocumentFromAuth(
            auth.currentUser,
            { displayName },
            userChoice
        );
    } catch (error) {
        console.log('from within sign up method', error);
    }
};
Enter fullscreen mode Exit fullscreen mode

2.createUserBasedOnChoice()
The additionalInfo params is/if the user specifies a displayName. I defined the return type to either void or a created user document. Based on user choice, I'll create a collection for either employers or employees. I'll store the appropriate data to the user based on that choice, along with the displayName (if any).

export const createUserBasedOnChoice = async (
    authUser: User,
    additionalInfo = {} as AdditionalInfo,
    userChoice: string
): Promise<void | QueryDocumentSnapshot<UserData>> => {
    if (!authUser) return;
    const userDocRef =
        userChoice === 'employees'
            ? doc(db, 'employees', authUser.uid)
            : doc(db, 'employers', authUser.uid);

    const userSnapShot = await getDoc(userDocRef);

    // if user doc doesn't exist, will create one in collection
    if (!userSnapShot.exists()) {
        const { email, displayName } = authUser;
        const createdAt = new Date();

        try {
            if (userChoice === 'employees') {
                await setDoc(userDocRef, {
                    email,
                    displayName,
                    createdAt,
                    ...additionalInfo,
                    title: '',
                    isForHire: false,
                    websiteURL: '',
                    githubUrl: '',
                    yearsOfExperience: 0,
                    skills: [],
                    summary: '',
                    projects: [],
                });
            } else if (userChoice === 'employers') {
                await setDoc(userDocRef, {
                    email,
                    displayName,
                    createdAt,
                    ...additionalInfo,
                    company: '',
                    companyURL: '',
                    isHiring: false,
                    companySize: 50,
                    companyType: '',
                    jobs: [],
                });
            }
        } catch (error) {
            console.log('get user auth and create doc', error);
        }
        return userSnapShot as QueryDocumentSnapshot<UserData>;
    }
};
Enter fullscreen mode Exit fullscreen mode

These are the types I defined for my params within in these functions

type AdditionalInfo = {
    displayName?: string;
};
type UserData = {
    createdAt: Date;
    displayName: string;
    email: string;
};
type FormFields = {
    email: string;
    password: string;
    displayName: string;
};
Enter fullscreen mode Exit fullscreen mode

Data structure for project & Trello

Initially, I have 4 sets of data that I plan to use throughout this project.

  • User
  • Company
  • Project
  • Job

// User
sample = {
  id: xxxxxxxx
  name: james
  email: james@mail.com
  title: Front-end developer
  isForHire: true
  websiteUrl: www.me.com
  githubUrl: www.james@github.com
  yearsOfExperience: 3,
  skills: [react, javascript, nodejs]
  summary: lorem ipsum
  projects: [Project]
}

// Project
sample = {
  id: xxxxxxxxxx,
  title: React Project,
  tech: [react, node],
  summary: lorem ipsum,
  github: www.reactproject@github.com,
  projectUrl: www.reactproject.com
}

// Company
sample = {
  id: xxxxxxxxxx,
  company: Goodcorp,
  companyUrl: www.Goodcorp.com
  email: goodcorp@mail.com,
  isHiring: true,
  companySize: 1-50,
  companyType: private
  jobs: [Jobs]
}

// Job
sample = {
  id: xxxxxxxx,
  position: Web developer,
  location: remote,
  salary: 70k,
  datePosted: Jun 1,2022,
  jobType: full-time,
  applyUrl: www.mycompany.com
  description: lorem ipsum
}

Enter fullscreen mode Exit fullscreen mode

A glimpse of what I have in Trello for managing this project :)

Trello for project

That's all for now. Stay tuned for more! View the full source code.

P.S I might be getting into Redux in the next one, I want to add in small pieces at a time before getting too in-depth and have to refactor later. Just my preference, Happy Friday!

Top comments (0)