mirror of
https://github.com/Dannecron/ich-lerne-deutsch.git
synced 2025-12-25 21:02:35 +03:00
Add profile page. Extend working with firebase.
Some refactoring of validation rules and page logic.
This commit is contained in:
166
src/components/User/ProfileData.vue
Normal file
166
src/components/User/ProfileData.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-card>
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-0">
|
||||
<v-icon>person</v-icon>
|
||||
{{ userName }}
|
||||
</h3>
|
||||
<h3 class="headline mb-0">
|
||||
<v-icon>email</v-icon>
|
||||
{{ userEmail }}
|
||||
</h3>
|
||||
</div>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn flat color="orange" @click.stop="dialog = true">Изменить</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
<v-dialog v-model="dialog" persistent max-width="550px">
|
||||
<v-card>
|
||||
<v-card-title class="headline">Изменить данные?</v-card-title>
|
||||
<v-card-text>
|
||||
<v-alert
|
||||
type="warning"
|
||||
class="mb-2"
|
||||
:value="getError"
|
||||
>
|
||||
{{ getError }}
|
||||
</v-alert>
|
||||
|
||||
<v-form id="edit-profile-form" v-model="isValid" @submit.prevent="changeUserData">
|
||||
<v-text-field
|
||||
prepend-icon="email"
|
||||
v-model="email"
|
||||
name="login"
|
||||
label="Email"
|
||||
type="email"
|
||||
required
|
||||
:rules="emailRules"
|
||||
>
|
||||
</v-text-field>
|
||||
|
||||
<v-text-field
|
||||
prepend-icon="lock"
|
||||
v-model="password"
|
||||
name="password"
|
||||
label="Пароль"
|
||||
type="password"
|
||||
required
|
||||
:rules="passwordRules"
|
||||
>
|
||||
</v-text-field>
|
||||
|
||||
<h3>Какие данные нужно изменить?</h3>
|
||||
<v-radio-group v-model="changeType" row>
|
||||
<v-radio label="Имя" value="changeName"></v-radio>
|
||||
<v-radio label="Email" value="changeEmail"></v-radio>
|
||||
<v-radio label="Пароль" value="changePassword"></v-radio>
|
||||
</v-radio-group>
|
||||
|
||||
<v-text-field
|
||||
v-if="changeType == 'changeName'"
|
||||
prepend-icon="person"
|
||||
v-model="newName"
|
||||
name="newName"
|
||||
type="text"
|
||||
label="Новое имя"
|
||||
required
|
||||
:rules="nameRules"
|
||||
>
|
||||
</v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-if="changeType == 'changeEmail'"
|
||||
prepend-icon="email"
|
||||
v-model="newEmail"
|
||||
name="newLogin"
|
||||
type="email"
|
||||
label="Новый email"
|
||||
required
|
||||
:rules="emailRules"
|
||||
>
|
||||
</v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-if="changeType == 'changePassword'"
|
||||
prepend-icon="lock"
|
||||
v-model="newPassword"
|
||||
name="newPassword"
|
||||
type="password"
|
||||
label="Новый пароль"
|
||||
required
|
||||
:rules="passwordRules"
|
||||
>
|
||||
</v-text-field>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="green darken-1" flat @click="dialog = false">Отмена</v-btn>
|
||||
<v-btn
|
||||
type="submit"
|
||||
color="green darken-1"
|
||||
form="edit-profile-form"
|
||||
flat
|
||||
:disabled="getProcessing || !isValid"
|
||||
>
|
||||
Изменить
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { emailRules, passwordRules, nameRules } from "@/helpers";
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
email: null,
|
||||
password: null,
|
||||
newEmail: null,
|
||||
newPassword: null,
|
||||
newName: null,
|
||||
|
||||
changeType: 'changeName',
|
||||
dialog: false,
|
||||
isValid: false,
|
||||
|
||||
emailRules,
|
||||
passwordRules,
|
||||
nameRules
|
||||
}),
|
||||
computed: {
|
||||
...mapGetters(['userName', 'userEmail', 'getProcessing', 'getError']),
|
||||
},
|
||||
methods: {
|
||||
changeUserData() {
|
||||
const {
|
||||
email,
|
||||
password,
|
||||
newEmail,
|
||||
newPassword,
|
||||
newName,
|
||||
changeType,
|
||||
} = this;
|
||||
|
||||
this.$store.dispatch('changeUserProfileData', {
|
||||
email,
|
||||
password,
|
||||
newEmail,
|
||||
newPassword,
|
||||
newName,
|
||||
changeType,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
13
src/helpers/formRules.js
Normal file
13
src/helpers/formRules.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const emailRules = [
|
||||
(value) => !!value || 'Пожалуйста, введите email',
|
||||
(value) => /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value) || 'Неправильный email',
|
||||
];
|
||||
|
||||
export const passwordRules = [
|
||||
(value) => !!value || 'Пожалуйста введите пароль',
|
||||
(value) => (value && value.length >= 6) || 'Пароль слишком короткий - минимум 6 символов',
|
||||
];
|
||||
|
||||
export const nameRules = [
|
||||
(value) => !!value || 'Пожалуйста введите ваше имя',
|
||||
];
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from '@/helpers/article';
|
||||
export * from '@/helpers/utils';
|
||||
export * from '@/helpers/utils';
|
||||
export * from '@/helpers/formRules';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Vue from 'vue';
|
||||
import firebase from 'firebase/app';
|
||||
import 'firebase/auth';
|
||||
|
||||
@@ -6,16 +7,25 @@ export default {
|
||||
user: {
|
||||
isAuthentificated: false,
|
||||
uid: null,
|
||||
email: null,
|
||||
name: null,
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setUser(state, payload) {
|
||||
setUser(state, { id, email}) {
|
||||
state.user.isAuthentificated = true;
|
||||
state.user.uid = payload;
|
||||
state.user.uid = id;
|
||||
state.user.email = email;
|
||||
},
|
||||
unSetUser(state) {
|
||||
state.user.isAuthentificated = false;
|
||||
state.user.uid = null;
|
||||
},
|
||||
setUserName(state, name) {
|
||||
Vue.set(state.user, 'name', name);
|
||||
},
|
||||
setUserEmail(state, email) {
|
||||
Vue.set(state.user, 'email', email);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@@ -23,10 +33,15 @@ export default {
|
||||
commit('setProcessing', true);
|
||||
commit('clearError');
|
||||
|
||||
const { email, password } = payload;
|
||||
const { email, password, name } = payload;
|
||||
firebase.auth()
|
||||
.createUserWithEmailAndPassword(email, password)
|
||||
.then(() => {
|
||||
firebase.auth().currentUser
|
||||
.updateProfile({
|
||||
displayName: name,
|
||||
})
|
||||
.then(() => commit('setUserName', name));
|
||||
commit('setProcessing', false);
|
||||
})
|
||||
.catch(function(error) {
|
||||
@@ -56,15 +71,60 @@ export default {
|
||||
},
|
||||
stateChanged({ commit, dispatch }, payload) {
|
||||
if (payload) {
|
||||
commit('setUser', payload.uid);
|
||||
commit('setUser', payload);
|
||||
commit('setUserName', payload.displayName);
|
||||
dispatch('loadUserData', payload.uid);
|
||||
} else {
|
||||
commit('unSetUser');
|
||||
}
|
||||
}
|
||||
},
|
||||
changeUserProfileData({ commit }, payload) {
|
||||
const { email, password } = payload;
|
||||
const credential = firebase.auth.EmailAuthProvider.credential(email, password);
|
||||
|
||||
commit('setProcessing', true);
|
||||
commit('clearError');
|
||||
|
||||
firebase.auth().currentUser.reauthenticateAndRetrieveDataWithCredential(credential)
|
||||
.then(() => {
|
||||
const { changeType } = payload;
|
||||
const reauthenticatedUser = firebase.auth().currentUser;
|
||||
|
||||
if (changeType === 'changeName') {
|
||||
const { newName } = payload;
|
||||
return reauthenticatedUser.updateProfile({
|
||||
displayName: newName,
|
||||
})
|
||||
.then(() => commit('setUserName', newName))
|
||||
}
|
||||
|
||||
if (changeType === 'changeEmail') {
|
||||
const { newEmail } = payload;
|
||||
return reauthenticatedUser.updateEmail(newEmail)
|
||||
.then(() => commit('setUserEmail', newEmail))
|
||||
}
|
||||
|
||||
if (changeType === 'changePassword') {
|
||||
const { newPassword } = payload;
|
||||
return reauthenticatedUser.updatePassword(newPassword);
|
||||
}
|
||||
|
||||
throw Error('invalid change type');
|
||||
})
|
||||
.then(() => commit('setProcessing', false))
|
||||
.catch((e) => {
|
||||
window.console.error(e);
|
||||
|
||||
const { message } = e;
|
||||
commit('setProcessing', false);
|
||||
commit('setError', message);
|
||||
});
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
isUserAuthentificated: state => state.user.isAuthentificated,
|
||||
userId: state => state.user.uid,
|
||||
userName: state => state.user.name,
|
||||
userEmail: state => state.user.email,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,12 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Profile</h2>
|
||||
</div>
|
||||
<v-container grid-list-md>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs12 sm10 offset-sm1>
|
||||
<v-tabs v-model="tabMode" color="accent" dark fixed-tabs slider-color="success">
|
||||
<v-tab :key="'myData'" ripple>
|
||||
Мои данные
|
||||
</v-tab>
|
||||
<v-tab :key="'myArticles'" ripple>
|
||||
Мои статьи
|
||||
</v-tab>
|
||||
<v-tab :key="'myWords'" ripple>
|
||||
Мои слова
|
||||
</v-tab>
|
||||
|
||||
<v-tab-item :key="'myData'">
|
||||
<user-profile-data></user-profile-data>
|
||||
</v-tab-item>
|
||||
<v-tab-item :key="'myArticles'">
|
||||
</v-tab-item>
|
||||
<v-tab-item :key="'myWords'">
|
||||
</v-tab-item>
|
||||
</v-tabs>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import UserProfileData from '@/components/User/ProfileData';
|
||||
|
||||
export default {
|
||||
|
||||
}
|
||||
beforeMount() {
|
||||
this.$store.commit('clearError');
|
||||
},
|
||||
data: () => ({
|
||||
tabMode: 'myData',
|
||||
}),
|
||||
components: {
|
||||
UserProfileData,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<v-form id="sign-in-form" v-model="isValid" @submit.prevent="signIn">
|
||||
<v-text-field
|
||||
prepend-icon="person"
|
||||
prepend-icon="email"
|
||||
v-model="email"
|
||||
name="login"
|
||||
label="Email"
|
||||
@@ -52,21 +52,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { emailRules, passwordRules } from '@/helpers';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
email: null,
|
||||
password: null,
|
||||
isValid: false,
|
||||
emailRules: [
|
||||
(value) => !!value || 'Пожалуйста, введите email',
|
||||
(value) => /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value) || 'Неправильный email',
|
||||
],
|
||||
passwordRules: [
|
||||
(value) => !!value || 'Пожалуйста введите пароль',
|
||||
],
|
||||
};
|
||||
beforeMount() {
|
||||
this.$store.commit('clearError');
|
||||
},
|
||||
data: () => ({
|
||||
email: null,
|
||||
password: null,
|
||||
isValid: false,
|
||||
|
||||
emailRules,
|
||||
passwordRules,
|
||||
}),
|
||||
computed: {
|
||||
error() {
|
||||
return this.$store.getters.getError;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<v-toolbar-title>Регистрация</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-alert
|
||||
<v-alert
|
||||
:value="error"
|
||||
type="warning"
|
||||
>
|
||||
@@ -18,6 +18,17 @@
|
||||
<v-form id="sign-up-form" v-model="isValid" @submit.prevent="signUp">
|
||||
<v-text-field
|
||||
prepend-icon="person"
|
||||
v-model="name"
|
||||
name="name"
|
||||
label="Имя"
|
||||
type="text"
|
||||
required
|
||||
:rules="nameRules"
|
||||
>
|
||||
</v-text-field>
|
||||
|
||||
<v-text-field
|
||||
prepend-icon="email"
|
||||
v-model="email"
|
||||
name="login"
|
||||
label="Email"
|
||||
@@ -52,22 +63,22 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { emailRules, passwordRules, nameRules } from '@/helpers';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
email: null,
|
||||
password: null,
|
||||
isValid: false,
|
||||
emailRules: [
|
||||
(value) => !!value || 'Пожалуйста, введите email',
|
||||
(value) => /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value) || 'Неправильный email',
|
||||
],
|
||||
passwordRules: [
|
||||
(value) => !!value || 'Пожалуйста введите пароль',
|
||||
(value) => (value && value.length >= 6) || 'Пароль слишком короткий - минимум 6 символов',
|
||||
],
|
||||
};
|
||||
beforeMount() {
|
||||
this.$store.commit('clearError');
|
||||
},
|
||||
data: () => ({
|
||||
email: null,
|
||||
password: null,
|
||||
name: null,
|
||||
isValid: false,
|
||||
|
||||
emailRules,
|
||||
passwordRules,
|
||||
nameRules,
|
||||
}),
|
||||
computed: {
|
||||
error() {
|
||||
return this.$store.getters.getError;
|
||||
@@ -88,8 +99,8 @@
|
||||
},
|
||||
methods: {
|
||||
signUp() {
|
||||
const { email, password } = this;
|
||||
this.$store.dispatch('signUp', { email, password });
|
||||
const { email, password, name } = this;
|
||||
this.$store.dispatch('signUp', { email, password, name });
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user