ali %!s(int64=2) %!d(string=hai) anos
pai
achega
c69df3685a

+ 4 - 1
src/api/models/Basket.js

@@ -154,11 +154,14 @@ export default class BasketAPI extends APIRepository {
     })
   }
 
-  createInvoice (basketId) {
+  createInvoice (basketId, owner) {
     return this.sendRequest({
       apiMethod: 'put',
       api: this.api,
       request: this.APIAdresses.createInvoice(basketId),
+      data: this.getNormalizedSendData({
+        owner: null // String
+      }, { owner }),
       resolveCallback: (response) => {
         return new Invoice(response.data)
       },

+ 14 - 0
src/api/models/BasketItem.js

@@ -70,6 +70,20 @@ export default class BasketItemAPI extends APIRepository {
     })
   }
 
+  remove (id) {
+    return this.sendRequest({
+      apiMethod: 'delete',
+      api: this.api,
+      request: this.APIAdresses.byId(id),
+      resolveCallback: (response) => {
+        return new BasketItem(response.data)
+      },
+      rejectCallback: (error) => {
+        return error
+      }
+    })
+  }
+
   addProduct (productId, count) {
     return this.sendRequest({
       apiMethod: 'post',

+ 5 - 1
src/components/Widgets/Store/Cart/components/step1/step1.vue

@@ -77,6 +77,10 @@ export default {
         })
     },
     onDecrease (basketItem) {
+      if (basketItem.count === 1) {
+        this.onRemove(basketItem)
+        return
+      }
       basketItem.loading = true
       const promise = basketItem.product ? APIGateway.basketItem.decrementProduct(basketItem.product) : APIGateway.basketItem.decrementPackage(basketItem.package)
       // const newCount = basketItem.count - 1
@@ -91,7 +95,7 @@ export default {
     },
     onRemove (basketItem) {
       basketItem.loading = true
-      APIGateway.basketItem.update(basketItem.id, 0)
+      APIGateway.basketItem.remove(basketItem.id)
         .then(() => {
           this.checkoutReview()
         })

+ 14 - 2
src/components/Widgets/Store/Cart/components/step3/InvoiceInfo.vue

@@ -5,8 +5,13 @@
     </div>
     <div class="invoice-info-body">
       <div class="invoice-info-body-item">
-        عنوان:
-        {{ classroom.title }}
+        <template v-if="classroom.id">
+          عنوان:
+          {{ classroom.title }}
+        </template>
+        <template v-if="basket.id">
+          <cart-items :basket-items="basket.items_info" />
+        </template>
       </div>
       <div class="invoice-info-body-item">
         شناسه:
@@ -17,16 +22,23 @@
 </template>
 
 <script>
+import { Basket } from 'src/models/Basket.js'
 import { Invoice } from 'src/models/Invoice.js'
 import { Classroom } from 'src/models/Classroom.js'
+import CartItems from './cartItems.vue'
 
 export default {
   name: 'InvoiceInfo',
+  components: { CartItems },
   props: {
     invoice: {
       type: Invoice,
       default: new Invoice()
     },
+    basket: {
+      type: Basket,
+      default: new Basket()
+    },
     classroom: {
       type: Classroom,
       default: new Classroom()

+ 99 - 0
src/components/Widgets/Store/Cart/components/step3/cartItem.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="cart-item">
+    <div class="cart-item__use-type">
+      <q-icon :name="usageIcon" />
+    </div>
+    <div class="cart-item__thumbnail">
+      <q-img :src="packageOrProductObject.thumbnail" />
+    </div>
+    <div class="cart-item__title">
+      {{ packageOrProductObject.title }}
+    </div>
+  </div>
+</template>
+
+<script>
+import { Product } from 'src/models/Product.js'
+import { BasketItem } from 'src/models/BasketItem.js'
+
+export default {
+  name: 'CartItem',
+  props: {
+    basketItem: {
+      type: BasketItem,
+      default: new BasketItem()
+    }
+  },
+  emits: ['increase', 'decrease', 'remove'],
+  data () {
+    return {
+      step: 1
+    }
+  },
+  computed: {
+    packageOrProductObject () {
+      if (this.basketItem.product) {
+        return this.basketItem.product_info
+      }
+      if (this.basketItem.package) {
+        return this.basketItem.package_info
+      }
+
+      return new Product()
+    },
+    usageIcon () {
+      if (this.basketItem.package) {
+        return 'inventory_2'
+      }
+      if (this.packageOrProductObject.is_physical) {
+        return 'local_shipping'
+      }
+      return 'file_download'
+    }
+  },
+  methods: {
+    onIncrease () {
+      this.$emit('increase', this.basketItem)
+    },
+    onDecrease () {
+      this.$emit('decrease', this.basketItem)
+    },
+    onRemove () {
+      this.$emit('remove', this.basketItem)
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.cart-item {
+  position: relative;
+  .cart-item__use-type {
+    position: absolute;
+    top: 0;
+    right: 0;
+    width: 41px;
+    height: 41px;
+    background: #C8FFCF;
+    border-radius: 0 8px;
+    opacity: 0.57;
+    color: $primary;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 2;
+    .q-icon {
+      font-size: 25px;
+    }
+  }
+  .cart-item__thumbnail {
+    border-radius: 8px;
+    overflow: hidden;
+  }
+  .cart-item__title {
+    font-size: 14px;
+    color: #212121;
+    text-align: center;
+  }
+}
+</style>

+ 88 - 0
src/components/Widgets/Store/Cart/components/step3/cartItems.vue

@@ -0,0 +1,88 @@
+<template>
+  <div class="cart-items">
+    <div class="cart-items__title">
+      <q-icon name="shopping_cart" />
+      خرید شما:
+    </div>
+    <div class="cart-items__items row q-col-gutter-md">
+      <div v-for="(basketItem, basketItemIndex) in basketItems.list"
+           :key="basketItemIndex"
+           class="col-md-2 col-sm-6 col-xs-12">
+        <cart-item :basket-item="basketItem"
+                   class="cart-items__item" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import CartItem from './cartItem.vue'
+import { Product } from 'src/models/Product'
+import { BasketItemList } from 'src/models/BasketItem.js'
+
+export default {
+  name: 'CartItems',
+  components: { CartItem },
+  props: {
+    basketItems: {
+      type: BasketItemList,
+      default: new BasketItemList()
+    }
+  },
+  emits: ['increase', 'decrease', 'remove'],
+  data () {
+    return {
+      step: 1
+    }
+  },
+  computed: {
+    packageOrProductObject () {
+      if (this.basketItem.product) {
+        return this.basketItem.product_info
+      }
+      if (this.basketItem.package) {
+        return this.basketItem.package_info
+      }
+
+      return new Product()
+    },
+    usageIcon () {
+      if (this.basketItem.package) {
+        return 'inventory_2'
+      }
+      if (this.packageOrProductObject.is_physical) {
+        return 'local_shipping'
+      }
+      return 'file_download'
+    }
+  },
+  methods: {
+    onIncrease () {
+      this.$emit('increase', this.basketItem)
+    },
+    onDecrease () {
+      this.$emit('decrease', this.basketItem)
+    },
+    onRemove () {
+      this.$emit('remove', this.basketItem)
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.cart-items {
+  border-radius: 8px;
+  background: #F9F9FB;
+  border: 1px solid #DFE1EC;
+  padding: 20px 38px;
+  .cart-items__title {
+    color: #727272;
+    font-size: 16px;
+    margin-bottom: 22px;
+  }
+  .cart-items__items {
+    padding-left: 20px;
+  }
+}
+</style>

+ 6 - 16
src/components/Widgets/Store/Cart/components/step3/step3.vue

@@ -5,7 +5,7 @@
     <template v-if="!basket.loading">
       <invoice-info v-if="!invoice.loading"
                     :invoice="invoice"
-                    :classroom="classroom"
+                    :basket="basket"
                     class="invoice-info" />
       <invoice-payment-card v-if="!invoice.loading"
                             :wallet="wallet"
@@ -28,7 +28,7 @@ import { APIGateway } from 'src/api/APIGateway.js'
 import InvoicePaymentCard from 'src/components/InvoicePaymentCard/InvoicePaymentCard.vue'
 
 export default {
-  name: 'step2',
+  name: 'step3',
   components: { InvoicePaymentCard, InvoiceInfo },
   mixins: [mixinAuth],
   props: {
@@ -85,7 +85,7 @@ export default {
     },
     getBasketInvoice () {
       this.invoice.loading = true
-      APIGateway.basket.createInvoice(this.basket.id)
+      APIGateway.basket.createInvoice(this.basket.id, this.user.id)
         .then((invoice) => {
           this.invoice = new Invoice(invoice)
         })
@@ -149,19 +149,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
-.step2 {
-  display: flex;
-  flex-flow: row;
-  gap: 28px;
-  $sidebar-width: 312px;
-  .step2__cart-info {
-    width: calc( 100% - #{$sidebar-width} );
-    display: flex;
-    flex-flow: column;
-    gap: 24px;
-  }
-  .step2__sidebar {
-    width: $sidebar-width;
+.step3 {
+  .invoice-info {
+    margin-bottom: 24px;
   }
 }
 

+ 2 - 3
src/components/Widgets/Store/Cart/components/stepper.vue

@@ -28,8 +28,7 @@
               title="پرداخت"
               icon="account_balance_wallet"
               done-icon="account_balance_wallet"
-              active-icon="account_balance_wallet"
-              disable>
+              active-icon="account_balance_wallet">
         <step3 />
       </q-step>
     </q-stepper>
@@ -54,7 +53,7 @@ export default {
   data () {
     return {
       mounted: false,
-      step: 1
+      step: 3
     }
   },
   mounted() {

+ 2 - 2
src/components/Widgets/Store/Shop/components/packageItem.vue

@@ -71,13 +71,13 @@ export default {
         })
     },
     checkoutReview () {
-      this.basket.loading = true
+      this.addToCartLoading = true
       APIGateway.basket.checkoutReview()
         .then((basket) => {
           this.$store.commit('Shop/updateBasket', new Basket(basket))
         })
         .finally(() => {
-          this.basket.loading = false
+          this.addToCartLoading = false
         })
     }
   }

+ 2 - 2
src/components/Widgets/Store/Shop/components/productItem.vue

@@ -79,13 +79,13 @@ export default {
         })
     },
     checkoutReview () {
-      this.basket.loading = true
+      this.addToCartLoading = true
       APIGateway.basket.checkoutReview()
         .then((basket) => {
           this.$store.commit('Shop/updateBasket', new Basket(basket))
         })
         .finally(() => {
-          this.basket.loading = false
+          this.addToCartLoading = false
         })
     }
   }