Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
27 changes: 25 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"private": true,
"dependencies": {
"@babel/plugin-proposal-private-property-in-object": "7.21.11",
"@chakra-ui/icons": "^2.2.0",
"@chakra-ui/react": "^2.8.2",
"@chakra-ui/icons":"^2.2.0",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@giphy/js-fetch-api": "^5.6.0",
Expand All @@ -24,6 +24,7 @@
"react-icons": "^5.2.1",
"react-router-dom": "^6.24.0",
"react-scripts": "^5.0.1",
"react-toastify": "^11.0.5",
"uuid": "^10.0.0",
"web-vitals": "^4.2.0",
"yup": "^1.4.0"
Expand Down
11 changes: 11 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Signin from "./pages/SignIn";
import SignUp from "./pages/SignUp";
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import Home from "./pages/Home";

Expand All @@ -9,6 +11,14 @@ import { Route, Routes, Navigate } from "react-router-dom";

export default function App() {
return (
<>
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
closeOnClick
pauseOnHover
/>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
<Routes>
<Route path="/" element={<Navigate replace to="signin" />} />
<Route
Expand All @@ -22,5 +32,6 @@ export default function App() {
<Route path="/signin" element={<Signin />} />
<Route path="/signup" element={<SignUp />} />
</Routes>
</>
);
}
51 changes: 38 additions & 13 deletions src/pages/SignIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,51 @@ import {
import { auth } from "../firebase";

import { useEffect } from "react";

import { useNavigate } from "react-router-dom";
import FormContainer from "../components/Form/FormContainer";

import { Button, VStack, HStack, useColorMode } from "@chakra-ui/react";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import FormContainer from "../components/Form/FormContainer";
import { Button, VStack, HStack, useColorMode } from "@chakra-ui/react";
import YupValidation, { initialValues } from "../components/Form/YupSignIn";
import TextField from "../components/Form/TextField";
import { Formik, Form } from "formik";

import { IconContext } from "react-icons";
import { FiLogIn } from "react-icons/fi";

const getAuthErrorMessage = (error) => {
switch (error.code) {
case 'auth/user-not-found':
case 'auth/wrong-password':
case 'auth/invalid-credential':
return 'Invalid email or password. Please try again.';
case 'auth/invalid-email':
return 'Please enter a valid email address.';
case 'auth/too-many-requests':
return 'Too many attempts. Please try again later or reset your password.';
case 'auth/popup-closed-by-user':
case 'auth/cancelled-popup-request':
return 'The sign-in process was cancelled.';
case 'auth/popup-blocked':
return 'Pop-up blocked. Please allow pop-ups for this site to sign in.';
default:
return 'An unexpected error occurred. Please try again.';
}
};

export default function Signin() {
const Navigate = useNavigate();
const { colorMode } = useColorMode();

useEffect(() => {
onAuthStateChanged(auth, (user) => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
Navigate("/main");
}
});
// eslint-disable-next-line
}, [auth]);
return () => unsubscribe();
}, [Navigate]);

const NavToSignUp = () => {
Navigate("/signup");
Expand All @@ -40,28 +60,33 @@ export default function Signin() {
const SignInWithGoogle = () => {
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then((cred) => {
console.log("Log in successfully");
.then(() => {
toast.success("Successfully logged in!");
})
.catch((err) => {
console.log(err);
const message = getAuthErrorMessage(err);
toast.error(message);
console.error("Firebase Google Auth Error:", err);
});
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const SignInWithEmailPassword = (values, actions) => {
signInWithEmailAndPassword(auth, values.email, values.password)
.then(() => {
toast.success("Successfully logged in!");
actions.setSubmitting(false);
console.log("Sign in Successfully");
})
.catch((err) => {
const message = getAuthErrorMessage(err);
toast.error(message);
actions.setSubmitting(false);
console.error("Something went wrong", err);
console.error("Firebase Email Auth Error:", err);
});
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

return (
<FormContainer Icon={LoginIcon} title="Sign in for an account!">
<FormContainer Icon={LoginIcon} title="Sign in to your account!">
<ToastContainer position="top-right" autoClose={5000} hideProgressBar={false} />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Move ToastContainer to app root level.

Rendering ToastContainer inside individual page components can lead to multiple container instances when navigating between pages (e.g., SignIn ↔ SignUp), potentially causing duplicate toasts or inconsistent behavior.

Recommended approach:

  1. Remove ToastContainer from this component (and from SignUp.js)
  2. Add a single ToastContainer at the app root level (typically in App.js or index.js)

Example in App.js:

import { ToastContainer } from 'react-toastify';

function App() {
  return (
    <>
      <ToastContainer 
        position="top-right" 
        autoClose={5000} 
        hideProgressBar={false} 
      />
      {/* Your routes and components */}
    </>
  );
}

Then you can call toast.success() or toast.error() from any component without needing to render ToastContainer in each one.

🤖 Prompt for AI Agents
In src/pages/SignIn.js around line 67, the ToastContainer is rendered inside the
SignIn page which can produce multiple instances and duplicate toasts when
navigating; remove the ToastContainer from this file (and similarly from
SignUp.js) and add a single ToastContainer at the app root (e.g., App.js or
index.js) with the same props (position="top-right", autoClose={5000},
hideProgressBar={false}) so all components can call toast.* without rendering
their own container.

<Formik
initialValues={initialValues}
validationSchema={YupValidation}
Expand Down
37 changes: 29 additions & 8 deletions src/pages/SignUp.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
import { useNavigate } from "react-router-dom";
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";

import FormContainer from "../components/Form/FormContainer";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import FormContainer from "../components/Form/FormContainer";
import { VStack, Button, HStack } from "@chakra-ui/react";

import TextField from "../components/Form/TextField";
import { Formik, Form } from "formik";
import YupValidation, { initialValues } from "../components/Form/YupSignUp";

const getSignUpErrorMessage = (error) => {
switch (error.code) {
case 'auth/email-already-in-use':
return 'This email address is already taken.';
case 'auth/weak-password':
return 'The password is too weak. Please use at least 6 characters.';
case 'auth/invalid-email':
return 'Please enter a valid email address.';
default:
return 'An unexpected error occurred. Please try again.';
}
};


export default function SignUp() {
// Init
const auth = getAuth();
const Navigate = useNavigate();

const SignUp = (values, actions) => {
console.log(actions)
createUserWithEmailAndPassword(auth, values.email, values.confirmPassword)
createUserWithEmailAndPassword(auth, values.email, values.password)
.then(() => {
toast.success("Account created successfully!", {
autoClose: 2000,
onClose: () => Navigate("/signin"),
});
actions.setSubmitting(false);
})
.catch(() => {
.catch((error) => {

const message = getSignUpErrorMessage(error);
toast.error(message);
actions.setSubmitting(false);
console.error("Firebase SignUp Error:", error);
});
};

Expand All @@ -31,6 +52,7 @@ export default function SignUp() {

return (
<FormContainer title="Sign up for an account!">
<ToastContainer />
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
<Formik
initialValues={initialValues}
validationSchema={YupValidation}
Expand All @@ -56,7 +78,6 @@ export default function SignUp() {
title="Confirm Password"
YupValidation={YupValidation}
/>

<VStack w={"full"} marginTop="2">
<HStack w={"full"}>
<Button type="submit" isLoading={props.isSubmitting} w={"full"}>
Expand All @@ -75,4 +96,4 @@ export default function SignUp() {
</Button>
</FormContainer>
);
}
}