AccountSecurityDialog.vue 1.6 KB

123456789101112131415161718192021222324252627282930313233
  1. <script setup lang="ts">
  2. import AppIcon from '@/components/common/AppIcon.vue'
  3. import AccountSecurityPanel from '@/components/app/AccountSecurityPanel.vue'
  4. import { useAuthStore } from '@/stores/auth'
  5. const props = defineProps<{ open: boolean }>()
  6. const emit = defineEmits<{ close: [] }>()
  7. const auth = useAuthStore()
  8. async function logout() {
  9. await auth.logout()
  10. emit('close')
  11. }
  12. </script>
  13. <template>
  14. <Teleport to="body">
  15. <div v-if="open" class="layer" @mousedown.self="emit('close')">
  16. <section class="dialog" role="dialog" aria-modal="true" aria-label="账号安全">
  17. <button class="icon-button close-button" type="button" aria-label="关闭" @click="emit('close')"><AppIcon name="close" /></button>
  18. <AccountSecurityPanel :open="open" @saved="emit('close')" @logout="logout" />
  19. </section>
  20. </div>
  21. </Teleport>
  22. </template>
  23. <style scoped>
  24. .layer{position:fixed;z-index:285;inset:0;display:grid;place-items:center;padding:20px;background:var(--scrim);backdrop-filter:blur(6px)}
  25. .dialog{position:relative;width:min(680px,100%);max-height:calc(100dvh - 40px);box-sizing:border-box;padding:24px;overflow:auto;border:1px solid var(--line);border-radius:18px;background:var(--surface-raised);box-shadow:var(--shadow-float)}
  26. .dialog :deep(.panel-heading){padding-right:34px}
  27. .close-button{position:absolute;z-index:1;top:18px;right:18px}
  28. @media(max-width:620px){.layer{place-items:end center;padding:0}.dialog{width:100%;max-height:calc(100dvh - 12px);padding:20px 18px max(20px,env(safe-area-inset-bottom));border-radius:18px 18px 0 0}.close-button{top:14px;right:14px}}
  29. </style>