From 48a54ecdbb11c00cf730985b847e0840c5ad1353 Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Mon, 17 Jun 2024 13:36:15 +0200 Subject: [PATCH] Added Worship page rendering --- controllers/worshipController.js | 32 +- .../20240617095455-add-day-name-to-worship.js | 16 + models/MenuItem.js | 2 +- models/Worship.js | 5 + package-lock.json | 10 + package.json | 1 + routes/worships.js | 5 +- src/components/ContentComponent.vue | 115 ++-- src/components/RenderContentComponent.vue | 74 +++ src/components/WorshipRender.vue | 94 +++ src/content/admin/AdminMenuManagement.vue | 207 ------- src/content/admin/EditPagesComponent.vue | 16 +- src/content/admin/MenuManagement.vue | 546 +++++++++--------- src/content/admin/PagePreviewComponent.vue | 41 +- src/content/admin/WorshipManagement.vue | 3 + src/store/index.js | 18 +- src/utils/render.js | 15 - 17 files changed, 637 insertions(+), 563 deletions(-) create mode 100644 migrations/20240617095455-add-day-name-to-worship.js create mode 100644 src/components/RenderContentComponent.vue create mode 100644 src/components/WorshipRender.vue delete mode 100644 src/content/admin/AdminMenuManagement.vue delete mode 100644 src/utils/render.js diff --git a/controllers/worshipController.js b/controllers/worshipController.js index b112c35..d11c950 100644 --- a/controllers/worshipController.js +++ b/controllers/worshipController.js @@ -1,4 +1,5 @@ -const { Worship } = require('../models'); +const { Worship, EventPlace } = require('../models'); +const { Op } = require('sequelize'); // Importieren Sie die Operatoren von Sequelize exports.getAllWorships = async (req, res) => { try { @@ -14,6 +15,7 @@ exports.createWorship = async (req, res) => { const worship = await Worship.create(req.body); res.status(201).json(worship); } catch (error) { + console.log(error); res.status(500).json({ message: 'Fehler beim Erstellen des Gottesdienstes' }); } }; @@ -45,3 +47,31 @@ exports.deleteWorship = async (req, res) => { res.status(500).json({ message: 'Fehler beim Löschen des Gottesdienstes' }); } }; + +exports.getFilteredWorships = async (req, res) => { + const { location, orderBy } = req.query; + const where = {}; + + if (location && location !== '-1') { + where.eventPlaceId = location; + } + + where.date = { + [Op.gte]: new Date(), // Only include events from today onwards + }; + + try { + const worships = await Worship.findAll({ + where, + include: { + model: EventPlace, + as: 'eventPlace', + }, + order: [orderBy.split(' ')], + }); + res.status(200).json(worships); + } catch (error) { + console.log(error); + res.status(500).json({ message: 'Fehler beim Abrufen der gefilterten Gottesdienste' }); + } +}; diff --git a/migrations/20240617095455-add-day-name-to-worship.js b/migrations/20240617095455-add-day-name-to-worship.js new file mode 100644 index 0000000..3929961 --- /dev/null +++ b/migrations/20240617095455-add-day-name-to-worship.js @@ -0,0 +1,16 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + up: async (queryInterface, Sequelize) => { + await queryInterface.addColumn('worships', 'day_name', { + type: Sequelize.STRING, + allowNull: false, + default: '' + }); + }, + + down: async (queryInterface, Sequelize) => { + await queryInterface.removeColumn('worships', 'day_name'); + } +}; diff --git a/models/MenuItem.js b/models/MenuItem.js index 4ad1f33..cb53fbb 100644 --- a/models/MenuItem.js +++ b/models/MenuItem.js @@ -34,7 +34,7 @@ module.exports = (sequelize) => { allowNull: false, defaultValue: 0 }, - page_title: { // Neuer Eintrag + page_title: { type: DataTypes.STRING, allowNull: true } diff --git a/models/Worship.js b/models/Worship.js index e387884..c5cd682 100644 --- a/models/Worship.js +++ b/models/Worship.js @@ -50,6 +50,11 @@ module.exports = (sequelize) => { introLine: { type: DataTypes.STRING, allowNull: true + }, + dayName: { + type: DataTypes.STRING, + defaultValue: '', + allowNull: false } }, { tableName: 'worships', diff --git a/package-lock.json b/package-lock.json index 546fed4..cac17e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "core-js": "^3.8.3", "cors": "^2.8.5", "crypto": "^1.0.1", + "date-fns": "^3.6.0", "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", @@ -5708,6 +5709,15 @@ "node": ">=0.12" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", diff --git a/package.json b/package.json index 551ae97..e5f95d5 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "core-js": "^3.8.3", "cors": "^2.8.5", "crypto": "^1.0.1", + "date-fns": "^3.6.0", "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", diff --git a/routes/worships.js b/routes/worships.js index e39ea8f..b53dc6d 100644 --- a/routes/worships.js +++ b/routes/worships.js @@ -1,11 +1,12 @@ const express = require('express'); const router = express.Router(); -const { getAllWorships, createWorship, updateWorship, deleteWorship } = require('../controllers/worshipController'); +const { getAllWorships, createWorship, updateWorship, deleteWorship, getFilteredWorships } = require('../controllers/worshipController'); const authMiddleware = require('../middleware/authMiddleware'); -router.get('/', authMiddleware, getAllWorships); +router.get('/', getAllWorships); router.post('/', authMiddleware, createWorship); router.put('/:id', authMiddleware, updateWorship); router.delete('/:id', authMiddleware, deleteWorship); +router.get('/filtered', getFilteredWorships); module.exports = router; diff --git a/src/components/ContentComponent.vue b/src/components/ContentComponent.vue index e3ea700..6f45833 100644 --- a/src/components/ContentComponent.vue +++ b/src/components/ContentComponent.vue @@ -1,73 +1,74 @@ - - - - + }; + + + + \ No newline at end of file diff --git a/src/components/RenderContentComponent.vue b/src/components/RenderContentComponent.vue new file mode 100644 index 0000000..3124042 --- /dev/null +++ b/src/components/RenderContentComponent.vue @@ -0,0 +1,74 @@ + + + + + + \ No newline at end of file diff --git a/src/components/WorshipRender.vue b/src/components/WorshipRender.vue new file mode 100644 index 0000000..3cd8708 --- /dev/null +++ b/src/components/WorshipRender.vue @@ -0,0 +1,94 @@ + + + + + \ No newline at end of file diff --git a/src/content/admin/AdminMenuManagement.vue b/src/content/admin/AdminMenuManagement.vue deleted file mode 100644 index 49ea0f5..0000000 --- a/src/content/admin/AdminMenuManagement.vue +++ /dev/null @@ -1,207 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/content/admin/EditPagesComponent.vue b/src/content/admin/EditPagesComponent.vue index b7e3b2d..fe2f0c3 100644 --- a/src/content/admin/EditPagesComponent.vue +++ b/src/content/admin/EditPagesComponent.vue @@ -46,7 +46,7 @@ - - - \ No newline at end of file + + const saveMenuData = async () => { + try { + const flatMenuData = flattenMenuData(menuData.value); + await axios.post('/menu-data', flatMenuData); + alert('Menü-Daten erfolgreich gespeichert'); + } catch (error) { + console.error('Fehler beim Speichern der Menü-Daten:', error); + } + }; + + const flattenMenuData = (data, parentId = null) => { + return data.reduce((acc, item) => { + const newItem = { ...item, parent_id: parentId, page_title: item.pageTitle }; + const { submenu, ...rest } = newItem; + acc.push(rest); + if (submenu && submenu.length) { + acc.push(...flattenMenuData(submenu, newItem.id)); + } + return acc; + }, []); + }; + + const addMenuItem = () => { + const newItem = { + name: '', + link: '', + component: '', + pageTitle: '', + showInMenu: true, + requiresAuth: false, + orderId: 0, + submenu: [], + parent_id: null, + }; + menuData.value.push(newItem); + selectMenuItem(newItem); + }; + + const addSubmenu = (menuItem) => { + const newSubItem = { + name: '', + link: '', + component: '', + pageTitle: '', + showInMenu: true, + requiresAuth: false, + orderId: 0, + parent_id: menuItem.id, + }; + menuItem.submenu.push(newSubItem); + selectMenuItem(newSubItem); + }; + + const removeMenuItem = (menuItem) => { + const index = menuData.value.indexOf(menuItem); + if (index > -1) { + menuData.value.splice(index, 1); + } + selectedMenuItem.value = null; + }; + + const removeSubmenu = (menuItem, submenuItem) => { + const index = menuItem.submenu.indexOf(submenuItem); + if (index > -1) { + menuItem.submenu.splice(index, 1); + } + selectedMenuItem.value = null; + }; + + const selectMenuItem = (menuItem) => { + selectedMenuItem.value = menuItem; + }; + + const sortedMenuData = computed(() => { + return [...menuData.value].sort((a, b) => a.orderId - b.orderId); + }); + + const sortedSubmenu = (menuItem) => { + return menuItem.submenu.slice().sort((a, b) => a.orderId - b.orderId); + }; + + const getIndentedName = (item) => { + return ' '.repeat(item.indent * 2) + item.name; + }; + + onMounted(fetchMenuData); + + return { + menuData, + sortedMenuData, + sortedSubmenu, + selectedMenuItem, + fetchMenuData, + saveMenuData, + addMenuItem, + addSubmenu, + removeMenuItem, + removeSubmenu, + selectMenuItem, + getIndentedName, + }; + }, +}; + + + \ No newline at end of file diff --git a/src/content/admin/PagePreviewComponent.vue b/src/content/admin/PagePreviewComponent.vue index 59677d2..08dd3dc 100644 --- a/src/content/admin/PagePreviewComponent.vue +++ b/src/content/admin/PagePreviewComponent.vue @@ -1,26 +1,55 @@ diff --git a/src/content/admin/WorshipManagement.vue b/src/content/admin/WorshipManagement.vue index 370fd7e..7bbdd3b 100644 --- a/src/content/admin/WorshipManagement.vue +++ b/src/content/admin/WorshipManagement.vue @@ -9,6 +9,9 @@ + + + diff --git a/src/store/index.js b/src/store/index.js index dc3f85d..0921467 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,6 +1,6 @@ import { createStore } from 'vuex'; import axios from 'axios'; -import router from '../router'; // Importieren des Routers +import router from '../router'; let user = []; try { @@ -16,6 +16,8 @@ export default createStore({ token: localStorage.getItem('token') || '', menuData: [], pageContent: '', + pageTitle: '', + selectedPage: '', }, mutations: { setLogin(state, { user, token }) { @@ -44,6 +46,12 @@ export default createStore({ UPDATE_PAGE_CONTENT(state, content) { state.pageContent = content; }, + setPageTitle(state, title) { + state.pageTitle = title; + }, + setSelectedPage(state, page) { + state.selectedPage = page; + }, }, actions: { async loadMenuData({ commit }) { @@ -77,6 +85,12 @@ export default createStore({ console.error('Fehler beim Speichern des Seiteninhalts:', error); } }, + setPageTitle({ commit }, title) { + commit('setPageTitle', title); + }, + setSelectedPage({ commit }, page) { + commit('setSelectedPage', page); + }, login({ commit }, { user, token }) { commit('setLogin', { user, token }); }, @@ -89,5 +103,7 @@ export default createStore({ user: state => state.user, menuData: state => state.menuData, pageContent: state => state.pageContent, + pageTitle: state => state.pageTitle, + selectedPage: state => state.selectedPage, } }); diff --git a/src/utils/render.js b/src/utils/render.js deleted file mode 100644 index b343785..0000000 --- a/src/utils/render.js +++ /dev/null @@ -1,15 +0,0 @@ -export function render(content) { - console.log('do render', content); - const worshipsPattern = /{{ worshipslist:(.*?) }}/g; - const renderedContent = content.replace(worshipsPattern, (match, config) => { - return renderWorships(config); - }); - - return renderedContent; - } - - function renderWorships(config) { - console.log('render worships', config); - return `
Worships at location ${location}
`; - } - \ No newline at end of file