sajjad_talkhabi 3 years ago
parent b001b7a7d9
commit 6407154954

@ -1,38 +1,16 @@
// import axios from "axios";
// import url from "@/router/url";
// import { getJson, setData } from "../resources/FileResource";
import axios from "axios";
import url from "@/router/url";
import { getJson, setData } from "../resources/FileResource";
// export default class FileRepository {
export default class FileRepository {
// async store(data) {
// console.log('data', data);
// const formData = setData(data);
// let response = await axios.post(url("storeFile"), formData);
// if (response.status === 200) {
// return getJson(response.data.data);
// }
// }
// async destroy(fileId) {
// let response = await axios.delete(url("destroyFile", {file: fileId}));
// if (response.status === 200) {
// return true;
// }
// }
// async verifyImage(fileId) {
// await axios.post(url("verifyImage",{file:fileId}) );
// }
// async unverifyImage(fileId) {
// await axios.post(url("unverifyImage", {file: fileId}));
// }
// async pdfVerify(imageId) {
// await axios.post(url("pdfVerify",{media:imageId}) );
// }
// async pdfUnVerify(imageId) {
// await axios.post(url("pdfUnVerify",{media:imageId}) );
// }
// }
async store(data) {
console.log('data', data);
const formData = setData(data);
console.log(formData);
let response = await axios.post(url("storeFile"), formData);
if (response.status === 200) {
return getJson(response.data.data);
}
}
}

@ -2,6 +2,8 @@ import axios from "axios";
import url from "@/router/url";
import {
getArray,
getJson,
setData
} from "../resources/programResource";
export default class ProgramRepository {
async index() {
@ -12,4 +14,11 @@ export default class ProgramRepository {
return getArray(response.data);
}
}
async store(data) {
let json = setData(data);
let response = await axios.post(url("storeProgram"), json);
if (response.status === 201) {
return getJson(response.data);
}
}
}

@ -1,6 +1,6 @@
import axios from "axios";
import url from "@/router/url";
import { getArray } from "../resources/sportCategoriesResource";
import { getArray, getJson } from "../resources/sportCategoriesResource";
export default class SportCategoriesRepository {
async index() {
let response = await axios.get(url("indexSportCategories"));
@ -8,4 +8,10 @@ export default class SportCategoriesRepository {
return getArray(response.data);
}
}
async show(sportCategoryId) {
let response = await axios.get(url("showSportCategory", { sportCategory: sportCategoryId }));
if (response.status === 200) {
return getJson(response.data.data);
}
}
}

@ -4,7 +4,6 @@ import { getArray, setQuery } from "../resources/workoutCategoriesResources";
export default class WorkoutCategoriesRepository {
async index(data) {
let params = setQuery(data);
console.log(params);
let response = await axios.get(url("indexWorkoutCategories"), { params });
if (response.status === 200) {
return getArray(response.data);

@ -8,14 +8,29 @@ export default class WorkoutRepository {
return getArray(response.data);
}
}
async show(workoutId) {
let response = await axios.get(url("showWorkout", { workout: workoutId }));
if (response.status === 200) {
return getJson(response.data.data);
}
}
async store(data) {
let json = setData(data);
let response = await axios.post(url("storeWorkout"), json);
console.log('kldsbhakjbg', response.data);
if (response.status === 201) {
return getJson(response.data);
}
}
async update(workoutId, data) {
let json = setData(data, true);
let response = await axios.post(
url("updateWorkout", { workout: workoutId }),
json
);
if (response.status === 200) {
return response.data.data;
}
}
async delete(workoutId) {
await axios.delete(url("destroyWorkout", { workout: workoutId }));
}

@ -1,16 +1,14 @@
// import { objectToFormData } from "@/utils/objectToFormData";
import { objectToFormData } from "@/utils/objectToFormData";
// export const getJson = (data) => ({
// id: data.id,
// thumbnail: data.thumbnail,
// image: data.image,
// mime_type: data.mime_type,
// file_name: data.file_name,
// size: data.size,
// });
export const getJson = (data) => ({
id: data.id,
url: data.url,
});
// export const setData = (data) => (
// objectToFormData({
// file: data.file,
// crop: data.crop,
// }));
export const setData = (data) => (
objectToFormData({
media: data.media.file,
crop: data.crop,
batch_id: data.batch_id,
collection: data.collection,
}));

@ -1,19 +1,33 @@
import { SetPagination } from "@/utils/setQueriesObject";
import { getJsonTrainer } from './trainerProgramResource';
import { getJsonSportCategory } from './sportCategoryPorgramResource';
import { objectToFormData } from "@/utils/objectToFormData";
export const getJson = (data) => ({
id: data.id,
trainer: data.trainer ? getJsonTrainer(data.trainer) : {},
sport_category: data.trainer ? getJsonSportCategory(data.trainer) : {},
sport_category_id: data.sport_category_id,
thumbnail: data.thumbnail,
verified: data.verified,
status: data.status,
title: data.title,
description: data.description,
created_at: data.created_at,
updated_at: data.updated_at,
series_count: data.series_count
series_count: data.series_count,
workouts_count: data.workouts_count,
});
export const setData = (data, isUpdate = false) => {
let formData = {
sport_category_id: data.sport_category_id,
title: data.title,
description: data.description,
tags: data.tags,
batch_id: data.batch_id
};
if (isUpdate) {
formData["_method"] = "put";
}
return objectToFormData(formData);
};
export const getArray = ({ data, meta }) => {
const pagination = SetPagination(meta);
data = data.map((program) => getJson(program));

@ -3,12 +3,12 @@ export const getJson = (data) => ({
id: data.id,
local_name: data.local_name,
name: data.name,
workout_category_id: data.workout_category.id,
sport_category_id: data.workout_category.sport_category ? data.workout_category.sport_category.id : null,
description: data.description,
suggestion_default: {
suggested_per_ste: data.suggestion_default.suggested_per_set,
suggested_set: data.suggestion_default.suggested_set,
suggested_time: data.suggestion_default.suggested_time,
},
suggested_per_set: data.suggested_per_set,
suggested_set: data.suggested_set,
suggested_time: data.suggested_time,
tags: data.tags,
thumbnail: data.thumbnail,
title: data.title,
@ -16,6 +16,7 @@ export const getJson = (data) => ({
});
export const setData = (data, isUpdate = false) => {
let formData = {
id: data.id,
workout_category_id: data.workout_category_id,
name: data.name,
local_name: data.local_name,
@ -25,7 +26,7 @@ export const setData = (data, isUpdate = false) => {
suggested_per_set: data.suggested_per_set,
suggested_set: data.suggested_set,
suggested_time: data.suggested_time,
thumbnail: data.thumbnail,
batch_id: data.batch_id,
tags: data.tags,
};
if (isUpdate) {

@ -14,28 +14,31 @@
<v-row class="mt-4">
<v-col cols="3">
<div class="h-100">
<div class="add__workout dark w-100 h-100">
<div class="add__workout__picture d-flex align-center">
<i class="WMi-picture add__workout__picture--icon"></i>
<div class="add__workout__picture--text">
select a cover image
</div>
</div>
<div class="add__program dark w-100 h-100">
<ImageCropper
label="manager image"
:url.sync="form.thumbnail"
v-model="fileForm.media"
/>
</div>
</div>
</v-col>
<v-col cols="9">
<v-row>
<v-col cols="4"
><v-text-field
placeholder="product name"
label="product name"
class="no-error-msg pt-0 mt-0"
><v-autocomplete
dark
></v-text-field>
class="mt-0 pt-0"
item-text="name"
item-value="id"
label="program category"
:items="getSportCategories"
v-model="form.sport_category_id"
></v-autocomplete>
</v-col>
<v-col cols="8"
><v-text-field
v-model="form.title"
placeholder="a short quote"
label="a short quote"
class="no-error-msg pt-0 mt-0"
@ -46,6 +49,7 @@
<v-row>
<v-col cols="12">
<v-textarea
v-model="form.description"
rows="5"
label="description"
placeholder="description"
@ -60,25 +64,32 @@
<v-col cols="12">
<v-row>
<v-col cols="12">
<v-autocomplete
class="pt-0 multiple"
:items="items"
item-value="id"
item-text="name"
attach
<v-combobox
v-model="form.tags"
clearable
:append-icon="null"
chips
label="product tags - useful for better search"
placeholder="product tags - useful for better search"
hide-selected
class="multiple"
label="program tags - useful for better search"
placeholder="program tags - useful for better search"
multiple
persistent-hint
small-chips
dark
>
<template #selection="{ item }">
<v-chip label small color="white" text-color="black">{{
item.name
}}</v-chip>
<template #selection="{ item, select }">
<v-chip
label
small
color="white"
text-color="black"
close
@click="select"
@click:close="removeTags(item)"
>{{ item }}</v-chip
>
</template>
</v-autocomplete>
</v-combobox>
</v-col>
</v-row>
</v-col>
@ -86,16 +97,19 @@
<div class="mt-2">
<v-divider dark class="mb-2"></v-divider>
<div class="d-flex justify-space-between">
<router-link :to="{ name: 'programs' }">
<RectangleButton
text="IVE CHANGED MY MIND"
icon="WMi-cancel"
class="px-0"
height="19"
/>
</router-link>
<RectangleButton
text="add the product"
text="add the program"
class="custom-btn add-btn"
height="25"
@click.native="submit"
/>
</div>
</div>
@ -105,26 +119,55 @@
</template>
<script>
import SectionTitle from "../Global/Section/SectionTitle.vue";
import ImageCropper from "../Global/Input/ImageCropper.vue";
import FileRepository from "../../abstraction/repository/FileRepository";
import { mapGetters, mapActions } from "vuex";
import { makeid } from "@/utils/math";
const RANDOM_TOKEN = makeid(50);
export default {
components: {
SectionTitle,
ImageCropper,
},
data: () => ({
items: [
{
id: 1,
name: "fkskad",
form: {
batch_id: RANDOM_TOKEN,
},
{
id: 2,
name: "dasf",
fileForm: {
batch_id: RANDOM_TOKEN,
collection: "thumbnail",
},
],
}),
computed: {
...mapGetters("sportCategories", ["getSportCategories"]),
},
methods: {
...mapActions("sportCategories", ["loadSportCategories"]),
...mapActions("programs", ["addProgram"]),
async submit() {
try {
if (this.fileForm.media) {
let repository = new FileRepository();
await repository.store(this.fileForm);
}
this.addProgram(this.form);
} catch (e) {
return e;
}
},
removeTags(item) {
this.form.tags.splice(this.form.tags.indexOf(item), 1);
this.form.tags = [...this.form.tags];
},
},
created() {
this.loadSportCategories();
},
};
</script>
<style scoped>
.add__workout,
.add__program,
.upload {
border: 1px dotted var(--color-gray) !important;
position: relative;
@ -133,18 +176,19 @@ export default {
padding-right: 100px !important;
padding-left: 100px !important;
}
.add__workout__picture {
.add__program__picture {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90%;
}
.add__workout__picture--text {
.add__program__picture--text {
width: max-content;
line-height: 18px;
text-transform: uppercase;
}
.add__workout__picture--icon {
.add__program__picture--icon {
font-size: 40px;
margin-right: 20px;
}

@ -7,7 +7,7 @@
backText="workouts"
link="workouts"
icon="WMi-left-open"
title="add a workout"
:title="(workoutId ? 'edit' : 'add') + ' a workout'"
subTitle="let us know you better, it comes handy."
/>
</div>
@ -16,8 +16,9 @@
<div class="pb-14 h-100">
<div class="add__workout dark w-100 h-100">
<ImageCropper
:url.sync="form.thumbnail"
label="manager image"
:url.sync="form.thumbnail"
v-model="fileForm.media"
/>
</div>
</div>
@ -90,7 +91,7 @@
placeholder="suggested course time?"
label="suggested course time?"
class="no-error-msg pt-0 mt-0"
v-model="form.suggested_time"
v-model="form.suggested_set"
></v-text-field
></v-col>
<v-col cols="2"
@ -99,18 +100,16 @@
placeholder="suggested times each course?"
label="suggested times each course?"
class="no-error-msg pt-0 mt-0"
v-model="form.suggested_set"
v-model="form.suggested_per_set"
></v-text-field
></v-col>
<v-col cols="2"
><v-text-field
dark
<v-col cols="2">
<TimeInput
v-model="form.suggested_time"
class="no-error-msg pt-0 mt-0"
placeholder="suggested ESTIMATED TIME"
label="suggested ESTIMATED TIME"
class="no-error-msg pt-0 mt-0"
v-model="form.suggested_per_set"
></v-text-field
></v-col>
/></v-col>
<v-col cols="6"
><v-text-field
dark
@ -125,18 +124,28 @@
<v-col cols="12">
<v-combobox
v-model="form.tags"
:search-input.sync="search"
clearable
:append-icon="null"
hide-selected
class="multiple"
label="Add some tags"
placeholder="Add some tags"
multiple
persistent-hint
small-chips
dark
>
<template #selection="{ item }">
<v-chip label small color="white" text-color="black">{{
item
}}</v-chip>
<template #selection="{ item, select }">
<v-chip
label
small
color="white"
text-color="black"
close
@click="select"
@click:close="removeTags(item)"
>{{ item }}</v-chip
>
</template>
</v-combobox>
</v-col>
@ -146,15 +155,17 @@
<div class="mt-2">
<v-divider dark class="mb-2"></v-divider>
<div class="d-flex justify-space-between">
<router-link :to="{ name: 'workouts' }">
<RectangleButton
text="IVE CHANGED MY MIND"
icon="WMi-cancel"
class="px-0"
height="19"
/>
</router-link>
<RectangleButton
text="add the workout"
@click.native="add"
:text="(workoutId ? 'update' : 'add') + ' the workout'"
@click.native="submit"
class="custom-btn add-btn"
height="25"
/>
@ -167,46 +178,80 @@
<script>
import SectionTitle from "../Global/Section/SectionTitle.vue";
import ImageCropper from "../Global/Input/ImageCropper.vue";
import FileRepository from "../../abstraction/repository/FileRepository";
import { mapActions, mapGetters } from "vuex";
import { makeid } from "@/utils/math";
const RANDOM_TOKEN = makeid(50);
export default {
components: {
SectionTitle,
ImageCropper,
},
data: () => ({
search: null,
form: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
batch_id: RANDOM_TOKEN,
},
fileForm: {
batch_id: RANDOM_TOKEN,
collection: "thumbnail",
},
}),
computed: {
...mapGetters("sportCategories", ["getSportCategories"]),
...mapGetters("workoutCategories", ["getWorkoutCategories"]),
...mapGetters("workouts", ["getWorkout"]),
workoutId() {
return this.$route.params.id;
},
},
watch: {
"form.name"(val) {
this.form.local_name = val;
},
$route(to) {
this.workoutId = to.params.workoutId;
},
},
methods: {
...mapActions("workouts", ["addWorkout"]),
...mapActions("workouts", ["addWorkout", "loadWorkout", "updateWorkout"]),
...mapActions("workoutCategories", ["loadWorkoutCategories"]),
...mapActions("sportCategories", ["loadSportCategories"]),
async add() {
console.log(this.form);
async submit() {
try {
if (this.fileForm.media) {
let repository = new FileRepository();
await repository.store(this.fileForm);
}
if (this.workoutId) {
this.updateWorkout(this.form);
} else {
this.addWorkout(this.form);
}
} catch (e) {
return e;
}
},
async load() {
await this.loadWorkout(this.workoutId);
this.form = this.getWorkout;
this.loadWorkoutCategories(this.form.sport_category_id);
},
changeSportCategories() {
this.loadWorkoutCategories(this.form.sport_category_id);
},
removeTags(item) {
this.form.tags.splice(this.form.tags.indexOf(item), 1);
this.form.tags = [...this.form.tags];
},
},
created() {
this.loadSportCategories();
if (this.workoutId) {
this.load();
} else {
console.log("mo");
}
},
};
</script>
@ -233,7 +278,3 @@ export default {
}
</style>
<style>
.v-autocomplete .v-input__control .v-input__slot .v-select__slot label {
top: 7px !important;
}
</style>

@ -0,0 +1,64 @@
<template>
<div>
<v-menu
v-model="menu"
:close-on-content-click="false"
:nudge-right="40"
transition="scale-transition"
offset-y
min-width="auto"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
class="pt-0"
v-model="time"
:label="label"
:placeholder="placeholder || label"
prepend-inner-icon="mdi-calendar"
readonly
:color="color"
v-bind="attrs"
v-on="on"
dark
/>
</template>
<v-time-picker
:dark="dark"
use-seconds
:color="color"
v-model="time"
:type="type"
@input="menu = false"
/>
</v-menu>
</div>
</template>
<script>
export default {
props: {
label: {},
placeholder: {},
color: {},
value: {},
type: {
default: "time",
},
dark: {
default: true,
},
},
data: () => ({
menu: false,
}),
computed: {
time: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
},
},
},
};
</script>

@ -3,7 +3,7 @@
<div class="wa__program__images">
<div
class="wa__program__image"
:style="{ backgroundImage: `url(${program.src})` }"
:style="{ backgroundImage: `url(${program.thumbnail})` }"
></div>
<div class="wa__program__image__button">
<div class="wa__program__image__button--icon">
@ -55,7 +55,7 @@
class="mr-1 text-uppercase"
x-small
>
{{ program.workout }} workout
{{ program.workouts_count }} workout
</v-chip>
</div>
</div>
@ -67,6 +67,9 @@ export default {
type: Object,
},
},
created() {
console.log(this.program);
},
};
</script>
<style scoped>

@ -27,10 +27,10 @@
v-for="(item, i) in workout.tags"
:key="i"
>
{{ item.name }}
{{ item }}
</v-chip>
</div>
<div>
<div class="d-flex">
<RectangleButton
size="large"
height="26"
@ -38,12 +38,19 @@
class="custom-btn custom-icon ml-1"
@click.native="deleteWorkout(workout.id)"
/>
<router-link
:to="{
name: 'addWorkout',
params: { id: workout.id },
}"
>
<RectangleButton
size="large"
height="26"
icon="WMi-pencil"
class="custom-btn custom-icon ml-1"
/>
</router-link>
</div>
</div>
</div>

@ -50,7 +50,7 @@ export default [
name: 'addProgram'
},
{
path: '/add-workout',
path: '/add-workout/:id?',
view: 'AddWorkout',
name: 'addWorkout'
},

@ -1,16 +1,27 @@
import { urlGenerator } from "@/utils/urlGenerator";
const urls = {
// authentication
login: "auth/login",
register: "auth/register",
resetPassword: "auth/forget-password",
logout: "auth/logout",
// programs
indexProgram: "courses",
storeProgram: 'trainer/courses',
// sport categories
indexSportCategories: "admin/sport-categories",
showSportCategory: "admin/sport-categories/:sportCategory",
// workout categories
indexWorkoutCategories: "admin/workout-categories",
storeWorkout: "admin/workouts",
// workouts
indexWorkout: "admin/workouts",
showWorkout: "admin/workouts/:workout",
storeWorkout: "admin/workouts",
updateWorkout: "admin/workouts/:workout",
destroyWorkout: "admin/workouts/:workout",
// file
storeFile: 'media'
};
export default urlGenerator(urls);

@ -2,7 +2,6 @@ export default {
isModal: (state) => (...names) => {
for (const name of names) {
if (state.modals.findIndex(x => x.name == name) != -1) {
console.log(state.modals.findIndex(x => x.name == name) != -1);
return true;
}
}

@ -5,5 +5,10 @@ export default {
const resource = await repository.index();
commit("SET_PROGRAMS", resource.data);
commit("SET_PAGINATION", resource.pagination);
}
},
async addProgram({ commit }, data) {
let repository = new ProgramRepository();
const resource = await repository.store(data);
commit("ADD_PROGRAM", resource.data);
},
};

@ -7,5 +7,7 @@ export default {
pagination = { ...state.pagination, ...pagination };
Vue.set(state, "pagination", pagination);
},
ADD_PROGRAM(state, data) {
state.programs.push(data);
},
};

@ -4,5 +4,10 @@ export default {
let repository = new SportCategoriesRepository();
const resource = await repository.index();
commit("SET_SPORT_CATEGORIES", resource.data);
}
},
async loadSportCategory({ commit }, sportCategoryId) {
let repository = new SportCategoriesRepository();
const resource = await repository.show(sportCategoryId);
commit("SET_SPORT_CATEGORY", resource);
},
};

@ -1,3 +1,4 @@
export default {
getSportCategories: state => state.sportCategories,
getSportCategory: state => state.sportCategory,
}

@ -3,4 +3,7 @@ export default {
SET_SPORT_CATEGORIES(state, data) {
Vue.set(state, "sportCategories", data);
},
SET_SPORT_CATEGORY(state, data) {
Vue.set(state, "sportCategory", data);
},
};

@ -1,3 +1,4 @@
export default {
sportCategories: []
sportCategories: [],
sportCategory: []
};

@ -1,18 +1,28 @@
import workoutRepository from "@/abstraction/repository/workoutRepository";
import WorkoutRepository from "@/abstraction/repository/workoutRepository";
export default {
async loadWorkouts({ commit }) {
let repository = new workoutRepository();
let repository = new WorkoutRepository();
const resource = await repository.index();
commit("SET_WORKOUT", resource.data);
commit("SET_WORKOUTS", resource.data);
// commit("SET_PAGINATION", resource.pagination);
},
async loadWorkout({ commit }, workoutId) {
let repository = new WorkoutRepository();
const resource = await repository.show(workoutId);
commit("SET_WORKOUT", resource);
},
async addWorkout({ commit }, data) {
let repository = new workoutRepository();
let repository = new WorkoutRepository();
const resource = await repository.store(data);
commit("ADD_WORKOUT", resource.data);
},
async updateWorkout({ commit }, data) {
let repository = new WorkoutRepository();
const resource = await repository.update(data.id, data);
commit("UPDATE_WORKOUT", resource);
},
async deleteWorkout({ commit }, workoutId) {
let repository = new workoutRepository();
let repository = new WorkoutRepository();
await repository.delete(workoutId);
commit('DELETE_WORKOUT', workoutId);
}

@ -1,3 +1,4 @@
export default {
getWorkouts: state => state.workouts
getWorkouts: state => state.workouts,
getWorkout: state => state.workout,
}

@ -1,11 +1,18 @@
import Vue from "vue";
export default {
SET_WORKOUT(state, data) {
SET_WORKOUTS(state, data) {
Vue.set(state, "workouts", data);
},
SET_WORKOUT(state, data) {
Vue.set(state, "workout", data);
},
ADD_WORKOUT(state, data) {
state.workouts.push(data);
},
UPDATE_WORKOUT(state, data) {
const index = state.workouts.findIndex((x) => x.id === data.id);
Vue.set(state.workouts, index, data);
},
DELETE_WORKOUT(state, workoutId) {
const index = state.workouts.findIndex((x) => x.id === workoutId);
state.workouts.splice(index, 1);

@ -1,3 +1,4 @@
export default {
workouts: []
workouts: [],
workout: {}
};

@ -17,7 +17,9 @@
ul {
list-style-type: none;
}
a {
text-decoration: none !important;
}
.wa__link a {
text-decoration: none;
display: block;

@ -8,6 +8,7 @@ import AuthFooter from '../components/Global/Footer/AuthFooter.vue';
import RectangleButton from '../components/Global/Button/RectangleButton.vue';
import MainBack from '../components/Global/Section/MainBackground.vue';
import DateInput from '../components/Global/Input/DateInput.vue';
import TimeInput from '../components/Global/Input/TimeInput.vue';
import BasicModal from "../components/Global/Modal/BasicModal";
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
@ -19,4 +20,5 @@ Vue.component('auth-footer', AuthFooter);
Vue.component('RectangleButton', RectangleButton);
Vue.component('main-back', MainBack);
Vue.component('DateInput', DateInput);
Vue.component('TimeInput', TimeInput);
Vue.component('basic-modal', BasicModal);

@ -132,7 +132,6 @@ export default {
async doRegister() {
let response = await this.register(this.form);
if (response) {
console.log("response", response);
this.$router.push("/");
}
},

Loading…
Cancel
Save