Bugs in settings fixed, profile added

This commit is contained in:
Torsten Schulz
2024-09-21 00:25:42 +02:00
parent c5a72d57d8
commit e494fe41db
65 changed files with 3121 additions and 7478 deletions

View File

@@ -14,14 +14,15 @@
<td>{{ formatDateTimeLong(contact.createdAt) }}</td>
<td>{{ contact.email }}</td>
<td>
<button @clicked="openRequest(contact)">{{ $t('admin.contacts.open') }}</button>
<button @clicked="finishRequest(contact)">{{ $t('admin.contacts.finished') }}</button>
<button @click="openRequest(contact)">{{ $t('admin.contacts.open') }}</button>
<button @click="finishRequest(contact)">{{ $t('admin.contacts.finished') }}</button>
</td>
</tr>
</tbody>
</table>
</div>
<ErrorDialog ref="errorDialog" />
<AnswerContact ref="answerContactDialog" />
</template>
<script>
@@ -29,11 +30,13 @@ import apiClient from '@/utils/axios.js';
import { mapGetters } from 'vuex';
import ErrorDialog from '@/dialogues/standard/ErrorDialog.vue';
import { formatDateTimeLong } from '@/utils/datetime.js';
import AnswerContact from '../../dialogues/admin/AnswerContact.vue';
export default {
name: 'AdminContactsView',
components: {
ErrorDialog
ErrorDialog,
AnswerContact,
},
data() {
return {
@@ -54,10 +57,10 @@ export default {
}
},
async openRequest(contact) {
this.$refs.answerContactDialog.open(contact);
},
async finishRequest(contact) {
await apiClient.get('/api/admin/opencontacts/finish/${contact.id}');
}
}
}

View File

@@ -0,0 +1,17 @@
<template>
<div>
<h2>{{ $t("settings.flirt.title") }}</h2>
<SettingsWidget :settingsType="'flirt'" />
</div>
</template>
<script>
import SettingsWidget from '@/components/SettingsWidget.vue';
export default {
name: 'FlirtSettingsView',
components: {
SettingsWidget,
}
}
</script>

View File

@@ -0,0 +1,206 @@
<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>
<UserProfileDialog ref="userProfileDialog" :username="selectedUsername" />
</template>
<script>
import Multiselect from 'vue-multiselect';
import 'vue-multiselect/dist/vue-multiselect.min.css';
import apiClient from '@/utils/axios.js';
import UserProfileDialog from '@/dialogues/socialnetwork/UserProfileDialog.vue';
export default {
components: {
Multiselect,
UserProfileDialog
},
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.$refs.userProfileDialog.userId = id;
this.$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>