Enhance member gallery generation with customizable image size selection
This commit updates the member gallery generation feature by allowing users to specify the image size through the frontend. The DiaryView component now includes a dropdown for selecting image dimensions (100x100, 150x150, 200x200), which is passed to the backend for processing. The memberService has been modified to validate the size parameter, ensuring only allowed dimensions are used. These changes improve user experience by providing flexibility in gallery display options.
This commit is contained in:
@@ -120,7 +120,8 @@ const generateMemberGallery = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.params;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const result = await MemberService.generateMemberGallery(userToken, clubId);
|
||||
const size = parseInt(req.query.size) || 200; // Default: 200x200
|
||||
const result = await MemberService.generateMemberGallery(userToken, clubId, size);
|
||||
if (result.status === 200) {
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('Cache-Control', 'no-store');
|
||||
|
||||
@@ -1070,10 +1070,14 @@ class MemberService {
|
||||
}
|
||||
}
|
||||
|
||||
async generateMemberGallery(userToken, clubId) {
|
||||
async generateMemberGallery(userToken, clubId, size = 200) {
|
||||
try {
|
||||
await checkAccess(userToken, clubId);
|
||||
|
||||
// Validiere und setze tileDimension (nur 100, 150, 200 erlaubt)
|
||||
const validSizes = [100, 150, 200];
|
||||
const tileDimension = validSizes.includes(size) ? size : 200;
|
||||
|
||||
const members = await Member.findAll({
|
||||
where: {
|
||||
clubId,
|
||||
@@ -1130,8 +1134,6 @@ class MemberService {
|
||||
error: 'Keine aktiven Mitglieder mit Bildern gefunden'
|
||||
};
|
||||
}
|
||||
|
||||
const tileDimension = 200;
|
||||
// Maximale Breite für die Galerie (Dialog-Breite 900px - 32px Padding = 868px)
|
||||
const maxGalleryWidth = 868;
|
||||
// Berechne maximale Anzahl Spalten, die in die Breite passen
|
||||
|
||||
@@ -510,6 +510,14 @@
|
||||
@close="closeGalleryDialog"
|
||||
>
|
||||
<div class="gallery-dialog-content">
|
||||
<div class="gallery-controls">
|
||||
<label for="gallery-size">Bildgröße:</label>
|
||||
<select id="gallery-size" v-model="gallerySize" @change="regenerateGallery" :disabled="galleryLoading">
|
||||
<option :value="100">100x100 px</option>
|
||||
<option :value="150">150x150 px</option>
|
||||
<option :value="200">200x200 px</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="galleryLoading" class="gallery-loading">Galerie wird erstellt…</div>
|
||||
<div v-else-if="galleryImageUrl" class="gallery-image-wrapper">
|
||||
<img :src="galleryImageUrl" alt="Mitglieder-Galerie" class="gallery-dialog-image">
|
||||
@@ -667,6 +675,7 @@ export default {
|
||||
galleryLoading: false,
|
||||
galleryImageUrl: null,
|
||||
galleryError: '',
|
||||
gallerySize: 200,
|
||||
editShowDropdown: false,
|
||||
editSearchResults: [],
|
||||
editSearchForId: null,
|
||||
@@ -786,16 +795,22 @@ export default {
|
||||
}
|
||||
},
|
||||
async openGalleryDialog() {
|
||||
if (!this.currentClub || this.galleryLoading) {
|
||||
return;
|
||||
}
|
||||
this.showGalleryDialog = true;
|
||||
await this.loadGallery();
|
||||
},
|
||||
async loadGallery() {
|
||||
if (!this.currentClub || this.galleryLoading) {
|
||||
return;
|
||||
}
|
||||
this.galleryLoading = true;
|
||||
this.galleryError = '';
|
||||
try {
|
||||
const response = await apiClient.get(`/clubmembers/gallery/${this.currentClub}`, { responseType: 'blob' });
|
||||
const response = await apiClient.get(`/clubmembers/gallery/${this.currentClub}?size=${this.gallerySize}`, { responseType: 'blob' });
|
||||
this.revokeGalleryImage();
|
||||
this.galleryImageUrl = URL.createObjectURL(response.data);
|
||||
this.showGalleryDialog = true;
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Erstellen der Mitglieder-Galerie:', error);
|
||||
this.galleryError = error?.response?.data?.error || 'Galerie konnte nicht erstellt werden.';
|
||||
@@ -804,6 +819,9 @@ export default {
|
||||
this.galleryLoading = false;
|
||||
}
|
||||
},
|
||||
async regenerateGallery() {
|
||||
await this.loadGallery();
|
||||
},
|
||||
closeGalleryDialog() {
|
||||
this.showGalleryDialog = false;
|
||||
this.revokeGalleryImage();
|
||||
@@ -2474,6 +2492,7 @@ h3 {
|
||||
|
||||
.gallery-dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
@@ -2482,6 +2501,36 @@ h3 {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.gallery-controls {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--border-color, #ddd);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background: #f9f9f9;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gallery-controls label {
|
||||
font-weight: 500;
|
||||
color: var(--text-color, #333);
|
||||
}
|
||||
|
||||
.gallery-controls select {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border-color, #ddd);
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gallery-controls select:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.gallery-image-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user