mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge pull request #474 from gradido/Feature--Profile-Page-API
Feature: Profile Page + Update API
This commit is contained in:
commit
3be482c40e
@ -78,6 +78,27 @@ const loginAPI = {
|
||||
CONFIG.LOGIN_API_URL + 'loginViaEmailVerificationCode?emailVerificationCode=' + optin,
|
||||
)
|
||||
},
|
||||
getUserInfos: async (sessionId, email) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
email: email,
|
||||
ask: ['user.first_name', 'user.last_name'],
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'getUserInfos', payload)
|
||||
},
|
||||
updateUserInfos: async (sessionId, email, data) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
email,
|
||||
update: {
|
||||
'User.first_name': data.firstName,
|
||||
'User.last_name': data.lastName,
|
||||
'User.description': data.description,
|
||||
},
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
},
|
||||
|
||||
changePassword: async (sessionId, email, password) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
@ -88,6 +109,27 @@ const loginAPI = {
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
},
|
||||
changePasswordProfile: async (sessionId, email, password, passwordNew) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
email,
|
||||
update: {
|
||||
'User.password': password,
|
||||
'User.passwordNew': passwordNew,
|
||||
},
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
},
|
||||
changeUsernameProfile: async (sessionId, email, usernameNew) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
email,
|
||||
update: {
|
||||
'User.usernameNew': usernameNew,
|
||||
},
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
},
|
||||
updateLanguage: async (sessionId, email, language) => {
|
||||
const payload = {
|
||||
session_id: sessionId,
|
||||
|
||||
@ -20,17 +20,25 @@
|
||||
},
|
||||
"decay": "Vergänglichkeit",
|
||||
"form": {
|
||||
"cancel":"Abbrechen",
|
||||
"cancel": "Abbrechen",
|
||||
"reset": "Zurücksetzen",
|
||||
"close":"schließen",
|
||||
"close": "schließen",
|
||||
"edit": "bearbeiten",
|
||||
"save": "speichern",
|
||||
"receiver":"Empfänger",
|
||||
"sender":"Absender",
|
||||
"username":"Username",
|
||||
"firstname":"Vorname",
|
||||
"lastname":"Nachname",
|
||||
"description": "Beschreibung",
|
||||
"email":"E-Mail",
|
||||
"email_repeat":"eMail wiederholen",
|
||||
"password":"Passwort",
|
||||
"password_repeat":"Passwort wiederholen",
|
||||
"password_old":"altes Passwort",
|
||||
"password_new":"neues Passwort",
|
||||
"password_new_repeat":"neues Passwort wiederholen",
|
||||
"change": "ändern",
|
||||
"amount":"Betrag",
|
||||
"memo":"Nachricht für den Empfänger",
|
||||
"message":"Nachricht",
|
||||
@ -49,8 +57,9 @@
|
||||
"send_transaction_error":"Leider konnte die Transaktion nicht ausgeführt werden!",
|
||||
"validation": {
|
||||
"double": "Das Feld {field} muss eine Dezimalzahl mit zwei Nachkommastellen sein",
|
||||
"is-not": "Du kannst dir selbst keine Gradidos überweisen"
|
||||
}
|
||||
"is-not": "Du kannst Dir selbst keine Gradidos überweisen"
|
||||
},
|
||||
"change_username_info": "Das ändern des Usernamens bedarf mehrerer Schritte."
|
||||
},
|
||||
"error": {
|
||||
"error":"Fehler"
|
||||
@ -96,7 +105,6 @@
|
||||
"add_work":"neuer Gemeinschaftsbeitrag"
|
||||
},
|
||||
"profil": {
|
||||
"transactions":"transactions",
|
||||
"activity": {
|
||||
"chart":"Gemeinschaftsstunden Chart",
|
||||
"new":"Neue Gemeinschaftsstunden eintragen",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"message": "hello gradido !!",
|
||||
"welcome":"Welcome!",
|
||||
"community": "Gemeinschaft",
|
||||
"community": "Community",
|
||||
"logout":"Logout",
|
||||
"login":"Login",
|
||||
"signup": "Sign up",
|
||||
@ -23,14 +23,22 @@
|
||||
"cancel":"Cancel",
|
||||
"reset": "Reset",
|
||||
"close":"Close",
|
||||
"edit": "Edit",
|
||||
"save": "save",
|
||||
"receiver":"Receiver",
|
||||
"sender":"Sender",
|
||||
"username":"Username",
|
||||
"firstname":"Firstname",
|
||||
"lastname":"Lastname",
|
||||
"description": "Description",
|
||||
"email":"Email",
|
||||
"email_repeat":"Repeat Email",
|
||||
"password":"Password",
|
||||
"password_repeat":"Repeat password",
|
||||
"password_old":"Old password",
|
||||
"password_new":"New password",
|
||||
"password_new_repeat":"Repeat new password",
|
||||
"change": "change",
|
||||
"amount":"Amount",
|
||||
"memo":"Message for the recipient",
|
||||
"message":"Message",
|
||||
@ -50,7 +58,8 @@
|
||||
"validation": {
|
||||
"double": "The {field} field must be a decimal with two digits",
|
||||
"is-not": "You cannot send Gradidos to yourself"
|
||||
}
|
||||
},
|
||||
"change_username_info": "Changing the username requires several steps."
|
||||
},
|
||||
"error": {
|
||||
"error":"Error"
|
||||
|
||||
@ -16,25 +16,11 @@ const routes = [
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: () => import('../views/Pages/UserProfile.vue'),
|
||||
component: () => import('../views/Pages/UserProfileOverview.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: '/profileedit',
|
||||
// component: () => import('../views/Pages/UserProfileEdit.vue'),
|
||||
// meta: {
|
||||
// requiresAuth: true,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: '/activity',
|
||||
// component: () => import('../views/Pages/UserProfileActivity.vue'),
|
||||
// meta: {
|
||||
// requiresAuth: true,
|
||||
// },
|
||||
// },
|
||||
{
|
||||
path: '/transactions',
|
||||
component: () => import('../views/Pages/UserProfileTransactionList.vue'),
|
||||
|
||||
@ -13,6 +13,18 @@ export const mutations = {
|
||||
sessionId: (state, sessionId) => {
|
||||
state.sessionId = sessionId
|
||||
},
|
||||
username: (state, username) => {
|
||||
state.username = username
|
||||
},
|
||||
firstName: (state, firstName) => {
|
||||
state.firstName = firstName
|
||||
},
|
||||
lastName: (state, lastName) => {
|
||||
state.lastName = lastName
|
||||
},
|
||||
description: (state, description) => {
|
||||
state.description = description
|
||||
},
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
@ -20,10 +32,18 @@ export const actions = {
|
||||
commit('sessionId', data.sessionId)
|
||||
commit('email', data.user.email)
|
||||
commit('language', data.user.language)
|
||||
commit('username', data.user.username)
|
||||
commit('firstName', data.user.first_name)
|
||||
commit('lastName', data.user.last_name)
|
||||
commit('description', data.user.description)
|
||||
},
|
||||
logout: ({ commit, state }) => {
|
||||
commit('sessionId', null)
|
||||
commit('email', null)
|
||||
commit('username', '')
|
||||
commit('firstName', '')
|
||||
commit('lastName', '')
|
||||
commit('description', '')
|
||||
sessionStorage.clear()
|
||||
},
|
||||
}
|
||||
@ -39,6 +59,10 @@ export const store = new Vuex.Store({
|
||||
email: '',
|
||||
language: null,
|
||||
modals: false,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
username: '',
|
||||
description: '',
|
||||
},
|
||||
getters: {},
|
||||
// Syncronous mutation of the state
|
||||
|
||||
@ -40,7 +40,7 @@ describe('Vuex store', () => {
|
||||
{ commit, state },
|
||||
{ sessionId: 1234, user: { email: 'someone@there.is', language: 'en' } },
|
||||
)
|
||||
expect(commit).toHaveBeenCalledTimes(3)
|
||||
expect(commit).toHaveBeenCalledTimes(7)
|
||||
})
|
||||
|
||||
it('commits sessionId', () => {
|
||||
@ -74,7 +74,7 @@ describe('Vuex store', () => {
|
||||
|
||||
it('calls two commits', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenCalledTimes(2)
|
||||
expect(commit).toHaveBeenCalledTimes(6)
|
||||
})
|
||||
|
||||
it('commits sessionId', () => {
|
||||
|
||||
@ -78,7 +78,7 @@ describe('DashboardLayoutGdd', () => {
|
||||
})
|
||||
|
||||
it('has five items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(2)
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('has first item "send" in navbar', () => {
|
||||
@ -103,21 +103,21 @@ describe('DashboardLayoutGdd', () => {
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/transactions')
|
||||
})
|
||||
|
||||
// it('has tree items in the navbar', () => {
|
||||
// expect(navbar.findAll('ul > li')).toHaveLength(3)
|
||||
// })
|
||||
//
|
||||
// it('has third item "My profile" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(2).text()).toEqual('site.navbar.my-profil')
|
||||
// })
|
||||
//
|
||||
// it.skip('has third item "My profile" linked to profile in navbar', async () => {
|
||||
// navbar.findAll('ul > li > a').at(2).trigger('click')
|
||||
// await flushPromises()
|
||||
// await jest.runAllTimers()
|
||||
// await flushPromises()
|
||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
||||
// })
|
||||
it('has tree items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('has third item "My profile" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(2).text()).toEqual('site.navbar.my-profil')
|
||||
})
|
||||
|
||||
it.skip('has third item "My profile" linked to profile in navbar', async () => {
|
||||
navbar.findAll('ul > a').at(2).trigger('click')
|
||||
await flushPromises()
|
||||
await jest.runAllTimers()
|
||||
await flushPromises()
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
||||
})
|
||||
|
||||
// it('has fourth item "Settigs" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(3).text()).toEqual('site.navbar.settings')
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div>
|
||||
<side-bar @logout="logout" :balance="balance" :pending="pending">
|
||||
<template slot="links">
|
||||
<sidebar-item
|
||||
@ -14,18 +14,12 @@
|
||||
path: '/transactions',
|
||||
}"
|
||||
></sidebar-item>
|
||||
|
||||
<!--
|
||||
<b-nav-item href="#!" to="/profile">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.my-profil') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<b-nav-item href="#!" to="/profileedit">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.settings') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<b-nav-item href="#!" to="/activity">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.activity') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
-->
|
||||
<sidebar-item
|
||||
:link="{
|
||||
name: $t('site.navbar.my-profil'),
|
||||
path: '/profile',
|
||||
}"
|
||||
></sidebar-item>
|
||||
</template>
|
||||
</side-bar>
|
||||
<div class="main-content">
|
||||
@ -39,6 +33,7 @@
|
||||
:transactions="transactions"
|
||||
:transactionCount="transactionCount"
|
||||
:pending="pending"
|
||||
:UserProfileTestData="UserProfileTestData"
|
||||
@update-balance="updateBalance"
|
||||
@update-transactions="updateTransactions"
|
||||
></router-view>
|
||||
@ -90,6 +85,11 @@ export default {
|
||||
bookedBalance: 0,
|
||||
transactionCount: 0,
|
||||
pending: true,
|
||||
UserProfileTestData: {
|
||||
username: 'Mustermax',
|
||||
desc:
|
||||
'Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. ',
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<base-nav
|
||||
container-classes="container-fluid"
|
||||
class="navbar-top navbar-expand"
|
||||
class="navbar-expand"
|
||||
:class="{ 'navbar-dark': type === 'default' }"
|
||||
>
|
||||
<!-- Navbar links -->
|
||||
@ -15,7 +15,7 @@
|
||||
<span class="pb-2 text-lg font-weight-bold">
|
||||
{{ $store.state.email }}
|
||||
</span>
|
||||
<b-media-body class="ml-2 d-none d-lg-block d-md-block">
|
||||
<b-media-body class="ml-2">
|
||||
<span class="avatar">
|
||||
<vue-qrcode :value="$store.state.email" type="image/png"></vue-qrcode>
|
||||
</span>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-container fluid class="p-lg-2 mt-lg-1">
|
||||
<b-container fluid>
|
||||
<gdd-status
|
||||
v-if="showContext"
|
||||
:pending="pending"
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Header -->
|
||||
<div class="header bg-gradient-info py-7 py-lg-3 pt-lg-2">
|
||||
<b-container>
|
||||
<div class="header-body text-center mb-7">
|
||||
<p class="h1">GDD</p>
|
||||
<p class="h4">Explorer</p>
|
||||
</div>
|
||||
</b-container>
|
||||
<div class="separator separator-bottom separator-skew zindex-100">
|
||||
<svg
|
||||
x="0"
|
||||
y="0"
|
||||
viewBox="0 0 2560 100"
|
||||
preserveAspectRatio="none"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polygon class="fill-default" points="2560 0 2560 100 0 100"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page content -->
|
||||
|
||||
<div>
|
||||
<b-card>
|
||||
<b-card-body>This is some text within a card body.</b-card-body>
|
||||
</b-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,134 +0,0 @@
|
||||
<template>
|
||||
<card style="background-color: #ebebeba3 !important">
|
||||
<b-form @submit.prevent="updateProfile">
|
||||
<h6 class="heading-small text-muted mb-4">User information</h6>
|
||||
|
||||
<div class="pl-lg-4">
|
||||
<b-row>
|
||||
<b-col lg="6">
|
||||
<base-input
|
||||
type="text"
|
||||
label="Username"
|
||||
placeholder="Username"
|
||||
v-model="user.username"
|
||||
></base-input>
|
||||
</b-col>
|
||||
<b-col lg="6">
|
||||
<base-input
|
||||
type="email"
|
||||
label="Email address"
|
||||
placeholder="mike@email.com"
|
||||
v-model="user.email"
|
||||
></base-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col lg="6">
|
||||
<base-input
|
||||
type="text"
|
||||
label="First Name"
|
||||
placeholder="First Name"
|
||||
v-model="user.firstName"
|
||||
></base-input>
|
||||
</b-col>
|
||||
<b-col lg="6">
|
||||
<base-input
|
||||
type="text"
|
||||
label="Last Name"
|
||||
placeholder="Last Name"
|
||||
v-model="user.lastName"
|
||||
></base-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
<hr class="my-4" />
|
||||
|
||||
<!-- Address -->
|
||||
<h6 class="heading-small text-muted mb-4">Contact information</h6>
|
||||
|
||||
<div class="pl-lg-4">
|
||||
<b-row>
|
||||
<b-col md="12">
|
||||
<base-input
|
||||
type="text"
|
||||
label="Address"
|
||||
placeholder="Home Address"
|
||||
v-model="user.address"
|
||||
></base-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col lg="4">
|
||||
<base-input
|
||||
type="text"
|
||||
label="City"
|
||||
placeholder="City"
|
||||
v-model="user.city"
|
||||
></base-input>
|
||||
</b-col>
|
||||
<b-col lg="4">
|
||||
<base-input
|
||||
type="text"
|
||||
label="Country"
|
||||
placeholder="Country"
|
||||
v-model="user.country"
|
||||
></base-input>
|
||||
</b-col>
|
||||
<b-col lg="4">
|
||||
<base-input
|
||||
label="Postal Code"
|
||||
placeholder="ZIP Code"
|
||||
v-model="user.postalCode"
|
||||
></base-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
|
||||
<hr class="my-4" />
|
||||
<!-- Description -->
|
||||
<h6 class="heading-small text-muted mb-4">About me</h6>
|
||||
<div class="pl-lg-4">
|
||||
<b-form-group
|
||||
label="About Me"
|
||||
label-class="form-control-label"
|
||||
class="mb-0"
|
||||
label-for="about-form-textaria"
|
||||
>
|
||||
<!-- <label class="form-control-label">About Me</label> -->
|
||||
<b-form-textarea
|
||||
rows="4"
|
||||
value="A beautiful premium dashboard for BootstrapVue."
|
||||
id="about-form-textaria"
|
||||
placeholder="A few words about you ..."
|
||||
></b-form-textarea>
|
||||
</b-form-group>
|
||||
</div>
|
||||
</b-form>
|
||||
</card>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
user: {
|
||||
company: 'Creative Code Inc.',
|
||||
username: 'michael23',
|
||||
email: '',
|
||||
firstName: 'Mike',
|
||||
lastName: 'Andrew',
|
||||
address: 'Bld Mihail Kogalniceanu, nr. 8 Bl 1, Sc 1, Ap 09',
|
||||
city: 'New York',
|
||||
country: 'USA',
|
||||
postalCode: '',
|
||||
aboutMe: `Lamborghini Mercy, Your chick she so thirsty, I'm in that two seat Lambo.`,
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateProfile() {
|
||||
alert('Your data: ' + JSON.stringify(this.user))
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- slot for parent component to activate the file changer -->
|
||||
<div @click="launchFilePicker()">
|
||||
<slot name="activator"></slot>
|
||||
</div>
|
||||
<!-- image input: style is set to hidden and assigned a ref so that it can be triggered -->
|
||||
<input
|
||||
type="file"
|
||||
ref="file"
|
||||
:name="uploadFieldName"
|
||||
@change="onFileChange($event.target.name, $event.target.files)"
|
||||
style="display: none"
|
||||
/>
|
||||
<!-- error dialog displays any potential errors -->
|
||||
<v-dialog v-model="errorDialog" max-width="300">
|
||||
<v-card>
|
||||
<v-card-text class="subheading">{{ errorText }}</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="errorDialog = false" flat>Got it!</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'avatar-uploader',
|
||||
data: () => ({
|
||||
errorDialog: null,
|
||||
errorText: '',
|
||||
uploadFieldName: 'file',
|
||||
maxSize: 1024,
|
||||
}),
|
||||
props: {
|
||||
// Use "value" here to enable compatibility with v-model
|
||||
value: Object,
|
||||
},
|
||||
methods: {
|
||||
launchFilePicker() {
|
||||
this.$refs.file.click()
|
||||
},
|
||||
onFileChange(fieldName, file) {
|
||||
const { maxSize } = this
|
||||
const imageFile = file[0]
|
||||
|
||||
// check if user actually selected a file
|
||||
if (file.length > 0) {
|
||||
const size = imageFile.size / maxSize / maxSize
|
||||
if (!imageFile.type.match('image.*')) {
|
||||
// check whether the upload is an image
|
||||
this.errorDialog = true
|
||||
this.errorText = 'Please choose an image file'
|
||||
} else if (size > 1) {
|
||||
// check whether the size is greater than the size limit
|
||||
this.errorDialog = true
|
||||
this.errorText = 'Your file is too big! Please select an image under 1MB'
|
||||
} else {
|
||||
// Append file into FormData & turn file into image URL
|
||||
const formData = new FormData()
|
||||
const imageURL = URL.createObjectURL(imageFile)
|
||||
formData.append(fieldName, imageFile)
|
||||
// Emit FormData & image URL to the parent component
|
||||
this.$emit('input', { formData, imageURL })
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,67 +1,41 @@
|
||||
<template>
|
||||
<b-card
|
||||
no-body
|
||||
class="card-profile"
|
||||
alt="Image placeholder"
|
||||
img-top
|
||||
style="background-color: #ebebeba3 !important"
|
||||
>
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="3" class="order-lg-2">
|
||||
<div class="card-profile-image">
|
||||
<a href="#">
|
||||
<vue-qrcode :value="$store.state.email" type="image/png"></vue-qrcode>
|
||||
</a>
|
||||
<b-card class="bg-transparent">
|
||||
<div class="w-100 text-center">
|
||||
<vue-qrcode :value="$store.state.email" type="image/png"></vue-qrcode>
|
||||
</div>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<div class="card-profile-stats d-flex justify-content-center mt-md-5">
|
||||
<div>
|
||||
<span class="heading">
|
||||
{{ $n(balance) }}
|
||||
</span>
|
||||
<span class="description">GDD</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="heading">{{ transactionCount }}</span>
|
||||
<span class="description">{{ $t('transactions') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="heading">--</span>
|
||||
<span class="description">{{ $t('community') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-card-header class="text-center border-0 pt-8 pt-md-4 pb-0 pb-md-4">
|
||||
<div class="d-flex justify-content-between">
|
||||
<br />
|
||||
</div>
|
||||
</b-card-header>
|
||||
|
||||
<b-card-body class="pt-0">
|
||||
<b-row>
|
||||
<b-col>
|
||||
<div class="card-profile-stats d-flex justify-content-center mt-md-5">
|
||||
<div>
|
||||
<span class="heading">--</span>
|
||||
<span class="description">Transactions</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="heading">--</span>
|
||||
<span class="description">Community</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="heading">
|
||||
{{ $n(balance, 'decimal') }}
|
||||
</span>
|
||||
<span class="description">GDD</span>
|
||||
</div>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="text-center">
|
||||
<h5 class="h3">
|
||||
{{ this.$store.state.email }}
|
||||
<span class="font-weight-light"></span>
|
||||
</h5>
|
||||
</div>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
</template>
|
||||
<script>
|
||||
import VueQrcode from 'vue-qrcode'
|
||||
|
||||
export default {
|
||||
name: 'profilecard',
|
||||
name: 'UserCard',
|
||||
components: {
|
||||
VueQrcode,
|
||||
},
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
108
frontend/src/views/Pages/UserProfile/UserCard_FormUserData.vue
Normal file
108
frontend/src/views/Pages/UserProfile/UserCard_FormUserData.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="userdata_form">
|
||||
<b-card
|
||||
id="userdata_form"
|
||||
class="bg-transparent"
|
||||
style="background-color: #ebebeba3 !important"
|
||||
>
|
||||
<b-container>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a href="#userdata_form" v-if="editUserdata" @click="editUserdata = !editUserdata">
|
||||
<span>{{ $t('form.edit') }}</span>
|
||||
</a>
|
||||
<div v-else>
|
||||
<a href="#userdata_form" @click="onSubmit">
|
||||
<span class="mr-4 text-success display-4">{{ $t('form.save') }}</span>
|
||||
</a>
|
||||
<a href="#userdata_form" @click="editUserdata = !editUserdata">
|
||||
<span>
|
||||
<b>{{ $t('form.cancel') }}</b>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<div>
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-12 col-sm-12 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.firstname') }}</small>
|
||||
</b-col>
|
||||
<b-col v-if="editUserdata" class="col-md-9 col-sm-10">
|
||||
{{ form.firstName }}
|
||||
</b-col>
|
||||
<b-col v-else class="col-md-9 col-sm-10">
|
||||
<b-input type="text" v-model="form.firstName"></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-12 col-sm-12 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.lastname') }}</small>
|
||||
</b-col>
|
||||
<b-col v-if="editUserdata" class="col-md-9 col-sm-10">
|
||||
{{ form.lastName }}
|
||||
</b-col>
|
||||
<b-col v-else class="col-md-9 col-sm-10">
|
||||
<b-input type="text" v-model="form.lastName"></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.description') }}</small>
|
||||
</b-col>
|
||||
<b-col v-if="editUserdata" class="col-md-9 col-sm-10">
|
||||
{{ form.description }}
|
||||
</b-col>
|
||||
<b-col v-else class="col-md-9 col-sm-10">
|
||||
<b-textarea rows="3" max-rows="6" v-model="form.description"></b-textarea>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</b-container>
|
||||
</b-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../../apis/loginAPI'
|
||||
|
||||
export default {
|
||||
name: 'FormUserData',
|
||||
props: {
|
||||
UserProfileTestData: { type: Object },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editUserdata: true,
|
||||
sessionId: this.$store.state.sessionId,
|
||||
form: {
|
||||
firstName: this.$store.state.firstName,
|
||||
lastName: this.$store.state.lastName,
|
||||
description: this.$store.state.description,
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
const result = await loginAPI.updateUserInfos(
|
||||
this.$store.state.sessionId,
|
||||
this.$store.state.email,
|
||||
{
|
||||
firstName: this.form.firstName,
|
||||
lastName: this.form.lastName,
|
||||
description: this.form.description,
|
||||
},
|
||||
)
|
||||
if (result.success) {
|
||||
this.$store.commit('firstName', this.form.firstName)
|
||||
this.$store.commit('lastName', this.form.lastName)
|
||||
this.$store.commit('description', this.form.description)
|
||||
this.editUserdata = true
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<b-card id="formusermail" class="bg-transparent" style="background-color: #ebebeba3 !important">
|
||||
<b-container>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a href="#formusermail" v-if="edit_email" @click="edit_email = !edit_email">
|
||||
<span>E-Mail {{ $t('form.change') }}</span>
|
||||
</a>
|
||||
<div v-else>
|
||||
<a href="#formusermail" @click="onSubmit">
|
||||
<span class="mr-4 text-success display-4">{{ $t('form.save') }}</span>
|
||||
</a>
|
||||
<a href="#formusermail" @click="edit_email = !edit_email">
|
||||
<span>
|
||||
<b>{{ $t('form.cancel') }}</b>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>E-Mail</small>
|
||||
</b-col>
|
||||
<b-col v-if="edit_email" class="col-md-9 col-sm-10">{{ $store.state.email }}</b-col>
|
||||
<b-col v-else class="col-md-9 col-sm-10">
|
||||
<b-input type="text" v-model="newEmail"></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-card>
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../../apis/loginAPI'
|
||||
|
||||
export default {
|
||||
name: 'FormUserMail',
|
||||
data() {
|
||||
return {
|
||||
edit_email: true,
|
||||
newEmail: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
// console.log(this.data)
|
||||
const result = await loginAPI.changeEmailProfil(
|
||||
this.$store.state.sessionId,
|
||||
this.email,
|
||||
this.newEmail,
|
||||
)
|
||||
if (result.success) {
|
||||
alert('changePassword success')
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<b-card id="change_pwd" class="bg-transparent" style="background-color: #ebebeba3 !important">
|
||||
<b-container>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a href="#change_pwd" v-if="edit_pwd" @click="edit_pwd = !edit_pwd">
|
||||
<span>{{ $t('form.password') }} {{ $t('form.change') }}</span>
|
||||
</a>
|
||||
<div v-else>
|
||||
<a href="#change_pwd" @click="onSubmit">
|
||||
<span class="mr-4 text-success display-4">{{ $t('form.save') }}</span>
|
||||
</a>
|
||||
<a href="#change_pwd" @click="edit_pwd = !edit_pwd">
|
||||
<span>
|
||||
<b>{{ $t('form.cancel') }}</b>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<div v-if="!edit_pwd">
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.password_old') }}</small>
|
||||
</b-col>
|
||||
<b-col class="col-md-9 col-sm-10">
|
||||
<b-input
|
||||
type="text"
|
||||
:placeholder="$t('form.password_old')"
|
||||
v-model="password"
|
||||
></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.password_new') }}</small>
|
||||
</b-col>
|
||||
<b-col class="col-md-9 col-sm-10">
|
||||
<b-input
|
||||
type="text"
|
||||
:placeholder="$t('form.password_new')"
|
||||
v-model="passwordNew"
|
||||
></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.password_new_repeat') }}</small>
|
||||
</b-col>
|
||||
<b-col class="col-md-9 col-sm-10">
|
||||
<b-input
|
||||
type="text"
|
||||
:placeholder="$t('form.password_new_repeat')"
|
||||
v-model="passwordNew2"
|
||||
></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</b-container>
|
||||
</b-card>
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../../apis/loginAPI'
|
||||
|
||||
export default {
|
||||
name: 'FormUserPasswort',
|
||||
data() {
|
||||
return {
|
||||
edit_pwd: true,
|
||||
email: null,
|
||||
password: '',
|
||||
passwordNew: '',
|
||||
passwordNew2: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
// console.log(this.data)
|
||||
const result = await loginAPI.changePasswordProfile(
|
||||
this.$store.state.sessionId,
|
||||
this.email,
|
||||
this.password,
|
||||
this.passwordNew,
|
||||
)
|
||||
if (result.success) {
|
||||
alert('changePassword success')
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<b-card id="formusername" class="bg-transparent" style="background-color: #ebebeba3 !important">
|
||||
<b-container>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a href="#formusername" v-if="edit_username" @click="edit_username = !edit_username">
|
||||
<span>{{ $t('form.username') }} {{ $t('form.change') }}</span>
|
||||
</a>
|
||||
<div v-else>
|
||||
<a href="#formusername" @click="edit_username = !edit_username">
|
||||
<span>
|
||||
<b>{{ $t('form.cancel') }}</b>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="mb-3">
|
||||
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
|
||||
<small>{{ $t('form.username') }}</small>
|
||||
</b-col>
|
||||
<b-col v-if="edit_username" class="col-md-9 col-sm-10">@{{ $store.state.username }}</b-col>
|
||||
<b-col v-else class="col-md-9 col-sm-10">
|
||||
<validation-observer v-slot="{ handleSubmit }" ref="formValidator">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<b-form-input v-model="username" :placeholder="$store.state.username"></b-form-input>
|
||||
<div>
|
||||
{{ $t('form.change_username_info') }}
|
||||
</div>
|
||||
<div class="text-center" ref="submitButton">
|
||||
<b-button type="submit" class="mt-4">
|
||||
{{ $t('form.save') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-card>
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../../apis/loginAPI'
|
||||
|
||||
export default {
|
||||
name: 'FormUsername',
|
||||
data() {
|
||||
return {
|
||||
edit_username: true,
|
||||
username: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
// console.log(this.data)
|
||||
const result = await loginAPI.changeUsernameProfile(this.username)
|
||||
if (result.success) {
|
||||
alert('changeUsername success')
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="header pb-7 pt-5"></div>
|
||||
|
||||
<b-container fluid class="mt--6">
|
||||
<div class="display-4 mb-3">{{ $t('site.profil.activity.chart') }}</div>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<div class="chart">
|
||||
<line-chart :height="350" :chart-data="bigLineChart.chartData"></line-chart>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<hr />
|
||||
<div class="display-4 mt-6">{{ $t('site.profil.activity.new') }}</div>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<gdd-add-work-2 />
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<hr />
|
||||
<div class="display-4 mb-3">{{ $t('site.profil.activity.list') }}</div>
|
||||
<b-row>
|
||||
<b-col class="mb-5">
|
||||
{{ $t('community') }}
|
||||
<gdd-work-table></gdd-work-table>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import GddWorkTable from '../../views/Pages/AccountOverview/GddWorkTable.vue'
|
||||
import GddAddWork2 from '../../views/Pages/AccountOverview/GddAddWork2.vue'
|
||||
|
||||
import * as chartConfigs from '@/components/Charts/config'
|
||||
import LineChart from '@/components/Charts/LineChart'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GddWorkTable,
|
||||
LineChart,
|
||||
GddAddWork2,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bigLineChart: {
|
||||
allData: [
|
||||
[0, 20, 10, 30, 15, 40, 20, 60, 60],
|
||||
[0, 20, 5, 25, 10, 30, 35, 60, 40],
|
||||
[0, 2, 5, 7, 10, 30, 15, 9, 10],
|
||||
[0, 2, 5, 7, 10, 14, 29, 78, 120],
|
||||
],
|
||||
activeIndex: 0,
|
||||
chartData: {
|
||||
datasets: [
|
||||
{
|
||||
label: 'Gemeinschaftsstunden',
|
||||
data: [30, 20, 10, 30, 65, 40, 20, 60, 70],
|
||||
},
|
||||
],
|
||||
labels: ['2020 Aug', 'Sep', 'Okt', 'Nov', 'Dez', 'Jan', 'Feb', 'Mär 2021'],
|
||||
},
|
||||
extraOptions: chartConfigs.blueChartOptions,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,23 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="header pb-8 pt-5 pt-lg-8 d-flex align-items-center profile-header"></div>
|
||||
|
||||
<b-container fluid class="mt--6">
|
||||
<b-row>
|
||||
<b-col xl="12" class="order-xl-1">
|
||||
<edit-profile-form></edit-profile-form>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import EditProfileForm from './UserProfile/EditProfileForm.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditProfileForm,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
29
frontend/src/views/Pages/UserProfileOverview.vue
Normal file
29
frontend/src/views/Pages/UserProfileOverview.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<b-container fluid>
|
||||
<user-card :balance="balance" :transactionCount="transactionCount"></user-card>
|
||||
<form-user-data :UserProfileTestData="UserProfileTestData" />
|
||||
<form-username />
|
||||
<form-user-passwort />
|
||||
</b-container>
|
||||
</template>
|
||||
<script>
|
||||
import UserCard from './UserProfile/UserCard.vue'
|
||||
import FormUserData from './UserProfile/UserCard_FormUserData.vue'
|
||||
import FormUsername from './UserProfile/UserCard_FormUsername.vue'
|
||||
import FormUserPasswort from './UserProfile/UserCard_FormUserPasswort.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserCard,
|
||||
FormUserData,
|
||||
FormUsername,
|
||||
FormUserPasswort,
|
||||
},
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
UserProfileTestData: { type: Object },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,17 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="header pb-sm-1 pb-md-7 d-flex align-items-center profile-header"
|
||||
style="max-height: 200px"
|
||||
></div>
|
||||
|
||||
<gdd-transaction-list
|
||||
:timestamp="timestamp"
|
||||
:transactionCount="transactionCount"
|
||||
:transactions="transactions"
|
||||
:show-pagination="true"
|
||||
@update-transactions="updateTransactions"
|
||||
/>
|
||||
<b-container fluid>
|
||||
<b-row>
|
||||
<b-col class="order-xl-1">
|
||||
<gdd-transaction-list
|
||||
:timestamp="timestamp"
|
||||
:transactionCount="transactionCount"
|
||||
:transactions="transactions"
|
||||
:show-pagination="true"
|
||||
@update-transactions="updateTransactions"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user