From c7f3c9d908506a35e7c1fec5dc54cc9fbcc41a7c Mon Sep 17 00:00:00 2001 From: NGPixel Date: Mon, 30 Mar 2020 01:30:10 -0400 Subject: [PATCH] feat: user profile fetch info + groups --- client/components/common/nav-header.vue | 9 +- client/components/profile.vue | 15 +- client/components/profile/profile.vue | 458 +++++++++++++++++++++++- server/graph/resolvers/user.js | 18 + server/graph/schemas/user.graphql | 18 + server/helpers/error.js | 4 + 6 files changed, 498 insertions(+), 24 deletions(-) diff --git a/client/components/common/nav-header.vue b/client/components/common/nav-header.vue index b613e160..4071e0df 100644 --- a/client/components/common/nav-header.vue +++ b/client/components/common/nav-header.vue @@ -180,11 +180,10 @@ //- v-list-item-content //- v-list-item-title {{$t('common:header.myWiki')}} //- v-list-item-subtitle.overline Coming soon - //- v-list-item(href='/p', disabled) - //- v-list-item-action: v-icon(color='blue') mdi-face-profile - //- v-list-item-content - //- v-list-item-title {{$t('common:header.profile')}} - //- v-list-item-subtitle.overline Coming soon + v-list-item(href='/p') + v-list-item-action: v-icon(color='blue-grey') mdi-face-profile + v-list-item-content + v-list-item-title(:class='$vuetify.theme.dark ? `blue-grey--text text--lighten-3` : `blue-grey--text`') {{$t('common:header.profile')}} v-list-item(href='/a', v-if='isAuthenticated && isAdmin') v-list-item-action.btn-animate-rotate: v-icon(:color='$vuetify.theme.dark ? `blue-grey lighten-3` : `blue-grey`') mdi-cog v-list-item-title(:class='$vuetify.theme.dark ? `blue-grey--text text--lighten-3` : `blue-grey--text`') {{$t('common:header.admin')}} diff --git a/client/components/profile.vue b/client/components/profile.vue index 72f4e972..efd55e24 100644 --- a/client/components/profile.vue +++ b/client/components/profile.vue @@ -4,14 +4,14 @@ v-navigation-drawer.pb-0(v-model='profileDrawerShown', app, fixed, clipped, left, permanent) v-list(dense, nav) v-list-item(to='/profile') - v-list-item-action: v-icon mdi-account-badge + v-list-item-action: v-icon mdi-face-profile v-list-item-content v-list-item-title Profile - v-list-item(to='/preferences', disabled) - v-list-item-action: v-icon(color='grey lighten-1') mdi-settings-outline - v-list-item-content - v-list-item-title Preferences - v-list-item-subtitle.caption.grey--text.text--lighten-1 Coming soon + //- v-list-item(to='/preferences', disabled) + //- v-list-item-action: v-icon(color='grey lighten-1') mdi-cog-outline + //- v-list-item-content + //- v-list-item-title Preferences + //- v-list-item-subtitle.caption.grey--text.text--lighten-1 Coming soon v-list-item(to='/pages', disabled) v-list-item-action: v-icon(color='grey lighten-1') mdi-file-document v-list-item-content @@ -43,7 +43,7 @@ const router = new VueRouter({ routes: [ { path: '/', redirect: '/profile' }, { path: '/profile', component: () => import(/* webpackChunkName: "profile" */ './profile/profile.vue') }, - { path: '/preferences', component: () => import(/* webpackChunkName: "profile" */ './profile/preferences.vue') }, + // { path: '/preferences', component: () => import(/* webpackChunkName: "profile" */ './profile/preferences.vue') }, { path: '/pages', component: () => import(/* webpackChunkName: "profile" */ './profile/pages.vue') }, { path: '/comments', component: () => import(/* webpackChunkName: "profile" */ './profile/comments.vue') } ] @@ -59,6 +59,7 @@ router.afterEach((to, from) => { }) export default { + i18nOptions: { namespaces: 'profile' }, data() { return { profileDrawerShown: true diff --git a/client/components/profile/profile.vue b/client/components/profile/profile.vue index a6e63e3f..3dd7d9d3 100644 --- a/client/components/profile/profile.vue +++ b/client/components/profile/profile.vue @@ -5,20 +5,134 @@ .profile-header img.animated.fadeInUp(src='/svg/icon-profile.svg', alt='Users', style='width: 80px;') .profile-header-title - .headline.primary--text.animated.fadeInLeft Profile - .subheading.grey--text.animated.fadeInLeft Personal profile + .headline.primary--text.animated.fadeInLeft {{$t('profile:title')}} + .subheading.grey--text.animated.fadeInLeft {{$t('profile:subtitle')}} v-spacer v-btn.animated.fadeInDown(outlined, color='primary', disabled).mr-0 v-icon(left) mdi-earth - span View Public Profile + span {{$t('profile:viewPublicProfile')}} v-flex(lg6 xs12) v-card v-toolbar(color='primary', dark, dense, flat) - v-toolbar-title.subtitle-1 User Details - v-card-text - v-text-field(label='Name', :counter='255', v-model='name', prepend-icon='mdi-account') - v-text-field(label='Job Title', :counter='255', prepend-icon='mdi-human') - v-text-field(label='Location / Office', :counter='255', prepend-icon='mdi-map-marker') + v-toolbar-title.subtitle-1 {{$t('profile:myInfo')}} + v-list(two-line, dense) + v-list-item + v-list-item-avatar(size='32') + v-icon mdi-account + v-list-item-content + v-list-item-title {{$t('profile:displayName')}} + v-list-item-subtitle {{ user.name }} + v-list-item-action + v-menu( + v-model='editPop.name' + :close-on-content-click='false' + min-width='350' + left + ) + template(v-slot:activator='{ on }') + v-btn(icon, color='grey', x-small, v-on='on', @click='focusField(`iptDisplayName`)') + v-icon mdi-pencil + v-card + v-text-field( + ref='iptDisplayName' + v-model='user.name' + :label='$t(`profile:displayName`)' + solo + hide-details + append-icon='mdi-check' + @click:append='editPop.name = false' + @keydown.enter='editPop.name = false' + @keydown.esc='editPop.name = false' + ) + v-divider + v-list-item + v-list-item-avatar(size='32') + v-icon mdi-map-marker + v-list-item-content + v-list-item-title {{$t('profile:location')}} + v-list-item-subtitle {{ user.location }} + v-list-item-action + v-menu( + v-model='editPop.location' + :close-on-content-click='false' + min-width='350' + left + ) + template(v-slot:activator='{ on }') + v-btn(icon, color='grey', x-small, v-on='on', @click='focusField(`iptLocation`)') + v-icon mdi-pencil + v-card + v-text-field( + ref='iptLocation' + v-model='user.location' + :label='$t(`profile:location`)' + solo + hide-details + append-icon='mdi-check' + @click:append='editPop.location = false' + @keydown.enter='editPop.location = false' + @keydown.esc='editPop.location = false' + ) + v-divider + v-list-item + v-list-item-avatar(size='32') + v-icon mdi-briefcase + v-list-item-content + v-list-item-title {{$t('profile:jobTitle')}} + v-list-item-subtitle {{ user.jobTitle }} + v-list-item-action + v-menu( + v-model='editPop.jobTitle' + :close-on-content-click='false' + min-width='350' + left + ) + template(v-slot:activator='{ on }') + v-btn(icon, color='grey', x-small, v-on='on', @click='focusField(`iptJobTitle`)') + v-icon mdi-pencil + v-card + v-text-field( + ref='iptJobTitle' + v-model='user.jobTitle' + :label='$t(`profile:jobTitle`)' + solo + hide-details + append-icon='mdi-check' + @click:append='editPop.jobTitle = false' + @keydown.enter='editPop.jobTitle = false' + @keydown.esc='editPop.jobTitle = false' + ) + v-divider + v-list-item + v-list-item-avatar(size='32') + v-icon mdi-map-clock-outline + v-list-item-content + v-list-item-title {{$t('profile:timezone')}} + v-list-item-subtitle {{ user.timezone }} + v-list-item-action + v-menu( + v-model='editPop.timezone' + :close-on-content-click='false' + min-width='350' + left + ) + template(v-slot:activator='{ on }') + v-btn(icon, color='grey', x-small, v-on='on', @click='focusField(`iptTimezone`)') + v-icon mdi-pencil + v-card + v-select( + ref='iptTimezone' + :items='timezones' + v-model='user.timezone' + :label='$t(`profile:timezone`)' + solo + dense + hide-details + append-icon='mdi-check' + @click:append='editPop.timezone = false' + @keydown.enter='editPop.timezone = false' + @keydown.esc='editPop.timezone = false' + ) v-card-chin v-spacer v-btn.px-4(color='success') @@ -63,17 +177,29 @@ v-icon(size='64', color='grey lighten-2') mdi-account-circle v-btn(depressed).mx-4.elevation-1 Upload Picture v-btn(depressed, disabled).elevation-1 Remove Picture + v-card.mt-3 + v-toolbar(color='primary', dark, dense, flat) + v-toolbar-title + .subtitle-1 Groups + v-list(dense) + template(v-for='(grp, idx) of user.groups') + v-list-item(:key='`grp-id-` + grp') + v-list-item-avatar(size='32') + v-icon mdi-account-group + v-list-item-content + v-list-item-title.body-2 {{grp}} + v-divider(v-if='idx < user.groups.length - 1') v-card.mt-3 v-toolbar(color='teal', dark, dense, flat) v-toolbar-title .subtitle-1 Activity v-card-text.grey--text.text--darken-2 .caption.grey--text Joined on - .body-2: strong January 1st, 2018 at 12:00 AM + .body-2: strong {{ user.createdAt | moment('LLLL') }} .caption.grey--text.mt-3 Profile last updated on - .body-2: strong January 1st, 2018 at 12:00 AM + .body-2: strong {{ user.updatedAt | moment('LLLL') }} .caption.grey--text.mt-3 Last login on - .body-2: strong January 1st, 2018 at 12:00 AM + .body-2: strong {{ user.lastLoginOn | moment('LLLL') }} v-divider.mt-3 .caption.grey--text.mt-3 Pages created .body-2: strong 0 @@ -82,10 +208,318 @@