Files
ReelShortWeb/src/views/Login/Login.vue
T

277 lines
5.5 KiB
Vue

<!-- Author: fruit.com.cn -->
<script setup lang="ts">
import { LoginForm, RegisterForm } from './components'
import { ThemeSwitch } from '@/components/ThemeSwitch'
import { LocaleDropdown } from '@/components/LocaleDropdown'
import { useI18n } from '@/hooks/web/useI18n'
import { getCssVar, underlineToHump } from '@/utils'
import { useAppStore } from '@/store/modules/app'
import { computed, ref } from 'vue'
import { ElScrollbar } from 'element-plus'
const appStore = useAppStore()
const { t } = useI18n()
const isLogin = ref(true)
const isDark = computed(() => appStore.getIsDark)
const toolColor = computed(() => (isDark.value ? '#e5eaf3' : '#303133'))
const themeChange = () => {
const color = getCssVar('--el-bg-color')
appStore.setMenuTheme(color)
appStore.setHeaderTheme(color)
}
</script>
<template>
<div class="login-page" :class="{ 'is-dark': isDark }">
<ElScrollbar class="login-scroll">
<div class="login-shell">
<section class="login-hero">
<div class="hero-brand">
<img src="@/assets/imgs/logo.png" alt="" />
<span>{{ underlineToHump(appStore.getTitle) }}</span>
</div>
<div class="hero-copy">
<p class="hero-kicker">FruitShorts Studio</p>
<h1>{{ t('login.welcome') }}</h1>
<p>{{ t('login.message') }}</p>
<ul>
<li>{{ t('login.pointDrama') }}</li>
<li>{{ t('login.pointPublish') }}</li>
<li>{{ t('login.pointAccess') }}</li>
</ul>
</div>
</section>
<section class="login-panel">
<div class="login-tools">
<ThemeSwitch @change="themeChange" />
<LocaleDropdown :color="toolColor" />
</div>
<div class="login-card">
<LoginForm v-if="isLogin" @to-register="isLogin = false" />
<RegisterForm v-else @to-login="isLogin = true" />
</div>
</section>
</div>
</ElScrollbar>
</div>
</template>
<style lang="less" scoped>
.login-page {
height: 100%;
color: var(--el-text-color-primary);
background: #eef3f9;
}
.login-scroll {
height: 100%;
}
.login-shell {
display: flex;
min-height: 100vh;
}
.login-hero {
position: relative;
display: flex;
padding: 40px 56px 56px;
overflow: hidden;
color: #fff;
background:
radial-gradient(circle at 18% 18%, rgb(255 255 255 / 16%), transparent 28%),
radial-gradient(circle at 82% 78%, rgb(64 158 255 / 45%), transparent 32%),
linear-gradient(155deg, #0d2344 0%, #1a4f96 52%, #409eff 100%);
flex: 1.05;
flex-direction: column;
justify-content: space-between;
&::after {
position: absolute;
right: -80px;
bottom: -120px;
width: 360px;
height: 360px;
border: 1px solid rgb(255 255 255 / 16%);
border-radius: 50%;
content: '';
}
}
.hero-brand {
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 12px;
font-size: 20px;
font-weight: 700;
img {
width: 42px;
height: 42px;
}
}
.hero-copy {
position: relative;
z-index: 1;
max-width: 460px;
h1 {
margin: 10px 0 12px;
font-size: 40px;
font-weight: 700;
line-height: 1.2;
color: #fff;
}
p {
margin: 0;
font-size: 15px;
line-height: 1.7;
color: rgb(255 255 255 / 82%);
}
}
.hero-kicker {
font-size: 13px;
font-weight: 600;
letter-spacing: 0.08em;
color: #d9ecff !important;
}
.hero-copy ul {
display: flex;
padding: 0;
margin: 28px 0 0;
list-style: none;
flex-wrap: wrap;
gap: 10px;
li {
padding: 8px 14px;
font-size: 13px;
color: #fff;
background: rgb(255 255 255 / 12%);
border: 1px solid rgb(255 255 255 / 18%);
border-radius: 999px;
}
}
.login-panel {
position: relative;
display: flex;
flex: 0.95;
align-items: center;
justify-content: center;
padding: 88px 32px 48px;
background: #f4f7fb;
}
.login-tools {
position: absolute;
top: 22px;
right: 24px;
display: flex;
gap: 12px;
align-items: center;
}
.login-card {
width: min(420px, 100%);
padding: 36px 32px 28px;
background: #fff;
border: 1px solid #e6edf5;
border-radius: 18px;
box-shadow: 0 18px 50px rgb(15 39 68 / 8%);
}
.is-dark {
background: #0e1116;
.login-hero {
background:
radial-gradient(circle at 18% 18%, rgb(64 158 255 / 18%), transparent 30%),
linear-gradient(155deg, #07111f 0%, #0e2744 58%, #163e73 100%);
}
.login-panel {
background: #0e1116;
}
.login-card {
background: #161b22;
border-color: #2a313c;
box-shadow: none;
}
}
@media (width <= 960px) {
.login-shell {
flex-direction: column;
}
.login-hero {
flex: none;
min-height: 280px;
padding: 28px 24px 32px;
}
.hero-copy h1 {
font-size: 30px;
}
.login-panel {
padding: 72px 16px 32px;
}
}
</style>
<style lang="less">
.login-heading {
margin-bottom: 8px;
h2 {
margin: 0;
font-size: 28px;
font-weight: 700;
line-height: 1.2;
color: var(--el-text-color-primary);
}
p {
margin: 8px 0 0;
font-size: 14px;
color: var(--el-text-color-secondary);
}
}
.login-register {
display: flex;
margin-top: 16px;
font-size: 14px;
color: var(--el-text-color-secondary);
gap: 6px;
align-items: center;
justify-content: center;
button {
padding: 0;
font: inherit;
color: var(--el-color-primary);
cursor: pointer;
background: none;
border: 0;
}
}
body:has(.login-page) {
min-width: 0;
background: transparent;
}
</style>