| | |
| | | &:disabled { |
| | | background-color: $LIGHT_GREY; |
| | | } |
| | | } |
| | | |
| | | .pam-cus-tabs { |
| | | display: flex; |
| | | width: 100%; |
| | | height: 45px; |
| | | |
| | | .cus-tab-item { |
| | | width: 50%; |
| | | text-align: center; |
| | | font-size: 24px; |
| | | border-bottom: solid 3px $LIGHT_GREY; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .is-active { |
| | | font-weight: bold; |
| | | border-bottom: solid 3px $PRIMARY_BLACK; |
| | | |
| | | } |
| | | } |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <el-row type="flex" class="rowStyle"> |
| | | <el-col :xs="5" :sm="3"> |
| | | <el-avatar |
| | | :size="50" |
| | | src="" |
| | | class="cursor--pointer" |
| | | ></el-avatar> |
| | | <div class="satisfaction"> |
| | | <i class="icon-star pam-icon icon--yellow satisfaction"></i> |
| | | <span>{{'1'}}</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="14" :sm="15"> |
| | | <div class="smTxt_bold name">{{client.name}}</div> |
| | | <div class="message">é ç´æå</div> |
| | | <div class="professionals"> |
| | | <template v-if="client.requirements.length > 0"> |
| | | <span |
| | | v-for="(item, index) in client.requirements" |
| | | :key="index" |
| | | class="professionalsTxt" |
| | | >#{{item}}</span> |
| | | </template> |
| | | <template v-else> |
| | | <span class="professionalsTxt noProfessionalsTxt" |
| | | >(å®¢æ¶æªæä¾éæ±é
ç®)</span> |
| | | </template> |
| | | </div> |
| | | </el-col> |
| | | <el-col class="flex-column contactInfo" :xs="5" :sm="6"> |
| | | <div class="smTxt_bold cursor--pointer" |
| | | :class="client.communicateStatus" |
| | | @click="openDetail" |
| | | >{{isReserved ? 'å·²é ç´' : 'å·²è¯çµ¡'}} |
| | | </div> |
| | | <div class="date xsTxt text--mid_grey">{{date}}</div> |
| | | <div class="xsTxt text--mid_grey">{{time}}</div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <Ui-Dialog |
| | | :isVisible.sync="isVisibleDialog" |
| | | :width="width" |
| | | > |
| | | <h5 class="subTitle text--center mb-30" |
| | | >{{isReserved ? 'é ç´æå' : 'å·²è¯çµ¡è³è¨'}}</h5> |
| | | <p class="smTxt text-right">ä»å¤© 10:00</p> |
| | | <div class="dialogTxt"> |
| | | <p>å§åï¼{{client.name}}</p> |
| | | <p>é»è©±ï¼0912345678</p> |
| | | <p>Emailï¼</p> |
| | | <p>æ§å¥ï¼{{client.gender === 'male' ? 'ç·æ§' : '女æ§'}}</p> |
| | | <p>年齡ï¼{{client.age}}</p> |
| | | <p>è·æ¥ï¼ä¸è¬è·æ¥</p> |
| | | <p>éæ±ï¼{{client.requirements}}</p> |
| | | <p>é£çµ¡ææ®µä¸ï¼ææä¸,æææ¥ 18:00~21:00</p> |
| | | <div class="mt-30 text--center"> |
| | | <el-button>{{isReserved ? 'æ¨è¨»çºå·²é£çµ¡' : 'ç¼é滿æåº¦'}}</el-button> |
| | | </div> |
| | | </div> |
| | | </Ui-Dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop } from 'nuxt-property-decorator'; |
| | | import { isMobileDevice } from '~/assets/ts/device'; |
| | | import { Clients } from '~/pages/clientReservedList.vue'; |
| | | |
| | | @Component |
| | | export default class ClientList extends Vue { |
| | | @Prop() client!: Clients; |
| | | isVisibleDialog = false; |
| | | width = ''; |
| | | |
| | | get time() { |
| | | const hours = this.client.time.getHours(); |
| | | const minutes = this.client.time.getMinutes(); |
| | | return `${hours} : ${minutes}` |
| | | } |
| | | |
| | | get date() { |
| | | const month = this.client.time.getMonth(); |
| | | const date = this.client.time.getDate(); |
| | | return `${month} / ${date}` |
| | | } |
| | | |
| | | get isReserved() { |
| | | return this.client.communicateStatus === 'reserved'; |
| | | } |
| | | |
| | | openDetail() { |
| | | this.width = isMobileDevice() ? '80%' : ''; |
| | | this.isVisibleDialog = true; |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .rowStyle { |
| | | padding: 10px; |
| | | background-color: $PRIMARY_WHITE; |
| | | margin-bottom: 10px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | |
| | | .satisfaction { |
| | | font-size: 12px; |
| | | font-weight: bold; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | .message { |
| | | margin:10px 0; |
| | | } |
| | | |
| | | .professionals { |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | |
| | | .professionalsTxt { |
| | | font-size: 12px; |
| | | font-weight: bold; |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | .noProfessionalsTxt { |
| | | color: $PRUDENTIAL_GREY; |
| | | font-weight: lighter; |
| | | } |
| | | } |
| | | |
| | | .contactInfo { |
| | | text-align: right; |
| | | .date { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | |
| | | .reserved { |
| | | @extend .text--primary; |
| | | } |
| | | |
| | | .contacted { |
| | | color: $SKY_BLUE; |
| | | } |
| | | } |
| | | |
| | | .flex-column { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .dialogTxt { |
| | | font-size: 20px; |
| | | } |
| | | |
| | | .text-right { |
| | | text-align: right; |
| | | } |
| | | </style> |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <template v-if="clients.length > 0"> |
| | | <ClientCard |
| | | v-for="(client, index) in clients" |
| | | :key="index" |
| | | :client="client" |
| | | ></ClientCard> |
| | | </template> |
| | | <template v-else> |
| | | <div class="emptyRowStyle"> |
| | | <div class="smTxt txt">{{title === 'reservedList' ? 'æ¨ç®åç¡å·²é ç´å®¢æ¶' : 'æ¨ç®åç¡å·²è¯çµ¡å®¢æ¶'}}</div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang='ts'> |
| | | import { Vue, Component, Prop } from 'nuxt-property-decorator'; |
| | | import { Clients } from '~/pages/clientReservedList.vue'; |
| | | |
| | | @Component |
| | | export default class ClientList extends Vue { |
| | | @Prop() clients!: Clients[]; |
| | | @Prop() title!: string; |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .emptyRowStyle { |
| | | background-color: $PRIMARY_WHITE; |
| | | width: 100%; |
| | | height: 100px; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | |
| | | .txt { |
| | | color: $PRUDENTIAL_GREY; |
| | | margin-left: 17px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-pagination |
| | | :current-page.sync="currentPage" |
| | | layout="prev, pager, next" |
| | | :total="totalList.length" |
| | | :page-size="pageSize" |
| | | @current-change="handleCurrentChange" |
| | | class="mt-10" |
| | | > |
| | | </el-pagination> |
| | | </template> |
| | |
| | | } |
| | | |
| | | handleCurrentChange(currentPage: number) { |
| | | |
| | | if (this.totalList.length <= this.pageSize && currentPage !== 1) { |
| | | currentPage -= 1; |
| | | } |
| | | |
| | | if (this.totalList) { |
| | | this.pageList = this.totalList.slice(this.pageSize * currentPage - this.pageSize, this.pageSize * currentPage) |
| | | this.chagnePage(); |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <div class="pam-cus-tabs mb-30"> |
| | | <div |
| | | class="cus-tab-item" |
| | | :class="{'is-active': activeTabName === 'reservedList'}" |
| | | @click="tabClick('reservedList')" |
| | | >客æ¶é ç´ |
| | | <span class="p">({{reservedList.length}})</span> |
| | | </div> |
| | | <div |
| | | class="cus-tab-item" |
| | | :class="{'is-active': activeTabName === 'contactedList'}" |
| | | @click="tabClick('contactedList')" |
| | | >å·²è¯çµ¡ |
| | | <span class="p">({{contactedList.length}})</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <NuxtChild |
| | | :contactedList="contactedList" |
| | | :reservedList="reservedList" |
| | | ></NuxtChild> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Context } from '@nuxt/types'; |
| | | import { Vue, Component } from 'nuxt-property-decorator'; |
| | | |
| | | @Component |
| | | export default class ClientReservedList extends Vue { |
| | | activeTabName = 'reservedList'; |
| | | reservedList: Clients[] = []; |
| | | contactedList: Clients[] = []; |
| | | clients: Clients[] = []; |
| | | |
| | | async asyncData(context: Context) { |
| | | let reservedList: Clients[] = []; |
| | | let contactedList: Clients[] = []; |
| | | let clients: Clients[] = []; |
| | | |
| | | await context.$service.home.clientReservedList().then((result: Clients[]) => { |
| | | clients = result; |
| | | }) |
| | | |
| | | contactedList = clients.filter(item => item.communicateStatus === 'contacted'); |
| | | reservedList = clients.filter(item => item.communicateStatus === 'reserved'); |
| | | |
| | | return { |
| | | clients, |
| | | contactedList, |
| | | reservedList |
| | | } |
| | | } |
| | | |
| | | tabClick(path: string) { |
| | | this.activeTabName = path; |
| | | this.$router.push('/clientReservedList/' + this.activeTabName) |
| | | } |
| | | } |
| | | |
| | | export interface Clients { |
| | | name: string, |
| | | clientId: string, |
| | | phone: string, |
| | | time: Date, |
| | | gender: string, |
| | | age: string, |
| | | job: string, |
| | | requirements: string[], |
| | | communicateStatus: string |
| | | } |
| | | </script> |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <ClientList |
| | | :clients="pageList" |
| | | :title="'contactedList'" |
| | | ></ClientList> |
| | | |
| | | <UiPagination |
| | | :totalList="contactedList" |
| | | @changePage="changePage" |
| | | ></UiPagination> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop } from 'nuxt-property-decorator'; |
| | | import { Clients } from '../clientReservedList.vue'; |
| | | |
| | | @Component |
| | | export default class ClientContactedList extends Vue { |
| | | @Prop() contactedList!: Clients[]; |
| | | pageList: Clients[] = []; |
| | | |
| | | changePage(pageList: Clients[]) { |
| | | this.pageList = pageList; |
| | | } |
| | | } |
| | | </script> |
¤ñ¹ï·sÀÉ®× |
| | |
| | | <template> |
| | | <div> |
| | | <ClientList |
| | | :clients="pageList" |
| | | :title="'reservedList'" |
| | | ></ClientList> |
| | | |
| | | <UiPagination |
| | | :totalList="reservedList" |
| | | @changePage="changePage" |
| | | ></UiPagination> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { Vue, Component, Prop } from 'nuxt-property-decorator'; |
| | | import { Clients } from '../clientReservedList.vue'; |
| | | |
| | | @Component |
| | | export default class ClientReservedList extends Vue { |
| | | @Prop() reservedList!: Clients[]; |
| | | pageList: Clients[] = []; |
| | | |
| | | changePage(pageList: Clients[]) { |
| | | this.pageList = pageList; |
| | | } |
| | | } |
| | | </script> |
| | |
| | | <template> |
| | | <div> |
| | | <div class="flex mb-30"> |
| | | <div class="pam-cus-tabs mb-30"> |
| | | <div |
| | | class="cus-tab-item" |
| | | :class="{'is-active': activeTabName === 'consultantList'}" |
| | |
| | | } |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .flex { |
| | | display: flex; |
| | | width: 100%; |
| | | height: 45px; |
| | | |
| | | .cus-tab-item { |
| | | width: 50%; |
| | | text-align: center; |
| | | font-size: 24px; |
| | | border-bottom: solid 3px $LIGHT_GREY; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .is-active { |
| | | font-weight: bold; |
| | | border-bottom: solid 3px $PRIMARY_BLACK; |
| | | |
| | | } |
| | | } |
| | | |
| | | </style> |
| | | </script> |
| | |
| | | new: true, |
| | | agentNo: 0, |
| | | name: 'å¼µå°ç¾', |
| | | img: 'https://randomuser.me/api/portraits/women/31.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'è³ç¢è½ç§»'], |
| | | satisfaction: 4.8, |
| | | contactStatus: 'reserved', |
| | |
| | | new: true, |
| | | agentNo: 1, |
| | | name: 'è£å¸¥å¥', |
| | | img: 'https://randomuser.me/api/portraits/men/32.jpg', |
| | | img: '', |
| | | professionals: [], |
| | | satisfaction: 4, |
| | | contactStatus: 'contacted', |
| | |
| | | new: false, |
| | | agentNo: 2, |
| | | name: 'æç¾å¥³', |
| | | img: 'https://randomuser.me/api/portraits/women/33.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'è³ç¢è½ç§»'], |
| | | satisfaction: 5, |
| | | contactStatus: 'picked', |
| | |
| | | new: false, |
| | | agentNo: 3, |
| | | name: 'è¡ç¾ç', |
| | | img: 'https://randomuser.me/api/portraits/women/34.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'è³ç¢è½ç§»'], |
| | | satisfaction: 4.3, |
| | | contactStatus: 'picked', |
| | |
| | | new: true, |
| | | agentNo: 4, |
| | | name: 'å¼µå°ç¾', |
| | | img: 'https://randomuser.me/api/portraits/women/35.jpg', |
| | | img: '', |
| | | professionals: [], |
| | | satisfaction: 4.8, |
| | | contactStatus: 'picked', |
| | |
| | | new: true, |
| | | agentNo: 5, |
| | | name: 'è£å¸¥å¥', |
| | | img: 'https://randomuser.me/api/portraits/men/36.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'è³ç¢è½ç§»'], |
| | | satisfaction: 4.8, |
| | | contactStatus: 'reserved', |
| | |
| | | new: false, |
| | | agentNo: 6, |
| | | name: 'æç¾å¥³', |
| | | img: 'https://randomuser.me/api/portraits/women/37.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'è³ç¢ç§»è½', 'ç¯ç¨
', 'æ¨æ´»éä¼'], |
| | | satisfaction: 4.8, |
| | | contactStatus: 'picked', |
| | |
| | | new: false, |
| | | agentNo: 7, |
| | | name: 'è¡ç¾ç', |
| | | img: 'https://randomuser.me/api/portraits/women/38.jpg', |
| | | img: '', |
| | | professionals: ['財åè¦å', 'ç¯ç¨
', 'æ¨æ´»éä¼'], |
| | | satisfaction: 4.8, |
| | | contactStatus: 'picked', |
| | | updateTime: 'Tue Sep 02 2021 09:40:02 GMT+0800 (å°åæ¨æºæé)' |
| | | } |
| | | ] |
| | | return CommonService.prototype.withDebugData(debugData, 'https://randomuser.me/api/') |
| | | return CommonService.prototype.withDebugData(debugData, '') |
| | | }, |
| | | clientReservedList() { |
| | | const debugData = [{ |
| | | name: 'çè°æ', |
| | | clientId: '1', |
| | | phone: '091234567', |
| | | time: new Date('Tue Nov 02 2021 11:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'male', |
| | | age: '26-30', |
| | | job: 'general', |
| | | requirements: ['ä¿å®å¥æª¢/è¦å', 'é²ç«ä¿å®ç¸é'], |
| | | communicateStatus: 'reserved' |
| | | },{ |
| | | name: 'Ariel', |
| | | clientId: '2', |
| | | phone: '091234567', |
| | | time: new Date('Tue Oct 15 2020 11:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'female', |
| | | age: '30-40', |
| | | job: 'general', |
| | | requirements: ['ä¿å®å¥æª¢/è¦å', 'è³ç¢è½ç§»', 'é²ç«ä¿å®ç¸é'], |
| | | communicateStatus: 'contacted' |
| | | },{ |
| | | name: 'Donna', |
| | | clientId: '3', |
| | | phone: '091234567', |
| | | time: new Date('Tue Oct 31 2021 10:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'female', |
| | | age: '10-20', |
| | | job: 'general', |
| | | requirements: ['é²ç«ä¿å®ç¸é'], |
| | | communicateStatus: 'reserved' |
| | | },{ |
| | | name: 'é³ç¸ç¸', |
| | | clientId: '4', |
| | | phone: '091234567', |
| | | time: new Date('Tue Dec 31 2020 19:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'female', |
| | | age: '50-60', |
| | | job: 'general', |
| | | requirements: ['è³ç¢è½ç§»', 'ç¯ç¨
'], |
| | | communicateStatus: 'reserved' |
| | | },{ |
| | | name: 'æä¼¯ä¼¯', |
| | | clientId: '5', |
| | | phone: '091234567', |
| | | time: new Date('Tue Oct 15 2020 11:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'male', |
| | | age: '60-70', |
| | | job: 'general', |
| | | requirements: ['ç¯ç¨
', 'è³ç¢è½ç§»', 'é²ç«ä¿å®ç¸é'], |
| | | communicateStatus: 'contacted' |
| | | },{ |
| | | name: 'è¡åª½åª½', |
| | | clientId: '6', |
| | | phone: '091234567', |
| | | time: new Date('Tue Dec 31 2020 19:23:14 GMT+0800 (å°åæ¨æºæé)'), |
| | | gender: 'female', |
| | | age: '50-60', |
| | | job: 'general', |
| | | requirements: [], |
| | | communicateStatus: 'reserved' |
| | | }] |
| | | |
| | | return CommonService.prototype.withDebugData(debugData, '') |
| | | } |
| | | }) |
| | | |