From a01905df8b1fca62ef856e7273f7d7609fcd1c15 Mon Sep 17 00:00:00 2001 From: KatKowalik Date: Wed, 10 Apr 2024 12:35:50 -0400 Subject: [PATCH] first stage of signup page --- package-lock.json | 16 + package.json | 1 + src/App.jsx | 2 + src/components/InputField/InputField.jsx | 22 ++ src/components/Navbar/Navbar.jsx | 329 ++++++++++++------ .../PasswordInputField/PasswordInputField.jsx | 42 +++ src/pages/SignUpPage/SignUpPage.jsx | 49 +++ tailwind.config.js | 185 +++++----- 8 files changed, 460 insertions(+), 186 deletions(-) create mode 100644 src/components/InputField/InputField.jsx create mode 100644 src/components/PasswordInputField/PasswordInputField.jsx create mode 100644 src/pages/SignUpPage/SignUpPage.jsx diff --git a/package-lock.json b/package-lock.json index 8e38150..c4c166d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "react-chartjs-2": "^5.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.51.1", "react-router": "^6.17.0", "react-router-dom": "^6.17.0", "react-swipeable-list": "^1.9.3", @@ -5610,6 +5611,21 @@ "react": "^18.2.0" } }, + "node_modules/react-hook-form": { + "version": "7.51.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.1.tgz", + "integrity": "sha512-ifnBjl+kW0ksINHd+8C/Gp6a4eZOdWyvRv0UBaByShwU8JbVx5hTcTWEcd5VdybvmPTATkVVXk9npXArHmo56w==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index f19ddc9..a466da8 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "react-chartjs-2": "^5.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", + "react-hook-form": "^7.51.1", "react-router": "^6.17.0", "react-router-dom": "^6.17.0", "react-swipeable-list": "^1.9.3", diff --git a/src/App.jsx b/src/App.jsx index 3c7f266..1b2eae4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,6 +6,7 @@ import AboutUsPage from './pages/AboutUsPage/AboutUsPage'; import TutorialPage from './components/TutorialPage/TutorialPage'; import ShareSpoonfull from './pages/ShareSpoonfull/ShareSpoonfull'; import Navbar from './components/Navbar/Navbar'; +import SignUpPage from './pages/SignUpPage/SignUpPage'; import "@fontsource/lato"; import "@fontsource/lato/400.css"; import "@fontsource/lato/700.css"; @@ -112,6 +113,7 @@ function App() { } /> } /> } /> + } /> ) diff --git a/src/components/InputField/InputField.jsx b/src/components/InputField/InputField.jsx new file mode 100644 index 0000000..69da255 --- /dev/null +++ b/src/components/InputField/InputField.jsx @@ -0,0 +1,22 @@ +/* eslint-disable react/prop-types */ +import { useForm } from "react-hook-form"; + +const InputField = ({ name, label, type }) => { + const { register } = useForm(); + + return ( +
+ + +
+ ); +}; + +export default InputField; diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx index 514e3ec..6689316 100644 --- a/src/components/Navbar/Navbar.jsx +++ b/src/components/Navbar/Navbar.jsx @@ -1,13 +1,28 @@ /* eslint-disable react/prop-types */ import { useEffect, useState } from "react"; -import { Link } from 'react-router-dom' +import { Link } from "react-router-dom"; import { createPortal } from "react-dom"; -import { AppBar, Badge, Box, Toolbar, Typography, IconButton, useTheme, useMediaQuery, Divider, List, Drawer, ListItemButton, ListItemIcon, styled } from '@mui/material' -import SpoonsModal from '../SpoonsModal/SpoonsModal'; -import MenuIcon from '@mui/icons-material/Menu'; +import { + AppBar, + Badge, + Box, + Toolbar, + Typography, + IconButton, + useTheme, + useMediaQuery, + Divider, + List, + Drawer, + ListItemButton, + ListItemIcon, + styled, +} from "@mui/material"; +import SpoonsModal from "../SpoonsModal/SpoonsModal"; +import MenuIcon from "@mui/icons-material/Menu"; import logo from "../../assets/spoonfull-logo.svg"; -import HomeIcon from '@mui/icons-material/Home'; -import DirectionsWalkIcon from '@mui/icons-material/DirectionsWalk'; +import HomeIcon from "@mui/icons-material/Home"; +import DirectionsWalkIcon from "@mui/icons-material/DirectionsWalk"; import aboutUsIcon from "../../assets/about-us-icon.svg"; import faqIcon from "../../assets/faq-icon.svg"; import shareLinkIcon from "../../assets/share-link-icon.svg"; @@ -25,87 +40,115 @@ const Navbar = ({ plannedSpoons, setPlannedSpoons, showWelcomePage, - showTutorialPage }) => { - + showTutorialPage, +}) => { const [open, setOpen] = useState(false); const theme = useTheme(); - const largeScreen = useMediaQuery(theme.breakpoints.up("md")) - const mediumScreen = useMediaQuery(theme.breakpoints.up("sm")) - const Offset = styled('div')(({ theme }) => theme.mixins.toolbar); + const largeScreen = useMediaQuery(theme.breakpoints.up("md")); + const mediumScreen = useMediaQuery(theme.breakpoints.up("sm")); + const Offset = styled("div")(({ theme }) => theme.mixins.toolbar); + const currentPath = location.pathname; + const noNavbarLocation = + currentPath === "/signup" || currentPath === "/login"; const handleDrawerOpen = () => { - setOpen(true) - } + setOpen(true); + }; const handleDrawerClose = () => { - setOpen(false) - } + setOpen(false); + }; const navigation = [ { - name: 'Home', - href: '/', + name: "Home", + href: "/", icon: , - current: true + current: true, }, { - name: 'About Us', - href: 'aboutus', + name: "About Us", + href: "aboutus", icon: about us, - current: false + current: false, }, { - name: 'Tutorial', - href: 'tutorial', + name: "Tutorial", + href: "tutorial", icon: , current: false, disabled: true, }, { - name: 'FAQ', - href: 'faq', + name: "FAQ", + href: "faq", icon: faq, - current: false + current: false, }, { - name: 'Share With Friends', + name: "Share With Friends", icon: shareable link, - href: 'sharespoonfull', - current: false + href: "sharespoonfull", + current: false, }, - ] + ]; useEffect(() => { const spoonCount = (arr) => { - const checkedArray = []; - arr.map(task => { + arr.map((task) => { if (task.checked === true) { - return checkedArray.push(task.spoons) + return checkedArray.push(task.spoons); } - }) - const used = checkedArray.reduce((accumulator, spoon) => accumulator + spoon, 0); + }); + const used = checkedArray.reduce( + (accumulator, spoon) => accumulator + spoon, + 0 + ); const spoonArray = []; - arr.map(task => { + arr.map((task) => { return spoonArray.push(task.spoons); - }) - const totalSpoons = spoonArray.reduce((accumulator, currentSpoon) => accumulator + currentSpoon, 0); + }); + const totalSpoons = spoonArray.reduce( + (accumulator, currentSpoon) => accumulator + currentSpoon, + 0 + ); - setUsedSpoons(used) - setPlannedSpoons(totalSpoons - used) - setRemainingSpoons(maxSpoons - totalSpoons) - } + setUsedSpoons(used); + setPlannedSpoons(totalSpoons - used); + setRemainingSpoons(maxSpoons - totalSpoons); + }; spoonCount(taskList); - - }, [taskList]) + }, [ + maxSpoons, + setPlannedSpoons, + setRemainingSpoons, + setUsedSpoons, + taskList, + ]); return ( -
+
- - + + - - - spoonfull logo + + + spoonfull logo - - {showSpoonsModal && createPortal( - , - document.body - )} + {showSpoonsModal && + createPortal( + , + document.body + )} { - handleDrawerClose() + handleDrawerClose(); }} open={open} >

Menu

- + {navigation.map((item) => { return ( - - {item.icon} - {item.name} - - ) + + + {" "} + {item.icon}{" "} + + {item.name} + + ); })}
copyright symbol - {mediumScreen ?

SpoonFull, all rights reserved

- : -

SpoonFull, all rights reserved

- } + {mediumScreen ? ( +

+ SpoonFull, all rights reserved +

+ ) : ( +

+ SpoonFull, all rights reserved +

+ )}
); -} +}; -export default Navbar; \ No newline at end of file +export default Navbar; diff --git a/src/components/PasswordInputField/PasswordInputField.jsx b/src/components/PasswordInputField/PasswordInputField.jsx new file mode 100644 index 0000000..86754af --- /dev/null +++ b/src/components/PasswordInputField/PasswordInputField.jsx @@ -0,0 +1,42 @@ +import InputField from "../InputField/InputField"; +import { useState } from "react"; +import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined"; +import VisibilityOffOutlinedIcon from "@mui/icons-material/VisibilityOffOutlined"; + +const PasswordInputField = () => { + const [visiblePassword, setVisiblePassword] = useState("password"); + const handleVisiblePassword = (e) => { + e.preventDefault(); + setVisiblePassword(visiblePassword === "text" ? "password" : "text"); + }; + return ( +
+ + +
+ ); +}; + +export default PasswordInputField; diff --git a/src/pages/SignUpPage/SignUpPage.jsx b/src/pages/SignUpPage/SignUpPage.jsx new file mode 100644 index 0000000..46985e2 --- /dev/null +++ b/src/pages/SignUpPage/SignUpPage.jsx @@ -0,0 +1,49 @@ +import { useForm } from "react-hook-form"; +import InputField from "/src/components/InputField/InputField"; +import Logo from "/src/assets/spoonfull-logo.svg"; +import { Checkbox } from "@mui/material"; +import PasswordInputField from "../../components/PasswordInputField/PasswordInputField"; + +const SignUpPage = () => { + const { + handleSubmit, + formState: { errors }, + } = useForm({ + defaultValues: { + firstName: "", + email: "", + password: "", + }, + }); + + return ( +
+ spoonful logo +

Sign up

+
+ + {errors.firstName?.message} + + {errors.email?.message} + + {errors.password?.message} +

+ Must be 8 or more characters and contain at least 1 number and 1 + special character. +

+
+ +

Remember me

+
+ + +
+

+ OR +

+
+
+ ); +}; + +export default SignUpPage; diff --git a/tailwind.config.js b/tailwind.config.js index c8bded2..7a3d72a 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,94 +1,123 @@ /** @type {import('tailwindcss').Config} */ export default { - content: [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ], + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], theme: { colors: { - 'primary': '#23A1AF', - 'primary1': 'rgba(35, 161, 175, 0.75)', - 'primary2':'rgba(35, 161, 175, 0.50)', - 'primary3':'rgba(35, 161, 175, 0.25)', - 'primary4': 'rgba(35, 161, 175, 0.10)', - 'primary-text': '#1C7E87', - 'accent': '#F7559E', - 'accent1': 'rgba(247, 85, 158, 0.75)', - 'accent2': 'rgba(247, 85, 158, 0.50)', - 'accent3': 'rgba(247, 85, 158, 0.25)', - 'accent-text': '#E50B6D', - 'text': '#001111', - 'text1': 'rgba(0, 17, 17, 0.75)', - 'text2': 'rgba(0, 17, 17, 0.50)', - 'text3': 'rgba(0, 17, 17, 0.25)', - 'background': '#FCFEFE', - 'link': '#285ED7', - 'success': '#41993F', - 'success1': 'rgba(65, 153, 63, 0.75)', - 'success2': 'rgba(65, 153, 63, 0.50)', - 'success3': 'rgba(65, 153, 63, 0.25)', - 'error': '#D61F14', - 'white': '#FFF', - 'divider': 'rgba(15, 1, 41, 0.10)' - + primary: "#23A1AF", + primary1: "rgba(35, 161, 175, 0.75)", + primary2: "rgba(35, 161, 175, 0.50)", + primary3: "rgba(35, 161, 175, 0.25)", + primary4: "rgba(35, 161, 175, 0.10)", + "primary-text": "#1C7E87", + accent: "#F7559E", + accent1: "rgba(247, 85, 158, 0.75)", + accent2: "rgba(247, 85, 158, 0.50)", + accent3: "rgba(247, 85, 158, 0.25)", + "accent-text": "#E50B6D", + text: "#001111", + text1: "rgba(0, 17, 17, 0.75)", + text2: "rgba(0, 17, 17, 0.50)", + text3: "rgba(0, 17, 17, 0.25)", + background: "#FCFEFE", + link: "#285ED7", + success: "#41993F", + success1: "rgba(65, 153, 63, 0.75)", + success2: "rgba(65, 153, 63, 0.50)", + success3: "rgba(65, 153, 63, 0.25)", + error: "#D61F14", + white: "#FFF", + divider: "rgba(15, 1, 41, 0.10)", + border: "#79747E", }, fontFamily: { - sans: ['Lato', 'sans-serif'], + sans: ["Lato", "sans-serif"], }, - + fontSize: { - 'header1': ['4rem', { - letterSpacing: '-2%', - fontWeight: '700', - }], - 'header2': ['3.5rem', { - letterSpacing: '-2%', - fontWeight: '700', - }], - 'header3': ['2.25rem', { - letterSpacing: '-2%', - fontWeight: '600', - }], - 'header4': ['1.5rem', { - letterSpacing: '-0.48px', - fontWeight: '400', - }], - 'bold-body': ['1.125rem', { - fontWeight: '700', - }], - 'subtitle': ['1.25rem', { - fontWeight: '400' - }], - 'body': ['1.125rem', { - lineHeight: '140%', - fontWeight: '400', - }], - 'small-body': ['1rem', { - fontWeight: '400', - }], - 'button-text': ['1rem', { - letterSpacing: "0.1px", - fontWeight: '500', - }], - 'caption': ['0.875rem', { - letterSpacing: '0%', - fontWeight: '400', - }], - 'over-line': ['0.875rem', { - letterSpacing: '4%', - fontWeight: '400', - }], + header1: [ + "4rem", + { + letterSpacing: "-2%", + fontWeight: "700", + }, + ], + header2: [ + "3.5rem", + { + letterSpacing: "-2%", + fontWeight: "700", + }, + ], + header3: [ + "2.25rem", + { + letterSpacing: "-2%", + fontWeight: "600", + }, + ], + header4: [ + "1.5rem", + { + letterSpacing: "-0.48px", + fontWeight: "400", + }, + ], + "bold-body": [ + "1.125rem", + { + fontWeight: "700", + }, + ], + subtitle: [ + "1.25rem", + { + fontWeight: "400", + }, + ], + body: [ + "1.125rem", + { + lineHeight: "140%", + fontWeight: "400", + }, + ], + "small-body": [ + "1rem", + { + fontWeight: "400", + }, + ], + "button-text": [ + "1rem", + { + letterSpacing: "0.1px", + fontWeight: "500", + }, + ], + caption: [ + "0.875rem", + { + letterSpacing: "0%", + fontWeight: "400", + }, + ], + "over-line": [ + "0.875rem", + { + letterSpacing: "4%", + fontWeight: "400", + }, + ], }, extend: { borderRadius: { - '4xl': '1.75rem', + "4xl": "1.75rem", }, boxShadow: { - "box-shadow": '0px 3px 3px 0px rgba(0, 0, 0, 0.14)', - "card-shadow": '0px 0px 3px 1px rgba(0, 0, 0, 0.10)' - } + "box-shadow": "0px 3px 3px 0px rgba(0, 0, 0, 0.14)", + "card-shadow": "0px 0px 3px 1px rgba(0, 0, 0, 0.10)", + }, }, }, plugins: [], -} - +};