Przeglądaj źródła

style: 调整样式

Jack Zhou 3 miesięcy temu
rodzic
commit
40f75b9d9a

+ 7 - 3
src/components/DateRange/src/components/CalendarDate.vue

@@ -29,6 +29,10 @@ const props = defineProps({
   isETA: {
     type: Boolean,
     default: false
+  },
+  isShowPopupClass: {
+    type: Boolean,
+    default: false
   }
 })
 const ETDDate = ref([])
@@ -38,7 +42,6 @@ const CreatePlaceholder = computed(() => {
   } else {
     return ['Start ATA Time', 'End ATA Time']
   }
-
 })
 watch(
   () => props.Date,
@@ -49,7 +52,7 @@ watch(
         current[1] ? dayjs(current[1]).format(valueFormatDate) : ''
       ]
     } else {
-      ETDDate.value  = []
+      ETDDate.value = []
     }
   },
   { immediate: true, deep: true }
@@ -140,10 +143,11 @@ const isTwoDate = (date: any) => {
         width: props.CalendarWidth,
         backgroundColor: props.isType ? 'var(--more-type-bg-color)' : 'var(--management-bg-color)'
       }"
+      :popupClassName="{ 'th-color': props.isShowPopupClass }"
       :open="open"
       :disabled="Disabled"
       @change="changeRangeData"
-      :placeholder="isNeedFooter? ['Start Time', 'End Time'] : CreatePlaceholder"
+      :placeholder="isNeedFooter ? ['Start Time', 'End Time'] : CreatePlaceholder"
       :format="userStore.dateFormat"
       valueFormat="MM/DD/YYYY"
       @openChange="handleCalendarOpen(ETDDate)"

+ 3 - 0
src/styles/Antdui.scss

@@ -151,6 +151,9 @@ tr
 .ant-picker-dropdown .ant-picker-date-panel .ant-picker-content th {
   color: var(--color-neutral-2);
 }
+.th-color.ant-picker-dropdown .ant-picker-date-panel .ant-picker-content th {
+  color: var(--color-ant-picker-th);
+}
 .ant-picker-dropdown .ant-picker-decade-panel,
 .ant-picker-dropdown .ant-picker-year-panel,
 .ant-picker-dropdown .ant-picker-quarter-panel,

+ 5 - 0
src/styles/theme.scss

@@ -350,6 +350,8 @@
   --color-guide-icon-bg: rgba(237, 237, 237, 0.6);
   --color-guide-icon-hover-bg: rgba(237, 237, 237, 0.45);
   --color--process-data-tips-bg: #e8ebef;
+
+  --color-ant-picker-th: #b5b9bf;
 }
 
 :root.dark {
@@ -573,4 +575,7 @@
   --color-guide-icon-bg: rgba(237, 237, 237, 0.1);
   --color-guide-icon-hover-bg: rgba(237, 237, 237, 0.15);
   --color--process-data-tips-bg: #4f5760;
+  
+  --color-ant-picker-th: rgba(240, 241, 243,0.3);
 }
+  

+ 1 - 1
src/views/DestinationDelivery/src/DestinationDelivery.vue

@@ -138,7 +138,7 @@ const handleSearch = () => {
         </div>
         <div class="date-tips_filter filter-item">
           <span class="label">Creation Date</span>
-          <CalendarDate @DateChange="DateChange"></CalendarDate>
+          <CalendarDate :isShowPopupClass="true" @DateChange="DateChange"></CalendarDate>
         </div>
         <div class="input-tips_filter filter-item">
           <el-input

+ 85 - 0
src/views/Login/src/components/ActivatedDialog.vue

@@ -0,0 +1,85 @@
+<script setup lang="ts">
+const dialogModel = ref(false)
+const state = ref<'reset' | 'activate'>('activate')
+
+const tipsData = ref({
+  reset: {
+    title: 'Password Reset Successfully',
+    firstLine: 'Your password has been successfully reset.',
+    secondLine: 'You can now log in using your email and your new password.'
+  },
+  activate: {
+    title: 'Account Activated Successfully',
+    firstLine: 'Your account has been successfully activated.',
+    secondLine: 'You can now log in using your email and the password you just created.'
+  }
+})
+const handleGotoLogin = () => {
+  dialogModel.value = false
+  // Navigate to login page
+}
+</script>
+
+<template>
+  <el-dialog v-model="dialogModel" top="23vh" class="activated-dialog" width="480">
+    <div class="activated-dialog-content">
+      <div class="successfully-icon">
+        <span style="font-size: 60px; color: white" class="font_family icon-icon_confirm_b"></span>
+      </div>
+      <div class="title">{{ tipsData[state].title }}</div>
+      <div class="description">
+        <p>{{ tipsData[state].firstLine }}</p>
+        <p>{{ tipsData[state].secondLine }}</p>
+      </div>
+    </div>
+    <template #footer>
+      <el-button style="width: 120px; height: 40px" class="el-button--dark" @click="handleGotoLogin"
+        >Go to Login</el-button
+      >
+    </template>
+  </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+.activated-dialog {
+  background-color: red;
+  .successfully-icon {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100px;
+    height: 100px;
+    background-color: rgb(0, 168, 112);
+    border-radius: 50%;
+  }
+  .activated-dialog-content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding-top: 16px;
+  }
+  .title {
+    margin-top: 12px;
+    font-size: 18px;
+    font-weight: 700;
+  }
+  .description {
+    margin-top: 10px;
+    margin-bottom: 8px;
+    text-align: center;
+    line-height: 21px;
+  }
+}
+</style>
+<style lang="scss">
+.activated-dialog {
+  .el-dialog__header {
+    display: none;
+  }
+  .el-dialog__footer {
+    padding-left: 16px;
+    text-align: center;
+  }
+}
+</style>

+ 332 - 0
src/views/Login/src/components/SetPasswordDialog.vue

@@ -0,0 +1,332 @@
+<script setup lang="ts">
+const dialogModel = ref(false)
+const state = ref<'reset' | 'activate'>('activate')
+
+const loginForm = ref({
+  username: '',
+  oldPassword: '',
+  newPassword: '',
+  confirmPassword: ''
+})
+
+const newPwdErrTips = ref('')
+const loginError: any = ref({
+  oldPassword: false,
+  newPassword: false,
+  confirmPassword: false
+})
+
+const handleChangePwd = () => {
+  if (loginForm.value.newPassword !== loginForm.value.confirmPassword) {
+    loginError.value.confirmPassword = true
+    return
+  }
+  if (loginForm.value.newPassword.length < 12 || loginForm.value.newPassword.length > 20) {
+    loginError.value.newPassword = true
+    newPwdErrTips.value = 'Password length between 12 - 20'
+    return
+  }
+  if (!/[A-Z]/.test(loginForm.value.newPassword)) {
+    loginError.value.newPassword = true
+    newPwdErrTips.value = 'Password must contain uppercase letters'
+    return
+  }
+  if (!/[a-z]/.test(loginForm.value.newPassword)) {
+    loginError.value.newPassword = true
+    newPwdErrTips.value = 'Password must contain lowercase letters'
+    return
+  }
+  if (!/[0-9]/.test(loginForm.value.newPassword)) {
+    loginError.value.newPassword = true
+    newPwdErrTips.value = 'Password must contain numbers'
+    return
+  }
+  $api
+    .resetPwd({
+      uname: loginForm.value.username,
+      old_password: loginForm.value.oldPassword,
+      password: loginForm.value.newPassword
+    })
+    .then((res: any) => {
+      // if (res.code === 200) {
+      //   router.push({
+      //     name: 'Login',
+      //     query: {
+      //       isChange: 'true'
+      //     }
+      //   })
+      // } else if (res.code === 400) {
+      //   if (res.msg === 'Old password is incorrect') {
+      //     loginError.value.oldPassword = true
+      //   } else {
+      //     loginError.value.newPassword = true
+      //     newPwdErrTips.value = res.msg
+      //   }
+      // }
+    })
+}
+
+const hiddenError = (key: string) => {
+  loginError.value[key] = false
+}
+
+const hasUppercase = ref(false)
+const hasLowercase = ref(false)
+const hasNumber = ref(false)
+const isValidLength = ref(false)
+const checkPassword = () => {
+  const pwd = loginForm.value.newPassword
+  // 检测是否包含大写字母
+  hasUppercase.value = /[A-Z]/.test(pwd)
+  // 检测是否包含小写字母
+  hasLowercase.value = /[a-z]/.test(pwd)
+  // 检测是否包含数字
+  hasNumber.value = /[0-9]/.test(pwd)
+  // 检测长度是否符合要求
+  isValidLength.value = pwd.length >= 12 && pwd.length <= 20
+}
+
+const confirmPwd = () => {
+  if (loginForm.value.confirmPassword !== loginForm.value.newPassword) {
+    loginError.value.confirmPassword = true
+  } else {
+    loginError.value.confirmPassword = false
+  }
+}
+</script>
+
+<template>
+  <el-dialog
+    v-model="dialogModel"
+    class="set-password-dialog"
+    width="480"
+    :close-on-click-modal="false"
+  >
+    <div class="content">
+      <div class="top-section">
+        <div class="title">Set Your Password</div>
+        <div class="description">
+          Hello Caroline, please create a new password for your account.
+        </div>
+      </div>
+      <div class="login-form">
+        <div class="label" style="margin-top: 0">
+          <span>New Password</span>
+        </div>
+        <el-input
+          ref="passWordRef"
+          :class="{ 'is-error': loginError.newPassword }"
+          v-model="loginForm.newPassword"
+          type="password"
+          placeholder="Please input password"
+          show-password
+          @focus="hiddenError('newPassword')"
+          @input="checkPassword"
+        >
+          <template #prefix>
+            <span class="font_family icon-icon_password_b"></span>
+          </template>
+        </el-input>
+        <div class="error" v-if="loginError.newPassword">{{ newPwdErrTips }}</div>
+        <div class="limit-tips">
+          <div class="tip-item">
+            <span class="font_family icon-icon_confirm_b" :class="{ active: hasUppercase }"></span>
+            <span>Password must contain uppercase letters</span>
+          </div>
+          <div class="tip-item">
+            <span class="font_family icon-icon_confirm_b" :class="{ active: hasLowercase }"></span>
+            <span>Password must contain lowercase letters</span>
+          </div>
+          <div class="tip-item">
+            <span class="font_family icon-icon_confirm_b" :class="{ active: hasNumber }"></span>
+            <span>Password must contain numbers</span>
+          </div>
+          <div class="tip-item">
+            <span
+              style="padding-top: 2px"
+              class="font_family icon-icon_confirm_b"
+              :class="{ active: isValidLength }"
+            ></span>
+            <span>Password length between12 - 20 </span>
+          </div>
+        </div>
+        <div class="label">
+          <span>Confirm New Password</span>
+        </div>
+
+        <el-input
+          ref="passWordRef"
+          :class="{ 'is-error': loginError.confirmPassword }"
+          v-model="loginForm.confirmPassword"
+          type="password"
+          placeholder="Please input password"
+          show-password
+          @focus="hiddenError('confirmPassword')"
+          @blur="confirmPwd"
+        >
+          <template #prefix>
+            <span class="font_family icon-icon_password_b"></span>
+          </template>
+        </el-input>
+        <div class="error" v-if="loginError.confirmPassword">
+          The password does not match. Please try again.
+        </div>
+        <el-button @click="handleChangePwd" class="el-button--dark set-btn">{{
+          state === 'reset' ? 'Reset Password' : 'Set Password & Activate Account'
+        }}</el-button>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+.set-password-dialog {
+  .content {
+    padding-bottom: 40px;
+    .top-section {
+      width: 100%;
+      height: 158px;
+      padding-top: 64px;
+      background: url(../image/bg-login-card.png) no-repeat;
+      background-position: top left; /* 从左上角开始显示 */
+      background-size: 480px 200px; /* 保持背景图像的原始尺寸 */
+      .title {
+        font-size: 24px;
+        font-weight: 700;
+        text-align: center;
+      }
+      .description {
+        margin-top: 16px;
+        text-align: center;
+      }
+    }
+    .set-btn {
+      width: 100%;
+      height: 40px;
+      margin-top: 16px;
+    }
+  }
+  .login-form {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    padding: 0 40px;
+    .el-input {
+      height: 40px;
+      .confirm-icon {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        height: 16px;
+        width: 16px;
+        margin-right: 4px;
+        font-size: 14px;
+        color: #fff;
+        background-color: var(--color-success);
+        border-radius: 50%;
+      }
+
+      &.is-error {
+        :deep(.el-input__wrapper) {
+          box-shadow: 0 0 0 1px var(--color-danger) inset;
+        }
+      }
+
+      :deep(.el-input__prefix) {
+        margin: 0 4px;
+        background-color: transparent;
+      }
+      &.is-disabled {
+        :deep(.el-input__inner) {
+          -webkit-text-fill-color: var(--color-neutral-1);
+          color: var(--color-neutral-1);
+          font-weight: 700;
+        }
+      }
+    }
+    .limit-tips {
+      margin-top: 10px;
+      .tip-item {
+        display: flex;
+        align-items: center;
+        margin-bottom: 8px;
+        font-size: 12px;
+        color: var(--color-neutral-2);
+        &:nth-last-child(1) {
+          margin-bottom: 0;
+        }
+        .font_family {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          height: 12px;
+          width: 12px;
+          padding-top: 1px;
+          background-color: #b5b9bf;
+          font-size: 10px;
+          color: white;
+          border-radius: 50%;
+          &.active {
+            background-color: #00a870;
+          }
+        }
+        span {
+          margin-left: 4px;
+        }
+      }
+    }
+    .verification-code {
+      margin-top: 16px;
+      .verification-code-img {
+        width: 130px;
+        height: 38px;
+        object-fit: cover;
+      }
+      :deep(.el-input-group__append) {
+        padding: 0;
+        padding-right: 1px;
+      }
+    }
+    .el-input.user-name {
+      :deep(.el-input__wrapper) {
+        padding-right: 6px;
+        box-shadow: 0 0 0 1px var(--color-input-disabled-border) inset;
+      }
+    }
+
+    .label {
+      display: flex;
+      justify-content: space-between;
+      width: 100%;
+      margin-top: 14px;
+      font-size: 12px;
+      line-height: 18px;
+
+      span {
+        color: var(--color-neutral-2);
+      }
+
+      .forgot-password {
+        color: var(--color-theme);
+        cursor: pointer;
+      }
+    }
+
+    .error {
+      font-size: 12px;
+      color: var(--color-danger);
+      line-height: 14px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.set-password-dialog {
+  .el-dialog__header {
+    display: none;
+  }
+  .el-dialog__body {
+    padding: 0;
+  }
+}
+</style>

+ 4 - 0
src/views/Login/src/loginView.vue

@@ -7,6 +7,8 @@ import { useThemeStore } from '@/stores/modules/theme'
 import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
 import CryptoJS from 'crypto-js'
 import dayjs from 'dayjs'
+import ActivatedDialog from './components/ActivatedDialog.vue'
+import SetPasswordDialog from './components/SetPasswordDialog.vue'
 
 const router = useRouter()
 const route = useRoute()
@@ -476,6 +478,8 @@ const firstLoginTipsRef = ref()
     ></VSliderVerification>
     <ErrorTips ref="errorTipsRef" @forget-password="status = 'reset'"></ErrorTips>
     <FirstLoginTips ref="firstLoginTipsRef" @forget-password="status = 'reset'"></FirstLoginTips>
+    <ActivatedDialog></ActivatedDialog>
+    <SetPasswordDialog></SetPasswordDialog>
   </div>
 </template>