保誠-保戶業務員媒合平台
HelenHuang
2022-06-09 9bdb95c9e34cef640534e5e5a1e2225a80442000
PAMapp/components/NavBar.vue
@@ -1,151 +1,334 @@
<template>
    <header class="pam-header">
      <img class="pam-header__logo" src="~/assets/images/logo.png" alt="" @click="$router.push('/')">
        <div class="pam-header__title">
          我的幸福我作主
          <div class="pam-header__sub-title">
            預約我的幸福守護者
          </div>
        </div>
        <div class="pam-header__action-bar">
          <i class="icon-bell text--dark-blue cursor--pointer" @click="$router.push('/notification')"></i>
          <!-- <el-dropdown @command="handleCommand">
            <i class="icon-avatar text--dark-blue cursor--pointer"></i>
            <el-dropdown-menu slot="dropdown" class="pam-header__dropdown">
              <li class="pam-header__dropdown-item" @click="$router.push('/login')">登入</li>
              <li class="pam-header__dropdown-item" @click="$router.push('/accountSetting')">個人帳號設定</li>
              <li class="pam-header__dropdown-item" @click="$router.push('/record/contactRecord')">查看紀錄</li>
              <li class="pam-header__dropdown-item" @click="$router.push('/myConsultantList/consultantList')">我的顧問清單</li>
              <li class="pam-header__dropdown-item">登出</li>
              <li class="pam-header__dropdown-item pam-header__dropdown-divider" @click="$router.push('/consultantLogin')">顧問登入</li>
            </el-dropdown-menu>
          </el-dropdown> -->
  <header class="pam-header">
    <div class="pam-header__logo"
      @click="pushRouterByLoginRole"></div>
    <div class="pam-header__title">
      <div class="pam-header__title--main">我的幸福我做主</div>
      <div class="pam-header__title--sub">預約我的幸福守護者</div>
    </div>
    <div class="pam-header__action-bar">
      <i
        v-if="isShowNotification"
        class="icon-bell text--dark-blue cursor--pointer"
        @click="$router.push('/notification')"
      >
        <span :class="{'newNotification': isNewNotification}"></span>
      </i>
          <el-dropdown>
            <i class="icon-avatar text--dark-blue cursor--pointer"></i>
            <el-dropdown-menu slot="dropdown" class="pam-header__dropdown">
              <template v-for="(navbarItem,index) in navBarList">
                <li class="pam-header__dropdown-item"
                  :class="{'pam-header__dropdown-divider':navbarItem.title === '顧問登入'}"
                  v-if="navbarItem.needRole.includes(loginRole)"
                  :key="index"
                  @click="linkTo(navbarItem.link)">
                    {{navbarItem.title}}
                </li>
              </template>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
    </header>
        <el-dropdown :class="{'is-open':isOpenDropdown}"
          ref="dropdown"
          trigger="click"
          @command="routerNavigateTo">
          <div
            @click="isOpenDropdown =!isOpenDropdown"
            @blur="isOpenDropdown =false">
            <template v-if="isAdminLogin">
              <UiAvatar
              :size="30"
              :agentNo="consultantId"
              class="admin-avatar"
              ></UiAvatar>
            </template>
            <template v-else>
              <i class="icon-avatar text--dark-blue cursor--pointer fix-chrome-click--issue"></i>
            </template>
          </div>
          <el-dropdown-menu
            class="pam-header__dropdown">
            <template v-for="(item,index) in navBarList">
              <el-dropdown-item :key="index"
                v-if="item.authorityOfRoleList.includes(loginRole)"
                class="fix-chrome-click--issue"
                :class="{'pam-header__dropdown-divider':item.title === '顧問登入'}"
                :command="item.routeUrl">
                {{item.title}}
              </el-dropdown-item>
            </template>
          </el-dropdown-menu>
        </el-dropdown>
    </div>
  </header>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import * as _ from 'lodash';
@Component
export default class NavBar extends Vue {
  navBarList=[
    {
      needRole:[Role.NOT_LOGIN],
      link:'/login',
      title:'登入',
    },
    {
      needRole:[Role.USER],
      link:'/accountSetting',
      title:'個人帳號設定',
    },
    {
      needRole:[Role.ADMIN],
      link:'/notFinish',
      title:'查看帳號資訊',
    },
    {
      needRole:[Role.USER,Role.ADMIN],
      link:'/record/contactRecord',
      title:'查看紀錄',
    },
    {
      needRole:[Role.NOT_LOGIN,Role.USER],
      link:'/myConsultantList/consultantList',
      title:'我的顧問清單',
    },
    {
      needRole:[Role.USER,Role.ADMIN],
      link:'',
      title:'登出',
    },
    {
      needRole:[Role.NOT_LOGIN,Role.USER],
      link:'/consultantLogin',
      title:'顧問登入',
    },
  ];
  get idToken():string | null{
    return localStorage.getItem('id_token');
  }
  get roleOfState():string | null{
    return localStorage.getItem('roleOfState');
  }
  get loginRole():string{
    return this.roleOfState&&this.idToken ? this.roleOfState : Role.NOT_LOGIN;
  import { Vue, Component } from 'vue-property-decorator';
  import { Action, namespace, State, Watch } from 'nuxt-property-decorator';
  import { Role } from '~/shared/models/enum/Role';
  import * as _ from 'lodash';
  import { NotificationList } from '~/shared/models/reviews.model';
  import { AppointmentLog } from '~/shared/models/appointment.model';
  const roleStorage = namespace('localStorage');
  @Component
  export default class NavBar extends Vue {
    @roleStorage.Getter
    idToken!: string | null;
    @roleStorage.Getter
    currentRole!: string | null;
    @roleStorage.Getter
    consultantId!: string | null;
    @roleStorage.Mutation
    storageClear!: () => void;
    @roleStorage.Getter
    isAdminLogin!: boolean;
    @roleStorage.Getter
    isUserLogin!: boolean;
    @Action
    storeMyPersonalNotification!: () => void;
    @State
    notificationList!: NotificationList[];
    @Action
    storeMyAppointmentReviewLog!: () => void;
    @State
    unReviewLogList!: AppointmentLog[];
    isOpenDropdown = false;
    navBarList = [{
        authorityOfRoleList: [Role.NOT_LOGIN],
        routeUrl: '/login',
        title: '登入 | 註冊',
      },
      {
        authorityOfRoleList: [Role.USER],
        routeUrl: '/accountSetting',
        title: '個人帳號設定',
      },
      {
        authorityOfRoleList:[Role.ADMIN],
        routeUrl: '/agentInfo/',
        title: '查看帳號資訊',
      },
      {
        authorityOfRoleList:[Role.ADMIN],
        routeUrl: '/record',
        title: '查看紀錄',
      },
      {
        authorityOfRoleList: [Role.USER],
        routeUrl: '/userReviewsRecord',
        title: '查看紀錄',
      },
      {
        authorityOfRoleList: [Role.NOT_LOGIN, Role.USER],
        routeUrl: '/myConsultantList/consultantList',
        title: '我的顧問清單',
      },
      {
        authorityOfRoleList: [Role.NOT_LOGIN, Role.USER],
        routeUrl: '/faq',
        title: 'FAQ 常見問題',
      },
      {
        authorityOfRoleList: [Role.USER, Role.ADMIN],
        routeUrl: '',
        title: '登出',
      },
      {
        authorityOfRoleList: [Role.NOT_LOGIN],
        routeUrl: '/consultantLogin',
        title: '顧問登入',
      },
    ];
    //////////////////////////////////////////////////////////////////////
    @Watch('$route', {immediate: true})
    onRouterChange() {
        if (this.currentRole) {
          this.storeMyPersonalNotification();
          this.storeMyAppointmentReviewLog();
        }
    }
    //////////////////////////////////////////////////////////////////////
    routerNavigateTo(url: string): void {
      (this.$refs.dropdown as any).hide();
      _.isEqual(url,'')
        ? this.logout()
        : this.$router.push(_.isEqual(url,'/agentInfo/') ? url+this.consultantId :url);
    }
    pushRouterByLoginRole(): void {
      const link = _.isEqual(this.currentRole, Role.ADMIN) ? '/myAppointmentList/appointmentList' : '/';
      this.$router.push(link);
    }
    logout(): void {
      this.storageClear();
      _.isEqual(this.$route.name, 'index') ? location.reload() : this.$router.push('/');
    }
    get loginRole(): Role {
      return this.idToken && this.currentRole ? (this.currentRole as Role): Role.NOT_LOGIN;
    }
    get isShowNotification() {
      if (this.isUserLogin) {
        return this.notificationList.length || this.unReviewLogList.length;
      }
      if (this.isAdminLogin) {
        return this.notificationList.length
      }
    }
    get isNewNotification() {
      if (this.currentRole) {
        return this.notificationList.filter(item => !item.readDate).length;
      }
    }
  }
  linkTo(routerLink:string):void{
    _.isEqual(routerLink,'') ? this.fakeLogout() :this.$router.push(routerLink);
  }
  // TODO: 僅OTP認證開發前 暫時使用
  fakeLogout():void{
    localStorage.clear();
    this.$router.go(0);
  }
}
export enum Role{
  USER='user',
  ADMIN='admin',
  NOT_LOGIN='',
}
</script>
<style lang="scss" scoped>
.pam-header {
  height: 53px;
  display: flex;
  align-items: center;
  .pam-header__logo {
    height: 100%;
  }
  .pam-header__title {
    flex: 1;
    margin: 10px 0;
    padding-left: 10px;
    border-left: 1px solid #CCCCCC;
    font-size: 16px;
    font-weight: bold;
    color: $PRUDENTIAL_GREY;
    letter-spacing: 3.6px;
    flex-basis: 140px;
    .pam-header__sub-title {
      padding-top: 2px;
      font-size: 13px;
      font-weight: bold;
      color: $CORAL;
      letter-spacing: 1.2px
    }
  }
  .pam-header__action-bar {
  .pam-header {
    position: fixed;
    top: 0;
    height: $MOB_NAV_BAR;
    width: 100%;
    display: flex;
    font-size: 24px;
    font-weight: bold;
    justify-content: space-around;
    i {
      padding: 0 15px;
      @media screen and (max-width: 320px) {
        padding: 0 5px;
    align-items: center;
    background-color: $PRIMARY_WHITE;
    z-index: 6;
    .pam-header__logo {
      height: 30px;
      width: 115px;
      margin: 0 10px;
      background-image: url('~/assets/images/taiwan-logo.png');
      background-repeat: no-repeat;
      background-size: contain;
      background-position: center;
    }
    .pam-header__title {
      flex: 1;
      flex-basis: 160px;
      border-left: 1px #CCCCCC solid;
      padding-left: 10px;
    .pam-header__title--main {
      font-size: 16px;
      font-weight: bold;
      color: $PRUDENTIAL_GREY;
      letter-spacing: 0.8px;
      @media screen and (max-width: 352px) {
        font-size: 12px;
      }
    }
    .pam-header__title--sub {
      padding-top: 2px;
        font-size: 12px;
        transform: scale(0.9);
        -webkit-transform-origin-x: 0;
        font-weight: bold;
        color: $CORAL;
        letter-spacing: 1.2px;
      }
    }
    .pam-header__action-bar {
      position: relative;
      display: flex;
      height: 100%;
      font-size: 24px;
      font-weight: bold;
      align-items: center;
      justify-content: space-around;
      i {
        padding: 0px 15px;
        @extend .fix-chrome-click--issue;
        @media screen and (max-width: 352px) {
          padding: 0px 10px;
        }
      }
      .admin-avatar {
        margin: 0px 15px;
        @media screen and (max-width: 352px) {
          margin: 0px 10px;
        }
      }
      .icon-bell {
        position: relative;
        .newNotification {
          position: absolute;
          width: 10px;
          height: 10px;
          top: 0;
          right: 15px;
          border-radius: 50px;
          background: $PRIMARY_RED;
        }
      }
    }
  }
}
  .el-dropdown{
    height: 100%;
    display: flex;
    align-items: center;
    &.is-open {
        background-color: $PEACH;
      i {
        color: $PRIMARY_WHITE;
      }
    }
  }
  @include desktop {
    .pam-header {
      height: $DESKTOP_NAV_BAR;
      .pam-header__logo {
        width: 160px;
        height: 70px;
        margin: 0;
        background-image: url('~/assets/images/logo.png');
        background-size: contain;
        background-repeat: no-repeat;
        background-position: center;
      }
      .pam-header__title {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        border: none;
        padding-left: 30px;
        .pam-header__title--main {
          font-size: 30px;
          letter-spacing: 1.5px;
        }
        .pam-header__title--sub {
          font-size: 20px;
          letter-spacing: 2px;
          transform: none;
          margin-left: 30px;
        }
      }
    }
  }
</style>