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

0
resources/css/app.css Executable file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,77 @@
/* This stylesheet generated by Transfonter (https://transfonter.org) on June 21, 2017 9:51 AM */
@font-face {
font-family: 'ProximaNova-Thin';
src: url('ProximaNova-Thin.eot');
src: local('Proxima Nova Thin'), local('ProximaNova-Thin'),
url('ProximaNova-Thin.eot?#iefix') format('embedded-opentype'),
url('ProximaNova-Thin.woff') format('woff'),
url('ProximaNova-Thin.ttf') format('truetype');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-Light";
src: url("ProximaNova-Light.eot");
src: local("Proxima Nova Light"), local("ProximaNova-Light"),
url("ProximaNova-Light.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Light.woff") format("woff"),
url("ProximaNova-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-Regular";
src: url("ProximaNova-Regular.eot");
src: local("Proxima Nova Regular"), local("ProximaNova-Regular"),
url("ProximaNova-Regular.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Regular.woff") format("woff"),
url("ProximaNova-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-SemiBold";
src: url("ProximaNova-Semibold.eot");
src: local("Proxima Nova Semibold"), local("ProximaNova-Semibold"),
url("ProximaNova-Semibold.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Semibold.woff") format("woff"),
url("ProximaNova-Semibold.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-Bold";
src: url("ProximaNova-Bold.eot");
src: local("Proxima Nova Bold"), local("ProximaNova-Bold"),
url("ProximaNova-Bold.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Bold.woff") format("woff"),
url("ProximaNova-Bold.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-ExtraBold";
src: url("ProximaNova-Extrabld.eot");
src: local("Proxima Nova Extrabold"), local("ProximaNova-Extrabld"),
url("ProximaNova-Extrabld.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Extrabld.woff") format("woff"),
url("ProximaNova-Extrabld.ttf") format("truetype");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: "ProximaNova-Black";
src: url("ProximaNova-Black.eot");
src: local("Proxima Nova Black"), local("ProximaNova-Black"),
url("ProximaNova-Black.eot?#iefix") format("embedded-opentype"),
url("ProximaNova-Black.woff") format("woff"),
url("ProximaNova-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
}

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

19
resources/sass/_variables.scss Executable file
View File

@@ -0,0 +1,19 @@
// Body
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
// Colors
$blue: #3490dc;
$indigo: #6574cd;
$purple: #9561e2;
$pink: #f66d9b;
$red: #e3342f;
$orange: #f6993f;
$yellow: #ffed4a;
$green: #38c172;
$teal: #4dc0b5;
$cyan: #6cb2eb;

View File

View File

@@ -0,0 +1,408 @@
// CSS3-Prefix
@mixin css3-prefix($prop, $value) {
-webkit-#{$prop}: #{$value};
-moz-#{$prop}: #{$value};
-ms-#{$prop}: #{$value};
-o-#{$prop}: #{$value};
#{$prop}: #{$value};
}
// div {
// @include css3-prefix(transform, scale3d(2.5, 2, 1.5));
// }
//
@mixin text-clamp($clamp, $height:auto) {
-webkit-line-clamp: $clamp;
height: $height;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
// Fonts
@mixin font-face($name, $file) {
@font-face {
font-family: #{$name};
src: url("../fonts/Qanelas/#{$file}.ttf") format("truetype");
// src: url("../fonts/Qanelas/#{$file}.eot");
// src: url("../fonts/Qanelas/#{$file}.eot?#iefix") format("embedded-opentype"),
// url("../fonts/Qanelas/#{$file}.woff") format("woff"),
// url("../fonts/Qanelas/#{$file}.ttf") format("truetype"),
// url("../fonts/Qanelas/#{$file}.svg?#webfont") format("svg");
}
}
// @include font-face("My Font", my-font);
// Keyframes
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
// Absolute Position
@mixin abs-position ($top, $right, $bottom, $left) {
position: absolute;
top: $top;
right: $right;
bottom: $bottom;
left: $left;
}
// div {
// @include abs-position(100px, 100px, auto, auto);
// }
// Retina Image
@mixin retina-image($image, $width, $height) {
@media (min--moz-device-pixel-ratio: 1.3),
(-o-min-device-pixel-ratio: 2.6/2),
(-webkit-min-device-pixel-ratio: 1.3),
(min-device-pixel-ratio: 1.3),
(min-resolution: 1.3dppx) {
background-image: url($image);
background-size: $width $height;
}
}
// .image {
// background: url("my-image.png") no-repeat;
// @include retina-image("my-image2x.png", 1000px, 500px);
// }
// Arrows
@mixin arrow($direction: down, $size: 5px, $color: #555) {
width: 0;
height: 0;
@if ($direction==left) {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
border-right: $size solid $color;
}
@else if ($direction==right) {
border-top: $size solid transparent;
border-bottom: $size solid transparent;
border-left: $size solid $color;
}
@else if ($direction==down) {
border-left: $size solid transparent;
border-right: $size solid transparent;
border-top: $size solid $color;
}
@else {
border-left: $size solid transparent;
border-right: $size solid transparent;
border-bottom: $size solid $color;
}
}
// without arguments (default)
// div {
// @include arrow();
// }
// with custom arguments
// div {
// @include arrow(up, 10px, #efefef);
// }
// Aspect ratio
@mixin aspect-ratio($width, $height) {
position: relative;
&:before {
display: block;
content: "";
width: 100%;
padding-top: ($height / $width) * 100%;
}
>.inner-box {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
// <!-- HTML -->
// <div class="outer-box">
// <div class="inner-box"></div>
// </div>
// SCSS
// .outer-box {
// @include aspect-ratio(4, 3);
// }
// Media Queries
$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;
}
}
}
// @include mq('tablet-wide') {
// padding-top: 4rem;
// font-size: 2.4rem;
// }
// Z-index
@function z($name) {
@if index($z-indexes, $name) {
@return (length($z-indexes) - index($z-indexes, $name))+1;
}
@else {
@warn 'There is no item "#{$name}" in this list; choose one of: #{$z-indexes}';
@return null;
}
}
$z-indexes: ("outdated-browser",
"modal",
"site-header",
"page-wrapper",
"site-footer"
);
// .site-header {
// z-index: z('site-header');
// }
// Perspective
@mixin hardware($backface: true, $perspective: 1000) {
@if $backface {
backface-visibility: hidden;
}
perspective: $perspective;
}
// Box
@mixin box($width, $height: $width) {
width: $width;
height: $height;
}
// Opacity
@mixin opacity($opacity) {
opacity: $opacity;
$opacity-ie: $opacity * 100;
filter: alpha(opacity=$opacity-ie); //IE8
}
// .fade {
// @include opacity(.4);
// }
// Font Size
@mixin font-size($size, $base: 16) {
font-size: $size; // fallback for old browsers
font-size: ($size / $base) * 1rem;
}
// body {
// @include font-size(16);
// }
// p {
// @include font-size(12, 10);
// }
// Gradients
@mixin gradient($start-color, $end-color, $orientation) {
background: $start-color;
@if $orientation=='vertical' {
background: -webkit-linear-gradient(top, $start-color, $end-color);
background: linear-gradient(to bottom, $start-color, $end-color);
}
@else if $orientation=='horizontal' {
background: -webkit-linear-gradient(left, $start-color, $end-color);
background: linear-gradient(to right, $start-color, $end-color);
}
@else {
background: -webkit-radial-gradient(center, ellipse cover, $start-color, $end-color);
background: radial-gradient(ellipse at center, $start-color, $end-color);
}
}
// .gradient {
// @include gradient(#07c, #06f, vertical);
// }
// Define vertical, horizontal, or both position
@mixin center($position) {
position: absolute;
@if $position=='vertical' {
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
@else if $position=='horizontal' {
left: 50%;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translate(-50%);
}
@else if $position=='both' {
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
}
// Using the mixin
// .foo {
// @include center(both);
// }
// .foo-parent {
// position: relative;
// }
//Padding mixin
@mixin padding($top, $right, $bottom, $left) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
//Margin mixin
@mixin margin($top, $right, $bottom, $left) {
margin-top: $top;
margin-right: $right;
margin-bottom: $bottom;
margin-left: $left;
}
//Usage definition
// @include padding(top, right, bottom, left);
// @include margin(top, right, bottom, left);
//Usage 1
// @include padding(1px, 2px, 3px, 4px);
// @include margin(1px, 2px, 3px, 4px);
//Output 1
// padding: 1px 2px 3px 4px;
// margin: 1px 2px 3px 4px;
//Usage 2 (with null properties)
// @include padding(1px, null, 3px, 4px);
// @include margin(1px, 2px, null, 4px);
//Output 2
// padding-top: 1px;
// padding-bottom: 3px;
// padding-left: 4px;
// margin-top: 1px;
// margin-right: 2px;
// margin-left: 4px;
// PLACEHOLDER
%btn {
padding: 10px;
color: #fff;
cursor: pointer;
border: none;
box-shadow: none;
font-size: 14px;
width: 150px;
margin: 5px 0;
text-align: center;
display: block;
}
/* BUTTON MIXIN
============================================= */
@mixin btn-background($btn-background) {
@extend %btn;
background-color: $btn-background;
&:hover {
background-color: lighten($btn-background, 10%);
}
}
// BUTTONS
// .cta-btn {
// @include btn-background(green);
// }
// .main-btn {
// @include btn-background(orange);
// }
// .info-btn {
// @include btn-background(blue);
// }
@mixin center-vertically {
position: absolute;
top: 50%;
left: 50%;
@include prefix(transform, translate(-50%, -50%), 'webkit''ms');
}
// .vc-box {
// @include center-vertically;
// }

View File

@@ -0,0 +1,123 @@
// 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%);
}
// Background Image
%bgcontain {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
%bgcover {
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
// Flex Center center
%fcc {
display: flex;
justify-content: center;
align-items: center;
}
%fjb {
display: flex;
justify-content: space-between;
align-items: center;
}
%fja {
display: flex;
justify-content: space-around;
align-items: center;
}
%fjs {
display: flex;
justify-content: flex-start;
align-items: center;
}
%fjs {
display: flex;
justify-content: flex-end;
align-items: center;
}
// Img Fluid
%whfluid {
max-width: 100%;
height: auto;
}
// img full
%wh100 {
width: 100%;
height: 100%;
}
// Position Full
%pa_full {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
// Transition
%tr03 {
transition: all 0.3s ease-out;
}
%tr02 {
transition: all 0.2s ease-out;
}
%text-shorten {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
%center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
%aftercenter {
position: relative;
&::after {
content: "";
z-index: -2;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}

View File

@@ -0,0 +1,3 @@
// Colors
$my-orange: #ff621a;
$my-dark-gray: #5b5b5b;

9
resources/sass/app.scss Executable file
View File

@@ -0,0 +1,9 @@
// Fonts
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
//@import './vendor.scss';

View File

@@ -0,0 +1,24 @@
@keyframes mover {
0% {
transform: translateY(2px) scale(.99);
}
100% {
transform: translateY(-10px) scale(1);
}
}
@keyframes mover2 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-10px);
}
}
@keyframes mover3 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(10px);
}
}

81
resources/sass/base/_base.scss Executable file
View File

@@ -0,0 +1,81 @@
html {
scroll-behavior: smooth !important;
}
* {
outline: none !important;
&::selection {
background-color: $my-orange;
color: white;
}
}
.btn.focus,
.btn:focus {
outline: 0;
box-shadow: none;
}
button:focus {
outline: none !important;
outline: 0 auto -webkit-focus-ring-color;
}
.form-control:focus {
outline: 0;
box-shadow: none;
}
.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label,
.input-group > .custom-select:focus,
.input-group > .form-control:focus {
z-index: 0;
}
.btn-dark:not(:disabled):not(.disabled).active:focus,
.btn-dark:not(:disabled):not(.disabled):active:focus,
.show > .btn-dark.dropdown-toggle:focus {
box-shadow: 0;
}
a {
@extend %tr02;
text-decoration: none;
color: inherit;
&:hover {
text-decoration: none;
color: inherit;
}
}
@media (min-width: 1200px) {
.container,
.container-lg,
.container-md,
.container-sm,
.container-xl {
max-width: 1200px;
}
}
body {
&.menu-active {
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
}
body {
background-color: #fff !important;
font-family: "ProximaNova", Arial, Helvetica, sans-serif;
font-weight: normal;
font-style: normal;
}
html {
position: relative;
height: 100%;
}

87
resources/sass/base/_fonts.scss Executable file
View File

@@ -0,0 +1,87 @@
/* Fonts */
// @include font-face("Exo2-Thin", Exo2-Thin); // 100
// @include font-face("Exo2-ExtraLight", Exo2-ExtraLight); // 200
// @include font-face("Exo2-Light", Exo2-Light); // 300
// @include font-face("Exo2-Regular", Exo2-Regular); // 400
// @include font-face("Exo2-Medium", Exo2-Medium); // 500
// @include font-face("Exo2-SemiBold", Exo2-SemiBold); // 600
// @include font-face("Exo2-Bold", Exo2-Bold); // 700
// @include font-face("Exo2-ExtraBold", Exo2-ExtraBold); // 800
// @include font-face("Exo2-Black", Exo2-Black); // 900
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Thin.eot");
src: local("Proxima Nova Thin"), local("ProximaNova-Thin"),
url("../fonts/ProximaNova/ProximaNova-Thin.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Thin.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Thin.ttf") format("truetype");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Light.eot");
src: local("Proxima Nova Light"), local("ProximaNova-Light"),
url("../fonts/ProximaNova/ProximaNova-Light.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Light.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Regular.eot");
src: local("Proxima Nova Regular"), local("ProximaNova-Regular"),
url("../fonts/ProximaNova/ProximaNova-Regular.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Regular.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Semibold.eot");
src: local("Proxima Nova Semibold"), local("ProximaNova-Semibold"),
url("../fonts/ProximaNova/ProximaNova-Semibold.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Semibold.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Semibold.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Bold.eot");
src: local("Proxima Nova Bold"), local("ProximaNova-Bold"),
url("../fonts/ProximaNova/ProximaNova-Bold.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Bold.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Bold.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Extrabld.eot");
src: local("Proxima Nova Extrabold"), local("ProximaNova-Extrabld"),
url("../fonts/ProximaNova/ProximaNova-Extrabld.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Extrabld.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Extrabld.ttf") format("truetype");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: "ProximaNova";
src: url("../fonts/ProximaNova/ProximaNova-Black.eot");
src: local("Proxima Nova Black"), local("ProximaNova-Black"),
url("../fonts/ProximaNova/ProximaNova-Black.eot?#iefix") format("embedded-opentype"),
url("../fonts/ProximaNova/ProximaNova-Black.woff") format("woff"),
url("../fonts/ProximaNova/ProximaNova-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,24 @@
.section-title {
font-size: 36px;
font-weight: normal;
color: rgb(34, 34, 34);
@include mq("tablet", max) {
font-size: 32px;
}
a {
&:hover {
color: $my-orange;
text-decoration: underline;
}
}
}
.section-title-small {
font-size: 20px;
font-weight: 600;
color: rgb(26, 26, 26);
line-height: 1.333;
text-align: left;
}

View File

View File

@@ -0,0 +1,86 @@
// Hamburger
// ==================================================
.hamburger {
padding: $hamburger-padding-y $hamburger-padding-x;
display: inline-block;
cursor: pointer;
transition-property: opacity, filter;
transition-duration: 0.15s;
transition-timing-function: linear;
// Normalize (<button>)
font: inherit;
color: inherit;
text-transform: none;
background-color: transparent;
border: 0;
margin: 0;
overflow: visible;
&:hover {
@if $hamburger-hover-use-filter == true {
filter: $hamburger-hover-filter;
}
@else {
opacity: $hamburger-hover-opacity;
}
}
&.is-active {
&:hover {
@if $hamburger-hover-use-filter == true {
filter: $hamburger-active-hover-filter;
}
@else {
opacity: $hamburger-active-hover-opacity;
}
}
.hamburger-inner,
.hamburger-inner::before,
.hamburger-inner::after {
background-color: $hamburger-active-layer-color;
}
}
}
.hamburger-box {
width: $hamburger-layer-width;
height: $hamburger-layer-height * 3 + $hamburger-layer-spacing * 2;
display: inline-block;
position: relative;
}
.hamburger-inner {
display: block;
top: 50%;
margin-top: $hamburger-layer-height / -2;
&,
&::before,
&::after {
width: $hamburger-layer-width;
height: $hamburger-layer-height;
background-color: $hamburger-layer-color;
border-radius: $hamburger-layer-border-radius;
position: absolute;
transition-property: transform;
transition-duration: 0.15s;
transition-timing-function: ease;
}
&::before,
&::after {
content: "";
display: block;
}
&::before {
top: ($hamburger-layer-spacing + $hamburger-layer-height) * -1;
}
&::after {
bottom: ($hamburger-layer-spacing + $hamburger-layer-height) * -1;
}
}

View File

@@ -0,0 +1,144 @@
.my-btn__white {
padding: 12px 15px;
width: 170px;
margin-top: 20px;
display: inline-block;
border-style: solid;
border-width: 2px;
border-color: rgb(255, 255, 255);
background-color: rgba(203, 86, 42, 0);
font-size: 16px;
border-radius: 25.5px;
font-weight: normal;
color: rgb(255, 255, 255);
line-height: 1;
text-align: center;
i {
font-size: 14px;
@extend %tr02;
}
&:hover {
i {
transform: translateX(5px);
}
color: white;
background-color: rgba(white, 0.15);
}
}
.my-btn {
height: 45px;
min-width: 120px;
padding: 8px 15px;
border: 1px solid transparent;
border-radius: 22.5px;
font-size: 18px;
font-weight: normal;
color: rgb(0, 0, 0);
line-height: 1;
text-align: center;
@extend %tr02;
&__gray {
background-color: rgb(239, 239, 239);
&:hover {
background-color: rgba($color: $my-dark-gray, $alpha: 0.3);
}
}
&__orange {
background-color: $my-orange;
color: white;
&:hover {
background-color: #d65a12;
}
&--small {
padding: 4px 10px;
font-size: 14px;
height: auto;
min-width: unset;
cursor: unset !important;
&:hover {
background-color: $my-orange;
}
}
}
}
.btn-links {
display: inline-block;
min-width: 200px;
padding: 15px;
border: 1px solid transparent;
border-radius: 27.5px;
font-size: 18px;
font-weight: normal;
line-height: 1;
vertical-align: middle;
text-align: center;
text-decoration: none;
&:hover {
text-decoration: none;
}
&__one {
background-color: #f8445a;
border-color: rgb(248, 68, 90);
color: white;
&.bg__green {
background-color: #42c28d;
border-color: #42c28d;
}
&:hover {
color: white;
box-shadow: 0px 5px 14.25px 0.75px rgba(248, 68, 90, 0.35);
&.bg__green {
background-color: #42c28d;
box-shadow: 0px 5px 14.25px 0.75px rgba(66, 194, 141, 0.35);
border-color: #42c28d;
}
}
}
&__two {
background-color: $my-orange;
border-color: $my-orange;
color: white;
&:hover {
color: white;
box-shadow: 0px 5px 14.25px 0.75px rgba(255, 99, 25, 0.35);
}
}
&__three {
background-color: #fff;
border-color: rgba(0, 0, 0, 0.5);
border-width: 2px;
color: white;
color: rgb(0, 0, 0);
&:hover {
background-color: rgba($color: #fff, $alpha: 0.4);
}
}
}
.no-button {
background-color: #c2c2c2 !important;
border-color: #c2c2c2 !important;
box-shadow: none !important;
cursor: no-drop;
&:hover {
background-color: #c2c2c2 !important;
box-shadow: none !important;
border-color: #c2c2c2 !important;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
@charset "UTF-8";
/*!
* Hamburgers
* @description Tasty CSS-animated hamburgers
* @author Jonathan Suh @jonsuh
* @site https://jonsuh.com/hamburgers
* @link https://github.com/jonsuh/hamburgers
*/
// Settings
// ==================================================
$hamburger-padding-x : 0px !default;
$hamburger-padding-y : 0px !default;
$hamburger-layer-width : 22px !default;
$hamburger-layer-height : 2px !default;
$hamburger-layer-spacing : 4px !default;
$hamburger-layer-color : #333 !default;
$hamburger-layer-border-radius : 4px !default;
$hamburger-hover-opacity : 1 !default;
$hamburger-active-layer-color : $hamburger-layer-color !default;
$hamburger-active-hover-opacity: $hamburger-hover-opacity !default;
// To use CSS filters as the hover effect instead of opacity,
// set $hamburger-hover-use-filter as true and
// change the value of $hamburger-hover-filter accordingly.
$hamburger-hover-use-filter : false !default;
$hamburger-hover-filter : opacity(50%) !default;
$hamburger-active-hover-filter: $hamburger-hover-filter !default;
// Types (Remove or comment out what you dont need)
// ==================================================
$hamburger-types: (
3dx,
3dx-r,
3dy,
3dy-r,
3dxy,
3dxy-r,
arrow,
arrow-r,
arrowalt,
arrowalt-r,
arrowturn,
arrowturn-r,
boring,
collapse,
collapse-r,
elastic,
elastic-r,
emphatic,
emphatic-r,
minus,
slider,
slider-r,
spin,
spin-r,
spring,
spring-r,
stand,
stand-r,
squeeze,
vortex,
vortex-r
) !default;
// Base Hamburger (We need this)
// ==================================================
@import "base";
// Hamburger types
// ==================================================
@import "types/3dx";
@import "types/3dx-r";
@import "types/3dy";
@import "types/3dy-r";
@import "types/3dxy";
@import "types/3dxy-r";
@import "types/arrow";
@import "types/arrow-r";
@import "types/arrowalt";
@import "types/arrowalt-r";
@import "types/arrowturn";
@import "types/arrowturn-r";
@import "types/boring";
@import "types/collapse";
@import "types/collapse-r";
@import "types/elastic";
@import "types/elastic-r";
@import "types/emphatic";
@import "types/emphatic-r";
@import "types/minus";
@import "types/slider";
@import "types/slider-r";
@import "types/spin";
@import "types/spin-r";
@import "types/spring";
@import "types/spring-r";
@import "types/stand";
@import "types/stand-r";
@import "types/squeeze";
@import "types/vortex";
@import "types/vortex-r";
// ==================================================
// Cooking up additional types:
//
// The Sass for each hamburger type should be nested
// inside an @if directive to check whether or not
// it exists in $hamburger-types so only the CSS for
// included types are generated.
//
// e.g. hamburgers/types/_new-type.scss
//
// @if index($hamburger-types, new-type) {
// .hamburger--new-type {
// ...
// }
// }

View File

@@ -0,0 +1,231 @@
.modal {
&-content,
&-body,
&-header,
&-footer {
border: 0;
border-radius: 10px;
}
&-body {
padding: 30px 40px;
@include mq("tablet", max) {
padding-left: 20px;
padding-right: 20px;
}
position: relative;
.close {
position: absolute;
top: 15px;
right: 15px;
}
h4 {
font-size: 30px;
font-weight: 600;
color: rgb(34, 34, 34);
text-align: left;
@include mq("tablet", max) {
font-size: 24px;
}
}
}
}
.terms-of-use {
&__content {
margin-top: 20px;
font-size: 16px;
font-weight: normal;
color: rgb(34, 34, 34);
line-height: 1.3;
text-align: left;
max-height: 600px;
overflow-y: auto;
padding-right: 10px;
// @include mq("desktop", min) {
/* width */
&::-webkit-scrollbar {
width: 4px;
height: 4px;
}
/* Track */
&::-webkit-scrollbar-track {
background-color: rgba(#b5bdcc, 0.329);
}
/* Handle */
&::-webkit-scrollbar-thumb {
background-color: #b5bdcc;
}
/* Handle on hover */
&::-webkit-scrollbar-thumb:hover {
background-color: #b5bdcc;
}
// }
}
}
.basket-modal {
.product {
padding: 10px;
margin: 20px 0;
&-title {
font-size: 16px;
a {
font-size: 16px;
}
}
@include mq("desktop", min) {
// box-shadow: none;
// padding: 0px;
}
&-img {
margin-top: 0;
margin-bottom: 0;
height: 120px;
}
.product-buttons {
margin-bottom: 0;
button {
width: 100%;
}
}
}
.sum-of-products {
margin-right: 0;
}
}
.basket-modal {
.btn-links {
height: 45px;
padding: 13px 5px;
font-size: 18px;
}
@media (min-width: 576px) {
.modal-dialog {
max-width: 550px;
}
}
@media (min-width: 900px) {
.modal-dialog {
max-width: 850px;
}
}
@media (max-width: 576px) {
form {
button,
a {
width: 100%;
margin: 10px 0 !important;
}
.product-buttons {
width: 100%;
}
}
}
}
.alert-when-has-product {
h5 {
font-size: 20px;
font-weight: 600;
color: rgb(34, 34, 34);
text-align: left;
@include mq("tablet", max) {
font-size: 20px;
}
}
p {
font-size: 16px;
font-weight: normal;
color: rgb(34, 34, 34);
text-align: left;
@include mq("tablet", max) {
font-size: 16px;
}
}
}
.installment {
.nav-pills .nav-link {
border: 2px solid #b5bdcc;
margin: 0 5px;
background-color: transparent;
color: #000;
min-width: 150px;
text-align: center;
position: relative;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
@media screen and (max-width: 576px) {
min-width: unset;
}
&::after {
content: "";
position: absolute;
top: 5px;
right: 10px;
width: 15px;
height: 15px;
border-radius: 50%;
border: 2px solid #b5bdcc;
}
&::before {
content: "";
position: absolute;
top: 8px;
right: 13px;
width: 9px;
height: 9px;
border-radius: 50%;
background-color: $my-orange;
opacity: 0;
}
}
.nav-item {
@media screen and (max-width: 576px) {
width: 48%;
}
}
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
border-color: $my-orange;
&::after {
border-color: $my-orange;
}
&::before {
opacity: 1;
}
}
.my-form__group {
input:disabled {
color: #000;
}
}
}

View File

@@ -0,0 +1,327 @@
.my-form {
&__group {
display: flex;
flex-direction: column;
label {
order: -1;
}
}
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
p {
font-size: 16px;
font-weight: normal;
color: rgb(34, 34, 34);
line-height: 1.5;
text-align: left;
}
label {
display: block;
font-size: 18px;
font-weight: normal;
color: rgba(34, 34, 34, 0.502);
line-height: 1.333;
@extend %tr02;
}
input,
select,
textarea {
display: block;
width: 100%;
border-style: solid;
border-width: 1px;
border-color: rgba(34, 34, 34, 0.2);
border-radius: 6px;
background-color: transparent;
height: 50px;
padding: 6px 15px;
color: rgba(34, 34, 34, 0.99);
@extend %tr02;
font-size: 18px;
font-weight: 600;
line-height: 1.333;
@include mq("tablet", max) {
font-size: 16px;
}
@include mq("phone-small", max) {
font-size: 14px;
}
&::placeholder {
color: rgba(34, 34, 34, 0.502);
}
&:focus {
border-color: $my-orange;
& ~ label {
color: $my-orange;
}
}
}
textarea {
height: auto;
resize: none;
}
select {
&:focus {
border-color: rgba(34, 34, 34, 0.2);
box-shadow: unset;
& ~ label {
color: $my-orange;
}
}
}
.reset-password {
font-size: 16px;
font-weight: normal;
text-decoration: underline;
text-align: right;
}
.form-payment {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
label {
font-size: 16px;
font-weight: 600;
color: rgb(26, 26, 26) !important;
line-height: 1.5;
cursor: pointer;
}
& > div {
margin-top: 5px;
margin-bottom: 5px;
}
& + div {
margin-top: 50px;
textarea {
display: block;
width: 100%;
border-radius: 8px;
padding: 8px 15px;
background-color: transparent;
border: 1px solid #fff;
color: rgba(34, 34, 34, 0.99);
font-weight: normal;
font-size: 14px;
line-height: 24px;
transition: all 0.2s ease-in-out;
resize: none;
border-color: rgba(0, 0, 0, 0.2);
&:focus {
border-color: $my-orange;
color: #000;
}
}
}
}
h3 {
font-size: 20px;
font-weight: 600;
color: rgb(26, 26, 26);
line-height: 1.333;
text-align: left;
}
h2 {
font-size: 24px;
font-weight: 600;
color: rgb(26, 26, 26);
line-height: 1.333;
text-align: left;
}
h4 {
font-size: 16px;
font-weight: bold;
color: rgb(26, 26, 26);
line-height: 1.333;
text-align: left;
}
.custom-control-label::before {
background-color: transparent;
}
.custom-control-label::after {
width: 1.7rem;
height: 1.7rem;
top: -1px;
left: -1.7rem;
background: no-repeat 35%/35% 35%;
// background: unset;
// content: "\f00c";
// font-family: "Font Awesome 5 Pro";
// font-weight: 300;
}
.custom-checkbox
.custom-control-input:checked
~ .custom-control-label::after {
background-image: url("../img/check.png");
}
.custom-control-input:not(:disabled):active ~ .custom-control-label::before {
color: #fff;
background-color: transparent;
border-color: $my-orange;
}
.custom-control-input:checked ~ .custom-control-label::before {
color: white;
background-color: transparent;
border-color: $my-orange;
}
.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {
border-color: #adb5bd;
}
.custom-control-input:focus ~ .custom-control-label::before {
box-shadow: unset;
}
.custom-radio {
font-size: 16px;
font-weight: normal;
color: rgb(0, 0, 0);
line-height: 1.5;
}
.custom-radio .custom-control-input:checked ~ .custom-control-label::after {
background-image: none;
width: 11px;
height: 11px;
background-color: #ff621a;
border-radius: 50%;
top: 0.4rem;
left: -1.35rem;
}
.custom-radio .custom-control-label::after {
background: no-repeat 38%/30% 30%;
}
.my-custom-control {
.custom-control-label {
font-size: 16px;
color: #000;
font-weight: normal;
}
.custom-control-input:checked ~ .custom-control-label::before {
color: #fff;
background-color: #ff621a;
border-color: #ff621a;
}
}
}
.my-form__countBy {
select {
height: 32px;
padding: 5px 10px;
text-decoration: none;
color: #000;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
font-weight: normal;
color: #222;
border-style: solid;
border-width: 1px;
border-color: #cbccd3;
border-radius: 3px;
background-color: rgba(255, 255, 255, 0);
min-width: 150px;
@include mq("tablet", max) {
min-width: unset;
max-width: 100px;
}
}
p {
font-size: 16px;
font-weight: 600;
color: #222;
}
}
.select-months {
position: relative;
&::after {
content: "";
position: absolute;
top: -12px;
width: 100%;
height: 1px;
background-color: #000;
opacity: 0.3;
z-index: 0;
}
margin-top: 30px;
padding: 0 15px;
label {
cursor: pointer;
min-width: 60px;
text-align: center;
font-size: 16px;
&::before {
top: -20px;
left: 50%;
transform: translateX(-50%);
}
color: #000 !important;
}
input {
display: none;
}
.custom-control {
&-inline {
margin: 0 5px;
}
padding-left: 0;
position: relative;
z-index: 22;
}
.custom-control-label::after {
top: -17.5px;
left: 50%;
transform: translateX(-50%);
background-color: #fff;
}
.custom-radio .custom-control-input:checked ~ .custom-control-label::after {
top: -17.5px;
left: 50%;
transform: translateX(-50%);
}
.custom-control-label::before {
background-color: #fff;
}
.custom-control-input:checked ~ .custom-control-label::before {
background-color: #fff;
}
}

View File

@@ -0,0 +1,281 @@
// .my-navbars {
// position: relative;
// &::after {
// content: "";
// width: 100vw;
// height: 100%;
// position: absolute;
// background-color: rgba(255, 255, 255, 0.102);
// left: 0;
// right: 0;
// top: 0;
// }
// }
.my-navbar {
overflow: hidden;
// background-color: #2c2c2c;
background-color: #00b58d;
height: 80px;
@include mq("tablet-wide", max) {
overflow-y: auto;
position: absolute;
width: 84%;
height: 100%;
min-height: 100%;
top: 0;
// padding-top: 90px;
padding-top: 110px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
transform: translateX(0px);
left: -100%;
z-index: 111;
transition: 0.2s transform ease-out;
@include mq("phablet", max) {
min-height: 105%;
}
}
&-active {
transform: translateX(118%);
}
.container {
height: 100%;
@include mq("tablet-wide", max) {
height: auto;
padding: 0;
}
.nav {
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
&-item {
width: calc(100% / 8);
@include mq("tablet-wide", max) {
width: 100%;
}
}
@include mq("tablet-wide", max) {
flex-direction: column;
}
}
}
.nav-item {
overflow: hidden;
list-style-type: none;
height: 100%;
& > i {
display: none;
width: 50px;
height: 30px;
position: absolute;
top: 5px;
transform: translateX(-50%);
right: -15px;
color: #999;
// color: #ff621a;
// color: #00b58d;
z-index: 11;
margin-left: 15px;
padding: 5px;
}
@include mq("tablet-wide", max) {
position: relative;
border-bottom: 1px solid #00000015;
padding-left: 10px;
& > i {
display: flex;
justify-content: center;
align-items: center;
}
}
&.checkout {
// background-image: linear-gradient(137deg, #f8583d 0%, #f8445a 100%);
background-image: linear-gradient(137deg, #ff8a52, #ff6319);
@include mq("tablet-wide", max) {
background-image: unset;
a {
color: $my-orange;
}
}
}
}
.nav-item .dropbtn {
height: 100%;
border: none;
outline: none;
padding: 10px;
background-color: inherit;
text-decoration: none;
font-size: 15px;
font-family: "ProximaNova", Arial, Helvetica, sans-serif;
color: rgb(255, 255, 255);
line-height: 1.333;
display: flex;
justify-content: center;
align-items: center;
@include mq("tablet-wide", max) {
justify-content: flex-start;
color: #000;
height: auto;
}
span {
text-align: center;
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
@include mq("tablet-wide", max) {
br {
display: none;
}
text-align: left;
margin: unset;
width: 80%;
display: inline-block;
}
}
}
& a:hover,
.nav-item:hover .dropbtn {
background-color: rgba(255, 255, 255, 0.102);
}
.nav-item-content {
overflow-y: auto;
@include mq("tablet-wide", min) {
height: 353px;
}
@include mq("desktop", min) {
height: 400px;
}
@include mq("desktop-wide", min) {
height: 503px;
}
padding: 30px 0;
display: none;
position: absolute;
width: 100%;
left: 0;
z-index: 1111;
box-shadow: 0px 20px 18px 2px rgba(5, 8, 9, 0.1);
background-color: rgb(255, 255, 255);
@include mq("tablet-wide", max) {
padding: 10px 20px;
width: 95%;
max-height: 350px;
overflow-y: auto;
margin: 0 auto;
position: relative;
display: none;
box-shadow: unset;
}
a {
text-decoration: none;
display: block;
margin: 5px 0;
text-align: left;
font-size: 14px;
font-weight: normal;
color: rgb(34, 34, 34);
padding-right: 36px;
@include mq("tablet", max) {
padding-right: 12px;
}
&:hover {
color: $my-orange;
}
}
h3,
h3 a {
font-size: 16px;
font-weight: bold;
color: rgb(34, 34, 34);
line-height: 1.2;
@include mq("tablet-wide", max) {
font-size: 14px;
font-weight: normal;
}
}
h3 {
display: flex;
align-items: center;
position: relative;
img {
position: absolute;
left: -38px;
top: 5px;
width: 30px;
height: 30px;
object-fit: cover;
object-position: center;
@include mq("desktop", max) {
left: -30px;
top: 5px;
width: 25px;
height: 25px;
}
@include mq("tablet-wide", max) {
display: none;
}
}
i {
margin-left: 10px;
font-size: 14px;
padding: 5px;
width: 50px;
height: 30px;
position: absolute;
top: 0px;
transform: translateX(-50%);
right: -30px;
z-index: 11;
margin-left: 15px;
padding: 5px;
display: flex;
justify-content: center;
align-items: center;
color: #999;
@include mq("tablet-wide", min) {
display: none;
}
}
}
&__toggle {
@include mq("tablet-wide", max) {
display: none;
padding-left: 10px;
}
}
}
.nav-item:hover .nav-item-content {
@include mq("tablet-wide", min) {
display: block;
}
}
}

View File

@@ -0,0 +1,33 @@
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 99999999;
transform: translate3d(0, -50px, 0);
transition: transform 0.5s ease-out;
}
.pace.pace-active {
transform: translate3d(0, 0, 0);
}
.pace .pace-progress {
display: block;
position: fixed;
z-index: 2000;
top: 0;
right: 100%;
width: 100%;
height: 2px;
background: $my-orange;
pointer-events: none;
}

View File

@@ -0,0 +1,51 @@
html, .product-subtitle {
@include mq("desktop", min) {
/* width */
&::-webkit-scrollbar {
width: 8px;
height: 4px;
}
/* Track */
&::-webkit-scrollbar-track {
background-color: rgba(#b5bdcc, 0.329);
}
/* Handle */
&::-webkit-scrollbar-thumb {
background: rgba(#2c2c2c, 1);
background-image: linear-gradient(137deg, #f8583d 0, #f8445a 100%);
}
/* Handle on hover */
&::-webkit-scrollbar-thumb:hover {
background: #2c2c2c;
background-image: linear-gradient(137deg, #f8583d 0, #f8445a 100%);
}
}
}
// .nav-item-content {
// @include mq("desktop", min) {
// /* width */
// &::-webkit-scrollbar {
// width: 8px;
// height: 4px;
// }
// /* Track */
// &::-webkit-scrollbar-track {
// background-color: rgba(#b5bdcc, 0.329);
// }
// /* Handle */
// &::-webkit-scrollbar-thumb {
// background: rgba(#2c2c2c, 1);
// }
// /* Handle on hover */
// &::-webkit-scrollbar-thumb:hover {
// background: #2c2c2c;
// }
// }
// }

View File

@@ -0,0 +1,412 @@
.swiper-header {
&__item {
width: 100%;
@extend %bgcover;
@include mq("desktop", min) {
height: 453px;
}
@include mq("desktop-wide", min) {
height: 553px;
}
@include mq("desktop-large", min) {
height: 753px;
}
@include mq("desktop", max) {
height: 353px;
}
@include mq("tablet-wide", max) {
height: 303px;
}
}
.swiper-pagination-bullets {
@include mq("tablet", min) {
bottom: 20px;
}
}
.swiper-pagination-bullets .swiper-pagination-bullet {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: rgb(255, 255, 255);
opacity: 0.502;
@extend %tr02;
}
.swiper-pagination-bullets .swiper-pagination-bullet-active {
width: 20px;
border-radius: 20px;
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
right: 50px;
@include mq("tablet", max) {
display: none;
}
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
left: 50px;
@include mq("tablet", max) {
display: none;
}
}
.swiper-button-next:after,
.swiper-container-rtl .swiper-button-prev:after {
content: "\f061";
font-family: "Font Awesome 5 Pro";
font-weight: 300;
font-size: 18px;
color: white;
opacity: 0.7;
}
.swiper-button-prev:after,
.swiper-container-rtl .swiper-button-next:after {
content: "\f060";
font-family: "Font Awesome 5 Pro";
font-weight: 300;
font-size: 18px;
color: white;
opacity: 0.7;
}
.swiper-button-next:before,
.swiper-button-prev::before {
border-color: rgb(255, 255, 255);
opacity: 0.7;
border-style: solid;
border-width: 2px;
border-radius: 50%;
width: 44px;
height: 44px;
position: absolute;
content: "";
@extend %c-c;
}
}
.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;
.swiper-wrapper {
z-index: 22;
}
}
}
.swiper-banners,
.swiper-product {
.swiper-button-next,
.swiper-button-prev {
z-index: 2;
@include mq("tablet", min) {
top: 25px;
}
@include mq("tablet", max) {
display: none;
}
&::after {
width: 36px;
height: 36px;
border-radius: 50%;
content: "";
position: absolute;
@extend %c-c;
z-index: -1;
background-color: #f2f4f6;
@extend %tr02;
}
&::before {
font-family: "Font Awesome 5 Pro";
font-weight: 400;
color: #999;
font-size: 14px;
position: absolute;
@extend %c-c;
z-index: 0;
@extend %tr02;
}
&:hover::after {
background-color: $my-orange;
}
&:hover::before {
color: white;
}
}
.swiper-button-prev {
@include mq("tablet", min) {
right: 145px;
left: unset;
}
&::before {
content: "\f053";
}
}
.swiper-button-next {
&::before {
content: "\f054";
}
}
.swiper-pagination {
width: 100%;
@include mq("tablet", min) {
height: 50px;
top: 20px;
right: 50px;
left: unset;
}
@include mq("tablet", max) {
bottom: 0;
}
}
.swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
@include mq("tablet", min) {
left: unset !important;
transform: unset !important;
}
}
.swiper-pagination-bullet {
background: rgb(144, 144, 144);
opacity: 1;
}
.swiper-pagination-bullet-active-main {
background: $my-orange;
}
}
.swiper-banners {
padding: 75px 0 0px;
margin-top: -50px;
@include mq("tablet", max) {
// margin-left: -15px;
// margin-right: -15px;
padding-bottom: 30px;
}
}
.swiper-partners {
.swiper-button-next,
.swiper-button-prev {
@include mq("tablet", max) {
top: 70%;
}
}
}
.swiper-news {
margin-bottom: 20px;
}
// Product item slider
.slider-small {
.sldier-slide {
height: 100%;
}
.slider__img {
height: 70px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
background-color: #fff;
padding: 5px;
img {
height: 60px;
width: 100%;
object-fit: contain;
object-position: center;
}
border: 1px solid transparent;
}
.slick-current {
border: 1px solid #d3d3d3;
border-radius: 4px;
}
@include mq("tablet", max) {
display: none !important;
}
.slick-prev,
.slick-next {
width: 40px;
height: 40px;
border-radius: 50%;
z-index: 45;
}
.slick-prev:before,
.slick-next:before {
color: $my-dark-gray;
font-size: 24px;
font-family: "Font Awesome 5 Pro";
font-weight: 300;
}
.slick-prev:before {
content: "\f137";
}
.slick-next:before {
content: "\f138";
}
}
.slider-big {
margin: 5px;
margin-bottom: 10px;
.slider__content {
height: 400px;
position: relative;
padding: 30px;
padding-top: 32px;
min-height: 1px;
}
.slick-list {
border-radius: 5px;
background-color: #fff;
box-shadow: 0 3px 15px 3px rgba(5, 8, 9, 0.1);
}
.slider__img {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
img {
box-shadow: unset;
max-width: 100%;
max-height: 100%;
width: unset !important;
@include mq("desktop", min) {
}
@include mq("tablet-wide", max) {
// max-width: 300px;
}
@include mq("tablet", max) {
// max-width: 100%;
}
}
}
// Arrows
.slick-prev,
.slick-next {
width: 40px;
height: 40px;
border-radius: 50%;
z-index: 45;
}
.slick-prev {
left: -15px;
}
.slick-next {
right: -15px;
}
.slick-prev:before,
.slick-next:before {
color: $my-dark-gray;
font-size: 36px;
font-family: "Font Awesome 5 Pro";
font-weight: 300;
}
.slick-prev:before {
content: "\f137";
}
.slick-next:before {
content: "\f138";
}
}
// XZoom
.xzoom-source {
@include mq("tablet-wide", max) {
display: none !important;
}
}
.xzoom-preview {
z-index: 9999;
}
.swiper-category {
margin-top: 0;
padding-top: 10px;
.category-item {
width: 100%;
margin: 0;
&__title {
@include mq("tablet", max) {
padding-left: 5px;
padding-right: 5px;
}
}
}
@include mq("tablet", min) {
padding-left: 0;
padding-right: 0;
}
}
.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;
margin-top: 0;
}
.specials {
.special {
width: 100%;
@include mq("tablet", max) {
margin-bottom: 0;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dx-r) {
/*
* 3DX Reverse
*/
.hamburger--3dx-r {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateY(-180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dx) {
/*
* 3DX
*/
.hamburger--3dx {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateY(180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dxy-r) {
/*
* 3DXY Reverse
*/
.hamburger--3dxy-r {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateX(180deg) rotateY(180deg) rotateZ(-180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dxy) {
/*
* 3DXY
*/
.hamburger--3dxy {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateX(180deg) rotateY(180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dy-r) {
/*
* 3DY Reverse
*/
.hamburger--3dy-r {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateX(180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
@if index($hamburger-types, 3dy) {
/*
* 3DY
*/
.hamburger--3dy {
.hamburger-box {
perspective: $hamburger-layer-width * 2;
}
.hamburger-inner {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
background-color 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
&::before,
&::after {
transition: transform 0s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
&.is-active {
.hamburger-inner {
background-color: transparent !important;
transform: rotateX(-180deg);
&::before {
transform: translate3d(0, $hamburger-layer-height + $hamburger-layer-spacing, 0) rotate(45deg);
}
&::after {
transform: translate3d(0, ($hamburger-layer-height + $hamburger-layer-spacing) * -1, 0) rotate(-45deg);
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
@if index($hamburger-types, arrow-r) {
/*
* Arrow Right
*/
.hamburger--arrow-r.is-active {
.hamburger-inner {
&::before {
transform: translate3d($hamburger-layer-width * 0.2, 0, 0) rotate(45deg) scale(0.7, 1);
}
&::after {
transform: translate3d($hamburger-layer-width * 0.2, 0, 0) rotate(-45deg) scale(0.7, 1);
}
}
}
}

View File

@@ -0,0 +1,16 @@
@if index($hamburger-types, arrow) {
/*
* Arrow
*/
.hamburger--arrow.is-active {
.hamburger-inner {
&::before {
transform: translate3d($hamburger-layer-width * -0.2, 0, 0) rotate(-45deg) scale(0.7, 1);
}
&::after {
transform: translate3d($hamburger-layer-width * -0.2, 0, 0) rotate(45deg) scale(0.7, 1);
}
}
}
}

View File

@@ -0,0 +1,36 @@
@if index($hamburger-types, arrowalt-r) {
/*
* Arrow Alt Right
*/
.hamburger--arrowalt-r {
.hamburger-inner {
&::before {
transition: top 0.1s 0.1s ease,
transform 0.1s cubic-bezier(0.165, 0.84, 0.44, 1);
}
&::after {
transition: bottom 0.1s 0.1s ease,
transform 0.1s cubic-bezier(0.165, 0.84, 0.44, 1);
}
}
&.is-active {
.hamburger-inner {
&::before {
top: 0;
transform: translate3d($hamburger-layer-width * 0.2, $hamburger-layer-width * -0.25, 0) rotate(45deg) scale(0.7, 1);
transition: top 0.1s ease,
transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
&::after {
bottom: 0;
transform: translate3d($hamburger-layer-width * 0.2, $hamburger-layer-width * 0.25, 0) rotate(-45deg) scale(0.7, 1);
transition: bottom 0.1s ease,
transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
@if index($hamburger-types, arrowalt) {
/*
* Arrow Alt
*/
.hamburger--arrowalt {
.hamburger-inner {
&::before {
transition: top 0.1s 0.1s ease,
transform 0.1s cubic-bezier(0.165, 0.84, 0.44, 1);
}
&::after {
transition: bottom 0.1s 0.1s ease,
transform 0.1s cubic-bezier(0.165, 0.84, 0.44, 1);
}
}
&.is-active {
.hamburger-inner {
&::before {
top: 0;
transform: translate3d($hamburger-layer-width * -0.2, $hamburger-layer-width * -0.25, 0) rotate(-45deg) scale(0.7, 1);
transition: top 0.1s ease,
transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
&::after {
bottom: 0;
transform: translate3d($hamburger-layer-width * -0.2, $hamburger-layer-width * 0.25, 0) rotate(45deg) scale(0.7, 1);
transition: bottom 0.1s ease,
transform 0.1s 0.1s cubic-bezier(0.895, 0.03, 0.685, 0.22);
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More