feat: new login experience (#2139)
* feat: multiple auth instances * fix: auth setup + strategy initialization * feat: admin auth - add strategy * feat: redirect on login - group setting * feat: oauth2 generic - props definitions * feat: new login UI (wip) * feat: new login UI (wip) * feat: admin security login settings * feat: tabset editor indicators + print view improvements * fix: code styling
This commit is contained in:
@@ -1,189 +1,240 @@
|
||||
<template lang="pug">
|
||||
v-app
|
||||
.login
|
||||
v-container(grid-list-lg)
|
||||
v-layout(row, wrap)
|
||||
v-flex(
|
||||
xs12
|
||||
offset-sm1, sm10
|
||||
offset-md2, md8
|
||||
offset-lg3, lg6
|
||||
offset-xl4, xl4
|
||||
.login-sd
|
||||
.d-flex
|
||||
.login-logo
|
||||
v-avatar(tile, size='34')
|
||||
v-img(:src='logoUrl')
|
||||
.login-title
|
||||
.text-h6 {{ siteTitle }}
|
||||
//-------------------------------------------------
|
||||
//- PROVIDERS LIST
|
||||
//-------------------------------------------------
|
||||
template(v-if='screen === `login` && strategies.length > 1')
|
||||
.login-subtitle.mt-5
|
||||
.text-subtitle-1 Select Authentication Provider
|
||||
.login-list
|
||||
v-list.elevation-1.radius-7(nav)
|
||||
v-list-item-group(v-model='selectedStrategyKey')
|
||||
v-list-item(
|
||||
v-for='(stg, idx) of strategies'
|
||||
:key='stg.key'
|
||||
:value='stg.key'
|
||||
:color='stg.strategy.color'
|
||||
)
|
||||
v-avatar.mr-3(tile, size='24', v-html='stg.strategy.icon')
|
||||
span.text-none {{stg.displayName}}
|
||||
//-------------------------------------------------
|
||||
//- LOGIN FORM
|
||||
//-------------------------------------------------
|
||||
template(v-if='screen === `login` && selectedStrategy.strategy.useForm')
|
||||
.login-subtitle
|
||||
.text-subtitle-1 Enter your credentials
|
||||
.login-form
|
||||
v-text-field(
|
||||
solo
|
||||
flat
|
||||
prepend-inner-icon='mdi-clipboard-account'
|
||||
background-color='white'
|
||||
hide-details
|
||||
ref='iptEmail'
|
||||
v-model='username'
|
||||
:placeholder='$t("auth:fields.emailUser")'
|
||||
)
|
||||
v-text-field.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-inner-icon='mdi-form-textbox-password'
|
||||
background-color='white'
|
||||
hide-details
|
||||
ref='iptPassword'
|
||||
v-model='password'
|
||||
:append-icon='hidePassword ? "mdi-eye-off" : "mdi-eye"'
|
||||
@click:append='() => (hidePassword = !hidePassword)'
|
||||
:type='hidePassword ? "password" : "text"'
|
||||
:placeholder='$t("auth:fields.password")'
|
||||
@keyup.enter='login'
|
||||
)
|
||||
transition(name='fadeUp')
|
||||
v-card.elevation-5(v-show='isShown', light)
|
||||
v-toolbar(color='indigo', flat, dense, dark)
|
||||
v-spacer
|
||||
.subheading(v-if='screen === "tfa"') {{ $t('auth:tfa.subtitle') }}
|
||||
.subheading(v-if='screen === "changePwd"') {{ $t('auth:changePwd.subtitle') }}
|
||||
.subheading(v-else-if='selectedStrategy.key !== "local"') {{ $t('auth:loginUsingStrategy', { strategy: selectedStrategy.title, interpolation: { escapeValue: false } }) }}
|
||||
.subheading(v-else) {{ $t('auth:loginRequired') }}
|
||||
v-spacer
|
||||
v-card-text.text-center
|
||||
h1.display-1.indigo--text.py-2 {{ siteTitle }}
|
||||
template(v-if='screen === "login"')
|
||||
v-text-field.mt-3(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-clipboard-account'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptEmail'
|
||||
v-model='username'
|
||||
:placeholder='$t("auth:fields.emailUser")'
|
||||
)
|
||||
v-text-field.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-textbox-password'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptPassword'
|
||||
v-model='password'
|
||||
:append-icon='hidePassword ? "mdi-eye-off" : "mdi-eye"'
|
||||
@click:append='() => (hidePassword = !hidePassword)'
|
||||
:type='hidePassword ? "password" : "text"'
|
||||
:placeholder='$t("auth:fields.password")'
|
||||
@keyup.enter='login'
|
||||
)
|
||||
template(v-else-if='screen === "tfa"')
|
||||
.body-2 Enter the security code generated from your trusted device:
|
||||
v-text-field.centered.mt-2(
|
||||
solo
|
||||
flat
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptTFA'
|
||||
v-model='securityCode'
|
||||
:placeholder='$t("auth:tfa.placeholder")'
|
||||
@keyup.enter='verifySecurityCode'
|
||||
)
|
||||
template(v-else-if='screen === "changePwd"')
|
||||
.body-2 {{$t('auth:changePwd.instructions')}}
|
||||
v-text-field.mt-2(
|
||||
type='password'
|
||||
solo
|
||||
flat
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptNewPassword'
|
||||
v-model='newPassword'
|
||||
:placeholder='$t(`auth:changePwd.newPasswordPlaceholder`)'
|
||||
)
|
||||
v-text-field.mt-2(
|
||||
type='password'
|
||||
solo
|
||||
flat
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
v-model='newPasswordVerify'
|
||||
:placeholder='$t(`auth:changePwd.newPasswordVerifyPlaceholder`)'
|
||||
@keyup.enter='changePassword'
|
||||
)
|
||||
template(v-else-if='screen === "forgot"')
|
||||
.body-2 {{ $t('auth:forgotPasswordSubtitle') }}
|
||||
v-text-field.mt-3(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='mdi-email'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptEmailForgot'
|
||||
v-model='username'
|
||||
:placeholder='$t("auth:fields.email")'
|
||||
)
|
||||
v-card-actions.pb-4
|
||||
v-spacer
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-if='screen === "login"'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='login'
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:actions.login') }}
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "tfa"'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='verifySecurityCode'
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:tfa.verifyToken') }}
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "changePwd"'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='changePassword'
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:changePwd.proceed') }}
|
||||
v-btn(
|
||||
width='100%'
|
||||
max-width='250px'
|
||||
v-else-if='screen === "forgot"'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='forgotPasswordSubmit'
|
||||
rounded
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:sendResetPassword') }}
|
||||
v-spacer
|
||||
v-card-actions.pb-3(v-if='screen === "login" && selectedStrategy.key === "local"')
|
||||
v-spacer
|
||||
a.caption(@click.stop.prevent='forgotPassword', href='#forgot') {{ $t('auth:forgotPasswordLink') }}
|
||||
v-spacer
|
||||
v-card-actions.pb-3(v-else-if='screen === "forgot"')
|
||||
v-spacer
|
||||
a.caption(@click.stop.prevent='screen = `login`', href='#cancelforgot') {{ $t('auth:forgotPasswordCancel') }}
|
||||
v-spacer
|
||||
template(v-if='screen === "login" && isSocialShown')
|
||||
v-divider
|
||||
v-card-text.grey.lighten-4.text-center
|
||||
.pb-2.body-2.text-xs-center.grey--text.text--darken-2 {{ $t('auth:orLoginUsingStrategy') }}
|
||||
v-btn.mx-1.social-login-btn(
|
||||
v-for='strategy in strategies', :key='strategy.key'
|
||||
large
|
||||
@click='selectStrategy(strategy)'
|
||||
dark
|
||||
:color='strategy.color'
|
||||
:depressed='strategy.key === selectedStrategy.key'
|
||||
)
|
||||
v-avatar.mr-3(tile, :class='strategy.color', size='24', v-html='strategy.icon')
|
||||
span(style='text-transform: none;') {{ strategy.title }}
|
||||
template(v-if='screen === "login" && selectedStrategy.key === `local` && selectedStrategy.selfRegistration')
|
||||
v-divider
|
||||
v-card-actions.py-3(:class='isSocialShown ? "" : "grey lighten-4"')
|
||||
v-spacer
|
||||
i18next.caption(path='auth:switchToRegister.text', tag='div')
|
||||
a.caption(href='/register', place='link') {{ $t('auth:switchToRegister.link') }}
|
||||
v-spacer
|
||||
v-btn.mt-2.text-none(
|
||||
width='100%'
|
||||
v-if='screen === "login"'
|
||||
large
|
||||
color='primary'
|
||||
dark
|
||||
@click='login'
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:actions.login') }}
|
||||
.text-center.mt-5(v-if='screen === "login"')
|
||||
v-btn.text-none(
|
||||
text
|
||||
rounded
|
||||
color='grey darken-3'
|
||||
@click.stop.prevent='forgotPassword'
|
||||
href='#forgot'
|
||||
): .caption {{ $t('auth:forgotPasswordLink') }}
|
||||
v-btn.text-none(
|
||||
v-if='screen === "login" && selectedStrategyKey === `local` && selectedStrategy.selfRegistration'
|
||||
color='indigo darken-2'
|
||||
text
|
||||
rounded
|
||||
href='/register'
|
||||
): .caption {{ $t('auth:switchToRegister.link') }}
|
||||
//- .login-main
|
||||
//- v-container(grid-list-lg, fluid)
|
||||
//- v-row(no-gutters)
|
||||
//- v-col(cols='12', xl='4')
|
||||
//- transition(name='fadeUp')
|
||||
//- v-card.elevation-5(v-show='isShown', light)
|
||||
//- v-toolbar(color='indigo', flat, dense, dark)
|
||||
//- v-spacer
|
||||
//- .subheading(v-if='screen === "tfa"') {{ $t('auth:tfa.subtitle') }}
|
||||
//- .subheading(v-if='screen === "changePwd"') {{ $t('auth:changePwd.subtitle') }}
|
||||
//- .subheading(v-else-if='selectedStrategy.key !== "local"') {{ $t('auth:loginUsingStrategy', { strategy: selectedStrategy.title, interpolation: { escapeValue: false } }) }}
|
||||
//- .subheading(v-else) {{ $t('auth:loginRequired') }}
|
||||
//- v-spacer
|
||||
//- v-card-text.text-center
|
||||
//- h1.display-1.indigo--text.py-2 {{ siteTitle }}
|
||||
//- template(v-if='screen === "login"')
|
||||
//- v-text-field.mt-3(
|
||||
//- solo
|
||||
//- flat
|
||||
//- prepend-icon='mdi-clipboard-account'
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- ref='iptEmail'
|
||||
//- v-model='username'
|
||||
//- :placeholder='$t("auth:fields.emailUser")'
|
||||
//- )
|
||||
//- v-text-field.mt-2(
|
||||
//- solo
|
||||
//- flat
|
||||
//- prepend-icon='mdi-textbox-password'
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- ref='iptPassword'
|
||||
//- v-model='password'
|
||||
//- :append-icon='hidePassword ? "mdi-eye-off" : "mdi-eye"'
|
||||
//- @click:append='() => (hidePassword = !hidePassword)'
|
||||
//- :type='hidePassword ? "password" : "text"'
|
||||
//- :placeholder='$t("auth:fields.password")'
|
||||
//- @keyup.enter='login'
|
||||
//- )
|
||||
//- template(v-else-if='screen === "tfa"')
|
||||
//- .body-2 Enter the security code generated from your trusted device:
|
||||
//- v-text-field.centered.mt-2(
|
||||
//- solo
|
||||
//- flat
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- ref='iptTFA'
|
||||
//- v-model='securityCode'
|
||||
//- :placeholder='$t("auth:tfa.placeholder")'
|
||||
//- @keyup.enter='verifySecurityCode'
|
||||
//- )
|
||||
//- template(v-else-if='screen === "changePwd"')
|
||||
//- .body-2 {{$t('auth:changePwd.instructions')}}
|
||||
//- v-text-field.mt-2(
|
||||
//- type='password'
|
||||
//- solo
|
||||
//- flat
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- ref='iptNewPassword'
|
||||
//- v-model='newPassword'
|
||||
//- :placeholder='$t(`auth:changePwd.newPasswordPlaceholder`)'
|
||||
//- )
|
||||
//- v-text-field.mt-2(
|
||||
//- type='password'
|
||||
//- solo
|
||||
//- flat
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- v-model='newPasswordVerify'
|
||||
//- :placeholder='$t(`auth:changePwd.newPasswordVerifyPlaceholder`)'
|
||||
//- @keyup.enter='changePassword'
|
||||
//- )
|
||||
//- template(v-else-if='screen === "forgot"')
|
||||
//- .body-2 {{ $t('auth:forgotPasswordSubtitle') }}
|
||||
//- v-text-field.mt-3(
|
||||
//- solo
|
||||
//- flat
|
||||
//- prepend-icon='mdi-email'
|
||||
//- background-color='grey lighten-4'
|
||||
//- hide-details
|
||||
//- ref='iptEmailForgot'
|
||||
//- v-model='username'
|
||||
//- :placeholder='$t("auth:fields.email")'
|
||||
//- )
|
||||
//- v-card-actions.pb-4
|
||||
//- v-spacer
|
||||
//- v-btn(
|
||||
//- width='100%'
|
||||
//- max-width='250px'
|
||||
//- v-if='screen === "login"'
|
||||
//- large
|
||||
//- color='primary'
|
||||
//- dark
|
||||
//- @click='login'
|
||||
//- rounded
|
||||
//- :loading='isLoading'
|
||||
//- ) {{ $t('auth:actions.login') }}
|
||||
//- v-btn(
|
||||
//- width='100%'
|
||||
//- max-width='250px'
|
||||
//- v-else-if='screen === "tfa"'
|
||||
//- large
|
||||
//- color='primary'
|
||||
//- dark
|
||||
//- @click='verifySecurityCode'
|
||||
//- rounded
|
||||
//- :loading='isLoading'
|
||||
//- ) {{ $t('auth:tfa.verifyToken') }}
|
||||
//- v-btn(
|
||||
//- width='100%'
|
||||
//- max-width='250px'
|
||||
//- v-else-if='screen === "changePwd"'
|
||||
//- large
|
||||
//- color='primary'
|
||||
//- dark
|
||||
//- @click='changePassword'
|
||||
//- rounded
|
||||
//- :loading='isLoading'
|
||||
//- ) {{ $t('auth:changePwd.proceed') }}
|
||||
//- v-btn(
|
||||
//- width='100%'
|
||||
//- max-width='250px'
|
||||
//- v-else-if='screen === "forgot"'
|
||||
//- large
|
||||
//- color='primary'
|
||||
//- dark
|
||||
//- @click='forgotPasswordSubmit'
|
||||
//- rounded
|
||||
//- :loading='isLoading'
|
||||
//- ) {{ $t('auth:sendResetPassword') }}
|
||||
//- v-spacer
|
||||
//- v-card-actions.pb-3(v-if='screen === "login" && selectedStrategy.key === "local"')
|
||||
//- v-spacer
|
||||
//- a.caption(@click.stop.prevent='forgotPassword', href='#forgot') {{ $t('auth:forgotPasswordLink') }}
|
||||
//- v-spacer
|
||||
//- v-card-actions.pb-3(v-else-if='screen === "forgot"')
|
||||
//- v-spacer
|
||||
//- a.caption(@click.stop.prevent='screen = `login`', href='#cancelforgot') {{ $t('auth:forgotPasswordCancel') }}
|
||||
//- v-spacer
|
||||
|
||||
loader(v-model='isLoading', :color='loaderColor', :title='loaderTitle', :subtitle='$t(`auth:pleaseWait`)')
|
||||
nav-footer(color='grey darken-5', dark-color='grey darken-5')
|
||||
notify
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* global siteConfig */
|
||||
|
||||
// <span>Photo by <a href="https://unsplash.com/@isaacquesada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Isaac Quesada</a> on <a href="/t/textures-patterns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></span>
|
||||
|
||||
import _ from 'lodash'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
import strategiesQuery from 'gql/login/login-query-strategies.gql'
|
||||
import loginMutation from 'gql/login/login-mutation-login.gql'
|
||||
import tfaMutation from 'gql/login/login-mutation-tfa.gql'
|
||||
import changePasswordMutation from 'gql/login/login-mutation-changepassword.gql'
|
||||
import gql from 'graphql-tag'
|
||||
import { sync } from 'vuex-pathify'
|
||||
|
||||
export default {
|
||||
i18nOptions: { namespaces: 'auth' },
|
||||
@@ -191,7 +242,8 @@ export default {
|
||||
return {
|
||||
error: false,
|
||||
strategies: [],
|
||||
selectedStrategy: { key: 'local' },
|
||||
selectedStrategyKey: 'local',
|
||||
selectedStrategy: { key: 'local', strategy: { useForm: true } },
|
||||
screen: 'login',
|
||||
username: '',
|
||||
password: '',
|
||||
@@ -207,40 +259,39 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
activeModal: sync('editor/activeModal'),
|
||||
siteTitle () {
|
||||
return siteConfig.title
|
||||
},
|
||||
isSocialShown () {
|
||||
return this.strategies.length > 1
|
||||
}
|
||||
},
|
||||
logoUrl () { return siteConfig.logoUrl }
|
||||
},
|
||||
watch: {
|
||||
strategies(newValue, oldValue) {
|
||||
this.selectedStrategy = _.find(newValue, ['key', 'local'])
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.isShown = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptEmail.focus()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* SELECT STRATEGY
|
||||
*/
|
||||
selectStrategy (strategy) {
|
||||
this.selectedStrategy = strategy
|
||||
this.selectedStrategy = _.head(newValue)
|
||||
},
|
||||
selectedStrategyKey (newValue, oldValue) {
|
||||
this.selectedStrategy = _.find(this.strategies, ['key', newValue])
|
||||
this.screen = 'login'
|
||||
if (!strategy.useForm) {
|
||||
if (!this.selectedStrategy.strategy.useForm) {
|
||||
this.isLoading = true
|
||||
window.location.assign('/login/' + strategy.key)
|
||||
window.location.assign('/login/' + newValue)
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptEmail.focus()
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.isShown = true
|
||||
this.$nextTick(() => {
|
||||
// this.$refs.iptEmail.focus()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* LOGIN
|
||||
*/
|
||||
@@ -265,7 +316,24 @@ export default {
|
||||
this.isLoading = true
|
||||
try {
|
||||
let resp = await this.$apollo.mutate({
|
||||
mutation: loginMutation,
|
||||
mutation: gql`
|
||||
mutation($username: String!, $password: String!, $strategy: String!) {
|
||||
authentication {
|
||||
login(username: $username, password: $password, strategy: $strategy) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
slug
|
||||
message
|
||||
}
|
||||
jwt
|
||||
mustChangePwd
|
||||
mustProvideTFA
|
||||
continuationToken
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
@@ -334,7 +402,11 @@ export default {
|
||||
} else {
|
||||
this.isLoading = true
|
||||
this.$apollo.mutate({
|
||||
mutation: tfaMutation,
|
||||
mutation: gql`
|
||||
{
|
||||
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
continuationToken: this.continuationToken,
|
||||
securityCode: this.securityCode
|
||||
@@ -377,7 +449,11 @@ export default {
|
||||
this.loaderTitle = this.$t('auth:changePwd.loading')
|
||||
this.isLoading = true
|
||||
const resp = await this.$apollo.mutate({
|
||||
mutation: changePasswordMutation,
|
||||
mutation: gql`
|
||||
{
|
||||
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
continuationToken: this.continuationToken,
|
||||
newPassword: this.newPassword
|
||||
@@ -421,8 +497,26 @@ export default {
|
||||
},
|
||||
apollo: {
|
||||
strategies: {
|
||||
query: strategiesQuery,
|
||||
update: (data) => data.authentication.strategies,
|
||||
query: gql`
|
||||
{
|
||||
authentication {
|
||||
activeStrategies {
|
||||
key
|
||||
strategy {
|
||||
key
|
||||
logo
|
||||
color
|
||||
icon
|
||||
useForm
|
||||
}
|
||||
displayName
|
||||
order
|
||||
selfRegistration
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
update: (data) => _.sortBy(data.authentication.activeStrategies, ['order']),
|
||||
watchLoading (isLoading) {
|
||||
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'login-strategies-refresh')
|
||||
}
|
||||
@@ -433,61 +527,73 @@ export default {
|
||||
|
||||
<style lang="scss">
|
||||
.login {
|
||||
background-color: mc('indigo', '900');
|
||||
background-image: url('../static/svg/motif-blocks.svg');
|
||||
background-repeat: repeat;
|
||||
background-size: 200px;
|
||||
background-image: url('/_assets/img/splash/1.jpg');
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: loginBgReveal 20s linear infinite;
|
||||
|
||||
@include keyframes(loginBgReveal) {
|
||||
0% {
|
||||
background-position-y: 0;
|
||||
}
|
||||
100% {
|
||||
background-position-y: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-image: url('../static/svg/motif-overlay.svg');
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
opacity: .5;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
> .container {
|
||||
&-sd {
|
||||
background-color: rgba(255,255,255,.8);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border-left: 1px solid rgba(255,255,255,.85);
|
||||
border-right: 1px solid rgba(255,255,255,.85);
|
||||
width: 450px;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
margin-left: 5vw;
|
||||
|
||||
@at-root .no-backdropfilter & {
|
||||
background-color: rgba(255,255,255,.95);
|
||||
}
|
||||
|
||||
@include until($tablet) {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&-logo {
|
||||
padding: 12px 0 0 12px;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
background-color: #222;
|
||||
margin-left: 12px;
|
||||
border-bottom-left-radius: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
height: 58px;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-shadow: .5px .5px #FFF;
|
||||
}
|
||||
|
||||
.social-login-btn {
|
||||
cursor: pointer;
|
||||
transition: opacity .2s ease;
|
||||
&:hover {
|
||||
opacity: .8;
|
||||
}
|
||||
margin: .25rem 0;
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
bottom: 0;
|
||||
path {
|
||||
fill: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.v-text-field.centered input {
|
||||
&-subtitle {
|
||||
padding: 24px 12px 12px 12px;
|
||||
color: #111;
|
||||
font-weight: 500;
|
||||
text-shadow: 1px 1px rgba(255,255,255,.5);
|
||||
background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.15));
|
||||
text-align: center;
|
||||
border-bottom: 1px solid rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
&-list {
|
||||
border-top: 1px solid rgba(255,255,255,.85);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
&-form {
|
||||
padding: 12px;
|
||||
border-top: 1px solid rgba(255,255,255,.85);
|
||||
}
|
||||
|
||||
&-main {
|
||||
flex: 1 0 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user