Client - init login and getting user profile
This commit is contained in:
parent
4c56d75752
commit
cd418c9be2
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'"
|
v-if="action === 'register'"
|
||||||
id="username"
|
id="username"
|
||||||
required
|
required
|
||||||
v-model="user.username"
|
v-model="formData.username"
|
||||||
:placeholder="t('user.REGISTER')"
|
:placeholder="t('user.REGISTER')"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id="email"
|
id="email"
|
||||||
required
|
required
|
||||||
type="email"
|
type="email"
|
||||||
v-model="user.email"
|
v-model="formData.email"
|
||||||
:placeholder="t('user.EMAIL')"
|
:placeholder="t('user.EMAIL')"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id="password"
|
id="password"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
v-model="user.password"
|
v-model="formData.password"
|
||||||
:placeholder="t('user.PASSWORD')"
|
:placeholder="t('user.PASSWORD')"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
@ -29,7 +29,7 @@
|
|||||||
id="confirm-password"
|
id="confirm-password"
|
||||||
type="password"
|
type="password"
|
||||||
required
|
required
|
||||||
v-model="user.confirmPassword"
|
v-model="formData.confirmPassword"
|
||||||
:placeholder="t('user.PASSWORD-CONFIRM')"
|
:placeholder="t('user.PASSWORD-CONFIRM')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -45,6 +45,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, reactive, ref } from 'vue'
|
import { defineComponent, reactive, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { IFormData } from '@/interfaces.ts'
|
||||||
|
import { USER_STORE } from '@/store/constants'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'UserForm',
|
name: 'UserForm',
|
||||||
@ -56,21 +59,25 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const user = reactive({
|
const formData: IFormData = reactive({
|
||||||
username: '',
|
username: '',
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
confirmPassword: '',
|
confirmPassword: '',
|
||||||
})
|
})
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
function onSubmit(action: string) {
|
const store = useStore()
|
||||||
console.log(action, user)
|
function onSubmit(actionType: string) {
|
||||||
|
return store.dispatch(USER_STORE.ACTIONS.LOGIN_OR_REGISTER, {
|
||||||
|
actionType,
|
||||||
|
formData,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
errorMessage: ref(null),
|
errorMessage: ref(null),
|
||||||
t,
|
t,
|
||||||
user,
|
formData,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,3 +2,10 @@ export interface IDropdownOption {
|
|||||||
value: string | number
|
value: string | number
|
||||||
label: string
|
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 { 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 = {
|
export const ROOT_STORE = {
|
||||||
MUTATIONS: RootMutations,
|
MUTATIONS: RootMutations,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const USER_STORE = {
|
export const USER_STORE = {
|
||||||
|
ACTIONS: UserActions,
|
||||||
GETTERS: UserGetters,
|
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 {
|
export enum UserGetters {
|
||||||
IS_AUTHENTICATED = 'IS_AUTHENTICATED',
|
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'
|
import { IUserGetters, IUserState } from '@/store/modules/user/interfaces'
|
||||||
|
|
||||||
export const getters: GetterTree<IUserState, IRootState> & IUserGetters = {
|
export const getters: GetterTree<IUserState, IRootState> & IUserGetters = {
|
||||||
|
[USER_STORE.GETTERS.AUTH_TOKEN]: (state: IUserState) => {
|
||||||
|
return state.authToken
|
||||||
|
},
|
||||||
[USER_STORE.GETTERS.IS_AUTHENTICATED]: (state: IUserState) => {
|
[USER_STORE.GETTERS.IS_AUTHENTICATED]: (state: IUserState) => {
|
||||||
return state.authToken !== null
|
return state.authToken !== null
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { Module } from 'vuex'
|
import { Module } from 'vuex'
|
||||||
import { IRootState } from '@/store/modules/root/interfaces'
|
import { IRootState } from '@/store/modules/root/interfaces'
|
||||||
|
import { actions } from '@/store/modules/user/actions'
|
||||||
import { getters } from '@/store/modules/user/getters'
|
import { getters } from '@/store/modules/user/getters'
|
||||||
import { IUserState } from '@/store/modules/user/interfaces'
|
import { IUserState } from '@/store/modules/user/interfaces'
|
||||||
import { userState } from '@/store/modules/user/state.ts'
|
import { userState } from '@/store/modules/user/state.ts'
|
||||||
|
import { mutations } from '@/store/modules/user/mutations'
|
||||||
|
|
||||||
const user: Module<IUserState, IRootState> = {
|
const user: Module<IUserState, IRootState> = {
|
||||||
state: userState,
|
state: userState,
|
||||||
|
actions,
|
||||||
getters,
|
getters,
|
||||||
|
mutations,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default user
|
export default user
|
||||||
|
@ -1,9 +1,49 @@
|
|||||||
|
import { ActionContext } from 'vuex'
|
||||||
|
import { IFormData } from '@/interfaces'
|
||||||
import { USER_STORE } from '@/store/constants'
|
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 {
|
export interface IUserState {
|
||||||
authToken: string | null
|
authToken: string | null
|
||||||
|
authUserProfile: IAuthUserProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IUserGetters {
|
export interface IUserGetters {
|
||||||
|
[USER_STORE.GETTERS.AUTH_TOKEN](state: IUserState): string
|
||||||
[USER_STORE.GETTERS.IS_AUTHENTICATED](state: IUserState): boolean
|
[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 = {
|
export const userState: IUserState = {
|
||||||
authToken: null,
|
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'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user