Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated authentication #24

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
412 changes: 324 additions & 88 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@ramonak/react-progress-bar": "^5.0.3",
"classnames": "^2.3.2",
"env-cmd": "^10.1.0",
"firebase": "^8.10.1",
"jsonwebtoken": "^9.0.0",
"papaparse": "^5.4.1",
"react": "^17.0.2",
"react-circular-progressbar": "^2.1.0",
Expand All @@ -13,12 +16,14 @@
"react-scripts": "4.0.3",
"react-search-box": "^2.3.0",
"react-select": "^5.7.0",
"react-slidy": "^4.3.3",
"react-spinners": "^0.13.8",
"react-toastify": "^8.1.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
Expand Down
11 changes: 7 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@ const App = () => {
<Route path="/" element={<HomeLayout />}>
<Route path="sign-up" element={<SignUp toast={toast} />} />
<Route path="upcoming" element={<Upcoming toast={toast} />} />
<Route path="tasks" element={<AllTasks />} />
<Route path="task-details" element={<TaskDetails />} />
<Route path="roadmap" element={<Roadmap />} />
<Route path="tasks" element={<AllTasks toast={toast} />} />
<Route
path="task-details"
element={<TaskDetails toast={toast} />}
/>
<Route path="roadmap" element={<Roadmap toast={toast} />} />
</Route>
<Route path="forgot-password" element={<ForgotPassword />} />
<Route path="community" element={<Community />} />
<Route path="login" element={<Login />} />
<Route path="home" element={<Home />} />
<Route path="verifyEmail" element={<EmailVerification />} />
<Route path="verification" element={<EmailVerification />} />
</Routes>
</BrowserRouter>
</AppContextProvider>
Expand Down
146 changes: 146 additions & 0 deletions src/components/AddChild/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import React, { useState, useEffect } from "react";
import classNames from "classnames/bind";
import styles from "./index.module.css";
import { useWindowSize } from "../../lib/hooks";
import {
AUTH_INPUT_LABELS,
SCHOOL_DISTRICT,
DISABILITY,
WINDOW_TYPE,
STATUS_CODE,
} from "../../lib/constants";
import { AuthInputBlock } from "../../components/AuthInputBlock";
import { AuthSelectBlock } from "../../components/AuthSelectBlock";
import { AuthButton } from "../AuthButton";

const cx = classNames.bind(styles);

export function AddChild(props) {
const isMobile = useWindowSize().type === WINDOW_TYPE.MOBILE;

const [child, setChild] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState("");
const [submitted, setSubmitted] = useState(false);
const [leavePage, setLeavePage] = useState(false);

useEffect(() => {
if (leavePage) {
if (submitted) {
props.setChildren([...props.currChildren, child]);
}
props.setAddChild(false);
}
}, [leavePage]);

const checkValidBirthday = () => {
const birthday = child.birthDate;

// Regular expression for MM-DD-YYYY format
const regex = /^\d{2}-\d{2}-\d{4}$/;

// Check if the input matches the regular expression
if (!regex.test(birthday)) {
return false;
}

// Check if the date is valid
const parts = birthday.split("-");
const month = parseInt(parts[0], 10);
const day = parseInt(parts[1], 10);
const year = parseInt(parts[2], 10);

// JavaScript Date object will automatically handle leap year
const date = new Date(year, month - 1, day);
const isValid =
date.getFullYear() === year &&
date.getMonth() === month - 1 &&
date.getDate() === day;

return isValid;
};

const onSubmit = async () => {
if (!child.firstName) props.toast("Please provide your child's name");
else if (!child.birthDate)
props.toast("Please provide your child's birthdate");
else if (!checkValidBirthday(child.birthDate))
props.toast("Please enter the birthday in the correct format");
else if (!child.schoolDistrict)
props.toast("Please provide your child's school district");
else if (!child.disabilities)
props.toast("Please provide your child's disability");
else {
setSubmitted(true);
setLeavePage(true);
}
};

return (
<div className={cx(styles.content)}>
<div className={cx(styles.popup)}>
<div classname={cx(styles.close_wrapper)}>
<div className={cx(styles.close)}>
<AuthButton
label={"X"}
onClick={() => setLeavePage(true)}
style={{
borderRadius: "30%",
height: "auto",
width: "30px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
/>
</div>{" "}
</div>
<h1 className={cx(styles.title)}>Add a Child</h1>
<AuthInputBlock
label={AUTH_INPUT_LABELS.FIRST_NAME}
containerClassName={cx(styles.inputBlock)}
value={child.firstName}
isMobile={isMobile}
onChange={(value) => setChild({ ...child, firstName: value })}
/>
<AuthInputBlock
label={AUTH_INPUT_LABELS.BIRTH_DATE}
containerClassName={cx(styles.inputBlock)}
value={child.birthDate}
placeholder={"MM-DD-YYYY"}
isMobile={isMobile}
onChange={(value) => setChild({ ...child, birthDate: value })}
/>
<AuthSelectBlock
label={AUTH_INPUT_LABELS.SCHOOL_DISTRICT}
containerClassName={cx(styles.selectBlock)}
options={SCHOOL_DISTRICT}
value={child.schoolDistrict}
isClearable={true}
isMulti={false}
isMobile={isMobile}
onChange={(value) =>
setChild({ ...child, schoolDistrict: value.label })
}
/>
<AuthSelectBlock
label={AUTH_INPUT_LABELS.DISABILITY}
containerClassName={cx(styles.selectBlock)}
options={DISABILITY}
placeholder={"Select Disabilities..."}
isClearable={true}
isMulti={true}
isMobile={isMobile}
onChange={(value) => setChild({ ...child, disabilities: value })}
/>
<AuthButton
className={cx(styles.register)}
label={AUTH_INPUT_LABELS.ADD_CHILD}
// pass child object back to sign up page
onClick={onSubmit}
isMobile={isMobile}
/>
</div>
</div>
);
}
85 changes: 85 additions & 0 deletions src/components/AddChild/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.content {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.2);

display: flex;
justify-content: center;
align-items: center;
}

.popup {
display: block;
background-color: white;
width: 80%;
height: auto;

font-family: "Poppins";
padding: 30px;
border-radius: 30px;
}

.title {
margin: 0;
font-size: 7vw;
}

.desc {
font-size: 4vw;
width: 100%;
}

.input {
width: 95%;
font-family: "Poppins";
font-size: 3vw;
height: 30vh;
padding: 10px;
margin: 15px 0;
border-radius: 20px;
}

.submit {
/* background-color: rgb(2, 152, 186);
border-radius: 20px;
font-size: 5vw;
padding: 10px;
width: 50%;
color: white; */
width: 99%;
height: 6vh;
font-size: 2vh;
font-family: "Poppins";
font-weight: bold;
color: white;
border-width: 0;
border-radius: 20px;
background-color: rgb(2, 152, 186);
padding: 0;
}
.submit:hover {
cursor: pointer;
transform: scale(1.01);
transition: 0.2s;
box-shadow: 0 6px 4px darkgray;
}

.submit_wrapper {
display: flex;
align-items: center;
justify-content: center;
border-width: 0;
}

.close_wrapper {
display: flex;
border-radius: 50%;
}

.close {
margin-left: auto;
width: 5vw;
}
58 changes: 43 additions & 15 deletions src/components/AllTasksSection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,55 @@ import styles from "./index.module.css";
import classNames from "classnames/bind";
import React from "react";
import { TaskListItem } from "../../components/TaskListItem";
import { useState, useEffect } from "react";
import { COLORS_ARR } from "../../lib/constants";

const cx = classNames.bind(styles);

export const AllTasksSection = React.forwardRef((props, ref) => {
const { taskList } = props;
const { taskList, isMobile } = props;
const [isExpanded, setIsExpanded] = useState(false);
const [color, setColor] = useState("#0198BA26");

const toggleExpansion = () => {
setIsExpanded(!isExpanded);
};

useEffect(() => {
// randomize color for the display block
setColor(COLORS_ARR[Math.floor(Math.random() * COLORS_ARR.length)]);
}, []);

return (
<div className={cx(styles.tasksSection)}>
<p className={cx(styles.childName)}>{taskList[0]?.childName}</p>
<div>
{taskList.map((item, index) => (
<TaskListItem
taskName={item.title}
dueAt={item.timePeriod}
taskId={item._id}
childName={item.childName}
childId={item.childId}
completed={item.completed}
key={index}
/>
))}
<div
className={cx(styles.entireSection, {
[styles.mobile]: isMobile,
})}
style={{
backgroundColor: color,
}}
>
<p
onClick={toggleExpansion}
className={cx(styles.childName, {
[styles.mobile]: isMobile,
})}
>
{taskList[0]?.childName}
</p>
<div className={cx(styles.tasksSection)}>
{isExpanded &&
taskList.map((item, index) => (
<TaskListItem
taskName={item.title}
dueAt={item.timePeriod}
taskId={item._id}
childId={item.childId}
completed={item.completed}
key={index}
isMobile={isMobile}
/>
))}
</div>
</div>
);
Expand Down
Loading