@@ -16,7 +16,7 @@
import { defineComponent } from 'vue'
export default defineComponent({
- name: 'UserStatCard',
+ name: 'StatCard',
props: {
icon: {
type: String,
@@ -36,7 +36,7 @@
diff --git a/fittrackee_client/src/components/Workout/WorkoutEdition.vue b/fittrackee_client/src/components/Workout/WorkoutEdition.vue
index fb094656..9e6c6c1a 100644
--- a/fittrackee_client/src/components/Workout/WorkoutEdition.vue
+++ b/fittrackee_client/src/components/Workout/WorkoutEdition.vue
@@ -1,6 +1,7 @@
@@ -416,12 +417,6 @@
@import '~@/scss/base';
#workout-edition {
- margin: 100px auto;
- width: 700px;
- @media screen and (max-width: $medium-limit) {
- width: 100%;
- margin: 0 auto 50px auto;
- }
@media screen and (max-width: $small-limit) {
&.center-form {
margin: 50px auto;
diff --git a/fittrackee_client/src/locales/en/administration.json b/fittrackee_client/src/locales/en/administration.json
index c19cfcab..193762a7 100644
--- a/fittrackee_client/src/locales/en/administration.json
+++ b/fittrackee_client/src/locales/en/administration.json
@@ -1,3 +1,11 @@
{
- "ADMIN": "Admin"
+ "ADMIN_RIGHTS_DELETE_USER_ACCOUNT": "Add/remove admin rights, delete user account.",
+ "ADMIN": "Admin",
+ "ADMINISTRATION": "Administration",
+ "APPLICATION": "Application",
+ "ENABLE_DISABLE_SPORTS": "Enable/disable sports.",
+ "REGISTRATION_DISABLED": "Registration is currently disabled.",
+ "REGISTRATION_ENABLED": "Registration is currently enabled.",
+ "UPDATE_APPLICATION_DESCRIPTION": "Update application configuration (maximum number of registered users, maximum files size).",
+ "USER": "user | users"
}
diff --git a/fittrackee_client/src/locales/en/en.ts b/fittrackee_client/src/locales/en/en.ts
index 9f0eb3c5..fc7c0860 100644
--- a/fittrackee_client/src/locales/en/en.ts
+++ b/fittrackee_client/src/locales/en/en.ts
@@ -10,7 +10,7 @@ import UserTranslations from './user.json'
import WorkoutsTranslations from './workouts.json'
export default {
- administration: AdministrationTranslations,
+ admin: AdministrationTranslations,
api: ApiTranslations,
buttons: ButtonsTranslations,
common: CommonTranslations,
diff --git a/fittrackee_client/src/locales/fr/administration.json b/fittrackee_client/src/locales/fr/administration.json
index c19cfcab..7cc7a5c3 100644
--- a/fittrackee_client/src/locales/fr/administration.json
+++ b/fittrackee_client/src/locales/fr/administration.json
@@ -1,3 +1,11 @@
{
- "ADMIN": "Admin"
+ "ADMIN_RIGHTS_DELETE_USER_ACCOUNT": "Ajouter/retirer des droits d'adminsitration, supprimer des comptes utilisateurs.",
+ "ADMIN": "Admin",
+ "ADMINISTRATION": "Administration",
+ "APPLICATION": "Application",
+ "ENABLE_DISABLE_SPORTS": "Activer/désactiver des sports.",
+ "REGISTRATION_DISABLED": "Les inscriptions sont actuellement désactivées.",
+ "REGISTRATION_ENABLED": "Les inscriptions sont actuellement activées.",
+ "UPDATE_APPLICATION_DESCRIPTION": "Configurer l'application (nombre maximum d'utilisateurs inscrits, taille maximale des fichers).",
+ "USER": "utilisateur | utilisateurs"
}
diff --git a/fittrackee_client/src/locales/fr/fr.ts b/fittrackee_client/src/locales/fr/fr.ts
index 9f0eb3c5..fc7c0860 100644
--- a/fittrackee_client/src/locales/fr/fr.ts
+++ b/fittrackee_client/src/locales/fr/fr.ts
@@ -10,7 +10,7 @@ import UserTranslations from './user.json'
import WorkoutsTranslations from './workouts.json'
export default {
- administration: AdministrationTranslations,
+ admin: AdministrationTranslations,
api: ApiTranslations,
buttons: ButtonsTranslations,
common: CommonTranslations,
diff --git a/fittrackee_client/src/router/index.ts b/fittrackee_client/src/router/index.ts
index 79cfb7b5..b2b12f0e 100644
--- a/fittrackee_client/src/router/index.ts
+++ b/fittrackee_client/src/router/index.ts
@@ -162,6 +162,12 @@ const routes: Array = [
/* webpackChunkName: 'workouts' */ '@/views/workouts/AddWorkout.vue'
),
},
+ {
+ path: '/admin',
+ name: 'Administration',
+ component: () =>
+ import(/* webpackChunkName: 'admin' */ '@/views/AdminView.vue'),
+ },
{
path: '/:pathMatch(.*)*',
name: 'not-found',
diff --git a/fittrackee_client/src/scss/base.scss b/fittrackee_client/src/scss/base.scss
index 56287936..d6b4da6f 100644
--- a/fittrackee_client/src/scss/base.scss
+++ b/fittrackee_client/src/scss/base.scss
@@ -195,30 +195,31 @@ button {
.description-list {
dl {
- overflow: hidden;
+ display: flex;
+ flex-direction: column;
width: 100%;
- padding: 0 $default-padding;
dt {
font-weight: bold;
- float: left;
- width: 25%;
}
dd {
- float: left;
+ margin-bottom: $default-margin;
}
}
- @media screen and (max-width: $x-small-limit) {
- dl {
- overflow: auto;
- width: initial;
- dt {
- font-weight: bold;
- float: none;
- width: initial;
- }
- dd {
- float: none;
- }
+}
+
+.center-card {
+ margin: 0 auto;
+ width: 700px;
+ &.with-margin {
+ margin-top: 100px;
+ }
+
+ @media screen and (max-width: $medium-limit) {
+ width: 100%;
+ margin: 0 auto 50px auto;
+
+ &.with-margin {
+ margin-top: 0;
}
}
-}
\ No newline at end of file
+}
diff --git a/fittrackee_client/src/store/modules/root/actions.ts b/fittrackee_client/src/store/modules/root/actions.ts
index 5e4bccfb..4f9b5f27 100644
--- a/fittrackee_client/src/store/modules/root/actions.ts
+++ b/fittrackee_client/src/store/modules/root/actions.ts
@@ -28,4 +28,22 @@ export const actions: ActionTree & IRootActions = {
context.commit(ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_LOADING, false)
)
},
+ [ROOT_STORE.ACTIONS.GET_APPLICATION_STATS](
+ context: ActionContext
+ ): void {
+ context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
+ authApi
+ .get('stats/all')
+ .then((res) => {
+ if (res.data.status === 'success') {
+ context.commit(
+ ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_STATS,
+ res.data.data
+ )
+ } else {
+ handleError(context, null)
+ }
+ })
+ .catch((error) => handleError(context, error))
+ },
}
diff --git a/fittrackee_client/src/store/modules/root/enums.ts b/fittrackee_client/src/store/modules/root/enums.ts
index c12a2dfd..944ca3db 100644
--- a/fittrackee_client/src/store/modules/root/enums.ts
+++ b/fittrackee_client/src/store/modules/root/enums.ts
@@ -1,10 +1,12 @@
export enum RootActions {
GET_APPLICATION_CONFIG = 'GET_APPLICATION_CONFIG',
+ GET_APPLICATION_STATS = 'GET_APPLICATION_STATS',
}
export enum RootGetters {
APP_CONFIG = 'APP_CONFIG',
APP_LOADING = 'APP_LOADING',
+ APP_STATS = 'APP_STATS',
ERROR_MESSAGES = 'ERROR_MESSAGES',
LANGUAGE = 'LANGUAGE',
LOCALE = 'LOCALE', // date-fns
@@ -15,5 +17,6 @@ export enum RootMutations {
SET_ERROR_MESSAGES = 'SET_ERROR_MESSAGES',
UPDATE_APPLICATION_CONFIG = 'UPDATE_APPLICATION_CONFIG',
UPDATE_APPLICATION_LOADING = 'UPDATE_APPLICATION_LOADING',
+ UPDATE_APPLICATION_STATS = 'UPDATE_APPLICATION_STATS',
UPDATE_LANG = 'UPDATE_LANG',
}
diff --git a/fittrackee_client/src/store/modules/root/getters.ts b/fittrackee_client/src/store/modules/root/getters.ts
index 93668052..f1e3e0ff 100644
--- a/fittrackee_client/src/store/modules/root/getters.ts
+++ b/fittrackee_client/src/store/modules/root/getters.ts
@@ -10,6 +10,9 @@ export const getters: GetterTree & IRootGetters = {
[ROOT_STORE.GETTERS.APP_LOADING]: (state: IRootState) => {
return state.appLoading
},
+ [ROOT_STORE.GETTERS.APP_STATS]: (state: IRootState) => {
+ return state.application.statistics
+ },
[ROOT_STORE.GETTERS.ERROR_MESSAGES]: (state: IRootState) => {
return state.errorMessages
},
diff --git a/fittrackee_client/src/store/modules/root/mutations.ts b/fittrackee_client/src/store/modules/root/mutations.ts
index 5b122188..228f398f 100644
--- a/fittrackee_client/src/store/modules/root/mutations.ts
+++ b/fittrackee_client/src/store/modules/root/mutations.ts
@@ -2,7 +2,7 @@ import { MutationTree } from 'vuex'
import { ROOT_STORE } from '@/store/constants'
import { IRootState, TRootMutations } from '@/store/modules/root/types'
-import { IAppConfig } from '@/types/application'
+import { IAppConfig, IAppStatistics } from '@/types/application'
import { localeFromLanguage } from '@/utils/locales'
export const mutations: MutationTree & TRootMutations = {
@@ -27,6 +27,12 @@ export const mutations: MutationTree & TRootMutations = {
) {
state.appLoading = loading
},
+ [ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_STATS](
+ state: IRootState,
+ statistics: IAppStatistics
+ ) {
+ state.application.statistics = statistics
+ },
[ROOT_STORE.MUTATIONS.UPDATE_LANG](state: IRootState, language: string) {
state.language = language
state.locale = localeFromLanguage[language]
diff --git a/fittrackee_client/src/store/modules/root/types.ts b/fittrackee_client/src/store/modules/root/types.ts
index 8e6bcc17..abd43ebd 100644
--- a/fittrackee_client/src/store/modules/root/types.ts
+++ b/fittrackee_client/src/store/modules/root/types.ts
@@ -7,7 +7,7 @@ import {
} from 'vuex'
import { ROOT_STORE } from '@/store/constants'
-import { IAppConfig, IApplication } from '@/types/application'
+import { IAppConfig, IApplication, IAppStatistics } from '@/types/application'
export interface IRootState {
root: boolean
@@ -22,6 +22,9 @@ export interface IRootActions {
[ROOT_STORE.ACTIONS.GET_APPLICATION_CONFIG](
context: ActionContext
): void
+ [ROOT_STORE.ACTIONS.GET_APPLICATION_STATS](
+ context: ActionContext
+ ): void
}
export interface IRootGetters {
@@ -29,6 +32,8 @@ export interface IRootGetters {
[ROOT_STORE.GETTERS.APP_LOADING](state: IRootState): boolean
+ [ROOT_STORE.GETTERS.APP_STATS](state: IRootState): IAppStatistics
+
[ROOT_STORE.GETTERS.ERROR_MESSAGES](
state: IRootState
): string | string[] | null
@@ -44,6 +49,18 @@ export type TRootMutations = {
state: S,
errorMessages: string
): void
+ [ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_CONFIG](
+ state: S,
+ config: IAppConfig
+ ): void
+ [ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_LOADING](
+ state: S,
+ loading: boolean
+ ): void
+ [ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_STATS](
+ state: S,
+ statistics: IAppStatistics
+ ): void
[ROOT_STORE.MUTATIONS.UPDATE_LANG](state: S, language: string): void
}
diff --git a/fittrackee_client/src/store/modules/user/enums.ts b/fittrackee_client/src/store/modules/user/enums.ts
index 93076112..c3b3eb69 100644
--- a/fittrackee_client/src/store/modules/user/enums.ts
+++ b/fittrackee_client/src/store/modules/user/enums.ts
@@ -15,6 +15,7 @@ export enum UserActions {
export enum UserGetters {
AUTH_TOKEN = 'AUTH_TOKEN',
AUTH_USER_PROFILE = 'AUTH_USER_PROFILE',
+ IS_ADMIN = 'IS_ADMIN',
IS_AUTHENTICATED = 'IS_AUTHENTICATED',
USER_LOADING = 'USER_LOADING',
}
diff --git a/fittrackee_client/src/store/modules/user/getters.ts b/fittrackee_client/src/store/modules/user/getters.ts
index 3feeb1af..7e6adff1 100644
--- a/fittrackee_client/src/store/modules/user/getters.ts
+++ b/fittrackee_client/src/store/modules/user/getters.ts
@@ -14,6 +14,9 @@ export const getters: GetterTree & IUserGetters = {
[USER_STORE.GETTERS.IS_AUTHENTICATED]: (state: IUserState) => {
return state.authToken !== null
},
+ [USER_STORE.GETTERS.IS_ADMIN]: (state: IUserState) => {
+ return state.authUserProfile && state.authUserProfile.admin
+ },
[USER_STORE.GETTERS.USER_LOADING]: (state: IUserState) => {
return state.loading
},
diff --git a/fittrackee_client/src/store/modules/user/types.ts b/fittrackee_client/src/store/modules/user/types.ts
index 168ead28..6e2090b8 100644
--- a/fittrackee_client/src/store/modules/user/types.ts
+++ b/fittrackee_client/src/store/modules/user/types.ts
@@ -82,6 +82,8 @@ export interface IUserGetters {
[USER_STORE.GETTERS.AUTH_USER_PROFILE](state: IUserState): IAuthUserProfile
+ [USER_STORE.GETTERS.IS_ADMIN](state: IUserState): boolean
+
[USER_STORE.GETTERS.IS_AUTHENTICATED](state: IUserState): boolean
[USER_STORE.GETTERS.USER_LOADING](state: IUserState): boolean
diff --git a/fittrackee_client/src/views/AdminView.vue b/fittrackee_client/src/views/AdminView.vue
new file mode 100644
index 00000000..f7c13698
--- /dev/null
+++ b/fittrackee_client/src/views/AdminView.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+