219 lines
5.6 KiB
Vue
219 lines
5.6 KiB
Vue
<template>
|
|
<v-container fluid fill-height class="d-flex align-center justify-center">
|
|
<v-row>
|
|
<v-col
|
|
sm="6"
|
|
cols="12"
|
|
align-self="stretch"
|
|
class="d-flex justify-sm-end justify-center pb-10 pb-sm-0 pr-sm-10"
|
|
>
|
|
<div class="d-flex flex-column align-end justify-space-around">
|
|
<v-card
|
|
color="rgb(0, 0, 0, 0)"
|
|
flat
|
|
class="d-flex align-center justify-center flex-column"
|
|
width="100%"
|
|
>
|
|
<div
|
|
class="d-flex flex-column align-sm-end align-center justify-center"
|
|
:class="alignOnViewport"
|
|
>
|
|
<h1 class="whiteText title">
|
|
Savvy Firebase Tutorial
|
|
</h1>
|
|
<p class="whiteText mb-0 mt-2">Log in or create an account.</p>
|
|
</div>
|
|
</v-card>
|
|
<v-card color="rgb(0, 0, 0, 0)" flat width="100%">
|
|
<div
|
|
class="text-align-right d-flex flex-column align-sm-end align-center justify-center"
|
|
>
|
|
<p class="whiteText mb-0">Don't have an account? Create one.</p>
|
|
</div>
|
|
</v-card>
|
|
</div>
|
|
</v-col>
|
|
<v-col
|
|
cols="12"
|
|
sm="6"
|
|
class="d-flex justify-sm-start justify-center pl-sm-10"
|
|
>
|
|
<v-card
|
|
color="rgb(0, 0, 0, 0)"
|
|
flat
|
|
class="d-flex align-center flex-column"
|
|
>
|
|
<v-icon color="white" size="3em" class="pb-4"
|
|
>mdi-account-circle</v-icon
|
|
>
|
|
<v-form
|
|
v-model="valid"
|
|
ref="form"
|
|
class="pt-4 d-flex flex-column align-center justify-start"
|
|
>
|
|
<v-text-field
|
|
v-for="field in formFields"
|
|
:key="field.name"
|
|
outlined
|
|
rounded
|
|
required
|
|
:type="field.password ? 'password' : 'text'"
|
|
background-color="rgb(100%, 100%, 100%, 10%)"
|
|
color="rgb(100%, 100%, 100%, 20%)"
|
|
class="white-placeholder full-width"
|
|
v-model="field.value"
|
|
:rules="field.rules"
|
|
:label="field.placeholder"
|
|
:success="!!field.value"
|
|
@click:append="field.showIconData = !field.showIconData"
|
|
>
|
|
<template #prepend-inner>
|
|
<v-icon color="white" class="pr-3">
|
|
{{ field.prependIcon }}
|
|
</v-icon>
|
|
</template>
|
|
<template #append>
|
|
<div class="innerIcon">
|
|
<v-btn
|
|
v-if="field.appendIconShow"
|
|
icon
|
|
text
|
|
x-small
|
|
@click="
|
|
() => {
|
|
field.showIconData = !field.showIconData;
|
|
field.password = !field.password;
|
|
}
|
|
"
|
|
>
|
|
<v-icon color="white">
|
|
{{
|
|
field.showIconData
|
|
? field.appendIconShow
|
|
: field.appendIconHide
|
|
}}
|
|
</v-icon>
|
|
</v-btn>
|
|
</div>
|
|
</template>
|
|
</v-text-field>
|
|
<v-btn
|
|
depressed
|
|
large
|
|
color="primary"
|
|
class="lighten-3"
|
|
:loading="load"
|
|
@click="submit"
|
|
>Submit</v-btn
|
|
>
|
|
</v-form>
|
|
<p class="whiteText mb-0 pt-5">Forgot password?</p>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "LoginForm",
|
|
data() {
|
|
return {
|
|
valid: false,
|
|
load: false,
|
|
formFields: [
|
|
{
|
|
name: "Email",
|
|
rules: [
|
|
v => !!v || "You must enter an email address.",
|
|
v => /.+@.+/.test(v) || "Email is not valid."
|
|
],
|
|
placeholder: "Email",
|
|
successmessage: "Email is valid.",
|
|
prependIcon: "mdi-at",
|
|
value: ""
|
|
},
|
|
{
|
|
name: "Password",
|
|
rules: [
|
|
v => !!v || "You must enter a password.",
|
|
v => (v && v.length >= 8) || "Minimum 8 characters."
|
|
],
|
|
placeholder: "Password",
|
|
successmessage: "Password is valid.",
|
|
prependIcon: "mdi-lock",
|
|
appendIconShow: "mdi-eye",
|
|
appendIconHide: "mdi-eye-off",
|
|
showIconData: false,
|
|
value: "",
|
|
password: true
|
|
}
|
|
]
|
|
};
|
|
},
|
|
methods: {
|
|
async submit() {
|
|
this.load = !this.load;
|
|
console.log("loading");
|
|
if (this.$refs.form.validate()) {
|
|
console.log(`Email: ${this.formFields[0].value}`);
|
|
console.log(`Password: ${this.formFields[1].value}`);
|
|
} else {
|
|
console.log("Not valid");
|
|
this.load = !this.load;
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
alignOnViewport() {
|
|
return this.$vuetify.breakpoint.xsOnly
|
|
? "text-align-center"
|
|
: "text-align-right";
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
// @import "../../scss/_variables.scss";
|
|
|
|
.whiteText {
|
|
color: white;
|
|
}
|
|
|
|
.red-text {
|
|
color: red;
|
|
}
|
|
|
|
.full-width {
|
|
width: 100%;
|
|
}
|
|
|
|
.text-align-right {
|
|
text-align: right;
|
|
}
|
|
|
|
.text-align-center {
|
|
text-align: center;
|
|
}
|
|
|
|
.title {
|
|
font-size: 2rem !important;
|
|
}
|
|
|
|
.white-placeholder ::v-deep input::placeholder {
|
|
color: white !important;
|
|
opacity: 1;
|
|
}
|
|
|
|
.white-placeholder ::v-deep input {
|
|
color: white !important;
|
|
opacity: 1;
|
|
}
|
|
|
|
.white-placeholder ::v-deep .v-label {
|
|
color: white !important;
|
|
opacity: 1;
|
|
}
|
|
</style>
|