|
@@ -0,0 +1,135 @@
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
+import { defineProps, defineEmits, watch, ref } from 'vue'
|
|
|
|
+import { accountIcon } from '@/assets/icons.ts'
|
|
|
|
+import { useTokenStore } from '@/stores/auth.ts'
|
|
|
|
+
|
|
|
|
+const props = defineProps<{
|
|
|
|
+ modelValue: boolean;
|
|
|
|
+}>();
|
|
|
|
+
|
|
|
|
+const emits = defineEmits<{
|
|
|
|
+ (e: 'update:modelValue', value: boolean): void;
|
|
|
|
+}>();
|
|
|
|
+
|
|
|
|
+const isVisible = ref(false);
|
|
|
|
+const displayStyle = ref({
|
|
|
|
+ display: "none"
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+watch(() => props.modelValue, (newValue, oldValue) => {
|
|
|
|
+ oldValue = Boolean(oldValue);
|
|
|
|
+ if (oldValue && !newValue) {
|
|
|
|
+ isVisible.value = false;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ displayStyle.value = { display: "none" };
|
|
|
|
+ }, 300);
|
|
|
|
+ } else if (!oldValue && newValue) {
|
|
|
|
+ displayStyle.value = { display: "flex" };
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ isVisible.value = true;
|
|
|
|
+ }, 20);
|
|
|
|
+ }
|
|
|
|
+}, {immediate: true});
|
|
|
|
+
|
|
|
|
+const closeDialog = () => {
|
|
|
|
+ emits('update:modelValue', false);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const psw = ref("");
|
|
|
|
+
|
|
|
|
+const tokenStore = useTokenStore();
|
|
|
|
+
|
|
|
|
+const placeholder = ref("PASS TOKEN");
|
|
|
|
+const failed = ref(false);
|
|
|
|
+
|
|
|
|
+const handleLogin = () => {
|
|
|
|
+ tokenStore.pushPassToken(psw.value).then(res => {
|
|
|
|
+ if (!res) {
|
|
|
|
+ psw.value = "";
|
|
|
|
+ placeholder.value = "WRONG TOKEN";
|
|
|
|
+ failed.value = true;
|
|
|
|
+ } else {
|
|
|
|
+ closeDialog();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<template>
|
|
|
|
+ <div :class="isVisible ? ['visible'] : []" class="overlay" @mousedown="closeDialog" :style="displayStyle">
|
|
|
|
+ <div class="dialog" @mousedown.stop>
|
|
|
|
+ <div class="dialog-header">
|
|
|
|
+ <div class="close-btn" @click="closeDialog"/>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="dialog-content" style="display: flex; flex-direction: column; align-items: center; justify-content: center">
|
|
|
|
+ <div style="width: 32px; height: 32px; fill: var(--text-color)" v-html="accountIcon.template"/>
|
|
|
|
+ <input :placeholder="placeholder" v-model="psw" class="p-input" :class="failed ? ['p-input-danger'] : []" type="password">
|
|
|
|
+ </div>
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
+ <div class="p-button" @click="handleLogin">LOGIN</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+
|
|
|
|
+.overlay {
|
|
|
|
+ position: fixed;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ opacity: 0;
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ z-index: 1000;
|
|
|
|
+ transition: all .3s;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.visible {
|
|
|
|
+ opacity: 100%;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog {
|
|
|
|
+ background-color: var(--secondary-background-color);
|
|
|
|
+ border-radius: 12px;
|
|
|
|
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog-header {
|
|
|
|
+ padding: 10px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: end;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.close-btn {
|
|
|
|
+ width: 12px;
|
|
|
|
+ height: 12px;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ background: var(--danger-color);
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ transition: box-shadow .3s;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.close-btn:hover {
|
|
|
|
+ box-shadow: var(--danger-color) 0 0 12px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog-content {
|
|
|
|
+ padding: 10px;
|
|
|
|
+ width: 480px;
|
|
|
|
+ height: 100px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.dialog-footer {
|
|
|
|
+ width: calc(100% - 48px);
|
|
|
|
+ padding: 12px 24px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: end;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+</style>
|