Self-documentation of Hire +Plus: V1 (7)
Tags: webdev, react, programming, javascript
Published: 2022-06-03 22:36:50

## 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. 

```javascript
const Signup = (): ReactElement =>
```

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.

```javascript
// ...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;
```

## 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`. 

```javascript
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);
	}
};
```
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). 

```javascript
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>;
	}
};
```

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

```javascript
type AdditionalInfo = {
	displayName?: string;
};
type UserData = {
	createdAt: Date;
	displayName: string;
	email: string;
};
type FormFields = {
	email: string;
	password: string;
	displayName: string;
};
```

## Data structure for project & Trello
Initially, I have 4 sets of data that I plan to use throughout this project.

- User 
- Company
- Project
- Job

```javascript

// 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
}

```

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

![Trello for project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yb3yfb8dvbf6oqhsq4p2.png)
 
That's all for now. Stay tuned for more! View the [full source code](https://github.com/AjeaSmith/hire-plus-v1).

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!