perf: 登录界面重做
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="auth-title mb-9 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<div class="auth-title mb-8 w-full">
|
||||
<h2
|
||||
class="text-foreground mb-2.5 text-3xl font-semibold leading-[1.22] tracking-[-0.015em] lg:text-[2.15rem]"
|
||||
class="text-foreground mb-2.5 text-[1.9rem] font-semibold leading-[1.12] tracking-[-0.03em] sm:text-[2.1rem]"
|
||||
>
|
||||
<slot></slot>
|
||||
</h2>
|
||||
|
||||
<p class="text-muted-foreground text-[0.95rem] leading-7 lg:text-base">
|
||||
<p class="text-muted-foreground max-w-[34rem] text-[0.97rem] leading-7 sm:text-[1rem]">
|
||||
<slot name="desc"></slot>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { Recordable } from '@easyflow/types';
|
||||
import type {Recordable} from '@easyflow/types';
|
||||
|
||||
import type { EasyFlowFormSchema } from '@easyflow-core/form-ui';
|
||||
import type {EasyFlowFormSchema} from '@easyflow-core/form-ui';
|
||||
import {useEasyFlowForm} from '@easyflow-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {computed, reactive} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import { useEasyFlowForm } from '@easyflow-core/form-ui';
|
||||
import { EasyFlowButton } from '@easyflow-core/shadcn-ui';
|
||||
import {$t} from '@easyflow/locales';
|
||||
import {EasyFlowButton} from '@easyflow-core/shadcn-ui';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
@@ -89,10 +88,10 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="auth-code-login">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.welcomeBack') }} 📲
|
||||
{{ title || $t('authentication.welcomeBack') }}
|
||||
</slot>
|
||||
<template #desc>
|
||||
<span class="text-muted-foreground">
|
||||
@@ -102,13 +101,15 @@ defineExpose({
|
||||
</span>
|
||||
</template>
|
||||
</Title>
|
||||
<Form />
|
||||
<div class="auth-form-group">
|
||||
<Form />
|
||||
</div>
|
||||
<EasyFlowButton
|
||||
:class="{
|
||||
'cursor-wait': loading,
|
||||
}"
|
||||
:loading="loading"
|
||||
class="w-full"
|
||||
class="mt-6 h-11 w-full rounded-xl text-base font-medium"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<slot name="submitButtonText">
|
||||
@@ -117,7 +118,7 @@ defineExpose({
|
||||
</EasyFlowButton>
|
||||
<EasyFlowButton
|
||||
v-if="showBack"
|
||||
class="mt-4 w-full"
|
||||
class="mt-3 h-11 w-full rounded-xl"
|
||||
variant="outline"
|
||||
@click="goToLogin()"
|
||||
>
|
||||
@@ -125,3 +126,9 @@ defineExpose({
|
||||
</EasyFlowButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-form-group :deep(.easyflow-form-ui + .easyflow-form-ui) {
|
||||
margin-top: 0.95rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { EasyFlowFormSchema } from '@easyflow-core/form-ui';
|
||||
import type {EasyFlowFormSchema} from '@easyflow-core/form-ui';
|
||||
import {useEasyFlowForm} from '@easyflow-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {computed, reactive} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import { useEasyFlowForm } from '@easyflow-core/form-ui';
|
||||
import { EasyFlowButton } from '@easyflow-core/shadcn-ui';
|
||||
import {$t} from '@easyflow/locales';
|
||||
import {EasyFlowButton} from '@easyflow-core/shadcn-ui';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
@@ -82,10 +81,10 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="auth-forget-password">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.forgetPassword') }} 🤦🏻♂️
|
||||
{{ title || $t('authentication.forgetPassword') }}
|
||||
</slot>
|
||||
<template #desc>
|
||||
<slot name="subTitle">
|
||||
@@ -93,7 +92,9 @@ defineExpose({
|
||||
</slot>
|
||||
</template>
|
||||
</Title>
|
||||
<Form />
|
||||
<div class="auth-form-group">
|
||||
<Form />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<EasyFlowButton
|
||||
@@ -101,16 +102,26 @@ defineExpose({
|
||||
'cursor-wait': loading,
|
||||
}"
|
||||
aria-label="submit"
|
||||
class="mt-2 w-full"
|
||||
class="mt-6 h-11 w-full rounded-xl text-base font-medium"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<slot name="submitButtonText">
|
||||
{{ submitButtonText || $t('authentication.sendResetLink') }}
|
||||
</slot>
|
||||
</EasyFlowButton>
|
||||
<EasyFlowButton class="mt-4 w-full" variant="outline" @click="goToLogin()">
|
||||
<EasyFlowButton
|
||||
class="mt-3 h-11 w-full rounded-xl"
|
||||
variant="outline"
|
||||
@click="goToLogin()"
|
||||
>
|
||||
{{ $t('common.back') }}
|
||||
</EasyFlowButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-form-group :deep(.easyflow-form-ui + .easyflow-form-ui) {
|
||||
margin-top: 0.95rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { Recordable } from '@easyflow/types';
|
||||
import type {Recordable} from '@easyflow/types';
|
||||
|
||||
import type { EasyFlowFormSchema } from '@easyflow-core/form-ui';
|
||||
import type {EasyFlowFormSchema} from '@easyflow-core/form-ui';
|
||||
import {useEasyFlowForm} from '@easyflow-core/form-ui';
|
||||
|
||||
import type { AuthenticationProps } from './types';
|
||||
import type {AuthenticationProps} from './types';
|
||||
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {computed, onMounted, reactive, ref} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import { useEasyFlowForm } from '@easyflow-core/form-ui';
|
||||
import { EasyFlowButton, EasyFlowCheckbox } from '@easyflow-core/shadcn-ui';
|
||||
import {$t} from '@easyflow/locales';
|
||||
import {EasyFlowButton, EasyFlowCheckbox} from '@easyflow-core/shadcn-ui';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
import ThirdPartyLogin from './third-party-login.vue';
|
||||
@@ -33,6 +32,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
registerPath: '/auth/register',
|
||||
showCodeLogin: false,
|
||||
showForgetPassword: false,
|
||||
showHeader: true,
|
||||
showQrcodeLogin: false,
|
||||
showRegister: false,
|
||||
showRememberMe: false,
|
||||
@@ -58,11 +58,9 @@ const [Form, formApi] = useEasyFlowForm(
|
||||
);
|
||||
const router = useRouter();
|
||||
|
||||
const REMEMBER_ME_KEY = `REMEMBER_ME_USERNAME_${location.hostname}`;
|
||||
|
||||
const localUsername = localStorage.getItem(REMEMBER_ME_KEY) || '';
|
||||
|
||||
const rememberMe = ref(!!localUsername);
|
||||
const REMEMBER_ME_KEY = `REMEMBER_ME_ACCOUNT_${location.hostname}`;
|
||||
const localAccount = localStorage.getItem(REMEMBER_ME_KEY) || '';
|
||||
const rememberMe = ref(!!localAccount);
|
||||
|
||||
async function handleSubmit() {
|
||||
const { valid } = await formApi.validate();
|
||||
@@ -70,7 +68,7 @@ async function handleSubmit() {
|
||||
if (valid) {
|
||||
localStorage.setItem(
|
||||
REMEMBER_ME_KEY,
|
||||
rememberMe.value ? values?.username : '',
|
||||
rememberMe.value ? (values?.account ?? '') : '',
|
||||
);
|
||||
emit('submit', values);
|
||||
}
|
||||
@@ -81,8 +79,8 @@ function handleGo(path: string) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (localUsername) {
|
||||
formApi.setFieldValue('username', localUsername);
|
||||
if (localAccount) {
|
||||
formApi.setFieldValue('account', localAccount);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -93,65 +91,69 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<div class="auth-login" @keydown.enter.prevent="handleSubmit">
|
||||
<slot name="title">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.welcomeBack') }}
|
||||
</slot>
|
||||
<template #desc>
|
||||
<span class="text-muted-foreground">
|
||||
<slot name="subTitle">
|
||||
{{ subTitle || $t('authentication.loginSubtitle') }}
|
||||
</slot>
|
||||
</span>
|
||||
</template>
|
||||
</Title>
|
||||
</slot>
|
||||
<template v-if="showHeader">
|
||||
<slot name="title">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.welcomeBack') }}
|
||||
</slot>
|
||||
<template v-if="subTitle || $t('authentication.loginSubtitle')" #desc>
|
||||
<span class="text-muted-foreground">
|
||||
<slot name="subTitle">
|
||||
{{ subTitle || $t('authentication.loginSubtitle') }}
|
||||
</slot>
|
||||
</span>
|
||||
</template>
|
||||
</Title>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<Form />
|
||||
<div class="auth-form-group">
|
||||
<Form />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="showRememberMe || showForgetPassword"
|
||||
class="auth-login-options mb-7 mt-2 flex justify-between"
|
||||
class="auth-login-options mt-1 flex items-center justify-between gap-3"
|
||||
>
|
||||
<div class="flex-center">
|
||||
<EasyFlowCheckbox
|
||||
v-if="showRememberMe"
|
||||
v-model="rememberMe"
|
||||
name="rememberMe"
|
||||
>
|
||||
{{ $t('authentication.rememberMe') }}
|
||||
</EasyFlowCheckbox>
|
||||
</div>
|
||||
<EasyFlowCheckbox
|
||||
v-if="showRememberMe"
|
||||
v-model="rememberMe"
|
||||
class="auth-checkbox"
|
||||
name="rememberMe"
|
||||
>
|
||||
{{ $t('authentication.rememberMe') }}
|
||||
</EasyFlowCheckbox>
|
||||
|
||||
<span
|
||||
<button
|
||||
v-if="showForgetPassword"
|
||||
class="easyflow-link text-sm font-normal"
|
||||
class="auth-inline-action"
|
||||
type="button"
|
||||
@click="handleGo(forgetPasswordPath)"
|
||||
>
|
||||
{{ $t('authentication.forgetPassword') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<EasyFlowButton
|
||||
:class="{
|
||||
'cursor-wait': loading,
|
||||
}"
|
||||
:class="{ 'cursor-wait': loading }"
|
||||
:loading="loading"
|
||||
aria-label="login"
|
||||
class="auth-submit-button h-11 w-full rounded-xl text-base font-medium"
|
||||
class="auth-submit-button auth-brand-submit mt-6 h-11 w-full rounded-xl text-base font-medium"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
{{ submitButtonText || $t('common.login') }}
|
||||
</EasyFlowButton>
|
||||
|
||||
<slot name="overlay"></slot>
|
||||
|
||||
<div
|
||||
v-if="showCodeLogin || showQrcodeLogin"
|
||||
class="auth-login-quick mb-2 mt-5 flex items-center justify-between"
|
||||
class="auth-alt-modes mt-5 grid gap-3 sm:grid-cols-2"
|
||||
>
|
||||
<EasyFlowButton
|
||||
v-if="showCodeLogin"
|
||||
class="w-1/2"
|
||||
class="auth-secondary-button h-11 w-full rounded-xl"
|
||||
variant="outline"
|
||||
@click="handleGo(codeLoginPath)"
|
||||
>
|
||||
@@ -159,7 +161,7 @@ defineExpose({
|
||||
</EasyFlowButton>
|
||||
<EasyFlowButton
|
||||
v-if="showQrcodeLogin"
|
||||
class="ml-4 w-1/2"
|
||||
class="auth-secondary-button h-11 w-full rounded-xl"
|
||||
variant="outline"
|
||||
@click="handleGo(qrCodeLoginPath)"
|
||||
>
|
||||
@@ -172,21 +174,113 @@ defineExpose({
|
||||
</slot>
|
||||
|
||||
<slot name="to-register">
|
||||
<div v-if="showRegister" class="mt-4 text-center text-sm">
|
||||
<div v-if="showRegister" class="auth-footer-copy mt-5 text-center text-sm">
|
||||
{{ $t('authentication.accountTip') }}
|
||||
<span
|
||||
class="easyflow-link text-sm font-normal"
|
||||
<button
|
||||
class="auth-inline-action"
|
||||
type="button"
|
||||
@click="handleGo(registerPath)"
|
||||
>
|
||||
{{ $t('authentication.createAccount') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-login :deep(.easyflow-form-ui + .easyflow-form-ui) {
|
||||
.auth-login {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.auth-form-group :deep(.easyflow-form-ui + .easyflow-form-ui) {
|
||||
margin-top: 0.95rem;
|
||||
}
|
||||
|
||||
.auth-form-group :deep(.easyflow-form-ui .text-destructive) {
|
||||
font-size: 0.84rem;
|
||||
margin-top: 0.45rem;
|
||||
}
|
||||
|
||||
.auth-login-options {
|
||||
min-height: 1.5rem;
|
||||
}
|
||||
|
||||
.auth-checkbox {
|
||||
color: hsl(var(--text-muted));
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.auth-inline-action {
|
||||
color: hsl(var(--nav-item-active-foreground));
|
||||
font-size: 0.92rem;
|
||||
font-weight: 500;
|
||||
transition: opacity 0.18s ease;
|
||||
}
|
||||
|
||||
.auth-inline-action:hover {
|
||||
opacity: 0.76;
|
||||
}
|
||||
|
||||
.auth-secondary-button {
|
||||
background: hsl(var(--surface-elevated));
|
||||
border-color: hsl(var(--line-subtle));
|
||||
}
|
||||
|
||||
.auth-brand-submit {
|
||||
background:
|
||||
linear-gradient(
|
||||
120deg,
|
||||
rgb(11 111 211) 0%,
|
||||
rgb(22 159 200) 38%,
|
||||
rgb(38 199 193) 62%,
|
||||
rgb(11 111 211) 100%
|
||||
);
|
||||
background-size: 200% 200%;
|
||||
border: none;
|
||||
box-shadow:
|
||||
0 22px 34px -22px rgb(11 111 211 / 0.56),
|
||||
inset 0 1px 0 rgb(255 255 255 / 0.24);
|
||||
color: rgb(255 255 255);
|
||||
transition:
|
||||
transform 180ms ease,
|
||||
box-shadow 180ms ease,
|
||||
filter 180ms ease;
|
||||
animation: auth-brand-gradient 6s ease infinite;
|
||||
}
|
||||
|
||||
.auth-brand-submit:hover {
|
||||
box-shadow:
|
||||
0 24px 38px -22px rgb(11 111 211 / 0.62),
|
||||
inset 0 1px 0 rgb(255 255 255 / 0.28);
|
||||
filter: saturate(1.04);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.auth-brand-submit:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.auth-brand-submit:focus-visible {
|
||||
outline: 2px solid rgb(78 176 255 / 0.8);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.auth-footer-copy {
|
||||
color: hsl(var(--text-muted));
|
||||
}
|
||||
|
||||
@keyframes auth-brand-gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {ref} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
import {$t} from '@easyflow/locales';
|
||||
|
||||
import { EasyFlowButton } from '@easyflow-core/shadcn-ui';
|
||||
import {EasyFlowButton} from '@easyflow-core/shadcn-ui';
|
||||
|
||||
import { useQRCode } from '@vueuse/integrations/useQRCode';
|
||||
import {useQRCode} from '@vueuse/integrations/useQRCode';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
@@ -70,10 +70,10 @@ function goToLogin() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="auth-qrcode-login">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.welcomeBack') }} 📱
|
||||
{{ title || $t('authentication.welcomeBack') }}
|
||||
</slot>
|
||||
<template #desc>
|
||||
<span class="text-muted-foreground">
|
||||
@@ -84,9 +84,11 @@ function goToLogin() {
|
||||
</template>
|
||||
</Title>
|
||||
|
||||
<div class="flex-col-center mt-6">
|
||||
<img :src="qrcode" alt="qrcode" class="w-1/2" />
|
||||
<p class="text-muted-foreground mt-4 text-sm">
|
||||
<div class="auth-qrcode-panel mt-6">
|
||||
<div class="auth-qrcode-frame">
|
||||
<img :src="qrcode" alt="qrcode" class="auth-qrcode-image" />
|
||||
</div>
|
||||
<p class="text-muted-foreground mt-4 text-sm leading-6">
|
||||
<slot name="description">
|
||||
{{ description || $t('authentication.qrcodePrompt') }}
|
||||
</slot>
|
||||
@@ -95,7 +97,7 @@ function goToLogin() {
|
||||
|
||||
<EasyFlowButton
|
||||
v-if="showBack"
|
||||
class="mt-4 w-full"
|
||||
class="mt-6 h-11 w-full rounded-xl"
|
||||
variant="outline"
|
||||
@click="goToLogin()"
|
||||
>
|
||||
@@ -103,3 +105,32 @@ function goToLogin() {
|
||||
</EasyFlowButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-qrcode-panel {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.auth-qrcode-frame {
|
||||
align-items: center;
|
||||
background: linear-gradient(180deg, rgb(255 255 255 / 0.92), rgb(244 249 255 / 0.96));
|
||||
border: 1px solid hsl(var(--line-subtle));
|
||||
border-radius: 1.5rem;
|
||||
box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.6);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
max-width: 17rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.auth-qrcode-image {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 1rem;
|
||||
width: min(100%, 13rem);
|
||||
}
|
||||
|
||||
.dark .auth-qrcode-frame {
|
||||
background: linear-gradient(180deg, rgb(14 22 36 / 0.92), rgb(11 19 31 / 0.96));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { Recordable } from '@easyflow/types';
|
||||
import type {Recordable} from '@easyflow/types';
|
||||
|
||||
import type { EasyFlowFormSchema } from '@easyflow-core/form-ui';
|
||||
import type {EasyFlowFormSchema} from '@easyflow-core/form-ui';
|
||||
import {useEasyFlowForm} from '@easyflow-core/form-ui';
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {computed, reactive} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import { useEasyFlowForm } from '@easyflow-core/form-ui';
|
||||
import { EasyFlowButton } from '@easyflow-core/shadcn-ui';
|
||||
import {$t} from '@easyflow/locales';
|
||||
import {EasyFlowButton} from '@easyflow-core/shadcn-ui';
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
|
||||
@@ -85,10 +84,10 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="auth-register">
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.createAnAccount') }} 🚀
|
||||
{{ title || $t('authentication.createAnAccount') }}
|
||||
</slot>
|
||||
<template #desc>
|
||||
<slot name="subTitle">
|
||||
@@ -96,7 +95,9 @@ defineExpose({
|
||||
</slot>
|
||||
</template>
|
||||
</Title>
|
||||
<Form />
|
||||
<div class="auth-form-group">
|
||||
<Form />
|
||||
</div>
|
||||
|
||||
<EasyFlowButton
|
||||
:class="{
|
||||
@@ -104,18 +105,35 @@ defineExpose({
|
||||
}"
|
||||
:loading="loading"
|
||||
aria-label="register"
|
||||
class="mt-2 w-full"
|
||||
class="mt-6 h-11 w-full rounded-xl text-base font-medium"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<slot name="submitButtonText">
|
||||
{{ submitButtonText || $t('authentication.signUp') }}
|
||||
</slot>
|
||||
</EasyFlowButton>
|
||||
<div class="mt-4 text-center text-sm">
|
||||
<div class="mt-5 text-center text-sm text-[hsl(var(--text-muted))]">
|
||||
{{ $t('authentication.alreadyHaveAccount') }}
|
||||
<span class="easyflow-link text-sm font-normal" @click="goToLogin()">
|
||||
<button class="auth-inline-action" type="button" @click="goToLogin()">
|
||||
{{ $t('authentication.goToLogin') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.auth-form-group :deep(.easyflow-form-ui + .easyflow-form-ui) {
|
||||
margin-top: 0.95rem;
|
||||
}
|
||||
|
||||
.auth-inline-action {
|
||||
color: hsl(var(--nav-item-active-foreground));
|
||||
font-size: 0.92rem;
|
||||
font-weight: 500;
|
||||
transition: opacity 0.18s ease;
|
||||
}
|
||||
|
||||
.auth-inline-action:hover {
|
||||
opacity: 0.76;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,6 +52,11 @@ interface AuthenticationProps {
|
||||
*/
|
||||
showThirdPartyLogin?: boolean;
|
||||
|
||||
/**
|
||||
* @zh_CN 是否显示登录头部
|
||||
*/
|
||||
showHeader?: boolean;
|
||||
|
||||
/**
|
||||
* @zh_CN 登录框子标题
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user