Skip to content

Commit

Permalink
Merge pull request #82 from GenerateNU/CC-77-login-page-styling
Browse files Browse the repository at this point in the history
CC-77:  Signup/Login/Home page style
  • Loading branch information
matherg authored Dec 3, 2023
2 parents 1fee6dd + 4261b59 commit 1b898ac
Show file tree
Hide file tree
Showing 21 changed files with 330 additions and 104 deletions.
5 changes: 5 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import LoginPage from "./pages/LoginPage.tsx";
import SignUpPage from "./pages/SignUpPage.tsx";
import RequestsPurchasingPage from "./pages/RequestPurchasingPage.tsx";
import RequestPurchaseSuccess from "./pages/RequestPurchaseSuccess.tsx";
import ReturnHomePage from "./pages/ReturnHomePage.tsx";

function App() {
return (
Expand Down Expand Up @@ -36,6 +37,10 @@ function App() {
<GiftManagementPage/>
</AdminProvider>}
/>
<Route
path="/home/"
element={<ReturnHomePage />}
/>
<Route
path="/signup/"
element={<SignUpPage/>}
Expand Down
34 changes: 34 additions & 0 deletions client/src/components/Home/HomePrompt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";

type Props = {
titleText: string;
subText: string;
buttonText: string;
onClick: () => void;
image?: string;
imageStyle?: string;
textStyle?: string;
className?: string;
}
const HomePrompt = ({
titleText,
subText,
buttonText,
onClick,
image,
imageStyle,
textStyle,
className
}: Props) => {
return (
<div className={`flex flex-col ${className}`}>
{image && <img className={`w-[22rem] h-[22rem] mb-12 ${imageStyle}`} src={image} />}
<div className={`text-4xl font-seasons font-bold ${textStyle}`}> {titleText} </div>
<div className="text-base font-proxima mt-4"> {subText} </div>
<button className="btn-primary mt-12" onClick={onClick}> {buttonText} </button>
</div>
)
}


export default HomePrompt;
131 changes: 64 additions & 67 deletions client/src/components/Home/NavBarUpdated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,79 +9,76 @@ const Navbar = () => {
};

const buttonStyle =
"px-4 py-2 text-black text-s rounded-md border-gray-400";
"px-4 py-2 text-black text-s rounded-md border-gray-400";
const activeButtonStyle = "bg-DFB2AA";

return (
<div className="bg-FFF9F4 p-5">
<div className="flex">
<div className="flex space-x-2">
<button
className={`${buttonStyle} ${
activeButton === "Shop" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("Shop")}
>
Shop
</button>
<button
className={`${buttonStyle} ${
activeButton === "Request" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("Request")}
>
Request
</button>
<button
className={`${buttonStyle} ${
activeButton === "More" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("More")}
>
About
</button>
</div>
<div className="flex items-center justify-center flex-grow">
<img
src={logoImage}
alt="Logo"
className="w-15 h-15"
/>
</div>
<div className="ml-auto flex items-center space-x-4">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" className="w-6 h-6" style={{ marginRight: '10px' }}>
<path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z" clip-rule="evenodd" />
</svg>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="pink" className="w-6 h-6" style={{ marginRight: '10px' }}>
<path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" className="w-6 h-6" style={{marginRight: "30px"}}>
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM3.751 20.105a8.25 8.25 0 0116.498 0 .75.75 0 01-.437.695A18.683 18.683 0 0112 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 01-.437-.695z" clip-rule="evenodd" />
</svg>


<div className="bg-FFF9F4 p-5">
<div className="flex">
<div className="flex space-x-2">
<button
className={`${buttonStyle} ${
activeButton === "Shop" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("Shop")}
>
Shop
</button>
<button
className={`${buttonStyle} ${
activeButton === "Request" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("Request")}
>
Request
</button>
<button
className={`${buttonStyle} ${
activeButton === "More" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("More")}
>
About
</button>
</div>
<div className="flex items-center justify-center flex-grow">
<img
src={logoImage}
alt="Logo"
className="w-15 h-15"
/>
</div>
<div className="ml-auto flex items-center space-x-4">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" className="w-6 h-6" style={{ marginRight: '10px' }}>
<path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z" clip-rule="evenodd" />
</svg>

{/* <button
className={`${buttonStyle} ${
activeButton === "LogIn" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("LogIn")}
>
Log In
</button>
<button
className={`${buttonStyle} ${
activeButton === "SignUp" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("SignUp")}
>
Sign Up
</button> */}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="pink" className="w-6 h-6" style={{ marginRight: '10px' }}>
<path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" className="w-6 h-6" style={{marginRight: "30px"}}>
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM3.751 20.105a8.25 8.25 0 0116.498 0 .75.75 0 01-.437.695A18.683 18.683 0 0112 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 01-.437-.695z" clip-rule="evenodd" />
</svg>
<button
className={`${buttonStyle} ${
activeButton === "LogIn" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("LogIn")}
>
Log In
</button>
<button
className={`${buttonStyle} ${
activeButton === "SignUp" ? activeButtonStyle : ""
}`}
onClick={() => handleButtonClick("SignUp")}
>
Sign Up
</button>
</div>
</div>
</div>
</div>
);
};

export default Navbar;
export default Navbar;
41 changes: 30 additions & 11 deletions client/src/components/Login/FormInput.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,54 @@
import React from "react";
import React, { useState } from "react";
import ValidationAlert from "./ValidationAlert";
import { passwordValidation } from "../../data/formData";
import EyeOff from "../../images/eye_off.svg";
import EyeOn from "../../images/eye_on.svg";

export type FormInputProps = React.InputHTMLAttributes<HTMLInputElement> & {
label: string;
className?: string;
type: string;
includeValidation?: boolean;
};

const FormInput = ({label, className, type, ...rest}: FormInputProps) => {
const FormInput = ({label, className, type, value, includeValidation = false, ...rest}: FormInputProps) => {
const [icon, setIcon] = useState(EyeOn);

const toggleShowPassword = () => {
const input = document.getElementById(label) as HTMLInputElement;
input.type = input.type === "password" ? "text" : "password";
setIcon(icon === EyeOn ? EyeOff : EyeOn);
}

return (
<div className={`flex flex-col ${className}`}>
<label htmlFor={label}> {label} </label>
<label htmlFor={label} className="font-seasons font-bold font-base"> {label} </label>
<div>
<input
id={label}
className="border-solid border-2 rounded-md w-full"
className="border-brown border-solid border-[1.5px] bg-pearl rounded-md w-full text-base text-coffee font-proxima px-2 p-1"
type={type}
pattern={type === "password" && includeValidation ? "(?=.*(\\d|\\W))(?=.*[a-z])(?=.*[A-Z]).{8,}" : undefined}
{...rest}
/>
{type === "password" &&
<button
className="absolute ml-4 text-sm"
type="button"
onClick={toggleShowPassword}>
{"Toggle"}
</button>
{type === "password" &&
<>
<img
className="inline absolute ml-4 mt-2 w-5 h-5"
src={icon}
onClick={toggleShowPassword}
/>
{includeValidation && value !== "" && passwordValidation.map((validation) => (
<ValidationAlert
key={validation.validationText}
/* will always be a string from form state*/
fieldText={value as string}
validationText={validation.validationText}
validationRule={validation.validationRule}
className="mt-1"
/>
))}
</>
}
</div>
</div>
Expand Down
22 changes: 10 additions & 12 deletions client/src/components/Login/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from "react";
import { Link } from "react-router-dom";
import FormInput, { FormInputProps } from "./FormInput.tsx";
import { LoginInputs } from "../../pages/LoginPage.tsx";
import GoogleIcon from "../../images/google.svg";

export type FormData = {
title: string;
Expand All @@ -27,8 +28,6 @@ const LoginForm = <T extends LoginInputs>({formData, initialState, onSubmit}: Pr
...prevState,
[e.target.name]: e.target.value
}));

// additional error validation here
}

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
Expand All @@ -40,11 +39,11 @@ const LoginForm = <T extends LoginInputs>({formData, initialState, onSubmit}: Pr

return (
<form
className="w-[512px] h-screen shrink-0 flex flex-col px-14 pt-8 pr-28 lg:w-1/2"
className="w-[512px] shrink-0 flex flex-col px-14 pt-8 pr-28 lg:w-1/2"
onSubmit={handleSubmit}
>
<div className="text-3xl mt-4"> {formData.title} </div>
<div className="text-sm mt-4"> {formData.subText} </div>
<div className="text-4xl mt-4 font-seasons font-bold"> {formData.title} </div>
<div className="text-base text-drkbrown mt-4 font-proxima"> {formData.subText} </div>
{formData.inputs.map((props, index) => {
const [field, value] = Object.entries(formState)[index];
return (
Expand All @@ -59,7 +58,7 @@ const LoginForm = <T extends LoginInputs>({formData, initialState, onSubmit}: Pr
)
}
)}
<div className="mt-5 text-sm">
<div className="mt-5 text-base text-coffee font-proxima">
<span> {formData.additionalText} </span>
<Link
className="underline"
Expand All @@ -76,14 +75,13 @@ const LoginForm = <T extends LoginInputs>({formData, initialState, onSubmit}: Pr
</button>
<div className="flex items-center mt-8">
<span className={`${lineStyle}`}/>
<span className="px-3 text-center text-sm"> {"or"} </span>
<span className="px-3 text-center text-base font-proxima"> {"or"} </span>
<span className={`${lineStyle}`} />
</div>
<div className="flex justify-center space-x-6 mt-4">
{/* replace with icons */}
<span className="w-14 h-14 rounded-full bg-orange-900"/>
<span className="w-14 h-14 rounded-full bg-orange-900"/>
<span className="w-14 h-14 rounded-full bg-orange-900"/>
<div className="flex justify-center space-x-12 mt-4">
<div className="w-16 h-16 rounded-full bg-petalpink flex items-center justify-center">
<img src={GoogleIcon} className="w-8 h-8" />
</div>
</div>
</form>
)
Expand Down
20 changes: 20 additions & 0 deletions client/src/components/Login/ValidationAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Check from "../../images/check.svg";
import Error from "../../images/error.svg";

export type ValidationAlertProps = {
fieldText: string;
validationText: string;
validationRule: RegExp;
className?: string;
}

const ValidationAlert = ({ fieldText, validationText, validationRule, className }: ValidationAlertProps) => {
return (
<div className={`flex items-center ${className}`}>
<img className="w-4 h-4 mr-1" src={fieldText.match(validationRule) ? Check : Error} />
<span className="text-base"> {validationText} </span>
</div>
)
}

export default ValidationAlert;
26 changes: 24 additions & 2 deletions client/src/data/formData.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FormData } from "../components/Login/LoginForm.tsx";
import { ValidationAlertProps } from "../components/Login/ValidationAlert.tsx"

export const loginFormData: FormData = {
title: "Log In",
subText: "Log in to continue your gift giving journey",
subText: "Log in to continue your gift giving journey!",
inputs: [
{
className: "mt-10",
Expand Down Expand Up @@ -43,11 +44,32 @@ export const signUpFormData: FormData = {
{
className: "mt-4",
label: "Password",
type: "password"
type: "password" ,
includeValidation: true
}
],
additionalText: "Already have an account? ",
linkedText: "Log in",
link: "/login",
buttonText: "Sign Up"
};

export const passwordValidation: Omit<ValidationAlertProps, "fieldText">[] = [
{
validationText: "Contains uppercase letters",
validationRule: new RegExp("[A-Z]")
},
{
validationText: "Contains lowercase letters",
validationRule: new RegExp("[a-z]")
},
{
validationText: "Contains 8 characters",
validationRule: new RegExp(".{8,}")
},
{
validationText: "Contains a number or symbol",
validationRule: new RegExp("\\d|\\W")
}

];
Loading

0 comments on commit 1b898ac

Please sign in to comment.