first commit
This commit is contained in:
215
src/Components/SignupPage/SignupPage.js
Normal file
215
src/Components/SignupPage/SignupPage.js
Normal file
@@ -0,0 +1,215 @@
|
||||
import React, { useState } from "react";
|
||||
import Col from "react-bootstrap/Col";
|
||||
import Form from "react-bootstrap/Form";
|
||||
import Row from "react-bootstrap/Row";
|
||||
import Button from "../../pageElements/Button";
|
||||
import { db, auth } from "../../firebase";
|
||||
import { createUserWithEmailAndPassword } from "firebase/auth";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import TextInput from "../../pageElements/TextInput";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { collection, setDoc, doc } from "firebase/firestore";
|
||||
import { splitEvery } from "../../Utils/Array";
|
||||
import {
|
||||
getFormDataDefaults,
|
||||
getValidatedFormData,
|
||||
handleFormDataChange,
|
||||
isFormDataHasErrors,
|
||||
} from "../../Utils/Form";
|
||||
import { objectMap } from "../../Utils/Object";
|
||||
import { signupfields } from "../../Constants/Fields/Signupfields";
|
||||
import "../../styles/signup.scss";
|
||||
|
||||
const SignupPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const [notice, setNotice] = useState("");
|
||||
|
||||
const fieldsChunkSize = 2;
|
||||
|
||||
const [isBusy, setIsBusy] = useState(false);
|
||||
const [data, setData] = useState(getFormDataDefaults(signupfields));
|
||||
|
||||
const handleChangeInput = (e, name) => {
|
||||
const newData = handleFormDataChange(e, name, data, signupfields);
|
||||
if (newData !== null) {
|
||||
setData(newData);
|
||||
}
|
||||
};
|
||||
|
||||
const validateData = () => {
|
||||
const newData = getValidatedFormData(data, signupfields);
|
||||
const hasErrors = isFormDataHasErrors(newData);
|
||||
setData(newData);
|
||||
return hasErrors ? null : objectMap(({ value }) => value, newData);
|
||||
};
|
||||
|
||||
async function saveUserData(authId, dataValues) {
|
||||
const appUserId = uuidv4();
|
||||
const firmId = uuidv4();
|
||||
const fbAuthUid = authId;
|
||||
const {
|
||||
firstName,
|
||||
lastName,
|
||||
firm,
|
||||
telephone,
|
||||
streetAddress,
|
||||
city,
|
||||
state,
|
||||
zipCode,
|
||||
barNumber,
|
||||
practiceArea,
|
||||
email,
|
||||
} = dataValues;
|
||||
|
||||
const userData = {
|
||||
appUserId,
|
||||
fbAuthUid,
|
||||
firmId,
|
||||
firstName,
|
||||
lastName,
|
||||
firm,
|
||||
telephone,
|
||||
streetAddress,
|
||||
city,
|
||||
state,
|
||||
zipCode,
|
||||
barNumber,
|
||||
practiceArea,
|
||||
email,
|
||||
};
|
||||
|
||||
try {
|
||||
const usersRef = collection(db, "users");
|
||||
await setDoc(doc(usersRef, fbAuthUid), userData);
|
||||
} catch (error) {
|
||||
console.log(`Error saving new user to db: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
const handleSignup = async (e) => {
|
||||
e.preventDefault();
|
||||
if (isBusy) {
|
||||
return;
|
||||
}
|
||||
const dataValues = validateData();
|
||||
if (dataValues === null) {
|
||||
return;
|
||||
}
|
||||
setIsBusy(true);
|
||||
try {
|
||||
const userCredential = await createUserWithEmailAndPassword(
|
||||
auth,
|
||||
dataValues.email,
|
||||
dataValues.password
|
||||
);
|
||||
const user = userCredential.user;
|
||||
await saveUserData(user.uid, dataValues);
|
||||
navigate("/");
|
||||
} catch (error) {
|
||||
setIsBusy(false);
|
||||
setNotice(
|
||||
error.message || "Sorry, something went wrong. Please try again."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="signup-super-container">
|
||||
<div className="signup-sub-container">
|
||||
<div className="signup-header">
|
||||
<h1 className="signup-header-text">Create a Novodraft account</h1>
|
||||
</div>
|
||||
<Form className="signup-form">
|
||||
{splitEvery(
|
||||
Object.keys(signupfields).slice(0, -2),
|
||||
fieldsChunkSize
|
||||
).map((names, j) => (
|
||||
<Row key={`row${j}`}>
|
||||
{names.map((name, i) => (
|
||||
<Col key={`${name}${i + fieldsChunkSize * j}`} className="mb-3">
|
||||
<TextInput
|
||||
name={name}
|
||||
value={data[name].value}
|
||||
onChange={(e) => handleChangeInput(e, name)}
|
||||
error={data[name].error}
|
||||
message={data[name].message}
|
||||
label={
|
||||
data[name].value.length === 0
|
||||
? signupfields[name].label
|
||||
: ""
|
||||
}
|
||||
type={signupfields[name].type}
|
||||
values={signupfields[name].values}
|
||||
disabled={isBusy}
|
||||
/>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
))}
|
||||
<Row>
|
||||
<Col className="mb-3">
|
||||
<TextInput
|
||||
id="signupPassword"
|
||||
type="password"
|
||||
label={
|
||||
data.password.value.length === 0
|
||||
? signupfields.password.label
|
||||
: ""
|
||||
}
|
||||
value={data.password.value}
|
||||
error={data.password.error}
|
||||
message={data.password.message}
|
||||
onChange={(e) => handleChangeInput(e, "password")}
|
||||
disabled={isBusy}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col className="mb-3">
|
||||
<TextInput
|
||||
id="confirmPassword"
|
||||
type="password"
|
||||
label={
|
||||
data.confirmPassword.value.length === 0
|
||||
? signupfields.confirmPassword.label
|
||||
: ""
|
||||
}
|
||||
value={data.confirmPassword.value}
|
||||
error={data.confirmPassword.error}
|
||||
message={data.confirmPassword.message}
|
||||
onChange={(e) => handleChangeInput(e, "confirmPassword")}
|
||||
disabled={isBusy}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
<div className="signup-button-box">
|
||||
<Button
|
||||
className="primary-button"
|
||||
type="button"
|
||||
size="lg"
|
||||
onClick={handleSignup}
|
||||
disabled={isBusy}
|
||||
labelText="Create Account"
|
||||
/>
|
||||
<div className="mt-3">
|
||||
<span>
|
||||
<Link to="/">Return to login</Link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{"" !== notice && (
|
||||
<>
|
||||
<br></br>
|
||||
<div className="alert alert-danger" role="alert">
|
||||
{notice}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignupPage;
|
||||
Reference in New Issue
Block a user