mirror of
https://github.com/certd/certd.git
synced 2026-05-17 22:07:34 +08:00
🔱: [client] sync upgrade with 7 commits [trident-sync]
chore: Merge branch 'vben' # Conflicts: # package.json perf: antdv示例改成使用vben框架 chore: vben chore: vben chore: vben
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export { default as LockScreenModal } from "./lock-screen-modal.vue";
|
||||
export { default as LockScreen } from "./lock-screen.vue";
|
||||
@@ -0,0 +1,89 @@
|
||||
<script setup lang="ts">
|
||||
import type { Recordable } from "../../../types";
|
||||
|
||||
import { computed, reactive } from "vue";
|
||||
|
||||
import { $t } from "../../../locales";
|
||||
|
||||
import { useVbenForm, z } from "../../../form-ui";
|
||||
import { useVbenModal } from "../../../popup-ui";
|
||||
import { VbenAvatar, VbenButton } from "../../../shadcn-ui";
|
||||
|
||||
interface Props {
|
||||
avatar?: string;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: "LockScreenModal"
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
avatar: "",
|
||||
text: ""
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
submit: [Recordable<any>];
|
||||
}>();
|
||||
|
||||
const [Form, { resetForm, validate, getValues }] = useVbenForm(
|
||||
reactive({
|
||||
commonConfig: {
|
||||
hideLabel: true,
|
||||
hideRequiredMark: true
|
||||
},
|
||||
schema: computed(() => [
|
||||
{
|
||||
component: "VbenInputPassword" as const,
|
||||
componentProps: {
|
||||
placeholder: $t("ui.widgets.lockScreen.placeholder")
|
||||
},
|
||||
fieldName: "lockScreenPassword",
|
||||
formFieldProps: { validateOnBlur: false },
|
||||
label: $t("authentication.password"),
|
||||
rules: z.string().min(1, { message: $t("ui.widgets.lockScreen.placeholder") })
|
||||
}
|
||||
]),
|
||||
showDefaultActions: false
|
||||
})
|
||||
);
|
||||
|
||||
const [Modal] = useVbenModal({
|
||||
onConfirm() {
|
||||
handleSubmit();
|
||||
},
|
||||
onOpenChange(isOpen) {
|
||||
if (isOpen) {
|
||||
resetForm();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
const { valid } = await validate();
|
||||
const values = await getValues();
|
||||
if (valid) {
|
||||
emit("submit", values?.lockScreenPassword);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :footer="false" :fullscreen-button="false" :title="$t('ui.widgets.lockScreen.title')">
|
||||
<div class="mb-10 flex w-full flex-col items-center px-10" @keydown.enter.prevent="handleSubmit">
|
||||
<div class="w-full">
|
||||
<div class="ml-2 flex w-full flex-col items-center">
|
||||
<VbenAvatar :src="avatar" class="size-20" dot-class="bottom-0 right-1 border-2 size-4 bg-green-500" />
|
||||
<div class="text-foreground my-6 flex items-center font-medium">
|
||||
{{ text }}
|
||||
</div>
|
||||
</div>
|
||||
<Form />
|
||||
<VbenButton class="mt-1 w-full" @click="handleSubmit">
|
||||
{{ $t("ui.widgets.lockScreen.screenButton") }}
|
||||
</VbenButton>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -0,0 +1,131 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref } from "vue";
|
||||
|
||||
import { LockKeyhole } from "../../../icons";
|
||||
import { $t, useI18n } from "../../../locales";
|
||||
import { storeToRefs, useLockStore } from "../../../stores";
|
||||
|
||||
import { useScrollLock } from "../../../composables";
|
||||
import { useVbenForm, z } from "../../../form-ui";
|
||||
import { VbenAvatar, VbenButton } from "../../../shadcn-ui";
|
||||
|
||||
import { useDateFormat, useNow } from "@vueuse/core";
|
||||
|
||||
interface Props {
|
||||
avatar?: string;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: "LockScreen"
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
avatar: ""
|
||||
});
|
||||
|
||||
defineEmits<{ toLogin: [] }>();
|
||||
|
||||
const { locale } = useI18n();
|
||||
const lockStore = useLockStore();
|
||||
|
||||
const now = useNow();
|
||||
const meridiem = useDateFormat(now, "A");
|
||||
const hour = useDateFormat(now, "HH");
|
||||
const minute = useDateFormat(now, "mm");
|
||||
const date = useDateFormat(now, "YYYY-MM-DD dddd", { locales: locale.value });
|
||||
|
||||
const showUnlockForm = ref(false);
|
||||
const { lockScreenPassword } = storeToRefs(lockStore);
|
||||
|
||||
const [Form, { form, validate }] = useVbenForm(
|
||||
reactive({
|
||||
commonConfig: {
|
||||
hideLabel: true,
|
||||
hideRequiredMark: true
|
||||
},
|
||||
schema: computed(() => [
|
||||
{
|
||||
component: "VbenInputPassword" as const,
|
||||
componentProps: {
|
||||
placeholder: $t("ui.widgets.lockScreen.placeholder")
|
||||
},
|
||||
fieldName: "password",
|
||||
label: $t("authentication.password"),
|
||||
rules: z.string().min(1, { message: $t("authentication.passwordTip") })
|
||||
}
|
||||
]),
|
||||
showDefaultActions: false
|
||||
})
|
||||
);
|
||||
|
||||
const validPass = computed(() => lockScreenPassword?.value === form?.values?.password);
|
||||
|
||||
async function handleSubmit() {
|
||||
const { valid } = await validate();
|
||||
if (valid) {
|
||||
if (validPass.value) {
|
||||
lockStore.unlockScreen();
|
||||
} else {
|
||||
form.setFieldError("password", $t("authentication.passwordErrorTip"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleUnlockForm() {
|
||||
showUnlockForm.value = !showUnlockForm.value;
|
||||
}
|
||||
|
||||
useScrollLock();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-background fixed z-[2000] size-full">
|
||||
<transition name="slide-left">
|
||||
<div v-show="!showUnlockForm" class="size-full">
|
||||
<div class="flex-col-center text-foreground/80 hover:text-foreground group my-4 cursor-pointer text-xl font-semibold" @click="toggleUnlockForm">
|
||||
<LockKeyhole class="size-5 transition-all duration-300 group-hover:scale-125" />
|
||||
<span>{{ $t("ui.widgets.lockScreen.unlock") }}</span>
|
||||
</div>
|
||||
<div class="flex h-full justify-center px-[10%]">
|
||||
<div class="bg-accent flex-center relative mb-14 mr-20 h-4/5 w-2/5 flex-auto rounded-3xl text-center text-[260px]">
|
||||
<span class="absolute left-4 top-4 text-xl font-semibold">
|
||||
{{ meridiem }}
|
||||
</span>
|
||||
{{ hour }}
|
||||
</div>
|
||||
<div class="bg-accent flex-center mb-14 h-4/5 w-2/5 flex-auto rounded-3xl text-center text-[260px]">
|
||||
{{ minute }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<transition name="slide-right">
|
||||
<div v-if="showUnlockForm" class="flex-center size-full" @keydown.enter.prevent="handleSubmit">
|
||||
<div class="flex-col-center mb-10 w-[300px]">
|
||||
<VbenAvatar :src="avatar" class="enter-x mb-6 size-20" />
|
||||
|
||||
<div class="enter-x mb-2 w-full items-center">
|
||||
<Form />
|
||||
</div>
|
||||
<VbenButton class="enter-x w-full" @click="handleSubmit">
|
||||
{{ $t("ui.widgets.lockScreen.entry") }}
|
||||
</VbenButton>
|
||||
<VbenButton class="enter-x my-2 w-full" variant="ghost" @click="$emit('toLogin')">
|
||||
{{ $t("ui.widgets.lockScreen.backToLogin") }}
|
||||
</VbenButton>
|
||||
<VbenButton class="enter-x mr-2 w-full" variant="ghost" @click="toggleUnlockForm">
|
||||
{{ $t("common.back") }}
|
||||
</VbenButton>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div class="enter-y absolute bottom-5 w-full text-center xl:text-xl 2xl:text-3xl">
|
||||
<div v-if="showUnlockForm" class="enter-x mb-2 text-3xl">
|
||||
{{ hour }}:{{ minute }} <span class="text-lg">{{ meridiem }}</span>
|
||||
</div>
|
||||
<div class="text-3xl">{{ date }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user