| | |
| | | <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> |