ali 1 год назад
Родитель
Сommit
9fdb07df8c

+ 153 - 0
src/components/Widgets/Content/ContentCarousel/ContentCarousel.vue

@@ -0,0 +1,153 @@
+<template>
+  <div class="contentCarousel">
+    <div class="contentCarousel-title">
+      <div>
+        <q-banner class="banner">
+          سیر مطالعاتی و سخنرانی‌ها
+        </q-banner>
+      </div>
+      <div>
+        <q-btn flat
+               :to="{name: 'Public.ContentCategoryParentParent.List'}">
+          مشاهده همه
+          <svg xmlns="http://www.w3.org/2000/svg"
+               width="18.387"
+               height="11.502"
+               viewBox="0 0 18.387 11.502"
+               class="q-ml-sm">
+            <path id="Combined_Shape"
+                  data-name="Combined Shape"
+                  d="M-9.338,11.408a.748.748,0,0,0,.388-.656V6.5h8.2A.751.751,0,0,0,0,5.75.75.75,0,0,0-.75,5h-8.2V.75A.751.751,0,0,0-9.338.093.769.769,0,0,0-9.7,0a.735.735,0,0,0-.4.115l-7.938,5a.747.747,0,0,0-.35.635.742.742,0,0,0,.35.634l7.938,5a.751.751,0,0,0,.4.116A.746.746,0,0,0-9.338,11.408ZM-10.45,9.392l-5.78-3.641,5.78-3.642Z"
+                  transform="translate(18.387)"
+                  fill="#eac38a" />
+          </svg>
+        </q-btn>
+      </div>
+    </div>
+    <div class="carousel-section">
+      <div v-if="!contents.loading && contents.list.length > 0"
+           ref="slider"
+           class="splide"
+           role="group"
+           aria-label="Splide Basic HTML Example">
+        <div class="splide__track">
+          <ul class="splide__list">
+            <li v-for="(content, contentIndex) in contents.list"
+                :key="contentIndex"
+                class="splide__slide">
+              <content-item :content="content" />
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div v-else-if="!contents.loading && contents.list.length === 0">
+        رویدادی یافت نشد.
+      </div>
+      <div v-else-if="contents.loading">
+        کمی صبر کنید ...
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Splide from '@splidejs/splide'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { ContentList } from 'src/models/Content.js'
+import '@splidejs/splide/dist/css/splide-core.min.css'
+import ContentItem from './componetns/ContentItem.vue'
+import { mixinPrefetchServerData, mixinWidget } from 'src/mixin/Mixins.js'
+
+export default {
+  name: 'EventCarousel',
+  components: {
+    ContentItem
+  },
+  mixins: [mixinPrefetchServerData, mixinWidget],
+  data () {
+    return {
+      loading: false,
+      slider: null,
+      contents: new ContentList(),
+      breakpoints: {
+        1920: {
+          perPage: 3
+        },
+        900: {
+          perPage: 2
+        },
+        500: {
+          perPage: 1
+        }
+      },
+      maximizedToggle: true
+    }
+  },
+  mounted () {
+    this.loadSlider()
+  },
+  methods: {
+    loadSlider () {
+      this.$nextTick(() => {
+        if (!this.$refs.slider) {
+          return
+        }
+        new Splide(this.$refs.slider, {
+          direction: 'rtl',
+          paginationDirection: 'rtl',
+          // type: 'loop',
+          focus: 0,
+          gap: 24,
+          snap: true,
+          // focus: 'center',
+          breakpoints: this.breakpoints
+        }).mount()
+      })
+    },
+    prefetchServerDataPromise () {
+      return this.getContents()
+    },
+    prefetchServerDataPromiseThen (contentList) {
+      this.contents = new ContentList(contentList.list)
+      this.contents.loading = false
+      this.loadSlider()
+    },
+    prefetchServerDataPromiseCatch () {
+      this.contents.loading = false
+    },
+
+    getContents () {
+      const params = {}
+
+      if (this.localOptions.categoryCategoryCategoryId) {
+        params.category__parent__parent = this.localOptions.categoryCategoryCategoryId
+      }
+
+      if (this.localOptions.categoryCategoryId) {
+        params.category__parent = this.localOptions.categoryCategoryId
+      }
+
+      if (this.localOptions.categoryId) {
+        params.category = this.localOptions.categoryId
+      }
+
+      this.contents.loading = true
+      return APIGateway.content.index(params)
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.contentCarousel {
+  padding: 60px 0;
+  .contentCarousel-title {
+    display: flex;
+    flex-flow: row;
+    justify-content: space-between;
+    padding-bottom: 33px;
+  }
+  .carousel-section {
+  }
+}
+</style>

+ 65 - 0
src/components/Widgets/Content/ContentCarousel/OptionPanel.vue

@@ -0,0 +1,65 @@
+<template>
+  <option-panel-tabs v-model:options="localOptions">
+    <template #main-tab>
+      <div class="q-mt-md">
+        کد دسته پدربزرگ
+      </div>
+      <div class="row">
+        <div class="col-md-8 col-12">
+          <q-input v-model="localOptions.categoryCategoryCategoryId" />
+        </div>
+      </div>
+      <div>
+        کد دسته پدر
+      </div>
+      <div class="row">
+        <div class="col-md-4 col-12">
+          <q-checkbox v-model="localOptions.categoryCategoryFromQueryParams"
+                      label="استفاده از کوری پارام صفحه" />
+        </div>
+        <div v-if="!localOptions.categoryCategoryFromQueryParams"
+             class="col-md-8 col-12">
+          <q-input v-model="localOptions.categoryCategoryId" />
+        </div>
+      </div>
+      <div>
+        کد دسته فرزند
+      </div>
+      <div class="row">
+        <div class="col-md-4 col-12">
+          <q-checkbox v-model="localOptions.categoryFromQueryParams"
+                      label="استفاده از کوری پارام صفحه" />
+        </div>
+        <div v-if="!localOptions.categoryFromQueryParams"
+             class="col-md-8 col-12">
+          <q-input v-model="localOptions.categoryId" />
+        </div>
+      </div>
+    </template>
+  </option-panel-tabs>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { mixinOptionPanel } from 'quasar-ui-q-page-builder'
+import OptionPanelTabs from 'quasar-ui-q-page-builder/src/components/OptionPanelComponents/OptionPanelTabs.vue'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  components: {
+    OptionPanelTabs
+  },
+  mixins: [mixinOptionPanel],
+  data () {
+    return {
+      defaultOptions: {
+        categoryId: null,
+        categoryCategoryId: null,
+        categoryCategoryCategoryId: null,
+        categoryFromQueryParams: false,
+        categoryCategoryFromQueryParams: false
+      }
+    }
+  }
+})
+</script>

+ 128 - 0
src/components/Widgets/Content/ContentCarousel/componetns/ContentItem.vue

@@ -0,0 +1,128 @@
+<template>
+  <q-card flat
+          class="content-item">
+    <div class="thumbnail">
+      <img class="thumbnail-img"
+           :src="content.thumbnail"
+           @click="goToPage">
+    </div>
+    <div class="infos">
+      <div class="title ellipsis-2-lines">
+        <router-link :to="{name: 'Public.Content.Show', params: {id: content.id}}">
+          {{ content.title }}
+        </router-link>
+      </div>
+      <div class="date">
+        <q-icon name="calendar_month"
+                size="20px" />
+        {{ miladiToShamsi() }}
+      </div>
+    </div>
+    <q-card-actions class="action-section">
+      <q-btn color="primary"
+             class="btn-show-content"
+             :to="{name: 'Public.ShowEventInfo', params: {id: content.id}}">
+        مشاهده و ثبت نام
+        <svg xmlns="http://www.w3.org/2000/svg"
+             width="18.387"
+             height="11.502"
+             viewBox="0 0 18.387 11.502">
+          <path id="Combined_Shape"
+                data-name="Combined Shape"
+                d="M-9.338,11.408a.748.748,0,0,0,.388-.656V6.5h8.2A.751.751,0,0,0,0,5.75.75.75,0,0,0-.75,5h-8.2V.75A.751.751,0,0,0-9.338.093.769.769,0,0,0-9.7,0a.735.735,0,0,0-.4.115l-7.938,5a.747.747,0,0,0-.35.635.742.742,0,0,0,.35.634l7.938,5a.751.751,0,0,0,.4.116A.746.746,0,0,0-9.338,11.408ZM-10.45,9.392l-5.78-3.641,5.78-3.642Z"
+                transform="translate(18.387)"
+                fill="#fff" />
+        </svg>
+      </q-btn>
+    </q-card-actions>
+  </q-card>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import Assist from 'src/assets/js/Assist.js'
+import { Content } from 'src/models/Content.js'
+
+export default defineComponent({
+  name: 'ContentItem',
+  props: {
+    content: {
+      type: Content,
+      default: new Content()
+    }
+  },
+  data() {
+    return {
+    }
+  },
+  methods: {
+    goToPage () {
+      this.$router.push({ name: 'Public.ShowEventInfo', params: { id: this.content.id } })
+    },
+    miladiToShamsi () {
+      return Assist.miladiToShamsi(this.content.creation_time, 'jD jMMMM jYYYY ساعت HH:mm')
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.content-item {
+  width: 100%;
+  background-color: #F6F6F6;
+  border-radius: 8px;
+  position: relative;
+  z-index: 1;
+
+  .thumbnail {
+    padding: 0;
+    cursor: pointer;
+    .thumbnail-img {
+      width: 100%;
+      height: auto;
+    }
+  }
+  .infos {
+    position: absolute;
+    left: 0;
+    padding-top: 12px;
+    bottom: 60px;
+    width: 100%;
+    z-index: 2;
+    -webkit-box-shadow: inset 0px -200px 55px -90px rgba(0,0,0,0.32);
+    -moz-box-shadow: inset 0px -200px 55px -90px rgba(0,0,0,0.32);
+    box-shadow: inset 0px -200px 55px -90px rgba(0,0,0,0.32);
+    .title {
+      padding: 0 15px;
+      text-align: left;
+      margin-bottom: 49px;
+      a {
+        color: white;
+        font-size: 16px;
+        font-weight: bold;
+      }
+    }
+    .date {
+      padding: 0 15px;
+      text-align: left;
+      margin-bottom: 24px;
+      color: white;
+      font-size: 16px;
+      font-weight: normal;
+      .q-icon {
+        color: #EAC38A;
+        margin-right: 12.5px;
+      }
+    }
+  }
+  .action-section {
+    padding: 0;
+    .btn-show-content {
+      width: 100%;
+      height: 60px;
+      border-top-right-radius: 0;
+      border-top-left-radius: 0;
+    }
+  }
+}
+</style>

+ 2 - 8
src/components/Widgets/Post/LastPosts/OptionPanel.vue

@@ -5,12 +5,7 @@
         کد دسته پدربزرگ
       </div>
       <div class="row">
-        <div class="col-md-4 col-12">
-          <q-checkbox v-model="localOptions.categoryCategoryCategoryFromQueryParams"
-                      label="استفاده از کوری پارام صفحه" />
-        </div>
-        <div v-if="!localOptions.categoryCategoryCategoryFromQueryParams"
-             class="col-md-8 col-12">
+        <div class="col-md-8 col-12">
           <q-input v-model="localOptions.categoryCategoryCategoryId" />
         </div>
       </div>
@@ -62,8 +57,7 @@ export default defineComponent({
         categoryCategoryId: null,
         categoryCategoryCategoryId: null,
         categoryFromQueryParams: false,
-        categoryCategoryFromQueryParams: false,
-        categoryCategoryCategoryFromQueryParams: false
+        categoryCategoryFromQueryParams: false
       }
     }
   }

+ 1 - 0
src/models/Content.js

@@ -12,6 +12,7 @@ class Content extends Model {
       { key: 'description' },
       { key: 'summary' },
       { key: 'thumbnail' },
+      { key: 'creation_time' },
       {
         key: 'is_free',
         defalut: false