From 7da992c8abeef25fb3a17c6000c2fef048e296ea Mon Sep 17 00:00:00 2001 From: Advik Arora <aroraadvik@gmail.com> Date: Mon, 26 Feb 2024 20:07:13 -0500 Subject: [PATCH 1/9] button disabling feature --- compass/app/auth/new_Password/page.tsx | 76 ++++++++++++++++++++++++++ compass/components/Button.tsx | 17 +++--- 2 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 compass/app/auth/new_Password/page.tsx diff --git a/compass/app/auth/new_Password/page.tsx b/compass/app/auth/new_Password/page.tsx new file mode 100644 index 0000000..0ccee79 --- /dev/null +++ b/compass/app/auth/new_Password/page.tsx @@ -0,0 +1,76 @@ +// pages/index.tsx +"use client"; +import { useState, useEffect } from 'react'; +import Button from '@/components/Button'; +import Input from '@/components/Input'; +import Paper from '@/components/auth/Paper'; + + +function isStrongPassword(password: string): boolean { + const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/; + return strongPasswordRegex.test(password); +} + + +export default function Page() { + const [newPassword, setNewPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [isButtonDisabled, setIsButtonDisabled] = useState(true); + + + useEffect(() => { + setIsButtonDisabled(newPassword === '' || confirmPassword === ''); + }, [newPassword, confirmPassword]); + + + return ( + <> + <Paper> + <form + onSubmit={(e) => { + e.preventDefault(); + if (newPassword === confirmPassword) { + console.log('Passwords match. Submitting form...'); + } else { + console.log('Passwords do not match. Please try again.'); + } + }} + className="mb-0 mt-6 mb-6 space-y-4 rounded-lg p-4 shadow-lg sm:p-6 lg:p-8 bg-white" + > + <div className="text-center sm:text-left"> + <h1 className="text-2xl font-bold text-blue-900 sm:text-3xl">New Password</h1> + </div> + <div className="mb-4"> + <Input + type="password" + title="Enter New Password" + value={newPassword} + onChange={(e) => { + setNewPassword(e.target.value); + }} + /> + </div> + <div className="mb-6"> + <Input + type="password" + title="Confirm Password" + value={confirmPassword} + onChange={(e) => { + setConfirmPassword(e.target.value); + }} + /> + </div> + <div className="flex flex-col items-left space-y-4"> + <Button type="submit" disabled={isButtonDisabled} > + Send + </Button> + </div> + </form> + <p className="text-center mt-6 text-gray-500 text-xs">© 2024 Compass Center</p> + </Paper> + </> + ); +} + + + diff --git a/compass/components/Button.tsx b/compass/components/Button.tsx index 72c47f9..bf6dd55 100644 --- a/compass/components/Button.tsx +++ b/compass/components/Button.tsx @@ -3,21 +3,22 @@ import { FunctionComponent, ReactNode } from 'react'; type ButtonProps = { children: ReactNode; onClick?: () => void; // make the onClick handler optional + type?: "button" | "submit" | "reset"; // specify possible values for type + disabled?: boolean; }; -const Button: FunctionComponent<ButtonProps> = ({ children, onClick }) => { +const Button: FunctionComponent<ButtonProps> = ({ children, type, disabled, onClick }) => { + const buttonClassName = `inline-block rounded border ${disabled ? 'bg-gray-400 text-gray-600 cursor-not-allowed' : 'border-purple-600 bg-purple-600 text-white hover:bg-transparent hover:text-purple-600 focus:outline-none focus:ring active:text-purple-500'} px-12 py-3 text-sm font-semibold`; return ( <button - // className="px-4 py-2 font-bold text-white bg-purple-600 rounded hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-opacity-var focus:ring-color-var" - className="inline-block rounded border border-purple-600 bg-purple-600 px-12 py-3 text-sm font-semibold text-white hover:bg-transparent hover:text-purple-600 focus:outline-none focus:ring active:text-purple-500" - onClick={onClick} - // style={{ - // '--ring-opacity-var': `var(--ring-opacity)`, - // '--ring-color-var': `rgba(var(--ring-color), var(--ring-opacity))` - // }} + className={buttonClassName} + onClick={onClick} + type={type} + disabled={disabled} > {children} </button> ); }; + export default Button; From c510c590576460a1e2bb53355f0d6aa70b9d49af Mon Sep 17 00:00:00 2001 From: Advik Arora <aroraadvik@gmail.com> Date: Tue, 27 Feb 2024 14:53:03 -0500 Subject: [PATCH 2/9] debug disabled prop --- compass/app/auth/{new_Password => newPassword}/page.tsx | 5 ++++- compass/components/Input.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) rename compass/app/auth/{new_Password => newPassword}/page.tsx (91%) diff --git a/compass/app/auth/new_Password/page.tsx b/compass/app/auth/newPassword/page.tsx similarity index 91% rename from compass/app/auth/new_Password/page.tsx rename to compass/app/auth/newPassword/page.tsx index 0ccee79..a49f566 100644 --- a/compass/app/auth/new_Password/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -19,7 +19,10 @@ export default function Page() { useEffect(() => { - setIsButtonDisabled(newPassword === '' || confirmPassword === ''); + console.log('newPassword',newPassword) + console.log('confirmPassword',confirmPassword) + setIsButtonDisabled(newPassword === '' || confirmPassword === '' || newPassword !== confirmPassword); + console.log('newPasswordDisabledTest',isButtonDisabled) }, [newPassword, confirmPassword]); diff --git a/compass/components/Input.tsx b/compass/components/Input.tsx index 618295b..d5a4348 100644 --- a/compass/components/Input.tsx +++ b/compass/components/Input.tsx @@ -1,13 +1,14 @@ -import React, { FunctionComponent, InputHTMLAttributes, ReactNode } from 'react'; +import React, { FunctionComponent, InputHTMLAttributes, ReactNode, ChangeEvent } from 'react'; type InputProps = InputHTMLAttributes<HTMLInputElement> & { icon?: ReactNode; title?: ReactNode; type?:ReactNode; placeholder?:ReactNode + onChange: (event: ChangeEvent<HTMLInputElement>) => void; }; -const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, ...rest }) => { +const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, onChange, ...rest }) => { return ( <div> <label @@ -20,6 +21,7 @@ const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, type={type} id={title} placeholder={placeholder} + onChange={onChange} className="mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm" /> </label> From 6dcb0eb5ccc784a204d0879b9fe025038ac0d19b Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Thu, 29 Feb 2024 19:20:58 -0500 Subject: [PATCH 3/9] added validation for strong passwords. --- compass/app/auth/newPassword/page.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index a49f566..cdf55d8 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -15,15 +15,21 @@ function isStrongPassword(password: string): boolean { export default function Page() { const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); + const [valid, setValid] = useState(false); + const [matching, setMatching] = useState(false); const [isButtonDisabled, setIsButtonDisabled] = useState(true); + useEffect(() => { + setValid(isStrongPassword(newPassword)) + setMatching(newPassword === confirmPassword) + }, [newPassword, confirmPassword]) useEffect(() => { - console.log('newPassword',newPassword) - console.log('confirmPassword',confirmPassword) - setIsButtonDisabled(newPassword === '' || confirmPassword === '' || newPassword !== confirmPassword); + setIsButtonDisabled(newPassword === '' || confirmPassword === '' || !matching || !valid); + console.log(matching) + console.log(valid) console.log('newPasswordDisabledTest',isButtonDisabled) - }, [newPassword, confirmPassword]); + }, [matching, valid]); return ( From 21c4717bc8de5b8ce4b781e400fedd43be16cc13 Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Thu, 29 Feb 2024 22:51:58 -0500 Subject: [PATCH 4/9] Added error messages with tips when invalid or not matching. --- compass/app/auth/newPassword/page.tsx | 30 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index cdf55d8..d230894 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -15,20 +15,24 @@ function isStrongPassword(password: string): boolean { export default function Page() { const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); - const [valid, setValid] = useState(false); - const [matching, setMatching] = useState(false); + const [valid, setValid] = useState(true); + const [matching, setMatching] = useState(true); const [isButtonDisabled, setIsButtonDisabled] = useState(true); useEffect(() => { - setValid(isStrongPassword(newPassword)) + if (newPassword !== ''){ + setValid(isStrongPassword(newPassword)) + } + }, [newPassword]) + + useEffect(() => { + if (confirmPassword !== ''){ setMatching(newPassword === confirmPassword) - }, [newPassword, confirmPassword]) + } +}, [newPassword, confirmPassword]) useEffect(() => { setIsButtonDisabled(newPassword === '' || confirmPassword === '' || !matching || !valid); - console.log(matching) - console.log(valid) - console.log('newPasswordDisabledTest',isButtonDisabled) }, [matching, valid]); @@ -59,6 +63,12 @@ export default function Page() { }} /> </div> + {valid ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> + <strong className="block font-medium text-red-800"> Password is not strong enough. </strong> + <p className="mt-2 text-sm text-red-700"> + Tip: Use a mix of letters, numbers, and symbols for a strong password. Aim for at least 8 characters! + </p> + </div>} <div className="mb-6"> <Input type="password" @@ -69,6 +79,12 @@ export default function Page() { }} /> </div> + {matching ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> + <strong className="block font-medium text-red-800"> Passwords do not match. </strong> + <p className="mt-2 text-sm text-red-700"> + Please make sure both passwords are the exact same! + </p> + </div>} <div className="flex flex-col items-left space-y-4"> <Button type="submit" disabled={isButtonDisabled} > Send From fb15863b2fc502b834a3c514eea648dfe290359a Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Sat, 2 Mar 2024 01:40:02 -0500 Subject: [PATCH 5/9] simplified code by removing multiple useEffects() --- .vscode/settings.json | 1 + compass/app/auth/newPassword/page.tsx | 23 +++++------------------ compass/components/Input.tsx | 5 +++-- 3 files changed, 9 insertions(+), 20 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index d230894..1b626ab 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -15,25 +15,11 @@ function isStrongPassword(password: string): boolean { export default function Page() { const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); - const [valid, setValid] = useState(true); - const [matching, setMatching] = useState(true); const [isButtonDisabled, setIsButtonDisabled] = useState(true); useEffect(() => { - if (newPassword !== ''){ - setValid(isStrongPassword(newPassword)) - } - }, [newPassword]) - - useEffect(() => { - if (confirmPassword !== ''){ - setMatching(newPassword === confirmPassword) - } -}, [newPassword, confirmPassword]) - - useEffect(() => { - setIsButtonDisabled(newPassword === '' || confirmPassword === '' || !matching || !valid); - }, [matching, valid]); + setIsButtonDisabled(newPassword === '' || confirmPassword === '' || newPassword !== confirmPassword|| !isStrongPassword(newPassword)); + }, [newPassword, confirmPassword]); return ( @@ -58,12 +44,13 @@ export default function Page() { type="password" title="Enter New Password" value={newPassword} + valid={isButtonDisabled} onChange={(e) => { setNewPassword(e.target.value); }} /> </div> - {valid ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> + {isStrongPassword(newPassword) || newPassword === '' ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> <strong className="block font-medium text-red-800"> Password is not strong enough. </strong> <p className="mt-2 text-sm text-red-700"> Tip: Use a mix of letters, numbers, and symbols for a strong password. Aim for at least 8 characters! @@ -79,7 +66,7 @@ export default function Page() { }} /> </div> - {matching ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> + {newPassword === confirmPassword || confirmPassword === '' ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> <strong className="block font-medium text-red-800"> Passwords do not match. </strong> <p className="mt-2 text-sm text-red-700"> Please make sure both passwords are the exact same! diff --git a/compass/components/Input.tsx b/compass/components/Input.tsx index d5a4348..07c4d16 100644 --- a/compass/components/Input.tsx +++ b/compass/components/Input.tsx @@ -5,15 +5,16 @@ type InputProps = InputHTMLAttributes<HTMLInputElement> & { title?: ReactNode; type?:ReactNode; placeholder?:ReactNode + valid?:boolean; onChange: (event: ChangeEvent<HTMLInputElement>) => void; }; -const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, onChange, ...rest }) => { +const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, onChange, valid, ...rest }) => { return ( <div> <label htmlFor={title} - className="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600" + className="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600" > <span className="text-xs font-semibold text-gray-700"> {title} </span> From 445c8512fb371ccf34389d8ed3e29d6ffb81ef2b Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Sat, 2 Mar 2024 01:44:44 -0500 Subject: [PATCH 6/9] added error outline when password conditions not met. --- compass/app/auth/newPassword/page.tsx | 3 ++- compass/components/Input.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index 1b626ab..12d4faa 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -44,7 +44,7 @@ export default function Page() { type="password" title="Enter New Password" value={newPassword} - valid={isButtonDisabled} + valid={!isButtonDisabled || isStrongPassword(newPassword)} onChange={(e) => { setNewPassword(e.target.value); }} @@ -61,6 +61,7 @@ export default function Page() { type="password" title="Confirm Password" value={confirmPassword} + valid={!isButtonDisabled || (newPassword === confirmPassword && confirmPassword !== '')} onChange={(e) => { setConfirmPassword(e.target.value); }} diff --git a/compass/components/Input.tsx b/compass/components/Input.tsx index 07c4d16..3eced0a 100644 --- a/compass/components/Input.tsx +++ b/compass/components/Input.tsx @@ -14,7 +14,7 @@ const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, <div> <label htmlFor={title} - className="block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600" + className={valid ? "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600" : "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600"} > <span className="text-xs font-semibold text-gray-700"> {title} </span> From 8381211591595f0a2b164d1b22fd87f9064cebad Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Sat, 2 Mar 2024 01:51:33 -0500 Subject: [PATCH 7/9] fixed fonts to match site styling --- compass/app/auth/newPassword/page.tsx | 8 ++++---- compass/components/Input.tsx | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index 12d4faa..c9bf8f8 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -51,8 +51,8 @@ export default function Page() { /> </div> {isStrongPassword(newPassword) || newPassword === '' ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> - <strong className="block font-medium text-red-800"> Password is not strong enough. </strong> - <p className="mt-2 text-sm text-red-700"> + <strong className="block text-sm font-semibold text-red-800"> Password is not strong enough. </strong> + <p className="mt-2 text-xs font-thin text-red-700"> Tip: Use a mix of letters, numbers, and symbols for a strong password. Aim for at least 8 characters! </p> </div>} @@ -68,8 +68,8 @@ export default function Page() { /> </div> {newPassword === confirmPassword || confirmPassword === '' ? null : <div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4"> - <strong className="block font-medium text-red-800"> Passwords do not match. </strong> - <p className="mt-2 text-sm text-red-700"> + <strong className="block text-sm font-semibold text-red-800"> Passwords do not match. </strong> + <p className="mt-2 text-xs font-thin text-red-700"> Please make sure both passwords are the exact same! </p> </div>} diff --git a/compass/components/Input.tsx b/compass/components/Input.tsx index 3eced0a..0517a01 100644 --- a/compass/components/Input.tsx +++ b/compass/components/Input.tsx @@ -14,6 +14,7 @@ const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, <div> <label htmlFor={title} + // this class name should be simplified, was just having problems with it className={valid ? "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600" : "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600"} > <span className="text-xs font-semibold text-gray-700"> {title} </span> From 05a0b1690b7ef50d9e6cc3bba78d518aef6a7c6e Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Sat, 2 Mar 2024 14:40:42 -0500 Subject: [PATCH 8/9] code clean --- compass/app/auth/newPassword/page.tsx | 4 ++-- compass/app/page.tsx | 2 +- compass/components/{Button.tsx => Button1.tsx} | 0 compass/components/{Input.tsx => Input1.tsx} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename compass/components/{Button.tsx => Button1.tsx} (100%) rename compass/components/{Input.tsx => Input1.tsx} (100%) diff --git a/compass/app/auth/newPassword/page.tsx b/compass/app/auth/newPassword/page.tsx index c9bf8f8..6b4aaef 100644 --- a/compass/app/auth/newPassword/page.tsx +++ b/compass/app/auth/newPassword/page.tsx @@ -1,8 +1,8 @@ // pages/index.tsx "use client"; import { useState, useEffect } from 'react'; -import Button from '@/components/Button'; -import Input from '@/components/Input'; +import Button from '@/components/Button1'; +import Input from '@/components/Input1'; import Paper from '@/components/auth/Paper'; diff --git a/compass/app/page.tsx b/compass/app/page.tsx index 48493ae..0d73d47 100644 --- a/compass/app/page.tsx +++ b/compass/app/page.tsx @@ -1,6 +1,6 @@ // pages/index.tsx -import Button from '@/components/Button'; +import Button from '@/components/Button1'; import Input from '@/components/Input' import InlineLink from '@/components/InlineLink'; import Paper from '@/components/auth/Paper'; diff --git a/compass/components/Button.tsx b/compass/components/Button1.tsx similarity index 100% rename from compass/components/Button.tsx rename to compass/components/Button1.tsx diff --git a/compass/components/Input.tsx b/compass/components/Input1.tsx similarity index 100% rename from compass/components/Input.tsx rename to compass/components/Input1.tsx From 26732593a3996c7fbf8a9579272b2e2238d81d9a Mon Sep 17 00:00:00 2001 From: Nicholas <nsanaie@unc.edu> Date: Sat, 2 Mar 2024 14:46:07 -0500 Subject: [PATCH 9/9] conflict resolve --- compass/components/Button.tsx | 24 ++++++++++++++++++++++++ compass/components/Input.tsx | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 compass/components/Button.tsx create mode 100644 compass/components/Input.tsx diff --git a/compass/components/Button.tsx b/compass/components/Button.tsx new file mode 100644 index 0000000..bf6dd55 --- /dev/null +++ b/compass/components/Button.tsx @@ -0,0 +1,24 @@ +import { FunctionComponent, ReactNode } from 'react'; + +type ButtonProps = { + children: ReactNode; + onClick?: () => void; // make the onClick handler optional + type?: "button" | "submit" | "reset"; // specify possible values for type + disabled?: boolean; +}; + +const Button: FunctionComponent<ButtonProps> = ({ children, type, disabled, onClick }) => { + const buttonClassName = `inline-block rounded border ${disabled ? 'bg-gray-400 text-gray-600 cursor-not-allowed' : 'border-purple-600 bg-purple-600 text-white hover:bg-transparent hover:text-purple-600 focus:outline-none focus:ring active:text-purple-500'} px-12 py-3 text-sm font-semibold`; + return ( + <button + className={buttonClassName} + onClick={onClick} + type={type} + disabled={disabled} + > + {children} + </button> + ); +}; + +export default Button; diff --git a/compass/components/Input.tsx b/compass/components/Input.tsx new file mode 100644 index 0000000..0517a01 --- /dev/null +++ b/compass/components/Input.tsx @@ -0,0 +1,34 @@ +import React, { FunctionComponent, InputHTMLAttributes, ReactNode, ChangeEvent } from 'react'; + +type InputProps = InputHTMLAttributes<HTMLInputElement> & { + icon?: ReactNode; + title?: ReactNode; + type?:ReactNode; + placeholder?:ReactNode + valid?:boolean; + onChange: (event: ChangeEvent<HTMLInputElement>) => void; +}; + +const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, onChange, valid, ...rest }) => { + return ( + <div> + <label + htmlFor={title} + // this class name should be simplified, was just having problems with it + className={valid ? "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600" : "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600"} +> + <span className="text-xs font-semibold text-gray-700"> {title} </span> + + <input + type={type} + id={title} + placeholder={placeholder} + onChange={onChange} + className="mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm" + /> +</label> +</div> + ); +}; + +export default Input;