Commit dcd0a86e authored by TTS Kieu Tuan Anh's avatar TTS Kieu Tuan Anh

Merge branch 'dev' into 'feature/UI-vuetify'

# Conflicts:
#   pages/login.vue
parents 0c71bd4b dda1f1e8
<template> <template>
<div>
<Nuxt /> <Nuxt />
</div>
</template> </template>
<script> <script>
export default {}; export default {
computed: {
theme () {
return (this.$vuetify.theme.dark) ? 'dark' : 'light'
}
}
}
</script> </script>
<style>
</style>
\ No newline at end of file
...@@ -94,6 +94,6 @@ export default { ...@@ -94,6 +94,6 @@ export default {
} }
} }
] ]
}, }
} }
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
"vue": "^2.7.10", "vue": "^2.7.10",
"vue-server-renderer": "^2.7.10", "vue-server-renderer": "^2.7.10",
"vue-template-compiler": "^2.7.10", "vue-template-compiler": "^2.7.10",
"vuelidate": "^0.7.7",
"vuetify": "^2.6.10" "vuetify": "^2.6.10"
}, },
"devDependencies": { "devDependencies": {
......
<template> <template>
<div style="background-color: #8fc2ff"> <v-app :style="{background: $vuetify.theme.themes.light.background}">
<Notification :message="error" v-if="error" /> <div class="body">
<div <form class="login-form">
class="container"
style="
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #8fc2ff;
"
>
<div id="form-login">
<form @submit.prevent="login">
<NuxtLogo /> <NuxtLogo />
<input <v-text-field
id="email"
v-model="email" v-model="email"
type="email" :error-messages="emailErrors"
class="form-control mb-3" label="E-mail"
placeholder="Email"
required required
@input="$v.email.$touch()"
@blur="$v.email.$touch()"
/> />
<input <v-text-field
id="password"
v-model="password" v-model="password"
type="password" :error-messages="passwordErrors"
class="form-control mb-3" :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
placeholder="password" :type="showPassword ? 'text' : 'password'"
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);" label="Password"
maxlength="16" hint="At least 6 characters"
min="6"
required required
@input="$v.password.$touch()"
@blur="$v.password.$touch()"
@click:append="showPassword = !showPassword"
/> />
<b-form-checkbox <v-checkbox
id="checkbox-1" v-model="checkbox"
v-model="status" color="green"
name="checkbox-1" label="Remember me"
value="accepted" required
class="mb-2" @change="$v.checkbox.$touch()"
unchecked-value="not_accepted" @blur="$v.checkbox.$touch()"
> />
Remember me <v-btn class="mr-4" @click="login">
</b-form-checkbox> Login
<div class="col text-center"> </v-btn>
<button <v-btn @click="clear">
class="w-30 btn btn-lg btn-primary text-center" clear
type="submit" </v-btn>
> <p class="pt-3">
Sign in Don't have an account?
</button> <router-link to="/register">
</div> Sign up
</router-link>
</p>
</form> </form>
</div> </div>
</div> </v-app>
</div>
</template> </template>
<script> <script>
export default { export default {
layout: "none", // eslint-disable-next-line no-undef
}; components: { NuxtLogo }
}
</script> </script>
<script> <script>
import { reactive } from "vue"; import { validationMixin } from 'vuelidate'
import { required, minLength, email } from 'vuelidate/lib/validators'
export default { export default {
layout: "none", dark: false,
data: () => { mixins: [validationMixin],
return { layout: 'empty',
email: "", validations: {
password: "", email: { required, email },
status: null, password: { required, minLength: minLength(6) },
error: null, checkbox: {
}; checked (val) {
return val
}
}
},
data: () => ({
email: '',
password: '',
showPassword: false,
checkbox: false
}),
computed: {
emailErrors () {
const errors = []
if (!this.$v.email.$dirty) {
return errors
}
!this.$v.email.email && errors.push('Must be valid e-mail')
!this.$v.email.required && errors.push('E-mail is required')
return errors
},
passwordErrors () {
const errors = []
if (!this.$v.password.$dirty) {
return errors
}
!this.$v.password.minLength && errors.push('Password must be at least 6 charactors')
!this.$v.password.required && errors.push('Password is required')
return errors
}
}, },
methods: { methods: {
async login() { submit () {
this.$v.$touch()
},
clear () {
this.$v.$reset()
this.email = ''
this.password = ''
this.checkbox = false
},
async login () {
try { try {
const resp = await fetch("http://127.0.0.1:8000/api/login", { const resp = await fetch('http://127.0.0.1:8000/api/login', {
method: "POST", method: 'POST',
headers: { headers: {
"Content-Type": "application/json", 'Content-Type': 'application/json',
Accept: "application/json", Accept: 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({
email: this.email, email: this.email,
password: this.password, password: this.password,
status: this.status, status: this.status
}), })
}).then((response) => { }).then((response) => {
return response.json(); return response.json()
}); })
console.log(resp.status); console.log(resp.status)
localStorage.setItem("token", resp.data.bearer_token); localStorage.setItem('token', resp.data.bearer_token)
this.$auth.$storage.setUniversal("token", resp.data.bearer_token); this.$auth.$storage.setUniversal('token', resp.data.bearer_token)
this.$auth.$storage.setUniversal("userName", resp.data.name); this.$auth.$storage.setUniversal('userName', resp.data.name)
this.$auth.$storage.setUniversal("loggedIn", "true"); this.$auth.$storage.setUniversal('loggedIn', 'true')
if (resp.status == "success") { if (resp.status == 'success') {
this.$toast.success("Successfully authenticated", { this.$toast.success('Successfully authenticated', {
duration: 2000, duration: 2000
}); })
this.$router.push("home"); this.$router.push('home')
} }
} catch (e) { } catch (e) {
// this.error = "Username or Password not valid"; this.$toast.error('Username or Password not valid', {
this.$toast.error("Username or Password not valid", { duration: 2000
duration: 2000, })
}); this.$router.push('/login')
this.$router.push("/login");
} }
},
checkForm: function (e) {
if (this.name && this.age) {
return true;
} }
this.errors = [];
if (!this.name) {
this.errors.push("Name required.");
} }
if (!this.age) { }
this.errors.push("Age required.");
}
e.preventDefault();
},
},
};
</script> </script>
<style scoped> <style scoped>
#form-login { .body {
height: 50%;
width: 25%;
padding: 12px;
padding-top: 60px;
display: flex; display: flex;
justify-content: center; justify-content: center;
background-color: white; text-align: center;
border-radius: 3%; align-items: center;
font-weight: 600; background-color: #8fc2ff;
height: 100vh;
} }
.login-form{
width: 27%;
border: #8fc2ff 1px solid;
background-color: #111f70;
border-radius: 1rem;
padding: 2rem 1rem;
border-radius: 1rem;
}
</style> </style>
<!-- <template> <template>
<div style="background-color: #8fc2ff"> <div class="body">
<div class="container" style=" <form class="login-form" @submit.prevent="signup">
display: flex; <h1 class="h3 mb-3 fw-normal" style="text-align: center">
justify-content: center;
align-items: center;
height: 100vh;
background-color: #8fc2ff;
">
<div id="form-logout">
<form @submit.prevent="signin">
<h1 class="h3 mb-3 fw-normal" style="text-align: center">Sign up</h1>
<label>Name :</label>
<input type="text" class="form-control mb-2" placeholder="name" v-model="name" max="255" min="1" required />
<label>Email :</label>
<input type="email" class="form-control mb-2" placeholder="Email" v-model="email" required />
<label>Password :</label>
<input type="password" class="form-control mb-2" placeholder="password" v-model="password" required />
<label>Confirm Password :</label>
<input type="password" class="form-control mb-2" placeholder="Confirm password" v-model="confirm_password"
required />
<div class="button">
<button class="w-50 btn btn-lg btn-primary" type="submit">
Sign up Sign up
</button> </h1>
</div> <v-text-field
v-model="name"
:error-messages="nameErrors"
label="Name"
required
@input="$v.name.$touch()"
@blur="$v.name.$touch()"
/>
<v-text-field
v-model="email"
:error-messages="emailErrors"
label="E-mail"
required
@input="$v.email.$touch()"
@blur="$v.email.$touch()"
/>
<v-text-field
v-model="password"
:error-messages="passwordErrors"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showPassword ? 'text' : 'password'"
label="Password"
hint="At least 6 characters"
required
@input="$v.password.$touch()"
@blur="$v.password.$touch()"
@click:append="showPassword = !showPassword"
/>
<v-text-field
v-model="password_confirmation "
:error-messages="confirmPasswordErrors"
:append-icon="showConfirmPassword ? 'mdi-eye' : 'mdi-eye-off'"
:type="showConfirmPassword ? 'text' : 'password'"
label="confirmPassword"
hint="At least 6 characters"
required
@input="$v.password_confirmation .$touch()"
@blur="$v.password_confirmation .$touch()"
@click:append="showConfirmPassword = !showConfirmPassword"
/>
<v-btn class="mr-4" type="submit">
Sign up
</v-btn>
<v-btn @click="clear">
clear
</v-btn>
<p class="pt-3">
Already have an account?
<router-link to="/login">
Login
</router-link>
</p>
</form> </form>
</div> </div>
</div>
</div>
</template> </template>
<script> <script>
import { validationMixin } from 'vuelidate'
import { required, minLength, maxLength, email, sameAs } from 'vuelidate/lib/validators'
export default { export default {
layout: 'none', dark: false,
data: () => { mixins: [validationMixin],
return { layout: 'empty',
validations: {
name: { required, minLength: minLength(1), maxLength: maxLength(255) },
email: { required, email },
password: { required, minLength: minLength(6) },
password_confirmation: { required, sameAsPassword: sameAs('password') }
},
data: () => ({
name: '', name: '',
email: '', email: '',
password: '', password: '',
confirm_password: '', password_confirmation: '',
showPassword: false,
showConfirmPassword: false
}),
computed: {
nameErrors () {
const errors = []
if (!this.$v.name.$dirty) {
return errors
}
!this.$v.name.required && errors.push('E-mail is required')
!this.$v.name.minLength && errors.push('Name must be at least 1 character')
!this.$v.name.maxLength && errors.push('Name can not be longer than 255 characters')
return errors
},
emailErrors () {
const errors = []
if (!this.$v.email.$dirty) {
return errors
}
!this.$v.email.email && errors.push('Must be valid e-mail')
!this.$v.email.required && errors.push('E-mail is required')
return errors
},
passwordErrors () {
const errors = []
if (!this.$v.password.$dirty) {
return errors
} }
!this.$v.password.minLength && errors.push('Password must be at least 6 charactors')
!this.$v.password.required && errors.push('Password is required')
return errors
}, },
confirmPasswordErrors () {
const errors = []
if (!this.$v.password_confirmation.$dirty) {
return errors
}
!this.$v.password_confirmation.required && errors.push('Password confirmation is required')
!this.$v.password_confirmation.sameAsPassword && errors.push('Password and confirm password does not match')
return errors
}
},
methods: { methods: {
signin() { submit () {
fetch('http://127.0.0.1:8000/api/register', { this.$v.$touch()
method: 'POST', },
headers: { clear () {
'Content-Type': 'application/json', this.$v.$reset()
Accept: 'application/json', this.name = ''
this.email = ''
this.password = ''
this.password_confirmation = ''
}, },
body: JSON.stringify({ async signup () {
try {
await this.$axios.post('http://127.0.0.1:8000/api/register', {
name: this.name, name: this.name,
email: this.email, email: this.email,
password: this.password, password: this.password,
confirm_password: this.confirm_password, password_confirmation: this.password_confirmation
}), }
).then((resp) => {
if (resp.data.status === 'success') {
this.$toast.success('Register successfully', {
duration: 2000
}) })
this.$router.push("/login") this.$router.push('login')
}, }
}, })
} catch (error) {
this.$toast.error(error.response.data.message, {
duration: 2000
})
}
}
}
} }
</script> </script>
<style scoped> <style>
#form-logout { .body {
height: 60%;
width: 30%;
/* border: 1px solid black; */
padding: 12px;
padding-top: 30px;
display: flex; display: flex;
justify-content: center; justify-content: center;
background-color: white; text-align: center;
border-radius: 3%;
font-weight: 600;
}
.btn {
align-items: center; align-items: center;
justify-content: center; background-color: #8fc2ff;
margin-left: 50px; height: 100vh;
}
.login-form{
width: 27%;
border: #8fc2ff 1px solid;
background-color: #111f70;
border-radius: 1rem;
padding: 2rem 1rem;
border-radius: 1rem;
} }
</style> --> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment