mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 15:33:33 +09:00
first
This commit is contained in:
0
src/pages/auth/index.vue
Normal file
0
src/pages/auth/index.vue
Normal file
149
src/pages/auth/login-2.vue
Normal file
149
src/pages/auth/login-2.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<script setup lang="ts">
|
||||
const isLoading = ref(false)
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const notyf = useNotyf()
|
||||
const token = useUserToken()
|
||||
const redirect = route.query.redirect as string
|
||||
|
||||
const handleLogin = async () => {
|
||||
if (!isLoading.value) {
|
||||
isLoading.value = true
|
||||
|
||||
await sleep(2000)
|
||||
token.value = 'logged-in'
|
||||
|
||||
notyf.dismissAll()
|
||||
notyf.primary('Welcome back, Erik Kovalsky')
|
||||
|
||||
if (redirect) {
|
||||
router.push(redirect)
|
||||
}
|
||||
else {
|
||||
router.push('/sidebar/dashboards')
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
useHead({
|
||||
title: 'Auth Login 2 - Vuero',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper-inner columns is-gapless">
|
||||
<!-- Image section (hidden on mobile) -->
|
||||
<div class="column login-column is-8 h-hidden-mobile h-hidden-tablet-p hero-banner">
|
||||
<div class="hero login-hero is-fullheight is-app-grey">
|
||||
<div class="hero-body is-justify-content-center is-fullwidth">
|
||||
<div class="is-flex is-justify-content-center is-fullwidth">
|
||||
<img
|
||||
class="light-image has-light-shadow has-light-border"
|
||||
src="/images/illustrations/apps/vuero-banking-light.webp"
|
||||
alt=""
|
||||
>
|
||||
<img
|
||||
class="dark-image has-light-shadow"
|
||||
src="/images/illustrations/apps/vuero-banking-dark.webp"
|
||||
alt=""
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form section -->
|
||||
<div class="column is-4">
|
||||
<div class="hero is-fullheight is-white">
|
||||
<div class="hero-heading">
|
||||
<div class="auth-logo">
|
||||
<RouterLink to="/">
|
||||
<AnimatedLogo
|
||||
width="36px"
|
||||
height="36px"
|
||||
/>
|
||||
</RouterLink>
|
||||
<VDarkmodeToggle />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="auth-content">
|
||||
<h2>Welcome Back.</h2>
|
||||
<p>Please sign in to your account</p>
|
||||
<RouterLink to="/auth/signup-2">
|
||||
I do not have an account yet
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="auth-form-wrapper">
|
||||
<!-- Login Form -->
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
@submit.prevent="handleLogin"
|
||||
>
|
||||
<div class="login-form">
|
||||
<!-- Username -->
|
||||
<VField>
|
||||
<VControl icon="lucide:user">
|
||||
<VInput
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
autocomplete="username"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Password -->
|
||||
<VField>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Switch -->
|
||||
<VField>
|
||||
<VControl class="setting-item">
|
||||
<VCheckbox
|
||||
label="Remember me"
|
||||
paddingless
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Submit -->
|
||||
<div class="login">
|
||||
<VButton
|
||||
:loading="isLoading"
|
||||
color="primary"
|
||||
type="submit"
|
||||
bold
|
||||
fullwidth
|
||||
raised
|
||||
>
|
||||
Sign In
|
||||
</VButton>
|
||||
</div>
|
||||
|
||||
<div class="forgot-link has-text-centered">
|
||||
<a>Forgot Password?</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
130
src/pages/auth/login-3.vue
Normal file
130
src/pages/auth/login-3.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<script setup lang="ts">
|
||||
const isLoading = ref(false)
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const notyf = useNotyf()
|
||||
const token = useUserToken()
|
||||
const redirect = route.query.redirect as string
|
||||
|
||||
const handleLogin = async () => {
|
||||
if (!isLoading.value) {
|
||||
isLoading.value = true
|
||||
|
||||
await sleep(2000)
|
||||
token.value = 'logged-in'
|
||||
|
||||
notyf.dismissAll()
|
||||
notyf.primary('Welcome back, Erik Kovalsky')
|
||||
|
||||
if (redirect) {
|
||||
router.push(redirect)
|
||||
}
|
||||
else {
|
||||
router.push('/sidebar/dashboards')
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
useHead({
|
||||
title: 'Auth Login 3 - Vuero',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper-inner is-single">
|
||||
<LandingGrids class="is-contrasted" />
|
||||
<!--Fake navigation-->
|
||||
<div class="auth-nav">
|
||||
<div class="left" />
|
||||
<div class="center">
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="header-item"
|
||||
>
|
||||
<AnimatedLogo
|
||||
width="38px"
|
||||
height="38px"
|
||||
/>
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="right">
|
||||
<VDarkmodeToggle />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Single Centered Form-->
|
||||
<div class="single-form-wrap is-relative">
|
||||
<div class="inner-wrap">
|
||||
<!--Form Title-->
|
||||
<div class="auth-head">
|
||||
<h2>Welcome Back.</h2>
|
||||
<p>Please sign in to your account</p>
|
||||
<RouterLink to="/auth/signup-3">
|
||||
I do not have an account yet
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<!--Form-->
|
||||
<div class="form-card">
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
@submit.prevent="handleLogin"
|
||||
>
|
||||
<div class="login-form">
|
||||
<VField>
|
||||
<VControl icon="lucide:user">
|
||||
<VInput
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
autocomplete="username"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<VField>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Switch -->
|
||||
<VField>
|
||||
<VControl class="setting-item">
|
||||
<VCheckbox
|
||||
label="Remember me"
|
||||
color="primary"
|
||||
paddingless
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Submit -->
|
||||
<div class="login">
|
||||
<VButton
|
||||
:loading="isLoading"
|
||||
type="submit"
|
||||
color="primary"
|
||||
bold
|
||||
fullwidth
|
||||
raised
|
||||
>
|
||||
Sign In
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="forgot-link has-text-centered">
|
||||
<a>Forgot Password?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
759
src/pages/auth/login.vue
Normal file
759
src/pages/auth/login.vue
Normal file
@@ -0,0 +1,759 @@
|
||||
<script setup lang="ts">
|
||||
type StepId = 'login' | 'forgot-password'
|
||||
const step = ref<StepId>('login')
|
||||
const isLoading = ref(false)
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const notyf = useNotyf()
|
||||
const token = useUserToken()
|
||||
const redirect = route.query.redirect as string
|
||||
|
||||
const handleLogin = async () => {
|
||||
if (!isLoading.value) {
|
||||
isLoading.value = true
|
||||
|
||||
await sleep(2000)
|
||||
console.log('set token logged-in')
|
||||
token.value = 'logged-in'
|
||||
|
||||
notyf.dismissAll()
|
||||
notyf.primary('Welcome back, Erik Kovalsky')
|
||||
|
||||
if (redirect) {
|
||||
router.push(redirect)
|
||||
}
|
||||
else {
|
||||
router.push('/sidebar/dashboards')
|
||||
}
|
||||
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
useHead({
|
||||
title: 'Auth Login 1 - Vuero',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="modern-login">
|
||||
<div class="underlay h-hidden-mobile h-hidden-tablet-p" />
|
||||
|
||||
<div class="columns is-gapless is-vcentered">
|
||||
<div class="column is-relative is-8 h-hidden-mobile h-hidden-tablet-p">
|
||||
<div class="hero is-fullheight is-image">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<img
|
||||
class="hero-image"
|
||||
src="/images/illustrations/login/station.svg"
|
||||
alt=""
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4 is-relative">
|
||||
<div class="top-tools">
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="top-logo"
|
||||
>
|
||||
<AnimatedLogo
|
||||
width="38px"
|
||||
height="38px"
|
||||
/>
|
||||
</RouterLink>
|
||||
|
||||
<VDarkmodeToggle />
|
||||
</div>
|
||||
<div class="is-form">
|
||||
<div class="is-form-inner">
|
||||
<div
|
||||
class="form-text"
|
||||
:class="[step !== 'login' && 'is-hidden']"
|
||||
>
|
||||
<h2>Sign In</h2>
|
||||
<p>Welcome back to your account.</p>
|
||||
</div>
|
||||
<div
|
||||
class="form-text"
|
||||
:class="[step === 'login' && 'is-hidden']"
|
||||
>
|
||||
<h2>Recover Account</h2>
|
||||
<p>Reset your account password.</p>
|
||||
</div>
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
:class="[step !== 'login' && 'is-hidden']"
|
||||
class="login-wrapper"
|
||||
@submit.prevent="handleLogin"
|
||||
>
|
||||
<VMessage color="primary">
|
||||
<div>
|
||||
<strong class="pr-1">email:</strong>
|
||||
<span>john.doe@cssninja.io</span>
|
||||
</div>
|
||||
<div>
|
||||
<strong class="pr-1">password:</strong>
|
||||
<span>ada.lovelace</span>
|
||||
</div>
|
||||
</VMessage>
|
||||
|
||||
<VField>
|
||||
<VControl icon="lnil lnil-envelope autv-icon">
|
||||
<VLabel class="auth-label">
|
||||
Email Address
|
||||
</VLabel>
|
||||
<VInput
|
||||
type="email"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<VField>
|
||||
<VControl icon="lnil lnil-lock-alt autv-icon">
|
||||
<VLabel class="auth-label">
|
||||
Password
|
||||
</VLabel>
|
||||
<VInput
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<VField>
|
||||
<VControl class="is-flex">
|
||||
<VLabel
|
||||
raw
|
||||
class="remember-toggle"
|
||||
>
|
||||
<VInput
|
||||
raw
|
||||
type="checkbox"
|
||||
/>
|
||||
|
||||
<span class="toggler">
|
||||
<span class="active">
|
||||
<VIcon
|
||||
icon="lucide:check"
|
||||
/>
|
||||
</span>
|
||||
<span class="inactive">
|
||||
<VIcon
|
||||
icon="lucide:circle"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</VLabel>
|
||||
<VLabel
|
||||
raw
|
||||
class="remember-me"
|
||||
>
|
||||
Remember Me
|
||||
</VLabel>
|
||||
<a
|
||||
tabindex="0"
|
||||
role="button"
|
||||
@keydown.enter.prevent="step = 'forgot-password'"
|
||||
@click="step = 'forgot-password'"
|
||||
>
|
||||
Forgot Password?
|
||||
</a>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<div class="button-wrap has-help">
|
||||
<VButton
|
||||
id="login-button"
|
||||
:loading="isLoading"
|
||||
color="primary"
|
||||
type="submit"
|
||||
size="big"
|
||||
rounded
|
||||
raised
|
||||
bold
|
||||
>
|
||||
Confirm
|
||||
</VButton>
|
||||
<span>
|
||||
Or
|
||||
<RouterLink to="/auth/signup-1">Create</RouterLink>
|
||||
an account.
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
:class="[step !== 'forgot-password' && 'is-hidden']"
|
||||
class="login-wrapper"
|
||||
@submit.prevent
|
||||
>
|
||||
<p class="recover-text">
|
||||
Enter your email and click on the confirm button to reset your password.
|
||||
We'll send you an email detailing the steps to complete the procedure.
|
||||
</p>
|
||||
|
||||
<VField>
|
||||
<VControl icon="lnil lnil-envelope autv-icon">
|
||||
<VLabel class="auth-label">
|
||||
Email Address
|
||||
</VLabel>
|
||||
<VInput
|
||||
type="email"
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<div class="button-wrap">
|
||||
<VButton
|
||||
color="white"
|
||||
size="big"
|
||||
lower
|
||||
rounded
|
||||
@click="step = 'login'"
|
||||
>
|
||||
Cancel
|
||||
</VButton>
|
||||
<VButton
|
||||
color="primary"
|
||||
size="big"
|
||||
type="submit"
|
||||
lower
|
||||
rounded
|
||||
solid
|
||||
@click="step = 'login'"
|
||||
>
|
||||
Confirm
|
||||
</VButton>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modern-login {
|
||||
position: relative;
|
||||
background: var(--white);
|
||||
min-height: 100vh;
|
||||
|
||||
.column {
|
||||
&.is-relative {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.hero {
|
||||
&.has-background-image {
|
||||
position: relative;
|
||||
|
||||
.hero-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #5d4298 !important;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.underlay {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 66.6%;
|
||||
height: 100%;
|
||||
background: #fdfdfd;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.top-tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.25rem;
|
||||
margin-bottom: 5rem;
|
||||
|
||||
.dark-mode {
|
||||
transform: scale(0.6);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.top-logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 50px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.iconify {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-image {
|
||||
position: relative;
|
||||
border-inline-end: 1px solid var(--fade-grey);
|
||||
|
||||
.hero-image {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: block;
|
||||
margin: -80px auto 0;
|
||||
max-width: 60%;
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
.is-form {
|
||||
position: relative;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
|
||||
form {
|
||||
animation: fadeInLeft 0.5s;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
padding: 0 20px;
|
||||
animation: fadeInLeft 0.5s;
|
||||
|
||||
h2 {
|
||||
font-family: var(--font-alt);
|
||||
font-weight: 400;
|
||||
font-size: 2rem;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--muted-grey);
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.recover-text {
|
||||
font-size: 0.9rem;
|
||||
color: var(--dark-text);
|
||||
}
|
||||
|
||||
.login-wrapper {
|
||||
padding: 30px 20px;
|
||||
|
||||
.control {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-top: 16px;
|
||||
|
||||
.input {
|
||||
padding-top: 14px;
|
||||
height: 60px;
|
||||
border-radius: 10px;
|
||||
padding-inline-start: 55px;
|
||||
transition: all 0.3s; // transition-all test
|
||||
|
||||
&:focus {
|
||||
background: color-mix(in oklab, var(--fade-grey), white 6%);
|
||||
border-color: var(--placeholder);
|
||||
|
||||
~ .auth-label,
|
||||
~ .autv-icon .iconify {
|
||||
color: var(--muted-grey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: var(--danger);
|
||||
font-size: 0.8rem;
|
||||
display: none;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
.auth-label {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
inset-inline-start: 55px;
|
||||
font-size: 0.8rem;
|
||||
color: var(--dark-text);
|
||||
font-weight: 500;
|
||||
z-index: 2;
|
||||
transition: all 0.3s; // transition-all test
|
||||
}
|
||||
|
||||
.autv-icon,
|
||||
:deep(.autv-icon) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24px;
|
||||
color: var(--placeholder);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
&.has-validation {
|
||||
.validation-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-end: 0;
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.icon-wrapper {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: var(--radius-rounded);
|
||||
|
||||
.iconify {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
stroke-width: 3px;
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-success {
|
||||
.icon-wrapper {
|
||||
background: var(--success);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-error {
|
||||
.icon-wrapper {
|
||||
background: var(--danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-success {
|
||||
.validation-icon {
|
||||
&.is-success {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.is-error {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-error {
|
||||
.input {
|
||||
border-color: var(--danger);
|
||||
}
|
||||
|
||||
.error-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.validation-icon {
|
||||
&.is-error {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.is-success {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
margin-inline-start: auto;
|
||||
color: var(--muted-grey);
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.remember-me {
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted-grey);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-wrap {
|
||||
margin: 40px 0;
|
||||
|
||||
&.has-help {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> span {
|
||||
margin-inline-start: 12px;
|
||||
font-family: var(--font);
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
font-weight: 500;
|
||||
padding: 0 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 46px;
|
||||
width: 140px;
|
||||
margin-inline-start: 6px;
|
||||
|
||||
&:first-child {
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remember-toggle {
|
||||
width: 65px;
|
||||
display: block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
user-select: none;
|
||||
transform: scale(0.9);
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:checked ~ .toggler {
|
||||
border-color: var(--primary);
|
||||
|
||||
.active,
|
||||
.inactive {
|
||||
transform: translateX(calc(var(--transform-direction) * 100%)) rotate(360deg);
|
||||
}
|
||||
|
||||
.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toggler {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 34px;
|
||||
width: 61px;
|
||||
border: 2px solid var(--placeholder);
|
||||
border-radius: 100px;
|
||||
transition: all 0.3s; // transition-all test
|
||||
|
||||
.active,
|
||||
.inactive {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
inset-inline-start: 2px;
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
border-radius: var(--radius-rounded);
|
||||
background: black;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform: translateX(calc(var(--transform-direction) * 0))
|
||||
rotate(calc(var(--transform-direction) * 0));
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.iconify {
|
||||
color: var(--white);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.inactive {
|
||||
background: var(--placeholder);
|
||||
border-color: var(--placeholder);
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
opacity: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (width <= 767px) {
|
||||
.modern-login {
|
||||
.top-logo {
|
||||
top: 30px;
|
||||
}
|
||||
|
||||
.dark-mode {
|
||||
top: 36px;
|
||||
inset-inline-end: 44px;
|
||||
}
|
||||
|
||||
.is-form {
|
||||
padding-top: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (width >= 768px) and (width <= 1024px) and (orientation: portrait) {
|
||||
.modern-login {
|
||||
.top-logo {
|
||||
.iconify {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.dark-mode {
|
||||
top: -58px;
|
||||
inset-inline-end: 30%;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Dark mode
|
||||
========================================================================== */
|
||||
|
||||
.is-dark {
|
||||
.modern-login {
|
||||
background: var(--dark-sidebar);
|
||||
|
||||
.underlay {
|
||||
background: color-mix(in oklab, var(--dark-sidebar), white 10%);
|
||||
}
|
||||
|
||||
.is-image {
|
||||
border-color: color-mix(in oklab, var(--dark-sidebar), white 10%);
|
||||
}
|
||||
|
||||
.is-form {
|
||||
.form-text {
|
||||
h2 {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.login-wrapper {
|
||||
.control {
|
||||
&.is-flex {
|
||||
a:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
background: color-mix(in oklab, var(--dark-sidebar), white 4%);
|
||||
|
||||
&:focus {
|
||||
border-color: var(--primary);
|
||||
|
||||
~ .autv-icon {
|
||||
.iconify {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-label {
|
||||
color: var(--light-text);
|
||||
}
|
||||
}
|
||||
|
||||
.button-wrap {
|
||||
&.has-help {
|
||||
span {
|
||||
color: var(--light-text);
|
||||
|
||||
a {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remember-toggle {
|
||||
input {
|
||||
&:checked + .toggler {
|
||||
border-color: var(--primary);
|
||||
|
||||
> span {
|
||||
background: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toggler {
|
||||
border-color: color-mix(in oklab, var(--dark-sidebar), white 12%);
|
||||
|
||||
> span {
|
||||
background: color-mix(in oklab, var(--dark-sidebar), white 12%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1501
src/pages/auth/signup-1.vue
Normal file
1501
src/pages/auth/signup-1.vue
Normal file
File diff suppressed because it is too large
Load Diff
256
src/pages/auth/signup-2.vue
Normal file
256
src/pages/auth/signup-2.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<script setup lang="ts">
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { z } from 'zod'
|
||||
|
||||
const router = useRouter()
|
||||
const notyf = useNotyf()
|
||||
|
||||
const isLoading = ref(false)
|
||||
const { t } = useI18n()
|
||||
|
||||
// This is the Zod schema for the form input
|
||||
// It's used to define the shape that the form data will have
|
||||
const zodSchema = z
|
||||
.object({
|
||||
name: z
|
||||
.string({
|
||||
required_error: t('auth.errors.name.required'),
|
||||
})
|
||||
.min(1, t('auth.errors.name.required')),
|
||||
email: z
|
||||
.string({
|
||||
required_error: t('auth.errors.email.required'),
|
||||
})
|
||||
.email(t('auth.errors.email.format')),
|
||||
password: z
|
||||
.string({
|
||||
required_error: t('auth.errors.password.required'),
|
||||
})
|
||||
.min(8, t('auth.errors.password.length')),
|
||||
passwordCheck: z.string({
|
||||
required_error: t('auth.errors.passwordCheck.required'),
|
||||
}),
|
||||
promotional: z.boolean(),
|
||||
})
|
||||
// Refine is used to add custom validation rules to the schema
|
||||
.refine(data => data.password === data.passwordCheck, {
|
||||
message: t('auth.errors.passwordCheck.match'),
|
||||
path: ['passwordCheck'],
|
||||
})
|
||||
|
||||
// Zod has a great infer method that will
|
||||
// infer the shape of the schema into a TypeScript type
|
||||
type FormInput = z.infer<typeof zodSchema>
|
||||
|
||||
// Define a validation schema
|
||||
const validationSchema = toTypedSchema(zodSchema)
|
||||
|
||||
// Set initial values for the form
|
||||
const initialValues = {
|
||||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
passwordCheck: '',
|
||||
promotional: false,
|
||||
} satisfies FormInput
|
||||
|
||||
// here we create a vee-validate form context that
|
||||
// will be used in all vuero form components
|
||||
const { handleSubmit } = useForm({
|
||||
validationSchema,
|
||||
initialValues,
|
||||
})
|
||||
|
||||
const onSignup = handleSubmit(async (values) => {
|
||||
console.log('handleSignup values')
|
||||
console.table(values)
|
||||
|
||||
if (!isLoading.value) {
|
||||
isLoading.value = true
|
||||
|
||||
await sleep(800)
|
||||
|
||||
notyf.dismissAll()
|
||||
notyf.primary('Welcome, Erik Kovalsky')
|
||||
|
||||
router.push('/sidebar/dashboards')
|
||||
isLoading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: 'Auth Signup 2 - Vuero',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper-inner columns is-gapless">
|
||||
<!-- Form section -->
|
||||
<div class="column is-5">
|
||||
<div class="hero is-fullheight is-white">
|
||||
<div class="hero-heading">
|
||||
<div class="auth-logo">
|
||||
<LanguageDropdown />
|
||||
<RouterLink to="/">
|
||||
<AnimatedLogo
|
||||
class="top-logo"
|
||||
width="36px"
|
||||
height="36px"
|
||||
/>
|
||||
</RouterLink>
|
||||
<VDarkmodeToggle />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="auth-content">
|
||||
<h2>{{ t('auth.title') }}</h2>
|
||||
<p>{{ t('auth.subtitle') }}</p>
|
||||
<RouterLink to="/auth/login-2">
|
||||
{{ t('auth.action.login') }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="auth-form-wrapper">
|
||||
<!-- Login Form -->
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
@submit="onSignup"
|
||||
>
|
||||
<div class="login-form">
|
||||
<!-- Input -->
|
||||
<VField
|
||||
id="name"
|
||||
v-slot="{ field }"
|
||||
>
|
||||
<VControl icon="lucide:user">
|
||||
<VInput
|
||||
type="text"
|
||||
:placeholder="t('auth.placeholder.name')"
|
||||
autocomplete="name"
|
||||
/>
|
||||
<p
|
||||
v-if="field?.errorMessage"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ field.errorMessage }}
|
||||
</p>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Input -->
|
||||
<VField
|
||||
id="email"
|
||||
v-slot="{ field }"
|
||||
>
|
||||
<VControl icon="lucide:mail">
|
||||
<VInput
|
||||
type="text"
|
||||
:placeholder="t('auth.placeholder.email')"
|
||||
autocomplete="email"
|
||||
/>
|
||||
<p
|
||||
v-if="field?.errorMessage"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ field.errorMessage }}
|
||||
</p>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Input -->
|
||||
<VField
|
||||
id="password"
|
||||
v-slot="{ field }"
|
||||
>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
:placeholder="t('auth.placeholder.password')"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<p
|
||||
v-if="field?.errorMessage"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ field.errorMessage }}
|
||||
</p>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Input -->
|
||||
<VField
|
||||
id="passwordCheck"
|
||||
v-slot="{ field }"
|
||||
>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
:placeholder="t('auth.placeholder.passwordCheck')"
|
||||
/>
|
||||
<p
|
||||
v-if="field?.errorMessage"
|
||||
class="help is-danger"
|
||||
>
|
||||
{{ field.errorMessage }}
|
||||
</p>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<VField id="promitional">
|
||||
<VControl class="setting-item">
|
||||
<VCheckbox
|
||||
color="primary"
|
||||
:label="t('auth.label.promotional')"
|
||||
paddingless
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Submit -->
|
||||
|
||||
<div class="login">
|
||||
<VButton
|
||||
type="submit"
|
||||
color="primary"
|
||||
bold
|
||||
fullwidth
|
||||
raised
|
||||
>
|
||||
{{ t('auth.action.signup') }}
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Image section (hidden on mobile) -->
|
||||
<div class="column login-column is-7 is-hidden-mobile hero-banner">
|
||||
<div class="hero login-hero is-fullheight is-app-grey">
|
||||
<div class="hero-body is-justify-content-center is-fullwidth">
|
||||
<div class="is-flex is-justify-content-center is-fullwidth">
|
||||
<img
|
||||
class="light-image has-light-shadow has-light-border"
|
||||
src="/images/illustrations/apps/vuero-banking-light.webp"
|
||||
alt=""
|
||||
>
|
||||
<img
|
||||
class="dark-image has-light-shadow"
|
||||
src="/images/illustrations/apps/vuero-banking-dark.webp"
|
||||
alt=""
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
133
src/pages/auth/signup-3.vue
Normal file
133
src/pages/auth/signup-3.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<script setup lang="ts">
|
||||
const router = useRouter()
|
||||
const notyf = useNotyf()
|
||||
const isLoading = ref(false)
|
||||
|
||||
const handleSignup = async () => {
|
||||
if (!isLoading.value) {
|
||||
isLoading.value = true
|
||||
sleep(2000)
|
||||
|
||||
notyf.dismissAll()
|
||||
notyf.primary('Welcome, Erik Kovalsky')
|
||||
router.push('/sidebar/dashboards')
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
useHead({
|
||||
title: 'Auth Signup 3 - Vuero',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper-inner is-single">
|
||||
<LandingGrids class="is-contrasted" />
|
||||
<!--Fake navigation-->
|
||||
<div class="auth-nav">
|
||||
<div class="left" />
|
||||
<div class="center">
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="header-item"
|
||||
>
|
||||
<AnimatedLogo
|
||||
width="38px"
|
||||
height="38px"
|
||||
/>
|
||||
</RouterLink>
|
||||
</div>
|
||||
<div class="right">
|
||||
<VDarkmodeToggle />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Single Centered Form-->
|
||||
<div class="single-form-wrap is-relative">
|
||||
<div class="inner-wrap">
|
||||
<!--Form Title-->
|
||||
<div class="auth-head">
|
||||
<h2>Join Us Now.</h2>
|
||||
<p>Start by creating your account</p>
|
||||
<RouterLink to="/auth/login-3">
|
||||
I already have an account
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<!--Form-->
|
||||
<div class="form-card">
|
||||
<form
|
||||
method="post"
|
||||
novalidate
|
||||
@submit.prevent="handleSignup"
|
||||
>
|
||||
<div class="login-form">
|
||||
<!-- Input -->
|
||||
<VField>
|
||||
<VControl icon="lucide:user">
|
||||
<VInput
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
autocomplete="name"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<!-- Input -->
|
||||
<VField>
|
||||
<VControl icon="lucide:mail">
|
||||
<VInput
|
||||
type="text"
|
||||
placeholder="Email Address"
|
||||
autocomplete="email"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<!-- Input -->
|
||||
<VField>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
<!-- Input -->
|
||||
<VField>
|
||||
<VControl icon="lucide:lock">
|
||||
<VInput
|
||||
type="password"
|
||||
placeholder="Repeat Password"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<VField>
|
||||
<VControl class="setting-item">
|
||||
<VCheckbox
|
||||
label="Receive promotional offers"
|
||||
color="primary"
|
||||
paddingless
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
|
||||
<!-- Submit -->
|
||||
<div class="login">
|
||||
<VButton
|
||||
color="primary"
|
||||
type="submit"
|
||||
bold
|
||||
fullwidth
|
||||
raised
|
||||
>
|
||||
Sign Up
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
0
src/pages/auth/signup.vue
Normal file
0
src/pages/auth/signup.vue
Normal file
Reference in New Issue
Block a user