ki-frontend/src/views/Search.vue

187 lines
4.8 KiB
Vue
Raw Normal View History

2021-09-19 12:55:33 +02:00
<!--
SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
2021-06-07 17:41:25 +02:00
<template>
2021-09-21 23:56:17 +02:00
<div class="content">
<div class="bg-wtf text-white pt-3 pb-4">
<div class="container">
<div class="fs-3 text-center lh-1 mb-3">Finde WTF Member</div>
<div class="card mx-auto bg-white">
<div class="card-body">
<form @submit.prevent="handleSubmit">
<fieldset class="d-flex" :disabled="searching">
<div class="flex-grow-1 me-3">
<input
type="text"
class="form-control"
id="searchText"
v-model="searchText"
placeholder="Nick, Name, Fähigkeit, Sprache"
2021-09-21 23:56:17 +02:00
ref="searchTextInput"
/>
</div>
<div class="">
<button type="submit" class="btn btn-primary">
<i class="bi-search"></i>
<span class="d-none d-md-inline"> Suchen</span>
</button>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
2021-09-21 23:56:17 +02:00
<div class="container pt-4 pb-3">
<div class="text-center" v-if="showSpinner">
<Spinner />
</div>
<div
class="fs-2 text-danger text-center"
role="alert"
v-if="error"
>
<div class="fs-1 mb-3">Kernel panic :/</div>
Bei der Suche ist ein Fehler aufgetreten.
</div>
<div v-else-if="showNoResults" class="fs-2 text-black-50 text-center">
<div class="fs-1 mb-3">nullptr :/</div>
Es wurde kein Suchergebnis gefunden.
<p v-if="searchText !== ''">Probiere eine andere Suche.</p>
</div>
<div v-else-if="showResults">
2022-01-16 16:36:54 +01:00
<div class="d-flex justify-content-around">
<Paginator
:pages="pages"
:current="currentPage"
@page="handlePageSelected"
/>
</div>
2021-09-21 23:56:17 +02:00
<SearchResult
v-for="profile in profiles"
:key="profile.user_id"
class="mb-3"
:profile="profile"
/>
2022-01-16 16:36:54 +01:00
<div class="d-flex justify-content-around">
<Paginator
:pages="pages"
:current="currentPage"
@page="handlePageSelected"
/>
</div>
</div>
</div>
</div>
2021-06-07 17:41:25 +02:00
</template>
2021-09-21 23:56:17 +02:00
2021-06-07 17:41:25 +02:00
<script>
2021-09-21 23:56:17 +02:00
import { mapState } from 'vuex'
2022-01-16 16:36:54 +01:00
import Paginator from '@/components/Paginator'
2021-09-21 23:56:17 +02:00
import SearchResult from '@/components/SearchResult'
import Spinner from '@/components/Spinner'
2021-08-18 22:59:44 +02:00
2021-06-07 17:41:25 +02:00
export default {
2021-09-21 23:56:17 +02:00
name: 'Search',
components: {
2022-01-16 16:36:54 +01:00
Paginator,
2021-09-21 23:56:17 +02:00
SearchResult,
Spinner,
2021-06-07 17:41:25 +02:00
},
2022-01-16 16:36:54 +01:00
data() {
return {
textChanged: false
}
},
2021-09-21 23:56:17 +02:00
computed: {
...mapState({
searching: state => state.search.searching,
profiles: state => state.search.profiles,
error: state => state.search.error,
showSpinner: state => state.search.showSpinner,
2022-01-16 16:36:54 +01:00
pages: state => state.search.pages,
2021-09-21 23:56:17 +02:00
}),
searchText: {
get() {
return this.$store.state.search.query.search
},
set(text) {
this.$store.commit('search/setQuerySearch', text)
2022-01-16 16:36:54 +01:00
this.textChanged = true
}
},
currentPage: {
get() {
return this.$store.state.search.query.page
},
set(page) {
this.$store.commit('search/setQueryPage', page)
2021-09-21 23:56:17 +02:00
}
},
showNoResults() {
return !this.searching && (!this.profiles || this.profiles.length === 0)
},
showResults() {
return !this.error && this.profiles && this.profiles.length > 0
}
},
watch: {
searching(value) {
2021-09-24 17:45:11 +02:00
if (!value) {
2021-09-21 23:56:17 +02:00
if (this.$refs.searchTextInput) {
2021-09-24 17:45:11 +02:00
this.focusSearchText()
2021-09-21 23:56:17 +02:00
}
}
}
},
methods: {
handleSubmit() {
2022-01-16 16:36:54 +01:00
if (this.textChanged === true) {
this.$store.commit('search/setQueryPage', 1)
}
this.pushState()
2021-09-21 23:56:17 +02:00
this.$store.dispatch('search/search')
2021-09-24 17:45:11 +02:00
},
focusSearchText() {
this.$nextTick(() => {
this.$refs.searchTextInput.focus()
})
2022-01-16 16:36:54 +01:00
},
handlePageSelected(page) {
this.currentPage = page
this.pushState()
this.$store.dispatch('search/search')
},
pushState() {
this.$router.push({ query: { query: this.searchText, page: this.currentPage }})
2021-09-21 23:56:17 +02:00
}
},
2021-09-21 23:56:17 +02:00
created() {
2022-01-16 16:36:54 +01:00
if (this.$route.query.query) {
2021-09-21 23:56:17 +02:00
this.searchText = this.$route.query.query
this.$store.commit('search/clearProfiles')
}
2022-01-16 16:36:54 +01:00
if (this.$route.query.page) {
this.currentPage = parseInt(this.$route.query.page, 10)
this.$store.commit('search/clearProfiles')
}
2021-09-21 23:56:17 +02:00
this.$store.dispatch('search/search')
}
};
2021-07-28 21:52:12 +02:00
</script>
2021-09-21 23:56:17 +02:00
<style scoped>
.container {
max-width: 768px;
}
.content {
min-height: calc(100vh - 60px);
}
</style>