ali 2 vuotta sitten
vanhempi
commit
c3fc409fb3

+ 13 - 15
src/components/Widgets/Store/StoreProduct/StoreProductShow/StoreProductShow.vue

@@ -69,19 +69,6 @@
                @click="addToCart" />
       </div>
     </div>
-    <div v-if="false"
-         class="product-show__products">
-      <q-expansion-item expand-separator
-                        default-opened
-                        icon="inventory_2"
-                        label="اقلام داخل بسته">
-        <product-item v-for="(product, productIndex) in product.products_info.list"
-                      :key="productIndex"
-                      :product="product"
-                      class="product-item-component" />
-      </q-expansion-item>
-
-    </div>
     <div v-if="product.description"
          class="product-show__descriptions">
       <q-banner class="product-show__descriptions-title">
@@ -90,6 +77,10 @@
       <div class="product-show__descriptions-data"
            v-html="product.description" />
     </div>
+    <div v-if="product.medias_info"
+         class="product-show__medias">
+      <medias-component :medias="product.medias_info" />
+    </div>
   </div>
 </template>
 
@@ -98,12 +89,12 @@ import { Basket } from 'src/models/Basket.js'
 import { Product } from 'src/models/Product.js'
 import { mixinWidget } from 'src/mixin/Mixins.js'
 import { APIGateway } from 'src/api/APIGateway.js'
-import ProductItem from './components/productItem.vue'
+import MediasComponent from './components/Medias.vue'
 import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
 
 export default {
   name: 'ContentShow',
-  components: { Breadcrumbs, ProductItem },
+  components: { Breadcrumbs, MediasComponent },
   mixins: [mixinWidget],
   data () {
     return {
@@ -349,6 +340,7 @@ export default {
     border: 1px solid #DFE1EC;
     border-radius: 8px;
     background: #F6F6F6;
+    margin-bottom: 20px;
     .product-show__descriptions-title{
       color: #727272;
       font-size: 16px;
@@ -359,5 +351,11 @@ export default {
       font-size: 16px;
     }
   }
+  .product-show__medias {
+    background: #FFFFFF;
+    border: 1px solid #DFE1EC;
+    border-radius: 8px;
+    padding: 36px 46px;
+  }
 }
 </style>

+ 71 - 0
src/components/Widgets/Store/StoreProduct/StoreProductShow/components/MediaCategory.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="MediaCategory">
+    <div class="title">
+      <q-icon :name="icon"
+              size="19px" />
+      {{ title }}
+    </div>
+    <div class="media-list row q-col-gutter-md">
+      <div v-for="media in medias.list"
+           :key="media.id"
+           class="media-item col-md-3 col-sm-6 col-12">
+        <media-item :media="media"
+                    :media-type="mediaType"
+                    @onView="onView(media)" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { MediaList } from 'src/models/Media.js'
+import MediaItem from './MediaItem.vue'
+
+export default {
+  name: 'MediaCategory',
+  components: { MediaItem },
+  props: {
+    medias: {
+      type: MediaList,
+      default: new MediaList()
+    },
+    title: {
+      type: String,
+      default: ''
+    },
+    icon: {
+      type: String,
+      default: ''
+    },
+    mediaType: {
+      type: String,
+      default: null
+    }
+  },
+  emits: ['update:value', 'onView', 'onDelete'],
+  data () {
+    return {
+      entityCreateLoading: false
+    }
+  },
+  methods: {
+    onView (media) {
+      this.$emit('onView', media)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.MediaCategory {
+  .title {
+    font-size: 16px;
+    letter-spacing: 0;
+    color: #212121;
+    margin-bottom: 26px;
+    .q-icon {
+      margin-left: 9px;
+    }
+  }
+}
+</style>

+ 77 - 0
src/components/Widgets/Store/StoreProduct/StoreProductShow/components/MediaItem.vue

@@ -0,0 +1,77 @@
+<template>
+  <div class="MediaItem">
+    <div class="title ellipsis">
+      {{ media.title }}
+    </div>
+    <div class="actions">
+      <q-btn class="viewBtn"
+             color="primary"
+             @click="onView">
+        <template v-if="mediaType === 'video'">
+          مشاهده
+        </template>
+        <template v-else>
+          <q-icon name="file_download" />
+          دانلود
+        </template>
+      </q-btn>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Media } from 'src/models/Media.js'
+
+export default {
+  name: 'MediaItem',
+  props: {
+    media: {
+      type: Media,
+      default: new Media()
+    },
+    mediaType: {
+      type: String,
+      default: null
+    }
+  },
+  emits: ['update:value', 'onView', 'onDelete'],
+  data () {
+    return {
+      entityCreateLoading: false
+    }
+  },
+  methods: {
+    onView () {
+      this.$emit('onView')
+    },
+    onDelete () {
+      this.$emit('onDelete')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.MediaItem {
+  background: #F9F9F9;
+  border: 1px solid #DFE1EC;
+  border-radius: 10px;
+  padding: 10px 16px 10px 21px;
+  display: flex;
+  flex-flow: row;
+  justify-content: space-between;
+  align-items: center;
+  .title {
+    font-size: 15px;
+    letter-spacing: 0;
+    color: #212121;
+  }
+  .actions {
+    display: flex;
+    flex-flow: row;
+    justify-content: flex-end;
+    .q-btn {
+    }
+  }
+}
+</style>

+ 85 - 0
src/components/Widgets/Store/StoreProduct/StoreProductShow/components/Medias.vue

@@ -0,0 +1,85 @@
+<template>
+  <div class="Medias">
+    <media-category v-if="documentMedias.list.length > 0"
+                    :medias="documentMedias"
+                    icon="receipt_long"
+                    title="فایل"
+                    class="q-mt-lg"
+                    @onView="onView" />
+    <media-category v-if="soundMedias.list.length > 0"
+                    :medias="soundMedias"
+                    icon="mic_none"
+                    title="صوت"
+                    class="q-mt-lg"
+                    @onView="onView" />
+    <media-category v-if="videoMedias.list.length > 0"
+                    :medias="videoMedias"
+                    icon="play_circle_outline"
+                    title="ویدیو"
+                    class="q-mt-lg"
+                    media-type="video"
+                    @onView="onView" />
+    <media-category v-if="imageMedias.list.length > 0"
+                    :medias="imageMedias"
+                    icon="visibility"
+                    title="تصویر"
+                    class="q-mt-lg"
+                    @onView="onView" />
+  </div>
+</template>
+
+<script>
+import { MediaList } from 'src/models/Media.js'
+import MediaCategory from './MediaCategory.vue'
+
+export default {
+  name: 'Medias',
+  components: { MediaCategory },
+  props: {
+    medias: {
+      type: MediaList,
+      default: new MediaList()
+    },
+    sourceType: {
+      type: String,
+      default: 'CONTENT'
+    }
+  },
+  emits: ['update:value'],
+  data () {
+    return {
+      fetchLoading: false
+    }
+  },
+  computed: {
+    videoMedias () {
+      return new MediaList(this.medias.getType('VIDEO'))
+    },
+    soundMedias () {
+      return new MediaList(this.medias.getType('SOUND'))
+    },
+    imageMedias () {
+      return new MediaList(this.medias.getType('IMAGE'))
+    },
+    documentMedias () {
+      return new MediaList(this.medias.getType('DOCUMENT'))
+    }
+  },
+  methods: {
+    onView (media) {
+      if (media.url) {
+        window.open(media.url, '_blank')
+      }
+      if (media.file) {
+        window.open(media.file, '_blank')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.Medias {
+  width: 100%;
+}
+</style>

+ 10 - 1
src/models/Product.js

@@ -1,4 +1,5 @@
 import { Collection, Model } from 'js-abstract-model'
+import { MediaList } from 'src/models/Media.js'
 
 class Product extends Model {
   constructor (data) {
@@ -20,7 +21,15 @@ class Product extends Model {
       { key: 'is_physical' },
       { key: 'weight' },
       { key: 'physical_type' },
-      { key: 'specification' }
+      { key: 'specification' },
+      {
+        key: 'medias',
+        defalut: []
+      },
+      {
+        key: 'medias_info',
+        relatedModel: MediaList
+      }
     ], {
       is_physical: {
         infoKey: 'is_physical_info',