Skip to content

Commit c40ad05

Browse files
committed
add notifications for sign up and login
1 parent d1f6dfa commit c40ad05

File tree

8 files changed

+175
-13
lines changed

8 files changed

+175
-13
lines changed

package-lock.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"@mantine/hooks": "^6.0.1",
1111
"@mantine/notifications": "^6.0.1",
1212
"@mantine/nprogress": "^6.0.1",
13+
"@tabler/icons-react": "^2.11.0",
1314
"@testing-library/jest-dom": "^5.16.5",
1415
"@testing-library/react": "^13.4.0",
1516
"@testing-library/user-event": "^13.5.0",

src/components/auth/Login.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ export type LoginFields = z.infer<typeof schema>;
1919

2020
type Props = {
2121
onSubmit: (f: LoginFields) => void;
22+
isLoading: boolean;
2223
};
2324

2425
const Login = (props: Props) => {
25-
const { onSubmit } = props;
26+
const { onSubmit, isLoading } = props;
2627

2728
const form = useForm<LoginFields>({
2829
initialValues: {
@@ -52,7 +53,9 @@ const Login = (props: Props) => {
5253
/>
5354

5455
<Group mt="lg" position="right">
55-
<Button type="submit">Login</Button>
56+
<Button type="submit" loading={isLoading}>
57+
Login
58+
</Button>
5659
</Group>
5760
</form>
5861
</Stack>

src/components/auth/Signup.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import { z } from "zod";
1313
const schema = z
1414
.object({
1515
name: z.string().nonempty({ message: "Required" }),
16-
committee: z.string().nonempty({ message: "Required" }),
16+
subcomms: z.string().nonempty({ message: "Required" }),
1717
email: z.string().email().nonempty({ message: "Required" }),
18+
contactNum: z.string().regex(new RegExp(/^\d+$/), "Invalid phone number"),
1819
password: z.string().min(6),
1920
confirmPassword: z.string().nonempty({ message: "Required" }),
2021
})
@@ -32,15 +33,17 @@ export type SignupFields = z.infer<typeof schema>;
3233

3334
type Props = {
3435
onSubmit: (f: SignupFields) => void;
36+
isLoading: boolean;
3537
};
3638

3739
const Signup = (props: Props) => {
38-
const { onSubmit } = props;
40+
const { onSubmit, isLoading } = props;
3941

4042
const form = useForm<SignupFields>({
4143
initialValues: {
4244
name: "",
43-
committee: "",
45+
subcomms: "",
46+
contactNum: "",
4447
email: "",
4548
password: "",
4649
confirmPassword: "",
@@ -74,6 +77,13 @@ const Signup = (props: Props) => {
7477
mt="md"
7578
{...form.getInputProps("email")}
7679
/>
80+
<TextInput
81+
withAsterisk
82+
label="Contact Number"
83+
placeholder="12341234"
84+
mt="md"
85+
{...form.getInputProps("contactNum")}
86+
/>
7787
<PasswordInput
7888
withAsterisk
7989
label="Password"
@@ -90,7 +100,9 @@ const Signup = (props: Props) => {
90100
/>
91101

92102
<Group mt="lg" position="right">
93-
<Button type="submit">Sign Up</Button>
103+
<Button type="submit" loading={isLoading}>
104+
Sign Up
105+
</Button>
94106
</Group>
95107
</form>
96108
</Stack>

src/hooks/notification.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { IconCheck, IconX } from "@tabler/icons-react";
2+
import { notifications, NotificationProps } from "@mantine/notifications";
3+
4+
export const useNotification = () => {
5+
const showSuccess = (props: NotificationProps) => {
6+
notifications.show({
7+
...props,
8+
color: "green",
9+
icon: <IconCheck />,
10+
});
11+
};
12+
13+
const showError = (props: NotificationProps) => {
14+
notifications.show({
15+
...props,
16+
color: "red",
17+
icon: <IconX />,
18+
});
19+
};
20+
21+
return {
22+
notifications,
23+
showSuccess,
24+
showError,
25+
};
26+
};

src/pages/Login.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,52 @@
1+
import { login } from "api/auth";
2+
import { FirebaseError } from "firebase/app";
3+
import { useNotification } from "hooks/notification";
14
import React from "react";
25
import Login, { LoginFields } from "../components/auth/Login";
36

47
const LoginPage = () => {
8+
const { showSuccess, showError } = useNotification();
9+
const [isLoading, setLoading] = React.useState(false);
10+
511
const onSubmit = async (values: LoginFields) => {
612
const { email, password } = values;
713

8-
console.log(email);
9-
console.log(password);
14+
setLoading(true);
15+
try {
16+
await login({
17+
email,
18+
password,
19+
});
20+
showSuccess({
21+
title: "Login Success",
22+
message: "Logged in successfully",
23+
});
24+
} catch (e) {
25+
let errorMessage = "";
26+
27+
if (e instanceof FirebaseError) {
28+
if (e.code === "auth/user-not-found") {
29+
errorMessage = "User not found";
30+
} else if (e.code === "auth/wrong-password") {
31+
errorMessage = "Wrong password";
32+
} else {
33+
console.log(e.code);
34+
errorMessage = "Unknown error";
35+
}
36+
} else {
37+
errorMessage = "Unknown error";
38+
}
39+
40+
showError({
41+
title: "Error",
42+
message: errorMessage,
43+
});
44+
}
45+
46+
setLoading(false);
1047
};
1148

12-
return <Login onSubmit={onSubmit} />;
49+
return <Login onSubmit={onSubmit} isLoading={isLoading} />;
1350
};
1451

1552
export default LoginPage;

src/pages/Signup.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,52 @@
1+
import { FirebaseError } from "firebase/app";
2+
import { useNotification } from "hooks/notification";
13
import React from "react";
2-
import Signup from "../components/auth/Signup";
4+
import { signUp } from "../api/auth";
5+
import Signup, { SignupFields } from "../components/auth/Signup";
36

47
const SignupPage = () => {
5-
return <Signup onSubmit={() => {}} />;
8+
const { showSuccess, showError } = useNotification();
9+
const [isLoading, setLoading] = React.useState(false);
10+
11+
const onSubmit = async (values: SignupFields) => {
12+
const { name, email, subcomms, password, contactNum } = values;
13+
14+
setLoading(true);
15+
try {
16+
await signUp({
17+
name,
18+
email,
19+
subcomms,
20+
password,
21+
contactNum,
22+
});
23+
showSuccess({
24+
title: "Sign up Success",
25+
message: "Signed up successfully",
26+
});
27+
} catch (e) {
28+
let errorMessage = "";
29+
30+
if (e instanceof FirebaseError) {
31+
if (e.code === "auth/email-already-exists") {
32+
errorMessage = "Email already exists";
33+
} else {
34+
console.log(e.code);
35+
errorMessage = "Unknown error";
36+
}
37+
} else {
38+
errorMessage = "Unknown error";
39+
}
40+
41+
showError({
42+
title: "Error",
43+
message: errorMessage,
44+
});
45+
}
46+
setLoading(false);
47+
};
48+
49+
return <Signup onSubmit={onSubmit} isLoading={isLoading} />;
650
};
751

852
export default SignupPage;

yarn.lock

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,6 +2494,19 @@
24942494
"@svgr/plugin-svgo" "^5.5.0"
24952495
loader-utils "^2.0.0"
24962496

2497+
"@tabler/icons-react@^2.11.0":
2498+
version "2.11.0"
2499+
resolved "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-2.11.0.tgz"
2500+
integrity sha512-Mbie8IFLrtI0sGm802Bmierle0ixIi7FVczShoLjPZwRM0da1HcD588TF7oMuQ09zd241BY+L7M/f0Q6lquBng==
2501+
dependencies:
2502+
"@tabler/icons" "2.11.0"
2503+
prop-types "^15.7.2"
2504+
2505+
2506+
version "2.11.0"
2507+
resolved "https://registry.npmjs.org/@tabler/icons/-/icons-2.11.0.tgz"
2508+
integrity sha512-KPESQnvHoSpbAdgzDdrSmeZ9AE8fSU12fU3Cag79uXJCUkC8f741fcvPJPsFMDe0S96VSq3mMYF8JnA7a570uQ==
2509+
24972510
"@testing-library/dom@^8.5.0", "@testing-library/dom@>=7.21.4":
24982511
version "8.20.0"
24992512
resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz"
@@ -8343,7 +8356,7 @@ prompts@^2.0.1, prompts@^2.4.2:
83438356
kleur "^3.0.3"
83448357
sisteransi "^1.0.5"
83458358

8346-
prop-types@^15.6.2, prop-types@^15.8.1:
8359+
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
83478360
version "15.8.1"
83488361
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
83498362
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -8655,7 +8668,7 @@ [email protected]:
86558668
loose-envify "^1.4.0"
86568669
prop-types "^15.6.2"
86578670

8658-
"react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", react@>=16.6.0, react@>=16.8, react@>=16.8.0:
8671+
"react@^16.5.1 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", react@>=16.6.0, react@>=16.8, react@>=16.8.0:
86598672
version "18.2.0"
86608673
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
86618674
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==

0 commit comments

Comments
 (0)