Skip to content

Commit

Permalink
Merge pull request #30 from Chamindu36/ts-dev-migration
Browse files Browse the repository at this point in the history
[TS-Migration] Migrate user reducer code files and firebase related code to TypeScript
  • Loading branch information
Chamindu36 authored Aug 23, 2023
2 parents 968f287 + 1dc09ab commit 66c6bf3
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 95 deletions.
28 changes: 0 additions & 28 deletions src/store/user/user.action.js

This file was deleted.

56 changes: 56 additions & 0 deletions src/store/user/user.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createAction, withMatcher, Action, ActionWithPayload } from "../../utils/reducer/reducer.utils";
import { USER_ACTION_TYPES } from "./user.types";
import { UserData, AdditionalInfo } from "../../utils/firebase/firebase.utils";

// Degine action types
export type CheckUserSession = Action<USER_ACTION_TYPES.CHECK_USER_SESSION>;
export type SetCurrentUser = ActionWithPayload<USER_ACTION_TYPES.SET_CURRENT_USER, UserData>;
export type GoogleSignInStart = Action<USER_ACTION_TYPES.GOOGLE_SIGN_IN_START>;
export type EmailSignInStart = ActionWithPayload<USER_ACTION_TYPES.EMAIL_SIGN_IN_START, { email: string, password: string }>;
export type SignInSuccess = ActionWithPayload<USER_ACTION_TYPES.SIGN_IN_SUCCESS, UserData>;
export type SignInFailed = ActionWithPayload<USER_ACTION_TYPES.SIGN_IN_FAILED, Error>;
export type SignUpStart = ActionWithPayload<USER_ACTION_TYPES.SIGN_UP_START, { email: string, password: string, displayName: string }>;
export type SignUpSuccess = ActionWithPayload<USER_ACTION_TYPES.SIGN_UP_SUCCESS, { user: UserData, additionalDetails: AdditionalInfo }>;
export type SignUpFailed = ActionWithPayload<USER_ACTION_TYPES.SIGN_UP_FAILED, Error>;
export type SignOutStart = Action<USER_ACTION_TYPES.SIGN_OUT_START>;
export type SignOutSuccess = Action<USER_ACTION_TYPES.SIGN_OUT_SUCCESS>;
export type SignOutFailed = ActionWithPayload<USER_ACTION_TYPES.SIGN_OUT_FAILED, Error>;

export const setCurrentUser = withMatcher((user: UserData): SetCurrentUser =>
createAction(USER_ACTION_TYPES.SET_CURRENT_USER, user));

export const checkUserSession = withMatcher((): CheckUserSession =>
createAction(USER_ACTION_TYPES.CHECK_USER_SESSION));

export const googleSignInStart = withMatcher((): GoogleSignInStart =>
createAction(USER_ACTION_TYPES.GOOGLE_SIGN_IN_START));

export const emailSignInStart = withMatcher((email:string, password:string): EmailSignInStart =>
createAction(USER_ACTION_TYPES.EMAIL_SIGN_IN_START, { email, password }));

export const signInSuccess = withMatcher((user:UserData): SignInSuccess =>
createAction(USER_ACTION_TYPES.SIGN_IN_SUCCESS, user));

export const signInFailed = withMatcher((error: Error): SignInFailed =>
createAction(USER_ACTION_TYPES.SIGN_IN_FAILED, error));

export const signUpStart = withMatcher((
email:string,
password:string,
displayName:string): SignUpStart =>
createAction(USER_ACTION_TYPES.SIGN_UP_START,{ email, password, displayName }));

export const signUpSuccess = withMatcher((user:UserData, additionalDetails: AdditionalInfo) =>
createAction(USER_ACTION_TYPES.SIGN_UP_SUCCESS, { user, additionalDetails }));

export const signUpFailed = withMatcher((error: Error): SignUpFailed =>
createAction(USER_ACTION_TYPES.SIGN_UP_FAILED, error));

export const signOutStart = withMatcher((): SignOutStart =>
createAction(USER_ACTION_TYPES.SIGN_OUT_START));

export const signOutSuccess = withMatcher((): SignOutSuccess =>
createAction(USER_ACTION_TYPES.SIGN_OUT_SUCCESS));

export const signOutFailed = withMatcher((error: Error): SignOutFailed =>
createAction(USER_ACTION_TYPES.SIGN_OUT_FAILED, error));
42 changes: 0 additions & 42 deletions src/store/user/user.reducer.js

This file was deleted.

68 changes: 68 additions & 0 deletions src/store/user/user.reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { AnyAction } from "redux";

import {
signInFailed,
signInSuccess,
signUpFailed,
signUpSuccess,
signOutFailed,
signOutSuccess,
} from './user.action'

import { UserData } from "../../utils/firebase/firebase.utils";

// Define user state object
export type UserState = {
readonly currentUser: UserData | null,
readonly isLoading: boolean,
readonly error: Error | null,
};

// Setup initial state
const INITIAL_STATE: UserState = {
currentUser: null,
isLoading: false,
error: null,
};

export const userReducer = (state = INITIAL_STATE, action: AnyAction) => {

if (signInSuccess.match(action)) {
return {
...state,
currentUser: action.payload,
isLoading: false,
error: null,
};
};

if (signOutSuccess.match(action)) {
return {
...state,
currentUser: null,
isLoading: false,
error: null,
};
};

if (signUpSuccess.match(action)) {
return {
...state,
currentUser: action.payload.user,
isLoading: false,
error: null,
};
};

// All failed actions
if (signInFailed.match(action) || signOutFailed.match(action) || signUpFailed.match(action)) {
return {
...state,
error: action.payload,
isLoading: false,
};
};

return state;

};
1 change: 0 additions & 1 deletion src/store/user/user.selector.js

This file was deleted.

10 changes: 10 additions & 0 deletions src/store/user/user.selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createSelector } from 'reselect';

import { UserState } from './user.reducer';

export const selectUserReducer = (state): UserState => state.user;

export const selectCurrentUser = createSelector(
selectUserReducer,
(user) => user.currentUser
);
14 changes: 0 additions & 14 deletions src/store/user/user.types.js

This file was deleted.

14 changes: 14 additions & 0 deletions src/store/user/user.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export enum USER_ACTION_TYPES {
SET_CURRENT_USER = 'user/SET_CURRENT_USER',
CHECK_USER_SESSION = 'user/CHECK_USER_SESSION',
GOOGLE_SIGN_IN_START = 'user/GOOGLE_SIGN_IN_START',
EMAIL_SIGN_IN_START = 'user/EMAIL_SIGN_IN_START',
SIGN_IN_SUCCESS = 'user/SIGN_IN_SUCCESS',
SIGN_IN_FAILED = 'user/SIGN_IN_FAILED',
SIGN_UP_START = 'user/SIGN_UP_START',
SIGN_UP_SUCCESS = 'user/SIGN_UP_SUCCESS',
SIGN_UP_FAILED = 'user/SIGN_UP_FAILED',
SIGN_OUT_START = 'user/SIGN_OUT_START',
SIGN_OUT_SUCCESS = 'user/SIGN_OUT_SUCCESS',
SIGN_OUT_FAILED = 'user/SIGN_OUT_FAILED',
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
User,
NextOrObserver,
} from 'firebase/auth';

import {
Expand All @@ -19,8 +21,11 @@ import {
collection,
writeBatch,
query,
QueryDocumentSnapshot,
} from 'firebase/firestore';

import { Category } from '../../store/category/category.types';

// Web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyDAy_RME8eCqgH0M91pLmnyjlKFdDktmIA",
Expand All @@ -47,7 +52,15 @@ export const signInWithGoogleRedirect = () => signInWithRedirect(auth, googlePro

export const db = getFirestore();

export const addCollectionAndDocuments = async (collectionKey, objects) => {
// Define a type to add an object
export type ObjectToAdd = {
title: string,
}

export const addCollectionAndDocuments = async <T extends ObjectToAdd>(
collectionKey: string,
objects: Array<T>
) : Promise<void> => {
// create a batch to process multiple transactions
const batch = writeBatch(db);
// create a new collection
Expand All @@ -62,17 +75,20 @@ export const addCollectionAndDocuments = async (collectionKey, objects) => {
// write all transactions in batch to db
await batch.commit();
console.log('done');
}
};


export const getCategoriesAndDocuments = async () => {
export const getCategoriesAndDocuments = async (): Promise<Category[]> => {
// get collection reference
const collectionRef = collection(db, 'categories');
const q = query(collectionRef);

// get all documents and create a map
const querySnapshot = await getDocs(q);

return querySnapshot.docs.map(docSnapshot => docSnapshot.data());
return querySnapshot.docs.map(
docSnapshot => docSnapshot.data() as Category //casting for query objects
);

// const categoryMap = querySnapshot.docs.reduce((acc, docSnapshot) => {
// const { title, items } = docSnapshot.data();
Expand All @@ -83,7 +99,20 @@ export const getCategoriesAndDocuments = async () => {
// return categoryMap;
};

export const createUserDocumentFromAuth = async (userAuth, additionalInfo) => {
export type AdditionalInfo = {
displayName?: string;
};

export type UserData = {
createdAt: Date;
displayName: string;
email: string;
}

export const createUserDocumentFromAuth = async (
userAuth : User,
additionalInfo = {} as AdditionalInfo
) : Promise<QueryDocumentSnapshot<UserData> |void> => {
if (!userAuth) return;

// create the user upon sign in
Expand All @@ -106,19 +135,27 @@ export const createUserDocumentFromAuth = async (userAuth, additionalInfo) => {
...additionalInfo,
});
} catch (error) {
console.log('Error creating user', error.message);
console.log('Error creating user', error);
}
}

return userSnapshot as QueryDocumentSnapshot<UserData>;
};

export const createAuthUserWithEmailAndPassword = async (email, password) => {
export const createAuthUserWithEmailAndPassword = async (
email: string,
password: string,
) => {
// if not either email or password is given, return
if (!email || !password) return;

return await createUserWithEmailAndPassword(auth, email, password);
};

export const signInAuthUserWithEmailAndPassword = async (email, password) => {
export const signInAuthUserWithEmailAndPassword = async (
email : string,
password : string,
) => {
// if not either email or password is given, return
if (!email || !password) return;

Expand All @@ -127,10 +164,12 @@ export const signInAuthUserWithEmailAndPassword = async (email, password) => {

export const signOutUser = async () => await signOut(auth);

export const onAuthStateChangedListener = (callback) =>
export const onAuthStateChangedListener = (
callback: NextOrObserver<User>
) =>
onAuthStateChanged(auth, callback);

export const getCurrentUser = () => {
export const getCurrentUser = (): Promise<User | null> => {
return new Promise((resolve, reject) => {
const unsubscribe = onAuthStateChanged(
auth,
Expand Down

0 comments on commit 66c6bf3

Please sign in to comment.