Kaynağa Gözat

donation intro #472

ali 1 yıl önce
ebeveyn
işleme
cad4b5d3b7

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

@@ -21,7 +21,7 @@
     <q-card-actions class="action-section">
       <q-btn color="primary"
              class="btn-show-content"
-             :to="{name: 'Public.ShowEventInfo', params: {id: content.id}}">
+             :to="{name: 'Public.Content.Show', params: {id: content.id}}">
         مشاهده و ثبت نام
         <svg xmlns="http://www.w3.org/2000/svg"
              width="18.387"
@@ -57,7 +57,7 @@ export default defineComponent({
   },
   methods: {
     goToPage () {
-      this.$router.push({ name: 'Public.ShowEventInfo', params: { id: this.content.id } })
+      this.$router.push({ name: 'Public.Content.Show', params: { id: this.content.id } })
     },
     miladiToShamsi () {
       return Assist.miladiToShamsi(this.content.creation_time, 'jD jMMMM jYYYY ساعت HH:mm')

+ 123 - 0
src/components/Widgets/Donation/DonationIntro/DonationIntro.vue

@@ -0,0 +1,123 @@
+<template>
+  <div class="DonationIntro">
+    <div class="DonationIntro-title">
+      <q-banner class="banner">
+        صدقات و خیریه
+      </q-banner>
+    </div>
+    <div class="content">
+      <div class="text"
+           v-html="localOptions.text" />
+      <div class="carousel-section">
+        <div v-if="localOptions.slides.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="(slide, slideIndex) in localOptions.slides"
+                  :key="slideIndex"
+                  class="splide__slide">
+                <q-img :src="slide" />
+              </li>
+            </ul>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Splide from '@splidejs/splide'
+import { mixinWidget } from 'src/mixin/Mixins.js'
+import '@splidejs/splide/dist/css/splide-core.min.css'
+
+export default {
+  name: 'EventCarousel',
+  mixins: [mixinWidget],
+  data () {
+    return {
+      loading: false,
+      slider: null,
+      breakpoints: {
+        1920: {
+          perPage: 1
+        },
+        900: {
+          perPage: 1
+        },
+        600: {
+          perPage: 1
+        }
+      },
+      maximizedToggle: true,
+      defaultOptions: {
+        text: null,
+        slides: []
+      }
+    }
+  },
+  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()
+      })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.DonationIntro {
+  padding: 60px 0;
+  .DonationIntro-title {
+    display: flex;
+    flex-flow: row;
+    justify-content: space-between;
+    padding-bottom: 33px;
+  }
+  .content {
+    display: flex;
+    flex-flow: row;
+    gap: 48px;
+    justify-content: space-between;
+    align-items: flex-start;
+    .text {
+      width: 50%;
+    }
+    .carousel-section {
+      width: 50%;
+    }
+
+    @media screen and (max-width: 1200px) {
+      & {
+        flex-flow: column;
+        gap: 16px;
+        .text {
+          width: 100%;
+        }
+        .carousel-section {
+          width: 100%;
+        }
+      }
+    }
+  }
+}
+</style>

+ 100 - 0
src/components/Widgets/Donation/DonationIntro/OptionPanel.vue

@@ -0,0 +1,100 @@
+<template>
+  <option-panel-tabs v-model:options="localOptions">
+    <template #main-tab>
+      <div>
+        <div>
+          متن:
+        </div>
+        <form-builder-tiptap-editor v-model:value="localOptions.text"
+                                    :options="editorOptions" />
+      </div>
+      <q-separator class="q-my-lg" />
+      <div class="row">
+        <div class="col-12">
+          <q-btn color="primary"
+                 class="full-width"
+                 @click="addSlide">
+            افزودن تصویر آپلود شده
+          </q-btn>
+        </div>
+        <div class="col-12">
+          <div class="input-container col-12 q-mt-md">
+            <div class="outsideLabel">آدرس عکس</div>
+            <image-uploader v-model:file="newSlide" />
+          </div>
+        </div>
+      </div>
+      <div class="slides">
+        <div v-for="(slide, slideIndex) in localOptions.slides"
+             :key="slideIndex"
+             class="slide-item">
+          <q-btn color="red"
+                 @click="removeSlide(slideIndex)">
+            <q-icon name="close" />
+          </q-btn>
+          <q-img :src="slide" />
+        </div>
+      </div>
+    </template>
+  </option-panel-tabs>
+</template>
+
+<script>
+import { defineComponent } from 'vue'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { mixinOptionPanel } from 'quasar-ui-q-page-builder'
+import ImageUploader from 'src/components/ImageUploader.vue'
+import PostMixin from 'src/components/Widgets/Post/PostMixin.js'
+import FormBuilderTiptapEditor from 'src/components/FormBuilderCustumComponents/FormBuilderTiptapEditor.vue'
+import OptionPanelTabs from 'quasar-ui-q-page-builder/src/components/OptionPanelComponents/OptionPanelTabs.vue'
+
+export default defineComponent({
+  name: 'OptionPanel',
+  components: {
+    FormBuilderTiptapEditor,
+    OptionPanelTabs,
+    ImageUploader
+  },
+  mixins: [mixinOptionPanel, PostMixin],
+  data () {
+    const authorization = 'Bearer ' + this.$store.getters['Auth/accessToken']
+    const uploadVideo = this.uploadVideo
+    const uploadAudio = this.uploadAudio
+    return {
+      newSlide: null,
+      editorOptions: {
+        bubbleMenu: false,
+        floatingMenu: false,
+        poem: false,
+        reading: false,
+        loadBareHtml: true,
+        persianKeyboard: true,
+        mathliveOptions: { smartFence: false },
+        uploadServer: {
+          url: '/api' + APIGateway.media.APIAdresses.base,
+          instantUpload: true,
+          responseKey: 'file',
+          headers: { Authorization: authorization }
+        },
+        uploadVideo,
+        uploadAudio
+      },
+      defaultOptions: {
+        text: null,
+        slides: []
+      }
+    }
+  },
+  methods: {
+    addSlide () {
+      if (!this.newSlide) {
+        return
+      }
+      this.localOptions.slides.push(JSON.parse(JSON.stringify(this.newSlide)))
+    },
+    removeSlide(slideIndex) {
+      this.localOptions.slides.splice(slideIndex, 1)
+    }
+  }
+})
+</script>

+ 128 - 0
src/components/Widgets/Donation/DonationIntro/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.Content.Show', 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.Content.Show', 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>