From 7cd839c000ddac94533e52727bda8a7b80e48a51 Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 00:16:10 -0500 Subject: [PATCH 1/8] Updating login screen main --- frontend/src/Login.tsx | 265 +++++++++++++---------------------------- 1 file changed, 86 insertions(+), 179 deletions(-) diff --git a/frontend/src/Login.tsx b/frontend/src/Login.tsx index b3db73eb..e338c577 100644 --- a/frontend/src/Login.tsx +++ b/frontend/src/Login.tsx @@ -4,8 +4,6 @@ import { observer } from "mobx-react-lite"; import logo from "./images/bcan_logo.svg"; import { useNavigate } from "react-router-dom"; import "./external/bcanSatchel/mutators"; -import "./styles/button.css" - /** * Registered users can log in here @@ -13,6 +11,7 @@ import "./styles/button.css" const Login = observer(() => { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); + const [failure, setFailure] = useState(false); const navigate = useNavigate(); const { login } = useAuthContext(); @@ -24,85 +23,109 @@ const Login = observer(() => { if (success) { navigate("/grant-info"); } else { - alert("Login failed. Please check your credentials."); + setFailure(true); } }; return ( -
- {/* Blurred background layer */} +
+ {/* Blurred background layer
{/* Foreground content (not blurred) */} -
- {/* Crest area */} -
- BCAN Logo -

Grant Portal

+
+
+

Welcome back!

+

+ Enter your credentials to access your account +

- - {/* Single form container with both Sign In and Register */} -
-

Sign In

- - {/* UserID field */} - - setUsername(e.target.value)} - required - style={styles.input} - placeholder="Enter your username (e.g., bcanuser33)" - /> - - {/* Password field */} - - setPassword(e.target.value)} - required - style={styles.input} - placeholder="Enter your password" - /> + +
+
+ +
+ setUsername(e.target.value)} + placeholder="Enter your email" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+ +
+ setPassword(e.target.value)} + placeholder="Enter your password" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+
+ {failure ? ( +
+ Invalid username or password. Please try again. +
+ ) : ( +
{" "}
+ )} +
- {/* Buttons row: Sign In, vertical separator, and Register */} -
- - -
-
-
OR
-
-
+ className="w-full block mt-8 min-w-0 rounded-md grow bg-dark-orange text-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500" + style={{ ...styles.button, ...styles.helloButton }} + > + Login + +
+
+
or
+
+
+ {/* Buttons row: Sign In, vertical separator, and Register */} +
+ Don't have an account?{" "}
+ +
+
+ BCAN Logo +
+
); }); @@ -120,123 +143,7 @@ const styles: { [key: string]: React.CSSProperties } = { overflow: "hidden", display: "flex", justifyContent: "center", - alignItems: "center", - }, - backgroundLayer: { - position: "absolute", - top: 0, - left: 0, - width: "100%", - height: "100%", - zIndex: 0, - background: ` - linear-gradient(135deg, - rgb(164, 183, 251) 0%, - rgb(212, 240, 255) 47%, rgb(111, 147, 237) 96%) - `, - backgroundSize: "cover", - backgroundBlendMode: "overlay", - filter: "blur(7px)", - }, - foregroundContent: { - position: "relative", - zIndex: 1, - display: "flex", - flexDirection: "row", - justifyContent: "space-evenly", - alignItems: "center", - width: "100%", - }, - logoContainer: { - display: "flex", - alignItems: "center", - justifyContent: "center", - wordSpacing: "4px", - flexDirection: "row", - marginBottom: "2rem", - width: "50%", - }, - logoSquare: { - width: "28px", - height: "28px", - backgroundColor: "#f25022", - }, - logoText: { - fontSize: "1.6rem", - fontWeight: "bold", - }, - formContainer: { - width: "500px", - padding: "3rem", - backgroundColor: "rgba(255, 255, 255, 0.8)", - color: "#000", - borderRadius: "8px", - boxShadow: "0 2px 10px rgba(0,0,0,0.15)", - display: "flex", - flexDirection: "column", - }, - heading: { - marginBottom: "2rem", - fontSize: "2.2rem", - fontWeight: 500, - textAlign: "left", - }, - appName: { - marginBottom: "0.4rem", - fontSize: "2.2rem", - fontWeight: 700, - textAlign: "left", - color: "rgba(255, 105, 0, 1)", - }, - label: { - marginBottom: "0.75rem", - fontSize: "1.2rem", - textAlign: "left", - }, - input: { - marginBottom: "1.75rem", - padding: "1rem", - fontSize: "1.2rem", - border: "1px solid #ccc", - borderRadius: "4px", - width: "100%", - boxSizing: "border-box", - color: "lightgray", - }, - buttonRow: { - display: "flex", - alignItems: "center", - justifyContent: "center", - }, - verticalSeparator: { - display: "flex", - flexDirection: "column", - alignItems: "center", - margin: "0 1rem", - }, - separatorLine: { - width: "1px", - height: "15px", - backgroundColor: "#ccc", - }, - separatorOr: { - margin: "0.25rem 0", - fontWeight: "bold", - color: "#555", - }, - button: { - marginBottom: "1.2rem", - padding: "1.2rem", - fontSize: "1.4rem", - cursor: "pointer", - border: "2px solid", - borderRadius: "24px", - }, - helloButton: { - backgroundColor: "#0b303b", - border: "1px solid #ccc", - borderWidth: 0, - borderRadius: "100px", - color: "#fff", + alignItems: "start", + textAlign: "start", }, }; From b3f99d761db00f9e6436fd7594112b17539d2aaa Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 02:19:42 -0500 Subject: [PATCH 2/8] Working on register page --- frontend/src/Login.tsx | 9 +- frontend/src/Register.tsx | 330 ++++++++++----------- frontend/src/RegisterLanding.tsx | 50 ++++ frontend/src/animations/AnimatedRoutes.tsx | 7 + frontend/src/context/auth/authContext.tsx | 23 +- 5 files changed, 220 insertions(+), 199 deletions(-) create mode 100644 frontend/src/RegisterLanding.tsx diff --git a/frontend/src/Login.tsx b/frontend/src/Login.tsx index e338c577..619a3b62 100644 --- a/frontend/src/Login.tsx +++ b/frontend/src/Login.tsx @@ -29,10 +29,6 @@ const Login = observer(() => { return (
- {/* Blurred background layer -
- - {/* Foreground content (not blurred) */}

Welcome back!

@@ -40,7 +36,6 @@ const Login = observer(() => { Enter your credentials to access your account
- {/* Single form container with both Sign In and Register */}
@@ -83,7 +78,7 @@ const Login = observer(() => {
{failure ? (
- Invalid username or password. Please try again. + Your password is incorrect or this account doesn't exist
) : (
{" "}
@@ -118,7 +113,7 @@ const Login = observer(() => {
-
+
{ const [username, setUsername] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); + const [passwordRe, setPasswordRe] = useState(""); + const [failure, setFailure] = useState({ state: false, message: "" }); const navigate = useNavigate(); const { register } = useAuthContext(); @@ -18,90 +20,162 @@ const Register = observer(() => { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const success = await register(username, password, email); - if (success) { - navigate("/login"); + if (!failure.state && success.state) { + navigate("/registered"); } else { + setFailure({ state: true, message: "Registration failed: " + success.message }); console.warn("Registration failed"); } }; - return ( -
- {/* Blurred background layer */} -
- {/* Foreground content (not blurred) */} -
- {/* Crest area */} -
- BCAN Logo -

Grant Portal

-
+ const handlePassword = (e: string) => { + setPassword(e); + if (e !== password && passwordRe !== "") { + setFailure({ state: true, message: "Passwords do not match" }); + } else { + setFailure({ state: false, message: "" }); + } + }; - {/* Form container with partial transparency */} - -

Register

+ const handlePasswordMatch = (e: string) => { + setPasswordRe(e); + if (e !== password) { + setFailure({ state: true, message: "Passwords do not match" }); + } else { + setFailure({ state: false, message: "" }); + } + }; + + return ( +
+
+
+

Get Started Now

+
+ +
+
+ +
+ setUsername(e.target.value)} + placeholder="Enter your username" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+ +
+ setEmail(e.target.value)} + placeholder="Enter your email" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+ +
+ handlePassword(e.target.value)} + placeholder="Enter your password" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+ +
+ handlePasswordMatch(e.target.value)} + required + placeholder="Re-enter your password" + style={styles.inputContainer} + className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" + /> +
+
+
+
+
+ {failure.state ? failure.message : `• Passwords must have at least one special character (!@#$%^&*) +• Passwords must have at least one digit character ('0'-'9') +• Passwords must have at least one uppercase character ('A'-'Z')`} +
+
- {/* "Go Back to Sign In" button */} - +
+
+
or
+
+
- {/* Username field */} - - setUsername(e.target.value)} - required - style={styles.input} - placeholder="Create a username" - /> - - {/* Email field */} - - setEmail(e.target.value)} - required - style={styles.input} - placeholder="Enter your email address" - /> + {/* Buttons row: Sign In, vertical separator, and Register */} +
+ Don't have an account?{" "} + +
+ +
- {/* Password field */} - - setPassword(e.target.value)} - required - style={styles.input} - placeholder="Create a password" +
+
+ BCAN Logo - - {/* Register button */} - - +
); @@ -109,123 +183,17 @@ const Register = observer(() => { export default Register; -// -- Inline style objects (mirroring Login.tsx) -- +// Inline style objects const styles: { [key: string]: React.CSSProperties } = { pageContainer: { position: "relative", - width: "100vw", + width: "100%", height: "100vh", margin: 0, padding: 0, - overflow: "hidden", display: "flex", justifyContent: "center", - alignItems: "center", - }, - backgroundLayer: { - position: "absolute", - top: 0, - left: 0, - width: "100%", - height: "100%", - zIndex: 0, - background: ` - linear-gradient(135deg, - rgb(164, 183, 251) 0%, - rgb(212, 240, 255) 47%, rgb(111, 147, 237) 96%) - `, - backgroundSize: "cover", - backgroundBlendMode: "overlay", - filter: "blur(7px)", // blur only the background - }, - foregroundContent: { - position: "relative", - zIndex: 1, // on top of the background layer - display: "flex", - flexDirection: "row", - justifyContent: "space-evenly", - alignItems: "center", - width: "100%", - }, - logoContainer: { - display: "flex", - alignItems: "center", - justifyContent: "center", - marginBottom: "2rem", - width: "50%", - wordSpacing: "4px", - flexDirection: "row", - }, - logoSquare: { - width: "28px", - height: "28px", - backgroundColor: "#f25022", - marginRight: "10px", - }, - logoText: { - fontSize: "1.6rem", - fontWeight: "bold", - }, - formContainer: { - width: "500px", - padding: "3rem", - // Partially transparent background - backgroundColor: "rgba(255, 255, 255, 0.8)", - color: "#000", // ensure text is dark enough to stand out - borderRadius: "8px", - boxShadow: "0 2px 10px rgba(0,0,0,0.15)", - display: "flex", - flexDirection: "column", - }, - heading: { - marginBottom: "1.2rem", - fontSize: "2.2rem", - fontWeight: 500, - textAlign: "left", - }, - appName: { - marginBottom: "0.4rem", - fontSize: "2.2rem", - fontWeight: 700, - textAlign: "left", - color: "rgba(255, 105, 0, 1)", - }, - backButton: { - background: "none", - border: "none", - color: "#0b303b", - cursor: "pointer", - fontSize: "1.1rem", - marginBottom: "2rem", - alignSelf: "flex-start", - padding: 0, - }, - label: { - marginBottom: "0.75rem", - fontSize: "1.2rem", - textAlign: "left", - }, - input: { - marginBottom: "1.75rem", - padding: "1rem", - fontSize: "1.2rem", - border: "1px solid #ccc", - borderRadius: "4px", - width: "100%", - boxSizing: "border-box", - color: "lightgray", - }, - button: { - marginBottom: "1.2rem", - padding: "0.6rem", - fontSize: "1.2rem", - cursor: "pointer", - border: "2px solid", - borderRadius: "24px", - }, - helloButton: { - backgroundColor: "#0b303b", - border: "1px solid #ccc", - color: "#fff", + alignItems: "start", + textAlign: "start", }, }; diff --git a/frontend/src/RegisterLanding.tsx b/frontend/src/RegisterLanding.tsx new file mode 100644 index 00000000..dbe4ff23 --- /dev/null +++ b/frontend/src/RegisterLanding.tsx @@ -0,0 +1,50 @@ +import logo from "./images/bcan_logo.svg"; + +/** + * Registered users can log in here + */ +const RegisterLanding = () => { + return ( +
+
+
+ BCAN Logo +
+
+
+
+

+ Account registration successful! +

+

+ Thank you for registering. Your account is currently under review by + our team. You'll receive an email notification once your account has + been approved. Please try logging in after receiving approval. +

+
+
+
+ ); +}; + +export default RegisterLanding; + +// Inline style objects +const styles: { [key: string]: React.CSSProperties } = { + pageContainer: { + position: "relative", + width: "100vw", + height: "100vh", + margin: 0, + padding: 0, + overflow: "hidden", + display: "flex", + justifyContent: "center", + alignItems: "start", + textAlign: "start", + }, +}; diff --git a/frontend/src/animations/AnimatedRoutes.tsx b/frontend/src/animations/AnimatedRoutes.tsx index 413a3209..86216747 100644 --- a/frontend/src/animations/AnimatedRoutes.tsx +++ b/frontend/src/animations/AnimatedRoutes.tsx @@ -10,6 +10,7 @@ import { useAuthContext } from "../context/auth/authContext"; import MainPage from "../main-page/MainPage"; import Login from "../Login"; import Register from "../Register"; +import RegisterLanding from "../RegisterLanding"; /** * AnimatedRoutes: @@ -32,6 +33,12 @@ const AnimatedRoutes = observer(() => { isAuthenticated ? : } /> + + } + /> : } diff --git a/frontend/src/context/auth/authContext.tsx b/frontend/src/context/auth/authContext.tsx index 2c19660c..13931177 100644 --- a/frontend/src/context/auth/authContext.tsx +++ b/frontend/src/context/auth/authContext.tsx @@ -11,7 +11,7 @@ import { api } from '../../api'; interface AuthContextProps { isAuthenticated: boolean; login: (username: string, password: string) => Promise; - register: (username: string, password: string, email: string) => Promise; + register: (username: string, password: string, email: string) => Promise<{ state: boolean; message: String; }>; logout: () => void; user: User | null; } @@ -57,7 +57,7 @@ export const AuthProvider = observer(({ children }: { children: ReactNode }) => /** * Register a new user and automatically log them in */ - const register = async (username: string, password: string, email: string): Promise => { + const register = async (username: string, password: string, email: string): Promise<{ state: boolean; message: String; }>=> { try { const response = await api('/auth/register', { method: 'POST', @@ -69,24 +69,25 @@ export const AuthProvider = observer(({ children }: { children: ReactNode }) => if (response.ok) { const loggedIn = await login(username, password); - if (loggedIn) return true; + if (loggedIn) return {state: true, message: ''}; console.warn('User registered but auto-login failed'); - return false; + return {state: false, message: 'User registered but auto-login failed'}; } if (response.status === 409 || data.message?.includes('exists')) { - alert('An account with this username or email already exists.'); + //alert('An account with this username or email already exists.'); + return {state: false, message: 'An account with this username or email already exists.'} } else if (response.status === 400) { - alert(data.message || 'Invalid registration details.'); + //alert(data.message || 'Invalid registration details.'); + return {state: false, message: 'Invalid registration details. ' + (data.message || '')} } else { - alert('Registration failed. Please try again later.'); + //alert('Registration failed. Please try again later.'); + return {state: false, message: 'Please try again later.'} } - - return false; } catch (error) { console.error('Error during registration:', error); - alert('An unexpected error occurred. Please try again later.'); - return false; + //alert('An unexpected error occurred. Please try again later.'); + return {state: false, message: 'An unexpected error occurred. Please try again later.'} } }; From 7b67d16a6dc7a12cbcb25ca65bac26981f64ec17 Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 02:25:47 -0500 Subject: [PATCH 3/8] Added bell --- frontend/src/main-page/header/Bell.tsx | 63 +++++++++++++++++++------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/frontend/src/main-page/header/Bell.tsx b/frontend/src/main-page/header/Bell.tsx index 1aeb811d..68c99429 100644 --- a/frontend/src/main-page/header/Bell.tsx +++ b/frontend/src/main-page/header/Bell.tsx @@ -6,7 +6,6 @@ import NotificationPopup from "../notifications/NotificationPopup"; import { setNotifications as setNotificationsAction } from "../../external/bcanSatchel/actions"; import { getAppStore } from "../../external/bcanSatchel/store"; - // get current user id // const currUserID = sessionStorage.getItem('userId'); // const currUserID = "bcanuser33"; @@ -28,17 +27,25 @@ const BellButton = () => { const handleClick = async () => { //temporary dummy data for now const dummyNotifications = [ - {id: 1, title: "Grant Deadline", message: "Grant A deadline approaching in 3 days"}, - {id: 2, title: "Grant Deadline", message: "Grant B deadline tomorrow!"}, - {id: 3, title: "Grant Deadline", message: "Grant C deadline passed yesterday!"}, - {id: 4, title: "Grant Deadline", message: "Grant D deadline tomorrow!"} + { + id: 1, + title: "Grant Deadline", + message: "Grant A deadline approaching in 3 days", + }, + { id: 2, title: "Grant Deadline", message: "Grant B deadline tomorrow!" }, + { + id: 3, + title: "Grant Deadline", + message: "Grant C deadline passed yesterday!", + }, + { id: 4, title: "Grant Deadline", message: "Grant D deadline tomorrow!" }, ]; //previous api logic (for later) //const response = await api( - //`/notifications/user/${currUserID}`, - //{ - //method: "GET", - //} + //`/notifications/user/${currUserID}`, + //{ + //method: "GET", + //} //); //console.log(response); //const currNotifications = await response.json(); @@ -51,17 +58,41 @@ const BellButton = () => { return (
- + + + {notifications.length > 0 && ( + + )} +
{isClicked && ( )}
From 79cb878761073166fe84c3378c51c64f9b3b256e Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 20:28:46 -0500 Subject: [PATCH 4/8] Finalizing screens --- frontend/src/Login.tsx | 11 ++-- frontend/src/Register.tsx | 110 ++++++++++++++++++++++++------- frontend/src/RegisterLanding.tsx | 6 +- frontend/src/styles/index.css | 4 ++ 4 files changed, 97 insertions(+), 34 deletions(-) diff --git a/frontend/src/Login.tsx b/frontend/src/Login.tsx index 619a3b62..58397697 100644 --- a/frontend/src/Login.tsx +++ b/frontend/src/Login.tsx @@ -29,11 +29,12 @@ const Login = observer(() => { return (
+ {/*/ Left side: Registration form */}

Welcome back!

- Enter your credentials to access your account + Enter your credentials to access your account.

@@ -78,13 +79,12 @@ const Login = observer(() => {
{failure ? (
- Your password is incorrect or this account doesn't exist + Your password is incorrect or this account doesn't exist.
) : (
{" "}
)}
-
- - {/* Buttons row: Sign In, vertical separator, and Register */}
Don't have an account?{" "}
+ {/*/ Right side: logo */}
BCAN Logo diff --git a/frontend/src/Register.tsx b/frontend/src/Register.tsx index c50b8c7f..c7c8ede1 100644 --- a/frontend/src/Register.tsx +++ b/frontend/src/Register.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react-lite"; import { useNavigate } from "react-router-dom"; import logo from "./images/bcan_logo.svg"; import { useAuthContext } from "./context/auth/authContext"; +import "./styles/index.css"; /** * Register a new BCAN user @@ -12,51 +13,94 @@ const Register = observer(() => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [passwordRe, setPasswordRe] = useState(""); - const [failure, setFailure] = useState({ state: false, message: "" }); + const [failure, setFailure] = useState({ + state: false, + message: "", + item: "", + }); const navigate = useNavigate(); const { register } = useAuthContext(); + const passswordRegex: RegExp = + /^(?=.*[!@#$%^&*])(?=.*\d)(?=.*[A-Z])(?=.*[a-z]).{8,}$/; + const emailRegex: RegExp = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + const defaultPasswordMessage: string = `• Passwords must have at least one special character (!@#$%^&*) +• Passwords must have at least one digit character ('0'-'9') +• Passwords must have at least one uppercase letter ('A'-'Z') and one lowercase letter ('a'-'z') +• Passwords must be at least 8 characters long`; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); + // Input validation + if (!emailRegex.test(email)) { + setFailure({ + state: true, + message: "Please enter a valid email address.", + item: "email", + }); + return; + } + if (!passswordRegex.test(password)) { + setFailure({ + state: true, + message: defaultPasswordMessage, + item: "password", + }); + return; + } const success = await register(username, password, email); - if (!failure.state && success.state) { + if (password === passwordRe && success.state) { navigate("/registered"); } else { - setFailure({ state: true, message: "Registration failed: " + success.message }); + setFailure({ + state: true, + message: "Registration failed: " + success.message, + item: "registration", + }); console.warn("Registration failed"); } }; + // Handlers for password and password confirmation inputs const handlePassword = (e: string) => { setPassword(e); - if (e !== password && passwordRe !== "") { - setFailure({ state: true, message: "Passwords do not match" }); + if (e !== passwordRe && passwordRe !== "") { + setFailure({ + state: true, + message: "Passwords do not match.", + item: "password", + }); } else { - setFailure({ state: false, message: "" }); + setFailure({ state: false, message: "", item: "" }); } }; const handlePasswordMatch = (e: string) => { setPasswordRe(e); if (e !== password) { - setFailure({ state: true, message: "Passwords do not match" }); + setFailure({ + state: true, + message: "Passwords do not match.", + item: "password", + }); } else { - setFailure({ state: false, message: "" }); + setFailure({ state: false, message: "", item: "" }); } }; return (
-
+ {/*/ Left side: Registration form */} +

Get Started Now

+
{ required onChange={(e) => setEmail(e.target.value)} placeholder="Enter your email" - style={styles.inputContainer} + style={ + failure.item === "email" + ? styles.errorItem + : styles.inputContainer + } className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" />
@@ -103,7 +151,11 @@ const Register = observer(() => { required onChange={(e) => handlePassword(e.target.value)} placeholder="Enter your password" - style={styles.inputContainer} + style={ + failure.item === "password" + ? styles.errorItem + : styles.inputContainer + } className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" />
@@ -121,7 +173,11 @@ const Register = observer(() => { onChange={(e) => handlePasswordMatch(e.target.value)} required placeholder="Re-enter your password" - style={styles.inputContainer} + style={ + failure.item === "password" + ? styles.errorItem + : styles.inputContainer + } className="block min-w-0 rounded-md grow bg-white py-1.5 pr-3 pl-4 text-base placeholder:text-gray-500 border border-[#D9D9D9]" />
@@ -129,15 +185,10 @@ const Register = observer(() => {
- {failure.state ? failure.message : `• Passwords must have at least one special character (!@#$%^&*) -• Passwords must have at least one digit character ('0'-'9') -• Passwords must have at least one uppercase character ('A'-'Z')`} + {failure.state ? failure.message : defaultPasswordMessage}
@@ -153,8 +204,6 @@ const Register = observer(() => {
or

- - {/* Buttons row: Sign In, vertical separator, and Register */}
Don't have an account?{" "}
- + {/*/ Right side: logo */}
BCAN Logo @@ -196,4 +245,15 @@ const styles: { [key: string]: React.CSSProperties } = { alignItems: "start", textAlign: "start", }, + warning: { + color: "#616161", + backgroundColor: "#E7E7E7", + }, + error: { + color: "#D33221", + backgroundColor: "#FFA399", + }, + errorItem: { + borderColor: "#D33221", + }, }; diff --git a/frontend/src/RegisterLanding.tsx b/frontend/src/RegisterLanding.tsx index dbe4ff23..cab1248b 100644 --- a/frontend/src/RegisterLanding.tsx +++ b/frontend/src/RegisterLanding.tsx @@ -1,7 +1,7 @@ import logo from "./images/bcan_logo.svg"; /** - * Registered users can log in here + * Registered user landing page after signing up */ const RegisterLanding = () => { return ( @@ -9,7 +9,7 @@ const RegisterLanding = () => {
BCAN Logo @@ -17,7 +17,7 @@ const RegisterLanding = () => {
-

+

Account registration successful!

diff --git a/frontend/src/styles/index.css b/frontend/src/styles/index.css index b0ec10e3..548ff0f3 100644 --- a/frontend/src/styles/index.css +++ b/frontend/src/styles/index.css @@ -75,3 +75,7 @@ button:focus-visible { background-color: #f9f9f9; } } + + input:focus { + outline: 1px solid darkorange; + } \ No newline at end of file From 119161139e08cafa684c5a7f75e638b1783a9ece Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 20:32:49 -0500 Subject: [PATCH 5/8] Fixing logo --- frontend/src/images/bcan_logo.svg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/images/bcan_logo.svg b/frontend/src/images/bcan_logo.svg index 67c5c6bf..0c857a7c 100644 --- a/frontend/src/images/bcan_logo.svg +++ b/frontend/src/images/bcan_logo.svg @@ -1,9 +1,9 @@ - - + + - - + + - + From 8f57a6a2f47f3af1de200ab799f5f1ca3dbff015 Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 20:40:36 -0500 Subject: [PATCH 6/8] Adding observer to bell --- frontend/src/main-page/header/Bell.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/main-page/header/Bell.tsx b/frontend/src/main-page/header/Bell.tsx index 68c99429..759ce534 100644 --- a/frontend/src/main-page/header/Bell.tsx +++ b/frontend/src/main-page/header/Bell.tsx @@ -5,12 +5,13 @@ import { useEffect, useState } from "react"; import NotificationPopup from "../notifications/NotificationPopup"; import { setNotifications as setNotificationsAction } from "../../external/bcanSatchel/actions"; import { getAppStore } from "../../external/bcanSatchel/store"; +import { observer } from "mobx-react-lite"; // get current user id // const currUserID = sessionStorage.getItem('userId'); // const currUserID = "bcanuser33"; -const BellButton = () => { +const BellButton = observer(() => { // stores notifications for the current user const store = getAppStore(); const notifications = store.notifications ?? []; @@ -97,6 +98,6 @@ const BellButton = () => { )}

); -}; +}); export default BellButton; From dc23a5d8904cda2ecd6abc8d03fca2537447853f Mon Sep 17 00:00:00 2001 From: Jane Kamata Date: Sun, 23 Nov 2025 20:49:12 -0500 Subject: [PATCH 7/8] Fxing labels spacing --- frontend/src/main-page/grants/grant-list/GrantLabels.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/main-page/grants/grant-list/GrantLabels.tsx b/frontend/src/main-page/grants/grant-list/GrantLabels.tsx index d8cee2b4..961af701 100644 --- a/frontend/src/main-page/grants/grant-list/GrantLabels.tsx +++ b/frontend/src/main-page/grants/grant-list/GrantLabels.tsx @@ -18,7 +18,7 @@ const GrantLabels: React.FC<{ } return ( -
    +