restore composer.json, add mysqli extension

This commit is contained in:
2026-04-15 17:02:52 +05:00
commit 77cf56a348
4317 changed files with 1397107 additions and 0 deletions

70
resources/js/app.js Executable file
View File

@@ -0,0 +1,70 @@
import "./bootstrap";
import Vue from "vue";
import CKEditor from "@ckeditor/ckeditor5-vue";
import Multiselect from "vue-multiselect";
import Vue2Filters from "vue2-filters";
import VueInternationalization from "vue-i18n";
import Locale from "./vue-i18n-locales.generated";
import Moment from "vue-moment";
Vue.use(Moment);
//Dashboard
import ProductAdd from "./components/ProductStore.vue";
import ProductEdit from "./components/ProductEdit.vue";
import CompilationStore from "./components/Compilation/Store.vue";
import CompilationUpdate from "./components/Compilation/Update.vue";
import OrderUpdate from "./components/Order/Update.vue";
import CategoryStore from "./components/Dashboard/Category/Store.vue";
import CategoryUpdate from "./components/Dashboard/Category/Update.vue";
import CategoryIndex from "./components/Dashboard/Category/Index.vue";
import VueFileAgent from "vue-file-agent";
// import VueFileAgentStyles from "vue-file-agent/dist/vue-file-agent.css";
import ProductPreviewImport from "./components/ProductPreviewImport.vue";
import Logs from "./components/Dashboard/Logs.vue";
import Statics from "./components/Dashboard/Statics.vue";
import SliderView from "./components/Slider/SliderView.vue";
Vue.use(VueFileAgent);
Vue.component("product-add", ProductAdd);
Vue.component("product-edit", ProductEdit);
Vue.component("order-edit", OrderUpdate);
Vue.component("category-store", CategoryStore);
Vue.component("category-update", CategoryUpdate);
Vue.component("category-list", CategoryIndex);
Vue.component("compilation-store", CompilationStore);
Vue.component("compilation-update", CompilationUpdate);
Vue.component("product-preview", ProductPreviewImport);
Vue.component("logs-block", Logs);
Vue.component("dashboard-statics", Statics);
Vue.component("multiselect", Multiselect);
Vue.component("slider-view", SliderView);
Vue.use(CKEditor);
Vue.use(Vue2Filters);
Vue.use(VueInternationalization);
const lang = document.documentElement.lang.substr(0, 2);
Vue.config.devtools = true;
const i18n = new VueInternationalization({
locale: lang,
messages: Locale,
});
const app = new Vue({
el: "#app",
i18n,
});

20
resources/js/bootstrap.js vendored Executable file
View File

@@ -0,0 +1,20 @@
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// window._ = require('lodash');
/**
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
* for JavaScript based Bootstrap features such as modals and tabs. This
* code may be modified to fit the specific needs of your application.
*/
try {
window.Popper = require('popper.js').default;
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {}

View File

@@ -0,0 +1,83 @@
<template>
<div class="modal fade login" id="password-edit">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<i class="fal fa-times"></i>
</button>
<!-- Изменить пароль-Password -->
<div>
<h4 class="text-center">{{ $t('vue.change_password.title') }}</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.change_password.enter_current')" v-model="user.current_password" id="login_password1" required />
<label for="login_password1">{{ $t('vue.change_password.current') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.enter_new_password')" v-model="user.password" id="login_password2" required />
<label for="login_password2">{{ $t('vue.login.new_password') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.enter_new_re_password')" v-model="user.password_confirmation" id="login_password3" required />
<label for="login_password3">{{ $t('vue.login.new_re_password') }}</label>
</div>
<div class="mt-4 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="submit" class="my-btn my-btn__orange w-100">
{{ $t('vue.change_password.save') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data: () => ({
user: {
current_password: null,
password: null,
password_confirmation: null,
},
error: false,
errors: []
}),
methods: {
async SendForm() {
try {
const { status } = await axios.post('/profile/password/update', this.user);
if (status === 200) {
location.reload();
}
} catch (error) {
this.error = true;
this.errors = error.response.data.errors;
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,434 @@
<template>
<div class="modal fade login" id="login">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<i class="fal fa-times"></i>
</button>
<div v-if="step === 1">
<h4>{{ $t('app.auth.title') }}</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone" required>
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.next') }}
</button>
</div>
</form>
</div>
<div v-if="step === 2">
<h4 class="text-center">
{{ $t('vue.login.regg') }}
</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.enter_password')" v-model="user.password" id="password" required />
<label for="password">{{ $t('vue.login.password') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.re_password')" v-model="user.password_confirmation" id="login_password" required />
<label for="login_password">{{ $t('vue.login.re_password') }}</label>
</div>
<div class="mt-4 d-flex justify-content-between reply">
<div class="my-custom-control custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" checked id="customCheck" name="example1">
<label class="custom-control-label" for="customCheck" v-html="$t('vue.login.policy')">
</label>
</div>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.reg') }}
</button>
</div>
</form>
</div>
<div v-if="step === 3">
<h4 class="text-center">{{ $t('vue.login.regg') }}</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="text" :placeholder="$t('vue.login.enter_code')" v-model="user.verify" id="login_password" required />
<label for="login_password"> {{ $t('vue.login.code') }}</label>
</div>
<div class="text-danger mt-1" v-if="password_error">
{{ $t('vue.login.sms_empty') }}
</div>
<div class="mt-4 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.confirm') }}
</button>
</div>
</form>
</div>
<div v-if="step === 4">
<h4 class="text-center">
<h4>{{ $t('app.auth.title') }}</h4>
</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" v-model="user.password" :placeholder="$t('vue.login.password')" id="login_password" required />
<label for="login_password"> {{ $t('vue.login.password') }}</label>
</div>
<div class="text-danger mt-1" v-if="password_error">
{{ $t('vue.login.pass_err') }}
</div>
<div class="mt-4 d-flex justify-content-between reply">
<div class="my-custom-control custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="remember" v-model="user.remember" name="remember">
<label class="custom-control-label" for="remember">
{{ $t('vue.login.remember') }}
</label>
</div>
<a href="#" @click="step = 5 " class="reset-password text-primary">
{{ $t('vue.login.restore') }}
</a>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('app.layout.login') }}
</button>
</div>
</form>
</div>
<div v-if="step === 5 || step === 6 || step === 7">
<h4 class="text-center">
{{ $t('vue.login.restore_pass') }}
</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group" v-if="step === 7">
<input type="password" :placeholder="$t('vue.login.new_password')" v-model="user.password" id="password" required />
<label for="password">
{{ $t('vue.login.new_password') }}
</label>
</div>
<div class="mt-4 my-form__group" v-if="step === 7">
<input type="password" :placeholder="$t('vue.login.new_re_password')" v-model="user.password_confirmation" id="login_password" required />
<label for="login_password">
{{ $t('vue.login.new_re_password') }}
</label>
</div>
<div class="mt-4 my-form__group" v-if="step === 5 || step === 6 ">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group" v-if="step === 6">
<input type="text" :placeholder="$t('vue.login.enter_code')" v-model="user.verify" id="login_password" required />
<label for="login_password">{{ $t('vue.login.code') }}</label>
</div>
<div class="text-danger mt-1" v-if="step === 6 && password_error">
{{ $t('vue.login.sms_empty') }}
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button v-if="step === 5" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.next') }}
</button>
<button v-if="step === 6" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.confirm') }}
</button>
<button v-if="step === 7" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.restore_confirm') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
props: ['url'],
data: () => ({
user: {
phone: null,
verify: null,
password: null,
password_confirmation: null,
remember: false
},
step: 1,
verify: false,
error: false,
errors: [],
password_error: false
}),
methods: {
async SendForm () {
if (this.step === 1) {
const { data } = await axios.post('/auth/login', {
phone: this.user.phone
});
this.step = data.step;
// this.verify = true;
} else if (this.step === 2) {
try {
const { data } = await axios.post('/auth/register', {
phone: this.user.phone,
password: this.user.password,
password_confirmation: this.user.password_confirmation,
});
this.step = data.step;
} catch (error) {
this.error = true;
this.errors = error.response.data.errors;
}
} else if (this.step === 3) {
try {
let type;
let action;
if (this.$cookie.get('product-credit')) {
type = 'product-credit';
action = this.$cookie.get('product-credit');
} else if (this.$cookie.get('cart-preview')) {
type = 'cart-preview';
action = 'cart-preview';
} else {
type = 'auth';
action = null;
}
const { data } = await axios.post('/auth/verify', {
phone: this.user.phone,
code: this.user.verify,
type: type,
action: action
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
switch (data.action) {
case 'cart-preview':
window.location.href = data.url;
this.$cookie.delete('cart-preview');
break;
case 'product-credit':
window.location.href = data.url;
this.$cookie.delete('product-credit');
break;
default:
location.reload();
this.$cookie.delete('product-credit');
this.$cookie.delete('cart-preview');
break;
}
}
} catch (error) {
this.password_error = true;
}
} else if (this.step === 4 ) {
try {
let type;
let action;
if (this.$cookie.get('product-credit')) {
type = 'product-credit';
action = this.$cookie.get('product-credit');
} else if (this.$cookie.get('cart-preview')) {
type = 'cart-preview';
action = 'cart-preview';
} else {
type = 'auth';
action = null;
}
const { data } = await axios.post('/auth/password', {
phone: this.user.phone,
password: this.user.password,
type: type,
action: action,
remember: this.user.remember
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
switch (data.action) {
case 'cart-preview':
window.location.href = data.url;
this.$cookie.delete('cart-preview');
break;
case 'product-credit':
window.location.href = data.url;
this.$cookie.delete('product-credit');
break;
default:
location.reload();
this.$cookie.delete('product-credit');
this.$cookie.delete('cart-preview');
break;
}
}
} catch (error) {
this.password_error = true;
}
} else if (this.step === 5) {
try {
const { data } = await axios.post('/auth/restore', {
phone: this.user.phone,
});
this.step = data.step;
} catch (error) {
}
} else if (this.step === 6) {
try {
const { data } = await axios.post('/auth/restore/verify', {
phone: this.user.phone,
code: this.user.verify
});
this.user.password = null;
this.user.password_confirmation = null;
this.step = data.step;
} catch (error) {
this.password_error = true;
}
} else if (this.step === 7) {
try {
let type;
let action;
if (this.$cookie.get('product-credit')) {
type = 'product-credit';
action = this.$cookie.get('product-credit');
} else if (this.$cookie.get('cart-preview')) {
type = 'cart-preview';
action = 'cart-preview';
} else {
type = 'auth';
action = null;
}
const { data } = await axios.post('/auth/restore/confirm', {
phone: this.user.phone,
password: this.user.password,
password_confirmation: this.user.password_confirmation,
type: type,
action: action
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
switch (data.action) {
case 'cart-preview':
window.location.href = data.url;
this.$cookie.delete('cart-preview');
break;
case 'product-credit':
window.location.href = data.url;
this.$cookie.delete('product-credit');
break;
default:
location.reload();
this.$cookie.delete('product-credit');
this.$cookie.delete('cart-preview');
break;
}
}
} catch (error) {
this.error = true;
this.errors = error.response.data.errors;
}
}
},
async Resend () {
if (this.verify) {
await axios.post('/api/auth/login', {
phone: this.user.phone
});
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,88 @@
<template>
<swiper ref="mySwiperHeader" class="swiper-container swiper-header" :options="swiperOptions">
<swiper-slide v-for="(slider, index) in sliderData" :key="index">
<a :href="slider.link" class="w-100 h-100 d-block">
<div class="swiper-header__item" :style="{ 'background-image' : 'url(/' + slider.image +')' }"></div>
</a>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-header" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-header" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-header" slot="pagination"></div>
</swiper>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
// import "swiper/swiper-bundle.css";
import 'swiper/css/swiper.css'
export default {
props: ['sliderData'],
components: {
Swiper,
SwiperSlide,
},
data() {
return {
swiperOptions: {
slidesPerView: 1,
spaceBetween: 0,
navigation: {
nextEl: ".swiper-button-next-header",
prevEl: ".swiper-button-prev-header",
},
pagination: {
el: ".swiper-pagination-header",
clickable: true,
},
loop: true,
effect: "fade",
speed: 1000,
autoplay: {
delay: 6000,
},
},
};
},
computed: {
swiper() {
return this.$refs.mySwiperHeader.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<div>
<section class="section-bonus">
<div class="container">
<div class="banner" v-if="bannersData.length === 1">
<a :href="bannersData[0].link">
<img :src="'/' + bannersData[0].image" />
</a>
</div>
<div v-if="bannersData.length > 1">
<swiper
ref="mySwiperBonus"
class="swiper-container swiper-banners"
:options="swiperOptions"
>
<swiper-slide v-for="(banner, index) in bannersData" :key="index">
<div class="banner">
<a :href="banner.link">
<img :src="'/' + banner.image" />
</a>
</div>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-product" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product" slot="pagination"></div>
</swiper>
</div>
</div>
</section>
</div>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
import "swiper/css/swiper.css";
export default {
props: ['bannersData'],
components: {
Swiper,
SwiperSlide,
},
data() {
return {
swiperOptions: {
slidesPerView: 1,
spaceBetween: 0,
loop: true,
navigation: {
nextEl: ".swiper-button-next-product",
prevEl: ".swiper-button-prev-product",
},
pagination: {
el: ".swiper-pagination-product",
clickable: true,
dynamicBullets: true,
},
speed: 1000,
autoplay: {
delay: 4500,
},
},
products: [],
};
},
computed: {
swiper() {
return this.$refs.mySwiperBonus.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
.swiper-banners {
padding: 75px 0 0px;
margin-top: -50px;
@include mq("tablet", max) {
margin-left: -15px;
margin-right: -15px;
padding-bottom: 30px;
}
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<div>
<section class="section-categories">
<div class="container">
<h2 class="section-title">{{ getName(brandData.name) }}</h2>
<div class="aksiya">
<div class="alert alert-info w-100" v-if="products.length === 0">
<i class="fa fa-info-circle"></i> {{ $t('app.no_product') }}
</div>
<Product v-for="(product, index) in products" :key="index" :product="product" :login-info="loginInfo"/>
</div>
</div>
</section>
</div>
</template>
<script>
import Product from './Products/Product.vue';
export default {
props: {
productsData: {},
loginInfo: {},
brandData: {}
},
components: {
Product
},
data() {
return {
products: this.productsData.data
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
// console.log(value);
return value;
},
}
}
</script>

View File

@@ -0,0 +1,286 @@
<template>
<div>
<section class="section-checkout">
<div class="container">
<!-- <h2 class="section-title">Оформление заказа</h2>-->
<ul class="steps steps-one">
<li class="steps-item">
<a href="#">
{{ $t('vue.cart.step_1')}}
</a>
</li>
<li class="steps-item">
<a href="/checkout">
{{ $t('vue.cart.step_2')}}
</a>
</li>
<li class="steps-item">
<a href="/checkout">
{{ $t('vue.cart.step_3')}}
</a>
</li>
</ul>
</div>
</section>
<section class="section-basket">
<div class="container">
<div class="d-flex align-items-md-center justify-content-between py-3 flex-md-row flex-column">
<h2 class="section-title">{{ $t('app.cart.title') }}</h2>
</div>
<p class="mb-3 " v-if="products.length === 0">
{{ $t('app.no_product') }}
</p>
<div class="row" v-if="products.length > 0">
<div class="col-lg-12 col-md-6">
<div class="product my-3">
<div class="row align-items-center" v-for="(product, index) in products">
<div class="col-lg-2">
<div class="product-img">
<img :src="'/' + product.product.product.poster_thumb" :alt="getName(product.product.product.name)">
</div>
</div>
<div class="col-lg-3">
<h3 class="product-title">
{{ getName(product.product.product.name) }}
</h3>
<div class="product-address">{{ $t('app.product.article_number') }}: {{ product.product.product.article_number }}</div>
<div class="product-price_and_checkout mt-2">
<div class="product-price-by-count mr-3">{{ $t('app.price') }} {{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum_sht') }}</div>
<button class="my-btn my-btn__orange my-btn__orange--small" v-if="product.product.product.discountPrice > 0 && product.price_discount">{{ $t('app.discount') }}</button>
</div>
</div>
<div class="col-lg-2">
<div class="product-count__title">
{{ $t('vue.cart.count_by') }}
</div>
<div class="product-count">
<span class="decrement" @click="CountMinus(product)"><i class="fal fa-minus"></i></span>
<input type="text" v-model="product.count" min="0" readonly>
<span class="increment" @click="CountAdd(product)"><i class="fal fa-plus"></i></span>
</div>
</div>
<div class="col-lg-2">
<div class="product-price">
<div class="title-price">{{ $t('app.price') }}</div>
<div class="old-price mb-1" v-if="product.price_discount"> {{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</div>
<div class="new-price">{{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</div>
</div>
</div>
<div class="col-lg-3">
<div class="product-buttons">
<button class="product-to_favorite__thin" data-target="#login" data-toggle="modal" v-if="!loginInfo">
<i class="far fa-heart"></i>
<span>{{ $t('app.favorites.in_favorite') }}</span>
</button>
<button class="product-to_favorite__thin" :class="product.product.product.isFavorite ? 'product-to_favorite__thin is-active' : 'product-to_favorite__thin'" @click="Favorite(product.product.product)" v-if="loginInfo">
<i class="far fa-heart"></i>
<span>{{ $t('app.favorites.in_favorite') }}</span>
</button>
<div class="v-line">|</div>
<button class="product-to_delete" @click="removeProduct(product, index)">
<i class="fal fa-times fa-2x"></i>
<span>{{ $t('app.delete') }}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="basket__footer" v-if="products.length > 0">
<div class="basket__footer--left">
<!-- <form action="index.html" class="my-form my-form__auth">-->
<!-- <div class="d-flex align-items-xl-center flex-xl-row flex-column align-items-center align-items-md-start">-->
<!-- <div class="my-form__group">-->
<!-- <input type="text" placeholder="Промокод" id="login_password" required>-->
<!-- </div>-->
<!-- <div class="">-->
<!-- <button type="sbumit" class="my-btn my-btn__gray ml-xl-3 mt-xl-0 mt-3">-->
<!-- {{ $t('vue.cart.get_discount') }}-->
<!-- </button>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="mt-4 d-flex justify-content-md-start align-items-center align-items-md-start justify-content-center">-->
<!-- <a href="javascript:void(0)" class="reset-password">-->
<!-- {{ $t('vue.cart.get_promocode') }}-->
<!-- </a>-->
<!-- <a href="javascript:void(0)" class="reset-password d-none">-->
<!-- {{ $t('vue.cart.another_promocode') }}-->
<!-- </a>-->
<!-- </div>-->
<!-- </form>-->
</div>
<div class="basket__footer--right">
<div class="sum-of-products">
<h3>{{ $t('vue.cart.total_amount') }}: <span>{{ prices | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span></h3>
<h5>{{ $t('vue.cart.saving') }}: <span>0 сум</span></h5>
<h2>{{ $t('vue.cart.total_cost') }}: <span>{{ prices | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span></h2>
</div>
</div>
</div>
<div class="basket__footer" v-if="products.length > 0">
<a href="/" class="btn-links btn-links__one">{{ $t('vue.cart.continue_shopping') }}</a>
<div class="basket__footer--right mt-3 mt-md-0">
<button @click="removeAllProducts" class="btn-links btn-links__three mr-md-2 my-3 my-md-0">{{ $t('vue.cart.reset_cart') }}</button>
<a href="/cart/oncredit/" v-if="loginInfo && creditInfo" class="btn-links btn-links__one bg__green mr-md-2 my-3 my-md-0">
{{ $t('vue.cart.credit') }}
</a>
<a href="javascript:" v-if="!loginInfo && creditInfo" data-target="#login" data-toggle="modal" data-dismiss="modal" @click="CreditCookie" class="btn-links btn-links__one bg__green mr-md-2 my-3 my-md-0">
{{ $t('vue.cart.credit') }}
</a>
<a href="/checkout" class="btn-links btn-links__two">{{ $t('vue.cart.checkout_product') }}</a>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
export default {
props: {
cartData: {},
loginInfo: {},
pricesData: {},
creditInfo: {}
},
data() {
return {
products: this.cartData,
prices: this.pricesData
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async removeAllProducts() {
const { data } = await axios.delete('/cart/remove/all');
if (data.status) {
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
this.products = [];
}
},
async CountMinus(product) {
if (product.product.product.count >= product.count) {
if (product.count <= 1) {
product.count = 1;
} else {
product.count -= 1;
}
} else {
product.count = product.product.product.count;
}
const fields = {
product_id: product.product_id,
count: product.count
};
const { data } = await axios.post('/cart/update', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
product.product.product.count = data.max_count;
}
},
CreditCookie() {
this.$cookie.delete('product-credit');
this.$cookie.set('cart-preview', 1);
},
async CountAdd(product) {
if (product.product.product.count > product.count){
product.count += 1;
const fields = {
product_id: product.product_id,
count: product.count
};
const { data } = await axios.post('/cart/update', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
product.product.product.count = data.max_count;
}
}
},
async Favorite(product) {
var field = document.getElementById("favorite-count");
var count = field.value;
if (product.isFavorite === false) {
const { data } = await axios.get('/favorites/store/' + product.id);
product.isFavorite = true;
field.value = parseInt(count) + 1;
} else {
const { data } = await axios.get('/favorites/delete/' + product.id);
product.isFavorite = false;
field.value = parseInt(count) - 1;
}
},
async removeProduct(product, index) {
const { data } = await axios.delete('/cart/delete/' + product.product_id);
if (data.status) {
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
this.products.splice(index, 1)
}
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,228 @@
<template>
<div class="balance-link">
<a href="javascript:" data-target="#basket_modal" data-toggle="modal" @click="getCart" class="basket">
<i class="fas fa-shopping-basket"></i>
<div class="basket-count">
<input type="text" id="basket-count" readonly v-model="basket">
</div>
</a>
<div class="modal fade basket-modal" id="basket_modal">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<i class="fal fa-times"></i>
</button>
<h4>{{ $t('vue.cart_preview.basket_title') }}</h4>
<p class="mb-3 " v-if="products.length === 0">
{{ $t('app.no_product') }}
</p>
<form action="#" class="my-form my-form__auth">
<div class="product" v-for="(product, index) in products">
<div class="row align-items-center">
<div class="col-lg-2">
<div class="product-img">
<img :src="'/' + product.product.product.poster_thumb" :alt="getName(product.product.product.name)">
</div>
</div>
<div class="col-lg-5">
<h3 class="product-title">{{ getName(product.product.product.name) }}</h3>
<div class="product-price_and_checkout mt-2">
<div class="product-price-by-count mr-3">{{ $t('app.price') }} {{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum_sht') }}</div>
</div>
</div>
<div class="col-lg-2 mx-auto">
<div class="product-count mb-md-0 mx-auto my-3 my-md-0">
<span class="decrement" @click="CountMinus(product)"><i class="fal fa-minus"></i></span>
<input type="text" v-model="product.count" min="0" class="h-auto" readonly>
<span class="increment" @click="CountAdd(product)"><i class="fal fa-plus"></i></span>
</div>
</div>
<div class="col-lg-3">
<div class="product-buttons">
<button type="button" class="product-to_delete" @click="removeProduct(product, index)">
<i class="fal fa-times fa-2x"></i>
<span>{{ $t('app.delete') }}</span>
</button>
</div>
</div>
</div>
</div>
<hr v-if="products.length > 0">
<div class="sum-of-products d-flex justify-content-end my-4" v-if="products.length > 0">
<h3>{{ $t('vue.cart.total_amount') }}: <span>{{ prices | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span></h3>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center flex-md-row flex-column" v-if="products.length > 0">
<a href="/cart" class="my-btn my-btn__orange d-flex justift-content-center align-items-center text-white">{{ $t('vue.cart_preview.basket_checkout') }}</a>
<div class="product-buttons mb-0 ml-md-3" v-if="on_credit">
<a href="javascript:" v-if="!loginInfo" data-target="#login" data-toggle="modal" data-dismiss="modal" @click="CreditCookie" class="btn-links btn-links__one bg__green">
{{ $t('vue.cart.credit') }}
</a>
<a href="/cart/oncredit/" v-if="loginInfo" class="btn-links btn-links__one bg__green">
{{ $t('vue.cart.credit') }}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
loginInfo: {}
},
data() {
return {
products: [],
prices: 0,
basket: 0,
on_credit: 0
}
},
created() {
this.$eventBus.$on('cart-preview', this.getPreviews);
},
mounted() {
this.getCount()
},
methods: {
getPreviews() {
this.getCart();
},
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async CountMinus(product) {
if (product.product.product.count >= product.count) {
if (product.count <= 1) {
product.count = 1;
} else {
product.count -= 1;
}
} else {
product.count = product.product.product.count;
}
const fields = {
product_id: product.product_id,
count: product.count
};
const { data } = await axios.post('/cart/update', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
product.product.product.count = data.max_count;
}
},
async CountAdd(product) {
if (product.product.product.count > product.count){
product.count += 1;
const fields = {
product_id: product.product_id,
count: product.count
};
const { data } = await axios.post('/cart/update', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
this.prices = data.prices;
product.product.product.count = data.max_count;
}
}
},
async getCount() {
const { data } = await axios.get('/cart/basket/');
if (data.status) {
this.basket = data.basket;
}
},
async getCart() {
const { data } = await axios.get('/cart/preview/');
if (data.status) {
this.basket = data.products.length;
this.products = data.products;
this.prices = data.prices;
this.on_credit = data.on_credit
}
},
CreditCookie() {
this.$cookie.delete('product-credit');
this.$cookie.set('cart-preview', 1);
},
async removeProduct(product, index) {
const { data } = await axios.delete('/cart/delete/' + product.product_id);
if (data.status) {
this.basket = data.count;
this.prices = data.prices;
this.products.splice(index, 1)
}
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,377 @@
<template>
<section :class="products.length === 0 ? 'section-categories no-product-section' : 'section-categories'">
<div class="container">
<h1 class="section-title">
{{ getName(category.name) }}
</h1>
<div class="my-form my-form__checkout my-form__countBy mb-3 d-block d-md-none">
<div class="my-form__group d-flex flex-row justify-content-end">
<p class="mr-3">{{ $t('vue.catalog.view_by') }}</p>
<select @change="SendFilterParams" v-model="page_products" class="custom-select">
<option value="12">12</option>
<option value="24">24</option>
<option value="48">48</option>
</select>
</div>
</div>
<!-- Catalog on Mobile -->
<div class="catalog-on-mobile" v-if="mobile">
<ul class="outer-ul" :class="menu">
<li class="catalog" v-if="categories.length > 0">
{{ $t('vue.catalog.catalog_title') }} <i class="fas fa-caret-down"></i>
<ul class="inner-ul">
<li v-for="(category, index) in categories" v-if="category.published" :key="index">
<a :href="category.link">
{{ getName(category.name) }}
</a>
</li>
</ul>
</li>
<li class="filtr" v-if="characteristics.length > 0">
{{ $t('vue.catalog.catalog_filter') }} <i class="fas fa-caret-down"></i>
</li>
<ul class="inner-ul filtr-inner-ul" v-if="characteristics.length > 0">
<form action="#" @submit.prevent="SendFilterParams">
<div class="categories">
<div class="card" v-if="characteristics.length > 0" v-for="(char, index) in characteristics" :key="index">
<div class="card-header">
<a class="card-link" data-toggle="collapse" :href="'#collapse-'+ char.id">
{{ getName(char.name) }}
</a>
</div>
<div :id="'collapse-'+ char.id" class="collapse show" :data-parent="'#collapse-'+ char.id">
<div class="card-body">
<div class="card-content brand">
<div class="custom-control custom-checkbox" v-for="(attr, indexx) in char.attributes" :key="indexx">
<input type="checkbox" class="custom-control-input" v-model="filters" :id="'check'+char.id+indexx" name="filter" :value="{id: char.id, name: char.name, type: char.type, attribute: attr}">
<label class="custom-control-label" :for="'check'+char.id+indexx" v-if="char.type === 'checkbox'">
<span v-if="attr === 'true'">
{{ $t('app.exist') }}
</span>
<span v-if="attr === 'false'">
{{ $t('app.no') }}
</span>
</label>
<label class="custom-control-label" :for="'check'+char.id+indexx" v-else>
{{ attr }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="category-buttons pb-2 mt-4" v-if="characteristics.length > 0">
<button type="submit" class="my-btn my-btn__apply my-3 apply_mobile" >{{ $t('vue.catalog.catalog_accept') }}</button>
<button type="button" @click="removeAllFilter" class="my-btn my-btn__cancel my-3">{{ $t('vue.catalog.catalog_reset') }}</button>
</div>
</div>
</form>
</ul>
<li class="view">
{{ $t('vue.catalog.view_by') }} <i class="fas fa-caret-down"></i>
<ul class="inner-ul">
<li><a :class="orderby === 'all' ? 'active' : ''" @click="orderByChange('all')" href="#javascript:">{{ $t('vue.catalog.view_by_all') }}</a></li>
<li><a :class="orderby === 'new' ? 'active' : ''" @click="orderByChange('new')" href="#javascript:">{{ $t('vue.catalog.new') }}</a></li>
<li><a :class="orderby === 'cheap' ? 'active' : ''" href="javascript:" @click="orderByChange('cheap')">{{ $t('vue.catalog.view_by_cheap') }}</a></li>
<li><a :class="orderby === 'expensive' ? 'active' : ''" href="javascript:" @click="orderByChange('expensive')">{{ $t('vue.catalog.view_by_expensive') }}</a></li>
</ul>
</li>
</ul>
</div>
<div :class="categories.length > 0 || characteristics.length > 0 ? 'row row-outer' : 'row-outer'" >
<div v-if="!mobile && categories.length > 0 || !mobile && characteristics.length > 0" class="col-md-4 col-lg-3">
<form action="#" @submit.prevent="SendFilterParams" class="h-100 d-md-block d-none">
<div class="categories sticky-top">
<div :class="characteristics.length === 0 ? 'card border-bottom-0' : 'card'" v-if="categories.length > 0">
<div class="card-header">
<a class="card-link" data-toggle="collapse" href="#collapse-1111">
{{ $t('vue.catalog.catalog_title') }}
</a>
</div>
<div id="collapse-1111" class="collapse show" data-parent="#collapse-1111">
<div class="card-body">
<div class="card-content category">
<ul>
<li v-for="(category, index) in categories" v-if="category.published" :key="index">
<a :href="category.link">
{{ getName(category.name) }}
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="card" v-if="characteristics.length > 0" v-for="(char, index) in characteristics" :key="index">
<div class="card-header">
<a class="card-link" data-toggle="collapse" :href="'#collapse-'+ char.id">
{{ getName(char.name) }}
</a>
</div>
<div :id="'collapse-'+ char.id" class="collapse show" :data-parent="'#collapse-'+ char.id">
<div class="card-body">
<div class="card-content brand">
<div class="custom-control custom-checkbox" v-for="(attr, indexx) in char.attributes" :key="indexx">
<input type="checkbox" class="custom-control-input" v-model="filters" :id="'check'+char.id+indexx" name="filter" :value="{id: char.id, name: char.name, type: char.type, attribute: attr}">
<label class="custom-control-label" :for="'check'+char.id+indexx" v-if="char.type === 'checkbox'">
<span v-if="attr === 'true'">
{{ $t('app.exist') }}
</span>
<span v-else>
{{ $t('app.no') }}
</span>
</label>
<label class="custom-control-label" :for="'check'+char.id+indexx" v-else>
{{ attr }}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="category-buttons pb-2 mt-4" v-if="characteristics.length > 0">
<button type="submit" class="my-btn my-btn__apply my-3" >{{ $t('vue.catalog.catalog_accept') }}</button>
<button type="button" @click="removeAllFilter" class="my-btn my-btn__cancel my-3">{{ $t('vue.catalog.catalog_reset') }}</button>
</div>
</div>
</form>
</div>
<div :class="categories.length > 0 || characteristics.length > 0 ? 'col-md-8 col-lg-9' : 'col-12'">
<div class="d-md-block d-none" v-if="products.length > 0">
<div class="d-flex justify-content-between">
<ul class="sorting">
<li class="sorting-item"><a :class="orderby === 'all' ? 'active' : ''" @click="orderByChange('all')" href="#javascript:">{{ $t('vue.catalog.view_by_all') }}</a></li>
<li class="sorting-item"><a :class="orderby === 'new' ? 'active' : ''" @click="orderByChange('new')" href="#javascript:">{{ $t('vue.catalog.new') }}</a></li>
<li class="sorting-item"><a :class="orderby === 'cheap' ? 'active' : ''" href="javascript:" @click="orderByChange('cheap')">{{ $t('vue.catalog.view_by_cheap') }}</a></li>
<li class="sorting-item"><a :class="orderby === 'expensive' ? 'active' : ''" href="javascript:" @click="orderByChange('expensive')">{{ $t('vue.catalog.view_by_expensive') }}</a></li>
</ul>
<div class="my-form my-form__checkout my-form__countBy">
<div class="my-form__group">
<select @change="SendFilterParams" v-model="page_products" class="custom-select">
<option disabled selected>{{ $t('vue.catalog.view_byy') }}</option>
<option value="12">12</option>
<option value="24">24</option>
<option value="48">48</option>
</select>
</div>
</div>
</div>
<div class="selected-tags" v-if="filters.length > 0">
<ul>
<li v-for="(attr, index) in filters" :key="index">
<span v-if="attr.attribute === 'true'">
{{ getName(attr.name) }}: {{ $t('app.exist') }}
</span>
<span v-else-if="attr.attribute === 'false'">
{{ getName(attr.name) }}: {{ $t('app.no') }}
</span>
<span v-else>
{{ attr.attribute }}
</span>
<span class="close" @click="removeFilter(index)"><i class="fal fa-times"></i></span>
</li>
<li class="clear-all" @click="removeAllFilter" id="clear_all">{{ $t('vue.catalog.catalog_reset') }}</li>
</ul>
</div>
</div>
<div class="row row-inner">
<div v-if="products.length === 0">
{{ $t('app.no_category_product') }}
</div>
<div class="aksiya w-100 mt-0" v-if="categories.length === 0 && characteristics.length === 0">
<product-item v-for="(product, index) in products" :key="index" :product="product" :login-info="loginInfo"/>
</div>
<div v-if="categories.length > 0 || characteristics.length > 0" class="col-md-6 col-lg-4 col-xl-3 my-2" v-for="(product, index) in products">
<product-item :product="product" :login-info="loginInfo"></product-item>
</div>
</div>
<paginate v-if="product_count > 12"
v-model="page_current"
:pageCount="pageCount"
:clickHandler="PageCallBack"
:prevText="'<i class=\'far fa-long-arrow-left \'></i>'"
:nextText="'<i class=\'far fa-long-arrow-right \'></i>'"
:container-class="'pagination d-flex justify-content-center align-items-center flex-wrap mt-4'"
:page-class="'page-item'"
:page-link-class="'page-link'"
:next-class="'page-item'"
:prev-class="'page-item'"
:prev-link-class="'page-link'"
:next-link-class="'page-link'">
</paginate>
</div>
</div>
</div>
</section>
</template>
<script>
import Product from '../Products/Product';
import { isMobileOnly } from "mobile-device-detect";
import Paginate from 'vuejs-paginate'
export default {
created() {
this.MenuLiCount();
if (localStorage.url_filter == window.location) {
this.filters = JSON.parse(localStorage.filter);
} else {
localStorage.removeItem('url_filter');
localStorage.removeItem('filter');
}
let url = new URL(window.location.href);
let page = url.searchParams.get("page");
this.page_current = page;
if (this.page_current > 1) {
this.SendFilterParams()
}
},
props: {
productsData: {},
categoriesData: {},
loginInfo: {},
characteristicsData: {},
categoryData: {},
page: {}
},
components: {
'product-item': Product,
'paginate': Paginate
},
data() {
return {
products: this.productsData.data,
categories: this.categoriesData,
characteristics: this.characteristicsData,
category: this.categoryData,
filters: [],
orderby: 'all',
menu: 'three-li',
mobile: isMobileOnly ? true : false,
pageCount: this.productsData.last_page,
page_current: 1,
product_count: this.productsData.total,
paginate: false,
page_products: 12,
}
},
watch: {
filters: function (newVal) {
this.SendFilterParams();
localStorage.filter = JSON.stringify(this.filters);
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
PageCallBack(pageNum) {
this.page_current = pageNum;
window.scrollTo(0,0);
this.SendFilterParams();
},
async SendFilterParams() {
const fields = {
order_by: this.orderby,
filter: this.filters,
page: this.page,
paginate: this.page_products
};
const { data } = await axios.post('/category/filter/' + this.category.slug + '?page='+ this.page_current, fields);
localStorage.url_filter = window.location;
window.history.pushState({page: 1}, 'page', '?page=' + this.page_current);
// window.document.title = response.data.post.name
this.pageCount = data.page;
this.products = data.products;
this.product_count = data.count;
},
removeFilter(index) {
this.filters.splice(index, 1);
},
orderByChange(type) {
this.orderby = type;
this.SendFilterParams()
},
MenuLiCount() {
if (this.categories.length > 0 && this.characteristics.length > 0) {
this.menu = 'three-li';
} else if (this.categories.length === 0 ^ this.characteristics.length === 0) {
this.menu = 'two-li';
} else {
this.menu = 'one-li';
}
},
removeAllFilter() {
this.filters = [];
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,77 @@
<template>
<ul class="nav">
<li class="nav-item checkout">
<a href="/stocks" class="dropbtn"><span v-html="$t('vue.cat_sales')"></span></a>
</li>
<li class="nav-item" v-for="(category, index) in categories" @mouseover="category.hover = true" @mouseleave="category.hover = false">
<a :href="'/category/' + category.slug" class="dropbtn">
<span>
{{ getName(category.name) }}
</span>
</a>
<i class="fal fa-chevron-down"></i>
<div class="nav-item-content" v-if="category.hover"> <!--v-if="category.hover"-->
<div class="container">
<div class="row">
<div class="col-xl-2 col-lg-3 mb-lg-3 mb-1" v-for="(parent, index) in category.parents" v-if="parent.published">
<h3 class="nav-item-content__title">
<img v-if="parent.image" :src="'/' + parent.image">
<a :href="'/category/' + category.slug + '/' + parent.slug">
{{ getName(parent.name) }}
</a>
<i class="fal fa-plus"></i>
</h3>
<div class="nav-item-content__toggle">
<a v-for="(child, index) in parent.parents" :href="'/category/' + category.slug + '/' + parent.slug + '/' + child.slug" v-if="child.published">
{{ getName(child.name) }}
</a>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</template>
<script>
export default {
props: {
categoriesData: {}
},
data() {
return {
categories: this.categoriesData
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
// console.log(value);
return value;
},
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,723 @@
<template>
<div>
<section class="section-checkout">
<div class="container">
<h2 class="section-title">{{ $t('vue.cart.checkout_product') }}</h2>
<ul class="steps" :class="!login && step === 2 ? 'steps-two' : 'steps-three'">
<li class="steps-item">
<a href="/cart">
{{ $t('vue.cart.step_1') }}
</a>
</li>
<li class="steps-item">
<a href="javascript:void(0)" >
{{ $t('vue.cart.step_2') }}
</a>
</li>
<li class="steps-item">
<a href="javascript:void(0)" >
{{ $t('vue.cart.step_3') }}
</a>
</li>
</ul>
</div>
</section>
<section class="section-basket" v-if="step === 2">
<div class="container">
<div class="basket__footer">
<div class="col-md-5" v-if="user.step === 1">
<h4>{{ $t('app.auth.title') }}</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone" required>
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.next') }}
</button>
</div>
</form>
</div>
<div class="col-md-5" v-if="user.step === 2">
<h4 class="text-center">
{{ $t('vue.login.regg') }}
</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.enter_password')" v-model="user.password" id="password" required />
<label for="password">{{ $t('vue.login.password') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" :placeholder="$t('vue.login.re_password')" v-model="user.password_confirmation" id="login_password" required />
<label for="login_password">{{ $t('vue.login.re_password') }}</label>
</div>
<div class="mt-4 d-flex justify-content-between reply">
<div class="my-custom-control custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" checked id="customCheck" name="example1">
<label class="custom-control-label" for="customCheck" v-html="$t('vue.login.policy')">
</label>
</div>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.reg') }}
</button>
</div>
</form>
</div>
<div class="col-md-5" v-if="user.step === 3">
<h4 class="text-center">{{ $t('vue.login.regg') }}</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="text" :placeholder="$t('vue.login.enter_code')" v-model="user.verify" id="login_password" required />
<label for="login_password"> {{ $t('vue.login.code') }}</label>
</div>
<div class="text-danger mt-1" v-if="password_error">
{{ $t('vue.login.sms_empty') }}
</div>
<div class="mt-4 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.confirm') }}
</button>
</div>
</form>
</div>
<div class="col-md-5" v-if="user.step === 4">
<h4 class="text-center">
<h4>{{ $t('app.auth.title') }}</h4>
</h4>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="password" v-model="user.password" :placeholder="$t('vue.login.password')" id="login_password" required />
<label for="login_password"> {{ $t('vue.login.password') }}</label>
</div>
<div class="text-danger mt-1" v-if="password_error">
{{ $t('vue.login.pass_err') }}
</div>
<div class="mt-4 d-flex justify-content-between reply">
<div class="my-custom-control custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="remember" v-model="user.remember" name="remember">
<label class="custom-control-label" for="remember">
{{ $t('vue.login.remember') }}
</label>
</div>
<a href="#" @click="user.step = 5 " class="reset-password text-primary">
{{ $t('vue.login.restore') }}
</a>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('app.layout.login') }}
</button>
</div>
</form>
</div>
<div class="col-md-5" v-if="user.step === 5 || user.step === 6 || user.step === 7">
<h4 class="text-center">
{{ $t('vue.login.restore_pass') }}
</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group" v-if="user.step === 5 || user.step === 6 || user.step === 7 ">
<input type="tel" :placeholder="$t('app.auth.enter_phone')" disabled v-mask="'+998 (##) ###-##-##'" v-model="user.phone" id="login_phone">
<label for="login_phone">{{ $t('app.auth.phone') }}</label>
</div>
<div class="mt-4 my-form__group" v-if="user.step === 7">
<input type="password" :placeholder="$t('vue.login.new_password')" v-model="user.password" id="sss" required />
<label for="sss">
{{ $t('vue.login.new_password') }}
</label>
</div>
<div class="mt-4 my-form__group" v-if="user.step === 7">
<input type="password" :placeholder="$t('vue.login.new_re_password')" v-model="user.password_confirmation" id="new_re_password" required />
<label for="new_re_password">
{{ $t('vue.login.new_re_password') }}
</label>
</div>
<div class="mt-4 my-form__group" v-if="user.step === 6">
<input type="text" :placeholder="$t('vue.login.enter_code')" v-model="user.verify" id="login_password" required />
<label for="login_password">{{ $t('vue.login.code') }}</label>
</div>
<div class="text-danger mt-1" v-if="user.step === 6 && password_error">
{{ $t('vue.login.sms_empty') }}
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button v-if="user.step === 5" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.next') }}
</button>
<button v-if="user.step === 6" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.confirm') }}
</button>
<button v-if="user.step === 7" type="sumbit" class="my-btn my-btn__orange w-100">
{{ $t('vue.login.restore_confirm') }}
</button>
</div>
</form>
</div>
</div>
</div>
</section>
<section class="section-checkout" v-if="step === 3">
<div class="container">
<div class="col-12" v-if="!deliveryInfo && !pickupInfo">
<div class="row">
<div class="alert alert-info w-100">
<i class="fa fa-info-circle"></i> {{ $t('vue.checkout.no_ordered') }}
</div>
</div>
</div>
<form @submit.prevent="SendOrder" class="my-form my-form__checkout" v-if="pickupInfo || deliveryInfo">
<div class="row mb-5">
<div class="col-md-7">
<h3 class="mt-4 mb-3">{{ $t('vue.checkout.delivery_title') }}</h3>
<div class="form-payment">
<div class="custom-control custom-radio custom-control-inline" v-if="pickupInfo">
<input type="radio" class="custom-control-input" id="delivery1" name="delivery" v-model="order.delivery_type" value="pickup">
<label class="custom-control-label" for="delivery1">{{ $t('vue.checkout.delivery_pickup') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline" v-if="deliveryInfo">
<input type="radio" class="custom-control-input" id="delivery2" name="delivery" v-model="order.delivery_type" value="delivery">
<label class="custom-control-label" for="delivery2">{{ $t('vue.checkout.delivery_courier') }}</label>
</div>
</div>
<div v-if="order.delivery_type === 'delivery' && deliveryInfo">
<h3 class="mt-4 mb-3">{{ $t('vue.checkout.delivery_about') }}</h3>
<div class="row mb-3">
<div class="col-md-5 align-items-start justify-content-center d-flex flex-column">
<h4>{{ $t('vue.checkout.first_name') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<input type="text" placeholder="" required v-model="address.first_name" id="first_name">
</div>
</div>
<div class="row mb-3">
<div class="col-md-5 align-items-start justify-content-center d-flex flex-column">
<h4>{{ $t('vue.checkout.delivery_region') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<select name="regions" class="custom-select" @change="changeRegion($event)" v-model="address.region_id">
<option v-for="(region, index) in regions" :value="index" :selected="index === 0 ? 'selected' : false" >
{{ getName(region.name) }}
</option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-5 align-items-start justify-content-center d-flex flex-column">
<h4>{{ $t('vue.checkout.delivery_city') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<select name="cities" class="custom-select" v-model="address.city_id">
<option v-for="(city, index) in cities" :value="city.id" :selected="index === 0 ? 'selected' : false">
{{ getName(city.name) }}
</option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-md-5 align-items-start justify-content-center d-flex flex-column">
<h4>{{ $t('vue.checkout.delivery_address') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<input type="text" placeholder="" v-model="address.address" required id="your_address">
</div>
</div>
<div class="row mb-3">
<div class="col-md-5 align-items-start justify-content-center d-flex flex-column">
<h4>{{ $t('vue.checkout.delivery_additional_info') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<input type="text" placeholder="" v-mask="'+998 (##) ###-##-##'" v-model="address.other_phone" id="your_contact">
</div>
</div>
<div class="row mb-3">
<div class="col-md-5">
<h4>{{ $t('vue.checkout.delivery_cemments') }}</h4>
</div>
<div class="col-md-7 my-form__group">
<textarea cols="30" v-model="address.comment" rows="5"></textarea>
</div>
</div>
</div>
<div v-if="order.delivery_type === 'pickup' && pickupInfo">
<div class="alert alert-info" v-html="getName(pickupText)">
</div>
</div>
</div>
<div class="col-md-5" >
<div class="all_sum">
<div class="row mb-3 mb-md-0">
<div class="col-md-6 mb-md-2">
<span>{{ $t('vue.checkout.delivery_total_cost') }}</span>
</div>
<div class="col-md-6 text-md-right">
<span>{{ prices | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span>
</div>
</div>
<!-- <div class="row mb-3 mb-md-0">-->
<!-- <div class="col-md-6 mb-md-2">-->
<!-- <span>Промокод:</span>-->
<!-- <a href="#" class="d-block">Ввести другой промокод</a>-->
<!-- </div>-->
<!-- <div class="col-md-6 text-md-right">-->
<!-- <span>RY38990</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="row mb-3 mb-md-0">-->
<!-- <div class="col-md-6 mb-md-2">-->
<!-- <span>Скидка по промокоду:</span>-->
<!-- </div>-->
<!-- <div class="col-md-6 text-md-right">-->
<!-- <span>56 000 сум</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="row mb-3 mb-md-0" v-if="order.delivery_type === 'delivery' && deliveryInfo && order.delivery_price > 0">
<div class="col-md-6 mb-md-2">
<span>{{ $t('vue.checkout.delivery_price') }}:</span>
</div>
<div class="col-md-6 text-md-right">
<span>{{ order.delivery_price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span>
</div>
</div>
<div class="row mb-3 mb-md-0">
<div class="col-md-6 mb-md-2">
<span>{{ $t('vue.checkout.delivery_total_amount') }}:</span>
</div>
<div class="col-md-6 text-md-right">
<span>{{ order.delivery_type === 'delivery' ? prices + order.delivery_price : prices | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</span>
</div>
</div>
</div>
<h3 class="mt-4 mb-3">{{ $t('vue.checkout.delivery_about_price') }}</h3>
<div class="form-payment">
<div class="custom-control custom-radio custom-control-inline" v-if="cash">
<input type="radio" class="custom-control-input" id="payment-1" name="payment_type" value="cash" v-model="order.payment_type" checked="">
<label class="custom-control-label" for="payment-1">{{ $t('vue.checkout.delivery_in_cash') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="payment-2" value="apelsin" v-model="order.payment_type" name="payment_type">
<label class="custom-control-label" for="payment-2">Apelsin</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="payment-3" value="payme" v-model="order.payment_type" name="payment_type">
<label class="custom-control-label" for="payment-3">Payme</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="payment-4" value="click" v-model="order.payment_type" name="payment_type">
<label class="custom-control-label" for="payment-4">Click</label>
</div>
</div>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" v-if="error_type === 'available'" :key="index">
{{ error }}
</li>
<li v-for="(error, index) in errors" v-if="error_type === 'validation'" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<div class="d-flex justify-content-md-start justify-content-center">
<button type="sumbit" class="my-btn my-btn__orange">{{ $t('vue.cart.checkout_product') }}</button>
</div>
</div>
</div>
</form>
</div>
</section>
</div>
</template>
<script>
export default {
props: {
cartData: {},
loginInfo: {},
pricesData: {},
regionsData: {},
deliveryPrice: {},
pickupInfo: {},
deliveryInfo: {},
pickupText: {},
firstName: {},
addressData: {}
},
watch: {
'order.delivery_type': function (newVal, oldVal) {
this.order.delivery_type = newVal;
},
},
data() {
return {
user: {
phone: null,
verify: null,
password: null,
password_confirmation: null,
remember: false,
step: 1,
},
prices: this.pricesData,
address: {
first_name: this.firstName,
region_id: 0,
city_id: null,
address: this.addressData,
other_phone: null,
comment: null
},
order: {
delivery_type: this.deliveryInfo ? 'delivery' : 'pickup',
delivery_price: this.deliveryInfo ? this.deliveryPrice : 0,
payment_type: 'cash'
},
regions: this.regionsData,
cities: [],
verify: false,
step: this.loginInfo ? 3 : 2,
error: false,
errors: [],
error_type: null,
password_error: false,
cash: true,
login: this.loginInfo
}
},
mounted() {
this.cities = this.regions[0].cities;
this.address.city_id = this.cities[0] ? this.cities[0].id : null;
},
methods: {
async SendForm () {
if (this.user.step === 1) {
const { data } = await axios.post('/auth/login', {
phone: this.user.phone
});
this.user.step = data.step;
// this.verify = true;
} else if (this.user.step === 2) {
try {
const { data } = await axios.post('/auth/register', {
phone: this.user.phone,
password: this.user.password,
password_confirmation: this.user.password_confirmation,
});
this.user.step = data.step;
} catch (error) {
this.error = true;
this.errors = error.response.data.errors;
}
} else if (this.user.step === 3) {
try {
const { data } = await axios.post('/auth/verify', {
phone: this.user.phone,
code: this.user.verify,
//type: type,
//action: action
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
this.login = true;
this.step = 3;
this.error = false;
this.address.first_name = data.first_name;
this.address.address = data.address
}
} catch (error) {
this.password_error = true;
}
} else if (this.user.step === 4 ) {
try {
const { data } = await axios.post('/auth/password', {
phone: this.user.phone,
password: this.user.password,
//type: type,
//action: action,
remember: this.user.remember
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
this.login = true;
this.step = 3;
this.error = false;
this.address.first_name = data.first_name;
this.address.address = data.address
}
} catch (error) {
this.password_error = true;
}
} else if (this.user.step === 5) {
try {
const { data } = await axios.post('/auth/restore', {
phone: this.user.phone,
});
this.user.step = data.step;
} catch (error) {
}
} else if (this.user.step === 6) {
try {
const { data } = await axios.post('/auth/restore/verify', {
phone: this.user.phone,
code: this.user.verify
});
this.user.password = null;
this.user.password_confirmation = null;
this.user.step = data.step;
} catch (error) {
this.password_error = true;
}
} else if (this.user.step === 7) {
try {
const { data } = await axios.post('/auth/restore/confirm', {
phone: this.user.phone,
password: this.user.password,
password_confirmation: this.user.password_confirmation,
//type: type,
//action: action
//credit: this.$cookie.get('product-credit') ? this.$cookie.get('product-credit') : null,
});
if (data.status) {
this.login = true;
this.step = 3;
this.error = false;
this.address.first_name = data.first_name;
this.address.address = data.address
}
} catch (error) {
this.error = true;
this.errors = error.response.data.errors;
}
}
},
// async LoginSend() {
// if (!this.verify) {
// const { data } = await axios.post('/auth/login', {
// phone: this.user.phone
// });
//
// this.verify = true;
// } else {
//
// try {
// const { data } = await axios.post('/auth/verify', this.user);
// if (data.status) {
// this.login = true;
// this.step = 3;
// this.error = false;
// this.address.first_name = data.first_name;
// this.address.address = data.address
// }
// } catch (error) {
// this.error = true;
// }
// }
// },
async Resend () {
if (this.verify) {
await axios.post('/api/auth/login', {
phone: this.user.phone
});
}
},
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async SendOrder() {
var product_id = [];
for (var i = 0; i < this.cartData.length; i++) {
product_id.push(this.cartData[i].id);
}
const fields = {
delivery_type: this.order.delivery_type,
delivery_price: this.order.delivery_price,
payment_type: this.order.payment_type,
products: product_id,
address: this.address,
};
try {
const { data } = await axios.post('/checkout', fields);
if (data.status) {
window.location.href = data.url
} else {
this.error = true;
this.errors = data.errors;
this.error_type = 'available';
}
} catch (err) {
if (err.response.status === 422) {
this.error = true;
this.errors = err.response.data.errors;
this.error_type = 'validation';
}
}
},
changeRegion(event) {
let index = parseInt(event.target.value);
this.cash = this.regions[index].cash;
if (this.cash) {
this.order.payment_type = 'cash'
} else {
this.order.payment_type = 'payme'
}
this.cities = this.regions[index].cities;
this.address.city_id = this.cities[0] ? this.cities[0].id : null;
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,27 @@
<template>
<div class="media msg">
<div class="media-body">
<small class="pull-right time">
<i class="fas fa-calendar-alt mr-2"></i> {{ comment.created_at }}
</small>
<h5 class="media-heading">{{ comment.first_name }}</h5>
<small v-html="comment.body"></small>
</div>
</div>
</template>
<script>
export default {
props: ['commentData'],
data() {
return {
comment: this.commentData
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,224 @@
<template>
<div>
<div class="col-md-12 col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Добавить</h4>
</div>
<div class="card-content">
<form class="form form-vertical" @submit.prevent="Store">
<div class="card-body">
<div class="form-body">
<p>Все поля обозначенные * обязательные</p>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="ru">Названия RU *</label>
<input type="text" id="ru" class="form-control" v-model="title.ru"placeholder="Названия RU *">
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="uz">Названия UZ *</label>
<input type="text" id="uz" class="form-control" v-model="title.uz" placeholder="Названия UZ *">
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label for="category">Категория</label>
<select id="category" class="form-control" v-model="category_id">
<option value="0">Все</option>
<option v-for="category in categories" :value="category.id">
{{ category.name.ru }}
</option>
</select>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label>Продукты *</label>
<multiselect v-model="compilations"
placeholder="Искать"
label="name"
track-by="name"
:options="products"
:option-height="104"
:custom-label="customLabel"
:show-labels="false"
@search-change="SearchProduct"
:multiple="true"
>
<template slot="singleLabel" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<span class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</span>
</template>
<template slot="option" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<div class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</div>
</template>
</multiselect>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label>Выбранные продукты</label>
<div class="table-responsive">
<table class="table">
<tbody>
<tr v-for="(product, index) in compilations">
<td>
<img :src="product.poster" width="100" >
</td>
<td>
{{ product.name }}
</td>
<td>
<button type="button" @click="Delete(index)" class="btn btn-danger btn-sm btn-icon">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- <div class="col-12">-->
<!-- <fieldset>-->
<!-- <div class="vs-checkbox-con vs-checkbox-primary">-->
<!-- <input type="checkbox" v-model="published">-->
<!-- <span class="vs-checkbox">-->
<!-- <span class="vs-checkbox&#45;&#45;check">-->
<!-- <i class="vs-icon feather icon-check"></i>-->
<!-- </span>-->
<!-- </span>-->
<!-- <span class="">Публиковать</span>-->
<!-- </div>-->
<!-- </fieldset>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card-footer">
<div class="col-12 mb-0">
<div class="row">
<div class="col-3">
<button type="submit" class="btn btn-primary mr-1 mb-1 waves-effect waves-light btn-icon">
<i class="feather icon-save"></i> {{ $t('admin.save') }}
</button>
</div>
<div class="col-9">
<a href="/dashboard/compilations" class="btn btn-danger mr-1 mb-1 waves-effect waves-light btn-icon pull-right">
<i class="feather icon-x-circle"></i> {{ $t('admin.cancel') }}
</a>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['categories'],
data: () => ({
title: {
ru: null,
uz: null
},
products: [],
published: false,
category_id: null,
compilations: [],
}),
mounted() {
},
methods: {
customLabel ({ name }) {
return `${name}`
},
async Store() {
const array = {
title: this.title,
products: this.compilations,
published: this.published,
category_id: this.category_id
};
const { data } = await axios.post('/dashboard/compilations/store', array);
if (data.status) {
window.location.href = "/dashboard/compilations";
}
},
async SearchProduct(query) {
let name = query;
if (name.length > 0) {
axios.post('/dashboard/compilations/product/search', { name: name})
.then((response) => {
if (response.data.status) {
this.products = response.data.products;
}
}).catch((error) => {
if (error.response) {
this.error = true;
this.errors = error.response.data.errors;
}
});
}
console.log(query);
},
Delete(index) {
this.compilations.splice(index, 1);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,225 @@
<template>
<div>
<div class="col-md-12 col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Добавить</h4>
</div>
<div class="card-content">
<form class="form form-vertical" @submit.prevent="Update">
<div class="card-body">
<div class="form-body">
<p>Все поля обозначенные * обязательные</p>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="ru">Названия RU *</label>
<input type="text" id="ru" class="form-control" v-model="title.ru"placeholder="Названия RU *">
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="uz">Названия UZ *</label>
<input type="text" id="uz" class="form-control" v-model="title.uz" placeholder="Названия UZ *">
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label for="category">Категория</label>
<select id="category" class="form-control" v-model="category_id">
<option value="0">Все</option>
<option v-for="category in categories" :value="category.id">
{{ category.name.ru }}
</option>
</select>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label>Продукты *</label>
<multiselect v-model="compilations"
placeholder="Искать"
label="name"
track-by="name"
:options="products"
:option-height="104"
:custom-label="customLabel"
:show-labels="false"
@search-change="SearchProduct"
:multiple="true"
>
<template slot="singleLabel" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<span class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</span>
</template>
<template slot="option" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<div class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</div>
</template>
</multiselect>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label>Выбранные продукты</label>
<div class="table-responsive">
<table class="table">
<tbody>
<tr v-for="(product, index) in compilations">
<td>
<img :src="product.poster" width="100" >
</td>
<td>
{{ product.name }}
</td>
<td>
<a href="#" @click="Delete(index)" class="btn btn-danger btn-sm btn-icon">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- <div class="col-12">-->
<!-- <fieldset>-->
<!-- <div class="vs-checkbox-con vs-checkbox-primary">-->
<!-- <input type="checkbox" v-model="published">-->
<!-- <span class="vs-checkbox">-->
<!-- <span class="vs-checkbox&#45;&#45;check">-->
<!-- <i class="vs-icon feather icon-check"></i>-->
<!-- </span>-->
<!-- </span>-->
<!-- <span class="">Публиковать</span>-->
<!-- </div>-->
<!-- </fieldset>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card-footer">
<div class="col-12 mb-0">
<div class="row">
<div class="col-3">
<button type="submit" class="btn btn-primary mr-1 mb-1 waves-effect waves-light btn-icon">
<i class="feather icon-save"></i> {{ $t('admin.save') }}
</button>
</div>
<div class="col-9">
<a href="/dashboard/compilations" class="btn btn-danger mr-1 mb-1 waves-effect waves-light btn-icon pull-right">
<i class="feather icon-x-circle"></i> {{ $t('admin.cancel') }}
</a>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
compilation: {},
categories: {}
},
data: function() {
return {
title: {
ru: this.compilation.title.ru,
uz: this.compilation.title.uz,
},
published: this.compilation.published,
compilations: this.compilation.products,
category_id: this.compilation.category_id,
products: []
}
},
mounted() {
},
methods: {
customLabel ({ name }) {
return `${name}`
},
async Update() {
const array = {
title: this.title,
products: this.compilations,
published: this.published,
category_id: this.category_id
};
const { data } = await axios.post('/dashboard/compilations/update/' + this.compilation.id, array);
if (data.status) {
window.location.href = "/dashboard/compilations";
}
},
async SearchProduct(query) {
let name = query;
if (name.length > 0) {
axios.post('/dashboard/compilations/product/search', { name: name})
.then((response) => {
if (response.data.status) {
this.products = response.data.products;
}
}).catch((error) => {
if (error.response) {
this.error = true;
this.errors = error.response.data.errors;
}
});
}
console.log(query);
},
Delete(index) {
this.compilations.splice(index, 1);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,306 @@
<template>
<div class="row">
<div class="col-12">
<div
class="card"
style="
border-radius: 0;
box-shadow: 0 -1px 4px 0 rgb(0 0 0 / 15%);
"
>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="">Категория</label>
<select
v-model="category"
@change="handleMainCategory"
class="form-control"
>
<option :value="null">---</option>
<option
v-for="category in mainCategories"
:value="category"
>
{{ category.category }}
</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="">Подкатегория</label>
<select
v-model="subCategory"
@change="handleSubCategory"
class="form-control"
>
<option :value="null">---</option>
<option
v-for="category in subCategories"
:value="category"
>
{{ category.category }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
<Tree
:data="categories"
@change="Change"
draggable="draggable"
cross-tree="cross-tree"
>
<div slot-scope="{ data, store }">
<template v-if="!data.isDragPlaceHolder">
<div class="d-flex justify-content-start">
<b
v-if="data.children &amp;&amp; data.children.length"
@click="store.toggleOpen(data)"
>
<i
:class="
data.open
? 'fa fa-minus-square'
: 'fa fa-plus-square'
"
></i>
&nbsp;
</b>
<span>
<b>ID: {{ data.id }} </b>
{{ data.category }}
</span>
<div class="ml-auto">
<a
:href="
'/dashboard/categories/update/' +
data.id
"
class="btn-primary btn btn-icon btn-sm"
>
<i class="fa fa-edit"></i>
</a>
<a
:href="
'/dashboard/categories/delete/' +
data.id
"
onclick="return confirm('Вы действително хотите удалить')"
class="btn-danger btn btn-icon btn-sm"
>
<i class="fa fa-trash"></i>
</a>
</div>
</div>
</template>
</div>
</Tree>
<div class="mt-2 mb-3">
<button class="btn btn-primary" @click="SendForm">
<i class="fa fa-save"></i> Сохранить
</button>
</div>
</div>
</div>
</template>
<script>
import { DraggableTree } from "vue-draggable-nested-tree";
export default {
props: {
categoriesData: {},
},
components: {
Tree: DraggableTree,
},
mounted() {
console.log(this.categoriesData);
this.Change();
},
data() {
console.log(this.categoriesData);
return {
categories: this.categoriesData,
mainCategories: this.categoriesData,
subCategories: [],
category: null,
subCategory: null,
};
},
methods: {
async SendForm() {
const formData = new FormData();
for (var i = 0; i < this.categories.length; i++) {
formData.append(
"categories[" + i + "][id]",
this.categories[i].id
);
formData.append(
"categories[" + i + "][position]",
this.categories[i].position
);
formData.append(
"categories[" + i + "][parent_id]",
this.categories[i].parent_id
);
if (this.categories[i].children.length > 0) {
for (
var c = 0;
c < this.categories[i].children.length;
c++
) {
formData.append(
"categories[" + i + "][children][" + c + "][id]",
this.categories[i].children[c].id
);
formData.append(
"categories[" +
i +
"][children][" +
c +
"][position]",
this.categories[i].children[c].position
);
formData.append(
"categories[" +
i +
"][children][" +
c +
"][parent_id]",
this.categories[i].children[c].parent_id
);
if (
this.categories[i].children[c].children.length > 0
) {
for (
var w = 0;
w <
this.categories[i].children[c].children.length;
w++
) {
formData.append(
"categories[" +
i +
"][children][" +
c +
"][children][" +
w +
"][id]",
this.categories[i].children[c].children[w]
.id
);
formData.append(
"categories[" +
i +
"][children][" +
c +
"][children][" +
w +
"][position]",
this.categories[i].children[c].children[w]
.position
);
formData.append(
"categories[" +
i +
"][children][" +
c +
"][children][" +
w +
"][parent_id]",
this.categories[i].children[c].children[w]
.parent_id
);
}
}
}
}
}
const { data } = await axios.post(
"/dashboard/categories/position",
formData
);
if (data.status) {
// window.location.href = "/dashboard/categories";
}
},
Change() {
for (var i = 0; i < this.categories.length; i++) {
var num = i + 1;
this.categories[i].position = num;
this.categories[i].droppable = true;
if (this.categories[i].children.length > 0) {
for (
var c = 0;
c < this.categories[i].children.length;
c++
) {
var numm = c + 1;
this.categories[i].children[c].position = numm;
this.categories[i].children[c].parent_id =
this.categories[i].id;
this.categories[i].children[c].droppable = true;
if (
this.categories[i].children[c].children.length > 0
) {
for (
var w = 0;
w <
this.categories[i].children[c].children.length;
w++
) {
var nummm = w + 1;
this.categories[i].children[c].children[
w
].position = nummm;
this.categories[i].children[c].children[
w
].parent_id = this.categories[i].children[c].id;
this.categories[i].children[c].children[
w
].droppable = false;
}
}
}
}
}
},
handleMainCategory() {
if (this.category) {
this.categories = this.category.children;
this.subCategories = this.category.children;
} else {
this.categories = this.categoriesData;
this.subCategories = null;
}
},
handleSubCategory() {
if (this.subCategory) this.categories = this.subCategory.children;
else this.categories = this.category.children;
},
},
};
</script>
<style scoped></style>

View File

@@ -0,0 +1,821 @@
<template>
<div class="row">
<form
class="form form-vertical w-100"
@submit.prevent="saveForm"
action="#"
enctype="multipart/form-data"
method="post"
>
<div class="col-md-12 col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">{{ $t("admin.add") }}</h4>
</div>
<div class="card-content">
<div class="card-body">
<div class="form-body">
<p>{{ $t("admin.all_fields_with") }}</p>
<div class="row">
<div class="col-12">
<div class="row">
<div class="col-6">
<div class="form-group">
<label
for="first-name-vertical"
>{{
$t(
"admin.categories.name"
)
}}
UZ *</label
>
<input
type="text"
id="first-name-vertical"
v-model="
category.name.uz
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' UZ'
"
/>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="nameru"
>{{
$t(
"admin.categories.name"
)
}}
RU *</label
>
<input
type="text"
id="nameru"
required
v-model="
category.name.ru
"
class="form-control"
name="name[ru]"
:placeholder="
$t(
'admin.categories.name'
) + ' RU'
"
/>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label for="position"
>{{
$t(
"admin.categories.position"
)
}}
*</label
>
<input
type="text"
id="position"
required
class="form-control"
v-model="category.position"
name="position"
:placeholder="
$t(
'admin.categories.position'
)
"
/>
</div>
<div class="form-group">
<div class="custom-file">
<input
id="uploadImage"
class="custom-file-input"
type="file"
name="image"
@change="ImageFile($event)"
onchange="PreviewImage();"
/>
<label
class="custom-file-label"
>{{
$t(
"admin.categories.image"
)
}}</label
>
</div>
<br />
<div class="text-center">
<img
id="uploadPreview"
style="
width: 300px;
height: auto;
"
/>
</div>
</div>
<div class="form-group">
<label
>{{
$t("admin.brands.title")
}}
*</label
>
<multiselect
:options="brandsData"
v-model="category.brands"
:multiple="true"
:taggable="true"
label="name"
track-by="name"
></multiselect>
</div>
<div class="col-12">
<div class="row">
<h3>Характеристики</h3>
</div>
</div>
<div class="row">
<div
class="col-12"
v-for="(char, index) in char"
:key="index"
>
<div class="row">
<div class="col-4">
<div class="form-group">
<label
:for="
'first-name-vertical-uz' +
index
"
>{{
$t(
"admin.categories.char.name"
)
}}
UZ *</label
>
<input
type="text"
:id="
'first-name-vertical-uz' +
index
"
v-model="
char.name.uz
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' UZ'
"
/>
</div>
</div>
<div class="col-4">
<div class="form-group">
<label
:for="
'first-name-vertical-ru' +
index
"
>{{
$t(
"admin.categories.char.name"
)
}}
RU *</label
>
<input
type="text"
:id="
'first-name-vertical-ru' +
index
"
v-model="
char.name.ru
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' RU'
"
/>
</div>
</div>
<div class="col-2">
<div class="form-group">
<label
:for="
'type' +
index
"
>{{
$t(
"admin.categories.char.type"
)
}}
*</label
>
<select
class="form-control"
:id="
'type' +
index
"
v-model="
char.type
"
>
<option
value="text"
>
Text
</option>
<option
value="number"
>
Number
</option>
<option
value="checkbox"
>
checkbox
</option>
<option
value="select"
>
select
</option>
</select>
</div>
</div>
<div class="col-1">
<fieldset>
<label
>Фильтр</label
>
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
v-model="
char.filter
"
/>
<span
class="vs-checkbox"
>
<span
class="vs-checkbox--check"
>
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
</div>
</fieldset>
</div>
<div class="col-1">
<button
@click="
removeChar(
index
)
"
class="btn btn-danger mt-2"
type="button"
>
<i
class="fa fa-trash"
></i>
</button>
</div>
</div>
</div>
</div>
<button
type="button"
class="btn btn-warning"
@click="addChar"
>
<i class="fa fa-plus"></i> Добавить
характеристики
</button>
<div class="controls mt-1">
<button
id="add_cat"
type="button"
class="btn btn-outline-primary w-100"
>
{{
$t(
"admin.categories.add_cat"
)
}}
</button>
<button
id="remove_cat"
type="button"
class="btn btn-secondary w-100"
>
{{
$t(
"admin.categories.remove_cat"
)
}}
</button>
<br />
<br />
<div id="sub_cat" class="controls">
<label>{{
$t(
"admin.categories.sub_category"
)
}}</label>
<select
class="form-control"
v-model="category.parent_id"
>
<option value="0">
{{
$t(
"admin.categories.choose_cat"
)
}}
</option>
<option
v-for="(
category, index
) in categoriesData"
:key="index"
:value="category.id"
>
{{
getName(
category.name
)
}}
<span
v-if="
category.parent
"
>
(
{{
getName(
category
.parent
.name
)
}}
)
</span>
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">SEO</h4>
</div>
<div class="card-content">
<div class="card-body">
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="nameru"
>Title Seo RU *</label
>
<input
type="text"
v-model="category.title_seo.ru"
id="nameru"
class="form-control"
placeholder="Title Seo RU *"
/>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="name">Title Seo UZ *</label>
<input
type="text"
v-model="category.title_seo.uz"
id="name"
class="form-control"
placeholder="Title Seo UZ *"
/>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.keywords.ru
"
id="label-keywords-ru"
rows="3"
:placeholder="
$t(
'admin.settings.keywords'
) + ' RU'
"
></textarea>
<label for="label-keywords-ru"
>{{
$t(
"admin.settings.keywords"
)
}}
RU *</label
>
</fieldset>
</div>
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.keywords.uz
"
id="label-keywords"
rows="3"
:placeholder="
$t(
'admin.settings.keywords'
) + ' UZ'
"
></textarea>
<label for="label-keywords"
>{{
$t(
"admin.settings.keywords"
)
}}
UZ *</label
>
</fieldset>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.descriptions.ru
"
id="label-description-ru"
rows="3"
:placeholder="
$t(
'admin.settings.description'
) + ' RU'
"
></textarea>
<label
for="label-description-ru"
>{{
$t(
"admin.settings.description"
)
}}
RU *</label
>
</fieldset>
</div>
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.descriptions.uz
"
id="label-description"
rows="3"
:placeholder="
$t(
'admin.settings.description'
) + ' UZ'
"
></textarea>
<label for="label-description"
>{{
$t(
"admin.settings.description"
)
}}
UZ *</label
>
</fieldset>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12" v-if="error">
<div class="alert alert-danger mt-2">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-content">
<div class="card-body">
<div class="form-group mt-1">
<fieldset class="checkbox">
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
value="1"
name="popular"
v-model="category.published"
/>
<span class="vs-checkbox">
<span class="vs-checkbox--check">
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
<span class=""> Опубликовать </span>
</div>
</fieldset>
<fieldset class="checkbox">
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
value="1"
name="is_filter_power"
v-model="category.is_filter_power"
/>
<span class="vs-checkbox">
<span class="vs-checkbox--check">
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
<span class="">
Сортировать по kW
</span>
</div>
</fieldset>
</div>
</div>
<div class="card-footer pb-0 pl-0 pt-1">
<div class="col-12 mb-0">
<div class="row">
<div class="col-3">
<button
type="submit"
class="btn btn-primary mr-1 mb-1 waves-effect waves-light btn-icon"
>
<i class="feather icon-save"></i>
{{ $t("admin.save") }}
</button>
</div>
<div class="col-9">
<a
href="/dashboard/categories"
class="btn btn-danger mr-1 mb-1 waves-effect waves-light btn-icon pull-right"
>
<i
class="feather icon-x-circle"
></i>
{{ $t("admin.cancel") }}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
export default {
props: ["brandsData", "categoriesData"],
data() {
return {
category: {
name: {
uz: "",
ru: "",
},
published: true,
position: 0,
brands: [],
is_filter_power: false,
parent_id: 0,
descriptions: {
uz: "",
ru: "",
},
keywords: {
uz: "",
ru: "",
},
title_seo: {
uz: "",
ru: "",
},
image: null,
},
char: [],
error: false,
errors: [],
};
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = "";
if (lang) {
switch (lang) {
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async saveForm() {
const header = {
headers: {
"Content-Type": "multipart/form-data",
},
};
const formData = new FormData();
formData.append("name[ru]", this.category.name.ru);
formData.append("name[uz]", this.category.name.uz);
formData.append("position", this.category.position);
formData.append("parent_id", this.category.parent_id);
if (this.category.image)
formData.append("image", this.category.image);
formData.append("published", this.category.published);
formData.append("is_filter_power", this.category.is_filter_power);
formData.append("descriptions[ru]", this.category.descriptions.ru);
formData.append("descriptions[uz]", this.category.descriptions.uz);
formData.append("keywords[ru]", this.category.keywords.ru);
formData.append("keywords[uz]", this.category.keywords.uz);
formData.append("title_seo[ru]", this.category.title_seo.ru);
formData.append("title_seo[uz]", this.category.title_seo.uz);
for (var i = 0; i < this.category.brands.length; i++) {
formData.append(
"brands[" + i + "]",
this.category.brands[i].id
);
}
for (var i = 0; i < this.char.length; i++) {
formData.append(
"char[" + i + "][name][ru]",
this.char[i].name.ru
);
formData.append(
"char[" + i + "][name][uz]",
this.char[i].name.uz
);
formData.append("char[" + i + "][type]", this.char[i].type);
formData.append("char[" + i + "][filter]", this.char[i].filter);
}
axios
.post("/dashboard/categories/store", formData, header)
.then((response) => {
if (response.data.status) {
window.location.href = "/dashboard/categories";
}
})
.catch((error) => {
if (error.response) {
this.error = true;
this.errors = error.response.data.errors;
}
});
},
ImageFile(event) {
this.category.image = event.target.files[0];
},
addChar() {
this.char.push({
name: {
ru: "",
uz: "",
},
type: "text",
filter: false,
});
},
removeChar(index) {
this.char.splice(index, 1);
},
},
};
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style scoped></style>

View File

@@ -0,0 +1,836 @@
<template>
<div class="row">
<form
class="form form-vertical w-100"
@submit.prevent="saveForm"
action="#"
enctype="multipart/form-data"
method="post"
>
<div class="col-md-12 col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">{{ $t("admin.edit") }}</h4>
</div>
<div class="card-content">
<div class="card-body">
<div class="form-body">
<p>{{ $t("admin.all_fields_with") }}</p>
<div class="row">
<div class="col-12">
<div class="row">
<div class="col-6">
<div class="form-group">
<label
for="first-name-vertical"
>{{
$t(
"admin.categories.name"
)
}}
UZ *</label
>
<input
type="text"
id="first-name-vertical"
v-model="
category.name.uz
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' UZ'
"
/>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="nameru"
>{{
$t(
"admin.categories.name"
)
}}
RU *</label
>
<input
type="text"
id="nameru"
required
v-model="
category.name.ru
"
class="form-control"
name="name[ru]"
:placeholder="
$t(
'admin.categories.name'
) + ' RU'
"
/>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<label for="position"
>{{
$t(
"admin.categories.position"
)
}}
*</label
>
<input
type="text"
id="position"
required
class="form-control"
v-model="category.position"
name="position"
:placeholder="
$t(
'admin.categories.position'
)
"
/>
</div>
<div class="form-group">
<div class="custom-file">
<input
id="uploadImage"
class="custom-file-input"
type="file"
name="image"
@change="ImageFile($event)"
onchange="PreviewImage();"
/>
<label
class="custom-file-label"
>{{
$t(
"admin.categories.image"
)
}}</label
>
</div>
<br />
<div class="text-center">
<img
id="uploadPreview"
style="
width: 300px;
height: auto;
"
:src="category.image"
/>
</div>
</div>
<div class="form-group">
<label
>{{
$t("admin.brands.title")
}}
*</label
>
<multiselect
:options="brandsData"
v-model="category.brands"
:multiple="true"
:taggable="true"
label="name"
track-by="name"
></multiselect>
</div>
<div class="col-12">
<div class="row">
<h3>Характеристики</h3>
</div>
</div>
<div class="row">
<div
class="col-12"
v-for="(
char, index
) in category.characteristics"
:key="index"
>
<div class="row">
<div class="col-4">
<div class="form-group">
<label
:for="
'first-name-vertical-uz' +
index
"
>{{
$t(
"admin.categories.char.name"
)
}}
UZ *</label
>
<input
type="text"
:id="
'first-name-vertical-uz' +
index
"
v-model="
char.name.uz
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' UZ'
"
/>
</div>
</div>
<div class="col-4">
<div class="form-group">
<label
:for="
'first-name-vertical-ru' +
index
"
>{{
$t(
"admin.categories.char.name"
)
}}
RU *</label
>
<input
type="text"
:id="
'first-name-vertical-ru' +
index
"
v-model="
char.name.ru
"
required
class="form-control"
name="name[uz]"
:placeholder="
$t(
'admin.categories.name'
) + ' RU'
"
/>
</div>
</div>
<div class="col-2">
<div class="form-group">
<label
:for="
'type' +
index
"
>{{
$t(
"admin.categories.char.type"
)
}}
*</label
>
<select
class="form-control"
:id="
'type' +
index
"
v-model="
char.type
"
>
<option
value="text"
>
Text
</option>
<option
value="number"
>
Number
</option>
<option
value="checkbox"
>
checkbox
</option>
<option
value="select"
>
select
</option>
</select>
</div>
</div>
<div class="col-1">
<fieldset>
<label
>Фильтр</label
>
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
v-model="
char.filter
"
/>
<span
class="vs-checkbox"
>
<span
class="vs-checkbox--check"
>
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
</div>
</fieldset>
</div>
<div class="col-1">
<button
@click="
removeChar(
index,
char
)
"
class="btn btn-danger mt-2"
type="button"
>
<i
class="fa fa-trash"
></i>
</button>
</div>
</div>
</div>
</div>
<button
type="button"
class="btn btn-warning"
@click="addChar"
>
<i class="fa fa-plus"></i> Добавить
характеристики
</button>
<div class="controls mt-1">
<button
id="add_cat"
type="button"
class="btn btn-outline-primary w-100"
>
{{
$t(
"admin.categories.add_cat"
)
}}
</button>
<button
id="remove_cat"
type="button"
class="btn btn-secondary w-100"
>
{{
$t(
"admin.categories.remove_cat"
)
}}
</button>
<br />
<br />
<div id="sub_cat" class="controls">
<label>{{
$t(
"admin.categories.sub_category"
)
}}</label>
<select
class="form-control"
v-model="category.parent_id"
>
<option value="0">
{{
$t(
"admin.categories.choose_cat"
)
}}
</option>
<option
v-for="(
category, index
) in categoriesData"
:key="index"
:value="category.id"
>
{{
getName(
category.name
)
}}
<span
v-if="
category.parent
"
>
(
{{
getName(
category
.parent
.name
)
}}
)
</span>
</option>
</select>
</div>
</div>
</div>
<div class="col-12" v-if="error">
<div class="alert alert-danger mt-2">
<ul>
<li
v-for="(
error, index
) in errors"
:key="index"
>
<span
v-for="msg in error"
:key="msg"
>
{{ msg }}
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">SEO</h4>
</div>
<div class="card-content">
<div class="card-body">
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="nameru"
>Title Seo RU *</label
>
<input
type="text"
v-model="category.title_seo.ru"
id="nameru"
class="form-control"
placeholder="Title Seo RU *"
/>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="name">Title Seo UZ *</label>
<input
type="text"
v-model="category.title_seo.uz"
id="name"
class="form-control"
placeholder="Title Seo UZ *"
/>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.keywords.ru
"
id="label-keywords-ru"
rows="3"
:placeholder="
$t(
'admin.settings.keywords'
) + ' RU'
"
></textarea>
<label for="label-keywords-ru"
>{{
$t(
"admin.settings.keywords"
)
}}
RU *</label
>
</fieldset>
</div>
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.keywords.uz
"
id="label-keywords"
rows="3"
:placeholder="
$t(
'admin.settings.keywords'
) + ' UZ'
"
></textarea>
<label for="label-keywords"
>{{
$t(
"admin.settings.keywords"
)
}}
UZ *</label
>
</fieldset>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.descriptions.ru
"
id="label-description-ru"
rows="3"
:placeholder="
$t(
'admin.settings.description'
) + ' RU'
"
></textarea>
<label
for="label-description-ru"
>{{
$t(
"admin.settings.description"
)
}}
RU *</label
>
</fieldset>
</div>
<div class="col-md-6 float-left">
<fieldset class="form-label-group">
<textarea
class="form-control"
v-model="
category.descriptions.uz
"
id="label-description"
rows="3"
:placeholder="
$t(
'admin.settings.description'
) + ' UZ'
"
></textarea>
<label for="label-description"
>{{
$t(
"admin.settings.description"
)
}}
UZ *</label
>
</fieldset>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-content">
<div class="card-body">
<div class="form-group">
<fieldset class="checkbox">
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
value="1"
name="popular"
v-model="category.published"
/>
<span class="vs-checkbox">
<span class="vs-checkbox--check">
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
<span class=""> Опубликовать </span>
</div>
</fieldset>
<fieldset class="checkbox">
<div
class="vs-checkbox-con vs-checkbox-primary"
>
<input
type="checkbox"
value="1"
name="is_filter_power"
v-model="category.is_filter_power"
/>
<span class="vs-checkbox">
<span class="vs-checkbox--check">
<i
class="vs-icon feather icon-check"
></i>
</span>
</span>
<span class="">
Сортировать по kW
</span>
</div>
</fieldset>
</div>
</div>
</div>
<div class="card-footer pb-0 pl-0 pt-1">
<div class="col-12 mb-0">
<div class="row">
<div class="col-3">
<button
type="submit"
class="btn btn-primary mr-1 mb-1 waves-effect waves-light btn-icon"
>
<i class="feather icon-save"></i>
{{ $t("admin.save") }}
</button>
</div>
<div class="col-9">
<a
href="/dashboard/categories"
class="btn btn-danger mr-1 mb-1 waves-effect waves-light btn-icon pull-right"
>
<i class="feather icon-x-circle"></i>
{{ $t("admin.cancel") }}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
export default {
props: {
brandsData: {},
categoriesData: {},
categoryData: {},
},
data() {
return {
category: this.categoryData,
char: [],
file: null,
error: false,
errors: [],
deleted: {
char: [],
},
};
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = "";
if (lang) {
switch (lang) {
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async saveForm() {
const header = {
headers: {
"Content-Type": "multipart/form-data",
},
};
const formData = new FormData();
formData.append("name[ru]", this.category.name.ru);
formData.append("name[uz]", this.category.name.uz);
formData.append("position", this.category.position);
//formData.append('brands', this.category.brands);
formData.append("parent_id", this.category.parent_id);
formData.append("published", this.category.published);
formData.append("is_filter_power", this.category.is_filter_power);
formData.append("image", this.file);
formData.append("descriptions[ru]", this.category.descriptions.ru);
formData.append("descriptions[uz]", this.category.descriptions.uz);
formData.append("keywords[ru]", this.category.keywords.ru);
formData.append("keywords[uz]", this.category.keywords.uz);
formData.append("title_seo[ru]", this.category.title_seo.ru);
formData.append("title_seo[uz]", this.category.title_seo.uz);
for (var i = 0; i < this.category.brands.length; i++) {
formData.append(
"brands[" + i + "]",
this.category.brands[i].id
);
}
for (var i = 0; i < this.category.characteristics.length; i++) {
formData.append(
"char[" + i + "][name][ru]",
this.category.characteristics[i].name.ru
);
formData.append(
"char[" + i + "][name][uz]",
this.category.characteristics[i].name.uz
);
formData.append(
"char[" + i + "][type]",
this.category.characteristics[i].type
);
formData.append(
"char[" + i + "][filter]",
this.category.characteristics[i].filter
);
formData.append(
"char[" + i + "][id]",
this.category.characteristics[i].id
);
}
for (let i = 0; i < this.deleted.char.length; i++) {
formData.append(
"deletes[char][" + i + "]",
this.deleted.char[i]
);
}
axios
.post(
"/dashboard/categories/update/" + this.category.id,
formData,
header
)
.then((response) => {
if (response.data.status) {
window.location.href = "/dashboard/categories";
}
})
.catch((error) => {
if (error.response) {
this.error = true;
this.errors = error.response.data.errors;
}
});
},
ImageFile(event) {
this.file = event.target.files[0];
},
addChar() {
this.category.characteristics.push({
id: null,
name: {
ru: "",
uz: "",
},
type: "text",
filter: false,
});
},
removeChar(index, char) {
if (char.id != null) this.deleted.char.push(char.id);
this.category.characteristics.splice(index, 1);
},
},
};
</script>
<style scoped></style>

View File

@@ -0,0 +1,533 @@
<template>
<div>
<ul class="activity-timeline timeline-left list-unstyled" :key="index">
<!-- v-if="log.log_name != 'products' && log.decription != 'created' && log.properties.attributes.name != null"-->
<li v-for="(log, index) in logs" :key="index">
<div class="timeline-icon bg-primary" v-if="log.description == 'updated'">
<i class="feather icon-edit font-medium-2 align-middle"></i>
</div>
<div class="timeline-icon bg-danger" v-if="log.description == 'deleted'">
<i class="feather icon-trash-2 font-medium-2 align-middle"></i>
</div>
<div class="timeline-icon bg-success" v-if="log.description == 'created'">
<i class="feather icon-plus-circle font-medium-2 align-middle"></i>
</div>
<div class="timeline-info">
<p class="font-weight-bold mb-0">
<i :class="getIcon(log)"></i> {{ getType(log) }}
</p>
<span class="font-small-3" v-html="getMessage(log)">
</span>
<a href="#" @click="getData(log)" data-toggle="modal" data-target="#exampleModalLong">
подробнее
</a>
</div>
<small class="text-muted">
{{ log.created_at | moment("HH:mm, DD.MM.YYYY") }} | ID: {{ log.causer.id }} | Пользователь: <b>{{ log.causer.username }}</b>
</small>
</li>
</ul>
<div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Подробнее</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" v-if="log_modal">
<fieldset class="form-group">
<label for="basicInput">Пользователь</label>
<input type="text" class="form-control" disabled :value="log.causer.username" id="basicInput">
</fieldset>
<fieldset class="form-group">
<label for="basicInput">ID</label>
<input type="text" class="form-control" disabled :value="log.subject_id" id="basicInput" >
</fieldset>
<div v-if="log.log_name === 'products'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.name">
<label for="basicInput">Названия Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.name.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.name">
<label for="basicInput">Названия Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.name.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name.uz : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.price">
<label for="basicInput">Цена</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.price" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.price : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.price_discount">
<label for="basicInput">Цена со скидкой</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.price_discount" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.price_discount : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.count <= 0">
<label for="basicInput">Количество товаров на складе</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.count" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.count : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.article_number">
<label for="basicInput">Артикул</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.article_number" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.article_number : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.published === false || log.properties.attributes.published">
<label for="basicInput">Публиковать</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.published" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.published : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.available === false || log.properties.attributes.available">
<label for="basicInput">В наличии</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.available" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.available : '' }}
</fieldset>
</div>
</div>
<div v-if="log.log_name === 'orders'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.status">
<label for="basicInput">Статус</label>
<input type="text" class="form-control" disabled :value="getStatus(log.properties.attributes.status)" id="basicInput" >
Было: {{ getStatus(log.properties.old.status) }}
</fieldset>
</div>
</div>
<div v-if="log.log_name === 'staffs'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.username">
<label for="basicInput">Логин</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.username" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.username : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.password">
<label for="basicInput">Пароль</label>
<input type="password" class="form-control" disabled :value="log.properties.attributes.password" id="basicInput" >
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.role.name">
<label for="basicInput">Роль</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.role.name" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.role.name : '' }}
</fieldset>
</div>
</div>
<div v-if="log.log_name === 'roles'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.name">
<label for="basicInput">Названия</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.name" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name : '' }}
</fieldset>
</div>
</div>
<div v-if="log.log_name != 'products'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.name">
<label for="basicInput">Названия Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.name.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.name">
<label for="basicInput">Названия Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.name.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name.uz : '' }}
</fieldset>
</div>
</div>
<div v-if="log.log_name === 'special_offer'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.description">
<label for="basicInput">Описания Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.description.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.name.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.description">
<label for="basicInput">Описания Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.description.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.description.uz : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.link">
<label for="basicInput">Ccылка</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.link" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.link : '' }}
</fieldset>
</div>
</div>
<div v-if="log.log_name === 'settings'">
<div v-if="log.description">
<fieldset class="form-group" v-if="log.properties.attributes.title">
<label for="basicInput">Названия Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.title.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.title.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.title">
<label for="basicInput">Названия Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.title.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.title.uz : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.phone">
<label for="basicInput">Телефон</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.phone.default" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.phone.default : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.phone">
<label for="basicInput">Телефон другой</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.phone.other" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.phone.other : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.address">
<label for="basicInput">Адрес Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.address.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.address.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.address">
<label for="basicInput">Адрес Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.address.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.address.uz : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.socials">
<label for="basicInput">Телеграм</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.socials.telegram" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.socials.telegram : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.socials">
<label for="basicInput">Facebook</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.socials.facebook" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.socials.facebook : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.socials">
<label for="basicInput">Instagram</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.socials.instagram" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.socials.instagram : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.socials">
<label for="basicInput">Youtube</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.socials.youtube" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.socials.youtube : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.socials">
<label for="basicInput">Ok.ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.socials.okru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.socials.okru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.email">
<label for="basicInput">Email</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.email" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.email : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.landmark">
<label for="basicInput">Ориентер Ru</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.landmark.ru" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.landmark.ru : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.address">
<label for="basicInput">Ориентер Uz</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.landmark.uz" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.landmark.uz : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.day_delivery">
<label for="basicInput">Время доставки</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.day_delivery" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.day_delivery : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.price_delivery">
<label for="basicInput">Стоимость доставки</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.price_delivery" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.day_delivery : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.pickup === false || log.properties.attributes.pickup">
<label for="basicInput">Самовывоз</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.pickup" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.pickup : '' }}
</fieldset>
<fieldset class="form-group" v-if="log.properties.attributes.delivery === false || log.properties.attributes.delivery">
<label for="basicInput">Доставка курьером</label>
<input type="text" class="form-control" disabled :value="log.properties.attributes.delivery" id="basicInput" >
Было: {{ log.properties.old ? log.properties.old.delivery : '' }}
</fieldset>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Закрыть</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
logsData: {}
},
data() {
return {
logs: this.logsData.data,
log_modal: false,
log: {}
}
},
methods: {
getType(log) {
let message;
switch (log.log_name) {
case 'roles':
message = 'Роли';
break;
case 'products':
message = 'Продукты';
break;
case 'orders':
message = 'Заказы';
break;
case 'staffs':
message = 'Стаф';
break;
case 'users':
message = 'Пользователи';
break;
case 'posts':
message = 'Посты';
break;
case 'sliders':
message = 'Баннеры';
break;
case 'categories':
message = 'Категории';
break;
case 'billings':
message = 'История оплаты';
break;
case 'regions':
message = 'Регионы';
break;
case 'cities':
message = 'Города';
break;
case 'settings':
message = 'Настройки';
break;
case 'addresses':
message = 'Адрес';
break;
case 'brand':
message = 'Бренды';
break;
case 'pages':
message = 'Страницы';
break;
case 'special_offer':
message = 'Спецпредложения';
break;
}
// addresses, brand, pages, special_offer
return message;
},
getIcon(log) {
let icon;
switch (log.log_name) {
case 'roles':
icon = 'feather icon-check-circle';
break;
case 'products':
icon = 'feather icon-box';
break;
case 'orders':
icon = 'feather icon-shopping-cart';
break;
case 'staffs':
icon = 'feather icon-users';
break;
case 'users':
icon = 'feather icon-users';
break;
case 'posts':
icon = 'feather icon-align-center';
break;
case 'sliders':
icon = 'feather icon-align-center';
break;
case 'categories':
icon = 'feather icon-tag';
break;
case 'billings':
icon = 'feather icon-credit-card';
break;
case 'regions':
icon = 'feather icon-database';
break;
case 'cities':
icon = 'feather icon-layers';
break;
case 'settings':
icon = 'feather icon-settings';
break;
case 'addresses':
icon = 'feather icon-home';
break;
case 'brand':
icon = 'feather icon-cast';
break;
case 'pages':
icon = 'feather icon-align-center';
break;
case 'special_offer':
icon = 'feather icon-command';
break;
}
return icon;
},
getMessage(log) {
let message;
switch (log.description) {
case 'created':
message = '<b>ID: ' + log.subject_id + '</b> успешно создано';
break;
case 'deleted':
message = '<b>ID: ' + log.subject_id + '</b> успешно удалено';
break;
case 'updated':
message = '<b>ID: ' + log.subject_id + '</b> успешно редактировано';
break;
}
return message;
// switch (log.log_name) {
// case 'products':
// switch (log.description) {
// case 'created':
// message = 'Продукт <b>ID: ' + log.subject_id + '</b> успешно создано';
// break;
// case 'deleted':
// message = 'Продукт <b>ID: ' + log.subject_id + '</b> успешно удалено';
// break;
// case 'updated':
// message = 'Продукт <b>ID: ' + log.subject_id + '</b> успешно редактировано';
// break;
// }
// break;
// case 'orders':
// switch (log.description) {
// case 'deleted':
// message = 'Заказ <b>ID: ' + log.subject_id + '</b> успешно удалено';
// break;
// case 'updated':
// message = 'Заказ <b>ID: ' + log.subject_id + '</b> успешно редактировано';
// break;
// }
// break;
// }
//
// return message;
},
getStatus(status) {
let message;
switch (status) {
case 'processing':
message = 'В обработке';
break;
case 'collected':
message = 'Собран';
break;
case 'waiting_buyer':
message = 'Ожидает покупателя';
break;
case 'in_way':
message = 'В пути';
break;
case 'closed':
message = 'Закрыт';
break;
case 'cancelled':
message = 'Отменен';
break;
case 'replacement':
message = 'Замена';
break;
}
return message;
},
getData(log) {
this.log_modal = true;
this.log = log;
}
}
}
</script>
<style scoped>
</style>

View File

View File

@@ -0,0 +1,23 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>

View File

@@ -0,0 +1,238 @@
<template>
<div>
<section v-if="!mobile" class="section-favorite d-md-block d-none">
<div class="container">
<h3 class="mb-3 section-title-small">{{ $t('app.favorites.title') }}</h3>
<p class="mb-3 " v-if="favorites.length === 0">
{{ $t('app.no_product') }}
</p>
<div class="row" v-if="favorites.length > 0">
<div v-for="(product, index) in favorites" class="col-lg-12 col-md-6">
<div class="product my-3">
<div class="row align-items-center">
<div class="col-lg-2">
<div class="product-img">
<img :src="'/' + product.poster_thumb" :alt="getName(product.name)" :class="!product.isAvailable ? 'no-product-img' : ''" >
</div>
</div>
<div class="col-lg-4">
<h3 class="product-title">
<a :href="'/product/show/' + product.id + '-' + product.slug">
{{ getName(product.name) }}
</a>
</h3>
<div class="product-address">{{ $t('app.product.article_number') }}: {{ product.article_number }}</div>
<div class="product-price_and_checkout mt-2">
<div class="product-price-by-count mr-3">{{ $t('app.price') }} {{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum_sht') }}</div>
<button class="my-btn my-btn__orange my-btn__orange--small" v-if="product.discountPrice > 0 && product.price_discount">{{ $t('app.discount') }}</button>
</div>
</div>
<div class="col-lg-3 col-xl-2">
<div class="product-price">
<div class="title-price">{{ $t('app.price') }}</div>
<div class="old-price mb-1" v-if="product.price_discount">
{{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
<div class="new-price">{{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</div>
</div>
</div>
<div class="col-lg-3 col-xl-4">
<div class="product-buttons">
<div class="product-to_cart">
<button v-if="!product.isCart" :class="product.isCart ? 'product-to_basket is-active is-actived' : 'product-to_basket is-actived'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.to_cart') }}</span>
<div class="added-to-basket" v-html="$t('vue.favorite.added_to_basket')">
</div>
</button>
<button v-if="product.isCart && product.isAvailable" :class="product.isCart ? 'product-to_basket is-active is-actived' : 'product-to_basket is-actived'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.to_cart') }}</span>
</button>
<!-- <a href="balance.html" class="product-balance_link">-->
<!-- <button class="product-to_compares">-->
<!-- <i class="fas fa-balance-scale"></i>-->
<!-- </button>-->
<!-- <span>{{ $t('app.compare') }}</span>-->
<!-- </a>-->
</div>
<div class="v-line">|</div>
<button @click="removeProduct(product, index)" class="product-to_delete">
<i class="fal fa-times fa-2x"></i>
<span>{{ $t('app.delete') }}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Избранные товары -->
<section v-if="mobile" class="section-products d-block d-md-none section-favorite">
<div class="container">
<h3 class="section-title-small">
{{ $t('app.favorites.title') }}
</h3>
<p class="mb-3 " v-if="favorites.length === 0">
{{ $t('app.no_product') }}
</p>
<div class="swiper-container swiper-product swiper-favorite">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(product, index) in favorites">
<div class="product">
<div class="row align-items-center">
<div class="col-lg-2">
<div class="product-img">
<img :src="'/' + product.poster_thumb" :alt="getName(product.name)" :class="!product.isAvailable ? 'no-product-img' : ''" >
</div>
</div>
<div class="col-lg-4">
<h3 class="product-title">{{ getName(product.name) }}</h3>
<div class="product-address">{{ $t('app.product.article_number') }}: {{ product.article_number }}</div>
<div class="product-price_and_checkout mt-2">
<div class="product-price-by-count mr-3">{{ $t('app.price') }} {{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum_sht') }}</div>
<button class="my-btn my-btn__orange my-btn__orange--small">{{ $t('app.discount') }}</button>
</div>
</div>
<div class="col-lg-3 col-xl-2">
<div class="product-price">
<div class="title-price">{{ $t('app.price') }}</div>
<div class="old-price mb-1" v-if="product.price_discount">
{{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
<div class="new-price">{{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</div>
</div>
</div>
<div class="col-lg-3 col-xl-4">
<div class="product-buttons">
<div class="product-to_cart">
<button v-if="product.isCart && product.isAvailable" :class="product.isCart ? 'product-to_basket is-active is-actived' : 'product-to_basket is-actived'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.to_cart') }}</span>
</button>
<!-- <a href="balance.html" class="product-balance_link">-->
<!-- <button class="product-to_compares">-->
<!-- <i class="fas fa-balance-scale"></i>-->
<!-- </button>-->
<!-- <span>{{ $t('app.compare') }}</span>-->
<!-- </a>-->
</div>
<div class="v-line">|</div>
<button @click="removeProduct(product, index)" class="product-to_delete">
<i class="fal fa-times fa-2x"></i>
<span>{{ $t('app.delete') }}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product"></div>
<div class="swiper-button-prev swiper-button-prev-product"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product"></div>
</div>
</div>
</section>
</div>
</template>
<script>
import { isMobile } from 'mobile-device-detect';
export default {
props: {
products: {},
loginInfo: {}
},
data () {
return {
mobile: isMobile ? true : false,
favorites: this.products.data
}
},
mounted() {
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async removeProduct(product, index) {
var field = document.getElementById("favorite-count");
var count = field.value;
const { data } = await axios.get('/favorites/delete/' + product.id);
if (data.status) {
this.favorites.splice(index, 1);
field.value = parseInt(count) - 1;
}
},
async AddToCart(product) {
if (product.isCart) {
this.$eventBus.$emit('cart-preview');
return;
}
const fields = {
product_id: product.children.id,
count: 1
};
const { data } = await axios.post('/cart/store', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
}
}
}
}
</script>

View File

@@ -0,0 +1,195 @@
<template>
<div>
<!-- Category -->
<section class="section-category">
<div class="container">
<div class="category" v-if="!mobile">
<a :href="settingData.links.one" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img1.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_1') }}</h3>
</a>
<a :href="settingData.links.two" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img2.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_2') }}</h3>
</a>
<a :href="settingData.links.three" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img3.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_3') }}</h3>
</a>
<a :href="settingData.links.four" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img4.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_4') }}</h3>
</a>
<a :href="settingData.links.five" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img5.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_5') }}</h3>
</a>
</div>
<swiper
ref="mySwiperCategory"
class="swiper-container swiper-product swiper-category"
:options="swiperOptions"
v-if="mobile"
>
<swiper-slide>
<a :href="settingData.links.one" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img1.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_1') }}</h3>
</a>
</swiper-slide>
<swiper-slide>
<a :href="settingData.links.two" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img2.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_2') }}</h3>
</a>
</swiper-slide>
<swiper-slide>
<a :href="settingData.links.three" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img3.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_3') }}</h3>
</a>
</swiper-slide>
<swiper-slide>
<a :href="settingData.links.four" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img4.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_4') }}</h3>
</a>
</swiper-slide>
<swiper-slide>
<a :href="settingData.links.five" class="category-item">
<div class="category-item__logo">
<img src="/vendor/site/img/category_img5.png" alt />
</div>
<h3 class="category-item__title">{{ $t('vue.feature.feature_title_5') }}</h3>
</a>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-product" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product" slot="pagination"></div>
</swiper>
</div>
</section>
</div>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
// import "swiper/swiper-bundle.css";
import "swiper/css/swiper.css";
import { isMobileOnly } from "mobile-device-detect";
export default {
props: {
settingData: {}
},
components: {
Swiper,
SwiperSlide,
},
data() {
return {
swiperOptions: {
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-product",
prevEl: ".swiper-button-prev-product",
},
pagination: {
el: ".swiper-pagination-product",
dynamicBullets: true,
},
breakpoints: {
1200: {
slidesPerView: 6,
},
1024: {
slidesPerView: 4,
},
576: {
slidesPerView: 3,
},
0: {
slidesPerView: 2,
},
},
autoplay: {
delay: 5500,
},
},
products: [],
mobile: isMobileOnly ? true : false,
};
},
computed: {
swiper() {
return this.$refs.mySwiperCategory.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
.swiper-product {
padding: 75px 0 20px;
margin-top: -50px;
padding-left: 10px;
padding-right: 10px;
@include mq("tablet", max) {
margin-left: -15px;
margin-right: -15px;
padding-bottom: 30px;
}
}
</style>

146
resources/js/components/Home.vue Executable file
View File

@@ -0,0 +1,146 @@
<template>
<div>
<div class="row">
<div class="col-lg-3 col-sm-6 col-12">
<div class="card">
<div class="card-header d-flex flex-column align-items-start pb-0">
<div class="avatar bg-rgba-primary p-50 m-0">
<div class="avatar-content">
<i class="feather icon-users text-primary font-medium-5"></i>
</div>
</div>
<h2 class="text-bold-700 mt-1">{{ users }}</h2>
<p class="mb-0">Пользователи</p>
</div>
<div class="card-content">
<br>
</div>
</div>
</div>
<div class="col-lg-3 col-sm-6 col-12">
<div class="card">
<div class="card-header d-flex flex-column align-items-start pb-0">
<div class="avatar bg-rgba-success p-50 m-0">
<div class="avatar-content">
<i class="feather icon-credit-card text-success font-medium-5"></i>
</div>
</div>
<h2 class="text-bold-700 mt-1">{{ revenue | getRevenue }}</h2>
<p class="mb-0">Доход</p>
</div>
<div class="card-content">
<br>
</div>
</div>
</div>
<div class="col-lg-3 col-sm-6 col-12">
<div class="card">
<div class="card-header d-flex flex-column align-items-start pb-0">
<div class="avatar bg-rgba-warning p-50 m-0">
<div class="avatar-content">
<i class="feather icon-package text-warning font-medium-5"></i>
</div>
</div>
<h2 class="text-bold-700 mt-1">
{{ orders }}
</h2>
<p class="mb-0">Заказы</p>
</div>
<div class="card-content">
<br>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Количество заказов</h4>
<div class="btn-group dropdown mr-1 mb-1">
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Primary
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Option 1</a>
<a class="dropdown-item active" href="#">Option 2</a>
<a class="dropdown-item" href="#">Option 3</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
</div>
<div class="card-content">
<div class="card-body pl-0">
<div class="height-300">
<canvas id="count-chart" :data-data="{content}"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Стоимость заказа</h4>
</div>
<div class="card-content">
<div class="card-body pl-0" >
<div class="height-300" >
<canvas id="price-chart"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
users: {},
orders: {},
revenue: {},
orderData: {}
},
data: function () {
return {
content: []
}
},
created() {
Event.$on("document-was-processed", content => {
this.content = JSON.parse(this.props.orderData);
});
},
mounted() {
},
filters: {
getRevenue(revenue) {
let sum = revenue / 1000;
if (sum < 1000) {
return sum + 'k'
} else if (sum <= 10000) {
return sum / 1000 + 'M'
} else {
}
}
},
methods: {
}
}
</script>

View File

@@ -0,0 +1,40 @@
<template>
<div class="news">
<a :href="'/blog/news/' + postData.id + '-' + postData.slug" class="news-img">
<img :src="'/' + postData.image" :alt="postData.name" />
</a>
<div class="news-content">
<div class="news-date">
{{ postData.date }}
</div>
<h3 class="news-title">
<a :href="'/blog/news/' + postData.id + '-' + postData.slug">
{{ postData.name }}
</a>
</h3>
<p class="news-subtitle" v-html="postData.content.replace(/<\/?[^>]+>/ig, '')">
</p>
<a :href="'/blog/news/' + postData.id + '-' + postData.slug" class="news-link">
{{ $t('vue.news.news_read_more') }}
<i class="fal fa-chevron-right ml-2"></i>
</a>
</div>
</div>
</template>
<script>
export default {
props: ['postData'],
methods: {
htmlStrip() {
}
}
};
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,60 @@
<template>
<div>
<section class="section-news">
<div class="container">
<h2 class="section-title"><a title="Open another news" href="/blog/news">{{ $t('vue.news.news_title') }}</a></h2>
<!-- News on desktop -->
<div class="row mt-3 outer-row" v-if="!mobile">
<div class="col-lg-5" v-if="topPost">
<News :post-data="topPost" />
</div>
<div class="col-lg-7 mt-lg-0 mt-3" >
<div class="row inner-row">
<div class="col-md-4 col-sm-6 mb-md-0 mb-3" v-for="(post, index) in postsData" :key="index">
<News :post-data="post" />
</div>
</div>
</div>
</div>
<NewsSlider :posts-data="postsSlider" v-if="mobile" />
</div>
</section>
</div>
</template>
<script>
import News from "./News";
import NewsSlider from './NewsSlider';
import { isMobileOnly } from 'mobile-device-detect';
export default {
props: ['postsData', 'topPost'],
data() {
return {
mobile: isMobileOnly ? true : false,
postsSlider: this.postsData
};
},
components: {
News,
NewsSlider
},
mounted() {
this.setPostData();
},
methods: {
setPostData() {
this.postsSlider.unshift(this.topPost);
}
}
};
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,114 @@
<template>
<swiper ref="mySwiperNews" class="swiper-container swiper-product swiper-news" :options="swiperOptions">
<swiper-slide v-for="post in postsData" v-bind:key="post.id">
<News :post-data="post" />
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-news" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-news" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-news" slot="pagination"></div>
</swiper>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
import 'swiper/css/swiper.css'
import News from "./News";
export default {
props: ['postsData'],
components: {
Swiper,
SwiperSlide,
News
},
data() {
return {
swiperOptions: {
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-news",
prevEl: ".swiper-button-prev-news",
},
pagination: {
el: ".swiper-pagination-news",
dynamicBullets: true,
},
breakpoints: {
1200: {
slidesPerView: 5,
},
1024: {
slidesPerView: 4,
},
768: {
slidesPerView: 3,
},
576: {
slidesPerView: 2,
},
0: {
slidesPerView: 1.3,
},
},
autoplay: {
delay: 3500,
},
}
};
},
computed: {
swiper() {
return this.$refs.mySwiperNews.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
.swiper-product {
padding: 75px 0 20px;
margin-top: -50px;
padding-left: 10px;
padding-right: 10px;
@include mq("tablet", max) {
margin-left: -15px;
margin-right: -15px;
padding-bottom: 30px;
}
}
</style>

View File

@@ -0,0 +1,735 @@
<template>
<div>
<div class="row">
<div class="col-md-12 col-12">
<form class="form form-vertical" @submit.prevent="UpdateProduct">
<div class="card">
<div class="card-header">
<h4 class="card-title">Редактировать Заказ {{ order.id }}</h4>
</div>
<div class="card-content">
<div class="card-body">
<div class="form-body">
<p>Все поля обозначенные * обязательные</p>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-content">
<div class="card-body">
<div class="col-12">
<h3>
Товары
</h3>
<hr>
</div>
<div class="col-12">
<div class="table-responsive">
<table class="table">
<thead>
<th>
Фото
</th>
<th width="300">
Названия
</th>
<th>
Цена
</th>
<th>
Скидка
</th>
<th>
Размер
</th>
<th>
Кол-во
</th>
<th>
Действия
</th>
</thead>
<tbody>
<tr v-for="(product, index) in orders.products">
<td>
<img :src="'/' + product.product.poster_thumb" width="100" >
</td>
<td width="300">
{{ product.product.name.ru }}
</td>
<td>
<span v-if="product.product.price_discount">
<strike>
{{ product.product.price }} сум
</strike>
<br>
<span v-if="product.discount">
{{ product.product.price_discount }}
</span>
сум
</span>
<span v-else>
{{ product.product.price }} сум
</span>
</td>
<td>
<span v-if="product.discount">
{{ product.discount }}
</span>
<span v-else>
{{ product.product.discount }}
</span>
%
</td>
<td>
{{ product.size }}
</td>
<td>
{{ product.count }}
</td>
<td>
<button type="button" @click="Edit(index)" class="btn btn-primary btn-sm btn-icon">
<i class="fa fa-edit"></i>
</button>
<button type="button" @click="Delete(index)" class="btn btn-danger btn-sm btn-icon">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<button type="button" @click="addProduct" class="btn btn-info btn-icon">
<i class="fa fa-plus"></i> Добавить товар
</button>
<div class="col-12 mt-1" v-if="actions.store">
<div class="row">
<div class="col-12">
<h3>
Добавить продукт
</h3>
<hr>
</div>
<div class="col-12">
<div class="form-group">
<multiselect v-model="actions.product"
placeholder="Искать"
label="name"
track-by="name"
:options="actions.products"
:option-height="104"
:custom-label="customLabel"
:show-labels="false"
@search-change="SearchProduct"
>
<template slot="singleLabel" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<span class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</span>
</template>
<template slot="option" slot-scope="props">
<img class="option__image" :src="props.option.poster" width="50" alt="No Mans Sky">
<div class="option__desc">
<span class="option__title">{{ props.option.name }}</span>
</div>
</template>
</multiselect>
</div>
</div>
<div class="col-12" v-if="store.product">
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="count">Кол-во</label>
<input type="number" id="count" class="form-control" v-model.number="store.count" placeholder="Кол-во">
</div>
</div>
</div>
</div>
<div class="col-12">
<button type="button" @click="SaveProductStore" class="btn btn-success btn-icon">
<i class="fa fa-save"></i> Добавить
</button>
<button type="button" @click="CancelProduct('store')" class="btn btn-default btn-icon">
Отменить
</button>
</div>
</div>
</div>
<div class="col-12 mt-1" v-if="actions.edit">
<div class="row">
<div class="col-12">
<h3>
Редактировать продукт
</h3>
<hr>
</div>
<div class="col-12">
<div class="form-group">
<label for="count">Кол-во</label>
<input type="number" id="count" class="form-control" v-model="product.data.count" placeholder="Адрес">
</div>
</div>
<div class="col-12">
<button type="button" @click="SaveProduct" class="btn btn-success btn-icon">
<i class="fa fa-save"></i> Сохранить
</button>
<button type="button" @click="CancelProduct('edit')" class="btn btn-default btn-icon">
Отменить
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-content">
<div class="card-header">
<h4 class="card-title">Цены</h4>
<button type="button" class="btn btn-info" @click="TotalDiscount()"><i class="fa fa-refresh"></i> Пересчитать</button>
</div>
<div class="card-body">
<div class="col-12">
<div class="form-group">
<label for="price">Продукты</label>
<input type="number" disabled id="price" class="form-control" v-model="product_total" placeholder="Цена Продуты">
</div>
</div>
<div class="col-12" v-if="orders.type_delivery == 1">
<div class="form-group">
<label for="delivery_price">Цена за доставку</label>
<input type="number" id="delivery_price" class="form-control" v-model="orders.price_delivery" placeholder="Цена за доставку">
</div>
</div>
<div class="col-12">
<div class="form-group">
<label for="discount">Скидка %</label>
<input type="number" id="discount" class="form-control" v-model="orders.discount" placeholder="Скидка">
</div>
</div>
<div class="col-12">
<div class="form-group">
<label for="total">Итого</label>
<input type="number" disabled v-model="total" id="total" class="form-control" >
</div>
</div>
</div>
</div>
</div>
<div class="alert alert-danger" v-if="actions.error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<div class="card">
<div class="card-content">
<div class="card-footer">
<div class="col-12 mb-0">
<div class="row">
<div class="col-3">
<button type="submit" class="btn btn-primary mr-1 mb-1 waves-effect waves-light btn-icon">
<i class="feather icon-save"></i> {{ $t('admin.save') }}
</button>
</div>
<div class="col-9">
<a href="/dashboard/orders" class="btn btn-danger mr-1 mb-1 waves-effect waves-light btn-icon pull-right">
<i class="feather icon-x-circle"></i> {{ $t('admin.cancel') }}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
order: {},
branches: {},
},
data: function() {
return {
orders: this.order,
product: {
index: null,
data: {}
},
store: {
count: 1,
color: null,
color_id: null,
product: null,
discount: null,
order_id: this.order.id,
product_id: null,
size: "",
},
actions: {
error: false,
edit: false,
store: false,
product: null,
products: []
},
product_total: 0,
total: 0,
colors: [],
sizes: [],
errors: [],
deletes: {
products: []
}
}
},
mounted() {
this.TotalDiscount();
},
watch: {
'orders.price_total': function(newVal, oldVal) {
this.total = parseInt(this.orders.price_total) + parseInt(this.orders.price_delivery);
},
'orders.discount': function (newVal, oldVal) {
if (newVal === "" || newVal === 0) {
this.orders.discount = null;
} else {
if (this.orders.discount > 0) {
this.orders.discount = newVal;
}
}
this.TotalDiscount();
},
'orders.price_delivery': function (newVal, oldVal) {
if (newVal === "" || newVal === 0) {
this.orders.price_delivery = null;
} else {
if (this.orders.price_delivery > 0) {
this.orders.price_delivery = newVal;
}
}
this.TotalDiscount();
},
'product.data.discount' : function (newVal, oldVal) {
if (newVal === "" || newVal === 0) {
this.product.data.discount = null;
this.product.data.product.price_discount = null;
} else {
if (oldVal) {
if (this.product.data.discount > 0) {
this.product.data.product.price_discount = Math.round(this.product.data.product.price - parseInt(this.product.data.product.price) * parseFloat(this.product.data.discount) / 100);
}
}
}
},
'store.discount': function (newVal, oldVal) {
if (newVal === "" || newVal === 0) {
this.store.discount = null;
this.store.product.price_discount = null;
} else {
if (this.store.discount > 0) {
this.store.product.price_discount = this.store.product.price - parseInt(this.store.product.price) * parseFloat(this.store.discount) / 100;
}
}
},
'actions.product': function () {
this.getProductInfo();
},
},
methods: {
MathRound(number, precision) {
"use strict";
var nativeRound = Math.round,
castNumber = +number,
castPrecision = +precision,
scaledNumber, eSplit, eString;
// If the exp is undefined or zero, just use native rounding
if( typeof precision === "undefined" || 0 === castPrecision ) {
return nativeRound( number );
}
// If the value is not a number or the exp is not an integer...
if( isNaN( castNumber ) || !(typeof castPrecision === "number" && 0 === castPrecision % 1) ) {
return NaN;
}
// In case the number is already in scientific when casted to string, split off the exponent
eSplit = ("" + castNumber).split( "e" );
// Increase the exponent by the given precision and create a scientific notion string
eString = (eSplit[0] + "e" + (eSplit[1] ? (+eSplit[1] + castPrecision) : castPrecision));
// Cast to number and round
scaledNumber = nativeRound( +eString );
// Do the same as before, backwards
eSplit = ("" + scaledNumber).split( "e" );
eString = (eSplit[0] + "e" + (eSplit[1] ? (+eSplit[1] - castPrecision) : -castPrecision));
return +eString;
},
UpdateProduct() {
const data = {
products: this.orders.products,
product_total: this.product_total,
total: this.total
};
axios.post('/dashboard/orders/update/' + this.order.id, data).then((response) => {
if (response.data.status) {
window.location.href = "/dashboard/orders/view/"+ this.order.id;
}
}).catch((error) => {
if (error.response) {
this.actions.error = true;
this.errors = error.response.data.errors;
}
});
},
Edit(index) {
this.actions.edit = true;
this.product.index = index;
this.product.data = {...this.order.products[index]};
axios.get('/dashboard/orders/products/' + this.product.data.product_id).then((response) => {
if (response.data.status) {
this.colors = response.data.product.childrens;
for (let i = 0; i < this.colors.length; i++) {
if (this.colors[i].id === this.product.data.color_id) {
if (this.colors[i].sizes) {
this.sizes = this.colors[i].sizes;
}
}
}
}
});
},
SaveProduct() {
this.actions.edit = false;
this.orders.products[this.product.index] = this.product.data;
this.product.index = null;
this.sizes = [];
this.colors = [];
this.product.data = {};
setTimeout(this.TotalDiscount(), 1000);
},
CancelProduct(type) {
if (type === 'edit') {
this.actions.edit = false;
this.product.index = null;
this.product.data = {};
} else {
this.actions.store = false;
this.store = {
count: null,
color: null,
color_id: null,
product: null,
discount: null,
order_id: this.order.id,
product_id: null,
size: "",
};
this.actions.products = [];
this.actions.product = null;
}
this.sizes = [];
this.colors = [];
this.TotalDiscount();
},
SaveProductStore() {
this.actions.store = false;
this.orders.products.push({...this.store});
this.store = {
count: 1,
color: null,
color_id: null,
product: null,
discount: null,
order_id: this.order.id,
product_id: null,
size: "",
};
this.sizes = [];
this.colors = [];
this.actions.products = [];
this.actions.product = null;
this.TotalDiscount();
},
ChangeColor(event) {
let value;
if (event.target.value) {
value = event.target.value;
} else {
value = event;
}
const val = parseInt(value);
this.colors.forEach((color, index) => {
if (color.id === val) {
if (color.sizes.length > 0) {
this.product.data.color_id = color.id;
this.product.data.color = color;
this.sizes = color.sizes;
} else {
this.sizes = [];
}
}
});
},
ChangeColorStore(event) {
let value;
if (event.target.value) {
value = event.target.value;
} else {
value = event;
}
const val = parseInt(value);
this.colors.forEach((color, index) => {
if (color.id === val) {
if (color.sizes.length > 0) {
this.store.color_id = color.id;
this.store.color = color;
this.sizes = color.sizes;
} else {
this.sizes = [];
}
}
});
},
TotalDiscount() {
let price = [];
let price_discount = [];
if (this.orders.address_id == null) {
this.orders.address = {
first_name: '',
phone: ''
}
}
this.orders.products.forEach(function (product, index) {
if (product.discount === null && product.product.discountPrice === 0) { //|| product.product.price_discount === null
console.log(1);
price.push(parseInt(product.product.price) * product.count);
} else {
console.log(2);
//console.log(product.product.price_discount)
price_discount.push(parseInt(product.product.price_discount) * product.count);
}
});
//console.log(3);
//console.log(price_discount);
let total_price = price.reduce(function(total, num){ return total + num }, 0);
// console.log('price ' + total_price);
let total_discount = price_discount.reduce(function(total, num){ return total + num }, 0);
// console.log('dis ' + total_discount);
this.product_total = parseInt(total_price) + parseInt(total_discount);
let discount = this.orders.discount == null ? 0 : this.orders.discount;
total_price = parseInt(total_price) - parseInt(total_price) * parseInt(discount) / 100;
let delivery;
if (this.orders.type_delivery == 1) {
delivery = this.orders.price_delivery == null ? 0 : this.orders.price_delivery;
} else {
this.orders.price_delivery = 0;
delivery = 0;
}
this.total = parseInt(total_price) + parseInt(total_discount) + parseInt(delivery);
},
addProduct() {
this.actions.store = true;
},
Delete(index) {
//console.log(index);
this.deletes.products.push(this.orders.products[index].product_id);
this.orders.products.splice(index, 1);
this.TotalDiscount();
},
async getProductInfo() {
if (this.actions.product) {
const { data } = await axios.post('/dashboard/orders/product/info/' + this.actions.product.id);
if (data.product.price_discount) {
this.store.discount = 100 - parseInt(data.product.price_discount) * 100 / parseInt(data.product.price);
} else {
this.store.discount = null;
}
this.store.product = data.product;
this.store.product_id = data.product.id;
axios.get('/dashboard/orders/products/' + data.product.id).then((response) => {
if (response.data.status) {
this.colors = response.data.product.childrens;
this.store.color_id = response.data.product.childrens[0].id
}
});
} else {
this.store.product = null;
}
},
async SearchProduct(query) {
let name = query;
if (name.length > 0) {
axios.post('/dashboard/orders/product/search', { name: name})
.then((response) => {
if (response.data.status) {
this.actions.products = response.data.products;
}
}).catch((error) => {
if (error.response) {
this.actions.error = true;
this.errors = error.response.data.errors;
}
});
}
//console.log(query);
},
customLabel ({ name }) {
return `${name}`
},
},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,121 @@
<template>
<swiper
ref="mySwiperBrand"
class="swiper-container swiper-product"
:options="swiperOptions"
>
<swiper-slide v-for="(partner, index) in partnersData" :key="index">
<div class="partner">
<div class="partner-logo">
<a :href="'/brand/' + partner.slug">
<img :src="'/' + partner.image" :alt="partner.name" />
</a>
</div>
</div>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-product" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product" slot="pagination"></div>
</swiper>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
// import "swiper/swiper-bundle.css";
import 'swiper/css/swiper.css'
export default {
props: ['partnersData'],
components: {
Swiper,
SwiperSlide,
},
data() {
return {
swiperOptions: {
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-product",
prevEl: ".swiper-button-prev-product",
},
pagination: {
el: ".swiper-pagination-product",
dynamicBullets: true,
},
breakpoints: {
1200: {
slidesPerView: 6,
},
1024: {
slidesPerView: 4,
},
576: {
slidesPerView: 3,
},
0: {
slidesPerView: 2,
},
},
autoplay: {
delay: 5500,
},
},
products: [],
};
},
computed: {
swiper() {
return this.$refs.mySwiperBrand.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
.swiper-product {
padding: 75px 0 20px;
margin-top: -50px;
padding-left: 10px;
padding-right: 10px;
@include mq("tablet", max) {
margin-left: -15px;
margin-right: -15px;
padding-bottom: 30px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
<template>
<div class="row" id="table-head">
<div class="col-12">
<div class="card">
<div class="card-content ">
<div class="table-responsive table-responsive-xl" >
<table class="table mb-0">
<thead class="thead-dark">
<tr>
<th scope="col">{{ $t('admin.products.name') }} RU</th>
<th scope="col">{{ $t('admin.products.name') }} Uz</th>
<th scope="col" width="150">Артикул</th>
<th scope="col" width="170">{{ $t('admin.products.price') }}</th>
<th scope="col">{{ $t('admin.products.brand') }}</th>
<th scope="col">Лидеры продаж</th>
<th scope="col">Популярные товары</th>
<th scope="col">Х-рка</th>
<th scope="col">{{ $t('admin.actions') }}</th>
</tr>
</thead>
<tbody>
<tr v-if="products.length == 0">
<td class="text-center" colspan="9">
{{ $t('admin.no_data') }}
</td>
</tr>
<tr v-for="(product, index) in products" :key="index">
<td>
{{ product.name.ru }}
</td>
<td>
{{ product.name.uz }}
</td>
<td>
{{ product.article_number }}
</td>
<td>
<span v-if="product.price_discount">
<strike>{{ product.price }}</strike>
{{ $t('admin.ye') }}
<br>
{{ product.price_discount }}
{{ $t('admin.ye') }}
</span>
<span v-else>
{{ product.price }} {{ $t('admin.ye') }}
</span>
</td>
<td>
{{ product.brand }}
</td>
<td>
{{ product.leader_of_sales }}
</td>
<td>
{{ product.popular }}
</td>
<td>
<button type="button" @click="charView(product)" class="btn btn-primary btn-icon" data-toggle="modal" data-target="#large">
<i class="fa fa-eye"></i>
</button>
</td>
<td class="text-right">
<a href="#" @click="removeProduct(product, index)" class="btn btn-danger btn-icon">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<button type="button" class="btn btn-success" @click="sendProducts">
<i class="fa fa-save"></i> Сохранить
</button>
</div>
<div class="modal fade text-left" id="large" tabindex="-1" role="dialog" aria-labelledby="myModalLabel17" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel17">Характеристики</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="col-md-12" v-for="(char, index) in characteristics" :key="index">
<div class="row">
<div class="col-xl-4 col-md-6 col-12 mb-1">
<fieldset class="form-group">
<input type="text" disabled v-model="char.name.ru" class="form-control">
</fieldset>
</div>
<div class="col-xl-4 col-md-6 col-12 mb-1">
<fieldset class="form-group" v-if="char.type != 'checkbox'">
<input :type="char.type" min="0" v-model="char_data[index]" class="form-control">
</fieldset>
<fieldset v-else>
<div class="vs-checkbox-con vs-checkbox-primary">
<input type="checkbox" v-model="char_data[index]" >
<span class="vs-checkbox">
<span class="vs-checkbox--check">
<i class="vs-icon feather icon-check"></i>
</span>
</span>
</div>
</fieldset>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" @click="saveChar" data-dismiss="modal">Сохранить</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
productsData: {},
characteristicsData: {},
categoryData: {}
},
data() {
return {
products: this.productsData,
characteristics: this.characteristicsData.characteristics,
category_id: this.categoryData,
char_data: []
}
},
methods: {
removeProduct(product, index) {
this.products.splice(index, 1)
},
charView(product) {
this.char_data = product.characteristics;
},
saveChar() {
this.char_data = [];
},
async sendProducts() {
const fields = {
data: this.products,
category_id: this.category_id
};
const { data } = await axios.post('/dashboard/products/preview/store', fields);
if (data.status) {
window.location = '/dashboard/products'
}
}
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
<template>
<div>
<div class="modal fade buy-by-one-click" ref="buy_one_click" id="buy-by-one-click">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<i class="fal fa-times"></i>
</button>
<h4>{{ $t('vue.buy_one.title') }}</h4>
<div class="alert alert-danger" v-if="error">
<ul>
<li v-for="(error, index) in errors" :key="index">
<span v-for="msg in error" :key="msg">
{{ msg }}
</span>
</li>
</ul>
</div>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="text" placeholder="" v-model="first_name" id="your_name2" required />
<label for="your_name2">{{ $t('vue.buy_one.first_name') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="tel" :placeholder="$t('vue.buy_one.phone_place')" v-model="phone" v-mask="'+### ## ###-##-##'" id="phoneee" required />
<label for="phoneee">{{ $t('vue.buy_one.phone') }}</label>
</div>
<div class="mt-4 my-form__group">
<input type="email" placeholder="" v-model="email" id="your_name" />
<label for="your_name">{{ $t('vue.buy_one.email') }}</label>
</div>
<div class="mt-4 my-form__group">
<textarea name="" id="your_message2" v-model="comment" cols="30" rows="5"></textarea>
<label for="your_message2">{{ $t('vue.buy_one.comment') }}</label>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange">
{{ $t('vue.buy_one.send') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal fade success" ref="alertNotification">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body text-center">
<img src="/vendor/site/img/tick.png" alt="Tick icon">
<div class="my-3">
<h4 class="text-center">
{{ $t('vue.buy_one.thx') }}
</h4>
<h5 class="text-center px-lg-5">
{{ $t('vue.buy_one.thx_text') }}
</h5>
</div>
<div class="mt-4">
<button type="button" data-dismiss="modal" class="my-btn my-btn__orange">{{ $t('vue.noti.ok') }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
phoneProfile: {},
productId: {},
firstName: {}
},
data() {
return {
phone: this.phoneProfile,
first_name: this.firstName,
email: null,
comment: null,
product_id: this.productId,
error: false,
errors: []
}
},
methods: {
SendForm() {
const field = {
phone: this.phone,
first_name: this.first_name,
email: this.email,
comment: this.comment,
product_id: this.product_id
};
axios.post('/product/buy/click', field).then((response) => {
if (response.data.status) {
$(this.$refs.buy_one_click).modal('hide');
$(this.$refs.alertNotification).modal('show');
this.phone = this.phoneProfile;
this.first_name = null;
this.email = null;
this.comment = null
}
}).catch((error) => {
if (error.response) {
this.error = true;
this.errors = error.response.data.errors;
}
});
}
}
}
</script>
<style scoped>
</style>w

View File

@@ -0,0 +1,235 @@
<template>
<div>
<div class="modal fade installment" id="installment" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-body">
<!-- -->
<button class="close" data-dismiss="modal"><i class="fal fa-times"></i></button>
<div>
<h4 class="text-center">{{ $t('app.credit.title') }}</h4>
<ul class="nav nav-pills justify-content-center">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#by_alifmoliya">Alif Moliya</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="pill" href="#by_apelsin">Apelsin</a>
</li>
</ul>
<hr>
<div class="tab-content">
<div class="tab-pane container p-0 active" id="by_alifmoliya">
<form class="my-form my-form__auth">
<div class="row">
<div class="col-md-6">
<div class="my-form__group">
<input class="payment-price" readonly
:value="firstPay | number('0,0', { thousandsSeparator: ' ' })" type="number" id="initial-payment"
required="">
<label for="initial-payment">{{ $t('app.credit.alif.first_pay') }}</label>
</div>
<div class="small mt-1"><i class="fal fa-info-circle"></i> {{ $t('app.credit.alif.min_pay') }} {{ product.first_pay }}
</div>
</div>
<div class="col-md-6">
<div class="mt-md-0 mt-4 my-form__group">
<label>{{ $t('app.credit.alif.months') }}</label>
<div
class="d-flex justify-content-center align-items-center select-months">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input months"
id="month6" v-model="months" @change="handleMonth"
:value="6">
<label class="custom-control-label" for="month6">6
{{ $t('app.credit.month') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input months"
id="month9" v-model="months" @change="handleMonth"
:value="9">
<label class="custom-control-label" for="month9">9
{{ $t('app.credit.month') }}.</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input months"
id="month12" v-model="months" @change="handleMonth"
:value="12">
<label class="custom-control-label" for="month12">12
{{ $t('app.credit.month') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input months"
id="month3" v-model="months" @change="handleMonth"
:value="15">
<label class="custom-control-label" for="month3">15
{{ $t('app.credit.month') }}.</label>
</div>
<!-- <div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="month15" name="months"
value="customEx">
<label class="custom-control-label" for="month15">15 мес.</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" class="custom-control-input" id="month18" name="months"
value="customEx">
<label class="custom-control-label" for="month18">18 мес.</label>
</div> -->
</div>
</div>
</div>
<div class="col-md-6">
<div class="mt-4 my-form__group">
<input type="text" disabled="" :value="perMonth | number('0,0', { thousandsSeparator: ' ' })"
id="for_month" class="payment-price">
<label for="for_month">{{ $t('app.credit.alif.per_month') }}</label>
</div>
</div>
<div class="col-md-6">
<div class="mt-4 my-form__group">
<input type="text" disabled=""
:value="price | number('0,0', { thousandsSeparator: ' ' })"
class="payment-price" id="all_price">
<label for="all_price">{{ $t('app.credit.alif.price') }}</label>
</div>
</div>
<div class="col-md-6" v-if="phoneVerify">
<div class="mt-4 my-form__group">
<input type="tel"
v-model="phone"
v-mask="'+998 (##) ###-##-##'"
class="payment-price" id="phone">
<label for="phone">{{ $t('app.credit.alif.phone') }}</label>
</div>
</div>
<div class="col-md-6" v-if="phoneVerify">
<div class="mt-4 my-form__group" v-if="showVerify">
<input type="text"
v-mask="'####'"
v-model="verify"
class="payment-price" id="verify">
<label for="verify">{{ $t('app.credit.alif.verify_code') }}</label>
</div>
</div>
<div class="col-md-6 mx-auto mt-3">
<div
class="mt-4 d-flex justify-content-md-end justify-content-center align-items-center">
<button v-if="!phoneVerify" @click="showPhoneVerify" type="button" class="my-btn my-btn__orange w-100">
{{ $t('app.credit.btn') }}
</button>
<button v-if="phoneVerify && !showVerify" @click="sendPhone" type="button" class="my-btn my-btn__orange w-100">
{{ $t('app.credit.btn') }}
</button>
<button v-if="showVerify" @click="submit" type="button" class="my-btn my-btn__orange w-100">
{{ $t('app.credit.btn') }}
</button>
</div>
</div>
</div>
</form>
</div>
<div class="tab-pane container p-0 fade" id="by_apelsin">
<div class="mt-3">
<p>{{ $t('app.credit.apelsin_text') }}</p>
</div>
<div class="row">
<div class="col-md-6 mx-auto mt-3">
<a :href="`/product/oncredit/${product.id}`">
<button class="my-btn my-btn__orange w-100">{{ $t('app.credit.btn') }}</button>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Credit",
props: {
productData: {}
},
data() {
return {
product: this.productData,
firstPay: 0,
perMonth: this.productData.per_month,
price: Math.round(this.productData.price + (this.productData.price / 100) * 25),
months: 6,
phoneVerify: false,
showVerify: false,
phone: null,
verify: null
}
},
methods: {
handleFirstPay(event) {
if ((parseInt(event.target.value) < parseInt(this.product.first_pay)) || (parseInt(event.target.value) > parseInt(this.price)) || !event.target.value) {
this.firstPay = this.product.first_pay
} else {
this.perMonth = Math.round((this.price - this.firstPay) / this.months)
}
},
handleMonth(event) {
switch (this.months) {
case 6:
this.price = Math.round(this.product.price + (this.product.price / 100) * 25)
break
case 9:
this.price = Math.round(this.product.price + (this.product.price / 100) * 32)
break
case 12:
this.price = Math.round(this.product.price + (this.product.price / 100) * 38)
break
case 15:
this.price = Math.round(this.product.price + (this.product.price / 100) * 50)
break
}
this.months = parseInt(event.target.value)
this.perMonth = Math.round((this.price - this.firstPay) / parseInt(event.target.value))
},
showPhoneVerify(event) {
this.phoneVerify = true
},
sendPhone(event) {
axios.post('/product/phone-verify/', {phone: this.phone}).then(response => {
this.showVerify = true
})
},
submit() {
const form = new FormData()
form.append('phone', this.phone)
form.append('code', this.verify)
form.append('duration', this.months)
axios.post(`/product/oncredit/${this.product.id}`, form).then(response => {
$('#installment').modal('hide')
$('#success').modal('show')
})
}
}
}
</script>
<style scoped>
#initial-payment {
-webkit-appearance: none;
margin: 0;
-moz-appearance: textfield;
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<div>
<div class="modal fade alert-when-has-product" ref="notification_available" id="alert-when-has-product">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<i class="fal fa-times"></i>
</button>
<h4>{{ $t('vue.noti.title') }}</h4>
<p>{{ $t('vue.noti.text') }}</p>
<form @submit.prevent="SendForm" class="my-form my-form__auth">
<div class="mt-4 my-form__group">
<input type="tel" v-mask="'+### ## ###-##-##'" v-model="phone" :placeholder="$t('vue.buy_one.phone_place')" id="has_productsss" required />
<label for="has_productsss">{{ $t('vue.buy_one.phone') }}</label>
</div>
<div class="mt-3 d-flex justify-content-md-end justify-content-center align-items-center">
<button type="sumbit" class="my-btn my-btn__orange">{{ $t('vue.buy_one.send') }}</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal fade success" ref="alertNotification">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body text-center">
<img src="/vendor/site/img/tick.png" alt="Tick icon">
<div class="my-3">
<h5 class="text-center px-lg-5">
{{ $t('vue.noti.alert') }}
</h5>
</div>
<div class="mt-4">
<button type="button" data-dismiss="modal" class="my-btn my-btn__orange">{{ $t('vue.noti.ok') }}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
productId: {},
phoneProfile: {}
},
data() {
return {
phone: this.phoneProfile,
product_id: this.productId
}
},
methods: {
async SendForm() {
const { data } = await axios.post('/product/notification/available', {
phone: this.phone,
product_id: this.product_id
});
if (data.status) {
if (!this.phoneProfile) {
this.phone = null;
} else {
this.phone = '+' + this.phoneProfile;
}
$(this.$refs.notification_available).modal('hide');
$(this.$refs.alertNotification).modal('show');
}
},
doSomethingOnHidden(){
alert('hidden')
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,131 @@
<template>
<div class="product">
<div class="product-top">
<div class="type" v-if="product.diffDate && product.isAvailable">NEW</div>
<div class="discound" v-if="product.discountPrice > 0 && product.price_discount && product.isAvailable">
{{ $t('vue.sale') }}
</div>
<div class="xit" v-if="product.leader_of_sales && product.isAvailable">{{ $t('vue.xit') }}</div>
<div class="no-product" v-if="!product.isAvailable">{{ $t('vue.not_available') }}</div>
</div>
<a :href="'/product/show/' + product.id + '-' + product.slug" class="product-img">
<img :src="'/' + product.poster_thumb" :class="!product.isAvailable ? 'no-product-img' : ''" :alt="getName(product.name)" />
</a>
<div class="product-category">
<a v-for="(category, index) in product.categories" :href="category.link">
{{ getName(category.name) }}
</a>
</div>
<h3 class="product-title">
<a :href="'/product/show/' + product.id + '-' + product.slug">
{{ getName(product.name) }}
</a>
</h3>
<div class="product-price">
<div class="old-price" v-if="product.price_discount">
{{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
<div class="new-price">
{{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
</div>
<div class="product-buttons">
<div class="product-to_cart">
<button v-if="product.isAvailable && !product.isCart" :class="product.isCart ? 'product-to_basket is-active' : 'product-to_basket'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.product.in_cart') }}</span>
<div class="added-to-basket" v-html="$t('vue.favorite.added_to_basket')">
</div>
</button>
<button v-if="product.isAvailable && product.isCart" data-target="#basket_modal" data-toggle="modal" :class="product.isCart ? 'product-to_basket is-active' : 'product-to_basket'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.product.in_cart') }}</span>
</button>
<!-- <button class="product-to_compare">-->
<!-- <i class="far fa-balance-scale"></i>-->
<!-- </button>-->
</div>
<button class="product-to_favorite" data-target="#login" data-toggle="modal" v-if="!loginInfo">
<i class="fas fa-heart"></i>
</button>
<button :class="product.isFavorite ? 'product-to_favorite is-active' : 'product-to_favorite'" @click="Favorite(product)" v-if="loginInfo">
<i class="fas fa-heart"></i>
</button>
</div>
</div>
</template>
<script>
export default {
props: ['product', 'loginInfo'],
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async Favorite(product) {
var field = document.getElementById("favorite-count");
var count = field.value;
if (product.isFavorite === false) {
const { data } = await axios.get('/favorites/store/' + product.id);
this.product.isFavorite = true;
field.value = parseInt(count) + 1;
} else {
const { data } = await axios.get('/favorites/delete/' + product.id);
this.product.isFavorite = false;
field.value = parseInt(count) - 1;
}
},
async AddToCart(product) {
if (this.product.isCart){
this.$eventBus.$emit('cart-preview');
return;
}
const fields = {
product_id: product.children.id,
count: 1
};
const { data } = await axios.post('/cart/store', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
}
}
}
};
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,511 @@
<template>
<section class="section-product-item">
<div class="container">
<div class="row" itemtype="http://schema.org/Product" itemscope>
<meta itemprop="mpn" :content="product.id" />
<meta itemprop="name" :content="getName(product.name)" />
<link itemprop="image" :href="product.children.screen.path_thumb" />
<meta itemprop="description" :content="getName(product.short_body)" />
<div itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
<link itemprop="url" :href="'https://alistore.uz/product/show/' + product.id + '-' + product.slug " />
<meta itemprop="availability" content="https://schema.org/InStock" />
<meta itemprop="priceCurrency" content="UZS" />
<meta itemprop="itemCondition" content="https://schema.org/UsedCondition" />
<meta itemprop="price" :content="product.price_discount ? product.price_discount : product.price" />
</div>
<div class="col-lg-4">
<div class="product-cart">
<div class="product-top">
<div class="type" v-if="product.diffDate && product.isAvailable">NEW</div>
<div class="discound" v-if="product.discountPrice > 0 && product.price_discount && product.isAvailable">
{{ $t('vue.sale') }}
</div>
<div class="xit" v-if="product.leader_of_sales && product.isAvailable">{{ $t('vue.xit') }}</div>
<div class="discound"
v-if="product.discountPrice > 0 && product.price_discount && product.isAvailable">-{{
product.discountPrice }}%
</div>
<div class="xit" v-if="product.leader_of_sales && product.isAvailable">{{ $t('vue.xit') }}
</div>
<div class="no-product" v-if="!product.isAvailable">{{ $t('vue.not_available') }}</div>
</div>
<div class="product-buttons">
<button class="product-to_favorite" data-target="#login" data-toggle="modal"
v-if="!loginInfo">
<i class="fas fa-heart"></i>
</button>
<button
:class="product.isFavorite ? 'product-to_favorite is-active' : 'product-to_favorite'"
@click="Favorite(product)" v-if="loginInfo">
<i class="fas fa-heart"></i>
</button>
<!-- <button class="product-to_compare mt-2">-->
<!-- <i class="far fa-balance-scale"></i>-->
<!-- </button>-->
</div>
</div>
<div class="slider slider-big" id="aniimated-thumbnial">
<div class="slider__content" v-for="(screen, index) in product.childrens[0].screens">
<div class="slider__img">
<div class="item" :data-src="'/' + screen.path">
<img :src="'/' + screen.path_thumb" :alt="getName(product.name)">
</div>
</div>
</div>
</div>
<div class="slider slider-small py-3 px-2" id="aniimated-thumbnials">
<div class="slider__img" v-for="(screen, index) in product.childrens[0].screens">
<div class="item1" :data-src="'/' + screen.path">
<img class="" :src="'/' + screen.path_thumb" :alt="getName(product.name)">
</div>
</div>
</div>
</div>
<div class="col-lg-8 view_box">
<div class="product pt-lg-3 pt-0">
<div class="share d-flex align-items-md-center mt-lg-4 mt-2 flex-column flex-md-row mb-3">
<p class="mb-md-0 mr-md-3 mt-1">{{ $t('vue.news.news_share') }}:</p>
<div class="socials">
<ShareNetwork :url="url" network="facebook" :title="getName(product.name)">
<i class="fab fa-facebook-f"></i>
</ShareNetwork>
<ShareNetwork :url="url" network="telegram" :title="getName(product.name)">
<i class="fab fa-telegram-plane"></i>
</ShareNetwork>
<ShareNetwork :url="url" network="vk" :title="getName(product.name)">
<i class="fab fa-vk"></i>
</ShareNetwork>
<ShareNetwork :url="url" network="odnoklassniki" :title="getName(product.name)">
<i class="fab fa-odnoklassniki"></i>
</ShareNetwork>
</div>
</div>
<h1 class="product-title">
{{ getName(product.name) }}
</h1>
<div class="product-price mb-0">
<div class="new-price">
{{ product.price_discount ? product.price_discount : product.price | number('0,0', {
thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
<div class="old-price mt-1" v-if="product.price_discount">
{{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
</div>
<div class="product-price align-items-md-center h-100" v-if="settingData.on_credit && product.category.credit && product.price > 500000 && product.price > 500000">
<h3 class="product-title mr-2 mt-3 mt-md-0 mb-0">{{ $t('vue.product.in_credit') }}</h3>
<div class="new-price">{{ product.onCredit | number('0,0', { thousandsSeparator: ' ' }) }}
{{ $t('vue.product.sum_m') }}
</div>
</div>
<p class="product-subtitle" v-html="getName(product.short_body)">
</p>
<div class="product-color" v-if="colors">
<p>{{ $t('vue.cart.product_color_title') }}:</p>
<div class="colors">
<ul>
<li v-for="(color, index) in product.childrens" :key="index">
<label v-if="color.color">
<input type="radio" name="color" v-model="color_id" value="black"
:checked="index === 0">
<span class="swatch"
:style="{ 'background-color': '#' + color.color.color, 'border-color': '#' + color.color.color }"></span>
</label>
</li>
</ul>
</div>
</div>
<div class="d-flex align-items-md-center flex-wrap flex-md-row" v-if="product.isAvailable">
<div class="product-count">
<span class="decrement" @click="CountMinus"><i class="fal fa-minus"></i></span>
<input type="text" value="1" v-model="count" min="0" readonly>
<span class="increment" @click="CountAdd"><i class="fal fa-plus"></i></span>
</div>
<div class="product-buttons">
<button v-if="!product.isCart"
:class="product.isCart ? 'product-to_basket is-actived is-active' : 'product-to_basket is-actived'"
@click="AddToCart">
<i class="far fa-shopping-basket"></i>
<span class="d-inline-block">{{ $t('vue.cart.product_to_basket_title') }}</span>
<div class="added-to-basket" v-html="$t('vue.favorite.added_to_basket')">
</div>
</button>
<button v-if="product.isCart"
:class="product.isCart ? 'product-to_basket is-actived is-active' : 'product-to_basket is-actived'"
@click="AddToCart" data-target="#basket_modal" data-toggle="modal">
<i class="far fa-shopping-basket"></i>
<span class="d-inline-block">{{ $t('vue.cart.product_to_basket_title') }}</span>
</button>
<div v-if="product.category.credit && product.price > 500000">
<a href="javasciprt:" v-if="!loginInfo && settingData.on_credit && product.price > 500000"
data-target="#login" data-toggle="modal" @click="CreditCookie"
class="btn-links btn-links__one">{{ $t('vue.cart.buy_in_credit') }}</a>
<a href="javasciprt:" data-target="#installment" data-toggle="modal"
v-if="loginInfo && settingData.on_credit && product.price > 500000" class="btn-links btn-links__one">{{
$t('vue.cart.buy_in_credit') }}</a>
</div>
<a href="javascript:0" class="btn-links btn-links__one bg__green"
data-target="#buy-by-one-click" data-toggle="modal">{{ $t('vue.cart.buy_in_click')
}}</a>
</div>
</div>
<div class="now-no-product" v-if="!product.isAvailable">
<p>{{ $t('vue.not_available') }}</p>
<button data-target="#alert-when-has-product" data-toggle="modal">{{ $t('vue.notification')
}}
</button>
</div>
<div class="payments d-flex align-items-center my-4 flex-wrap">
<p class="mr-3 mb-0">{{ $t('vue.cart.payment_title') }}: </p>
<div class="d-flex align-items-baseline flex-wrap">
<div class="payments-item mr-md-4 m-3 ml-md-0 my-md-0">
<img class="img-fluid" src="/vendor/site/img/apelsin.png" alt="Apelsin">
</div>
<div class="payments-item mr-md-4 m-3 ml-md-0 my-md-0">
<img class="img-fluid" src="/vendor/site/img/click.png" alt="Click">
</div>
<div class="payments-item mr-md-4 m-3 ml-md-0 my-md-0">
<img class="img-fluid" src="/vendor/site/img/payme.png" alt="Payme">
</div>
<div class="payments-item mr-md-4 m-3 ml-md-0 my-md-0">
<img class="img-fluid" src="/vendor/site/img/naqt.png" alt="Naqt">
<span style="transform: translateY(2px);" class="ml-1 d-inline-block">{{ $t('vue.checkout.delivery_in_cash') }}</span>
</div>
</div>
</div>
<div class="product-info mb-2" v-if="settingData.delivery">
<p><b>{{ $t('vue.checkout.delivery_title') }}:</b>
{{ getName(settingData.other.delivery) }}
</p>
</div>
<div class="product-info mb-2" v-if="settingData.pickup">
<p><b>{{ $t('vue.checkout.delivery_pickup') }}:</b> {{ getName(settingData.other.pickup) }}
</p>
</div>
</div>
</div>
</div>
<div class="all_tabs py-4">
<ul class="tabs">
<li :class="product.characteristics.length > 0 ? 'active' : ''"
v-if="product.characteristics.length > 0" rel="tab1">{{ $t('vue.cart.characteristic') }}
</li>
<li :class="product.characteristics.length === 0 ? 'active' : ''" rel="tab2">{{
$t('vue.cart.description') }}
</li>
<li rel="tab3">{{ $t('vue.cart.reviews') }} <span class="badge badge-secondary">{{ product.comments.length }}</span>
</li>
<!-- <li rel="tab3">{{ $t('vue.cart.reviews') }} <sup><span class="badge badge-secondary" style="font-size: 100%;">5</span></sup></li>-->
</ul>
<div class="tab_container">
<h3 class="d_active tab_drawer_heading" rel="tab1" v-if="product.characteristics.length > 0 ">{{
$t('vue.cart.characteristic') }}</h3>
<div id="tab1" class="tab_content" v-if="product.characteristics.length > 0 ">
<h4 class="title title--lg p-b-15 view__title">{{ $t('vue.cart.all_characteristic') }}</h4>
<table class="view__table table table-bordered table-striped">
<tbody>
<tr v-for="(char, index) in product.characteristics" :key="index"
v-if="char.pivot.value != 'null'">
<td class="view__td-1">
<div class="view__td-dots">
<span class="view__td-info">
{{ getName(char.name) }}
</span>
</div>
</td>
<td class="view__td-2" v-if="char.type === 'checkbox'">
<span v-if="char.pivot.value === 'true'">
{{ $t('app.exist') }}
</span>
<span v-if="char.pivot.value === 'false'">
{{ $t('app.no') }}
</span>
</td>
<td class="view__td-2" v-else>
{{ char.pivot.value }}
</td>
</tr>
</tbody>
</table>
</div>
<!-- #tab1 -->
<h3 class="tab_drawer_heading" rel="tab2">{{ $t('vue.cart.description') }}</h3>
<div id="tab2" class="tab_content" v-html="getName(product.body)">
</div>
<!-- #tab2 -->
<h3 class="tab_drawer_heading" rel="tab3">{{ $t('vue.cart.reviews') }} <span
class="badge badge-secondary">{{ product.comments.length }}</span></h3>
<div id="tab3" class="tab_content">
<div class="container">
<div class="row">
<div class="message-wrap">
<div id="review" v-if="product.comments.length === 0">
<p>{{ $t('vue.cart.no_reviews') }}</p>
</div>
<div class="msg-wrap" v-if="product.comments.length > 0">
<comment-list v-for="(comment, index) in product.comments"
:comment-data="comment" :key="index"></comment-list>
</div>
</div>
</div>
</div>
<hr>
<div v-if="!loginInfo">
<h5>{{ $t('vue.cart.only_comment_after_auth') }}</h5>
<button type="button" class="my-btn my-btn__orange mt-3" data-target="#login"
data-toggle="modal">
{{ $t('vue.login.auth_title') }}
</button>
</div>
<div class="alert alert-success" v-if="alertComment">
<i class="fas fa-info-circle"></i> {{ $t('vue.cart.success_comment') }}
</div>
<form class="form-horizontal" @submit.prevent="StoreComment" id="form-review" v-if="loginInfo">
<h2>{{ $t('vue.cart.write_review') }}</h2>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-name">{{ $t('vue.cart.your_name')
}}:</label>
<input type="text" name="name" v-model="comment.first_name" value="" id="input-name"
class="form-control">
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label" for="input-review">{{ $t('vue.cart.your_review')
}}:</label>
<textarea name="text" v-model="comment.body" rows="5" id="input-review"
class="form-control"></textarea>
<!-- <div class="help-block">-->
<!-- <span style="color: #FF0000;">{{ $t('vue.cart.only_text') }}</span>-->
<!-- </div>-->
</div>
</div>
<div class="form-group required">
<div class="col-sm-12">
<label class="control-label">{{ $t('vue.cart.product_rating') }}</label>
&nbsp;&nbsp;&nbsp;{{ $t('vue.cart.bad') }}&nbsp;
<input type="radio" name="rating" v-model="comment.star" value="1">
&nbsp;
<input type="radio" name="rating" v-model="comment.star" value="2">
&nbsp;
<input type="radio" name="rating" v-model="comment.star" value="3">
&nbsp;
<input type="radio" name="rating" v-model="comment.star" value="4">
&nbsp;
<input type="radio" name="rating" v-model="comment.star" value="5">
&nbsp;{{ $t('vue.cart.good') }}
</div>
</div>
<div class="buttons clearfix">
<div class="pull-right">
<button type="submit" id="button-review" data-loading-text="Загрузка..."
class="btn btn-primary">{{ $t('vue.cart.sending') }}
</button>
</div>
</div>
</form>
</div>
<!-- #tab3 -->
</div>
</div>
</div>
<notification :product-id="this.product.id" v-if="!product.isAvailable"
:phone-profile="this.phoneProfile"></notification>
<buy-one-click :product-id="this.product.id" v-if="product.isAvailable" :phone-profile="this.phoneProfile"
:first-name="this.firstName"></buy-one-click>
</section>
</template>
<script>
import CommentList from '../Comment/CommentList';
import Notification from './Notification';
import BuyOneClick from './BuyOneClick';
import VueSocialSharing from 'vue-social-sharing'
export default {
props: {
productData: {},
loginInfo: {},
firstName: {},
settingData: {},
phoneProfile: {}
},
components: {
'comment-list': CommentList,
'ShareSocial': VueSocialSharing,
'notification': Notification,
'buy-one-click': BuyOneClick
},
created() {
this.url = window.location.href;
},
data() {
return {
product: this.productData,
count: 1,
color_id: null,
comment: {
star: 0,
body: '',
first_name: this.firstName
},
alertComment: false,
alertBasket: false,
colors: false,
url: ''
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (name) {
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
default:
value = name.ru;
break;
}
} else {
value = name.ru;
}
return value;
}
},
async Favorite(product) {
var field = document.getElementById("favorite-count");
var count = field.value;
if (product.isFavorite === false) {
const { data } = await axios.get('/favorites/store/' + product.id);
this.product.isFavorite = true;
field.value = parseInt(count) + 1;
} else {
const { data } = await axios.get('/favorites/delete/' + product.id);
this.product.isFavorite = false;
field.value = parseInt(count) - 1;
}
},
async AddToCart() {
if (this.product.isCart) {
this.$eventBus.$emit('cart-preview');
return;
}
const fields = {
product_id: this.product.childrens[0].id,
count: this.count
};
const { data } = await axios.post('/cart/store', fields);
if (data.status) {
this.product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
}
},
CountMinus() {
if (this.product.isAvailable) {
if (this.count <= 1) {
return 1;
} else {
this.count -= 1;
}
}
},
CountAdd() {
if (this.product.isAvailable && this.product.count > this.count) {
this.count += 1;
}
},
CreditCookie() {
this.$cookie.delete('cart-preview');
this.$cookie.set('product-credit', this.product.id);
},
async StoreComment() {
const { data } = await axios.post('/product/comment/' + this.product.id, this.comment);
if (data.status) {
this.comment = {
star: 0,
body: '',
first_name: this.firstName
};
this.alertComment = true;
}
}
}
}
</script>

View File

@@ -0,0 +1,157 @@
<template>
<swiper
ref="mySwiper"
class="swiper-container swiper-product swiper-product-lider_sales"
:options="swiperOptions"
>
<swiper-slide v-for="(product, index) in products" :key="index">
<Product :product="product" :login-info="loginInfo"/>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-product" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product" slot="pagination"></div>
</swiper>
</template>
<script>
import { Swiper, SwiperSlide, directive } from "vue-awesome-swiper";
//import "swiper/swiper-bundle.css";
import Product from './Product.vue';
import 'swiper/css/swiper.css'
export default {
props: {
productsData: {},
loginInfo: {}
},
components: {
Swiper,
SwiperSlide,
Product
},
data() {
return {
swiperOptions: {
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-product",
prevEl: ".swiper-button-prev-product",
},
pagination: {
el: ".swiper-pagination-product",
dynamicBullets: true,
},
breakpoints: {
1200: {
slidesPerView: 5,
},
1024: {
slidesPerView: 4,
},
768: {
slidesPerView: 3,
},
576: {
slidesPerView: 2,
},
0: {
slidesPerView: 1.3,
},
},
autoplay: {
delay: 4000,
},
},
products: this.productsData,
};
},
computed: {
swiper() {
return this.$refs.mySwiper.$swiper;
},
},
};
</script>
<style scoped lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px,
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
// Transition
%tr03 {
transition: all 0.3s ease-out;
}
%tr02 {
transition: all 0.2s ease-out;
}
$my-orange: rgb(255, 98, 26);
$my-dark-gray: #5b5b5b;
$my-blue-dark: #0a0d21;
// Vertical or Horizontal position
%v-c {
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
%h-c {
position: absolute;
left: 50%;
-ms-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
%c-c {
position: absolute;
left: 50%;
top: 50%;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.swiper-product {
padding: 75px 0 50px;
margin-top: -50px;
padding-left: 10px;
padding-right: 10px;
@include mq("tablet", max) {
margin-left: -15px;
margin-right: -15px;
padding-bottom: 30px;
}
}
</style>

View File

@@ -0,0 +1,164 @@
<template>
<div>
<div v-if="products.length === 0">
{{ $t('app.search_result', {text: searchText}) }}
</div>
<div class="row" v-if="products.length > 0">
<div v-for="(product, index) in products" class="col-lg-12 col-md-6">
<div class="product my-3">
<div class="row align-items-center">
<div class="col-lg-2">
<a :href="'/product/show/' + product.id + '-' + product.slug">
<div class="product-top">
<div class="type" v-if="product.diffDate && product.isAvailable">NEW</div>
<div class="discound" v-if="product.discountPrice > 0 && product.price_discount && product.isAvailable">
{{ $t('vue.sale') }}
</div>
<div class="xit" v-if="product.leader_of_sales && product.isAvailable">ХИТ</div>
<div class="no-product" v-if="!product.isAvailable">
{{ $t('vue.not_available') }}
</div>
</div>
<div class="product-img">
<img :src="'/' + product.poster_thumb" :alt="getName(product.name)" :class="!product.isAvailable ? 'no-product-img' : ''" >
</div>
</a>
</div>
<div class="col-lg-5">
<h3 class="product-title">
<a :href="'/product/show/' + product.id + '-' + product.slug">{{ getName(product.name) }}</a>
</h3>
<!-- <div class="product-address">{{ $t('app.product.article_number') }}: {{ product.article_number }}</div>-->
<div class="product-price_and_checkout mt-2" v-if="product.discountPrice > 0">
<button class="my-btn my-btn__orange my-btn__orange--small">{{ $t('app.discount') }}</button>
</div>
</div>
<div class="col-lg-2"></div>
<div class="col-lg-3">
<div class="product-price mt-3 mt-lg-0">
<div class="old-price mb-1 text-lg-right" v-if="product.price_discount">
{{ product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}
</div>
<div class="new-price text-lg-right">{{ product.price_discount ? product.price_discount : product.price | number('0,0', { thousandsSeparator: ' ' }) }} {{ $t('app.sum') }}</div>
</div>
<div class="product-buttons">
<div class="product-to_cart justify-content-lg-end">
<button v-if="!product.isCart && product.isAvailable" :class="product.isCart ? 'product-to_basket is-active is-actived' : 'product-to_basket is-actived'" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.to_cart') }}</span>
<div class="added-to-basket" v-html="$t('vue.favorite.added_to_basket')">
</div>
</button>
<button v-if="product.isCart && product.isAvailable" :class="product.isCart ? 'product-to_basket is-active is-actived' : 'product-to_basket is-actived'" data-target="#basket_modal" data-toggle="modal" @click="AddToCart(product)">
<i class="far fa-shopping-basket"></i>
<span>{{ $t('app.to_cart') }}</span>
</button>
<div class="d-flex">
<button class="product-to_compare mr-3 ml-2">
<i class="far fa-balance-scale"></i>
</button>
<button class="product-to_favorite" data-target="#login" data-toggle="modal" v-if="!loginInfo">
<i class="fas fa-heart"></i>
</button>
<button :class="product.isFavorite ? 'product-to_favorite is-active' : 'product-to_favorite'" @click="Favorite(product)" v-if="loginInfo">
<i class="fas fa-heart"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
searchData: {},
loginInfo: {},
searchText: {}
},
data () {
return {
products: this.searchData.data
}
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
async AddToCart(product) {
if (product.isCart) {
this.$eventBus.$emit('cart-preview');
return;
}
const fields = {
product_id: product.children.id,
count: 1
};
const { data } = await axios.post('/cart/store', fields);
if (data.status) {
product.isCart = true;
var basket = document.getElementById("basket-count");
basket.value = data.count;
}
},
async Favorite(product) {
var field = document.getElementById("favorite-count");
var count = field.value;
if (product.isFavorite === false) {
const { data } = await axios.get('/favorites/store/' + product.id);
product.isFavorite = true;
field.value = parseInt(count) + 1;
} else {
const { data } = await axios.get('/favorites/delete/' + product.id);
product.isFavorite = false;
field.value = parseInt(count) - 1;
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,152 @@
<template>
<div>
<div class="m-1">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link" @click="changeLang" id="ru" data-toggle="tab" href="#RU" aria-selected="true">RU</a>
</li>
<li class="nav-item">
<a class="nav-link" @click="changeLang" id="uz" data-toggle="tab" href="#UZ" aria-selected="false">UZ</a>
</li>
<li class="nav-item">
<a class="nav-link" @click="changeLang" data-toggle="tab" href="#all" aria-selected="false">Все</a>
</li>
</ul>
<ul class="nav nav-tabs" v-if="filter.lang" role="tablist">
<li class="nav-item">
<a class="nav-link" @click="changeType" id="mobile" data-toggle="tab" href="#RU" aria-selected="true">Мобильный</a>
</li>
<li class="nav-item">
<a class="nav-link" @click="changeType" id="desktop" data-toggle="tab" href="#UZ" aria-selected="false">Компьютер</a>
</li>
</ul>
<ul class="nav nav-tabs" v-if="filter.type" role="tablist">
<li class="nav-item">
<a class="nav-link" @click="changePlacement" id="top" data-toggle="tab" href="#RU" aria-selected="true">Верхний</a>
</li>
<li class="nav-item">
<a class="nav-link" @click="changePlacement" id="middle" data-toggle="tab" href="#UZ" aria-selected="false">Нижний</a>
</li>
</ul>
</div>
<div class="table-responsive">
<table class="table mb-0" :key="0">
<thead class="thead-dark">
<tr>
<th scope="col" width="50">ID</th>
<th scope="col" width="50">{{ $t('admin.slider.image') }}</th>
<th scope="col">{{ $t('admin.slider.name') }}</th>
<th scope="col">{{ $t('admin.slider.position') }}</th>
<th scope="col" class="text-right">{{ $t('admin.actions') }}</th>
</tr>
</thead>
<tbody v-if="sliders.length === 0">
<tr>
<td class="text-center" colspan="4">
{{ $t('admin.no_data') }}
</td>
</tr>
</tbody>
<draggable v-else v-model="sliders" tag="tbody">
<tr v-for="slider in sliders" :key="slider.id" v-if="(!filter.lang || filter.lang === slider.language) && (!filter.type || filter.type === slider.type) && (!filter.placement || filter.placement === slider.placement)">
<th scope="row">
{{ slider.id }}
</th>
<td>
<img :src="`/${slider.image}`" width="100%" alt="">
</td>
<td>
<i v-if="!slider.published" class="fa fa-info-circle text-danger" data-toggle="tooltip" data-original-title="$t('admin.no_publish')"></i>
{{ slider.name }}
</td>
<td>
{{ slider.position }}
</td>
<td class="text-right">
<a v-if="role.permissions.sliders.update" :href="`/dashboard/sliders/update/${slider.id}`" class="btn btn-sm btn-success btn-icon" data-toggle="tooltip" :data-original-title="$t('admin.edit')">
<i class="feather icon-edit"></i>
</a>
<a v-if="role.permissions.sliders.delete" :href="`/dashboard/sliders/delete/${slider.id}`" class="btn btn-sm btn-danger btn-icon" data-toggle="tooltip" :data-original-title="$t('admin.delete')">
<i class="feather icon-trash"></i>
</a>
</td>
</tr>
</draggable>
</table>
<div class="card-body">
<button class="btn btn-primary" @click="save">
<i class="fa fa-save"></i> Сохранить
</button>
</div>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
name: "SliderView",
components: {
draggable
},
props: {
slidersData: {},
role: {},
},
data() {
return {
sliders: this.slidersData,
filter: {
lang: null,
type: null,
placement: null,
},
}
},
// mounted() {
// console.log(this.sliders)
// },
methods: {
changeLang(event) {
let lang = event.target.getAttribute('id')
this.filter.lang = lang
if (!lang) {
this.filter.type = null
this.filter.placement = null
}
},
changeType(event) {
this.filter.type = event.target.getAttribute('id')
},
changePlacement(event) {
this.filter.placement = event.target.getAttribute('id')
},
changePosition() {
for (let i = 0; i < this.sliders.length; i++) {
let position = i + 1
this.sliders[i].position = i + 1;
}
},
save() {
this.changePosition()
const form = new FormData()
for (let i = 0; i < this.sliders.length; i++) {
let slider = this.sliders[i]
form.append(`sliders[${i}][id]`, slider.id)
form.append(`sliders[${i}][position]`, slider.position)
}
axios.post('/dashboard/sliders/position', form)
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
name: "Mobile"
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,188 @@
<template>
<div>
<div class="specials" v-if="!mobile">
<a v-for="(offer, index) in offers" :key="index" :href="offer.link" class="special" :style="{ 'background-image': 'url(/' + offer.image + ')' }">
<div class="special-content">
<h3 class="special-title">{{ getName(offer.name) }}</h3>
<p class="special-price">{{ getName(offer.description) }}</p>
<div class="my-btn my-btn__orange">
<span>{{ $t('vue.special.more') }}</span>
<i class="fal fa-chevron-right ml-2"></i>
</div>
</div>
</a>
</div>
<swiper
ref="mySwiperSpicial"
class="swiper-container swiper-product swiper-specials"
:options="swiperOptions"
v-if="mobile"
>
<swiper-slide v-for="(offer, index) in offers" :key="index">
<div class="specials">
<a :href="offer.link" class="special" :style="{ 'background-image': 'url(/' + offer.image + ')' }">
<div class="special-content">
<h3 class="special-title">{{ getName(offer.name) }}</h3>
<p class="special-price">{{ getName(offer.description) }}</p>
<div class="my-btn my-btn__orange">
<span>{{ $t('vue.special.more') }}</span>
</div>
</div>
</a>
</div>
</swiper-slide>
<!-- Add Arrows -->
<div class="swiper-button-next swiper-button-next-product" slot="button-next"></div>
<div class="swiper-button-prev swiper-button-prev-product" slot="button-prev"></div>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-product" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
import { Swiper, SwiperSlide } from "vue-awesome-swiper";
import 'swiper/css/swiper.css'
import { isMobileOnly } from "mobile-device-detect";
export default {
props: {
offersData: {}
},
components: {
Swiper,
SwiperSlide,
isMobileOnly
},
data() {
return {
mobile: isMobileOnly ? true : false,
swiperOptions: {
spaceBetween: 20,
navigation: {
nextEl: ".swiper-button-next-product",
prevEl: ".swiper-button-prev-product",
},
pagination: {
el: ".swiper-pagination-product",
dynamicBullets: true,
},
breakpoints: {
1200: {
slidesPerView: 3,
},
1024: {
slidesPerView: 2,
},
768: {
slidesPerView: 2,
},
576: {
slidesPerView: 1,
},
0: {
slidesPerView: 1,
},
},
autoplay: {
delay: 4000,
},
},
offers: this.offersData,
};
},
computed: {
swiper() {
return this.$refs.mySwiperSpicial.$swiper;
},
},
methods: {
getName(name) {
const lang = document.documentElement.lang.substr(0, 2);
let value = '';
if (lang) {
switch(lang){
case "ru":
value = name.ru;
break;
case "uz":
value = name.uz;
break;
}
} else {
value = name.ru;
}
return value;
},
}
}
</script>
<style lang="scss">
$breakpoints: (
"phone-smallest": 251px,
"phone-small": 321px,
"phone": 400px,
"phone-wide": 480px,
"phablet": 560px,
"tablet-small": 640px,
"tablet": 768px,
"tablet-wide": 1024px,
"desktop": 1248px,
"desktop-wide": 1440px,
"desktop-large": 2500px
);
@mixin mq($width, $type: min) {
@if map_has_key($breakpoints, $width) {
$width: map_get($breakpoints, $width);
@if $type==max {
$width: $width - 1px;
}
@media only screen and (#{$type}-width: $width) {
@content;
}
}
}
.swiper-specials {
padding-left: 0;
padding-right: 0;
margin-bottom: 0;
margin-top: 50px;
@include mq("tablet", max) {
margin-left: 0;
margin-right: 0;
margin-bottom: 0px;
padding-top: 0px;
padding-bottom: 30px;
margin-top: 0;
}
.specials {
.special {
width: 100%;
@include mq("tablet", max) {
margin-bottom: 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div>
<section class="section-products" v-if="newsData.length > 0">
<div class="container">
<h2 class="section-title">{{ $t('vue.stocks.sales') }}</h2>
<news-slider :posts-data="newsData"></news-slider>
</div>
</section>
<section class="section-categories">
<div class="container">
<h2 class="section-title">{{ $t('vue.stocks.discount') }}</h2>
<div class="aksiya">
<Product v-for="(product, index) in products" :key="index" :product="product" :login-info="loginInfo"/>
</div>
</div>
</section>
</div>
</template>
<script>
import Product from './Products/Product.vue';
export default {
props: {
productsData: {},
loginInfo: {},
newsData: {}
},
components: {
Product
},
data() {
return {
products: this.productsData.data
}
}
}
</script>

88
resources/js/vendor.js Executable file
View File

@@ -0,0 +1,88 @@
import Vue from 'vue';
import VueInternationalization from 'vue-i18n';
import Locale from './vue-i18n-locales.generated';
import Vue2Filters from 'vue2-filters'
import VueMask from 'v-mask'
import VueSocialSharing from 'vue-social-sharing'
import VueCookie from 'vue-cookie';
// New way (ES Modules)
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//Site
import ProductSlider from './components/Products/ProductSlider';
import ProductShow from './components/Products/ProductShow';
import Login from './components/Auth/Login';
import FavoritesBlock from './components/Favorites/FavoriteBlock';
import SearchBlock from './components/Search/SearchList';
import NewsSlider from './components/News/NewsSlider'
import NewsSection from './components/News/NewsSection'
import CategoriesBlock from "./components/CategoriesBlock";
import CartView from './components/Cart/CartList';
import CatalogShow from "./components/Catalog/CatalogShow";
import CheckoutView from "./components/Checkout/CheckoutView";
import CartPreview from "./components/Cart/CartPreview";
import PartnerSlider from "./components/Partners/PartnerSlider";
import HeaderSlider from './components/Banners/HeaderSlider';
import FeaturesSection from './components/FeaturesSection';
import BonusSection from "./components/BonusSection";
import StocksView from "./components/StocksView";
import SpecialBlock from "./components/Specials/SpecialBlock";
import BrandView from "./components/BrandView";
import Credit from "./components/Products/Credit";
Vue.component('news-slider', NewsSlider);
Vue.component('news-section', NewsSection);
Vue.component('products-slider', ProductSlider);
Vue.component('product-show', ProductShow);
Vue.component('search-block', SearchBlock);
Vue.component('categories-block', CategoriesBlock);
Vue.component('login', Login);
Vue.component('credit-modal', Credit);
Vue.component('favorite-block', FavoritesBlock);
Vue.component('cart-view', CartView);
Vue.component('checkout-view', CheckoutView);
Vue.component('catalog-show', CatalogShow);
Vue.component('cart-preview', CartPreview);
Vue.component('partners-slider', PartnerSlider);
Vue.component('header-slider', HeaderSlider);
Vue.component('features-section', FeaturesSection);
Vue.component('bonus-section', BonusSection);
Vue.component('stocks-view', StocksView);
Vue.component('brand-view', BrandView);
Vue.component('special-block', SpecialBlock);
Vue.use(VueMask);
Vue.use(VueSocialSharing);
Vue.use(VueCookie);
Vue.use(VueInternationalization);
Vue.use(Vue2Filters);
Vue.prototype.$eventBus = new Vue();
const lang = document.documentElement.lang.substr(0, 2);
const i18n = new VueInternationalization({
locale: lang,
messages: Locale
});
const app = new Vue({
el: '#app',
i18n,
});

File diff suppressed because it is too large Load Diff