Client - init login and getting user profile
This commit is contained in:
		
							
								
								
									
										24
									
								
								fittrackee_client/src/api/authApi.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								fittrackee_client/src/api/authApi.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import axios from 'axios'
 | 
			
		||||
import store from '@/store'
 | 
			
		||||
import { USER_STORE } from '@/store/constants'
 | 
			
		||||
import { getApiUrl } from '@/utils'
 | 
			
		||||
 | 
			
		||||
const authApi = axios.create({
 | 
			
		||||
  baseURL: getApiUrl(),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
authApi.interceptors.request.use(
 | 
			
		||||
  (config) => {
 | 
			
		||||
    const authToken = store.getters[USER_STORE.GETTERS.AUTH_TOKEN]
 | 
			
		||||
    if (authToken) {
 | 
			
		||||
      const auth = `Bearer ${authToken}`
 | 
			
		||||
      if (config.headers.Authorization !== auth) {
 | 
			
		||||
        config.headers.Authorization = `Bearer ${authToken}`
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return config
 | 
			
		||||
  },
 | 
			
		||||
  (error) => Promise.reject(error)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
export default authApi
 | 
			
		||||
							
								
								
									
										8
									
								
								fittrackee_client/src/api/defaultApi.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								fittrackee_client/src/api/defaultApi.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import axios from 'axios'
 | 
			
		||||
import { getApiUrl } from '@/utils'
 | 
			
		||||
 | 
			
		||||
const api = axios.create({
 | 
			
		||||
  baseURL: getApiUrl(),
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default api
 | 
			
		||||
@@ -7,21 +7,21 @@
 | 
			
		||||
            v-if="action === 'register'"
 | 
			
		||||
            id="username"
 | 
			
		||||
            required
 | 
			
		||||
            v-model="user.username"
 | 
			
		||||
            v-model="formData.username"
 | 
			
		||||
            :placeholder="t('user.REGISTER')"
 | 
			
		||||
          />
 | 
			
		||||
          <input
 | 
			
		||||
            id="email"
 | 
			
		||||
            required
 | 
			
		||||
            type="email"
 | 
			
		||||
            v-model="user.email"
 | 
			
		||||
            v-model="formData.email"
 | 
			
		||||
            :placeholder="t('user.EMAIL')"
 | 
			
		||||
          />
 | 
			
		||||
          <input
 | 
			
		||||
            id="password"
 | 
			
		||||
            required
 | 
			
		||||
            type="password"
 | 
			
		||||
            v-model="user.password"
 | 
			
		||||
            v-model="formData.password"
 | 
			
		||||
            :placeholder="t('user.PASSWORD')"
 | 
			
		||||
          />
 | 
			
		||||
          <input
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
            id="confirm-password"
 | 
			
		||||
            type="password"
 | 
			
		||||
            required
 | 
			
		||||
            v-model="user.confirmPassword"
 | 
			
		||||
            v-model="formData.confirmPassword"
 | 
			
		||||
            :placeholder="t('user.PASSWORD-CONFIRM')"
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -45,6 +45,9 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import { defineComponent, reactive, ref } from 'vue'
 | 
			
		||||
  import { useI18n } from 'vue-i18n'
 | 
			
		||||
  import { useStore } from 'vuex'
 | 
			
		||||
  import { IFormData } from '@/interfaces.ts'
 | 
			
		||||
  import { USER_STORE } from '@/store/constants'
 | 
			
		||||
 | 
			
		||||
  export default defineComponent({
 | 
			
		||||
    name: 'UserForm',
 | 
			
		||||
@@ -56,21 +59,25 @@
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    setup() {
 | 
			
		||||
      const user = reactive({
 | 
			
		||||
      const formData: IFormData = reactive({
 | 
			
		||||
        username: '',
 | 
			
		||||
        email: '',
 | 
			
		||||
        password: '',
 | 
			
		||||
        confirmPassword: '',
 | 
			
		||||
      })
 | 
			
		||||
      const { t } = useI18n()
 | 
			
		||||
      function onSubmit(action: string) {
 | 
			
		||||
        console.log(action, user)
 | 
			
		||||
      const store = useStore()
 | 
			
		||||
      function onSubmit(actionType: string) {
 | 
			
		||||
        return store.dispatch(USER_STORE.ACTIONS.LOGIN_OR_REGISTER, {
 | 
			
		||||
          actionType,
 | 
			
		||||
          formData,
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        errorMessage: ref(null),
 | 
			
		||||
        t,
 | 
			
		||||
        user,
 | 
			
		||||
        formData,
 | 
			
		||||
        onSubmit,
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -2,3 +2,10 @@ export interface IDropdownOption {
 | 
			
		||||
  value: string | number
 | 
			
		||||
  label: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IFormData {
 | 
			
		||||
  username: string
 | 
			
		||||
  email: string
 | 
			
		||||
  password: string
 | 
			
		||||
  confirmPassword: string
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,16 @@
 | 
			
		||||
import { RootMutations } from '@/store/modules/root/enums'
 | 
			
		||||
import { UserGetters } from '@/store/modules/user/enums'
 | 
			
		||||
import {
 | 
			
		||||
  UserActions,
 | 
			
		||||
  UserGetters,
 | 
			
		||||
  UserMutations,
 | 
			
		||||
} from '@/store/modules/user/enums'
 | 
			
		||||
 | 
			
		||||
export const ROOT_STORE = {
 | 
			
		||||
  MUTATIONS: RootMutations,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const USER_STORE = {
 | 
			
		||||
  ACTIONS: UserActions,
 | 
			
		||||
  GETTERS: UserGetters,
 | 
			
		||||
  MUTATIONS: UserMutations,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								fittrackee_client/src/store/modules/user/actions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								fittrackee_client/src/store/modules/user/actions.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { ActionContext, ActionTree } from 'vuex'
 | 
			
		||||
import { USER_STORE } from '@/store/constants'
 | 
			
		||||
import { IUserActions } from '@/store/modules/user/interfaces'
 | 
			
		||||
import { IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
import { IRootState } from '@/store/modules/root/interfaces'
 | 
			
		||||
import { ILoginOrRegisterData } from '@/store/modules/user/interfaces'
 | 
			
		||||
import api from '@/api/defaultApi'
 | 
			
		||||
import authApi from '@/api/authApi'
 | 
			
		||||
import router from '@/router'
 | 
			
		||||
 | 
			
		||||
export const actions: ActionTree<IUserState, IRootState> & IUserActions = {
 | 
			
		||||
  [USER_STORE.ACTIONS.GET_USER_PROFILE](
 | 
			
		||||
    context: ActionContext<IUserState, IRootState>
 | 
			
		||||
  ): void {
 | 
			
		||||
    authApi
 | 
			
		||||
      .get('auth/profile')
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        if (res.data.status === 'success') {
 | 
			
		||||
          context.commit(
 | 
			
		||||
            USER_STORE.MUTATIONS.UPDATE_AUTH_USER_PROFILE,
 | 
			
		||||
            res.data.data
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .catch((err) => console.log(err))
 | 
			
		||||
  },
 | 
			
		||||
  [USER_STORE.ACTIONS.LOGIN_OR_REGISTER](
 | 
			
		||||
    context: ActionContext<IUserState, IRootState>,
 | 
			
		||||
    data: ILoginOrRegisterData
 | 
			
		||||
  ): void {
 | 
			
		||||
    api
 | 
			
		||||
      .post(`/auth/${data.actionType}`, data.formData)
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        if (res.status == 200 && res.data.status === 'success') {
 | 
			
		||||
          const token = res.data.auth_token
 | 
			
		||||
          window.localStorage.setItem('authToken', token)
 | 
			
		||||
          context.commit(USER_STORE.MUTATIONS.UPDATE_AUTH_TOKEN, token)
 | 
			
		||||
          context
 | 
			
		||||
            .dispatch(USER_STORE.ACTIONS.GET_USER_PROFILE)
 | 
			
		||||
            .then(() => router.push('/'))
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .catch((err) => console.log(err))
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +1,12 @@
 | 
			
		||||
export enum UserActions {
 | 
			
		||||
  GET_USER_PROFILE = 'GET_USER_PROFILE',
 | 
			
		||||
  LOGIN_OR_REGISTER = 'LOGIN_OR_REGISTER',
 | 
			
		||||
}
 | 
			
		||||
export enum UserGetters {
 | 
			
		||||
  IS_AUTHENTICATED = 'IS_AUTHENTICATED',
 | 
			
		||||
  AUTH_TOKEN = 'AUTH_TOKEN',
 | 
			
		||||
}
 | 
			
		||||
export enum UserMutations {
 | 
			
		||||
  UPDATE_AUTH_TOKEN = 'UPDATE_AUTH_TOKEN',
 | 
			
		||||
  UPDATE_AUTH_USER_PROFILE = 'UPDATE_AUTH_USER_PROFILE',
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,9 @@ import { IRootState } from '@/store/modules/root/interfaces'
 | 
			
		||||
import { IUserGetters, IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
 | 
			
		||||
export const getters: GetterTree<IUserState, IRootState> & IUserGetters = {
 | 
			
		||||
  [USER_STORE.GETTERS.AUTH_TOKEN]: (state: IUserState) => {
 | 
			
		||||
    return state.authToken
 | 
			
		||||
  },
 | 
			
		||||
  [USER_STORE.GETTERS.IS_AUTHENTICATED]: (state: IUserState) => {
 | 
			
		||||
    return state.authToken !== null
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,16 @@
 | 
			
		||||
import { Module } from 'vuex'
 | 
			
		||||
import { IRootState } from '@/store/modules/root/interfaces'
 | 
			
		||||
import { actions } from '@/store/modules/user/actions'
 | 
			
		||||
import { getters } from '@/store/modules/user/getters'
 | 
			
		||||
import { IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
import { userState } from '@/store/modules/user/state.ts'
 | 
			
		||||
import { mutations } from '@/store/modules/user/mutations'
 | 
			
		||||
 | 
			
		||||
const user: Module<IUserState, IRootState> = {
 | 
			
		||||
  state: userState,
 | 
			
		||||
  actions,
 | 
			
		||||
  getters,
 | 
			
		||||
  mutations,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default user
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,49 @@
 | 
			
		||||
import { ActionContext } from 'vuex'
 | 
			
		||||
import { IFormData } from '@/interfaces'
 | 
			
		||||
import { USER_STORE } from '@/store/constants'
 | 
			
		||||
import { IRootState } from '@/store/modules/root/interfaces'
 | 
			
		||||
 | 
			
		||||
// DATA
 | 
			
		||||
export interface IAuthUserProfile {
 | 
			
		||||
  admin: boolean
 | 
			
		||||
  bio: string | null
 | 
			
		||||
  birth_date: string | null
 | 
			
		||||
  created_at: string
 | 
			
		||||
  email: string
 | 
			
		||||
  first_name: string | null
 | 
			
		||||
  language: string | null
 | 
			
		||||
  last_name: string | null
 | 
			
		||||
  location: string | null
 | 
			
		||||
  nb_sports: number
 | 
			
		||||
  nb_workouts: number
 | 
			
		||||
  picture: string | boolean
 | 
			
		||||
  sports_list: number[]
 | 
			
		||||
  timezone: string
 | 
			
		||||
  total_distance: number
 | 
			
		||||
  total_duration: string
 | 
			
		||||
  username: string
 | 
			
		||||
  weekm: boolean
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILoginOrRegisterData {
 | 
			
		||||
  actionType: string
 | 
			
		||||
  formData: IFormData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// STORE
 | 
			
		||||
export interface IUserState {
 | 
			
		||||
  authToken: string | null
 | 
			
		||||
  authUserProfile: IAuthUserProfile
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IUserGetters {
 | 
			
		||||
  [USER_STORE.GETTERS.AUTH_TOKEN](state: IUserState): string
 | 
			
		||||
  [USER_STORE.GETTERS.IS_AUTHENTICATED](state: IUserState): boolean
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IUserActions {
 | 
			
		||||
  [USER_STORE.ACTIONS.LOGIN_OR_REGISTER](
 | 
			
		||||
    context: ActionContext<IUserState, IRootState>,
 | 
			
		||||
    data: ILoginOrRegisterData
 | 
			
		||||
  ): void
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								fittrackee_client/src/store/modules/user/mutations.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								fittrackee_client/src/store/modules/user/mutations.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
import { MutationTree } from 'vuex'
 | 
			
		||||
import { TUserMutations } from '@/store/modules/user/types'
 | 
			
		||||
import { USER_STORE } from '@/store/constants'
 | 
			
		||||
import { IAuthUserProfile, IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
 | 
			
		||||
export const mutations: MutationTree<IUserState> & TUserMutations = {
 | 
			
		||||
  [USER_STORE.MUTATIONS.UPDATE_AUTH_TOKEN](
 | 
			
		||||
    state: IUserState,
 | 
			
		||||
    authToken: string
 | 
			
		||||
  ) {
 | 
			
		||||
    state.authToken = authToken
 | 
			
		||||
  },
 | 
			
		||||
  [USER_STORE.MUTATIONS.UPDATE_AUTH_USER_PROFILE](
 | 
			
		||||
    state: IUserState,
 | 
			
		||||
    authUserProfile: IAuthUserProfile
 | 
			
		||||
  ) {
 | 
			
		||||
    state.authUserProfile = authUserProfile
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
import { IAuthUserProfile, IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
 | 
			
		||||
export const userState: IUserState = {
 | 
			
		||||
  authToken: null,
 | 
			
		||||
  authUserProfile: <IAuthUserProfile>{},
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								fittrackee_client/src/store/modules/user/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								fittrackee_client/src/store/modules/user/types.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import { USER_STORE } from '@/store/constants'
 | 
			
		||||
import { IUserState } from '@/store/modules/user/interfaces'
 | 
			
		||||
 | 
			
		||||
export type TUserMutations<S = IUserState> = {
 | 
			
		||||
  [USER_STORE.MUTATIONS.UPDATE_AUTH_TOKEN](state: S, authToken: string): void
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								fittrackee_client/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								fittrackee_client/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
export const getApiUrl = (): string => {
 | 
			
		||||
  return process.env.NODE_ENV === 'production'
 | 
			
		||||
    ? '/api'
 | 
			
		||||
    : 'http://localhost:5000/api'
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user