From 7c8a1bb4233ca63c594507a6afaf22d7a94a6f34 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Fri, 24 Sep 2021 17:39:24 +0200 Subject: [PATCH 1/4] add login page name field autofocus #42 --- src/views/Index.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/Index.vue b/src/views/Index.vue index e3dd905..0d5e66f 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later id="exampleInputusername1" v-model="username" required + autofocus />
From c1d78fa8c1119e69c3d82756ff93db0be90d8696 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Fri, 24 Sep 2021 17:45:11 +0200 Subject: [PATCH 2/4] implement seach view autofocus #41 --- src/views/Search.vue | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/views/Search.vue b/src/views/Search.vue index b585cc6..ae36c63 100644 --- a/src/views/Search.vue +++ b/src/views/Search.vue @@ -100,9 +100,9 @@ export default { }, watch: { searching(value) { - if (value) { + if (!value) { if (this.$refs.searchTextInput) { - this.$refs.searchTextInput.focus() + this.focusSearchText() } } } @@ -111,6 +111,11 @@ export default { handleSubmit() { this.$router.push({ query: { query: this.searchText }}) this.$store.dispatch('search/search') + }, + focusSearchText() { + this.$nextTick(() => { + this.$refs.searchTextInput.focus() + }) } }, created() { From 2d700c77dc85fea64417350de194e9201537adde Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Fri, 24 Sep 2021 17:51:37 +0200 Subject: [PATCH 3/4] redirect users with token #38 --- src/router/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/router/index.js b/src/router/index.js index 4688ce1..b8577b9 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -46,7 +46,12 @@ const routes = [ { path: '/', name: 'Index', - component: Index + component: Index, + beforeEnter: (_to, _from, next) => { + if (store.state.token) { + next({name: 'Search'}) + } + } }, ] From 46fcaa2db6224dcd3a607b097cf3730d3172b5e1 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sun, 3 Oct 2021 17:56:52 +0200 Subject: [PATCH 4/4] implement profile view --- src/assets/skill_level.json | 27 +++-- src/components/ProfileList.vue | 8 +- src/components/Skill.vue | 81 +++++++++++++++ src/components/ViewError.vue | 39 +++++++ src/components/profile/Contact.vue | 39 +++++++ src/components/profile/Header.vue | 71 +++++++++++++ src/components/profile/Language.vue | 69 +++++++++++++ src/components/profile/Section.vue | 26 +++++ src/router/index.js | 2 + src/store/index.js | 6 +- src/store/profile.js | 117 +++++++++++++++++++++ src/views/profile/View.vue | 153 ++++++++++++++++++++-------- 12 files changed, 583 insertions(+), 55 deletions(-) create mode 100644 src/components/Skill.vue create mode 100644 src/components/ViewError.vue create mode 100644 src/components/profile/Contact.vue create mode 100644 src/components/profile/Header.vue create mode 100644 src/components/profile/Language.vue create mode 100644 src/components/profile/Section.vue create mode 100644 src/store/profile.js diff --git a/src/assets/skill_level.json b/src/assets/skill_level.json index a73f184..5e5faaf 100644 --- a/src/assets/skill_level.json +++ b/src/assets/skill_level.json @@ -1,7 +1,22 @@ { - "1": "bis 6 Monate", - "2": "bis 1 Jahr", - "3": "bis 3 Jahre", - "4": "bis 5 Jahre", - "5": "mehr als 5 Jahre" -} \ No newline at end of file + "1": { + "short": "≤ 6M", + "long": "bis 6 Monate" + }, + "2":{ + "short": "≤ 1J", + "long": "bis 1 Jahr" + }, + "3": { + "short": "≤ 3J", + "long": "bis 3 Jahre" + }, + "4": { + "short": "≤ 5J", + "long": "bis 5 Jahre" + }, + "5": { + "short": "> 5J", + "long": "mehr als 5 Jahre" + } +} diff --git a/src/components/ProfileList.vue b/src/components/ProfileList.vue index 22366f9..2ade5ee 100644 --- a/src/components/ProfileList.vue +++ b/src/components/ProfileList.vue @@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later :value="key" :key="key" > - {{ value }} + {{ value.long || value }}
@@ -90,11 +90,11 @@ SPDX-License-Identifier: AGPL-3.0-or-later + + diff --git a/src/components/ViewError.vue b/src/components/ViewError.vue new file mode 100644 index 0000000..5724a90 --- /dev/null +++ b/src/components/ViewError.vue @@ -0,0 +1,39 @@ + + + + + + diff --git a/src/components/profile/Contact.vue b/src/components/profile/Contact.vue new file mode 100644 index 0000000..3f996b6 --- /dev/null +++ b/src/components/profile/Contact.vue @@ -0,0 +1,39 @@ + + + + + + + diff --git a/src/components/profile/Header.vue b/src/components/profile/Header.vue new file mode 100644 index 0000000..dd53e63 --- /dev/null +++ b/src/components/profile/Header.vue @@ -0,0 +1,71 @@ + + + + + + diff --git a/src/components/profile/Language.vue b/src/components/profile/Language.vue new file mode 100644 index 0000000..45e545b --- /dev/null +++ b/src/components/profile/Language.vue @@ -0,0 +1,69 @@ + + + + + + + diff --git a/src/components/profile/Section.vue b/src/components/profile/Section.vue new file mode 100644 index 0000000..1056dbc --- /dev/null +++ b/src/components/profile/Section.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/src/router/index.js b/src/router/index.js index b8577b9..5680ec4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -50,6 +50,8 @@ const routes = [ beforeEnter: (_to, _from, next) => { if (store.state.token) { next({name: 'Search'}) + } else { + next() } } }, diff --git a/src/store/index.js b/src/store/index.js index c36f364..c7a3260 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,6 +4,7 @@ import { createStore } from 'vuex' +import profile from './profile' import search from './search' const localStorageKeys = { @@ -13,13 +14,13 @@ const localStorageKeys = { export default createStore({ modules: { + profile, search, }, state() { return { currentUserId: JSON.parse(localStorage.getItem(localStorageKeys.currentUserId)), token: JSON.parse(localStorage.getItem(localStorageKeys.token)), - currentProfile: null } }, mutations: { @@ -42,9 +43,6 @@ export default createStore({ state.token = token localStorage.setItem(localStorageKeys.token, JSON.stringify(token)) }, - setCurrentProfile(state, profile) { - state.currentProfile = profile - } }, actions: { clear(context) { diff --git a/src/store/profile.js b/src/store/profile.js new file mode 100644 index 0000000..1cf28c6 --- /dev/null +++ b/src/store/profile.js @@ -0,0 +1,117 @@ +// SPDX-FileCopyrightText: WTF Kooperative eG +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +export default { + namespaced: true, + state() { + return { + loading: false, + showSpinner: false, + profileId: null, + profile: null, + isOwnProfile: false, + error: false, + notFound: false + } + }, + mutations: { + setProfileId(state, profileId) { + state.profileId = profileId + }, + clearProfileId(state) { + state.profileId = null + }, + setProfile(state, profile) { + state.profile = profile + }, + clearProfile(state) { + state.profile = null + }, + setLoading(state) { + state.loading = true + }, + setNotLoading(state) { + state.loading = false + }, + setError(state) { + state.error = true + }, + clearError(state) { + state.error = false + }, + showSpinner(state) { + state.showSpinner = true + }, + hideSpinner(state) { + state.showSpinner = false + }, + setNotFound(state, notFound) { + state.notFound = notFound + }, + setIsOwnProfile(state, isOwnProfile) { + state.isOwnProfile = isOwnProfile + } + }, + actions: { + onError({commit}) { + commit('setError') + commit('clearProfileId') + commit('clearProfile') + commit('setNotLoading') + commit('hideSpinner') + }, + onNotFound({commit, dispatch}) { + dispatch('onError') + commit('setNotFound', true) + }, + async load({state, commit, dispatch, rootState}, profileId) { + if (state.loading) { + return + } + + commit('setProfileId', profileId) + commit('setIsOwnProfile', rootState.currentUserId === profileId) + commit('setLoading') + + const timeoutId = setTimeout(() => { + commit('showSpinner') + commit('clearProfile') + }, 0) + + commit('clearError') + commit('setNotFound', false) + + const url = new URL(`${window.ki.apiUrl}/users/${profileId}/profile`) + const headers = { + Authorization: `Bearer ${rootState.token}` + } + + let response + + try { + response = await fetch(url, {headers}) + } catch { + dispatch('onError') + return + } + + clearTimeout(timeoutId) + + if (response.status === 404) { + dispatch('onNotFound') + return + } + + if (!response.ok) { + dispatch('onError') + return + } + + const responseData = await response.json() + commit('setProfile', responseData.profile) + commit('hideSpinner') + commit('setNotSearching') + } + } +} diff --git a/src/views/profile/View.vue b/src/views/profile/View.vue index bce1417..3f76f9b 100644 --- a/src/views/profile/View.vue +++ b/src/views/profile/View.vue @@ -5,60 +5,131 @@ SPDX-License-Identifier: AGPL-3.0-or-later --> + +