Skip to content

Commit f8dc241

Browse files
committed
refactor: Remove loading state from TContextAuth and use local state in sign-in and sign-up views
1 parent 7d79a4c commit f8dc241

File tree

5 files changed

+72
-45
lines changed

5 files changed

+72
-45
lines changed

src/App.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import '@mantine/dates/styles.css';
44
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
55
import { ModalsProvider } from '@mantine/modals';
66
import { AuthProvider } from './context/auth-context';
7-
import { RouterProvider, createRouter } from '@tanstack/react-router';
7+
import { RouterProvider, createRouter, useRouter } from '@tanstack/react-router';
88
import './index.css';
99
import { LoadingOverlay } from '@mantine/core';
1010

@@ -34,15 +34,6 @@ const customTheme = createTheme(theme);
3434

3535
function AppWithRouter() {
3636
const auth = useAuthContext();
37-
if (auth.loading) {
38-
return (
39-
<LoadingOverlay
40-
loaderProps={{ type: 'dots', color: 'var(--primary)', size: 'xl' }}
41-
overlayProps={{ color: 'var(--dark-bg-color)' }}
42-
visible
43-
/>
44-
);
45-
}
4637
return <RouterProvider router={router} context={{ auth }} />;
4738
}
4839

src/context/auth-context.tsx

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,30 @@ import {
1616
import { collection, doc, setDoc } from 'firebase/firestore';
1717
import { database } from '@notes/database';
1818
import { CollectionType } from '@notes/types';
19+
import { FirebaseError } from 'firebase/app';
20+
import { useRouter } from '@tanstack/react-router';
1921

2022
export const AuthContext = createContext<TContextAuth | undefined>(undefined);
2123

2224
export function AuthProvider({ children }) {
2325
const [user, setUser] = useState<User | null>(getAuth().currentUser);
2426
const [rememberMe, setRememberMe] = useState(false);
25-
const [loading, setLoading] = useState(true);
27+
// const router = useRouter();
2628

27-
function setLoadingState(loading: boolean) {
28-
setLoading(loading);
29-
}
3029
async function signIn(email: string, password: string) {
3130
try {
3231
if (!rememberMe) {
3332
await setPersistence(auth, inMemoryPersistence);
3433
}
3534

36-
return signInWithEmailAndPassword(auth, email, password);
35+
const userCredential = await signInWithEmailAndPassword(auth, email, password);
36+
37+
setUser(userCredential.user);
38+
return userCredential;
3739
} catch (error) {
38-
if (error instanceof Error) {
40+
if (error instanceof FirebaseError) {
41+
throw new Error(error.code);
42+
} else if (error instanceof Error) {
3943
throw new Error(error.message);
4044
} else {
4145
throw new Error('An unknown error occurred');
@@ -44,14 +48,22 @@ export function AuthProvider({ children }) {
4448
}
4549

4650
async function signUp(email: string, password: string, displayName: string) {
47-
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
48-
// dodac jak mail juz jest uzywany
49-
await setDoc(doc(collection(database, CollectionType.USERS), userCredential.user.uid), {});
50-
await sendEmailVerification(userCredential.user);
51-
await updateProfile(userCredential.user, {
52-
displayName
53-
});
54-
return userCredential;
51+
try {
52+
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
53+
54+
await setDoc(doc(collection(database, CollectionType.USERS), userCredential.user.uid), {});
55+
await sendEmailVerification(userCredential.user);
56+
await updateProfile(userCredential.user, {
57+
displayName
58+
});
59+
return userCredential;
60+
} catch (err) {
61+
if (err instanceof FirebaseError) {
62+
throw new Error(err.code);
63+
} else {
64+
throw new Error(String(err));
65+
}
66+
}
5567
}
5668

5769
// sendPasswordResetEmail(auth, email)
@@ -68,22 +80,25 @@ export function AuthProvider({ children }) {
6880
return signOut(auth);
6981
}
7082
// add modal to display errors => maybe a global modal to be reused for every errors
71-
7283
useEffect(() => {
73-
setLoading(true);
7484
const unsubscribe = auth.onAuthStateChanged(user => {
7585
if (user) {
7686
setUser(user);
77-
setLoading(false);
87+
// router.invalidate(); // this is outside the router,
7888
} else {
7989
setUser(null);
80-
setLoading(false);
8190
}
8291
});
8392
return unsubscribe;
8493
}, []);
8594

86-
const value: TContextAuth = { user, signIn, signUp, signUserOut, loading, setLoadingState, setRememberMe };
95+
const value: TContextAuth = {
96+
user,
97+
signIn,
98+
signUp,
99+
signUserOut,
100+
setRememberMe
101+
};
87102

88103
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
89104
}

src/types/contexts.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ export type TContextAuth = {
44
user: User | null;
55
signIn: (email: string, password: string) => Promise<UserCredential>;
66
signUp: (email: string, password: string, displayName: string) => Promise<UserCredential>;
7-
loading: boolean;
8-
setLoadingState: (loading: boolean) => void;
97
signUserOut: () => Promise<void>;
108
setRememberMe: React.Dispatch<React.SetStateAction<boolean>>
119
};

src/views/auth/sign-in.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { Button, Checkbox, Flex, TextInput, Title, Text } from '@mantine/core';
44
import { z } from 'zod';
55
import { IconLogin, IconLogin2 } from '@tabler/icons-react';
66
import { useAuthContext } from 'src/hooks/use-auth-context';
7-
import { Link, useNavigate } from '@tanstack/react-router';
7+
import { Link, useNavigate, useRouter } from '@tanstack/react-router';
88
import { RoutesDef } from '@notes/utils';
99
import classes from './style.module.css';
10+
import { useState } from 'react';
1011

1112
type SignInValues = {
1213
email: string;
@@ -17,7 +18,9 @@ export const SignIn = () => {
1718
email: '',
1819
password: ''
1920
};
20-
const { signIn, setLoadingState, setRememberMe } = useAuthContext();
21+
const { signIn, setRememberMe } = useAuthContext();
22+
const [loading, setLoading] = useState(false);
23+
2124
const navigate = useNavigate();
2225

2326
const { Field, Subscribe, handleSubmit, state } = useForm({
@@ -27,14 +30,18 @@ export const SignIn = () => {
2730
handleOnSubmit(state.values);
2831
}
2932
});
30-
33+
const router = useRouter();
3134
const handleOnSubmit = async (state: SignInValues) => {
32-
setLoadingState(true);
35+
setLoading(true);
3336
try {
3437
await signIn(state.email, state.password);
35-
setLoadingState(false);
36-
navigate({ to: RoutesDef.HOME });
38+
console.log('🚀 ~ router:', router);
39+
40+
// router.invalidate();
41+
setLoading(false);
42+
navigate({ to: RoutesDef.HOME, invalidate: true });
3743
} catch (err) {
44+
setLoading(false);
3845
alert((err as Error).message);
3946
}
4047
};
@@ -116,8 +123,9 @@ export const SignIn = () => {
116123
right={0}
117124
type="submit"
118125
variant="notes-transparent-border"
119-
loading={isSubmitting}
126+
loading={isSubmitting || loading}
120127
disabled={!canSubmit}
128+
loaderProps={{ color: 'var(--white)', size: 20 }}
121129
>
122130
<IconLogin2 stroke={1.5} />
123131
</Button>

src/views/auth/sign-up.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import classes from './style.module.css';
77
import { useAuthContext } from '@notes/hooks';
88
import { RoutesDef } from '@notes/utils';
99
import { Link, useNavigate } from '@tanstack/react-router';
10+
import { useState } from 'react';
1011

1112
export const SignUp = () => {
1213
const initialState = {
@@ -25,15 +26,21 @@ export const SignUp = () => {
2526
}
2627
});
2728
const navigate = useNavigate();
28-
const { signUp, setLoadingState } = useAuthContext();
29+
const { signUp } = useAuthContext();
30+
const [emailError, setEmailError] = useState('');
31+
const [loading, setLoading] = useState(false);
2932

3033
const handleOnSubmit = async () => {
31-
setLoadingState(true);
34+
setLoading(true);
3235
try {
3336
await signUp(state.values.email, state.values.password, state.values.name);
3437
navigate({ to: RoutesDef.VERIFY_EMAIL });
35-
setLoadingState(false);
38+
setLoading(false);
3639
} catch (error) {
40+
if ((error as Error).message === 'auth/email-already-in-use') {
41+
setEmailError('E-mail already in use');
42+
}
43+
setLoading(false);
3744
throw new Error((error as Error).message);
3845
}
3946
};
@@ -54,8 +61,8 @@ export const SignUp = () => {
5461
<Field
5562
name="name"
5663
validators={{
57-
onSubmit: z.string().trim().min(1, "Field is required"),
58-
onBlur: z.string().trim().min(1, "Field is required")
64+
onSubmit: z.string().trim().min(1, 'Field is required'),
65+
onBlur: z.string().trim().min(1, 'Field is required')
5966
}}
6067
children={({ state, handleChange, handleBlur }) => {
6168
return (
@@ -79,6 +86,13 @@ export const SignUp = () => {
7986
validators={{
8087
onSubmit: z.string().email('Invalid e-mail').trim(),
8188
onBlur: z.string().email('Invalid e-mail')
89+
// onBlurAsync: async ({ value }) => {
90+
// console.log('auth:', auth);
91+
// await auth.getUserByEmail(value).then(data => {
92+
// console.log(data);
93+
// return 'sadgdfsg';
94+
// });
95+
// }
8296
}}
8397
children={({ state, handleChange, handleBlur }) => {
8498
return (
@@ -92,7 +106,7 @@ export const SignUp = () => {
92106
withAsterisk
93107
label="E-mail"
94108
placeholder="Enter e-mail address"
95-
error={state.meta?.errors[0]}
109+
error={state.meta?.errors[0] || emailError}
96110
/>
97111
);
98112
}}
@@ -154,12 +168,13 @@ export const SignUp = () => {
154168
return (
155169
<Flex justify={'flex-end'}>
156170
<Button
157-
loading={isSubmitting}
171+
loading={isSubmitting || loading}
158172
variant="notes-transparent-border"
159173
size="medium"
160174
right={0}
161175
type="submit"
162176
disabled={!canSubmit}
177+
loaderProps={{ color: 'var(--white)', size: 20 }}
163178
>
164179
<IconLogin2 stroke={1.5} />
165180
</Button>

0 commit comments

Comments
 (0)