mirror of https://github.com/halo-dev/halo
refactor: layout of login related page (#5413)
#### What type of PR is this? /area ui /kind improvement /milestone 2.13.0 #### What this PR does / why we need it: 优化登录相关页面的布局,修复在不同分辨率下的样式问题。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/5346 #### Special notes for your reviewer: 测试登录或者注册页面,任意放大或者缩小页面,观察页面样式是否正常。 #### Does this PR introduce a user-facing change? ```release-note 优化登录相关页面的布局,修复在不同分辨率下的样式问题。 ```pull/5422/head^2
parent
2bfa20d316
commit
827030dd68
|
@ -0,0 +1,13 @@
|
|||
<script lang="ts" setup>
|
||||
import IconLogo from "~icons/core/logo?width=5rem&height=2rem";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex h-screen flex-col items-center overflow-auto bg-white/90 pt-[30vh]"
|
||||
>
|
||||
<IconLogo class="mb-8 flex-none" />
|
||||
|
||||
<RouterView />
|
||||
</div>
|
||||
</template>
|
|
@ -1,98 +0,0 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, watch } from "vue";
|
||||
import IconLogo from "~icons/core/logo?width=5rem&height=2rem";
|
||||
import LoginForm from "@/components/login/LoginForm.vue";
|
||||
import { useRouteQuery } from "@vueuse/router";
|
||||
import SignupForm from "@/components/signup/SignupForm.vue";
|
||||
import SocialAuthProviders from "@/components/login/SocialAuthProviders.vue";
|
||||
import { useGlobalInfoFetch } from "@console/composables/use-global-info";
|
||||
import { useTitle } from "@vueuse/core";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AppName } from "@/constants/app";
|
||||
import MdiKeyboardBackspace from "~icons/mdi/keyboard-backspace";
|
||||
import LocaleChange from "@/components/common/LocaleChange.vue";
|
||||
|
||||
const { globalInfo } = useGlobalInfoFetch();
|
||||
const { t } = useI18n();
|
||||
|
||||
const SIGNUP_TYPE = "signup";
|
||||
|
||||
function onLoginSucceed() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function onSignupSucceed() {
|
||||
window.location.href = "/uc";
|
||||
}
|
||||
|
||||
const type = useRouteQuery<string>("type", "");
|
||||
|
||||
function handleChangeType() {
|
||||
type.value = type.value === SIGNUP_TYPE ? "" : SIGNUP_TYPE;
|
||||
}
|
||||
|
||||
const isLoginType = computed(() => type.value !== SIGNUP_TYPE);
|
||||
|
||||
// page title
|
||||
const title = useTitle();
|
||||
watch(
|
||||
() => type.value,
|
||||
(value) => {
|
||||
const routeTitle = t(
|
||||
`core.${value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
|
||||
);
|
||||
title.value = [routeTitle, AppName].join(" - ");
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center bg-white/90 pt-[30vh]">
|
||||
<IconLogo class="mb-8" />
|
||||
<div class="flex w-72 flex-col">
|
||||
<SignupForm v-if="type === 'signup'" @succeed="onSignupSucceed" />
|
||||
<LoginForm v-else @succeed="onLoginSucceed" />
|
||||
<SocialAuthProviders />
|
||||
<div class="flex justify-center gap-2 pt-3.5 text-xs">
|
||||
<div v-if="globalInfo?.allowRegistration" class="space-x-0.5">
|
||||
<span class="text-slate-500">
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.label")
|
||||
: $t("core.login.operations.return_login.label")
|
||||
}},
|
||||
</span>
|
||||
<span
|
||||
class="cursor-pointer text-secondary hover:text-gray-600"
|
||||
@click="handleChangeType"
|
||||
>
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.button")
|
||||
: $t("core.login.operations.return_login.button")
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="{ name: 'ResetPassword' }"
|
||||
class="text-secondary hover:text-gray-600"
|
||||
>
|
||||
{{ $t("core.login.operations.reset_password.button") }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="flex justify-center pt-3.5">
|
||||
<a
|
||||
class="inline-flex items-center gap-0.5 text-xs text-gray-600 hover:text-gray-900"
|
||||
href="/"
|
||||
>
|
||||
<MdiKeyboardBackspace class="!h-3.5 !w-3.5" />
|
||||
<span> {{ $t("core.login.operations.return_site") }} </span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bottom-0 mb-10 mt-auto flex items-center justify-center gap-2.5"
|
||||
>
|
||||
<LocaleChange />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -3,10 +3,8 @@ import BasicLayout from "@console/layouts/BasicLayout.vue";
|
|||
import UserStatsWidget from "./widgets/UserStatsWidget.vue";
|
||||
import UserList from "./UserList.vue";
|
||||
import UserDetail from "./UserDetail.vue";
|
||||
import Login from "./Login.vue";
|
||||
import { IconUserSettings } from "@halo-dev/components";
|
||||
import { markRaw } from "vue";
|
||||
import Binding from "./Binding.vue";
|
||||
import NotificationWidget from "./widgets/NotificationWidget.vue";
|
||||
|
||||
export default definePlugin({
|
||||
|
@ -15,22 +13,6 @@ export default definePlugin({
|
|||
NotificationWidget,
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
component: Login,
|
||||
meta: {
|
||||
title: "core.login.title",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/binding/:provider",
|
||||
name: "Binding",
|
||||
component: Binding,
|
||||
meta: {
|
||||
title: "core.binding.title",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/users",
|
||||
name: "UsersRoot",
|
||||
|
|
|
@ -2,10 +2,13 @@ import type { RouteRecordRaw } from "vue-router";
|
|||
import NotFound from "@/views/exceptions/NotFound.vue";
|
||||
import Forbidden from "@/views/exceptions/Forbidden.vue";
|
||||
import BasicLayout from "@console/layouts/BasicLayout.vue";
|
||||
import GatewayLayout from "@console/layouts/GatewayLayout.vue";
|
||||
import Setup from "@console/views/system/Setup.vue";
|
||||
import Redirect from "@console/views/system/Redirect.vue";
|
||||
import SetupInitialData from "@console/views/system/SetupInitialData.vue";
|
||||
import ResetPassword from "@console/views/system/ResetPassword.vue";
|
||||
import Login from "@console/views/system/Login.vue";
|
||||
import Binding from "@console/views/system/Binding.vue";
|
||||
|
||||
export const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
|
@ -24,13 +27,47 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
component: GatewayLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Login",
|
||||
component: Login,
|
||||
meta: {
|
||||
title: "core.login.title",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/binding/:provider",
|
||||
component: GatewayLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Binding",
|
||||
component: Binding,
|
||||
meta: {
|
||||
title: "core.binding.title",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/setup",
|
||||
name: "Setup",
|
||||
component: Setup,
|
||||
meta: {
|
||||
title: "core.setup.title",
|
||||
},
|
||||
component: GatewayLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Setup",
|
||||
component: Setup,
|
||||
meta: {
|
||||
title: "core.setup.title",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/setup-initial-data",
|
||||
|
@ -47,11 +84,17 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
},
|
||||
{
|
||||
path: "/reset-password",
|
||||
name: "ResetPassword",
|
||||
component: ResetPassword,
|
||||
meta: {
|
||||
title: "core.reset_password.title",
|
||||
},
|
||||
component: GatewayLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "ResetPassword",
|
||||
component: ResetPassword,
|
||||
meta: {
|
||||
title: "core.reset_password.title",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, onBeforeMount, onMounted } from "vue";
|
||||
import router from "@console/router";
|
||||
import IconLogo from "~icons/core/logo?width=5rem&height=2rem";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import LoginForm from "@/components/login/LoginForm.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
@ -51,41 +50,38 @@ function handleChangeType() {
|
|||
const isLoginType = computed(() => type.value !== "signup");
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center bg-white/90 pt-[30vh]">
|
||||
<IconLogo class="mb-8" />
|
||||
<div class="flex w-72 flex-col">
|
||||
<SignupForm
|
||||
v-if="type === 'signup'"
|
||||
button-text="core.binding.operations.signup_and_bind.button"
|
||||
@succeed="handleBinding"
|
||||
/>
|
||||
<LoginForm
|
||||
v-else
|
||||
button-text="core.binding.operations.login_and_bind.button"
|
||||
@succeed="handleBinding"
|
||||
/>
|
||||
<div
|
||||
v-if="globalInfo?.allowRegistration"
|
||||
class="flex justify-center gap-1 pt-3.5 text-xs"
|
||||
<div class="flex w-72 flex-col">
|
||||
<SignupForm
|
||||
v-if="type === 'signup'"
|
||||
button-text="core.binding.operations.signup_and_bind.button"
|
||||
@succeed="handleBinding"
|
||||
/>
|
||||
<LoginForm
|
||||
v-else
|
||||
button-text="core.binding.operations.login_and_bind.button"
|
||||
@succeed="handleBinding"
|
||||
/>
|
||||
<div
|
||||
v-if="globalInfo?.allowRegistration"
|
||||
class="flex justify-center gap-1 pt-3.5 text-xs"
|
||||
>
|
||||
<span class="text-slate-500">
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.label")
|
||||
: $t("core.login.operations.return_login.label")
|
||||
}}
|
||||
</span>
|
||||
<span
|
||||
class="cursor-pointer text-secondary hover:text-gray-600"
|
||||
@click="handleChangeType"
|
||||
>
|
||||
<span class="text-slate-500">
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.label")
|
||||
: $t("core.login.operations.return_login.label")
|
||||
}}
|
||||
</span>
|
||||
<span
|
||||
class="cursor-pointer text-secondary hover:text-gray-600"
|
||||
@click="handleChangeType"
|
||||
>
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.button")
|
||||
: $t("core.login.operations.return_login.button")
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.button")
|
||||
: $t("core.login.operations.return_login.button")
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,94 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, watch } from "vue";
|
||||
import LoginForm from "@/components/login/LoginForm.vue";
|
||||
import { useRouteQuery } from "@vueuse/router";
|
||||
import SignupForm from "@/components/signup/SignupForm.vue";
|
||||
import SocialAuthProviders from "@/components/login/SocialAuthProviders.vue";
|
||||
import { useGlobalInfoFetch } from "@console/composables/use-global-info";
|
||||
import { useTitle } from "@vueuse/core";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AppName } from "@/constants/app";
|
||||
import MdiKeyboardBackspace from "~icons/mdi/keyboard-backspace";
|
||||
import LocaleChange from "@/components/common/LocaleChange.vue";
|
||||
|
||||
const { globalInfo } = useGlobalInfoFetch();
|
||||
const { t } = useI18n();
|
||||
|
||||
const SIGNUP_TYPE = "signup";
|
||||
|
||||
function onLoginSucceed() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function onSignupSucceed() {
|
||||
window.location.href = "/uc";
|
||||
}
|
||||
|
||||
const type = useRouteQuery<string>("type", "");
|
||||
|
||||
function handleChangeType() {
|
||||
type.value = type.value === SIGNUP_TYPE ? "" : SIGNUP_TYPE;
|
||||
}
|
||||
|
||||
const isLoginType = computed(() => type.value !== SIGNUP_TYPE);
|
||||
|
||||
// page title
|
||||
const title = useTitle();
|
||||
watch(
|
||||
() => type.value,
|
||||
(value) => {
|
||||
const routeTitle = t(
|
||||
`core.${value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
|
||||
);
|
||||
title.value = [routeTitle, AppName].join(" - ");
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex w-72 flex-col">
|
||||
<SignupForm v-if="type === 'signup'" @succeed="onSignupSucceed" />
|
||||
<LoginForm v-else @succeed="onLoginSucceed" />
|
||||
<SocialAuthProviders />
|
||||
<div class="flex justify-center gap-2 pt-3.5 text-xs">
|
||||
<div v-if="globalInfo?.allowRegistration" class="space-x-0.5">
|
||||
<span class="text-slate-500">
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.label")
|
||||
: $t("core.login.operations.return_login.label")
|
||||
}},
|
||||
</span>
|
||||
<span
|
||||
class="cursor-pointer text-secondary hover:text-gray-600"
|
||||
@click="handleChangeType"
|
||||
>
|
||||
{{
|
||||
isLoginType
|
||||
? $t("core.login.operations.signup.button")
|
||||
: $t("core.login.operations.return_login.button")
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<RouterLink
|
||||
:to="{ name: 'ResetPassword' }"
|
||||
class="text-secondary hover:text-gray-600"
|
||||
>
|
||||
{{ $t("core.login.operations.reset_password.button") }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="flex justify-center pt-3.5">
|
||||
<a
|
||||
class="inline-flex items-center gap-0.5 text-xs text-gray-600 hover:text-gray-900"
|
||||
href="/"
|
||||
>
|
||||
<MdiKeyboardBackspace class="!h-3.5 !w-3.5" />
|
||||
<span> {{ $t("core.login.operations.return_site") }} </span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bottom-0 mb-10 mt-auto flex items-center justify-center gap-2.5 pt-3.5"
|
||||
>
|
||||
<LocaleChange />
|
||||
</div>
|
||||
</template>
|
|
@ -3,7 +3,6 @@ import { apiClient } from "@/utils/api-client";
|
|||
import { Toast, VButton } from "@halo-dev/components";
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import IconLogo from "~icons/core/logo?width=5rem&height=2rem";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -38,48 +37,45 @@ const inputClasses = {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center bg-white/90 pt-[30vh]">
|
||||
<IconLogo class="mb-8" />
|
||||
<div class="flex w-72 flex-col">
|
||||
<div class="flex w-72 flex-col">
|
||||
<FormKit
|
||||
id="reset-password-form"
|
||||
name="reset-password-form"
|
||||
type="form"
|
||||
:classes="{
|
||||
form: '!divide-none',
|
||||
}"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="onSubmit"
|
||||
@keyup.enter="$formkit.submit('reset-password-form')"
|
||||
>
|
||||
<FormKit
|
||||
id="reset-password-form"
|
||||
name="reset-password-form"
|
||||
type="form"
|
||||
:classes="{
|
||||
form: '!divide-none',
|
||||
}"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
@submit="onSubmit"
|
||||
@keyup.enter="$formkit.submit('reset-password-form')"
|
||||
>
|
||||
<FormKit
|
||||
:classes="inputClasses"
|
||||
name="username"
|
||||
:placeholder="$t('core.reset_password.fields.username.label')"
|
||||
:validation-label="$t('core.reset_password.fields.username.label')"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
:classes="inputClasses"
|
||||
name="email"
|
||||
:placeholder="$t('core.reset_password.fields.email.label')"
|
||||
:validation-label="$t('core.reset_password.fields.email.label')"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
<VButton
|
||||
class="mt-8"
|
||||
block
|
||||
:loading="loading"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('reset-password-form')"
|
||||
>
|
||||
{{ $t("core.reset_password.operations.send.label") }}
|
||||
</VButton>
|
||||
</div>
|
||||
:classes="inputClasses"
|
||||
name="username"
|
||||
:placeholder="$t('core.reset_password.fields.username.label')"
|
||||
:validation-label="$t('core.reset_password.fields.username.label')"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
:classes="inputClasses"
|
||||
name="email"
|
||||
:placeholder="$t('core.reset_password.fields.email.label')"
|
||||
:validation-label="$t('core.reset_password.fields.email.label')"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
validation="required"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
<VButton
|
||||
class="mt-8"
|
||||
block
|
||||
:loading="loading"
|
||||
type="secondary"
|
||||
@click="$formkit.submit('reset-password-form')"
|
||||
>
|
||||
{{ $t("core.reset_password.operations.send.label") }}
|
||||
</VButton>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
import IconLogo from "~icons/core/logo?width=5rem&height=2rem";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
import { Toast, VButton } from "@halo-dev/components";
|
||||
import { ref } from "vue";
|
||||
|
@ -44,87 +43,82 @@ const inputClasses = {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center bg-white/90 pt-[30vh]">
|
||||
<IconLogo class="mb-8" />
|
||||
<div class="flex w-72 flex-col">
|
||||
<FormKit
|
||||
id="setup-form"
|
||||
v-model="formState"
|
||||
name="setup-form"
|
||||
:actions="false"
|
||||
:classes="{
|
||||
form: '!divide-none',
|
||||
}"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleSubmit"
|
||||
@keyup.enter="$formkit.submit('setup-form')"
|
||||
>
|
||||
<FormKit
|
||||
name="siteTitle"
|
||||
:classes="inputClasses"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.site_title.label')"
|
||||
:placeholder="$t('core.setup.fields.site_title.label')"
|
||||
validation="required:trim|length:0,100"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="email"
|
||||
:classes="inputClasses"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.email.label')"
|
||||
:placeholder="$t('core.setup.fields.email.label')"
|
||||
validation="required|email|length:0,100"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="username"
|
||||
:classes="inputClasses"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.username.label')"
|
||||
:placeholder="$t('core.setup.fields.username.label')"
|
||||
:validation="[
|
||||
['required'],
|
||||
['length:0,63'],
|
||||
[
|
||||
'matches',
|
||||
/^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/,
|
||||
],
|
||||
]"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="password"
|
||||
:classes="inputClasses"
|
||||
type="password"
|
||||
:validation-label="$t('core.setup.fields.password.label')"
|
||||
:placeholder="$t('core.setup.fields.password.label')"
|
||||
validation="required:trim|length:5,100|matches:/^\S.*\S$/"
|
||||
autocomplete="current-password"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="password_confirm"
|
||||
:classes="inputClasses"
|
||||
type="password"
|
||||
:validation-label="$t('core.setup.fields.confirm_password.label')"
|
||||
:placeholder="$t('core.setup.fields.confirm_password.label')"
|
||||
validation="confirm|required:trim|length:5,100|matches:/^\S.*\S$/"
|
||||
autocomplete="current-password"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
<VButton
|
||||
block
|
||||
class="mt-8"
|
||||
type="secondary"
|
||||
:loading="loading"
|
||||
@click="$formkit.submit('setup-form')"
|
||||
>
|
||||
{{ $t("core.setup.operations.submit.button") }}
|
||||
</VButton>
|
||||
</div>
|
||||
<div
|
||||
class="bottom-0 mb-10 mt-auto flex items-center justify-center gap-2.5"
|
||||
<div class="flex w-72 flex-col">
|
||||
<FormKit
|
||||
id="setup-form"
|
||||
v-model="formState"
|
||||
name="setup-form"
|
||||
:actions="false"
|
||||
:classes="{
|
||||
form: '!divide-none',
|
||||
}"
|
||||
:config="{ validationVisibility: 'submit' }"
|
||||
type="form"
|
||||
@submit="handleSubmit"
|
||||
@keyup.enter="$formkit.submit('setup-form')"
|
||||
>
|
||||
<LocaleChange />
|
||||
</div>
|
||||
<FormKit
|
||||
name="siteTitle"
|
||||
:classes="inputClasses"
|
||||
:autofocus="true"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.site_title.label')"
|
||||
:placeholder="$t('core.setup.fields.site_title.label')"
|
||||
validation="required:trim|length:0,100"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="email"
|
||||
:classes="inputClasses"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.email.label')"
|
||||
:placeholder="$t('core.setup.fields.email.label')"
|
||||
validation="required|email|length:0,100"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="username"
|
||||
:classes="inputClasses"
|
||||
type="text"
|
||||
:validation-label="$t('core.setup.fields.username.label')"
|
||||
:placeholder="$t('core.setup.fields.username.label')"
|
||||
:validation="[
|
||||
['required'],
|
||||
['length:0,63'],
|
||||
[
|
||||
'matches',
|
||||
/^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/,
|
||||
],
|
||||
]"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="password"
|
||||
:classes="inputClasses"
|
||||
type="password"
|
||||
:validation-label="$t('core.setup.fields.password.label')"
|
||||
:placeholder="$t('core.setup.fields.password.label')"
|
||||
validation="required:trim|length:5,100|matches:/^\S.*\S$/"
|
||||
autocomplete="current-password"
|
||||
></FormKit>
|
||||
<FormKit
|
||||
name="password_confirm"
|
||||
:classes="inputClasses"
|
||||
type="password"
|
||||
:validation-label="$t('core.setup.fields.confirm_password.label')"
|
||||
:placeholder="$t('core.setup.fields.confirm_password.label')"
|
||||
validation="confirm|required:trim|length:5,100|matches:/^\S.*\S$/"
|
||||
autocomplete="current-password"
|
||||
></FormKit>
|
||||
</FormKit>
|
||||
<VButton
|
||||
block
|
||||
class="mt-8"
|
||||
type="secondary"
|
||||
:loading="loading"
|
||||
@click="$formkit.submit('setup-form')"
|
||||
>
|
||||
{{ $t("core.setup.operations.submit.button") }}
|
||||
</VButton>
|
||||
</div>
|
||||
<div class="bottom-0 mb-10 mt-auto flex items-center justify-center gap-2.5">
|
||||
<LocaleChange />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -46,8 +46,10 @@ const inputClasses = {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-screen flex-col items-center bg-white/90 pt-[30vh]">
|
||||
<IconLogo class="mb-8" />
|
||||
<div
|
||||
class="flex h-screen flex-col items-center overflow-auto bg-white/90 pt-[30vh]"
|
||||
>
|
||||
<IconLogo class="mb-8 flex-none" />
|
||||
<div class="flex w-72 flex-col">
|
||||
<FormKit
|
||||
id="reset-password-form"
|
||||
|
|
Loading…
Reference in New Issue