This commit is contained in:
mohadese namavar
2024-06-16 00:22:14 +04:30
commit ec84dfd222
322 changed files with 77942 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
<template>
<section class="cart-bought-products">
<div>
<h2>{{ $t("buyersBoughtProducts") }}</h2>
<Swiper slides-per-view="auto">
<SwiperSlide v-for="(product, i) in buyers" :key="i">
<ProductCard :data="product" mode="main" />
</SwiperSlide>
</Swiper>
<HomeMostPopularThisWeek />
</div>
</section>
</template>
<script setup>
const { buyers = [] } = inject('data')
</script>
<style lang="scss">
.cart-bought-products {
@apply flex justify-center py-6 lg:py-16 bg-[#F6F8FA];
& > div {
@apply container flex flex-col gap-6 lg:gap-16;
& > h2 {
@apply text-[#333333] self-center text-lg lg:text-3xl font-bold font-vazir;
}
& > .swiper {
@apply w-full py-2 lg:py-4 ;
.swiper-wrapper {
@apply w-max;
.swiper-slide {
@apply w-max ml-3 lg:ml-5 last:ml-0;
}
}
}
& > .home-most-popular-this-week {
@apply hidden lg:flex;
}
}
}
</style>
+170
View File
@@ -0,0 +1,170 @@
<template>
<div class="cart-item">
<img :src="data.coverPath" />
<div>
<h2>{{ data.title }}</h2>
<ul>
<li v-for="(item, i) in items1" :key="i">
<i :class="`isax isax-${item.icon}`"></i>
<span v-for="(title, j) in item.title" :key="j">
{{ title }}
</span>
</li>
</ul>
<div>
<div>
<i v-for="i in 2" :key="i"></i>
</div>
<ul>
<li v-for="(item, i) in items2" :key="i">
<i :class="`isax isax-${item.icon}`"></i>
<span>{{ item.title }}</span>
</li>
</ul>
</div>
</div>
<div>
<div>
<Chip>
<bdi>{{ quantity }} کارتن = {{ data.itemInBox * quantity }} عدد</bdi>
</Chip>
<CartQuantity v-model="quantity" :range="data.orderRange" />
</div>
<span>{{ numberFormat((data.specialPrice || data.price) * quantity) }} <small>تومان</small></span>
</div>
</div>
</template>
<script setup>
const { data } = defineProps(['data'])
const items1 = reactive([
{ title: ['فروشنده ' + data.shopID.shopName], icon: 'shop' },
{
title: [
'خرید کارتنی', `حداقل ${data.orderRange?.min} کارتن`, `تعداد در کارتن: ${data.itemInBox} عدد`
],
icon: 'd-square'
},
{ title: [data.warranty], icon: 'shield-tick' },
{ title: ['موجود در انبار فروشنده'], icon: 'box-tick' }
])
const items2 = reactive([
{
title: 'ارسال از آناهیتا پس از دریافت از فروشنده', icon: 'box', primary: data.localSend
},
{
title: 'ارسال از فروشنده پس از تایید نهایی 1-2 روز دیگر', icon: 'profile-circle', primary: !data.localSend
}
])
const cart = useCartStore()
const quantity = computed({
get: () => cart.find(data.id)?.quantity || 0,
set: (v) => cart.update(data.id, v)
})
const numberFormat = (number) =>
new Intl.NumberFormat('fa-IR', { maximumSignificantDigits: 3 }).format(number)
</script>
<style lang="scss">
.cart-item {
@apply w-auto flex flex-wrap justify-center items-center lg:flex-row lg:justify-between;
@apply gap-9 lg:gap-10 lg:max-w-[63.1rem] lg:max-h-[19.8rem];
&>img {
@apply object-contain object-center;
@apply w-40 h-40 lg:hidden xl:block;
@apply lg:w-[13.4rem] lg:h-[13.4rem];
}
&>div:nth-of-type(1) {
@apply flex flex-col gap-6;
&>h2 {
@apply text-[#333333] font-bold font-vazir text-base lg:text-xl;
}
&>ul {
@apply flex flex-col font-vazir gap-5 lg:gap-4 lg:mt-2.5;
li {
@apply flex items-center text-zinc-800;
@apply gap-[0.9rem] lg:gap-4 h-5 lg:h-7;
i {
@apply text-xl lg:text-2xl;
}
span {
@apply relative pl-0.5 text-xs lg:text-lg whitespace-nowrap;
&:not(:last-child)::after {
@apply content-['_'] w-px lg:w-0.5 h-4 bg-[#E5E5E5] absolute;
@apply -left-1.5 top-0.5 lg:-left-2 lg:top-1.5;
}
}
}
}
div {
@apply flex pr-0.5 lg:pr-[0.3rem] gap-4 lg:gap-6;
div {
@apply flex flex-col items-center justify-between relative;
@apply h-[3.3rem] -mt-[0.2rem] pt-[0.4rem];
@apply w-2.5 lg:h-[4.3rem] lg:pt-3.5 lg:-mt-1.5;
i {
@apply w-2.5 h-2.5 rounded-full first:bg-primary-600 last:bg-[#E5E5E5] z-0;
}
&::before {
@apply content-['_'] absolute w-0.5 inset-y-0 bg-[#E5E5E5];
}
}
ul {
@apply flex flex-col font-vazir gap-4 lg:gap-5;
li {
@apply flex gap-2 items-center h-[1.1rem] lg:h-[1.6rem];
i {
@apply text-primary-600 text-[1.1em] lg:text-xl;
}
span {
@apply text-zinc-500 text-[0.7em] lg:text-base;
}
}
}
}
}
&>div:nth-of-type(2) {
@apply w-full flex justify-around items-center;
@apply md:w-max md:flex-col-reverse md:items-end md:justify-between md:self-stretch;
&>span {
@apply whitespace-nowrap text-[#333333] font-bold font-vazir text-base lg:text-xl;
small {
@apply text-xs lg:text-inherit;
}
}
&>div {
@apply flex flex-col gap-4 flex-wrap justify-end;
&>div:nth-of-type(1) {
@apply bg-zinc-100 rounded-lg justify-center hidden lg:flex;
@apply lg:h-10 lg:w-full lg:text-base;
}
}
}
}
</style>
+40
View File
@@ -0,0 +1,40 @@
<template>
<div class="cart-quantity">
<div>
<Button icon="isax isax-add" text severity="secondary" @click="count++" :disabled="count >= range.max" />
<b>{{ count }}</b>
<Button icon="isax isax-minus" text severity="secondary" @click="count--" :disabled="count <= range.min" />
</div>
<Button icon="isax isax-trash" text severity="danger" @click="count = 0" />
</div>
</template>
<script setup>
defineProps({
range: { type: Object, default: { min: 1, max: 1000 } }
})
const count = defineModel({ default: 1 })
</script>
<style lang="scss">
.cart-quantity {
@apply flex items-center gap-3 lg:gap-4;
div {
@apply flex border border-[#E5E5E5] rounded-lg;
b {
@apply flex items-center justify-center text-primary-600;
@apply w-10 h-10 text-base lg:w-12 lg:h-12 lg:text-xl lg:pb-1;
}
button {
@apply rounded-lg text-primary-600 w-10 h-10 text-base lg:w-12 lg:h-12 lg:text-[1.8em] #{!important};
}
}
&>button {
@apply rounded-lg border border-[#E5E5E5] w-10 h-10 text-base lg:w-12 lg:h-12 lg:text-xl #{!important};
}
}
</style>
+77
View File
@@ -0,0 +1,77 @@
<template>
<section class="cart-tabs">
<ul>
<li v-for="(item, i) in tabs" :key="i">
<div :active="select == i" @click="select = i" v-ripple>
<h2>{{ $t(item) }}</h2>
<span>{{ i < 1 ? data.length : 0 }}</span>
</div>
</li>
</ul>
<Button v-if="device == 'desktop' && data.length > 0" :label="$t('removeAllFromCart')" icon="isax isax-trash"
iconPos="right" text raised severity="danger" :loading="loading" @click="clear()" />
</section>
</template>
<script setup>
const select = ref(0);
const data = inject('data')
const tabs = reactive(["cart", "previousPurchase"])
const { device } = inject('service')
const loading = ref(false)
const cart = useCartStore()
const clear = async () => {
loading.value = true
await cart.clear()
loading.value = false
}
</script>
<style lang="scss">
.cart-tabs {
@apply container w-full h-max max-lg:sticky top-0 flex justify-center lg:justify-start items-center pr-6 lg:pr-0 lg:border-b-2 border-[#E5E5E5];
@apply bg-white max-lg:z-[1];
ul {
@apply flex items-center lg:ml-[33.8rem];
li {
@apply whitespace-nowrap;
div {
@apply px-8 py-2.5 lg:px-6 lg:pb-6 flex items-center gap-3 hover:bg-gray-50 rounded-md cursor-pointer;
h2 {
@apply text-[#999999] text-lg font-normal lg:text-2xl lg:font-medium font-vazir;
}
span {
@apply w-[1.4rem] h-[1.4rem] lg:w-8 lg:h-8 bg-[#F2F2F2] rounded flex items-center justify-center;
@apply text-xs lg:text-lg font-medium font-vazir text-[#999999];
}
}
}
li:has([active="true"]) {
@apply relative;
* {
@apply text-primary-600;
}
&::after {
@apply content-['_'] inset-x-0 -bottom-[0.2rem] rounded-full h-0.5 lg:h-1 bg-primary-600 absolute;
}
}
}
button {
@apply h-[3.6rem] mb-3.5 text-[#AD3434];
.p-button-label {
@apply text-sm font-medium font-vazir
}
}
}
</style>
+108
View File
@@ -0,0 +1,108 @@
<template>
<div class="pre-factor">
<div>
<h2>
<i class="isax isax-receipt-2"></i>
<span>{{ $t("submitPreFactor") }}</span>
</h2>
<p>{{ $t("submitPreFactorDesc") }}</p>
</div>
<PanelSalesFactor :data="data" />
<ul>
<li v-for="(btn, key) in btns" :key="key">
<Button v-bind="btn.props" @click="click(key)" />
</li>
</ul>
</div>
</template>
<script setup>
import init from '../../../initialize/pre-factor.js'
const { btns } = init();
const dialog = inject('dialogRef');
const data = dialog.value.data
const router = useRouter()
const click = (key) => {
if (key == 'send')
router.push({ path: '/panel/factors', query: { id: data._id } });
dialog.value.close()
}
</script>
<style lang="scss">
.pre-factor {
@apply flex flex-col gap-8 rounded-2xl w-[77.5rem] py-8 bg-white overflow-y-auto;
&>div:nth-of-type(1) {
@apply flex flex-col items-center;
h2 {
@apply flex items-center gap-4 text-[#333333];
i {
@apply text-2xl;
}
span {
@apply text-xl font-bold font-vazir;
}
}
p {
@apply w-[30.2rem] mt-[1.1rem] text-center text-[#4C4C4C] text-lg font-vazir;
}
}
&>ul {
@apply w-full flex gap-4 px-8;
li {
button {
@apply w-full h-12 #{!important};
.p-button-label {
@apply h-[1.6rem] text-lg font-medium font-iran-sans;
}
.p-button-icon {
@apply text-2xl text-[#7F7F7F];
}
&.p-button-secondary {
@apply border-[#7F7F7F] justify-center;
.p-button-label {
@apply grow-0 text-[#7F7F7F];
}
}
}
}
li:nth-of-type(1) {
@apply w-[12.3rem];
}
li:nth-of-type(2) {
@apply w-[12.3rem] ml-auto;
}
li:nth-of-type(3) {
@apply w-[25.1rem];
}
li:nth-of-type(4) {
@apply w-[10.8rem];
}
}
}
body:has(.pre-factor) {
.sales-factor {
h2 {
@apply hidden #{!important};
}
}
}
</style>
+73
View File
@@ -0,0 +1,73 @@
<template>
<div class="cart-total-aside">
<ul>
<li v-for="(value, key) in items" :key="key">
<label>{{ $t(key) }}</label>
<span>
{{ numberFormat(value) }}
{{ key == 'productsCount' ? $t('product') : '' }}
</span>
</li>
</ul>
<Button :label="$t('submitAndViewPreFactor')" :loading="loading" @click="submitOrder()" />
</div>
</template>
<script setup>
import init from '../../../initialize/cart-total-invoice'
const { dialog } = inject('service')
const data = inject('data')
const items = computed(() => init(data.value))
const loading = ref(false)
const submitOrder = async () => {
loading.value = true
const { status, data: res } = await useFetch('/api/orders', {
headers: { Authorization: useCookie('token') }, method: 'post'
})
loading.value = false
if (status.value == 'success') {
dialog.show(resolveComponent('CartDialogPreFactor'), res.value)
const cart = useCartStore()
cart.get()
}
}
const numberFormat = (number) =>
new Intl.NumberFormat('fa-IR', { maximumSignificantDigits: 3 }).format(number)
</script>
<style lang="scss">
.cart-total-aside {
@apply w-full lg:max-w-[28.1rem] lg:h-[25rem] flex flex-col justify-between p-6 grow;
@apply lg:bg-neutral-50 lg:rounded-[0.6rem] lg:border border-neutral-200 font-vazir lg:mr-auto;
ul {
@apply flex flex-col gap-[1.1rem] lg:gap-6 lg:mt-2;
li {
@apply flex justify-between items-center;
label {
@apply text-zinc-500 text-sm lg:text-xl font-medium;
}
span {
@apply text-zinc-800 text-lg lg:text-2xl lg:font-medium;
}
}
}
button {
@apply max-lg:hidden;
span {
@apply text-xl font-bold;
}
}
}
</style>
+80
View File
@@ -0,0 +1,80 @@
<template>
<div class="total-invoice-fixed">
<Button :label="$t('submitAndViewPreFactor')" @click="submitOrder()" />
<div>
<label>{{ $t('totalFactor') }}</label>
<span>{{ numberFormat(items.totalFactor) }} {{ $t('priceUnit') }}</span>
</div>
<Button icon="isax isax-trash" severity="danger" text rounded @click="remove()" />
</div>
</template>
<script setup>
import init from '../../initialize/cart-total-invoice'
const { dialog } = inject('service')
const data = inject('data')
const items = computed(() => init(data.value))
const loading = ref(false)
const submitOrder = async () => {
loading.value = true
const { status, data } = await useFetch('/api/orders', {
headers: { Authorization: useCookie('token') }, method: 'post'
})
loading.value = false
if (status.value == 'success') {
dialog.open(resolveComponent('DialogPreFactorSubmit'), {
props: { modal: true },
data
})
}
}
const remove = () => {
dialog.show()
}
const numberFormat = (number) =>
new Intl.NumberFormat('fa-IR', { maximumSignificantDigits: 3 }).format(number)
</script>
<style lang="scss">
.total-invoice-fixed {
@apply fixed inset-x-0 bottom-16 h-[4.6rem] z-[11] bg-white flex justify-between items-center;
@apply shadow-[0px_-3px_5px_#0000000a] border-t border-[#F1F2F4] px-6 lg:hidden;
&>button:first-of-type {
@apply h-10 w-[10.7rem] #{!important};
.p-button-label {
@apply text-xs font-iran-sans font-bold;
}
}
&>div {
@apply flex flex-col gap-2 justify-between items-end font-vazir;
label {
@apply text-[#7F7F7F] text-xs;
}
span {
@apply text-[#333333] text-sm font-bold;
}
}
&>button:last-of-type {
@apply fixed lg:hidden w-[3.8rem] h-[3.8rem] right-6 bottom-36 z-10 bg-white #{!important};
@apply shadow-[0px_0px_10px_#00000014];
.p-button-icon {
@apply text-[2em] text-[#AD3434];
}
}
}
</style>