Skip to content

Instantly share code, notes, and snippets.

@0xabdou
Created February 20, 2021 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0xabdou/b63e53d71e2c9d77fefa5d2df6723c92 to your computer and use it in GitHub Desktop.
Save 0xabdou/b63e53d71e2c9d77fefa5d2df6723c92 to your computer and use it in GitHub Desktop.
Final version of auth-slice.tsx
import {createAsyncThunk, createSlice} from "@reduxjs/toolkit";
import User from "./types/user";
import AuthError from "./types/auth-error";
import {EmailPass} from "./types/email-pass";
import {StoreExtraArg} from "../../app/dependencies";
import {isRight} from "fp-ts/Either";
export type AuthState = {
currentUser: User | null,
loading: boolean,
error: AuthError | null,
};
type ThunkApi = {
rejectValue: AuthError,
extra: StoreExtraArg,
};
const loginWithEmailAndPass = createAsyncThunk<User, EmailPass, ThunkApi>(
'auth/loginWithEmailAndPass',
async (emailPass, thunkAPI) => {
const result = await thunkAPI.extra.authRepo.signInWithEmailAndPassword(emailPass);
if (isRight(result)) {
return result.right;
}
return thunkAPI.rejectWithValue(result.left);
}
);
const logout = createAsyncThunk<null, void, ThunkApi>(
'auth/logout',
async (_, thunkAPI) => {
const result = await thunkAPI.extra.authRepo.signOut();
if (isRight(result)) {
return result.right;
}
return thunkAPI.rejectWithValue(result.left);
}
);
const initialState: AuthState = {
currentUser: null,
loading: false,
error: null,
};
const authSlice = createSlice({
name: 'auth',
reducers: {},
initialState,
extraReducers: builder => {
// loginWithEmailAndPass
builder
.addCase(loginWithEmailAndPass.pending, state => {
// Login started
state.loading = true;
state.error = null;
})
.addCase(loginWithEmailAndPass.fulfilled, (state, action) => {
// Login succeeded
state.currentUser = action.payload;
state.loading = false;
})
.addCase(loginWithEmailAndPass.rejected, (state, action) => {
// Login failed
if (action.payload == undefined)
state.error = AuthError.general;
else
state.error = action.payload;
state.loading = false;
});
// logout
builder
.addCase(logout.pending, state => {
state.error = null;
})
.addCase(logout.fulfilled, state => {
state.currentUser = null;
})
.addCase(logout.rejected, (state, action) => {
if (action.payload == undefined)
state.error = AuthError.general;
else
state.error = action.payload;
state.loading = false;
});
}
});
export const authActions = {loginWithEmailAndPass, logout};
export default authSlice.reducer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment