Fixed pic upload page relation

This commit is contained in:
Torsten Schulz
2024-07-12 12:06:20 +02:00
parent 0f19465709
commit 2719bd3a3b
3 changed files with 161 additions and 132 deletions

View File

@@ -1,4 +1,4 @@
const { Image } = require('../models'); const { Image, MenuItem, Page } = require('../models');
const { v4: uuidv4 } = require('uuid'); const { v4: uuidv4 } = require('uuid');
const multer = require('multer'); const multer = require('multer');
const path = require('path'); const path = require('path');
@@ -17,17 +17,33 @@ const upload = multer({ storage });
exports.uploadImage = upload.single('image'); exports.uploadImage = upload.single('image');
exports.getAllPages = async (req, res) => {
try {
const pages = await MenuItem.findAll();
res.status(200).json(pages.map((item) => {return { link: item.link, name: item.name}; }));
} catch (error) {
console.log(error);
res.status(500).send('Fehler beim Auslesen');
}
}
exports.saveImageDetails = async (req, res) => { exports.saveImageDetails = async (req, res) => {
try { try {
const { title, description, pageId } = req.body; const { title, description, page } = req.body;
const filename = req.file.filename; const filename = req.file.filename;
const pageItem = await Page.findAll({ where: { link: page } });
console.log(pageItem)
const newImage = await Image.create({ const newImage = await Image.create({
id: uuidv4(), id: uuidv4(),
filename, filename,
title, title,
description, description,
pageId: pageId || null pageId: pageItem && pageItem[0] ? pageItem[0].id : null
}); });
if (page) {
const imageUrl = `/uploads/${filename}`;
await MenuItem.update({ image: imageUrl }, { where: { link: page} });
}
res.status(201).json(newImage); res.status(201).json(newImage);
} catch (error) { } catch (error) {
console.error('Fehler beim Speichern des Bildes:', error); console.error('Fehler beim Speichern des Bildes:', error);
@@ -37,7 +53,7 @@ exports.saveImageDetails = async (req, res) => {
exports.getImages = async (req, res) => { exports.getImages = async (req, res) => {
try { try {
const images = await Image.findAll({ order: [['title', 'ASC']]}); const images = await Image.findAll({ order: [['title', 'ASC']] });
res.status(200).json(images); res.status(200).json(images);
} catch (error) { } catch (error) {
console.error('Fehler beim Abrufen der Bilder:', error); console.error('Fehler beim Abrufen der Bilder:', error);

View File

@@ -1,12 +1,14 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { uploadImage, saveImageDetails, getImages, getImagesByPage, getImageById, getImageByHash, updateImage } = require('../controllers/imageController'); const { getAllPages, uploadImage, saveImageDetails, getImages, getImagesByPage, getImageById, getImageByHash, updateImage } = require('../controllers/imageController');
const authMiddleware = require('../middleware/authMiddleware') const authMiddleware = require('../middleware/authMiddleware')
router.post('/', authMiddleware, uploadImage, saveImageDetails); router.post('/', authMiddleware, uploadImage, saveImageDetails);
router.get('/', authMiddleware, getImages); router.get('/', authMiddleware, getImages);
router.get('/page/:pageId', getImagesByPage); router.get('/page/:pageId', getImagesByPage);
router.put('/hash/:id', getImageByHash);
router.get('/pages', getAllPages);
router.get('/:id', getImageById); router.get('/:id', getImageById);
router.put('/:id', authMiddleware, updateImage); router.put('/:id', authMiddleware, updateImage);
router.put('/hash/:id', getImageByHash);
module.exports = router; module.exports = router;

View File

@@ -1,134 +1,145 @@
<template> <template>
<div> <div>
<h1>Bild hochladen</h1> <h1>Bild hochladen</h1>
<form @submit.prevent="uploadImage"> <form @submit.prevent="uploadImage">
<div> <div>
<label for="title">Titel</label> <label for="title">Titel</label>
<input type="text" id="title" v-model="title" /> <input type="text" id="title" v-model="title" />
</div> </div>
<div> <div>
<label for="description">Beschreibung</label> <label for="description">Beschreibung</label>
<textarea id="description" v-model="description"></textarea> <textarea id="description" v-model="description"></textarea>
</div> </div>
<div> <div>
<label for="image">Bild</label> <label for="image">Bild</label>
<input type="file" id="image" @change="onFileChange" /> <input type="file" id="image" @change="onFileChange" />
</div> </div>
<div> <div>
<label for="page">Seite</label> <label for="page">Seite</label>
<select id="page" v-model="selectedPage"> <select id="page" v-model="selectedPage">
<option value="">Keine Seite</option> <option value="">Keine Seite</option>
<option v-for="page in pages" :key="page.id" :value="page.id">{{ page.title }}</option> <option v-for="page in pages" :key="page.value" :value="page.value">{{ page.caption }}</option>
</select> </select>
</div> </div>
<button type="submit">Hochladen</button> <button type="submit">Hochladen</button>
</form> </form>
<div v-if="images.length"> <div v-if="images.length">
<h2>Hochgeladene Bilder</h2> <h2>Hochgeladene Bilder</h2>
<div v-for="image in images" :key="image.id" class="uploaded-image"> <div v-for="image in images" :key="image.id" class="uploaded-image">
<img :src="`/images/uploads/${image.filename}`" :alt="image.title" width="100" /> <img :src="`/images/uploads/${image.filename}`" :alt="image.title" width="100" />
<input type="text" v-model="image.title" @change="updateImage(image)" /> <input type="text" v-model="image.title" @change="updateImage(image)" />
<textarea v-model="image.description" @change="updateImage(image)"></textarea> <textarea v-model="image.description" @change="updateImage(image)"></textarea>
<p>{{ formatDate(image.uploadDate) }} {{ formatTimeFromDate(image.uploadDate) }}</p> <p>{{ formatDate(image.uploadDate) }} {{ formatTimeFromDate(image.uploadDate) }}</p>
</div>
</div> </div>
</div> </div>
</template> </div>
</template>
<script> <script>
import axios from '../../axios'; import axios from '../../axios';
import { formatDate, formatTimeFromDate } from '@/utils/strings' import { formatDate, formatTimeFromDate } from '@/utils/strings'
export default { export default {
name: 'ImageUpload', name: 'ImageUpload',
data() { data() {
return { return {
title: '', title: '',
description: '', description: '',
image: null, image: null,
selectedPage: '', selectedPage: '',
pages: [], pages: [],
images: [] images: []
}; };
},
methods: {
formatDate,
formatTimeFromDate,
onFileChange(e) {
this.image = e.target.files[0];
}, },
methods: { async uploadImage() {
formatDate, const formData = new FormData();
formatTimeFromDate, formData.append('title', this.title);
onFileChange(e) { formData.append('description', this.description);
this.image = e.target.files[0]; formData.append('image', this.image);
}, formData.append('page', this.selectedPage);
async uploadImage() {
const formData = new FormData();
formData.append('title', this.title);
formData.append('description', this.description);
formData.append('image', this.image);
formData.append('pageId', this.selectedPage);
try { try {
await axios.post('/image/', formData); await axios.post('/image/', formData);
this.fetchImages(); this.fetchImages();
this.resetForm(); this.resetForm();
} catch (error) { } catch (error) {
console.error('Fehler beim Hochladen des Bildes:', error); console.error('Fehler beim Hochladen des Bildes:', error);
}
},
async fetchImages() {
try {
const response = await axios.get('/image');
this.images = response.data;
} catch (error) {
console.error('Fehler beim Abrufen der Bilder:', error);
}
},
async fetchPages() {
try {
const response = await axios.get('/image/pages');
this.pages = response.data;
} catch (error) {
console.error('Fehler beim Abrufen der Seiten:', error);
}
},
async updateImage(image) {
try {
await axios.put(`/image/${image.id}`, {
title: image.title,
description: image.description
});
this.fetchImages();
} catch (error) {
console.error('Fehler beim Aktualisieren des Bildes:', error);
}
},
resetForm() {
this.title = '';
this.description = '';
this.image = null;
this.selectedPage = '';
document.getElementById('image').value = null;
} }
}, },
mounted() { async fetchImages() {
this.fetchImages(); try {
this.fetchPages(); const response = await axios.get('/image');
this.images = response.data;
} catch (error) {
console.error('Fehler beim Abrufen der Bilder:', error);
}
},
async fetchPages() {
try {
const response = await axios.get('/menu-data');
const buildRecursive = function (data, prefix = '') {
return data.flatMap(item => {
let children = [];
if (item.submenu && item.submenu.length) {
children = buildRecursive(item.submenu, prefix + item.name + " -> ");
}
return [{ value: item.link, caption: prefix + item.name }, ...children];
});
};
this.pages = buildRecursive(response.data);
} catch (error) {
console.error('Fehler beim Abrufen der Seiten:', error);
}
},
async updateImage(image) {
try {
await axios.put(`/image/${image.id}`, {
title: image.title,
description: image.description
});
this.fetchImages();
} catch (error) {
console.error('Fehler beim Aktualisieren des Bildes:', error);
}
},
resetForm() {
this.title = '';
this.description = '';
this.image = null;
this.selectedPage = '';
document.getElementById('image').value = null;
} }
}; },
</script> mounted() {
this.fetchImages();
this.fetchPages();
}
};
</script>
<style scoped> <style scoped>
form div { form div {
margin-bottom: 10px; margin-bottom: 10px;
} }
.uploaded-image {
display: inline-block;
margin: 0 0 0.5em 0.5em;
border: 1px solid #e0e0e0;
padding: 10px;
}
.uploaded-image input,
.uploaded-image textarea {
width: 100%;
margin: 5px 0;
}
</style>
.uploaded-image {
display: inline-block;
margin: 0 0 0.5em 0.5em;
border: 1px solid #e0e0e0;
padding: 10px;
}
.uploaded-image input,
.uploaded-image textarea {
width: 100%;
margin: 5px 0;
}
</style>