| | |
| | | <template> |
| | | <div> |
| | | <Ui-Carousel></Ui-Carousel> |
| | | <div class="page-container"> |
| | | <h5 class="mdTxt mb-30">預約保險顧問</h5> |
| | | <el-button |
| | | class="reserveBtn recommendConsultant" |
| | | @click="routerPush('/recommendConsultant')" |
| | | > |
| | | <p>嚴選配對</p> |
| | | </el-button> |
| | | <el-button |
| | | class="reserveBtn quickFilter" |
| | | @click="routerPush('/quickFilter')" |
| | | > |
| | | <p>快速篩選</p> |
| | | </el-button> |
| | | <el-row class="mb-30 rowStyle"> |
| | | <el-col :span="16"> |
| | | <span class="mdTxt">我的顧問清單</span> |
| | | <span class="smTxt_bold amount">共 {{consultantList.length}} 筆</span> |
| | | </el-col> |
| | | <el-col |
| | | :span="8" |
| | | class="mdTxt readMore" |
| | | v-if="consultantList.length > 3" |
| | | @click.native="routerPush('/myConsultantList/consultantList')">查看更多</el-col> |
| | | </el-row> |
| | | <ConsultantList |
| | | :agents="consultantList.slice(0, 3)" |
| | | @removeAgent="removeAgent" |
| | | ></ConsultantList> |
| | | <div class='pam-recommend pb-30 pt-30'> |
| | | <h5 class="mdTxt">推薦保險顧問</h5> |
| | | <img class="absulate img" src="~/assets/images/index_recommend.svg" alt=""> |
| | | </div> |
| | | <ConsultantSwiper :agents="recommendList"></ConsultantSwiper> |
| | | <div> |
| | | <Ui-Carousel></Ui-Carousel> |
| | | <div class="page-container"> |
| | | |
| | | <div> |
| | | <h5 class="mdTxt">預約保險顧問</h5> |
| | | <div class="mt-10 pam-reserveBtn--block"> |
| | | <el-button class="reserveBtn recommendConsultant" |
| | | @click="navigateToRoute('/recommendConsultant')"> |
| | | <p>嚴選配對</p> |
| | | </el-button> |
| | | <el-button class="reserveBtn quickFilter" |
| | | @click="navigateToRoute('/quickFilter')"> |
| | | <p>快速篩選</p> |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="pam-paragraph"> |
| | | <el-row class="rowStyle"> |
| | | <el-col :span="16"> |
| | | <span class="mdTxt">我的顧問清單</span> |
| | | <span class="smTxt_bold amount">共 {{ consultantList.length }} 筆</span> |
| | | </el-col> |
| | | <el-col :span="8" |
| | | class="mdTxt readMore fix-chrome-click--issue" |
| | | v-if="consultantList.length > 3" |
| | | @click.native="navigateToRoute('/myConsultantList/consultantList')">查看更多</el-col> |
| | | </el-row> |
| | | <ConsultantList class="mt-10" |
| | | :agents="consultantList.slice(0, 3)"></ConsultantList> |
| | | </div> |
| | | |
| | | |
| | | <div class='pam-paragraph'> |
| | | <div class="pam-recommend"> |
| | | <h5 class="mdTxt">推薦保險顧問</h5> |
| | | <img class="img" |
| | | src="~/assets/images/index_recommend.svg" |
| | | alt=""> |
| | | </div> |
| | | <ConsultantSwiper :agents="recommendList"></ConsultantSwiper> |
| | | </div> |
| | | </div> |
| | | |
| | | <Ui-Dialog |
| | | :isVisible.sync="isShowAppointmentDialog" |
| | | :width="appointmentDialogWidth" |
| | | class="pam-myDemand-dialog pam-dialog-reserved" |
| | | > |
| | | <div v-if="appointmentDetail"> |
| | | <h5 class="subTitle text--center mb-30">預約成功</h5> |
| | | <p class="smTxt">{{appointmentDetail.appointmentDate | formatDate}}</p> |
| | | <div class="reserved-info"> |
| | | <p>姓名:{{appointmentDetail.name}}</p> |
| | | <p>電話:{{appointmentDetail.phone}}</p> |
| | | <p>Email:{{appointmentDetail.email}}</p> |
| | | <p>性別:{{gender}}</p> |
| | | <p>年齡:{{appointmentDetail.age | toAgeLabel }}</p> |
| | | <p>職業:{{appointmentDetail.job}}</p> |
| | | <p>諮詢方式:{{appointmentDetail.consultationMethod | toConsultationMethod }}</p> |
| | | <p>需求:{{ appointmentDetail.requirement ? appointmentDetail.requirement.split(',').join('、') : '--'}}</p> |
| | | <p |
| | | v-for="(item, index) in hopeContactTime" |
| | | :key="index" |
| | | >連絡時段{{index + 1 | formatNumber}}:{{ item | formatHopeContactTime }}</p> |
| | | <div v-if="appointmentDetail.satisfactionScore"> |
| | | <div class="mdTxt mt-10 mb-10">滿意度</div> |
| | | <el-rate |
| | | :value="appointmentDetail.satisfactionScore" |
| | | class="pam-myDemand-dialog__rate" |
| | | disabled> |
| | | </el-rate> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="notScoreAppointmentYet" class="reserved-btn"> |
| | | <el-button type="primary" |
| | | @click.native="reviewsBtn = true">給予滿意度評分</el-button> |
| | | </div> |
| | | |
| | | <div v-if="appointmentDetail.communicateStatus === 'reserved'" class="text--center mt-10"> |
| | | <el-button @click="isCancelPopup = true">取消預約</el-button> |
| | | <el-button @click="edit" type="primary">編輯</el-button> |
| | | </div> |
| | | </div> |
| | | </Ui-Dialog> |
| | | |
| | | <PopUpFrame |
| | | :isOpen.sync="isShowReAppointmentDialog" |
| | | @closePopUp="removeUrlQueryParameter('notContactAppointmentId')" |
| | | > |
| | | <div class="pam-dialog-review"> |
| | | <div class="mt-30 text--middle" v-if="agentInfo"> |
| | | 很抱歉!您預約的<span class="text--bold">{{ consultantName }}</span>顧問正忙碌中,請您取消預約並改選其他顧問 |
| | | </div> |
| | | |
| | | <el-row |
| | | type="flex" |
| | | class="mt-50" |
| | | justify="center"> |
| | | <el-button |
| | | type="primary" |
| | | @click="reAppointment">取消預約再改選其他顧問</el-button> |
| | | </el-row> |
| | | <el-row |
| | | type="flex" |
| | | class="mt-20" |
| | | justify="center"> |
| | | <el-button |
| | | class="outline_btn" |
| | | @click="cancelAppointment">取消預約</el-button> |
| | | </el-row> |
| | | </div> |
| | | </PopUpFrame> |
| | | |
| | | <PopUpFrame |
| | | :isOpen.sync="isShowReviewDialog" |
| | | @closePopUp="removeUrlQueryParameter('appointmentId')" |
| | | > |
| | | <div class="mdTxt pam-dialog-review"> |
| | | 保險顧問滿意度 |
| | | <span class="hint">選取星星</span> |
| | | <div class="mt-30 review-content" v-if="agentInfo"> |
| | | <UiAvatar :size="80" :agentNo="agentInfo.agentNo"></UiAvatar> |
| | | <div class="review-text">對於顧問 |
| | | <span class="text--primary">{{agentInfo.name}}</span> |
| | | 的整體服務,您給予幾顆星評價? |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="review-score"> |
| | | <el-rate v-model="inputScore" class="pam-rate mt-30"></el-rate> |
| | | </div> |
| | | |
| | | <div class="review-btn"> |
| | | <el-button |
| | | type="primary" |
| | | :disabled="!inputScore" |
| | | @click="userReviewsConsultants">送出</el-button> |
| | | </div> |
| | | </div> |
| | | </PopUpFrame> |
| | | |
| | | <div class="video-container" |
| | | v-if="isShowFilmPlayer" |
| | | style="position: fixed; bottom: 30px; right: 30px; z-index: 9999; display: flex; justify-content: flex-end;" |
| | | > |
| | | <iframe |
| | | id="ytplayer" type="text/html" width="360" height="270" |
| | | frameborder="0" |
| | | allowfullscreen |
| | | sandbox="allow-scripts allow-same-origin allow-popups allow-presentation fullscreen" |
| | | :src="filmVideoSrc" |
| | | ></iframe> |
| | | <div class="close-btn" @click="closeVideo()">X</div> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, State, Action } from 'nuxt-property-decorator'; |
| | | import { getFavoriteFromStorage, setFavoriteToStorage } from '~/assets/ts/storageConsultant'; |
| | | import { addFavoriteConsultant, Consultants, deleteConsultant } from '~/assets/ts/api/consultant'; |
| | | import { login, getFavoriteConsultant } from '~/assets/ts/api/consultant'; |
| | | import { isLogin } from '~/assets/ts/auth'; |
| | | import {Action, Component, Getter, Mutation, namespace, State, Vue, Watch} from 'nuxt-property-decorator'; |
| | | |
| | | @Component({ |
| | | import appointmentService from '~/shared/services/appointment.service'; |
| | | import utilService, {AccessFroms} from '~/shared/services/utils.service'; |
| | | import reviewsService from '~/shared/services/reviews.service'; |
| | | import myConsultantService from '~/shared/services/my-consultant.service'; |
| | | import {Appointment, AppointmentClosedInfo} from '~/shared/models/appointment.model'; |
| | | import {Consultant} from '~/shared/models/consultant.model'; |
| | | import {UserReviewParams} from '~/shared/models/reviews.model'; |
| | | import {StrictQueryParams} from '~/shared/models/strict-query.model'; |
| | | import {AgentInfo} from '~/shared/models/agent-info.model'; |
| | | import {ContactStatus} from '~/shared/models/enum/contact-status'; |
| | | import {SatisfactionType} from '~/shared/models/enum/satisfaction-type'; |
| | | |
| | | const localStorage = namespace('localStorage'); |
| | | const roleStorage = namespace('localStorage'); |
| | | |
| | | @Component({ |
| | | layout: 'home' |
| | | }) |
| | | export default class MainComponent extends Vue { |
| | | consultantList: Consultants[] = []; |
| | | agents: Consultants[] = []; |
| | | @State('recommendList') recommendList!: Consultants[]; |
| | | @Action storeRecommendList!: any; |
| | | }) |
| | | export default class MainComponent extends Vue { |
| | | |
| | | @State('recommendList') |
| | | recommendList!: Consultant[]; |
| | | |
| | | @State('myConsultantList') |
| | | myConsultantList!: Consultant[]; |
| | | |
| | | @roleStorage.Getter |
| | | isAdminLogin!: boolean; |
| | | |
| | | @roleStorage.Getter |
| | | isUserLogin!: boolean; |
| | | |
| | | @Action |
| | | storeRecommendList!: any; |
| | | |
| | | @Action |
| | | storeConsultantList!: any; |
| | | |
| | | @Mutation |
| | | setAccessSource!: (accessSource: AccessFroms) => void; |
| | | |
| | | @localStorage.Mutation |
| | | storageClearQuickFilter!: () => void; |
| | | |
| | | @localStorage.Mutation |
| | | storageClearRecommendConsultant!: () => void; |
| | | |
| | | @localStorage.Getter |
| | | currentSatisfactionIdFromMsg!: string; |
| | | |
| | | @localStorage.Getter |
| | | currentNotContactAppointmentIdFromMsg!: string; |
| | | |
| | | @localStorage.Mutation |
| | | storageClearSatisfactionIdFromMsg!: () => void; |
| | | |
| | | @localStorage.Mutation |
| | | storageClearNotContactAppointmentIdFromMsg!: () => void; |
| | | |
| | | @localStorage.Mutation |
| | | storageStrickQueryItem!: (strictQueryDto: StrictQueryParams) => void; |
| | | |
| | | consultantList: Consultant[] = []; |
| | | |
| | | appointmentDialogWidth = ''; |
| | | inputScore = 0; |
| | | isShowAppointmentDialog = false; |
| | | isShowReAppointmentDialog = false; |
| | | isShowReviewDialog = false; |
| | | consultantName = ''; |
| | | contactStatus = ContactStatus; |
| | | |
| | | appointmentDetail: Appointment = { |
| | | age : '', |
| | | agentNo : '', |
| | | appointmentClosedInfo: {} as AppointmentClosedInfo, |
| | | appointmentDate : '', |
| | | appointmentMemoList: [], |
| | | appointmentNoticeLogs: [], |
| | | communicateStatus: this.contactStatus.PICKED, |
| | | consultantReadTime: '', |
| | | consultantViewTime: '', |
| | | contactTime : '', |
| | | contactType : '', |
| | | customerId : 0, |
| | | email : '', |
| | | gender : '', |
| | | hopeContactTime : '', |
| | | interviewRecordDTOs: [], |
| | | id : 0, |
| | | job : '', |
| | | lastModifiedDate : '', |
| | | name : '', |
| | | otherRequirement : '', |
| | | phone : '', |
| | | requirement : '', |
| | | satisfactionScore : 0, |
| | | consultationMethod : '' |
| | | }; |
| | | |
| | | agentInfo: Consultant = { |
| | | agentNo : '', |
| | | name : '', |
| | | img : '', |
| | | expertise : [], |
| | | avgScore : 0, |
| | | contactStatus : '', |
| | | createTime : '', |
| | | updateTime : '', |
| | | customerViewTime : '', |
| | | role : '', |
| | | seniority : '', |
| | | appointments : [] |
| | | }; |
| | | |
| | | isCloseVideo = false; |
| | | |
| | | @Getter |
| | | fromAccess!: AccessFroms; |
| | | |
| | | get filmVideoSrc() { |
| | | if (!this.fromAccess) return ''; |
| | | return this.fromAccess === AccessFroms.FILM_1 |
| | | ? 'https://www.youtube.com/embed/zVBLW9hWD0g?autoplay=1&mute=1&loop=1&playlist=zVBLW9hWD0g' |
| | | : 'https://www.youtube.com/embed/655JnwbuRGA?autoplay=1&mute=1&loop=1&playlist=655JnwbuRGA'; |
| | | } |
| | | |
| | | |
| | | get isShowFilmPlayer() { |
| | | return !!this.fromAccess && !this.isCloseVideo; |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | mounted() { |
| | | if (!this.recommendList) { |
| | | this.storeRecommendList(); |
| | | if (this.$route.query.from) { |
| | | const fromSource = this.$route.query.from as AccessFroms; |
| | | this.setAccessSource(fromSource); |
| | | utilService.insertAccessFrom(fromSource); |
| | | } |
| | | if (this.isAdminLogin) { |
| | | this.$router.push('/myAppointmentList/appointmentList'); |
| | | } else { |
| | | if (!this.recommendList?.length) { |
| | | this.storeRecommendList(); |
| | | } |
| | | |
| | | if (isLogin()) { |
| | | this.addFavoriteFromStorageToApi(); |
| | | getFavoriteConsultant().then((response) => this.consultantList = response.data); |
| | | } else { |
| | | this.consultantList = getFavoriteFromStorage(); |
| | | this.storeConsultantList(); |
| | | this.storageClearQuickFilter(); |
| | | this.storageClearRecommendConsultant(); |
| | | |
| | | if (this.isUserLogin) { |
| | | appointmentService.getNotContactAppointment().then((appointment) => { |
| | | if (appointment) { |
| | | this.$router.push({ query: { notContactAppointmentId: appointment.id + ''}}); |
| | | this.autoOpenAppointmentBy('askReAppointment', appointment.id); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | addFavoriteFromStorageToApi() { |
| | | const agentNoList = getFavoriteFromStorage().map(i => i.agentNo) |
| | | if (agentNoList.length > 0) { |
| | | addFavoriteConsultant(agentNoList).then(res => res); |
| | | localStorage.removeItem('favoriteConsultant'); |
| | | destroyed() { |
| | | this.removeUrlQueryParameter(); |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | @Watch('myConsultantList') |
| | | onMyConsultantListChange() { |
| | | this.consultantList = (this.myConsultantList || []) |
| | | .map((item) => ({ ...item, formatDate: new Date(item.updateTime || item.createTime)})) |
| | | .sort((preItem, nextItem) => +nextItem.formatDate - +preItem.formatDate); |
| | | |
| | | if (this.currentNotContactAppointmentIdFromMsg) { |
| | | this.autoOpenAppointmentBy('askReAppointment', +this.currentNotContactAppointmentIdFromMsg); |
| | | return; |
| | | } |
| | | |
| | | if (this.currentSatisfactionIdFromMsg) { |
| | | this.autoOpenAppointmentBy('inviteReviewConsultant',+this.currentSatisfactionIdFromMsg); |
| | | this.storageClearSatisfactionIdFromMsg(); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | private autoOpenAppointmentBy(reason: string, targetAppointmentId: number): void { |
| | | const setAgentInfo = new Promise((resolve, reject) => { |
| | | this.agentInfo = this.myConsultantList.filter(item => { |
| | | const appointmentIndex = item.appointments?.findIndex(i => i.id === targetAppointmentId); |
| | | return appointmentIndex !== undefined && appointmentIndex > -1; |
| | | })[0]; |
| | | if (this.agentInfo) { |
| | | myConsultantService.getConsultantDetail(this.agentInfo.agentNo).then((res) => resolve(res)); |
| | | } |
| | | }); |
| | | |
| | | const setAppointment = new Promise((resolve, reject) => { |
| | | appointmentService.getAppointmentDetail(targetAppointmentId).then((res) => resolve(res)); |
| | | }); |
| | | |
| | | Promise.all([setAgentInfo, setAppointment]).then((values) => { |
| | | const agentInfo = values[0] as AgentInfo; |
| | | const appointmentInfo = values[1] as Appointment; |
| | | this.consultantName = agentInfo.name; |
| | | this.appointmentDetail = appointmentInfo; |
| | | this.appointmentDialogWidth = utilService.isMobileDevice() ? '80%' : ''; |
| | | this.isShowAppointmentDialog = true; |
| | | switch (reason) { |
| | | case 'inviteReviewConsultant': |
| | | if (this.notScoreAppointmentYet) { |
| | | setTimeout(() => { |
| | | this.isShowReviewDialog = true; |
| | | }, 500); |
| | | } |
| | | break; |
| | | case 'askReAppointment': |
| | | setTimeout(() => { |
| | | this.isShowReAppointmentDialog = true; |
| | | }, 500); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | } |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | navigateToRoute(path: string): void { |
| | | this.$router.push(path); |
| | | } |
| | | |
| | | edit() { |
| | | this.isShowAppointmentDialog = false; |
| | | this.$router.push({path: `/questionnaire/${this.agentInfo.agentNo}`, query: {'edit': 'true'}}); |
| | | } |
| | | |
| | | reAppointment(): void { |
| | | appointmentService.cancelAppointment(this.appointmentDetail.id).then(() => { |
| | | const requirements = this.appointmentDetail && this.appointmentDetail.requirement |
| | | ? this.appointmentDetail.requirement.split(',') |
| | | : []; |
| | | this.storeConsultantList(); |
| | | this.storageStrickQueryItem({ requirements: requirements }); |
| | | this.storageClearNotContactAppointmentIdFromMsg(); |
| | | this.removeUrlQueryParameter('notContactAppointmentId'); |
| | | this.$router.push('/recommendConsultant'); |
| | | }); |
| | | } |
| | | |
| | | cancelAppointment(): void { |
| | | appointmentService.cancelAppointment(this.appointmentDetail.id).then(() => { |
| | | this.storeConsultantList(); |
| | | this.storageClearNotContactAppointmentIdFromMsg(); |
| | | this.removeUrlQueryParameter('notContactAppointmentId'); |
| | | this.isShowReAppointmentDialog = false; |
| | | this.isShowAppointmentDialog = false; |
| | | this.$router.push('/'); |
| | | }); |
| | | } |
| | | |
| | | userReviewsConsultants() { |
| | | const reviewParams: UserReviewParams = { |
| | | appointmentId: this.appointmentDetail.id, |
| | | score: this.inputScore, |
| | | type: SatisfactionType.APPOINTMENT |
| | | } |
| | | this.appointmentDetail.satisfactionScore = this.inputScore; |
| | | |
| | | reviewsService.userReviewsConsultants(reviewParams).then((res) => { |
| | | this.isShowReviewDialog = false; |
| | | }); |
| | | } |
| | | |
| | | routerPush(path: string) { |
| | | this.$router.push(path); |
| | | } |
| | | |
| | | removeAgent(agentNo: string) { |
| | | |
| | | if (!isLogin()) { |
| | | const findIndex = this.consultantList.findIndex((item, i) => { |
| | | return item.agentNo === agentNo; |
| | | }) |
| | | this.consultantList.splice(findIndex, 1); |
| | | setFavoriteToStorage(this.consultantList) |
| | | } else { |
| | | deleteConsultant(agentNo).then(res => this.$router.go(0)) |
| | | removeUrlQueryParameter(targetKey?: string): void { |
| | | // NOTE: 刪除特定的 query parameter [Tomas, 2022/1/24 11:36] |
| | | // [REF] How to remove a parameter from this.$router.query Nuxt.js? https://reurl.cc/X45aMD |
| | | let newRouteQuery = {}; |
| | | if (targetKey) { |
| | | Object.keys(this.$route.query).forEach((key) => { |
| | | if (key !== targetKey) { |
| | | newRouteQuery[key] = this.$route.query[key] |
| | | } |
| | | }) |
| | | } |
| | | this.$router.push(newRouteQuery); |
| | | this.storageClearSatisfactionIdFromMsg(); |
| | | this.storageClearNotContactAppointmentIdFromMsg(); |
| | | } |
| | | } |
| | | |
| | | closeVideo(): void { |
| | | this.isCloseVideo = true; |
| | | } |
| | | |
| | | /////////////////////////////////////////////////////////////////////////////// |
| | | |
| | | get gender(): string { |
| | | if (this.appointmentDetail.gender) { |
| | | return this.appointmentDetail.gender === 'male' ? '男性' : '女性'; |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | get hopeContactTime(): string[] { |
| | | const contactList = this.appointmentDetail.hopeContactTime |
| | | .split("'").map((item: any) => item.slice(0, item.length)); |
| | | return contactList.filter((item: any) => !!item && item !== ",") |
| | | } |
| | | |
| | | get notScoreAppointmentYet(): boolean { |
| | | if (this.appointmentDetail.communicateStatus === 'closed' || this.appointmentDetail.communicateStatus === 'done') { |
| | | return !this.appointmentDetail.satisfactionScore; |
| | | }; |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .page-container { |
| | | margin: 0px 20px 30px 20px; |
| | | } |
| | | |
| | | .reserveBtn.el-button--default { |
| | | width : 100%; |
| | | height : 110px; |
| | | border-radius : 10px; |
| | | margin-bottom : 15px; |
| | | font-size : 32px; |
| | | font-weight : 700; |
| | | background-position: right; |
| | | background-size : cover; |
| | | color : #68737A; |
| | | text-align : left; |
| | | background-repeat : no-repeat; |
| | | box-shadow : 0px 0px 6px #a79b9b29; |
| | | border-width : 0; |
| | | |
| | | p { |
| | | text-shadow: 1px 1px 5px $PRIMARY_WHITE; |
| | | } |
| | | } |
| | | |
| | | .el-button+.el-button { |
| | | margin-left: 0px; |
| | | } |
| | | |
| | | .quickFilter { |
| | | background-image: url('~/assets/images/quickFilter/banner_mob.svg'); |
| | | } |
| | | |
| | | .recommendConsultant { |
| | | background-image: url('~/assets/images/recommendConsultant/banner_mob.svg'); |
| | | } |
| | | .rowStyle { |
| | | .amount { |
| | | color: $PRUDENTIAL_GREY; |
| | | } |
| | | .readMore { |
| | | color: $PRIMARY_RED; |
| | | cursor: pointer; |
| | | text-align: right; |
| | | } |
| | | } |
| | | |
| | | .pam-recommend { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | |
| | | @media (min-width: 576px) and (max-width: 767px) { |
| | | .quickFilter.el-button--default { |
| | | background-image: url('~/assets/images/quickFilter/banner_web.svg'); |
| | | } |
| | | |
| | | .recommendConsultant.el-button--default { |
| | | background-image: url('~/assets/images/recommendConsultant/banner_web.svg'); |
| | | } |
| | | } |
| | | |
| | | @include desktop { |
| | | .page-container { |
| | | padding: 0px 20px 30px 20px; |
| | | width: 700px; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | .reserveBtn.el-button--default { |
| | | width: 100%; |
| | | height: 110px; |
| | | border-radius: 10px; |
| | | margin: 0 auto 17px auto; |
| | | font-size: 32px; |
| | | font-weight: 700; |
| | | background-position: right; |
| | | background-size: cover; |
| | | color: #68737A; |
| | | text-align: left; |
| | | background-repeat: no-repeat; |
| | | box-shadow: 0px 0px 6px #a79b9b29; |
| | | border-width: 0; |
| | | .landing-container { |
| | | border: 2px solid blue; |
| | | border-radius: 10px; |
| | | padding: 10px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | p { |
| | | text-shadow: 1px 1px 5px $PRIMARY_WHITE; |
| | | } |
| | | |
| | | &:nth-child(3) { |
| | | margin-bottom: 42px; |
| | | } |
| | | |
| | | .pam-reserveBtn--block { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .reserveBtn+.reserveBtn { |
| | | margin-left: 0px; |
| | | .reserveBtn { |
| | | max-width: 335px; |
| | | } |
| | | } |
| | | |
| | | .quickFilter { |
| | | background-image: url('~/assets/images/quickFilter/banner_mob.svg'); |
| | | } |
| | | /* 確保 .video-container 有相對/絕對定位或固定寬度 */ |
| | | .video-container { |
| | | position: relative; |
| | | width: auto; /* 根據你的影片尺寸調整 */ |
| | | } |
| | | |
| | | .recommendConsultant { |
| | | background-image: url('~/assets/images/recommendConsultant/banner_mob.svg'); |
| | | } |
| | | /* 關閉按鈕樣式 */ |
| | | .close-btn { |
| | | position: absolute; |
| | | top: -10px; |
| | | right: -10px; |
| | | cursor: pointer; |
| | | font-size: 20px; |
| | | color: #fff; |
| | | background-color: #000; |
| | | width: 30px; |
| | | height: 30px; |
| | | text-align: center; |
| | | line-height: 30px; |
| | | border-radius: 50%; |
| | | opacity: 0.7; |
| | | } |
| | | |
| | | @media (min-width: 576px) and (max-width: 1023px) { |
| | | .quickFilter.el-button--default { |
| | | background-image: url('~/assets/images/quickFilter/banner_web.svg'); |
| | | } |
| | | |
| | | .recommendConsultant.el-button--default { |
| | | background-image: url('~/assets/images/recommendConsultant/banner_web.svg'); |
| | | } |
| | | } |
| | | |
| | | .rowStyle { |
| | | .amount { |
| | | color: $PRUDENTIAL_GREY; |
| | | } |
| | | .readMore { |
| | | color: $PRIMARY_RED; |
| | | cursor: pointer; |
| | | text-align: right; |
| | | } |
| | | } |
| | | |
| | | @include desktop { |
| | | .page-container { |
| | | width: 700px; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | .reserveBtn { |
| | | max-width: 340px; |
| | | |
| | | &:nth-child(2) { |
| | | margin-right: 15px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pam-recommend { |
| | | position: relative; |
| | | |
| | | .img { |
| | | position: absolute; |
| | | right: 20px; |
| | | bottom: 0px; |
| | | } |
| | | } |
| | | .close-btn:hover { |
| | | opacity: 1; |
| | | } |
| | | |
| | | </style> |