add loading to some page

master
sajjad 3 years ago
parent 20ba746f93
commit a9f3257155

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

@ -0,0 +1,87 @@
<template>
<div :class="{'isLoading':loading}">
<template v-if="loading">
<slot name="loading">
<we-loading />
</slot>
</template>
<template v-if="!loading">
<slot></slot>
</template>
<template v-if="!loading && items.length">
<slot
name="items"
:item="item"
v-for="(item, i) in items"
:index="i"
:itemNumber="pagination ? pagination.pageStart + i : i + 1"
/>
</template>
<template v-if="!items.length">
<slot name="items-container"> </slot>
</template>
<template v-if="!loading && !isFiltered && !items.length">
<slot name="no-items">
<no-items
src="/images/Global/Animated/Product.gif"
title=""
themeColor="product"
:hasBtn="false"
/>
</slot>
</template>
<template v-if="!loading && isFiltered && !items.length">
<slot name="no-results">
<no-items
src="/images/Global/Animated/NoResult.gif"
textFa=" no items found! "
textEn=" Sorry, No Items Found! "
themeColor="product"
:hasBtn="false"
/>
</slot>
</template>
<pagination
v-if="items.length && !loading && pagination"
:pagination="pagination"
@pagination="$emit('pagination', $event)"
></pagination>
</div>
</template>
<script>
import Pagination from "@/components/Global/Pagination/Pagination.vue";
export default {
name: "data-iterator",
components: {
Pagination,
},
props: {
pagination: {
type: Object,
default: null,
},
items: {
type: Array,
default: () => [],
},
loading: {
type: Boolean,
default: false,
},
isFiltered: {
type: Boolean,
default: false,
},
},
};
</script>
<style scoped>
.isLoading {
display: flex;
justify-content: center;
align-items: center;
height : 100vh;
}
</style>

@ -87,10 +87,10 @@ export default {
},
thumbnail: {
get() {
if(this.url) {
if (this.url) {
return this.url;
} else {
return DefaultImage
return DefaultImage;
}
},
set(value) {
@ -127,6 +127,7 @@ export default {
border: 1px solid #afafaf;
border-radius: 5px;
background-color: white !important;
height: 300px;
}
.upload-example-cropper.red {
border: 1px solid red;

@ -0,0 +1,45 @@
<template>
<div class="loading-container">
<div class="loading">
<img :src="src" alt="loading" />
</div>
<div class="loading__title">{{ title }}</div>
<div class="loading__message">{{ message }}</div>
</div>
</template>
<script>
import Idefault from '@/assets/Misterious_mist.gif'
export default {
props: {
src: {
default: Idefault,
},
title: {
default: " LOADING... ",
},
message: {
default: " thank you for your patience ",
},
},
};
</script>
<style scoped>
.loading-container {
text-align: center;
}
.loading__title,
.loading__message {
font-family: "Barlow-EL", sans-serif;
}
.loading__title {
letter-spacing: 2px;
text-transform: uppercase;
font-size: 30px;
font-weight: 700;
}
.loading__message {
font-size: 15px;
}
</style>

@ -0,0 +1,62 @@
<template>
<div class="we-no-result">
<!-- <img class="Thumbnail" :src="$_getPath(src, true)" />
<div class="Fa">{{ textFa }}</div>
<div class="En">{{ textEn }}</div>
<router-link v-if="hasBtn" :to="{ name: routeName }" class="flex lg6 xs12">
<v-btn
class="ma-2"
outlined
@click.native="emitClickEvent"
:color="$_color(themeColor)"
>
<v-icon left>WMi-{{ btnIcon }}</v-icon> {{ btnText }}
</v-btn>
</router-link> -->
<div class="text-center">There are no items to display</div>
</div>
</template>
<script>
export default {
props: {
src: { default: "/images/Global/Animated/no-result-purple.gif" },
textFa: { default: " آیتمی برای نمایش وجود ندارد " },
textEn: { default: " NO ITEMS AVAILABLE " },
themeColor: { default: "black" },
btnText: { default: "ثبت اولین آیتم" },
btnIcon: { default: "cancel" },
modal: { default: null },
routeName: { default: null },
hasBtn: { default: true },
},
methods: {
emitClickEvent(e) {
this.modal ? this.$_openModal(this.modal) : null;
this.$emit("button-clicked", e);
},
},
};
</script>
<style lang="scss" scoped>
.we-no-result {
text-align: center;
padding: 10px;
width: 100%;
}
.we-no-result img {
width: 300px;
height: 300px;
border-radius: 150px;
}
.we-no-result .Fa {
font-size: 18px;
}
.we-no-result .En {
direction: ltr;
font-size: 12px;
letter-spacing: 5px;
text-transform: uppercase;
}
</style>

@ -1,7 +1,7 @@
<template>
<div class="h-100">
<main-back height="100%">
<div class="py-12 px-10">
<div class="py-12 px-10 loading__container">
<div>
<SectionTitle
backText="home page"
@ -11,7 +11,8 @@
subTitle="let us know you better, it comes handy."
/>
</div>
<v-form @submit.prevent="submit">
<loading v-if="getProfileLoading" class="loading-data" />
<v-form @submit.prevent="submit" :class="{ 'loading-form': getProfileLoading }">
<v-row class="mt-4">
<v-col cols="3">
<div class="pb-14 h-100">
@ -150,12 +151,14 @@
icon="WMi-cancel"
class="px-0"
height="19"
lg
/></router-link>
<RectangleButton
text="SAVE THE INFO"
class="custom-btn save-btn"
height="25"
height="29"
type="submit"
lg
/>
</div>
</div>
@ -187,7 +190,7 @@ export default {
},
}),
computed: {
...mapGetters("profile", ["getProfile"]),
...mapGetters("profile", ["getProfile", "getProfileLoading"]),
...mapGetters("countries", ["getCountries"]),
},
methods: {
@ -218,4 +221,20 @@ export default {
padding-right: 100px !important;
padding-left: 100px !important;
}
.loading__container {
position: relative;
}
.loading-data {
position: absolute;
top: 50%;
left: 50%;
z-index: 9999;
transform: translate(-50%, -50%);
}
.loading-form {
filter: blur(5px);
}
</style>

@ -23,21 +23,28 @@
/>
</div>
</div>
<v-row v-for="(series, i) in getProgramSeries" :key="i" class="mt-4">
<v-col cols="12"
><SeriesItem
:seriesNumber="i + 1"
:series="series"
:programId="programId"
/></v-col>
</v-row>
<data-iterator
:is-filtered="isFilteredProgramSeries"
:loading="getProgramSeriesLoading"
:items="getProgramSeries"
class="row pb-10 mt-5"
>
<template #loading>
<loading />
</template>
<template #no-items>
<no-items />
</template>
<template #items="{ item, itemNumber }">
<v-col cols="12">
<SeriesItem :seriesNumber="itemNumber" :series="item" :programId="programId" />
</v-col>
</template>
</data-iterator>
</div>
</main-back>
<div class="text-center">
<AddSeriesModal
:programId="programId"
v-if="isModal('modal_add_series')"
/>
<AddSeriesModal :programId="programId" v-if="isModal('modal_add_series')" />
</div>
</div>
</template>
@ -54,7 +61,11 @@ export default {
AddSeriesModal,
},
computed: {
...mapGetters("programSeries", ["getProgramSeries"]),
...mapGetters("programSeries", [
"getProgramSeries",
"isFilteredProgramSeries",
"getProgramSeriesLoading",
]),
...mapGetters("modal", ["isModal"]),
programId() {

@ -22,10 +22,7 @@
:text="getFilterCount ? getFilterCount : '0'"
@click.native="$_openModal('filters')"
/>
<router-link
:to="{ name: 'addProgram' }"
class="text-decoration-none"
>
<router-link :to="{ name: 'addProgram' }" class="text-decoration-none">
<RectangleButton
icon="WMi-plus"
size="xx-large"
@ -36,22 +33,26 @@
</router-link>
</div>
</div>
<v-row class="mt-4">
<v-col
cols="12"
sm="4"
v-for="program in getPrograms"
:key="program.id"
class="mb-3"
><ProgramItem :program="program"
/></v-col>
</v-row>
</div>
<div class="text-center mt-40 mb-5">
<pagination
:pagination="getPaginationProgram"
<data-iterator
:is-filtered="isFilteredPrograms"
:loading="getProgramsLoading"
:items="getPrograms"
@pagination="changePagination"
/>
:pagination="getPaginationProgram"
class="row pb-10 mt-5"
>
<template #loading>
<loading />
</template>
<template #no-items>
<no-items />
</template>
<template #items="{ item }">
<v-col cols="12" sm="4" class="mb-3">
<ProgramItem :program="item" />
</v-col>
</template>
</data-iterator>
</div>
</main-back>
<div class="text-center">
@ -79,6 +80,8 @@ export default {
"getPrograms",
"getPaginationProgram",
"getFilterCount",
"isFilteredPrograms",
"getProgramsLoading",
]),
...mapGetters("modal", ["isModal"]),
},
@ -92,9 +95,7 @@ export default {
}
},
async load() {
this.role === "admin"
? await this.loadPrograms()
: await this.loadMyPrograms();
this.role === "admin" ? await this.loadPrograms() : await this.loadMyPrograms();
},
},
created() {

@ -8,7 +8,7 @@
backText="home page"
link="dashboard"
icon="WMi-left-open"
:title="role==='admin' ? 'users' : 'my trainees'"
:title="role === 'admin' ? 'users' : 'my trainees'"
subTitle="let us know you better, it comes handy."
/>
</div>
@ -24,17 +24,30 @@
/>
</div>
</div>
<v-row v-for="(user, i) in getUsers" :key="i" class="mt-4">
<v-col cols="12"><UserItem :user="user" @userId="userId" /></v-col>
</v-row>
</div>
<div class="text-center mt-40 mb-5">
<pagination
:pagination="getPaginationUser"
<data-iterator
:is-filtered="isFilteredUser"
:loading="getUsersLoading"
:items="getUsers"
@pagination="changePagination"
/>
:pagination="getPaginationUser"
class="row pb-10 mt-5"
>
<template #loading>
<loading />
</template>
<template #no-items>
<no-items />
</template>
<template #items="{ item }">
<v-col cols="12" class="pb-0">
<UserItem :user="item" @userId="userId" />
</v-col>
</template>
</data-iterator>
</div>
<!-- <div class="text-center mt-40 mb-5">
<pagination :pagination="getPaginationUser" @pagination="changePagination" />
</div> -->
</main-back>
<div class="text-center">
<ChangeRoleModal
@ -74,6 +87,8 @@ export default {
"getPaginationUser",
"getRoles",
"getFilterCount",
"isFilteredUser",
"getUsersLoading",
]),
...mapGetters("modal", ["isModal"]),
@ -89,9 +104,7 @@ export default {
}
},
async load() {
this.role === "admin"
? await this.loadUsers()
: await this.loadTrainerTrainee();
this.role === "admin" ? await this.loadUsers() : await this.loadTrainerTrainee();
},
userId(id) {
this.id = id;

@ -24,16 +24,23 @@
/>
</div>
</div>
<v-row class="mt-4">
<v-col
cols="12"
sm="6"
class="mb-3"
v-for="(seriesWorkout, i) in getWorkouts"
:key="i"
><WorkoutsSeriesItem :seriesWorkout="seriesWorkout" :seriesId="seriesId"
/></v-col>
</v-row>
<data-iterator
:loading="getProgramSeriesWorkoutsLoading"
:items="getWorkouts"
class="row pb-10 mt-5"
>
<template #loading>
<loading />
</template>
<template #no-items>
<no-items />
</template>
<template #items="{ item }">
<v-col cols="12" sm="6" class="mb-3">
<WorkoutsSeriesItem :seriesWorkout="item" :seriesId="seriesId" />
</v-col>
</template>
</data-iterator>
</div>
</main-back>
<div class="text-center">
@ -54,7 +61,7 @@ export default {
AddWorkoutModal,
},
computed: {
...mapGetters("workoutToSeries", ["getWorkouts"]),
...mapGetters("workoutToSeries", ["getWorkouts", "getProgramSeriesWorkoutsLoading"]),
...mapGetters("modal", ["isModal"]),
seriesId() {
return this.$route.params.seriesId;

@ -1,9 +1,17 @@
import ProfileRepository from "@/abstraction/repository/profileRepository"
export default {
async loadProfile({ commit },) {
try {
commit("SET_LOADING_PROFILE", true);
let repository = new ProfileRepository();
let resource = await repository.show();
commit('SET_PROFILE', resource)
} catch (e) {
return e;
} finally {
commit("SET_LOADING_PROFILE", false);
}
},
async updateProfile({ commit }, data) {
let repository = new ProfileRepository();

@ -1,3 +1,4 @@
export default {
getProfile: state => state.profile
getProfile: state => state.profile,
getProfileLoading: state => state.loading,
}

@ -1,9 +1,15 @@
import Vue from 'vue';
export default {
// SET
SET_PROFILE(state, payload) {
Vue.set(state, 'profile', payload)
},
// UPDATE
UPDATE_PROFILE(state, payload) {
Vue.set(state, 'profile', payload)
},
// LOADING
SET_LOADING_PROFILE(state, status) {
Vue.set(state, 'loading', status);
}
}

@ -1,3 +1,4 @@
export default {
profile: {}
profile: {},
loading: false,
}

@ -1,9 +1,17 @@
import ProgramSeriesRepository from "@/abstraction/repository/programSeriesRepository";
export default {
async loadProgramSeries({ commit }, courseId) {
try {
commit("SET_LOADING_PROGRAM_SERIES", true);
let repository = new ProgramSeriesRepository();
const resource = await repository.index(courseId);
commit("SET_PROGRAM_SERIES", resource.data);
} catch (e) {
return e;
} finally {
commit("SET_LOADING_PROGRAM_SERIES", false);
}
},
// async loadProgramSeries({ commit }, courseId) {
// let repository = new ProgramSeriesRepository();

@ -1,4 +1,6 @@
export default {
getProgramSeries: state => state.programSeries,
getCurrentSeriesId: state => state.currentSeriesId
getCurrentSeriesId: state => state.currentSeriesId,
isFilteredProgramSeries: state => state.isFiltered,
getProgramSeriesLoading: state => state.loading,
};

@ -1,5 +1,6 @@
import Vue from "vue";
export default {
// SET
SET_PROGRAM_SERIES(state, payload) {
Vue.set(state, "programSeries", payload);
},
@ -9,12 +10,14 @@ export default {
SET_CURRENT_SERIES_ID(state, payload) {
Vue.set(state, "currentSeriesId", payload);
},
// ADD
ADD_SERIES_TO_PROGRAM(state, payload) {
state.programSeries.push(payload);
},
// ADD_SERIES_TO_PROGRAM(state, payload) {
// state.programSeries.series.push(payload);
// },
// DELETE
DELETE_SERIES_FROM_PROGRAM(state, payload) {
const index = state.programSeries.findIndex((x) => x.id === payload);
Vue.delete(state.programSeries, index)
@ -23,4 +26,8 @@ export default {
// const index = state.programSeries.series.findIndex((x) => x.id === payload);
// Vue.delete(state.programSeries.series, index)
// }
// LOADING
SET_LOADING_PROGRAM_SERIES(state, status) {
Vue.set(state, 'loading', status);
}
};

@ -2,4 +2,6 @@ export default {
programSeries: [],
// programSeries: {},
currentSeriesId: null,
isFiltered: false,
loading: false,
};

@ -5,6 +5,7 @@ let role = UserStorage.getRole() ? UserStorage.getRole() : null;
export default {
async loadPrograms({ state, commit }) {
try {
commit("SET_LOADING_PROGRAMS", true);
let data = { pagination: state.pagination, filters: state.filters };
let repository = new ProgramRepository();
const resource = await repository.index(data);
@ -12,9 +13,10 @@ export default {
commit("SET_FILTER_COUNT", Object.keys(filterCount).length);
commit("SET_PROGRAMS", resource.data);
commit("SET_PAGINATION", resource.pagination);
}
catch (e) {
} catch (e) {
return e;
} finally {
commit("SET_LOADING_PROGRAMS", false);
}
},
async loadMyPrograms({ state, commit }) {

@ -3,5 +3,7 @@ export default {
getProgram: state => state.program,
getPaginationProgram: state => state.pagination,
getFilters: state => state.filters,
getFilterCount: state => state.filterCount
getFilterCount: state => state.filterCount,
isFilteredPrograms: state => state.isFiltered,
getProgramsLoading: state => state.loading,
};

@ -34,6 +34,10 @@ export default {
Vue.set(state.pagination, 'itemsLength', state.pagination.itemsLength - 1);
Vue.set(state.pagination, 'pageStop', state.pagination.pageStop - 1);
},
// LOADING
SET_LOADING_PROGRAMS(state, status) {
Vue.set(state, 'loading', status);
},
// OTHER
VERIFY_PROGRAM(state, payload) {
const index = state.programs.find(x => x.id === payload);

@ -5,5 +5,7 @@ export default {
itemsPerPage: 12
},
filters: {},
filterCount: null
filterCount: null,
isFiltered: false,
loading: false,
};

@ -3,6 +3,8 @@ import RoleRepository from "@/abstraction/repository/roleRepository";
import { setQuery } from "@/abstraction/resources/userResource";
export default {
async loadUsers({ state, commit }) {
try {
commit("SET_LOADING_USERS", true);
let data = { pagination: state.pagination, filters: state.filters }
let repository = new UserRepository();
const resource = await repository.indexUsers(data);
@ -10,6 +12,11 @@ export default {
commit("SET_FILTER_COUNT", Object.keys(filterCount).length);
commit("SET_USERS", resource.data);
commit("SET_PAGINATION", resource.pagination);
} catch (e) {
return e;
} finally {
commit("SET_LOADING_USERS", false);
}
},
async loadTrainerTrainee({ state, commit }) {
let data = { pagination: state.pagination }

@ -3,5 +3,7 @@ export default {
getRoles: state => state.roles,
getPaginationUser: state => state.pagination,
getFilters: state => state.filters,
getFilterCount: state => state.filterCount
getFilterCount: state => state.filterCount,
isFilteredUser: state => state.isFiltered,
getUsersLoading: state => state.loading,
};

@ -30,4 +30,8 @@ export default {
Vue.set(state.pagination, 'itemsLength', state.pagination.itemsLength - 1);
Vue.set(state.pagination, 'pageStop', state.pagination.pageStop - 1);
},
// LOADING
SET_LOADING_USERS(state, status) {
Vue.set(state, 'loading', status);
}
};

@ -5,5 +5,7 @@ export default {
itemsPerPage: 12
},
filters: {},
filterCount: null
filterCount: null,
isFiltered: false,
loading: false,
};

@ -1,9 +1,17 @@
import WorkoutToSeriesRepository from "../../../abstraction/repository/workoutToSeriesRepository";
import WorkoutToSeriesRepository from "@/abstraction/repository/workoutToSeriesRepository";
let repository = new WorkoutToSeriesRepository();
export default {
async loadProgramSeriesWorkouts({ commit }, data) {
try {
commit("SET_LOADING_PROGRAM_SERIES_WORKOUTS", true);
const resource = await repository.index(data);
commit("SET_PROGRAM_SERIES_WORKOUTS", resource.data);
} catch (e) {
return e;
} finally {
commit("SET_LOADING_PROGRAM_SERIES_WORKOUTS", false);
}
},
async loadWorkoutsToSeries({ state, commit }) {
try {

@ -1,5 +1,6 @@
export default {
getWorkoutsToSeries: state => state.workoutsToSeries,
getWorkoutToSeries: state => state.workoutToSeries,
getWorkouts: state => state.workouts
getWorkouts: state => state.workouts,
getProgramSeriesWorkoutsLoading: state => state.loading,
}

@ -1,5 +1,6 @@
import Vue from "vue";
export default {
// SET
SET_PROGRAM_SERIES_WORKOUTS(state, payload) {
Vue.set(state, "workouts", payload)
},
@ -12,8 +13,13 @@ export default {
SET_FILTER_WORKOUTS_TO_SERIES(state, payload) {
Vue.set(state, "filters", payload);
},
// DELETE
DELETE_WORKOUT_FROM_SERIES(state, workoutId) {
const index = state.workouts.findIndex((x) => x.id === workoutId);
Vue.delete(state.workouts, index)
},
// LOADING
SET_LOADING_PROGRAM_SERIES_WORKOUTS(state, status) {
Vue.set(state, 'loading', status);
}
};

@ -2,5 +2,6 @@ export default {
workouts: [],
workoutsToSeries: [],
workoutToSeries: {},
filters: {}
filters: {},
loading: false,
};

@ -13,7 +13,10 @@ import Pagination from "../components/Global/Pagination/Pagination.vue";
import Chip from "../components/Global/Chip/Chip.vue";
import VeeTextField from "@/components/Global/VeeValidate/TextField";
import VeeForm from "@/components/Global/VeeValidate/Form";
import SideBar from '../components/Global/Section/SideBar'
import SideBar from '../components/Global/Section/SideBar';
import Loading from "../components/Global/Misc/Loading";
import NoItems from "../components/Global/Misc/NoItems";
import DataIterator from "../components/Global/Input/DataIterator.vue";
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
@ -31,5 +34,8 @@ Vue.component('basic-modal', BasicModal);
Vue.component('pagination', Pagination);
Vue.component('Chip', Chip);
Vue.component('SideBar', SideBar);
Vue.component('data-iterator', DataIterator);
Vue.component('loading', Loading);
Vue.component('no-items', NoItems);
Vue.component("vee-text-field", VeeTextField);
Vue.component("vee-form", VeeForm);
Loading…
Cancel
Save