diff --git a/controllers/imageController.js b/controllers/imageController.js new file mode 100644 index 0000000..5667f4b --- /dev/null +++ b/controllers/imageController.js @@ -0,0 +1,95 @@ +const { Image } = require('../models'); +const { v4: uuidv4 } = require('uuid'); +const multer = require('multer'); +const path = require('path'); + +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + cb(null, 'public/images/uploads'); + }, + filename: (req, file, cb) => { + const uniqueSuffix = `${uuidv4()}${path.extname(file.originalname)}`; + cb(null, uniqueSuffix); + } +}); + +const upload = multer({ storage }); + +exports.uploadImage = upload.single('image'); + +exports.saveImageDetails = async (req, res) => { + try { + const { title, description, pageId } = req.body; + const filename = req.file.filename; + const newImage = await Image.create({ + id: uuidv4(), + filename, + title, + description, + pageId: pageId || null + }); + res.status(201).json(newImage); + } catch (error) { + console.error('Fehler beim Speichern des Bildes:', error); + res.status(500).send('Fehler beim Speichern des Bildes'); + } +}; + +exports.getImages = async (req, res) => { + try { + const images = await Image.findAll(); + res.status(200).json(images); + } catch (error) { + console.error('Fehler beim Abrufen der Bilder:', error); + res.status(500).send('Fehler beim Abrufen der Bilder'); + } +}; + +exports.getImagesByPage = async (req, res) => { + try { + const { pageId } = req.params; + const images = await Image.findAll({ where: { pageId } }); + res.status(200).json(images); + } catch (error) { + console.error('Fehler beim Abrufen der Bilder:', error); + res.status(500).send('Fehler beim Abrufen der Bilder'); + } +}; + +exports.getImageById = async (req, res) => { + try { + const { id } = req.params; + const image = await Image.findByPk(id); + if (image) { + res.status(200).json(image); + } else { + res.status(404).send('Bild nicht gefunden'); + } + } catch (error) { + console.error('Fehler beim Abrufen des Bildes:', error); + res.status(500).send('Fehler beim Abrufen des Bildes'); + } +}; + +exports.updateImage = async (req, res) => { + try { + const { id } = req.params; + const { title, description } = req.body; + + const image = await Image.findByPk(id); + + if (!image) { + return res.status(404).json({ error: 'Bild nicht gefunden' }); + } + + image.title = title; + image.description = description; + + await image.save(); + + res.json(image); + } catch (error) { + console.error('Fehler beim Aktualisieren des Bildes:', error); + res.status(500).json({ error: 'Fehler beim Aktualisieren des Bildes' }); + } +}; \ No newline at end of file diff --git a/controllers/menuDataController.js b/controllers/menuDataController.js index 6012bf7..33c5407 100644 --- a/controllers/menuDataController.js +++ b/controllers/menuDataController.js @@ -1,4 +1,4 @@ -const { MenuItem } = require('../models'); // Stellen Sie sicher, dass das Modell korrekt importiert wird +const { MenuItem } = require('../models'); const fetchMenuData = require('../utils/fetchMenuData'); exports.getMenuData = async (req, res) => { @@ -13,8 +13,15 @@ exports.getMenuData = async (req, res) => { exports.saveMenuData = async (req, res) => { try { const menuData = req.body; + const adjustedMenuData = menuData.map(item => { + item.parent_id = item.parent_id < 0 ? null : item.parent_id; + return item; + }) + .sort((a, b) => (a.parent_id === null ? -1 : 1) - (b.parent_id === null ? -1 : 1)); await MenuItem.destroy({ where: {} }); - await MenuItem.bulkCreate(menuData, { include: [{ model: MenuItem, as: 'submenu' }] }); + for (const item of adjustedMenuData) { + await MenuItem.create(item); + } res.status(200).send('Menü-Daten erfolgreich gespeichert'); } catch (error) { console.error('Fehler beim Speichern der Menü-Daten:', error); diff --git a/controllers/userController.js b/controllers/userController.js new file mode 100644 index 0000000..8ce9dea --- /dev/null +++ b/controllers/userController.js @@ -0,0 +1,60 @@ +const { User } = require('../models'); + +exports.getAllUsers = async (req, res) => { + try { + const users = await User.findAll(); + res.status(200).json(users); + } catch (error) { + res.status(500).json({ message: 'Error fetching users' }); + } +}; + +exports.getUserById = async (req, res) => { + try { + const user = await User.findByPk(req.params.id); + if (user) { + res.status(200).json(user); + } else { + res.status(404).json({ message: 'User not found' }); + } + } catch (error) { + res.status(500).json({ message: 'Error fetching user' }); + } +}; + +exports.createUser = async (req, res) => { + try { + const user = await User.create(req.body); + res.status(201).json(user); + } catch (error) { + res.status(500).json({ message: 'Error creating user' }); + } +}; + +exports.updateUser = async (req, res) => { + try { + const user = await User.findByPk(req.params.id); + if (user) { + await user.update(req.body); + res.status(200).json(user); + } else { + res.status(404).json({ message: 'User not found' }); + } + } catch (error) { + res.status(500).json({ message: 'Error updating user' }); + } +}; + +exports.deleteUser = async (req, res) => { + try { + const user = await User.findByPk(req.params.id); + if (user) { + await user.destroy(); + res.status(200).json({ message: 'User deleted successfully' }); + } else { + res.status(404).json({ message: 'User not found' }); + } + } catch (error) { + res.status(500).json({ message: 'Error deleting user' }); + } +}; diff --git a/controllers/worshipController.js b/controllers/worshipController.js index d11c950..4ded946 100644 --- a/controllers/worshipController.js +++ b/controllers/worshipController.js @@ -1,4 +1,4 @@ -const { Worship, EventPlace } = require('../models'); +const { Worship, EventPlace, Sequelize } = require('../models'); const { Op } = require('sequelize'); // Importieren Sie die Operatoren von Sequelize exports.getAllWorships = async (req, res) => { @@ -53,7 +53,14 @@ exports.getFilteredWorships = async (req, res) => { const where = {}; if (location && location !== '-1') { - where.eventPlaceId = location; + if (location.includes('|')) { + const locationsArray = location.split('|'); + where.eventPlaceId = { + [Sequelize.Op.in]: locationsArray + } + } else { + where.eventPlaceId = location; + } } where.date = { diff --git a/migrations/20240617191416-create-images-table.js b/migrations/20240617191416-create-images-table.js new file mode 100644 index 0000000..478fa99 --- /dev/null +++ b/migrations/20240617191416-create-images-table.js @@ -0,0 +1,35 @@ +'use strict'; + +module.exports = { + up: async (queryInterface, Sequelize) => { + await queryInterface.createTable('images', { + id: { + allowNull: false, + primaryKey: true, + type: Sequelize.UUID, + defaultValue: Sequelize.UUIDV4 + }, + filename: { + type: Sequelize.STRING, + allowNull: false + }, + title: { + type: Sequelize.STRING, + allowNull: true + }, + description: { + type: Sequelize.TEXT, + allowNull: true + }, + uploadDate: { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.NOW + } + }); + }, + + down: async (queryInterface, Sequelize) => { + await queryInterface.dropTable('images'); + } +}; diff --git a/migrations/20240617192740-create-images-table.js b/migrations/20240617192740-create-images-table.js new file mode 100644 index 0000000..df137c8 --- /dev/null +++ b/migrations/20240617192740-create-images-table.js @@ -0,0 +1,15 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.addColumn('images', 'pageId', { + type: Sequelize.INTEGER, + allowNull: true, + }); + }, + + async down (queryInterface, Sequelize) { + await queryInterface.removeColumn('images', 'pageId'); + } +}; diff --git a/models/Image.js b/models/Image.js new file mode 100644 index 0000000..3318bad --- /dev/null +++ b/models/Image.js @@ -0,0 +1,36 @@ +const { DataTypes } = require('sequelize'); + +module.exports = (sequelize) => { + const Image = sequelize.define('Image', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true + }, + filename: { + type: DataTypes.STRING, + allowNull: false + }, + title: { + type: DataTypes.STRING, + allowNull: true + }, + description: { + type: DataTypes.TEXT, + allowNull: true + }, + uploadDate: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW + }, + pageId: { + type: DataTypes.UUID, + allowNull: true + } + }, { + tableName: 'images', + timestamps: false + }); + + return Image; +}; diff --git a/package-lock.json b/package-lock.json index cac17e8..75abc4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "miriamgemeinde", "version": "0.1.0", "dependencies": { + "@iconoir/vue": "^7.7.0", "@tiptap/extension-bold": "^2.4.0", "@tiptap/extension-bullet-list": "^2.4.0", "@tiptap/extension-heading": "^2.4.0", @@ -21,7 +22,6 @@ "@tiptap/extension-underline": "^2.4.0", "@tiptap/starter-kit": "^2.4.0", "@tiptap/vue-3": "^2.4.0", - "@vueup/vue-quill": "^1.2.0", "axios": "^1.7.2", "bcryptjs": "^2.4.3", "body-parser": "^1.20.2", @@ -32,10 +32,12 @@ "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", + "multer": "^1.4.5-lts.1", "mysql2": "^3.10.1", "nodemon": "^3.1.3", "sequelize": "^6.37.3", "sequelize-cli": "^6.6.2", + "uuid": "^10.0.0", "vm-browserify": "^1.1.2", "vue": "^3.2.13", "vue-multiselect": "^3.0.0", @@ -1958,6 +1960,52 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@iconoir/vue": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@iconoir/vue/-/vue-7.7.0.tgz", + "integrity": "sha512-EvJK80DUGpCFd2MZsC5K6duv/h4zafruBSQYV9F5b+kJOrdWNCHxEHpwbUwjsI35GpSzMD0N2jAR86s3YTsMmw==", + "dependencies": { + "vue-demi": "^0.14.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/iconoir" + }, + "peerDependencies": { + "@vue/composition-api": ">=1.0.0-rc.1", + "vue": "^2.6.11 || >=3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@iconoir/vue/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -3741,18 +3789,6 @@ "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==", "dev": true }, - "node_modules/@vueup/vue-quill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vueup/vue-quill/-/vue-quill-1.2.0.tgz", - "integrity": "sha512-kd5QPSHMDpycklojPXno2Kw2JSiKMYduKYQckTm1RJoVDA557MnyUXgcuuDpry4HY/Rny9nGNcK+m3AHk94wag==", - "dependencies": { - "quill": "^1.3.7", - "quill-delta": "^4.2.2" - }, - "peerDependencies": { - "vue": "^3.2.41" - } - }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -4114,6 +4150,11 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/arch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", @@ -4657,8 +4698,7 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-xor": { "version": "1.0.3", @@ -4666,6 +4706,17 @@ "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -5143,6 +5194,47 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -5280,8 +5372,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -7158,11 +7249,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -8373,8 +8459,7 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -8822,11 +8907,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -8849,11 +8929,6 @@ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" - }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -9463,7 +9538,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9490,7 +9564,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "dependencies": { "minimist": "^1.2.6" }, @@ -9537,6 +9610,23 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", @@ -10995,8 +11085,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress": { "version": "2.0.3", @@ -11358,16 +11447,6 @@ "quill-delta": "^3.6.2" } }, - "node_modules/quill-delta": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz", - "integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==", - "dependencies": { - "fast-diff": "1.2.0", - "lodash.clonedeep": "^4.5.0", - "lodash.isequal": "^4.5.0" - } - }, "node_modules/quill/node_modules/fast-diff": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", @@ -11972,6 +12051,14 @@ "node": ">=10" } }, + "node_modules/sequelize/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -12290,6 +12377,15 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12436,6 +12532,14 @@ "readable-stream": "^3.5.0" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -12939,6 +13043,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -13064,8 +13173,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utila": { "version": "0.4.0", @@ -13082,9 +13190,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -13752,9 +13864,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -13995,9 +14107,9 @@ "dev": true }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" @@ -14015,6 +14127,14 @@ } } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index e5f95d5..0118f12 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@iconoir/vue": "^7.7.0", "@tiptap/extension-bold": "^2.4.0", "@tiptap/extension-bullet-list": "^2.4.0", "@tiptap/extension-heading": "^2.4.0", @@ -21,7 +22,6 @@ "@tiptap/extension-underline": "^2.4.0", "@tiptap/starter-kit": "^2.4.0", "@tiptap/vue-3": "^2.4.0", - "@vueup/vue-quill": "^1.2.0", "axios": "^1.7.2", "bcryptjs": "^2.4.3", "body-parser": "^1.20.2", @@ -32,10 +32,12 @@ "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", + "multer": "^1.4.5-lts.1", "mysql2": "^3.10.1", "nodemon": "^3.1.3", "sequelize": "^6.37.3", "sequelize-cli": "^6.6.2", + "uuid": "^10.0.0", "vm-browserify": "^1.1.2", "vue": "^3.2.13", "vue-multiselect": "^3.0.0", diff --git a/public/images/uploads/44390f72-e407-4796-8cc7-a5253dae4ebd.jpg b/public/images/uploads/44390f72-e407-4796-8cc7-a5253dae4ebd.jpg new file mode 100644 index 0000000..0295635 Binary files /dev/null and b/public/images/uploads/44390f72-e407-4796-8cc7-a5253dae4ebd.jpg differ diff --git a/routes/image.js b/routes/image.js new file mode 100644 index 0000000..65b1df0 --- /dev/null +++ b/routes/image.js @@ -0,0 +1,12 @@ +const express = require('express'); +const router = express.Router(); +const { uploadImage, saveImageDetails, getImages, getImagesByPage, getImageById, updateImage } = require('../controllers/imageController'); +const authMiddleware = require('../middleware/authMiddleware') + +router.post('/', authMiddleware, uploadImage, saveImageDetails); +router.get('/', authMiddleware, getImages); +router.get('/page/:pageId', getImagesByPage); +router.get('/:id', getImageById); +router.put('/:id', authMiddleware, updateImage); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..3dcd57c --- /dev/null +++ b/routes/users.js @@ -0,0 +1,12 @@ +const express = require('express'); +const router = express.Router(); +const { getAllUsers, createUser, updateUser, deleteUser, getUserById } = require('../controllers/userController'); +const authMiddleware = require('../middleware/authMiddleware'); + +router.get('/', authMiddleware, getAllUsers); +router.get('/:id', authMiddleware, getUserById); +router.post('/', authMiddleware, createUser); +router.put('/:id', authMiddleware, updateUser); +router.delete('/:id', authMiddleware, deleteUser); + +module.exports = router; diff --git a/server.js b/server.js index 05676c4..1fbfd5f 100644 --- a/server.js +++ b/server.js @@ -12,6 +12,8 @@ const eventRouter = require('./routes/event'); const menuDataRouter = require('./routes/menuData'); const worshipRouter = require('./routes/worships'); const pageRoutes = require('./routes/pages'); +const userRoutes = require('./routes/users'); +const imageRoutes = require('./routes/image'); const app = express(); const PORT = 3000; @@ -29,7 +31,8 @@ app.use('/api/events', eventRouter); app.use('/api/menu-data', menuDataRouter); app.use('/api/worships', worshipRouter); app.use('/api/page-content', pageRoutes); - +app.use('/api/users', userRoutes); +app.use('/api/image', imageRoutes); sequelize.sync().then(() => { app.listen(PORT, () => { console.log(`Server läuft auf Port ${PORT}`); diff --git a/src/assets/icons/Bold_Italic_Underline.png b/src/assets/icons/Bold_Italic_Underline.png new file mode 100644 index 0000000..80adbbf Binary files /dev/null and b/src/assets/icons/Bold_Italic_Underline.png differ diff --git a/src/assets/icons/format_list_bulleted.png b/src/assets/icons/format_list_bulleted.png new file mode 100644 index 0000000..020466b Binary files /dev/null and b/src/assets/icons/format_list_bulleted.png differ diff --git a/src/assets/icons/format_list_numbered.png b/src/assets/icons/format_list_numbered.png new file mode 100644 index 0000000..54b663e Binary files /dev/null and b/src/assets/icons/format_list_numbered.png differ diff --git a/src/assets/icons/image.png b/src/assets/icons/image.png new file mode 100644 index 0000000..3b074a4 Binary files /dev/null and b/src/assets/icons/image.png differ diff --git a/src/assets/icons/strikethrough.png b/src/assets/icons/strikethrough.png new file mode 100644 index 0000000..1781e00 Binary files /dev/null and b/src/assets/icons/strikethrough.png differ diff --git a/src/assets/icons/table.png b/src/assets/icons/table.png new file mode 100644 index 0000000..d7ab2d2 Binary files /dev/null and b/src/assets/icons/table.png differ diff --git a/src/common/components/FooterComponent.vue b/src/common/components/FooterComponent.vue index 74107cb..53d4109 100644 --- a/src/common/components/FooterComponent.vue +++ b/src/common/components/FooterComponent.vue @@ -1,7 +1,7 @@