Skip to content

Instantly share code, notes, and snippets.

@iErik
Created June 20, 2018 21:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iErik/78cf58d92da341f45878d2e582b29610 to your computer and use it in GitHub Desktop.
Save iErik/78cf58d92da341f45878d2e582b29610 to your computer and use it in GitHub Desktop.
<template>
<div class="activate-form">
<!-- modais -->
<login-modal
:opened="false"
title="Bem vindo ao clube!"
maintext="Parabéns, Seja bem vindo ao Clube!"
text="Você está pronto para encontrar os melhores descontos em mais de [13948] parceiros"
type="happy"
button="Aproveitar o clube"
/>
<div class="header">
<c-image
class="logo-form"
src="~@/assets/img/alelo-logo.svg"
placeholder="~@/assets/img/alelo-logo.svg"
width="80px"
height="50px"
/>
</div>
<div class="content">
<div class="title">
<c-title icon="key-hole">
Ativar conta
</c-title>
</div>
<form class="form" @submit.prevent="$emit('submit', userData)">
<div class="content-top">
<!-- Só é exibido caso usuario tenha acesso a outros clubes -->
<div class="club-list" v-if="credentials.password && companies.length">
<div class="list">
<p class="featured">Você esta nos clubes</p>
<p class="club" v-for="company in companies">{{ company.name }}</p>
</div>
<hr>
<div class="attention">
<p class="featured">Atenção</p>
<p class="text">Todas as informações inseridas serão alteradas em todas as contas do clube de benefício atrelados a este CPF</p>
</div>
</div>
<div class="wrapper-user">
<label class="user">
<c-image
class="image"
:src="avatarFile"
placeholder="~@/assets/img/userPlaceholder.svg"
width="85px"
height="85px"
ref="avatarPreview"
/>
<c-button
class="btn-pic"
icon="camera3"
type="button"
size"size"
@click="$refs['inputFile'].click()"
/>
<input
type="file"
accept="image/*"
v-show="false"
ref="inputFile"
@input="uploadAvatar"
/>
<span class="cpf">CPF {{ credentials.document }}</span>
</label>
</div>
</div>
<!-- nome -->
<c-input
label="Nome"
placeholder="Insira seu nome"
class="input-data"
name="nome"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('name') ? 'O campo de nome é obrigatório' : ''"
v-model="userData.name"
/>
<!-- sobrenome -->
<c-input
label="Sobrenome"
placeholder="Insira seu sobrenome"
class="input-data"
name="sobrenome"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('last_name') ? 'O campo de sobrenome é obrigatório' : ''"
v-model="userData.last_name"
/>
<!-- e-mail -->
<c-input
label="E-Mail"
placeholder="Insira seu e-mail"
class="input-data"
type="email"
name="email"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('email') ? 'O campo de email é obrigatório' : ''"
v-model="userData.email"
/>
<!-- celular -->
<c-input
label="Celular"
placeholder="Insira seu numero"
:mask="'(##) #####-####'"
class="input-data"
name="celular"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('phone') ? 'O campo de celular é obrigatório' : ''"
v-model="userData.phone"
/>
<!-- data de nascimento -->
<c-input
label="Data de Nascimento"
class="input-data"
name="date"
mask="##/##/####"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('phone') ? 'A data inserida não é válida' : ''"
:value="birthdayDate"
@input="updateBirthday"
/>
<!-- genero -->
<c-select
class="input bank"
label="Gênero"
placeholder="Mulher cisgênero"
:items="genderOptions"
track-by="value"
display-by="name"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('gender') ? 'O campo de gênero é obrigatório' : ''"
:value="userData.gender"
@input="userData.gender = $event"
/>
<!-- estado/cidade -->
<div class="select-group">
<c-select
class="input bank"
label="Estado"
track-by="sigla"
display-by="sigla"
placeholder="Estado"
:hasError="forceError"
:validation="!isValid('state') ? 'O campo de estado é obrigatório' : ''"
:items="stateOptions"
:disabled="isLoading"
:value="userData.state"
@input="updateState"
/>
<c-select
class="input bank"
label="Cidade"
placeholder="Cidade"
track-by="name"
display-by="name"
:hasError="forceError"
:validation="!isValid('city') ? 'O campo de cidade é obrigatório' : ''"
:items="cityOptions"
:disabled="isLoading"
:value="userData.city"
@input="userData.city = $event"
/>
</div>
<!-- senha (Só é exibido caso seja primeiro acesso/sem acesso a outros clubes) -->
<c-input
required
v-if="askPassword"
label="Senha"
placeholder="Insira seu senha"
type="password"
class="input-data"
name="password"
:hasError="forceError"
:disabled="isLoading"
:validation="!isValid('new_password') ? 'O campo de senha é obrigatório' : ''"
v-model="userData.new_password"
/>
<!-- confirmar senha (Só é exibido caso seja primeiro acesso/sem acesso a outros clubes) -->
<c-input
required
v-if="askPassword"
label="CONFIRMAR SENHA"
placeholder="Confirme sua senha"
type="password"
class="input-data"
name="confirmpassword"
:hasError="forceError"
:disabled="isLoading"
:validation="isConfirmPasswordInvalid ? 'O campo de confirmação de senha está incorreto' : ''"
v-model="userData.confirm_password"
/>
<hr>
<div class="underform">
<!-- Só é exibido caso usuario tenha acesso a outros clubes -->
<div class="text-group">
<p class="maintext">SENHA</p>
<p class="text">A sua senha será a mesma cadastrada antes, caso não se lembre, clique em <a href="#">esqueci minha senha</a>.</p>
</div>
<hr>
<p class="terms">Ao clicar em "Ativar Conta" você concorda com nosso <a href="#">
Termo de Usuário
</a>
e que leu a nossa <a href="#">política de Dados</a>, incluindo nosso uso de cookies.
</p>
<!-- botão de ativar conta -->
<c-button
class="btn"
icon="chevron-right"
size="lg"
primary
@click="validate"
:disabled="isLoading || isFormInvalid"
>
Ativar conta
</c-button>
</div>
</form>
</div>
</div>
</template>
<script>
import LoginModal from '@/components/Login/LoginModal'
import { states } from '@helpers/statesCities'
const genderOptions = [
{ name: 'Feminino', value: 'feminino' },
{ name: 'Masculino', value: 'masculino' },
{ name: 'Outros', value: 'outro' }
]
const USER_DEFAULT = {
name: '',
last_name: '',
email: '',
phone: '',
birthday: '',
gender: '',
state: states[0].sigla,
city: states[0].cidades[0],
}
export default {
components: { LoginModal },
props: {
credentials: {
type: Object,
required: true
},
companies: {
type: Array,
required: true
},
isLoading: {
type: Boolean,
required: true,
},
error: {
type: Object,
required: true
}
},
data () {
const credentials = Object.keys(this.credentials)
.reduce((acc, key) => ({
...acc,
...( !!this.credentials[key] ? { [key]: this.credentials[key] } : {} )
}), {})
return {
avatarFile: this.credentials.avatar || null,
forceError: !!this.credentials.password,
touched: false,
genderOptions,
userData: { ...USER_DEFAULT, avatar: null, ...credentials }
}
},
computed: {
isDirty () {
if (this.touched) return true
this.touched = this.document
return this.touched
},
cityOptions () {
const state = states.find(s => s.sigla === this.userData.state)
return (state || {}).cidades.map(c => ({ name: c }))
},
stateOptions () {
return states.map(({ sigla, nome }) => ({ sigla, nome }))
},
askPassword () {
return !this.credentials.password
},
isFormInvalid() {
const requireds =
[ ...Object.keys(USER_DEFAULT)
, ...(this.askPassword ? [ 'new_password', 'confirm_password' ] : [])
]
return requireds.some(field => !this.isValid(field))
},
isConfirmPasswordInvalid () {
if (this.credentials.password) return false
const isValid = this.userData.confirm_password === this.userData.new_password
return this.forceError && !isValid
},
birthdayDate () {
const date = (new Date(this.userData.birthday || '')).toLocaleDateString('pt-BR')
return date === 'Invalid Date' ? '' : date
},
},
methods: {
isValid (key) {
const fields =
{ name: /\w+/
, last_name: /\w+/
, email: /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
, phone: /^\([1-9]{2}\) [2-9][0-9]{3,4}\-[0-9]{4}$/
, birthday: /^[0-9]{4}[\-][0-9]{2}[\-][0-9]{2}$/
, gender: /^(masculino|feminino|outro)$/
, state: /^[A-Z]{2}$/
, city: /\w+/
, new_password: /^.+$/
, confirm_password: /^.+$/
}
return fields[key].test(this.userData[key] || '')
},
updateState (state) {
if (this.userData.state === state) return
this.userData.state = state
this.userData.city = ''
},
updateBirthday (ev) {
const re = /^[0-9]{2}[\/][0-9]{2}[\/][0-9]{4}$/g
if (!re.test(ev)) return this.userData.birthday = null
const values = ev.split('/')
const date = new Date(values[2], values[1] - 1, values[0])
this.userData.birthday = date.toISOString().slice(0,10)
},
uploadAvatar (ev) {
if (!ev.target['files'][0]) return
this.userData.avatar = ev.target['files'][0]
const reader = new FileReader()
reader.onload = (e) => this.avatarFile = e.target.result
reader.readAsDataURL(this.userData.avatar)
},
validate (ev) {
if (this.forceError || this.isDirty) return true
else ev.preventDefault()
this.touched = true
this.forceError = true
}
}
}
</script>
<style lang="scss">
@import '~@style/reference';
.activate-form {
& >.header {
width: 100%;
background-color: #fff;
display: flex;
justify-content: center;
padding: 15px;
}
& >.content {
display: flex;
flex-direction: column;
align-items: center;
background-image: url('~@assets/img/BGform.png');
background-repeat: no-repeat;
background-size: cover;
background-position: top;
padding: 0 10px;
hr {
margin: 0 auto;
margin-top: 30px;
margin-bottom: 30px;
opacity: 0.2;
background-color: #121E48;
}
& >.title {
min-width: 280px;
margin-top: 20px;
margin-bottom: 45px;
@media only screen and (min-width: 600px) {
width: 500px;
}
}
& >.form {
min-width: 280px;
margin-bottom: 100px;
@media only screen and (min-width: 600px) {
width: 378px;
}
& >.content-top {
text-align: center;
& >.club-list {
& >.list {
& >.club {
font-size: 12px;
font-weight: bold;
color: rgba(18,30,72,0.8);
opacity: 0.8;
text-transform: uppercase;
margin-bottom: 5px;
}
}
& >.attention {
margin-top: 40px;
margin-bottom: 30px;
& >.text {
margin: 0 auto;
margin-top: 15px;
width: 70%;
font-size: 14px;
color: rgba(18,30,72,0.5);
}
}
}
& > .wrapper-user > .user {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 40px;
& >.image {
border-radius: 50%;
}
& >.btn-pic {
width: 30px;
transform: translate(100%, -100%);
background-color: #fff;
}
& >.cpf {
color: #121E48;
font-size: 12px;
font-weight: bold;
opacity: 0.8;
}
}
}
.featured {
margin: 0 auto;
text-align: center;
display: table;
font-weight: 600;
opacity: 0.8;
margin-bottom: 10px;
color: rgb(18,30,72);
font-size: 14px;
&::after {
width: 80%;
margin: 0 auto;
height: 3px;
display: block;
margin-top: 5px;
background-color: $secondary-color-placeholder;
content: '';
}
}
& >.select-group {
display: flex;
justify-content: space-between;
.c-select {
width: 40%;
}
}
& >.input-data, .bank {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
& >.label {
width: 30%;
display: flex;
justify-content: flex-end;
align-items: center;
margin: 0 10px 0 0;
white-space: nowrap;
position: absolute;
right: 100%;
top: 50%;
transform: translateY(-50%);
}
& > .validation {
position: absolute;
top: 100%;
}
div.input {
width: 100%;
}
@media screen and (max-width: 675px) {
& > .label {
position: initial;
right: initial;
top: initial;
transform: none;
justify-content: flex-start;
}
}
}
& >.underform {
text-align: center;
hr { width: 100%; }
a { color: #397A5F; }
& >.text-group {
//width: 70%;
margin: 0 auto;
text-align: left;
& >.maintext {
font-size: 12px;
color: rgba(18,30,72,0.8);
font-weight: 500;
margin-bottom: 5px;
}
& >.text {
font-size: 14px;
color: rgba(18,30,72,0.5);
}
}
& >.terms {
font-size: 12px;
//width: 70%;
margin: 0 auto;
margin-bottom: 30px;
}
& >.btn {
max-width: 150px;
font-size: 12px;
padding: 0 15px;
}
}
}
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment