204 lines
5.5 KiB
Vue
204 lines
5.5 KiB
Vue
<template>
|
|
<div class="search-view">
|
|
<h2>{{ $t('socialnetwork.usersearch.title') }}</h2>
|
|
<form @submit.prevent="performSearch">
|
|
<div class="form-group">
|
|
<label for="username">{{ $t('socialnetwork.usersearch.username') }}:</label>
|
|
<input type="text" id="username" v-model="searchCriteria.username"
|
|
:placeholder="$t('socialnetwork.usersearch.username')" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="ageFrom">{{ $t('socialnetwork.usersearch.age_from') }}:</label>
|
|
<input type="number" id="ageFrom" v-model="searchCriteria.ageFrom" :min="14" :max="150"
|
|
:placeholder="$t('socialnetwork.usersearch.age_from')" class="age-input" />
|
|
<label for="ageTo">{{ $t('socialnetwork.usersearch.age_to') }}:</label>
|
|
<input type="number" id="ageTo" v-model="searchCriteria.ageTo" :min="14" :max="150"
|
|
:placeholder="$t('socialnetwork.usersearch.age_to')" class="age-input" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="gender">{{ $t('socialnetwork.usersearch.gender') }}:</label>
|
|
<multiselect v-model="searchCriteria.gender" :options="genderOptions" :multiple="true"
|
|
:close-on-select="false" :placeholder="$t('socialnetwork.usersearch.gender')" label="name"
|
|
track-by="name" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<button type="submit" class="search-button">{{ $t('socialnetwork.usersearch.search_button') }}</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="search-results" v-if="searchResults.length">
|
|
<h3>{{ $t('socialnetwork.usersearch.results_title') }}</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>{{ $t("socialnetwork.usersearch.result.nick") }}</th>
|
|
<th>{{ $t("socialnetwork.usersearch.result.gender") }}</th>
|
|
<th>{{ $t("socialnetwork.usersearch.result.age") }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="result in searchResults" :key="result.id">
|
|
<td><span @click.prevent="openUserProfile(result.id)" :class="'clickable g-' + result.gender">{{ result.username }}</span></td>
|
|
<td>{{ result.gender }}</td>
|
|
<td>{{ result.age }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div v-else class="no-results">
|
|
{{ $t('socialnetwork.usersearch.no_results') }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Multiselect from 'vue-multiselect';
|
|
import 'vue-multiselect/dist/vue-multiselect.min.css';
|
|
import apiClient from '@/utils/axios.js';
|
|
|
|
export default {
|
|
components: {
|
|
Multiselect,
|
|
},
|
|
data() {
|
|
return {
|
|
searchCriteria: {
|
|
username: '',
|
|
ageFrom: 14,
|
|
ageTo: 150,
|
|
gender: []
|
|
},
|
|
genderOptions: [],
|
|
searchResults: []
|
|
};
|
|
},
|
|
async mounted() {
|
|
await this.loadGenderOptions();
|
|
},
|
|
methods: {
|
|
async loadGenderOptions() {
|
|
try {
|
|
const response = await apiClient.post('/api/settings/getparamvalues', {
|
|
type: 'gender'
|
|
});
|
|
this.genderOptions = response.data.map(g => ({ name: g.name, value: g.value }));
|
|
} catch (error) {
|
|
console.error('Fehler beim Laden der Geschlechtsoptionen:', error);
|
|
}
|
|
},
|
|
async performSearch() {
|
|
const searchCriteria = {
|
|
username: this.searchCriteria.username,
|
|
ageFrom: this.searchCriteria.ageFrom,
|
|
ageTo: this.searchCriteria.ageTo,
|
|
gender: this.searchCriteria.gender.map(g => g.value)
|
|
};
|
|
|
|
try {
|
|
const response = await apiClient.post('/api/socialnetwork/usersearch', searchCriteria);
|
|
this.searchResults = response.data;
|
|
} catch (error) {
|
|
console.error('Fehler bei der Suche:', error);
|
|
}
|
|
},
|
|
openUserProfile(id) {
|
|
this.$root.$refs.userProfileDialog.userId = id;
|
|
this.$root.$refs.userProfileDialog.open();
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.search-view {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
padding: 0;
|
|
}
|
|
|
|
h2 {
|
|
margin-bottom: 10px;
|
|
text-align: center;
|
|
}
|
|
|
|
.form-group {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
label {
|
|
width: 120px;
|
|
font-weight: bold;
|
|
margin-right: 10px;
|
|
text-align: right;
|
|
}
|
|
|
|
input,
|
|
.multiselect__input {
|
|
flex: 1;
|
|
padding: 5px;
|
|
border-radius: 4px;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
.age-input {
|
|
width: 70px;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.search-results {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.search-results ul {
|
|
list-style-type: none;
|
|
padding: 0;
|
|
}
|
|
|
|
.search-results li {
|
|
padding: 8px;
|
|
background: #f9f9f9;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
|
|
table {
|
|
margin: 0.5em 0;
|
|
padding: 0;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
thead {
|
|
color: #7BBE55;
|
|
}
|
|
th, td {
|
|
padding-right: 1em;
|
|
|
|
}
|
|
|
|
th, td:not:last-child {
|
|
border-bottom: 1px solid #7E471B;
|
|
}
|
|
|
|
.clickable {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.no-results {
|
|
margin-top: 20px;
|
|
text-align: center;
|
|
color: #888;
|
|
}
|
|
|
|
.g-male {
|
|
color: #3377ff;
|
|
}
|
|
|
|
.g-female {
|
|
color: #ff3377;
|
|
}
|
|
</style>
|