Эх сурвалжийг харах

feat: 实现notification 卡片的暗黑模式样式

zhouyuhao 9 сар өмнө
parent
commit
6a8b279565

+ 1 - 0
src/components/NotificationMessageCard/src/NotificationMessageCard.vue

@@ -6,6 +6,7 @@ import FeatureUpdateCard from './components/FeatureUpdateCard.vue'
 const props = defineProps<{
 const props = defineProps<{
   data: any
   data: any
 }>()
 }>()
+console.log(props.data, 'props.data')
 </script>
 </script>
 
 
 <template>
 <template>

+ 44 - 17
src/components/NotificationMessageCard/src/components/EventCard.vue

@@ -18,7 +18,14 @@ interface EventCardPropsData {
   timezone?: string // 时区
   timezone?: string // 时区
   time: string
   time: string
   timeLabel: string
   timeLabel: string
-  previous?: Array<string>
+  serial_no?: string // 单号 用来跳转到Tracking详情页
+  order_from?: string // 订单来源 用来跳转到Tracking详情页
+  previous?: {
+    date: string
+    tag: string
+    time: string
+    timezone: string
+  }
   info?: {
   info?: {
     route?: []
     route?: []
     etdOrdeparturNum?: number
     etdOrdeparturNum?: number
@@ -43,6 +50,13 @@ const handleSeeAll = (data: any) => {
     }
     }
   })
   })
 }
 }
+
+const jumpTracking = (data: any) => {
+  router.push({
+    path: '/tracking/detail',
+    query: { a: data.serial_no, _schemas: data.order_from }
+  })
+}
 </script>
 </script>
 
 
 <template>
 <template>
@@ -54,9 +68,9 @@ const handleSeeAll = (data: any) => {
     <div class="content">
     <div class="content">
       <div
       <div
         class="more-tips"
         class="more-tips"
-        v-if="(data.type === 'milestone' || 'container') && data.numericRecords"
+        v-if="(data.type === 'milestone' || data.type === 'container') && data.numericRecords"
       >
       >
-        <span>Latest Status Updates ({{ data.numericRecords }})</span>
+        <span>Latest Status Updates ({{ data.numericRecords }}) </span>
         <el-button @click="handleSeeAll(data)" class="see-all-icon el-button--text">
         <el-button @click="handleSeeAll(data)" class="see-all-icon el-button--text">
           See All
           See All
           <span class="font_family icon-icon_next_b"></span>
           <span class="font_family icon-icon_next_b"></span>
@@ -108,7 +122,7 @@ const handleSeeAll = (data: any) => {
         <!-- 除了container类型,其他类型都显示运输方式图标 -->
         <!-- 除了container类型,其他类型都显示运输方式图标 -->
         <div style="display: inline-block" v-if="data.type !== 'container'">
         <div style="display: inline-block" v-if="data.type !== 'container'">
           <span class="font_family" :class="[`icon-${transportationMode?.[data.mode]}`]"></span>
           <span class="font_family" :class="[`icon-${transportationMode?.[data.mode]}`]"></span>
-          <span class="no">HBOL: {{ data.no }}</span>
+          <span @click="jumpTracking(data)" class="no no-link">HBOL: {{ data.no }}</span>
         </div>
         </div>
         <!-- container类型显示图标 -->
         <!-- container类型显示图标 -->
         <div v-else>
         <div v-else>
@@ -143,11 +157,11 @@ const handleSeeAll = (data: any) => {
       </div>
       </div>
       <div
       <div
         :class="{ 'delay-time': data.type === 'delay', 'change-time': data.type === 'change' }"
         :class="{ 'delay-time': data.type === 'delay', 'change-time': data.type === 'change' }"
-        v-if="(data.type === 'delay' || 'change') && data.info?.time"
+        v-if="(data.type === 'delay' || data.type === 'change') && data.info?.time"
       >
       >
         <span
         <span
           v-if="data.type === 'delay'"
           v-if="data.type === 'delay'"
-          style="margin-right: 5px"
+          style="margin-right: 6px"
           class="font_family icon-icon_delay_b"
           class="font_family icon-icon_delay_b"
         ></span>
         ></span>
         <span v-else class="font_family icon-icon_time_b"></span>
         <span v-else class="font_family icon-icon_time_b"></span>
@@ -169,7 +183,10 @@ const handleSeeAll = (data: any) => {
       </div>
       </div>
       <div class="previous" v-if="data.previous">
       <div class="previous" v-if="data.previous">
         <span class="previous-icon"></span>
         <span class="previous-icon"></span>
-        <span>{{ data.previous }}</span>
+        <span
+          >{{ data.previous.tag }}&nbsp;({{ data.previous.time }}
+          {{ getTimezone(data.previous.timezone) }})</span
+        >
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
@@ -201,6 +218,7 @@ const handleSeeAll = (data: any) => {
       margin-right: 10px;
       margin-right: 10px;
     }
     }
     .title {
     .title {
+      flex: 1;
       font-weight: 700;
       font-weight: 700;
     }
     }
   }
   }
@@ -232,16 +250,24 @@ const handleSeeAll = (data: any) => {
         font-weight: 700;
         font-weight: 700;
         line-height: 18px;
         line-height: 18px;
       }
       }
+      .no-link {
+        &:hover {
+          color: var(--color-theme);
+          cursor: pointer;
+        }
+      }
       .tag {
       .tag {
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
+        height: 18px;
+        margin-top: 2px;
         margin-left: 4px;
         margin-left: 4px;
         padding-left: 8px;
         padding-left: 8px;
         padding-right: 6px;
         padding-right: 6px;
-        background-color: #e6f1eb;
+        background-color: var(--color-milestone-tag-bg);
         border-radius: 3px;
         border-radius: 3px;
         &.delay {
         &.delay {
-          background-color: #f7e7e9;
+          background-color: var(--color-delay-tag-bg);
           .dot {
           .dot {
             background-color: #c9353f;
             background-color: #c9353f;
           }
           }
@@ -250,7 +276,7 @@ const handleSeeAll = (data: any) => {
           }
           }
         }
         }
         &.change {
         &.change {
-          background-color: #f5f2e6;
+          background-color: var(--color-change-tag-bg);
           .dot {
           .dot {
             background-color: #edb82f;
             background-color: #edb82f;
           }
           }
@@ -267,7 +293,6 @@ const handleSeeAll = (data: any) => {
           margin-right: 4px;
           margin-right: 4px;
         }
         }
         .text {
         .text {
-          margin-top: 2px;
           font-size: 10px;
           font-size: 10px;
           font-weight: 600;
           font-weight: 600;
           color: #5bb462;
           color: #5bb462;
@@ -293,7 +318,7 @@ const handleSeeAll = (data: any) => {
       span {
       span {
         color: var(--color-neutral-2);
         color: var(--color-neutral-2);
         font-size: 12px;
         font-size: 12px;
-        line-height: 16px;
+        line-height: 14px;
       }
       }
       .font_family {
       .font_family {
         font-size: 16px;
         font-size: 16px;
@@ -303,19 +328,22 @@ const handleSeeAll = (data: any) => {
       }
       }
     }
     }
     div.delay-time {
     div.delay-time {
+      height: 19px;
       margin-top: 6px;
       margin-top: 6px;
+      margin-bottom: -2px;
       span,
       span,
       .font_family {
       .font_family {
         color: #c9353f;
         color: #c9353f;
       }
       }
       span {
       span {
+        display: inline-block;
+        margin-top: 3px;
         line-height: 19px;
         line-height: 19px;
       }
       }
       .font_family {
       .font_family {
+        margin: 0 6px 0 -1px;
         line-height: 12px;
         line-height: 12px;
-        margin-left: -1px;
-        margin-right: 6px;
-        font-size: 19px;
+        font-size: 18px;
       }
       }
     }
     }
     div.change-time {
     div.change-time {
@@ -325,11 +353,10 @@ const handleSeeAll = (data: any) => {
       }
       }
     }
     }
     .previous {
     .previous {
-      height: 24px;
       margin-top: 8px;
       margin-top: 8px;
       padding-left: 8px;
       padding-left: 8px;
       line-height: 24px;
       line-height: 24px;
-      background-color: #e1e3e9;
+      background-color: var(--color-previous-bg);
       border-radius: 6px;
       border-radius: 6px;
       span {
       span {
         font-size: 12px;
         font-size: 12px;

+ 24 - 2
src/components/NotificationMessageCard/src/components/FeatureUpdateCard.vue

@@ -1,4 +1,6 @@
 <script setup lang="ts">
 <script setup lang="ts">
+import featureImg from '../images/test.png'
+
 interface FeatureUpdateCardPropsData {
 interface FeatureUpdateCardPropsData {
   title: string
   title: string
   header: string
   header: string
@@ -10,6 +12,7 @@ interface FeatureUpdateCardPropsData {
 const props = defineProps<{
 const props = defineProps<{
   data: FeatureUpdateCardPropsData
   data: FeatureUpdateCardPropsData
 }>()
 }>()
+console.log(props.data, 'props.data111')
 </script>
 </script>
 
 
 <template>
 <template>
@@ -28,7 +31,9 @@ const props = defineProps<{
         <div class="content-text">
         <div class="content-text">
           <span>{{ data.content }}</span>
           <span>{{ data.content }}</span>
         </div>
         </div>
-        <img src="../images/test.png" style="margin: 12px 0 16px 24px; border-radius: 8px" alt="" />
+        <div class="feature-img">
+          <el-image :src="featureImg" fit="contain" alt="feature-img"></el-image>
+        </div>
 
 
         <div class="change-btn" style="text-align: center">
         <div class="change-btn" style="text-align: center">
           <el-button class="el-button--main" style="height: 40px; padding: 0 32px">
           <el-button class="el-button--main" style="height: 40px; padding: 0 32px">
@@ -70,7 +75,12 @@ const props = defineProps<{
   }
   }
   .card-content {
   .card-content {
     padding: 16px 16px 24px 8px;
     padding: 16px 16px 24px 8px;
-    background: linear-gradient(137deg, #fff4eb 12.41%, #f0f3ff 52.63%, #e0f7f9 93.28%);
+    background: linear-gradient(
+      137deg,
+      var(--color-feature-card-first-bg) 12.41%,
+      var(--color-feature-card-second-bg) 52.63%,
+      var(--color-feature-card-third-bg) 93.28%
+    );
     border-radius: 12px;
     border-radius: 12px;
     .title {
     .title {
       img {
       img {
@@ -96,6 +106,18 @@ const props = defineProps<{
     .content-text {
     .content-text {
       margin: 8px 0 0px 24px;
       margin: 8px 0 0px 24px;
     }
     }
+    .feature-img {
+      margin-top: 12px;
+      margin-bottom: 16px;
+      padding-left: 24px;
+      .el-image {
+        display: block;
+        margin: 0 auto;
+        width: 352px;
+        height: 200px;
+        border-radius: 8px;
+      }
+    }
   }
   }
 }
 }
 </style>
 </style>

+ 14 - 4
src/components/NotificationMessageCard/src/components/PasswordCard.vue

@@ -2,7 +2,7 @@
 interface PasswordCardPropsData {
 interface PasswordCardPropsData {
   title: string
   title: string
   isExpiration: boolean
   isExpiration: boolean
-  tips: string
+  header: string
   isRead: boolean
   isRead: boolean
   content: string
   content: string
 }
 }
@@ -20,7 +20,7 @@ const props = defineProps<{
     <div class="card-content" :class="{ 'is-expired': data.isExpiration }">
     <div class="card-content" :class="{ 'is-expired': data.isExpiration }">
       <div class="title">
       <div class="title">
         <span class="font_family icon-icon_password_b"></span>
         <span class="font_family icon-icon_password_b"></span>
-        <span>{{ data.tips }}</span>
+        <span>{{ data.header }}</span>
       </div>
       </div>
       <div class="details">
       <div class="details">
         {{ data.content }}
         {{ data.content }}
@@ -65,15 +65,24 @@ const props = defineProps<{
   }
   }
   .card-content {
   .card-content {
     padding: 16px 8px 24px;
     padding: 16px 8px 24px;
-    background: linear-gradient(180deg, #ffe294 0%, #f6f8fa 100%);
+    background: linear-gradient(
+      180deg,
+      var(--color-password-card-first-bg) 0%,
+      var(--color-password-card-second-bg) 100%
+    );
     border-radius: 12px;
     border-radius: 12px;
     &.is-expired {
     &.is-expired {
-      background: linear-gradient(182deg, #ef99a0 2.2%, #f6f8fa 98.77%);
+      background: linear-gradient(
+        182deg,
+        var(--color-password-expired-card-first-bg) 2.2%,
+        var(--color-password-expired-card-second-bg) 98.77%
+      );
     }
     }
     .title {
     .title {
       span {
       span {
         vertical-align: middle;
         vertical-align: middle;
         font-weight: 700;
         font-weight: 700;
+        color: #2b2f36;
       }
       }
       .font_family {
       .font_family {
         margin-right: 8px;
         margin-right: 8px;
@@ -81,6 +90,7 @@ const props = defineProps<{
     }
     }
     .details {
     .details {
       margin: 8px 0 16px 24px;
       margin: 8px 0 16px 24px;
+      color: #2b2f36;
     }
     }
   }
   }
 }
 }

+ 1 - 1
src/styles/elementui.scss

@@ -338,7 +338,7 @@ div.el-drawer {
     height: 64px;
     height: 64px;
     padding: 16px;
     padding: 16px;
     margin-bottom: 0;
     margin-bottom: 0;
-    background-color: var(--color-table-header-bg);
+    background-color: var(--color-header-bg);
     & > span {
     & > span {
       font-weight: 700;
       font-weight: 700;
       font-size: 24px;
       font-size: 24px;

+ 29 - 0
src/styles/theme.scss

@@ -257,6 +257,20 @@
   --color-upload-file-border-bg: #f5b279;
   --color-upload-file-border-bg: #f5b279;
 
 
   --color-personal-preference-bg: #f5f7fa;
   --color-personal-preference-bg: #f5f7fa;
+
+  --color-password-card-first-bg: #ffe294;
+  --color-password-card-second-bg: #f6f8fa;
+  --color-password-expired-card-first-bg: #ef99a0;
+  --color-password-expired-card-second-bg: #f6f8fa;
+  --color-feature-card-first-bg: #fff4eb;
+  --color-feature-card-second-bg: #f0f3ff;
+  --color-feature-card-third-bg: #f0f3ff;
+
+  --color-milestone-tag-bg: #e6f1eb;
+  --color-delay-tag-bg: #f7e7e9;
+  --color-change-tag-bg: #f5f2e6;
+
+  --color-previous-bg: #e1e3e9;
 }
 }
 
 
 :root.dark {
 :root.dark {
@@ -337,6 +351,21 @@
   --color-v-box-content-drag-bg: #2b2f36;
   --color-v-box-content-drag-bg: #2b2f36;
 
 
   --color-input-disabled-border: #656f7d;
   --color-input-disabled-border: #656f7d;
+
+  --color-password-card-first-bg: #ffa000;
+  --color-password-card-second-bg: #d6c587;
+  --color-password-expired-card-first-bg: #f25a66;
+  --color-password-expired-card-second-bg: #cda9ac;
+  --color-feature-card-first-bg: #334181;
+  --color-feature-card-second-bg: #c651bd;
+  --color-feature-card-third-bg: #ffca6e;
+  --color-milestone-tag-bg: #3c5249;
+  --color-delay-tag-bg: #523942;
+  --color-change-tag-bg: #564f36;
+
+  --color-previous-bg: #454b54;
+
+  --color-system-message-nav-bg: #343a43;
   // 邮件
   // 邮件
   --w-e-toolbar-bg-color: var(--color-email-bg);
   --w-e-toolbar-bg-color: var(--color-email-bg);
   --w-e-textarea-bg-color: var(--color-email-bg);
   --w-e-textarea-bg-color: var(--color-email-bg);

+ 2 - 2
src/views/Layout/src/components/Header/HeaderView.vue

@@ -200,7 +200,7 @@ const notificationDrawer = ref(false)
           <span style="margin-top: -1px" class="font_family icon-icon_search_b"></span>
           <span style="margin-top: -1px" class="font_family icon-icon_search_b"></span>
         </template>
         </template>
       </el-input>
       </el-input>
-      <!-- <div class="notice-icon" v-if="userStore.userInfo?.uname">
+      <div class="notice-icon" v-if="userStore.userInfo?.uname">
         <span class="unread-tip-icon"></span>
         <span class="unread-tip-icon"></span>
         <el-button
         <el-button
           style="height: 40px; width: 40px; margin-right: 0px"
           style="height: 40px; width: 40px; margin-right: 0px"
@@ -209,7 +209,7 @@ const notificationDrawer = ref(false)
         >
         >
           <span class="font_family icon-icon_notice_b" style="font-size: 18px"></span>
           <span class="font_family icon-icon_notice_b" style="font-size: 18px"></span>
         </el-button>
         </el-button>
-      </div> -->
+      </div>
       <!-- 
       <!-- 
       <span class="font_family icon-icon_language_b" style="font-size: 16px"></span> -->
       <span class="font_family icon-icon_language_b" style="font-size: 16px"></span> -->
       <el-popover
       <el-popover

+ 80 - 79
src/views/Layout/src/components/Header/components/NotificationDrawer.vue

@@ -18,84 +18,84 @@ const notificationTypeList = ref({
   Feature_Update: 'Feature Update'
   Feature_Update: 'Feature Update'
 })
 })
 
 
-const notificationList = ref<any[]>([])
-// const notificationList = [
-//   {
-//     notificationType: 'feature',
-//     info: {
-//       isRead: true,
-//       title: 'Feature Update',
-//       header: 'New feature online: Quick search has been released!',
-//       content:
-//         'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
-//     }
-//   },
-//   {
-//     notificationType: 'event',
-//     info: {
-//       type: 'milestone',
-//       isMultiple: true,
-//       numericRecords: 3,
-//       isRead: true,
-//       title: 'Milestone Update',
-//       mode: 'Ocean Freight',
-//       no: 'HBOL: SHJN2301234',
-//       tag: 'Booking Confirmed',
-//       location: 'Hong Kong',
-//       time: 'Jan 10, 2025 14:30 UTC+8',
-//       info: {
-//         route: ['Hong Kong', 'Shanghai', 'Ningbo']
-//       }
-//     }
-//   },
-//   {
-//     notificationType: 'password',
-//     info: {
-//       title: 'Password Notifications',
-//       isExpiration: true,
-//       tips: 'Password Expiration in 311 Days',
-//       content:
-//         'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
-//     }
-//   },
-//   {
-//     notificationType: 'password',
-//     info: {
-//       isRead: false,
-//       title: 'Password Notifications',
-//       isExpiration: false,
-//       tips: 'Password Expiration in 3 Days',
-//       content:
-//         'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
-//     }
-//   },
-//   {
-//     notificationType: 'password',
-//     info: {
-//       isRead: true,
-//       title: 'Password Notifications',
-//       isExpiration: true,
-//       tips: 'Password Expiration in 31111 Days',
-//       content:
-//         'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
-//     }
-//   }
-// ]
+// const notificationList = ref<any[]>([])
+const notificationList = [
+  {
+    notificationType: 'feature',
+    info: {
+      isRead: true,
+      title: 'Feature Update',
+      header: 'New feature online: Quick search has been released!',
+      content:
+        'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
+    }
+  },
+  {
+    notificationType: 'event',
+    info: {
+      type: 'milestone',
+      isMultiple: true,
+      numericRecords: 3,
+      isRead: true,
+      title: 'Milestone Update',
+      mode: 'Ocean Freight',
+      no: 'HBOL: SHJN2301234',
+      tag: 'Booking Confirmed',
+      location: 'Hong Kong',
+      time: 'Jan 10, 2025 14:30 UTC+8',
+      info: {
+        route: ['Hong Kong', 'Shanghai', 'Ningbo']
+      }
+    }
+  },
+  {
+    notificationType: 'password',
+    info: {
+      title: 'Password Notifications',
+      isExpiration: true,
+      tips: 'Password Expiration in 311 Days',
+      content:
+        'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
+    }
+  },
+  {
+    notificationType: 'password',
+    info: {
+      isRead: false,
+      title: 'Password Notifications',
+      isExpiration: false,
+      tips: 'Password Expiration in 3 Days',
+      content:
+        'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
+    }
+  },
+  {
+    notificationType: 'password',
+    info: {
+      isRead: true,
+      title: 'Password Notifications',
+      isExpiration: true,
+      tips: 'Password Expiration in 31111 Days',
+      content:
+        'Your password will expire in 7 days. To ensure the security of your account, please change your password as soon as possible.'
+    }
+  }
+]
 
 
 const getNotificationList = () => {
 const getNotificationList = () => {
-  loading.value = true
-  $api
-    .getNotificationList({
-      rules_type: 'Milestone_Update'
-    })
-    .then((res) => {
-      if (res.code === 200) {
-        notificationList.value = res.data
-      }
-    })
-    .finally(() => {
-      loading.value = false
-    })
+  // loading.value = true
+  // $api
+  //   .getNotificationList({
+  //     rules_type: notificationType.value
+  //   })
+  //   .then((res) => {
+  //     if (res.code === 200) {
+  //       notificationList.value = res.data
+  //     }
+  //   })
+  //   .finally(() => {
+  //     loading.value = false
+  //   })
 }
 }
 
 
 const handleMarkAllRead = () => {
 const handleMarkAllRead = () => {
@@ -138,7 +138,7 @@ const clearData = () => {
       </el-select>
       </el-select>
     </template>
     </template>
     <template #default>
     <template #default>
-      <div v-vloading="loading" style="height: 100%">
+      <el-scrollbar v-vloading="loading" style="height: 100%">
         <div class="notification-header">
         <div class="notification-header">
           <el-button @click="handleMarkAllRead" class="mark-all-read el-button--text" size="small">
           <el-button @click="handleMarkAllRead" class="mark-all-read el-button--text" size="small">
             <span class="font_family icon-icon_confirm_b show-icon"></span>
             <span class="font_family icon-icon_confirm_b show-icon"></span>
@@ -165,7 +165,7 @@ const clearData = () => {
         <div class="notification-content">
         <div class="notification-content">
           <NotificationMessageCard :data="notificationList" />
           <NotificationMessageCard :data="notificationList" />
         </div>
         </div>
-      </div>
+      </el-scrollbar>
     </template>
     </template>
   </el-drawer>
   </el-drawer>
 </template>
 </template>
@@ -173,6 +173,7 @@ const clearData = () => {
 div.layout-toolbar {
 div.layout-toolbar {
   .notification-content {
   .notification-content {
     padding: 16px;
     padding: 16px;
+    background-color: var(--color-dialog-body-bg);
   }
   }
   .password-notifications {
   .password-notifications {
     margin-bottom: 16px;
     margin-bottom: 16px;
@@ -286,7 +287,7 @@ div.layout-toolbar {
       height: 40px;
       height: 40px;
       padding: 0 16px;
       padding: 0 16px;
       line-height: 40px;
       line-height: 40px;
-      background-color: white;
+      background-color: var(--color-dialog-body-bg);
       border-bottom: 1px solid var(--color-border);
       border-bottom: 1px solid var(--color-border);
       .mark-all-read {
       .mark-all-read {
         span {
         span {

+ 109 - 30
src/views/SystemMessage/src/SystemMessage.vue

@@ -1,27 +1,63 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import EventCard from '@/components/NotificationMessageCard/src/components/EventCard.vue'
 import EventCard from '@/components/NotificationMessageCard/src/components/EventCard.vue'
+import NotificationMessageCard from '@/components/NotificationMessageCard/src/NotificationMessageCard.vue'
 
 
 const collapseVModel = ref<string[]>(['1'])
 const collapseVModel = ref<string[]>(['1'])
 
 
+const unreadCount = ref(33)
+const readCount = ref(22)
+const allCount = ref(135)
+const tabCountList = [2, 1, 99, 0, 23]
+const handleCount = (count: number) => {
+  if (!count) return 0
+  return count > 99 ? '99+' : count
+}
 const navList = [
 const navList = [
+  'Milestone Update',
+  'Container Status Update',
+  'Departure/Arrival Delay',
+  'ETD/ETA Change'
+]
+const cardList = [
   {
   {
-    title: 'Milestone Update',
-    count: 2
-  },
-  {
-    title: 'Container Status Update',
-    count: 1
-  },
-  {
-    title: 'Departure/Arrival Delay',
-    count: '99+'
-  },
-  {
-    title: 'ETD/ETA Change',
-    count: 0
+    notificationType: 'event',
+    info: {
+      type: 'milestone',
+      isMultiple: true,
+      numericRecords: 3,
+      isRead: true,
+      title: 'Milestone Update',
+      mode: 'Ocean Freight',
+      no: 'HBOL: SHJN2301234',
+      tag: 'Booking Confirmed',
+      location: 'Hong Kong',
+      time: 'Jan 10, 2025 14:30 UTC+8',
+      info: {
+        route: ['Hong Kong', 'Shanghai', 'Ningbo']
+      }
+    }
   }
   }
 ]
 ]
 
 
+const result = {
+  countList: [2, 1, 99, 0, 33],
+  allCount: 135,
+  unreadCount: 33,
+  readCount: 22,
+  cardList: [
+    {
+      notificationType: 'feature',
+      info: {
+        isRead: true,
+        title: 'Feature Update',
+        header: 'New feature online: Quick search has been released!',
+        content:
+          'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
+      }
+    }
+  ]
+}
+
 const activeItem = ref('Milestone Update')
 const activeItem = ref('Milestone Update')
 const setActiveItem = (item: string) => {
 const setActiveItem = (item: string) => {
   activeItem.value = item
   activeItem.value = item
@@ -181,6 +217,39 @@ const notificationList = [
 // onMounted(() => {
 // onMounted(() => {
 //   getNotificationList()
 //   getNotificationList()
 // })
 // })
+
+const featureList = [
+  {
+    notificationType: 'feature',
+    info: {
+      isRead: true,
+      title: 'Feature Update',
+      header: 'New feature online: Quick search has been released!',
+      content:
+        'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
+    }
+  },
+  {
+    notificationType: 'feature',
+    info: {
+      isRead: true,
+      title: 'Feature Update',
+      header: 'New feature online: Quick search has been released!',
+      content:
+        'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
+    }
+  },
+  {
+    notificationType: 'feature',
+    info: {
+      isRead: true,
+      title: 'Feature Update',
+      header: 'New feature online: Quick search has been released!',
+      content:
+        'We are pleased to announce that the quick search function is now officially online! You can now quickly find what you need by entering keywords, greatly improving your work efficiency. Go and experience it!'
+    }
+  }
+]
 </script>
 </script>
 
 
 <template>
 <template>
@@ -190,16 +259,16 @@ const notificationList = [
       <el-collapse v-model="collapseVModel">
       <el-collapse v-model="collapseVModel">
         <el-collapse-item title="Event Notifications" name="1">
         <el-collapse-item title="Event Notifications" name="1">
           <div
           <div
-            @click="setActiveItem(item.title)"
+            @click="setActiveItem(item)"
             class="collapse-item"
             class="collapse-item"
-            :class="{ 'is-active': item.title === activeItem }"
-            v-for="item in navList"
-            :key="item.title"
+            :class="{ 'is-active': item === activeItem }"
+            v-for="(item, index) in navList"
+            :key="item"
           >
           >
-            <div v-if="item.title === activeItem" class="active-sign"></div>
-            <span>{{ item.title }}</span>
-            <div class="count" v-if="item.count">
-              <span>{{ item.count }}</span>
+            <div v-if="item === activeItem" class="active-sign"></div>
+            <span>{{ item }}</span>
+            <div class="count">
+              <span>{{ handleCount(tabCountList?.[index]) }}</span>
             </div>
             </div>
           </div>
           </div>
         </el-collapse-item>
         </el-collapse-item>
@@ -213,30 +282,39 @@ const notificationList = [
         <div v-if="activeItem === 'Feature Update'" class="active-sign"></div>
         <div v-if="activeItem === 'Feature Update'" class="active-sign"></div>
         <span>Feature Update</span>
         <span>Feature Update</span>
         <div class="count">
         <div class="count">
-          <span>33</span>
+          <span>{{ handleCount(tabCountList?.[tabCountList.length - 1]) }}</span>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
     <div class="right-content">
     <div class="right-content">
       <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
       <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
         <el-tab-pane label="All Notifications" name="first">
         <el-tab-pane label="All Notifications" name="first">
+          <template #label>
+            <span style="margin-right: 4px">All Notifications</span>
+            <div class="count">
+              <span>{{ handleCount(allCount) }}</span>
+            </div>
+          </template>
           <div style="padding: 10px 140px 0px 16px">
           <div style="padding: 10px 140px 0px 16px">
-            <EventCard
-              v-for="(item, index) in notificationList"
-              :key="index"
-              :data="item"
-            ></EventCard>
+            <NotificationMessageCard :data="cardList"></NotificationMessageCard>
           </div>
           </div>
         </el-tab-pane>
         </el-tab-pane>
         <el-tab-pane label="Unread" name="second">
         <el-tab-pane label="Unread" name="second">
           <template #label>
           <template #label>
             <span style="margin-right: 4px">Unread</span>
             <span style="margin-right: 4px">Unread</span>
             <div class="count">
             <div class="count">
-              <span>33</span>
+              <span>{{ handleCount(unreadCount) }}</span>
             </div>
             </div>
           </template>
           </template>
         </el-tab-pane>
         </el-tab-pane>
-        <el-tab-pane label="Read" name="third">Role</el-tab-pane>
+        <el-tab-pane label="Read" name="third">
+          <template #label
+            ><span style="margin-right: 4px">Read</span>
+            <div class="count">
+              <span>{{ handleCount(readCount) }}</span>
+            </div></template
+          >
+        </el-tab-pane>
       </el-tabs>
       </el-tabs>
     </div>
     </div>
   </div>
   </div>
@@ -260,6 +338,7 @@ const notificationList = [
     justify-content: center;
     justify-content: center;
     height: 18px;
     height: 18px;
     min-width: 18px;
     min-width: 18px;
+    padding-top: 1px;
     padding-left: 4px;
     padding-left: 4px;
     padding-right: 5px;
     padding-right: 5px;
     background-color: var(--color-theme);
     background-color: var(--color-theme);