Browse Source

feat: 实现System Settings页面中Personal Profile部分样式

zhouyuhao 9 months ago
parent
commit
7a1fb2edae

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

@@ -34,7 +34,6 @@ const props = defineProps<{
 }>()
 }>()
 
 
 const handleSeeAll = () => {
 const handleSeeAll = () => {
-  console.log('see all')
   router.push({
   router.push({
     name: 'System Message Detail'
     name: 'System Message Detail'
   })
   })

+ 13 - 0
src/stores/modules/breadCrumb.ts

@@ -40,6 +40,19 @@ export const useBreadCrumb = defineStore('breadCrumb', {
             query: toRoute.query
             query: toRoute.query
           }
           }
         ]
         ]
+      } else if (toRoute.name === 'System Message Detail') {
+        this.routeList = [
+          {
+            label: 'System Message',
+            path: '/system-message',
+            query: ''
+          },
+          {
+            label: 'System Message Detail',
+            path: '/system-message/detail',
+            query: toRoute.query
+          }
+        ]
       } else if (toRoute.name && whiteList.includes(toRoute.name)) {
       } else if (toRoute.name && whiteList.includes(toRoute.name)) {
         this.routeList.push({
         this.routeList.push({
           label: toRoute?.meta?.breadName || toRoute.name,
           label: toRoute?.meta?.breadName || toRoute.name,

+ 9 - 7
src/styles/elementui.scss

@@ -49,7 +49,7 @@ button.el-button.el-button--text {
 
 
 .el-button--main.is-plain {
 .el-button--main.is-plain {
   background-color: var(--color-white);
   background-color: var(--color-white);
-  border: 1px solid var(--color-border);
+  border: 1px solid var(--color-theme);
   span {
   span {
     color: var(--color-theme);
     color: var(--color-theme);
   }
   }
@@ -261,6 +261,7 @@ label.el-radio {
     background-color: var(--color-theme);
     background-color: var(--color-theme);
     border-color: var(--color-theme);
     border-color: var(--color-theme);
   }
   }
+
   .el-radio__inner {
   .el-radio__inner {
     height: 16px;
     height: 16px;
     width: 16px;
     width: 16px;
@@ -443,11 +444,11 @@ html.dark .el-checkbox.el-checkbox--large span.el-checkbox__inner::after {
   width: 5px; /* 打勾图标宽度 */
   width: 5px; /* 打勾图标宽度 */
   height: 10px; /* 打勾图标高度 */
   height: 10px; /* 打勾图标高度 */
 }
 }
-div .el-popper__arrow,
-div .el-popper__arrow:before {
-  // height: 0;
-  // width: 0;
-}
+// div .el-popper__arrow,
+// div .el-popper__arrow:before {
+// height: 0;
+// width: 0;
+// }
 .el-popper.is-dark,
 .el-popper.is-dark,
 div.el-popper.is-dark > .el-popper__arrow:before {
 div.el-popper.is-dark > .el-popper__arrow:before {
   background-color: var(--color-el-popper-bg);
   background-color: var(--color-el-popper-bg);
@@ -518,6 +519,7 @@ div .el-select-dropdown__item.is-hovering {
 .el-select-dropdown__item {
 .el-select-dropdown__item {
   border-radius: var(--border-radius-6);
   border-radius: var(--border-radius-6);
   margin: 0 8px;
   margin: 0 8px;
+  margin-bottom: 4px;
 }
 }
 
 
 div .el-badge__content--warning {
 div .el-badge__content--warning {
@@ -776,4 +778,4 @@ div .DaterangeClass {
   background-color: var(--management-bg-color) !important;
   background-color: var(--management-bg-color) !important;
   border-color: var(--management-bg-color) !important;
   border-color: var(--management-bg-color) !important;
   border-radius: 12px !important;
   border-radius: 12px !important;
-}
+}

+ 26 - 9
src/views/Layout/src/components/Header/HeaderView.vue

@@ -17,7 +17,6 @@ const route = useRoute()
 const router = useRouter()
 const router = useRouter()
 const headerSearch = useHeaderSearch()
 const headerSearch = useHeaderSearch()
 
 
-const themePopoverRef = ref()
 // 切换系统主题颜色
 // 切换系统主题颜色
 const toggleThemeMode = (theme: string) => {
 const toggleThemeMode = (theme: string) => {
   themeStore.toggleTheme(theme, true)
   themeStore.toggleTheme(theme, true)
@@ -178,11 +177,21 @@ 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>
-      <span
-        @click="notificationDrawer = true"
-        class="font_family icon-icon_notice_b"
-        style="font-size: 18px"
-      ></span>
+      <div class="notice-icon" v-if="userStore.username">
+        <!-- <span
+          @click="notificationDrawer = true"
+          class="font_family icon-icon_notice_b"
+          style="font-size: 18px"
+        ></span> -->
+
+        <el-button
+          style="height: 40px; width: 40px; margin-right: 0px"
+          class="el-button--text"
+          @click="notificationDrawer = true"
+        >
+          <span class="font_family icon-icon_notice_b" style="font-size: 18px"></span>
+        </el-button>
+      </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
@@ -294,7 +303,7 @@ const notificationDrawer = ref(false)
         :class="{ 'el-button--pain-theme': themeStore.theme === 'dark' }"
         :class="{ 'el-button--pain-theme': themeStore.theme === 'dark' }"
         v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
         v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
         class="el-button--main"
         class="el-button--main"
-        style="padding: 8px 10px; margin-right: 10px; margin-left: 0"
+        style="padding: 8px 10px; margin-right: 20px; margin-left: 0"
         plain
         plain
         @click="handleDownload"
         @click="handleDownload"
       >
       >
@@ -320,6 +329,7 @@ const notificationDrawer = ref(false)
 .header-avatar {
 .header-avatar {
   width: 24px;
   width: 24px;
   height: 24px;
   height: 24px;
+  margin-left: 8px;
   text-align: center;
   text-align: center;
   border-radius: 50%;
   border-radius: 50%;
   background-color: var(--color-theme);
   background-color: var(--color-theme);
@@ -344,9 +354,8 @@ const notificationDrawer = ref(false)
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   justify-content: center;
   justify-content: center;
-  gap: 8px;
   height: 100%;
   height: 100%;
-
+  gap: 8px;
   .el-input {
   .el-input {
     height: 32px;
     height: 32px;
     width: 400px;
     width: 400px;
@@ -365,6 +374,14 @@ const notificationDrawer = ref(false)
       height: 32px;
       height: 32px;
     }
     }
   }
   }
+
+  .notice-icon {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-top: 2px;
+    cursor: pointer;
+  }
 }
 }
 </style>
 </style>
 <style lang="scss">
 <style lang="scss">

+ 103 - 102
src/views/Layout/src/components/Header/components/TrainingCard.vue

@@ -1,107 +1,108 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import NotificationMessageCard from '@/components/NotificationMessageCard/src/NotificationMessageCard.vue'
 import NotificationMessageCard from '@/components/NotificationMessageCard/src/NotificationMessageCard.vue'
 
 
-const notificationList = [
-  {
-    notificationType: 'feature',
-    info: {
-      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'
-    }
-  },
-  {
-    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: {
-      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: {
-      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.'
-    }
-  },
-  {
-    notificationType: 'event',
-    info: {
-      type: 'milestone',
-      isMultiple: true,
-      numericRecords: 3,
-      isRead: true,
-      title: 'Milestone Update 1',
-      mode: 'Ocean Freight',
-      no: 'HBOL: SHJN2301234',
-      tag: 'Booking Confirmed',
-      location: 'Hong Kong',
-      time: 'Jan 10, 2025 14:30 UTC+8'
-    }
-  },
-  {
-    notificationType: 'event',
-    info: {
-      type: 'milestone',
-      isMultiple: true,
-      numericRecords: 3,
-      isRead: true,
-      title: 'Milestone Update 2',
-      mode: 'Ocean Freight',
-      no: 'HBOL: SHJN2301234',
-      tag: 'Booking Confirmed',
-      location: 'Hong Kong',
-      time: 'Jan 10, 2025 14:30 UTC+8'
-    }
-  },
-  {
-    notificationType: 'event',
-    info: {
-      type: 'milestone',
-      isMultiple: true,
-      numericRecords: 3,
-      isRead: true,
-      title: 'Milestone Update 3',
-      mode: 'Ocean Freight',
-      no: 'HBOL: SHJN2301234',
-      tag: 'Booking Confirmed',
-      location: 'Hong Kong',
-      time: 'Jan 10, 2025 14:30 UTC+8'
-    }
-  }
-]
+const notificationList = []
+// const notificationList = [
+//   {
+//     notificationType: 'feature',
+//     info: {
+//       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'
+//     }
+//   },
+//   {
+//     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: {
+//       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: {
+//       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.'
+//     }
+//   },
+//   {
+//     notificationType: 'event',
+//     info: {
+//       type: 'milestone',
+//       isMultiple: true,
+//       numericRecords: 3,
+//       isRead: true,
+//       title: 'Milestone Update 1',
+//       mode: 'Ocean Freight',
+//       no: 'HBOL: SHJN2301234',
+//       tag: 'Booking Confirmed',
+//       location: 'Hong Kong',
+//       time: 'Jan 10, 2025 14:30 UTC+8'
+//     }
+//   },
+//   {
+//     notificationType: 'event',
+//     info: {
+//       type: 'milestone',
+//       isMultiple: true,
+//       numericRecords: 3,
+//       isRead: true,
+//       title: 'Milestone Update 2',
+//       mode: 'Ocean Freight',
+//       no: 'HBOL: SHJN2301234',
+//       tag: 'Booking Confirmed',
+//       location: 'Hong Kong',
+//       time: 'Jan 10, 2025 14:30 UTC+8'
+//     }
+//   },
+//   {
+//     notificationType: 'event',
+//     info: {
+//       type: 'milestone',
+//       isMultiple: true,
+//       numericRecords: 3,
+//       isRead: true,
+//       title: 'Milestone Update 3',
+//       mode: 'Ocean Freight',
+//       no: 'HBOL: SHJN2301234',
+//       tag: 'Booking Confirmed',
+//       location: 'Hong Kong',
+//       time: 'Jan 10, 2025 14:30 UTC+8'
+//     }
+//   }
+// ]
 
 
 const curCard = ref(null)
 const curCard = ref(null)
 const curIndex = ref(-1)
 const curIndex = ref(-1)
@@ -163,7 +164,7 @@ const closeMessage = () => {
   position: absolute;
   position: absolute;
   top: 60px;
   top: 60px;
   right: 20px;
   right: 20px;
-  z-index: 2000;
+  z-index: 2010;
   width: 432px;
   width: 432px;
   padding: 16px;
   padding: 16px;
   padding-bottom: 0;
   padding-bottom: 0;

+ 5 - 2
src/views/SystemMessage/src/SystemMessage.vue

@@ -1,5 +1,6 @@
 <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 PersonalProfile from './components/PersonalProfile.vue'
 
 
 const collapseVModel = ref<string[]>(['1'])
 const collapseVModel = ref<string[]>(['1'])
 
 
@@ -27,7 +28,7 @@ const setActiveItem = (item: string) => {
   activeItem.value = item
   activeItem.value = item
 }
 }
 
 
-const activeName = ref('first')
+const activeName = ref('second')
 
 
 const handleClick = () => {}
 const handleClick = () => {}
 
 
@@ -128,7 +129,9 @@ const notificationList = [
             ></EventCard>
             ></EventCard>
           </div>
           </div>
         </el-tab-pane>
         </el-tab-pane>
-        <el-tab-pane label="Unread" name="second">Config</el-tab-pane>
+        <el-tab-pane label="Unread" name="second">
+          <PersonalProfile />
+        </el-tab-pane>
         <el-tab-pane label="Read" name="third">Role</el-tab-pane>
         <el-tab-pane label="Read" name="third">Role</el-tab-pane>
       </el-tabs>
       </el-tabs>
     </div>
     </div>

+ 286 - 0
src/views/SystemMessage/src/components/PersonalProfile.vue

@@ -0,0 +1,286 @@
+<script setup lang="ts">
+import dayjs from 'dayjs'
+
+const form = reactive({
+  firstName: '',
+  lastName: '',
+  username: '',
+  email: 'Chud',
+  phone: ''
+})
+
+const segmented = ref('dateTime')
+const handleSegmented = (type: string) => {
+  segmented.value = type
+}
+
+const dateFormat = ref('MM/DD/YYYY')
+const selectVModel = ref('MM/DD/YYYY')
+const dateFormatExample = computed(() => {
+  return {
+    'MM/DD/YYYY': [
+      {
+        label: dayjs().format('MM/DD/YYYY'),
+        value: 'MM/DD/YYYY'
+      },
+      {
+        label: dayjs().format('MMM/DD/YYYY'),
+        value: 'MMM/DD/YYYY'
+      }
+    ],
+    'DD/MM/YYYY': [
+      {
+        label: dayjs().format('DD/MM/YYYY'),
+        value: 'DD/MM/YYYY'
+      },
+      {
+        label: dayjs().format('DD/MMM/YYYY'),
+        value: 'DD/MMM/YYYY'
+      }
+    ],
+    'YYYY-MM-DD': [
+      {
+        label: dayjs().format('YYYY-MM-DD'),
+        value: 'YYYY-MM-DD'
+      },
+      {
+        label: dayjs().format('YYYY-MMM-DD'),
+        value: 'YYYY-MMM-DD'
+      }
+    ]
+  }
+})
+
+const handleDateFormat = (value: string) => {
+  selectVModel.value = dateFormatExample.value[value][0].value
+}
+
+const numbersFormat = ref('1')
+const handleNumbersFormat = (value: string) => {
+  numbersFormat.value = value
+}
+</script>
+
+<template>
+  <div class="personal-profile">
+    <div class="basic-information">
+      <div class="title">Basic Information</div>
+      <div class="content">
+        <div class="row">
+          <div class="item">
+            <p class="label">First Name</p>
+            <el-input size="large" v-model="form.firstName" placeholder="Please enter..." />
+          </div>
+          <div class="item">
+            <p class="label">Last Name</p>
+            <el-input size="large" v-model="form.lastName" placeholder="Please enter..." />
+          </div>
+        </div>
+        <div class="row">
+          <div class="item">
+            <p class="label">User Name</p>
+            <el-input size="large" :disabled="true" v-model="form.username" />
+          </div>
+          <div class="item">
+            <p class="label">Email</p>
+            <el-input size="large" :disabled="true" v-model="form.email" />
+          </div>
+        </div>
+        <div class="row">
+          <div class="item">
+            <p class="label">
+              Password
+              <span style="margin: 0 2px 0 8px" class="font_family icon-icon_time_b"></span>
+              <span>Your password will be expire in</span>
+              <span style="margin-left: 4px; color: var(--color-theme)">4 day(s)</span>
+            </p>
+            <div class="password-change">
+              <el-input size="large" style="width: 330px" :disabled="true" v-model="form.phone" />
+              <el-button class="el-button--main" plain size="large">Change Password</el-button>
+            </div>
+          </div>
+        </div>
+        <div class="row">
+          <el-button class="el-button--dark save-icon" size="large">Save</el-button>
+        </div>
+      </div>
+    </div>
+    <div class="personal-preferences">
+      <div class="title">Personal Preferences</div>
+      <div class="segmented">
+        <div
+          style="width: 121px"
+          :class="{ 'is-active': segmented === 'dateTime' }"
+          @click="handleSegmented('dateTime')"
+          class="item"
+        >
+          Date & Time
+        </div>
+        <div
+          style="width: 162px"
+          :class="{ 'is-active': segmented === 'numbersFormat' }"
+          @click="handleSegmented('numbersFormat')"
+          class="item"
+        >
+          Numbers Format
+        </div>
+      </div>
+      <div class="date-format" v-if="segmented === 'dateTime'">
+        <div class="title">Date & Time</div>
+        <div class="content">
+          <el-radio-group v-model="dateFormat" label="string" @change="handleDateFormat">
+            <el-row>
+              <el-col v-for="(list, key) in dateFormatExample" :key="key">
+                ><el-radio :value="key">
+                  <template #default>
+                    <span>{{ key }}</span>
+                    <el-select
+                      style="margin-left: 28px; width: 320px"
+                      v-if="dateFormat === key"
+                      size="large"
+                      v-model="selectVModel"
+                    >
+                      <el-option
+                        v-for="item in list"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value"
+                      ></el-option>
+                    </el-select>
+                  </template>
+                </el-radio>
+              </el-col>
+
+              <el-col>
+                <el-button style="padding: 0 40px" class="el-button--dark save-icon" size="large"
+                  >Save</el-button
+                >
+              </el-col>
+            </el-row>
+          </el-radio-group>
+        </div>
+      </div>
+      <div class="numbers-format" v-if="segmented === 'numbersFormat'">
+        <div class="title">Numbers Format</div>
+        <div class="content">
+          <el-radio-group v-model="numbersFormat" label="string" @change="handleNumbersFormat">
+            <el-row>
+              <el-col
+                ><el-radio value="1">
+                  <template #default>
+                    <span>1,234.56 (US/UK)</span>
+                  </template>
+                </el-radio></el-col
+              >
+              <el-col
+                ><el-radio value="2">
+                  <template #default>
+                    <span>1.234,56 (European)</span>
+                  </template>
+                </el-radio></el-col
+              >
+              <el-col>
+                <el-button style="padding: 0 40px" class="el-button--dark save-icon" size="large"
+                  >Save</el-button
+                >
+              </el-col>
+            </el-row>
+          </el-radio-group>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.personal-profile {
+  .basic-information,
+  .personal-preferences {
+    border: 1px solid var(--color-border);
+    border-radius: 12px;
+    padding: 16px 16px 32px;
+    & > .title {
+      margin-bottom: 21px;
+      font-size: 18px;
+      font-weight: 700;
+    }
+  }
+}
+.basic-information {
+  .content {
+    .row {
+      display: flex;
+      gap: 8px;
+      .item {
+        flex: 1;
+        margin-bottom: 16px;
+        .label {
+          margin-bottom: 4px;
+          font-size: 12px;
+          color: var(--color-neutral-2);
+          & > span {
+            font-size: 12px;
+            color: var(--color-neutral-3);
+          }
+        }
+        .password-change {
+          display: flex;
+          gap: 8px;
+        }
+      }
+    }
+    .save-icon {
+      margin-top: 16px;
+      padding: 0 40px;
+    }
+  }
+}
+.personal-profile {
+  div.personal-preferences {
+    margin-top: 16px;
+    padding-bottom: 8px;
+    .segmented {
+      width: 291px;
+      height: 40px;
+      margin-bottom: 8px;
+      padding: 4px;
+      border-radius: 12px;
+      background-color: #f5f7fa;
+      .item {
+        display: inline-block;
+        height: 32px;
+        line-height: 32px;
+        font-weight: 700;
+        font-size: 16px;
+        text-align: center;
+        border-radius: 6px;
+        color: var(--color-neutral-2);
+        cursor: pointer;
+        &.is-active {
+          background-color: var(--color-white);
+          color: var(--color-neutral-1);
+        }
+      }
+    }
+    .date-format,
+    .numbers-format {
+      padding: 0px 16px 32px;
+      background-color: #f5f7fa;
+      border-radius: 12px;
+      .title {
+        height: 40px;
+        font-size: 14px;
+        font-weight: 700;
+        line-height: 40px;
+      }
+      .el-col {
+        margin-bottom: 8px;
+        &:last-child {
+          margin-bottom: 0;
+          margin-top: 32px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 0 - 5
src/views/Tracking/src/components/TrackingDetail/src/TrackingDetail.vue

@@ -513,8 +513,3 @@ const openShareDialog = () => {
   text-overflow: ellipsis; /* 超出部分显示省略号 */
   text-overflow: ellipsis; /* 超出部分显示省略号 */
 }
 }
 </style>
 </style>
-<style lang="scss">
-.is-show-tooltip {
-  // display: none;
-}
-</style>