ki-frontend/src/views/Search.vue

134 lines
3.4 KiB
Vue

<!--
SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<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, Fähigkeit, Sprache"
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>
<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">
<SearchResult
v-for="profile in profiles"
:key="profile.user_id"
class="mb-3"
:profile="profile"
/>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import SearchResult from '@/components/SearchResult'
import Spinner from '@/components/Spinner'
export default {
name: 'Search',
components: {
SearchResult,
Spinner,
},
computed: {
...mapState({
searching: state => state.search.searching,
profiles: state => state.search.profiles,
error: state => state.search.error,
showSpinner: state => state.search.showSpinner,
}),
searchText: {
get() {
return this.$store.state.search.query.search
},
set(text) {
this.$store.commit('search/setQuerySearch', text)
}
},
showNoResults() {
return !this.searching && (!this.profiles || this.profiles.length === 0)
},
showResults() {
return !this.error && this.profiles && this.profiles.length > 0
}
},
watch: {
searching(value) {
if (value) {
if (this.$refs.searchTextInput) {
this.$refs.searchTextInput.focus()
}
}
}
},
methods: {
handleSubmit() {
this.$store.dispatch('search/search')
}
},
created() {
if (this.$route.query.query !== undefined) {
this.searchText = this.$route.query.query
this.$store.commit('search/clearProfiles')
}
this.$store.dispatch('search/search')
}
};
</script>
<style scoped>
.container {
max-width: 768px;
}
.content {
min-height: calc(100vh - 60px);
}
</style>