From 0e27da107dd3329b4d0c11ce7d0173c3bd1358e9 Mon Sep 17 00:00:00 2001
From: Jack <jack.su@pollex.com.tw>
Date: 星期三, 19 一月 2022 19:06:52 +0800
Subject: [PATCH] Merge branch 'Phase3' of ssh://dev.pollex.com.tw:29418/pcalife/PAM into Phase3

---
 PAMapp/components/Interview/InterviewAdd.vue                    |   66 ++--
 PAMapp/store/login.store.ts                                     |   28 +
 PAMapp/pages/consultantLogin/index.vue                          |    9 
 PAMapp/store/index.ts                                           |   42 --
 PAMapp/components/Appointment/AppointmentRecordList.vue         |  103 ------
 PAMapp/components/Interview/InterviewRecordCard.vue             |   99 ++++++
 PAMapp/components/BackActionBar.vue                             |   26 +
 PAMapp/components/Interview/InterviewCard.vue                   |  145 +++++++++
 PAMapp/store/appointment.store.ts                               |    7 
 PAMapp/components/Appointment/AppointmentInterviewList.vue      |  141 --------
 PAMapp/components/Client/ClientCard.vue                         |    4 
 PAMapp/components/Interview/InterviewMsg.vue                    |  110 +++---
 PAMapp/pages/appointment/_appointmentId/recordList/index.vue    |   32 ++
 PAMapp/shared/models/agent-info.model.ts                        |   37 +-
 PAMapp/store/localStorage.ts                                    |    1 
 PAMapp/pages/appointment/_appointmentId/interviewList/index.vue |   38 ++
 PAMapp/pages/appointment/_appointmentId/index.vue               |    3 
 17 files changed, 512 insertions(+), 379 deletions(-)

diff --git a/PAMapp/components/Appointment/AppointmentInterviewList.vue b/PAMapp/components/Appointment/AppointmentInterviewList.vue
index e7a3325..dc06f5b 100644
--- a/PAMapp/components/Appointment/AppointmentInterviewList.vue
+++ b/PAMapp/components/Appointment/AppointmentInterviewList.vue
@@ -1,82 +1,20 @@
 <template>
     <div>
-      <div class="interview__header">
-          <div class="mdTxt">蝝赤蝝����</div>
-          <div class="pam-link-button--lg"
-          @click="addInterview">+�憓�</div>
-      </div>
-
-      <template v-if="!interviewList.length">
-          <div class="record-card record-card--empty">
-            �蝝赤蝝����
-          </div>
-      </template>
-
-      <template v-if="interviewList.length">
-        <div
-            v-for="(item, index) in futureList"
-            :key="index + 'feature'"
-            class="interview--future"
-            @click="editInterview(item)"
-        >
-
-            <div class="record-card">
-                <div class="record-card-date">
-                    <div>
-                        <UiDateFormat
-                            class="date bold"
-                            :date="item.interviewDate"
-                            onlyShowSection="DAY" />
-                    </div>
-                    <div>
-                        <UiDateFormat
-                            class="time mt-5 line-space"
-                            :date="item.interviewDate"
-                            onlyShowSection="TIME" />
-                    </div>
-                </div>
-                <div class="record-card-content">
-                    <span>{{item.content}}</span>
-                </div>
-            </div>
+        <div class="interview__header">
+            <div class="mdTxt">蝝赤蝝����</div>
+            <div class="pam-link-button--lg"
+            @click="addInterview">+�憓�</div>
         </div>
+        <InterviewCard :interviewList="displayList.slice(0, 3)"></InterviewCard>
 
-        <section
-            class="interview--past"
-            v-for="(item, index) in pastList"
-            :key="index + 'past'"
-            @click="editInterview(item)"
-        >
-            <div class="record-card">
-                <div class="record-card-date">
-                    <div>
-                        <UiDateFormat
-                            class="date bold"
-                            :date="item.interviewDate"
-                            onlyShowSection="DAY" />
-                    </div>
-                    <div>
-                        <UiDateFormat
-                            class="time mt-5 line-space"
-                            :date="item.interviewDate"
-                            onlyShowSection="TIME" />
-                    </div>
-                </div>
-                <div class="record-card-content">
-                    <span>{{item.content}}</span>
-                </div>
-            </div>
+        <section class="text--right mt-30" v-if="interviewList.length > 3">
+                <div class="pam-link-button--lg" @click="readMoreBtn">撅��憭�</div>
         </section>
-
-        <section class="more-log-action">
-                <div class="pam-link-button--lg">撅��憭�</div>
-        </section>
-      </template>
     </div>
 </template>
 
 <script lang="ts">
-import { Vue, Component, Prop, Watch, Mutation } from 'nuxt-property-decorator';
+import { Vue, Component, Prop, Watch } from 'nuxt-property-decorator';
 import { InterviewRecord } from '~/shared/models/appointment.model';
 
 @Component
@@ -84,13 +22,8 @@
   @Prop()
   interviewList!: InterviewRecord[];
 
-  @Mutation
-  updateInterviewRecord!: (data: InterviewRecord) => void;
-
   appointmentId!: string;
-
-  futureList: InterviewRecord[] = [];
-  pastList: InterviewRecord[] = [];
+  displayList: InterviewRecord[] = [];
 
   //////////////////////////////////////////////////////////////////////
 
@@ -103,10 +36,9 @@
   @Watch('interviewList', {immediate: true})
   updateInterviewList() {
       if (this.interviewList && this.interviewList.length > 0) {
-          this.futureList = this.interviewList
-            .filter(item => new Date(item.interviewDate).getTime() >= new Date().getTime())
-          this.pastList = this.interviewList
-            .filter(item =>  new Date(item.interviewDate).getTime() < new Date().getTime());
+          this.displayList = this.interviewList
+            .map((i) => ({ ...i, sortDate: new Date(i.interviewDate)}))
+            .sort((preItem, nextItem) => +nextItem.sortDate - +preItem.sortDate);
       }
   }
 
@@ -116,9 +48,8 @@
     this.$router.push(`/appointment/${this.appointmentId}/interview/new`);
   }
 
-  editInterview(interviewRecord) {
-    this.updateInterviewRecord(interviewRecord);
-    this.$router.push(`/appointment/${this.appointmentId}/interview/${interviewRecord.id}`);
+  readMoreBtn() {
+      this.$router.push(`/appointment/${this.appointmentId}/interviewList`);
   }
 
 }
@@ -129,49 +60,5 @@
   display        : flex;
   justify-content: space-between;
   margin-bottom  : 10px;
-}
-.interview--future{
-    border-bottom: 1px solid #CCCCCC;
-    padding-bottom: 17px;
-    margin-bottom: 17px;
-    .record{
-        display: flex;
-        justify-content: space-between;
-        margin-bottom: 10px;
-    }
-}
-.record-card {
-    height: 62px;
-    border: 1px solid #707070;
-    border-radius: 5px;
-    display: flex;
-    border-bottom: 1px solid #000;
-    .record-card-date{
-        display: flex;
-        flex-direction: column;
-        margin-left: 10px;
-        margin-right: 10px;
-        margin-top: 10px;
-    }
-    .record-card-content{
-        height: 42px;
-        margin-top: 10px;
-        margin-right: 10px;
-        line-height: 1.2;
-    }
-  &.record-card--empty {
-    align-items     : center;
-    background-color: #fff;
-    color           : $MID_GREY;
-    justify-content : center;
-  }
-}
-.line-space{
-    letter-spacing: 1px;
-}
-.more-log-action{
-    margin-top: 30px;
-    display: flex;
-    justify-content:flex-end;
 }
 </style>
diff --git a/PAMapp/components/Appointment/AppointmentRecordList.vue b/PAMapp/components/Appointment/AppointmentRecordList.vue
index 15e880d..39b2835 100644
--- a/PAMapp/components/Appointment/AppointmentRecordList.vue
+++ b/PAMapp/components/Appointment/AppointmentRecordList.vue
@@ -2,42 +2,11 @@
     <div class="record-log-component">
         <div class="mdTxt mt-30 mb-10">蝟餌絞�蝝����</div>
 
-            <div v-for="(item, index) in displayLogs"
-                :key="index">
-                <section
-                    class="record-log-card"
-                >
-                    <div class="record-log-card-date-container">
-                        <div class="record-log-card-date-container-circle">
-                            <div class="xxsTxt bold line-height">{{item.createdDate | formatYear}}</div>
-                            <div>
-                                <UiDateFormat
-                                    class="xxsTxt bold line-height"
-                                    :date="item.createdDate"
-                                    onlyShowSection="DAY" />
-                            </div>
-                            <div>
-                                <UiDateFormat
-                                    class="xxsTxt mt-4 line-space"
-                                    :date="item.createdDate"
-                                    onlyShowSection="TIME" />
-                            </div>
-                        </div>
-                    </div>
-                        <div class="record-log-msg">
-                            <div>���赤�
-                                <span v-if="item.email && item.phone">(���陛閮�mail)</span>
-                                <span v-else-if="item.email">(Email)</span>
-                                <span v-else>(���陛閮�)</span>
-                            </div>
-                            <div class="mt-10">���{item.interviewDate | formatDate}}</div>
-                        </div>
-                </section>
-                <div class="time-line"></div>
-            </div>
+            <InterviewRecordCard :noticeLogsList="displayLogs.slice(0, 3)"></InterviewRecordCard>
 
-            <section class="more-log-action">
+            <section class="text--right mt-30" v-if="displayLogs.length > 3">
                 <div class="pam-link-button--lg"
+                @click="readMoreBtn"
                 >撅��憭�</div>
             </section>
     </div>
@@ -47,15 +16,7 @@
 import { Vue, Component, Prop, Watch } from 'nuxt-property-decorator';
 import { NoticeLogs } from '~/shared/models/appointment.model';
 
-@Component({
-    filters: {
-        formatYear(value) {
-            if (value) {
-                return new Date(value).getFullYear();
-            }
-        }
-    }
-})
+@Component
 export default class AppointmentRecordList extends Vue {
 
     @Prop()
@@ -63,6 +24,8 @@
 
     appointmentId: string       = '';
     displayLogs  : NoticeLogs[] = [];
+
+    //////////////////////////////////////////////////////////////////////
 
     mounted() {
         this.appointmentId = this.$route.params.appointmentId;
@@ -79,53 +42,11 @@
       }
     }
 
+    //////////////////////////////////////////////////////////////////////
+
+    readMoreBtn() {
+        this.$router.push(`/appointment/${this.appointmentId}/recordList`);
+    }
+
 }
 </script>
-
-<style lang="scss" scoped>
-.record-log-component{
-    display: flex;
-    flex-direction: column;
-    .record-log-card{
-        display: flex;
-        .record-log-card-date-container{
-            position:relative;
-            .record-log-card-date-container-circle{
-                display: flex;
-                flex-direction: column;
-                width: 56px;
-                height: 56px;
-                border-radius: 50%;
-                border:1px solid $PRIMARY_BLACK;
-                justify-content: center;
-                align-items: center;
-                align-content: center;
-            }
-        }
-    }
-}
-.mt-4{
-    margin-top: 4px;
-}
-.line-space{
-    letter-spacing: 1px;
-}
-.line-height{
-    line-height:1.2;
-}
-.time-line{
-    border-left: 1px solid black;
-    height: 30px;
-    margin-left: 28px;
-
-}
-.record-log-msg{
-    margin-left: 13px;
-    margin-top: 10px;
-}
-.more-log-action{
-    display: flex;
-    justify-content:flex-end;
-}
-
-</style>
diff --git a/PAMapp/components/BackActionBar.vue b/PAMapp/components/BackActionBar.vue
index 0f628c3..f7981a0 100644
--- a/PAMapp/components/BackActionBar.vue
+++ b/PAMapp/components/BackActionBar.vue
@@ -14,7 +14,8 @@
 import * as _ from 'lodash';
 import { Role } from '~/shared/models/enum/Role';
 
-const roleStorage = namespace('localStorage');
+const appointmentStore = namespace('appointment.store');
+const roleStorage      = namespace('localStorage');
 
 @Component
 export default class UiCarousel extends Vue {
@@ -22,11 +23,16 @@
   @roleStorage.Getter
   currentRole!:string;
 
+  @appointmentStore.Getter
+  isCloseAppointment!: boolean;
+
   //////////////////////////////////////////////////////////////////////
 
   goBack(): void {
     const pathName = this.$route.name;
-    pathName?.includes('myConsultantList') ? this.$router.push('/') : this.$router.go(-1);
+    pathName?.includes('myConsultantList')
+      ? this.$router.push('/')
+      : this.$router.go(-1);
   }
 
   get label(): string {
@@ -78,11 +84,21 @@
           featureLabel = 'F&Q 撣貉����';
           break;
         case 'appointment':
-          const appointmentFeatureLabel = this.$route.name.includes('close') ? '蝯��' : '������';
+          const appointmentFeatureLabel = this.$route.name.includes('close')
+                                                            ? '蝯��'
+                                                            : this.isCloseAppointment ? '蝯��敦' : '������';
           const inInterview = this.$route.name.includes('interview');
           const addNewInterview = this.$route.name.includes('new');
-          if (inInterview) {
-            featureLabel = addNewInterview ? '�憓�赤蝝����' : '蝺刻摩蝝赤蝝����';
+          const interviewList = this.$route.name.includes('interviewList');
+          const recordList = this.$route.name.includes('recordList');
+          if (interviewList) {
+            featureLabel = '蝝赤蝝����';
+          } else if (recordList) {
+            featureLabel = '蝟餌絞�蝝����';
+          } else if (inInterview) {
+            featureLabel = addNewInterview
+                  ? '�憓�赤蝝����'
+                  : '蝺刻摩蝝赤蝝����';
           } else {
             featureLabel = appointmentFeatureLabel;
           }
diff --git a/PAMapp/components/Client/ClientCard.vue b/PAMapp/components/Client/ClientCard.vue
index 6afbe92..f203dd0 100644
--- a/PAMapp/components/Client/ClientCard.vue
+++ b/PAMapp/components/Client/ClientCard.vue
@@ -210,7 +210,7 @@
     updateMyAppointmentList!: (data: Appointment) => void;
 
     @appointmentStore.Action
-    setAppointmentDetail!: (appointmentId: number) => Promise<Appointment>;
+    getAppointmentDetail!: (appointmentId: number) => Promise<Appointment>;
 
     @appointmentStore.Getter
     appointmentProgress!: ContactStatus;
@@ -256,7 +256,7 @@
     //////////////////////////////////////////////////////////////////////
 
     viewAppointmentDetail(): void {
-      this.setAppointmentDetail(this.client.id).then((_) => {
+      this.getAppointmentDetail(this.client.id).then((_) => {
         this.$router.push(`/appointment/${this.client.id}`);
       });
     }
diff --git a/PAMapp/components/Interview/InterviewAdd.vue b/PAMapp/components/Interview/InterviewAdd.vue
index 3f867d8..7a47229 100644
--- a/PAMapp/components/Interview/InterviewAdd.vue
+++ b/PAMapp/components/Interview/InterviewAdd.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="edit-appointment-record">
-      <div class="edit-appointment-record-date" v-if="interviewId">
+      <div class="edit-appointment-record-date" v-if="interviewId && interviewRecord">
           <span>{{interviewRecord.createdDate | formatDate}} 撱箇��</span>
           <span>{{interviewRecord.lastModifiedDate | formatDate}} ��</span>
       </div>
@@ -85,25 +85,26 @@
 
       <InterviewMsg
         :isVisible.sync="showInterviewMsgPopup"
+        :client="appointmentDetail"
         @closeDialog="closePopup"
       ></InterviewMsg>
   </div>
 </template>
 <script lang="ts">
-import { InterviewRecord, InterviewRecordInfo } from '~/shared/models/appointment.model';
-import { Vue, Component, Prop, State, Mutation, Watch, Action } from 'nuxt-property-decorator';
+import { Appointment, InterviewRecord, InterviewRecordInfo } from '~/shared/models/appointment.model';
+import { Vue, Component, Watch, namespace } from 'nuxt-property-decorator';
 import appointmentService from '~/shared/services/appointment.service';
+
+const appointmentStore = namespace('appointment.store');
 
 @Component
 export default class InterviewAdd extends Vue {
-    @State
-    interviewRecord!: InterviewRecord;
 
-    @Mutation
-    updateInterviewRecord!: (data: InterviewRecord) => void;
+    @appointmentStore.State
+    appointmentDetail!: Appointment;
 
-    @Mutation
-    clearInterviewRecord!: () => void;
+    @appointmentStore.Action
+    updateAppointmentDetail!: (id: number) => Appointment;
 
     interviewTime = '';
     content = '';
@@ -121,38 +122,29 @@
 
     defaultValue = '';
 
+    interviewRecord!: InterviewRecord;
+
     ////////////////////////////////////////////////////////////////////
 
     mounted() {
         this.interviewId = this.$route.params.interviewId;
         this.appointmentId = this.$route.params.appointmentId;
-        const isEditPage = this.interviewId && this.interviewRecord;
-        if (isEditPage) {
-            this.checkInterviewRecord();
-        }
-    }
 
-    private checkInterviewRecord() {
-        if (this.interviewRecord.appointmentId !== +this.appointmentId
-                || this.interviewRecord.id !== +this.interviewId) {
-            appointmentService.getAppointmentDetail(+this.appointmentId).then((data) => {
-                const currentInterviewRecord = data.interviewRecordDTOs.filter(item => item.id === +this.interviewId)[0];
-                this.updateInterviewRecord(currentInterviewRecord);
-            })
-        }
-    }
-
-    destroyed() {
-        this.clearInterviewRecord();
+        this.onAppointmentDetailChange();
     }
 
     ////////////////////////////////////////////////////////////////////
 
-    @Watch('interviewRecord', {immediate: true})
-    watchInterviewRecord() {
-        if (this.interviewRecord && this.interviewRecord.content) {
-            this.content = this.interviewRecord.content;
-            this.defaultValue = this.interviewRecord.interviewDate;
+    @Watch('appointmentDetail', {immediate: true})
+    onAppointmentDetailChange() {
+        if (this.appointmentDetail && this.appointmentDetail.id === +this.appointmentId) {
+            this.interviewRecord = this.appointmentDetail.interviewRecordDTOs
+                .filter(item => item.id === +this.interviewId)[0];
+
+                if (this.interviewRecord && this.interviewId) {
+                    this.content = this.interviewRecord.content;
+                    this.defaultValue = this.interviewRecord.interviewDate;
+                }
         }
     }
 
@@ -173,6 +165,7 @@
             }
             this.updateRecord(updateInterviewRecord);
         }
+        this.updateAppointmentDetail(+this.appointmentId);
     }
 
     private createdRecord(interviewRecordInfo) {
@@ -197,14 +190,11 @@
         }
     }
 
-    closePopup() {
-        this.$router.push(`/appointment/${this.appointmentId}`);
-    }
-
     deleteInterviewRecord() {
         appointmentService.deleteInterviewRecord(this.interviewId).then(res => {
             this.confirmTxt = '������';
             this.showConfirmPopup = true;
+            this.updateAppointmentDetail(+this.appointmentId);
         });
     }
 
@@ -214,10 +204,14 @@
            this.defaultValue = this.interviewRecord.interviewDate;
            this.isEdit = false;
         } else {
-           this.$router.push(`/appointment/${this.appointmentId}`);
+           this.$router.go(-1);
         }
     }
 
+    closePopup() {
+        this.$router.go(-1);
+    }
+
     ////////////////////////////////////////////////////////////////////
 
     get formatInterviewDate() {
diff --git a/PAMapp/components/Interview/InterviewCard.vue b/PAMapp/components/Interview/InterviewCard.vue
new file mode 100644
index 0000000..e3f4f54
--- /dev/null
+++ b/PAMapp/components/Interview/InterviewCard.vue
@@ -0,0 +1,145 @@
+<template>
+    <div>
+       <template v-if="!interviewList.length">
+          <div class="record-card record-card--empty">
+            �蝝赤蝝����
+          </div>
+      </template>
+
+      <template v-else>
+        <div class="interview--future">
+            <div class="record-card mb-10"
+                v-for="(item, index) in futureList"
+                :key="index + 'feature'"
+                @click="editInterview(item)"
+            >
+                <div class="record-card-date">
+                    <div>
+                        <UiDateFormat
+                            class="date bold"
+                            :date="item.interviewDate"
+                            onlyShowSection="DAY" />
+                    </div>
+                    <div>
+                        <UiDateFormat
+                            class="time mt-5 line-space"
+                            :date="item.interviewDate"
+                            onlyShowSection="TIME" />
+                    </div>
+                </div>
+                <div class="record-card-content">
+                    <span>{{item.content}}</span>
+                </div>
+            </div>
+        </div>
+
+        <section class="interview--past" v-if="pastList.length">
+            <div class="record-card mb-10"
+                v-for="(item, index) in pastList"
+                :key="index + 'past'"
+                @click="editInterview(item)"
+            >
+                <div class="record-card-date">
+                    <div>
+                        <UiDateFormat
+                            class="date bold"
+                            :date="item.interviewDate"
+                            onlyShowSection="DAY" />
+                    </div>
+                    <div>
+                        <UiDateFormat
+                            class="time mt-5 line-space"
+                            :date="item.interviewDate"
+                            onlyShowSection="TIME" />
+                    </div>
+                </div>
+                <div class="record-card-content">
+                    <span>{{item.content}}</span>
+                </div>
+            </div>
+        </section>
+      </template>
+    </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue, Watch } from "nuxt-property-decorator";
+import { InterviewRecord } from "~/shared/models/appointment.model";
+
+@Component
+export default class InterviewCard extends Vue {
+
+    @Prop()
+    interviewList!: InterviewRecord[];
+
+    futureList: InterviewRecord[] = [];
+    pastList: InterviewRecord[] = [];
+
+    appointmentId!: number;
+
+    mounted() {
+        this.appointmentId = +this.$route.params.appointmentId;
+    }
+
+    @Watch('interviewList', {immediate: true})
+    onInterviewListChange() {
+        if (this.interviewList.length > 0) {
+            this.futureList = this.interviewList
+            .filter(item => new Date(item.interviewDate).getTime() >= new Date().getTime())
+            .sort((preItem, nextItem) => +new Date(nextItem.interviewDate) - +new Date(preItem.interviewDate));
+          this.pastList = this.interviewList
+            .filter(item =>  new Date(item.interviewDate).getTime() < new Date().getTime())
+            .sort((preItem, nextItem) => +new Date(nextItem.interviewDate) - +new Date(preItem.interviewDate));
+        }
+
+    }
+
+    editInterview(interviewRecord) {
+        this.$router.push(`/appointment/${this.appointmentId}/interview/${interviewRecord.id}`);
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.interview--future{
+    .record{
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 10px;
+    }
+}
+.interview--past {
+    border-top: 1px solid #CCCCCC;
+    padding-top: 17px;
+    margin-top: 17px;
+}
+.record-card {
+    height: 62px;
+    border: 1px solid #707070;
+    border-radius: 5px;
+    display: flex;
+    border-bottom: 1px solid #000;
+    .record-card-date{
+        display: flex;
+        flex-direction: column;
+        margin-left: 10px;
+        margin-right: 10px;
+        margin-top: 10px;
+    }
+    .record-card-content{
+        height: 42px;
+        margin-top: 10px;
+        margin-right: 10px;
+        line-height: 1.2;
+    }
+  &.record-card--empty {
+    align-items     : center;
+    background-color: #fff;
+    color           : $MID_GREY;
+    justify-content : center;
+  }
+}
+.line-space{
+    letter-spacing: 1px;
+}
+</style>
diff --git a/PAMapp/components/Interview/InterviewMsg.vue b/PAMapp/components/Interview/InterviewMsg.vue
index 7d671ce..eaffa87 100644
--- a/PAMapp/components/Interview/InterviewMsg.vue
+++ b/PAMapp/components/Interview/InterviewMsg.vue
@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="interview-msg-component">
     <el-dialog
       :visible.sync="dialogVisible"
       :width="dialogWidth"
@@ -14,10 +14,10 @@
 
       <el-input
         type="textarea"
-        :rows="9"
+        :autosize="true"
         placeholder="蝝赤�"
         resize="none"
-        v-model="interviewTxt">
+        v-model="isInterviewTxt">
         </el-input>
 
       <div class="mdTxt mt-30 mb-10">����赤��挾</div>
@@ -41,29 +41,23 @@
   </div>
 </template>
 <script lang="ts">
-import { Vue, Component, Prop, PropSync, Emit, namespace } from 'nuxt-property-decorator';
+import { Vue, Component, Prop, PropSync, Emit, Action, namespace } from 'nuxt-property-decorator';
 
 import appointmentService from '~/shared/services/appointment.service';
 import { Appointment, ToInformAppointment } from '~/shared/models/appointment.model';
-import { ContactStatus } from '~/shared/models/enum/contact-status';
+import { AgentInfo } from '~/shared/models/agent-info.model';
 
+const loginStore = namespace('login.store');
 const appointmentStore = namespace('appointment.store');
 
 @Component
 export default class InterviewMsg extends Vue {
 
-    @appointmentStore.Action
-    getMyAppointmentList!: () => Promise<Appointment[]>;
-
+    @Action
+    storeMyAppointmentList!: () => Promise<number>;
 
     @appointmentStore.Action
-    updateMyAppointmentList!:(appointment: Appointment) => Appointment[];
-
-    @appointmentStore.Action
-    updateAppointmentDetail!: (appointmentId: number) => Promise<Appointment>;
-
-    @appointmentStore.State
-    appointmentDetail!: Appointment;
+    updateAppointmentDetail!: (id: number) => Appointment;
 
     @PropSync('isVisible')
     dialogVisible!: boolean;
@@ -79,12 +73,13 @@
         return;
     }
 
-    interviewTime      = '';
-    interviewTxt       = '';
+    @loginStore.State
+    loginConsultant!: AgentInfo;
+
     isShowSuccessAlert = false;
 
-    contactStatus = ContactStatus;
-
+    interviewTxt = "";
+    interviewTime = '';
     //////////////////////////////////////////////////////////////////////
 
     addInterview() {
@@ -95,57 +90,58 @@
         message      : this.interviewTxt,
         phone        : this.client?.phone,
       };
-
       appointmentService.informAppointment(appointmentInformation).then((_) => {
         this.isShowSuccessAlert = true ;
-        const updatedAppointment = {
-          ...this.appointmentDetail,
-          communicateStatus: this.contactStatus.CONTACTED,
-        };
-        this.updateMyAppointmentList(updatedAppointment);
-        this.updateAppointmentDetail(updatedAppointment.id);
+        this.updateAppointmentDetail(this.client.id);
       });
     }
 
     closeAllDialog() {
       this.isShowSuccessAlert = false ;
       this.dialogVisible = false;
-      this.getMyAppointmentList();
+      this.storeMyAppointmentList();
+    }
+
+    get isInterviewTxt() : string{
+      return this.interviewTxt = "�憟踝��靽���像����憿批��" + this.loginConsultant?.name + "嚗�����������銝膩������蝜�"+"\n"+"隞乩����閰梯�Ⅳ/Email嚗�"+"\n" + this.loginConsultant?.phoneNumber + "\n" + this.loginConsultant?.email + "\n"+"�甇斗���靘選����蝜恬�����"
     }
 
 }
 </script>
 
-<style lang="scss" scoped>
-.msg-dialog-title{
-  display: flex;
-  justify-content: center;
-  margin-bottom:30px;
-  color: $PRIMARY_BLACK;
-}
-.send-msg-nav{
-  display: flex;
-  justify-content: space-between;
-  margin-bottom: 10px;
-  color: $PRIMARY_BLACK;
-}
-.el-dialog{
-  width:90%
-}
-.el-textarea__inner{
-  font-size: 20px;
-  padding:10px;
-  text-align: justify;
-  font-weight: 500;
-}
-.msg-dialog-btn{
-  margin-top: 30px;
-  display: flex;
-  justify-content: center;
-}
-.invite-review{
+<style lang="scss" >
+.interview-msg-component{
+
+  .msg-dialog-title{
     display: flex;
-    flex-direction: column;
-    align-items: center;
+    justify-content: center;
+    margin-bottom:30px;
+    color: $PRIMARY_BLACK;
   }
+  .send-msg-nav{
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 10px;
+    color: $PRIMARY_BLACK;
+  }
+  .el-dialog{
+    width:90%
+  }
+  .el-textarea__inner{
+    font-size: 20px;
+    padding:10px;
+    text-align: justify;
+    font-weight: 600;
+  }
+  .msg-dialog-btn{
+    margin-top: 30px;
+    display: flex;
+    justify-content: center;
+  }
+  .invite-review{
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+}
 </style>
diff --git a/PAMapp/components/Interview/InterviewRecordCard.vue b/PAMapp/components/Interview/InterviewRecordCard.vue
new file mode 100644
index 0000000..34f1d28
--- /dev/null
+++ b/PAMapp/components/Interview/InterviewRecordCard.vue
@@ -0,0 +1,99 @@
+<template>
+    <div class="record-log-component">
+        <div v-for="(item, index) in noticeLogsList"
+                :key="index">
+                <section
+                    class="record-log-card"
+                >
+                    <div class="record-log-card-date-container">
+                        <div class="record-log-card-date-container-circle">
+                            <div class="xxsTxt bold line-height">{{item.createdDate | formatYear}}</div>
+                            <div>
+                                <UiDateFormat
+                                    class="xxsTxt bold line-height"
+                                    :date="item.createdDate"
+                                    onlyShowSection="DAY" />
+                            </div>
+                            <div>
+                                <UiDateFormat
+                                    class="xxsTxt mt-4 line-space"
+                                    :date="item.createdDate"
+                                    onlyShowSection="TIME" />
+                            </div>
+                        </div>
+                    </div>
+                        <div class="record-log-msg">
+                            <div>���赤�
+                                <span v-if="item.email && item.phone">(���陛閮�mail)</span>
+                                <span v-else-if="item.email">(Email)</span>
+                                <span v-else>(���陛閮�)</span>
+                            </div>
+                            <div class="mt-10">���{item.interviewDate | formatDate}}</div>
+                        </div>
+                </section>
+                <div class="time-line"></div>
+            </div>
+    </div>
+</template>
+
+<script lang="ts">
+import { Component, Prop, Vue } from "nuxt-property-decorator";
+import { NoticeLogs } from "~/shared/models/appointment.model";
+
+@Component({
+    filters: {
+        formatYear(value) {
+            if (value) {
+                return new Date(value).getFullYear();
+            }
+        }
+    }
+})
+export default class RecordCard extends Vue {
+    @Prop()
+    noticeLogsList!: NoticeLogs[];
+}
+</script>
+
+<style lang="scss" scoped>
+.record-log-component{
+    display: flex;
+    flex-direction: column;
+    .record-log-card{
+        display: flex;
+        .record-log-card-date-container{
+            position:relative;
+            .record-log-card-date-container-circle{
+                display: flex;
+                flex-direction: column;
+                width: 56px;
+                height: 56px;
+                border-radius: 50%;
+                border:1px solid $PRIMARY_BLACK;
+                justify-content: center;
+                align-items: center;
+                align-content: center;
+            }
+        }
+    }
+}
+.mt-4{
+    margin-top: 4px;
+}
+.line-space{
+    letter-spacing: 1px;
+}
+.line-height{
+    line-height:1.2;
+}
+.time-line{
+    border-left: 1px solid black;
+    height: 30px;
+    margin-left: 28px;
+
+}
+.record-log-msg{
+    margin-left: 13px;
+    margin-top: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/PAMapp/pages/appointment/_appointmentId/index.vue b/PAMapp/pages/appointment/_appointmentId/index.vue
index 2994205..b4a7da0 100644
--- a/PAMapp/pages/appointment/_appointmentId/index.vue
+++ b/PAMapp/pages/appointment/_appointmentId/index.vue
@@ -91,12 +91,9 @@
 </template>
 
 <script lang="ts">
-import { Context } from '@nuxt/types';
-
 import { Vue, Component } from 'vue-property-decorator';
 import { namespace } from 'nuxt-property-decorator';
 
-import appointmentService from '~/shared/services/appointment.service';
 import { Appointment } from '~/shared/models/appointment.model';
 import { ContactStatus } from '~/shared/models/enum/contact-status';
 
diff --git a/PAMapp/pages/appointment/_appointmentId/interviewList/index.vue b/PAMapp/pages/appointment/_appointmentId/interviewList/index.vue
new file mode 100644
index 0000000..197d949
--- /dev/null
+++ b/PAMapp/pages/appointment/_appointmentId/interviewList/index.vue
@@ -0,0 +1,38 @@
+
+<template>
+    <div>
+        <div class="text--right mb-30">
+            <div class="pam-link-button--lg"
+            @click="addInterview">+�憓�</div>
+        </div>
+        <InterviewCard :interviewList="appointmentDetail.interviewRecordDTOs"></InterviewCard>
+    </div>
+</template>
+
+<script lang="ts">
+import { Component, namespace, Vue } from "nuxt-property-decorator";
+import { Appointment } from "~/shared/models/appointment.model";
+
+const appointmentStore = namespace('appointment.store');
+
+@Component
+export default class InterviewList extends Vue {
+    @appointmentStore.State
+    appointmentDetail!: Appointment;
+
+    appointmentId!: number;
+
+    ////////////////////////////////////////////////////////
+
+    mounted() {
+      this.appointmentId = +this.$route.params.appointmentId;
+    }
+
+    ////////////////////////////////////////////////////////
+
+    addInterview(): void {
+        this.$router.push(`/appointment/${this.appointmentId}/interview/new`);
+    }
+
+}
+</script>
\ No newline at end of file
diff --git a/PAMapp/pages/appointment/_appointmentId/recordList/index.vue b/PAMapp/pages/appointment/_appointmentId/recordList/index.vue
new file mode 100644
index 0000000..89d7bf7
--- /dev/null
+++ b/PAMapp/pages/appointment/_appointmentId/recordList/index.vue
@@ -0,0 +1,32 @@
+
+
+<template>
+    <InterviewRecordCard :noticeLogsList="displayLogs"></InterviewRecordCard>
+</template>
+
+<script lang="ts">
+import { Component, namespace, Vue, Watch } from "nuxt-property-decorator";
+import { Appointment, NoticeLogs } from "~/shared/models/appointment.model";
+
+const appointmentStore = namespace('appointment.store');
+
+@Component
+export default class RecordList extends Vue {
+    @appointmentStore.State
+    appointmentDetail!: Appointment;
+
+    displayLogs: NoticeLogs[] = [];
+
+    ////////////////////////////////////////////////////////
+
+    @Watch('appointmentDetail', {immediate: true})
+    onAppointmentDetailChange() {
+      if (this.appointmentDetail?.appointmentNoticeLogs.length) {
+        this.displayLogs = this.appointmentDetail?.appointmentNoticeLogs
+                            .map((i) => ({ ...i, sortDate: new Date(i.createdDate)}))
+                            .sort((preItem, nextItem) => +nextItem.sortDate - +preItem.sortDate);
+      }
+    }
+
+}
+</script>
\ No newline at end of file
diff --git a/PAMapp/pages/consultantLogin/index.vue b/PAMapp/pages/consultantLogin/index.vue
index 2358123..dcebb79 100644
--- a/PAMapp/pages/consultantLogin/index.vue
+++ b/PAMapp/pages/consultantLogin/index.vue
@@ -61,8 +61,11 @@
   import { Role } from '~/shared/models/enum/Role';
   import messageBoxService from '~/shared/services/message-box.service';
   import loginService from '~/shared/services/login.service'
+import { AgentInfo } from '~/shared/models/agent-info.model';
 
+  const loginStore  = namespace('login.store');
   const roleStorage = namespace('localStorage');
+
   @Component({
     layout: 'home'
   })
@@ -75,6 +78,9 @@
 
     @roleStorage.Mutation
     storageConsultantId!:(id:string) => void;
+
+    @loginStore.Action
+    getLoginConsultantDetail!: (agentNo: string) => Promise<AgentInfo>;
 
     consultantDto = {
       password: '',
@@ -130,7 +136,7 @@
     private verify():void{
       loginService.getVerificationStatus(this.verificationCode).then( verifySuccess => {
         if(verifySuccess.data){
-          this.loginWithConsultant()
+          this.loginWithConsultant();
         }else{
           this.clearValue();
           this.regenerateImgOfVerification();
@@ -141,6 +147,7 @@
 
     private loginWithConsultant(): void {
       loginService.logInToConsultant(this.consultantDto).then(res => {
+        this.getLoginConsultantDetail(this.consultantDto.username);
         this.storageIdToken(res.data.id_token);
         this.storageRole(Role.ADMIN);
         this.storageConsultantId(this.consultantDto.username)
diff --git a/PAMapp/shared/models/agent-info.model.ts b/PAMapp/shared/models/agent-info.model.ts
index b91054d..e6af754 100644
--- a/PAMapp/shared/models/agent-info.model.ts
+++ b/PAMapp/shared/models/agent-info.model.ts
@@ -1,21 +1,22 @@
 export interface AgentInfo {
-  name            : string;
-  agentNo         : string;
-  role            : string;
-  img             : string;
-  avgScore        : number;
-  title           : string;
-  phoneNumber     : string;
-  serveArea       : string;
-  companyAddress  : string;
-  latestLoginTime : Date  ;
-  seniority       : string;
-  suitability     : number;
-  evaluation      : number;
-  expertise       : string[];
-  concept         : string;
-  experiences     : string;
-  awards          : string;
-  gender            : string,
+  agentNo           : string;
+  avgScore          : number;
+  awards            : string;
   communicationStyle: string;
+  companyAddress    : string;
+  concept           : string;
+  email?            : string;
+  evaluation        : number;
+  experiences       : string;
+  expertise         : string[];
+  gender            : string,
+  img               : string;
+  latestLoginTime   : Date  ;
+  name              : string;
+  phoneNumber       : string;
+  role              : string;
+  seniority         : string;
+  serveArea         : string;
+  suitability       : number;
+  title             : string;
 }
diff --git a/PAMapp/store/appointment.store.ts b/PAMapp/store/appointment.store.ts
index 8c7b3e5..e8c8eff 100644
--- a/PAMapp/store/appointment.store.ts
+++ b/PAMapp/store/appointment.store.ts
@@ -35,6 +35,11 @@
     .filter(item => item.communicateStatus === this.contactStatus.DONE || item.communicateStatus === this.contactStatus.CLOSE ).length;
   }
 
+  get isCloseAppointment(): boolean {
+    const closedStatusList = [this.contactStatus.DONE, this.contactStatus.CLOSE, this.contactStatus.CANCEL];
+    return closedStatusList.includes(this.appointmentDetail!.communicateStatus);
+  }
+
   //////////////////////////////////////////////////////////////////////
 
   @Mutation
@@ -63,7 +68,7 @@
   }
 
   @Action({ commit: 'SET_APPOINTMENT'})
-  async setAppointmentDetail(appointmentId: number): Promise<Appointment> {
+  async getAppointmentDetail(appointmentId: number): Promise<Appointment> {
     if (this.appointmentDetail && this.appointmentDetail.id === appointmentId) {
       return this.appointmentDetail;
     } else {
diff --git a/PAMapp/store/index.ts b/PAMapp/store/index.ts
index 5ccdda4..f322519 100644
--- a/PAMapp/store/index.ts
+++ b/PAMapp/store/index.ts
@@ -1,18 +1,13 @@
-import { StrictQueryParams } from '~/shared/models/strict-query.model';
 import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
-
-import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant';
 
 import myConsultantService from '~/shared/services/my-consultant.service';
 import queryConsultantService from '~/shared/services/query-consultant.service';
-import appointmentService from '~/shared/services/appointment.service';
 import reviewsService from '~/shared/services/reviews.service';
-
 import { Consultant } from '~/shared/models/consultant.model';
-import { Appointment, AppointmentLog, InterviewRecord } from '~/shared/models/appointment.model';
-import { AgentOfStrictQuery } from '~/shared/models/strict-query.model';
-import { AgentInfo } from '~/shared/models/agent-info.model';
-import { agentCommunicationStyleList } from '~/shared/const/agent-communication-style-list';
+import { getFavoriteFromStorage, setFavoriteToStorage } from '~/shared/storageConsultant';
+import { AppointmentLog } from '~/shared/models/appointment.model';
+import { AgentOfStrictQuery, StrictQueryParams } from '~/shared/models/strict-query.model';
+
 @Module
 export default class Store extends VuexModule {
     recommendList: Consultant[] = [];
@@ -20,16 +15,6 @@
     myConsultantList: Consultant[] = [];
 
     myAppointmentReviewLogList: AppointmentLog[] = [];
-    interviewRecord: InterviewRecord = {
-        appointmentId   : 0,
-        content         : '',
-        createdBy       : '',
-        createdDate     : '',
-        id              : 0,
-        interviewDate   : '',
-        lastModifiedBy  : '',
-        lastModifiedDate: ''
-    }
 
     get isUserLogin() {
         return this.context.getters['localStorage/isUserLogin'];
@@ -53,25 +38,6 @@
     @Mutation
     updateMyAppointmentReviewLog(data: AppointmentLog[]) {
         this.myAppointmentReviewLogList = data;
-    }
-
-    @Mutation
-    updateInterviewRecord(data: InterviewRecord) {
-        this.interviewRecord = data;
-    }
-
-    @Mutation
-    clearInterviewRecord() {
-        this.interviewRecord = {
-            appointmentId   : 0,
-            content         : '',
-            createdBy       : '',
-            createdDate     : '',
-            id              : 0,
-            interviewDate   : '',
-            lastModifiedBy  : '',
-            lastModifiedDate: ''
-        }
     }
 
     @Action
diff --git a/PAMapp/store/localStorage.ts b/PAMapp/store/localStorage.ts
index 17c0a95..4c6a959 100644
--- a/PAMapp/store/localStorage.ts
+++ b/PAMapp/store/localStorage.ts
@@ -75,6 +75,7 @@
     localStorage.removeItem('current_role');
     localStorage.removeItem('consultant_id');
     localStorage.removeItem('appointment');
+    localStorage.removeItem('login_consultant');
     this.id_token = localStorage.getItem('id_token');
     this.current_role = localStorage.getItem('current_role');
     this.consultant_id = localStorage.getItem('consultant_id');
diff --git a/PAMapp/store/login.store.ts b/PAMapp/store/login.store.ts
new file mode 100644
index 0000000..a26fc2f
--- /dev/null
+++ b/PAMapp/store/login.store.ts
@@ -0,0 +1,28 @@
+import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
+
+import myConsultantService from '~/shared/services/my-consultant.service';
+import { AgentInfo } from '~/shared/models/agent-info.model';
+
+@Module
+export default class AppointmentStore extends VuexModule {
+
+  loginConsultant?: AgentInfo = JSON.parse(localStorage.getItem('login_consultant')!);
+
+  //////////////////////////////////////////////////////////////////////
+
+  //////////////////////////////////////////////////////////////////////
+
+  @Mutation
+  SET_LOGIN_CONSULTANT(agentInfo: AgentInfo): void {
+    this.loginConsultant = agentInfo;
+    localStorage.setItem('login_consultant', JSON.stringify(agentInfo));
+  }
+
+  //////////////////////////////////////////////////////////////////////
+
+  @Action({ commit: 'SET_LOGIN_CONSULTANT' })
+  async getLoginConsultantDetail(agentNo: string): Promise<AgentInfo> {
+    return await myConsultantService.getConsultantDetail(agentNo).then((res) => res);
+  }
+
+}

--
Gitblit v1.8.0