HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/assets/vue/widgets/AppNotification/index.vue
<template>
  <div class="dropdown d-inline-block">
    <button
      type="button"
      class="btn header-item noti-icon waves-effect"
      @click="showNotficationsSlider = true"
    >
      <!-- <i class="bx bx-bell bx-tada"></i> -->
      <Icon icon="bx:bell" height="20" />
      <span class="badge bg-danger rounded-pill" v-if="unreadNotifications > 0">{{
        unreadNotifications
      }}</span>
    </button>
    <b-modal
      v-model="showNotficationsSlider"
      dialog-class="modal-dialog-slideout notification-modal"
      :hide-footer="true"
      content-class="rounded-0"
      header-class="mb-2"
      id="workflow-modal"
    >
      <template #modal-header>
        <div class="d-flex justify-content-between align-items-center">
          <button
            type="button"
            class="btn btn-primary"
            @click="showNotficationsSlider = false"
          >
            Close
          </button>
          <a
            href="#"
            class="text-reset bg-success badge rounded-pill bg-success p-2"
            @click.prevent="reloadNotifications"
            v-if="newNotficationsHaveCome"
            >You have recieneved new notifications. Reload!<i
              class="mdi mdi-arrow-right"
            ></i
          ></a>
        </div>
      </template>
      <div class="spinner-main">
        <Loader :loading="isLoading || newNotificationsLoading"> </Loader>
      </div>
      <template v-if="!(isLoading || newNotificationsLoading)">
        <div class="row justify-content-center">
          <div class="col-xl-12">
            <div class="card">
              <div class="card-body">
                <div class="d-flex justify-content-between align-items-baseline">
                  <h4 class="card-title mb-4">Notifications</h4>
                  <b-dropdown
                    dropleft
                    class="btn btn-sm px-3 font-size-16 me-2 mb-2 mb-sm-0 notification-dropdown"
                  >
                    <template slot="button-content">
                      <i class="bx bx-dots-vertical-rounded font-size-16"></i>
                    </template>

                    <a class="dropdown-item" href="javascript: void(0);">Settings</a>
                    <a
                      class="dropdown-item"
                      :class="{
                        'hello-world': pushEngageSubscribed ? false : true,
                      }"
                      @click="updateUserNotificationStatus"
                      ><i
                        class="bx bx-loader bx-spin font-size-16 align-middle me-2"
                        v-if="updateUserNotificationStatusLoading"
                      ></i>
                      {{ getMuteStatusText }}</a
                    >
                  </b-dropdown>
                </div>
                <p class="card-text text-center" v-if="!notifications.length">
                  There is no new notifications at this time.
                </p>

                <div v-else>
                  <notification-by-day
                    v-for="(notification, index) in notifications"
                    :key="index"
                    :notification="notification"
                    :bucketLimit="bucketLimit"
                  ></notification-by-day>
                  <div class="mt-4 text-center" v-if="showViewMoreButton">
                    <button
                      type="button"
                      class="btn btn-primary"
                      @click="isViewMoreClicked = true"
                    >
                      <i
                        class="bx bx-loader bx-spin font-size-16 align-middle me-2"
                        v-if="fetchNotificationLoading && isViewMoreClicked"
                      ></i>
                      View More
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>
    </b-modal>
  </div>
</template>

<script>
import Loader from "../../components/Loader/loader.vue";
import NotificationService from "../../service/notificationService";
import ProfileService from "../../service/profileService";
import NotificationByDay from "./NotificationByDay.vue";
import { toastConfig } from "../../utils/util";
import * as _ from "lodash";
import moment from "moment";
import { BModal, BDropdown } from "bootstrap-vue-next";
import { Icon } from "@iconify/vue";

export default {
  components: {
    NotificationByDay,
    Loader,
    BDropdown,
    BModal,
    Icon,
  },
  data() {
    return {
      userDetails: CURRENT_USER_DETAILS,
      isSubscribed: false,
      pushEngageSubscribed: false,
      showNotficationsSlider: false,
      unreadNotifications: 0,
      unreadNotificationsLoading: false,
      fetchNotificationLoading: false,
      notifications: [],
      rawNotifications: [],
      totalNotificationCount: 0,
      notificationfetchLimit: 50,
      currentPage: 1,
      bucketLimit: 4,
      updateUserNotificationStatusLoading: false,
      unviewedCountIntervalId: null,
      newNotficationsHaveCome: false,
      isViewMoreClicked: false,
      profileLoading: false,
      profileData: {},
      latestNotificationDetails: null,
      syncSubscriptionStatusIntervalId: null,
      modalOptions: {
        dialogClass: "modal-dialog-slideout notification-modal",
        hideFooter: true,
        contentClass: "rounded-0",
        headerClass: "mb-2",
      },
    };
  },
  mounted() {
    this.getPushEngageSubscribeStatus();
    this.getProfileInfo();
    this.getUnviewiedCount();
    this.unviewedCountIntervalId = setInterval(() => {
      // this.getUnviewiedCount();
    }, 5000);
    // this.syncSubscriptionStatusIntervalId = setInterval(() => {
    //   this.getPushEngageSubscribeStatus();
    // }, 10000);
  },
  destroyed() {
    clearInterval(this.unviewedCountIntervalId);
    clearInterval(this.syncSubscriptionStatusIntervalId);
  },
  computed: {
    isLoading() {
      return this.fetchNotificationLoading && !this.isViewMoreClicked;
    },
    newNotificationsLoading() {
      return this.fetchNotificationLoading && this.newNotficationsHaveCome;
    },
    getMuteStatusText() {
      return this.isSubscribed ? "Unsubscribe" : "Subscribe";
    },
    showViewMoreButton() {
      if (this.totalNotificationCount > 0) {
        const totalNumberOfPages = Math.ceil(
          this.totalNotificationCount / this.notificationfetchLimit
        );
        if (totalNumberOfPages !== this.currentPage) {
          return true;
        }
      }
      return false;
    },
  },
  methods: {
    getPushEngageSubscribeStatus() {
      let that = this;
      window._peq.push([
        // we can show a button
        "subscriber-status",
        function (res) {
          // console.log(res);
          if (res.statuscode === 1) {
            that.pushEngageSubscribed = true;
          }
          if (res.statuscode === 1) {
            if (that.profileData && !that.profileData.isSubscribed) {
              that.pushEngageSubscribed = true;
            }
          } else {
            if (that.profileData && that.profileData.isSubscribed) {
              that.pushEngageSubscribed = false;
              that.updateUserNotificationStatusCustom(false);
            }
          }
        },
      ]);
    },
    logNotification() {
      const validTypes = ["MISSED_CALL", "TEXT_MESSAGE", "FORM_SUBMISSION", "VOICE_MAIL"];
      NotificationService.logNotifications(
        this.userDetails.userID,
        validTypes[Math.floor(Math.random() * validTypes.length)]
      )
        .then(({ data: { success, data } }) => {
          console.log(success, data);
        })
        .catch((e) => {
          console.log("error", e);
        });
    },
    updateUserNotificationStatus() {
      // first execute script, then API
      this.updateUserNotificationStatusLoading = true;
      NotificationService.updateUserNotificationStatus(!this.isSubscribed)
        .then(({ data: { success, message } }) => {
          if (success) {
            this.updateUserNotificationStatusLoading = false;
            this.$toast.open(toastConfig.toastSuccess(message));
            this.getProfileInfo();
          } else {
            this.updateUserNotificationStatusLoading = false;
          }
        })
        .catch((e) => {
          this.updateUserNotificationStatusLoading = false;
          console.log("error", e);
        });
    },
    updateUserNotificationStatusCustom(status) {
      // first execute script, then API
      NotificationService.updateUserNotificationStatus(status)
        .then(({ data: { success, message } }) => {
          if (success) {
            this.getProfileInfo();
          } else {
          }
        })
        .catch((e) => {
          console.log("error", e);
        });
    },
    getProfileInfo() {
      this.profileLoading = true;
      ProfileService.getProfileInfo()
        .then(({ data: { success, message, data } }) => {
          if (success) {
            this.profileLoading = false;
            this.profileData = data;
            this.isSubscribed = data.isSubscribed;
          } else {
            this.$toast.open(toastConfig.toastError(message));
            this.profileLoading = false;
            this.profileData = null;
          }
        })
        .catch((e) => {
          this.profileLoading = false;
          this.profileData = null;
          console.log("error", e);
          this.$toast.open(
            toastConfig.toastError("Something went wrong while fetching profile details!")
          );
        });
    },
    getUnviewiedCount() {
      this.unreadNotificationsLoading = true;
      NotificationService.getUnviewiedCount()
        .then(({ data: { success, data } }) => {
          if (success) {
            this.unreadNotificationsLoading = false;
            this.unreadNotifications = data.count;
            if (this.showNotficationsSlider) {
              this.latestNotificationDetails = { ...data };
            }
          } else {
            this.unreadNotificationsLoading = false;
          }
        })
        .catch((e) => {
          this.unreadNotificationsLoading = false;
          console.log("error", e);
        });
    },
    getUserNotifications(limit, offset) {
      this.fetchNotificationLoading = true;
      NotificationService.getUserNotifications(limit, offset)
        .then(({ data: { success, data } }) => {
          this.isViewMoreClicked = false;
          this.newNotficationsHaveCome = false;
          if (success) {
            this.fetchNotificationLoading = false;
            if (data.notifications.length) {
              this.rawNotifications = [...this.rawNotifications, ...data.notifications];
              let tempNotifications = _.map(this.rawNotifications, (n) => {
                const createdAt = new Date(n.createdAt);
                const createdDay = moment(createdAt).format("L");
                const isyesterday =
                  createdDay === moment().subtract(1, "days").format("L");
                const istoday = createdDay === moment().format("L");
                return {
                  ...n,
                  createdAt,
                  createdByDay: moment(createdAt).format("L"),
                  timeFormattedString: moment(createdAt).fromNow(),
                  dateFormattedString: moment(createdAt).format("MMM Do"),
                  isyesterday,
                  istoday,
                };
              });
              tempNotifications = _.groupBy(tempNotifications, "createdByDay");
              this.notifications = _.map(
                _.orderBy(_.keys(tempNotifications), (k) => moment(k), ["desc"]),
                (d) => ({
                  day: d,
                  notifications: _.orderBy(
                    tempNotifications[d],
                    (k) => moment(k.createdAt),
                    ["desc"]
                  ),
                })
              );
              this.totalNotificationCount = data.totalRecordCount;
            }
            this.currentPage = offset / limit + 1;
          } else {
            this.fetchNotificationLoading = false;
          }
        })
        .catch((e) => {
          this.isViewMoreClicked = false;
          this.fetchNotificationLoading = false;
          console.log("error", e);
        });
    },
    reloadNotifications() {
      this.notifications = [];
      this.rawNotifications = [];
      this.totalNotificationCount = 0;
      this.currentPage = 1;
      this.newNotficationsHaveCome = false;
      this.isViewMoreClicked = false;
      this.getUserNotifications(this.notificationfetchLimit, 0);
    },
  },
  watch: {
    showNotficationsSlider(v) {
      if (v) {
        this.getUserNotifications(this.notificationfetchLimit, 0);
      } else {
        this.notifications = [];
        this.rawNotifications = [];
        this.totalNotificationCount = 0;
        this.currentPage = 1;
        this.newNotficationsHaveCome = false;
        this.isViewMoreClicked = false;
        this.latestNotificationDetails = null;
      }
    },
    latestNotificationDetails(v, prevValue) {
      if (
        this.showNotficationsSlider &&
        v !== null &&
        prevValue !== null &&
        v.lastFetchedNotficationId !== prevValue.lastFetchedNotficationId
      ) {
        if (new Date(v.createdAt) > new Date(prevValue.createdAt)) {
          this.newNotficationsHaveCome = true;
        }
      }
    },
    isViewMoreClicked(v) {
      if (v) {
        this.getUserNotifications(
          this.notificationfetchLimit,
          this.notificationfetchLimit * this.currentPage
        );
      }
    },
  },
};
</script>