Fixed format of events

This commit is contained in:
Torsten Schulz
2024-06-23 17:32:45 +02:00
parent 692e989861
commit 8b89d8b800
26 changed files with 455 additions and 157 deletions

View File

@@ -21,7 +21,7 @@ const getAllEvents = async (req, res) => {
const filterEvents = async (req, res) => {
try {
const { id, 'event-places': eventPlaces, 'event-types': eventTypes, display } = req.query;
const request = req.body;
const where = {
[Op.or]: [
{
@@ -36,7 +36,7 @@ const filterEvents = async (req, res) => {
]
};
if (id === 'all') {
if (request.id === 'all') {
const events = await Event.findAll({
where,
include: [
@@ -49,7 +49,7 @@ const filterEvents = async (req, res) => {
return res.json({ events });
}
if (id === 'home') {
if (request.id === 'home') {
const events = await Event.findAll({
where: {
alsoOnHomepage: 1,
@@ -65,23 +65,23 @@ const filterEvents = async (req, res) => {
return res.json({ events });
}
if (!id && !eventPlaces && !eventTypes) {
return res.json({ events: [], eventPlaces: [], eventTypes: [], contactPersons: [] });
if (!request.id && !request.places && !request.types) {
return res.json({ events: [], places: [], types: [], contactPersons: [] });
}
if (id) {
where.id = id;
if (request.id) {
where.id = request.id;
}
if (eventPlaces) {
if (request.places && request.places.length > 0) {
where.event_place_id = {
[Op.in]: eventPlaces.split('|').map(id => parseInt(id))
[Op.in]: request.places.map(id => parseInt(id))
};
}
if (eventTypes) {
if (request.types && request.types.length > 0) {
where.eventTypeId = {
[Op.in]: eventTypes.split('|').map(id => parseInt(id))
[Op.in]: request.types.map(id => parseInt(id))
};
}
@@ -94,8 +94,7 @@ const filterEvents = async (req, res) => {
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
]
});
const displayFields = display ? display.split('|') : [];
const displayFields = request.display ? request.display : [];
const filteredEvents = events.map(event => {
const filteredEvent = { ...event.toJSON() };

View File

@@ -18,6 +18,28 @@ const getAllInstitutions = async (req, res) => {
}
};
const getInstitutionById = async (req, res) => {
try {
const { id } = req.params;
const institution = await Institution.findByPk(id, {
include: [
{
model: ContactPerson,
as: 'contactPersons',
through: { attributes: [] }
}
]
});
if (!institution) {
return res.status(404).json({ error: 'Institution not found' });
}
res.json(institution);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch institution' });
console.error(error);
}
};
const createInstitution = async (req, res) => {
try {
const { contactPersonIds, ...institutionData } = req.body;
@@ -70,6 +92,7 @@ const deleteInstitution = async (req, res) => {
module.exports = {
getAllInstitutions,
getInstitutionById,
createInstitution,
updateInstitution,
deleteInstitution

View File

@@ -49,24 +49,21 @@ exports.deleteWorship = async (req, res) => {
};
exports.getFilteredWorships = async (req, res) => {
const { location, orderBy } = req.query;
const { location, order } = req.query;
const where = {};
if (location && location !== '-1') {
if (location.includes('|')) {
const locationsArray = location.split('|');
const locations = JSON.parse(location);
if (location && locations.length > 0) {
where.eventPlaceId = {
[Sequelize.Op.in]: locationsArray
[Sequelize.Op.in]: locations
}
} else {
where.eventPlaceId = location;
}
}
where.date = {
[Op.gte]: new Date(), // Only include events from today onwards
};
console.log(where, order);
try {
const worships = await Worship.findAll({
where,
@@ -74,7 +71,7 @@ exports.getFilteredWorships = async (req, res) => {
model: EventPlace,
as: 'eventPlace',
},
order: [orderBy.split(' ')],
order: [order.split(' ')],
});
res.status(200).json(worships);
} catch (error) {

View File

@@ -26,7 +26,7 @@ module.exports = (sequelize) => {
pageId: {
type: DataTypes.UUID,
allowNull: true
}
},
}, {
tableName: 'images',
timestamps: false

View File

@@ -37,7 +37,11 @@ module.exports = (sequelize) => {
page_title: {
type: DataTypes.STRING,
allowNull: true
}
},
image: {
type: DataTypes.STRING,
allowNull: true,
},
}, {
tableName: 'menu_items',
timestamps: false

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

View File

@@ -7,6 +7,6 @@ router.get('/', authMiddleware, getAllEvents);
router.post('/', authMiddleware, createEvent);
router.put('/:id', authMiddleware, updateEvent);
router.delete('/:id', authMiddleware, deleteEvent);
router.get('/filter', filterEvents);
router.post('/filter', filterEvents);
module.exports = router;

View File

@@ -1,9 +1,10 @@
const express = require('express');
const router = express.Router();
const institutionController = require('../controllers/institutionController');
const authMiddleware = require('../middleware/authMiddleware')
const authMiddleware = require('../middleware/authMiddleware');
router.get('/', authMiddleware, institutionController.getAllInstitutions);
router.get('/', institutionController.getAllInstitutions);
router.get('/:id', institutionController.getInstitutionById); // Neuer Endpunkt
router.post('/', authMiddleware, institutionController.createInstitution);
router.put('/:id', authMiddleware, institutionController.updateInstitution);
router.delete('/:id', authMiddleware, institutionController.deleteInstitution);

View File

@@ -24,10 +24,12 @@ export default {
await this.loadMenuData();
this.$router.push({ path: '/' }); // Zurück zur Startseite oder eine andere Seite, um sicherzustellen, dass der Router neu geladen wird
const routes = this.$store.state.menuData.map(item => {
return {
path: item.link,
component: () => import(`../components/${item.component}.vue`)
};
if (item.component) {
return {
path: item.link,
component: () => import(`../components/${item.component}.vue`)
};
}
});
routes.forEach(route => router.addRoute(route)); // Neue Routen hinzufügen
}

View File

@@ -18,6 +18,11 @@
<multiselect id="types-select" v-model="selectedEventTypes" :options="eventTypes" :multiple="true"
label="caption" track-by="id" />
</div>
<div v-if="selectedTypes.some(type => type.id === 'position')">
<label for="contact-select">Wählen Sie eine Position:</label>
<multiselect id="contact-select" v-model="selectedPositions" :options="positions" :multiple="false"
label="caption" track-by="id" />
</div>
<div v-if="selectedTypes.some(type => type.id === 'specific')">
<label for="contact-select">Wählen Sie eine Kontaktperson:</label>
<multiselect id="contact-select" v-model="selectedContact" :options="contacts" :multiple="false"
@@ -66,9 +71,11 @@ export default {
const contacts = ref([]);
const eventTypes = ref([]);
const places = ref([]);
const positions = ref([]);
const selectedContact = ref(null);
const selectedTypes = ref([]);
const selectedEventTypes = ref([]);
const selectedPositions = ref([]);
const selectedPlaces = ref([]);
const displayStyle = ref('float');
@@ -86,6 +93,7 @@ export default {
{ id: 'specific', caption: 'Eine Person' },
{ id: 'places', caption: 'Für bestimmte Orte' },
{ id: 'types', caption: 'Für bestimmte Typen' },
{ id: 'position', caption: 'Für bestimmte Positionen'}
]);
const displayStyles = ref([
@@ -98,6 +106,7 @@ export default {
fetchContacts();
fetchEventTypes();
fetchPlaces();
fetchPositions();
};
const closeAddContactDialog = () => {
@@ -110,16 +119,18 @@ export default {
selectedContact.value = null;
selectedEventTypes.value = [];
selectedPlaces.value = [];
selectedPositions.value = [];
} else if (selectedTypes.value.some(type => type.id === 'specific')) {
selectedTypes.value = [{ id: 'specific', caption: 'Eine Person' }];
selectedEventTypes.value = [];
selectedPlaces.value = [];
selectedPositions.value = [];
} else if (selectedTypes.value.some(type => type.id === 'places')) {
selectedContact.value = null;
selectedEventTypes.value = [];
} else if (selectedTypes.value.some(type => type.id === 'types')) {
selectedContact.value = null;
selectedPlaces.value = [];
} else if (selectedPositions.value.some(type => type.id === 'position')) {
selectedContact.value = null;
}
};
@@ -132,8 +143,9 @@ export default {
} else if (selectedTypes.value.some(type => type.id === 'specific') && selectedContact.value) {
selection['id'] = selectedContact.value.id;
} else {
selection['types'] = selectedEventTypes.value.map((type) => type.id).join('|');
selection['places'] = selectedPlaces.value.map((place) => place.id).join('|');
selection['types'] = selectedEventTypes.value.map((type) => type.id);
selection['places'] = selectedPlaces.value.map((place) => place.id);
selection['positions'] = selectedPositions.value((postion) => postion.id);
}
const contact = {
selection: selection,
@@ -166,13 +178,21 @@ export default {
const fetchPlaces = async () => {
try {
const response = await axios.get('/event-places');
console.log(response);
places.value = response.data;
} catch (error) {
console.error('Fehler beim Laden der Orte:', error);
}
};
const fetchPositions = async () => {
try {
const response = await axios.get('/positions');
positions.value = response.data;
} catch (error) {
console.error('Fehler beim Laden der Positionen:', error)
}
}
return {
isOpen,
contacts,
@@ -190,6 +210,8 @@ export default {
onTypeSelect,
places,
eventTypes,
positions,
selectedPositions,
};
},
};

View File

@@ -50,7 +50,8 @@
},
confirm() {
if (this.selectedFile) {
this.$emit('confirm', this.selectedFile.hash);
console.log(this.selectedFile.hash);
this.$emit('confirm', { hash: this.selectedFile.hash });
this.closeDialog();
} else {
alert('Bitte wählen Sie eine Datei aus.');

View File

@@ -102,23 +102,21 @@ export default {
};
const confirmAddEventConfiguration = () => {
let configString = '';
const displayString = Object.keys(displayOptions.value)
.filter(key => displayOptions.value[key])
.join('|');
const event = {};
event.display = Object.keys(displayOptions.value)
.filter(key => displayOptions.value[key]);
if (isHomepage.value) {
configString = `{{ events:id=home,display=${displayString} }}`
event.id = "home";
} else if (selectedTypes.value.includes('Alle')) {
configString = `{{ events:id=all,display=${displayString} }}`;
event.id = "all"
} else if (selectedTypes.value.includes('Ein bestimmtes')) {
configString = `{{ events:id=${selectedEvent.value.id},display=${displayString} }}`;
event.id = selectedEvent.value.id;
} else {
const placesString = selectedPlaces.value.map(place => place.id).join('|');
const eventTypesString = selectedEventTypes.value.map(eventType => eventType.id).join('|');
configString = `{{ events:${placesString ? `event-places=${placesString},` : ''}${eventTypesString ? `event-types=${eventTypesString},` : ''}display=${displayString} }}`;
event.types = selectedEventTypes.value.map(eventType => eventType.id);
event.places = selectedPlaces.value.map(place => place.id);
}
emit('confirm', configString);
emit('confirm', '{{ events:' + JSON.stringify(event) + ' }}');
closeAddEventDialog();
};

View File

@@ -42,7 +42,6 @@ export default {
const confirmAddImageConfiguration = () => {
if (selectedImage.value) {
console.log('->', selectImage.value);
emit('confirm', `${selectedImage.value.id}`);
}
closeAddImageDialog();

View File

@@ -0,0 +1,154 @@
<template>
<div>
<div v-if="isOpen" class="dialog-overlay">
<div class="dialog-content">
<h3>Institution hinzufügen</h3>
<div>
<label for="institution-select">Wählen Sie eine Institution:</label>
<multiselect id="institution-select" v-model="selectedInstitution" :options="institutionOptions" :multiple="false" label="name" track-by="id" @select="onInstitutionSelect" />
</div>
<div>
<label>Wählen Sie welche Elemente angezeigt werden sollen:</label>
<div class="display-options">
<label><input type="checkbox" v-model="displayOptions.street" /> Straße</label>
<label><input type="checkbox" v-model="displayOptions.zipcode" /> Postleitzahl</label>
<label><input type="checkbox" v-model="displayOptions.city" /> Stadt</label>
<label><input type="checkbox" v-model="displayOptions.phone" /> Telefon</label>
<label><input type="checkbox" v-model="displayOptions.fax" /> Fax</label>
<label><input type="checkbox" v-model="displayOptions.email" /> E-Mail</label>
</div>
<div>
<label for="displayStyle">Anzeigen als</label>
<select id="displayStyle" v-model="displayStyle">
<option v-for="style in displayStyles" :value="style.id" :key="style.id">{{ style.label }}</option>
</select>
</div>
</div>
<div>
<button @click="confirmAddInstitutionConfiguration">Bestätigen</button>
<button @click="closeAddInstitutionDialog">Schließen</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
import axios from '@/axios';
import Multiselect from 'vue-multiselect';
export default {
name: 'AddInstitutionDialog',
components: {
Multiselect,
},
emits: ['confirm'],
setup(props, { emit }) {
const isOpen = ref(false);
const institutions = ref([]);
const selectedInstitution = ref(null);
const displayStyle = ref('float');
const displayOptions = ref({
street: false,
zipcode: false,
city: false,
phone: false,
fax: false,
email: false,
});
const institutionOptions = ref([
{ id: 'all', name: 'Alle' },
...institutions.value,
]);
const displayStyles = ref([
{ id: 'float', label: 'Durchlaufender Text' },
{ id: 'box', label: 'Textbox' },
]);
const openAddInstitutionDialog = () => {
isOpen.value = true;
fetchInstitutions();
};
const closeAddInstitutionDialog = () => {
isOpen.value = false;
};
const onInstitutionSelect = () => {
if (selectedInstitution.value && selectedInstitution.value.id === 'all') {
institutionOptions.value = [{ id: 'all', name: 'Alle' }];
selectedInstitution.value = { id: 'all', name: 'Alle' };
}
};
const confirmAddInstitutionConfiguration = () => {
const displayArray = Object.keys(displayOptions.value).filter((key) => displayOptions.value[key]);
const institutionConfig = {
id: selectedInstitution.value.id,
display: displayArray,
style: displayStyle.value
};
const configString = `{{ institution:${JSON.stringify(institutionConfig)} }}`;
emit('confirm', configString);
closeAddInstitutionDialog();
};
const fetchInstitutions = async () => {
try {
const response = await axios.get('/institutions');
institutions.value = response.data;
institutionOptions.value = [{ id: 'all', name: 'Alle' }, ...institutions.value];
} catch (error) {
console.error('Fehler beim Laden der Institutionen:', error);
}
};
return {
isOpen,
institutions,
selectedInstitution,
displayOptions,
displayStyle,
displayStyles,
institutionOptions,
openAddInstitutionDialog,
closeAddInstitutionDialog,
confirmAddInstitutionConfiguration,
onInstitutionSelect,
};
},
};
</script>
<style scoped>
.dialog-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.dialog-content {
background: white;
padding: 20px;
border-radius: 8px;
}
.multiselect {
width: 100%;
}
.display-options label {
display: block;
}
</style>

View File

@@ -46,15 +46,11 @@ export default {
},
async created() {
try {
console.log('Initial config:', JSON.stringify(this.config));
this.displayOptions = this.config.display || [];
console.log('Display options:', this.displayOptions);
const response = await axios.post('/contact-persons/filter', {
config: JSON.stringify(this.config),
});
this.contacts = response.data;
console.log('Fetched contacts:', JSON.stringify(this.contacts));
console.log('Config style:', this.config.style);
this.loading = false;
} catch (error) {
console.error('Error loading contacts:', error);

View File

@@ -1,5 +1,5 @@
<template>
<span @click="downloadFile">{{ title }}</span>
<span v-if="title" @click="downloadFile">{{ title }}</span>
</template>
<script>
@@ -8,20 +8,33 @@ import axios from 'axios';
export default {
name: 'DownloadLink',
props: {
title: {
type: String,
required: true,
},
hash: {
type: String,
required: true,
},
extension: {
type: String,
required: true,
},
},
data() {
return {
title: '',
link: '',
};
},
async created() {
await this.fetchFile();
},
methods: {
async fetchFile() {
try {
console.log(this.hash);
const response = await axios.get('/files/hash/' + this.hash);
this.title = response.data.title;
console.log('Fetched files:', response.data.events);
this.events = response.data.events;
} catch (error) {
console.error('Fehler beim Abrufen der Events', error);
}
},
async downloadFile() {
const response = await axios.get(`/files/download/${this.hash}`, {
responseType: 'blob'

View File

@@ -49,19 +49,18 @@ export default {
},
methods: {
async fetchEvents() {
console.log(this.config);
try {
const response = await axios.get('/events/filter', {
params: this.config
});
console.log('Fetched events:', response.data.events);
const response = await axios.post('/events/filter',
this.config
);
this.events = response.data.events;
} catch (error) {
console.error('Fehler beim Abrufen der Events', error);
}
},
shouldDisplay(field) {
const displayFields = this.config.display.split('|');
return displayFields.includes(field);
return this.config.display.includes(field);
},
formatDateOrDay(date, dayOfWeek) {
if (date) {

View File

@@ -0,0 +1,64 @@
<template>
<div v-if="config && config.style === 'box' && institution">
<h3>{{ institution.name }}</h3>
<span v-if="displayOptions.includes('street')">Straße: {{ institution.street }}<br></span>
<span v-if="displayOptions.includes('zipcode')">Postleitzahl: {{ institution.zipcode }}<br></span>
<span v-if="displayOptions.includes('city')">Stadt: {{ institution.city }}<br></span>
<span v-if="displayOptions.includes('email')">E-Mail: {{ institution.email }}<br></span>
<span v-if="displayOptions.includes('phone')">Telefon: {{ institution.phone }}<br></span>
</div>
<span v-else-if="config.style === 'float' && institution">
{{ institution.name }}
<span v-if="displayOptions.includes('street')">, Straße: {{ institution.street }}</span>
<span v-if="displayOptions.includes('zipcode')">, Postleitzahl: {{ institution.zipcode }}</span>
<span v-if="displayOptions.includes('city')">, Stadt: {{ institution.city }}</span>
<span v-if="displayOptions.includes('email')">, E-Mail: {{ institution.email }}</span>
<span v-if="displayOptions.includes('phone')">, Telefon: {{ institution.phone }}</span>
</span>
<span v-else>
{{ config }}<br/>
---
{{ institution }}
</span>
</template>
<script>
import axios from '@/axios';
export default {
name: 'InstitutionRender',
props: {
config: {
type: Object,
required: true,
},
},
data() {
return {
institution: null,
loading: true,
error: null,
displayOptions: [],
};
},
async created() {
try {
this.displayOptions = this.config.display || [];
const response = await axios.get('/institutions/' + this.config.id, {
config: JSON.stringify(this.config),
});
this.institution = response.data;
this.loading = false;
} catch (error) {
console.error('Error loading institutions:', error);
this.error = 'Fehler beim Laden der Institutionen';
this.loading = false;
}
},
};
</script>
<style scoped>
/* Add styles if needed */
</style>

View File

@@ -7,7 +7,9 @@ import { createApp, h, ref, watch } from 'vue';
import WorshipRender from './WorshipRender.vue';
import ImageRender from './ImageRender.vue';
import EventRender from './EventRender.vue';
import ContactRender from './ContactRender.vue'; // Neue Komponente importieren
import ContactRender from './ContactRender.vue'; // Importiere die neue Komponente
import InstitutionRender from './InstitutionRender.vue'; // Importiere die neue Komponente
import DownloadLink from './DownloadLink.vue';
export default {
name: 'RenderContentComponent',
@@ -23,8 +25,10 @@ export default {
const renderContent = (content) => {
let result = renderWorship(content);
result = renderImage(result);
result = renderDownload(result);
result = renderEvent(result);
result = renderContact(result); // Neuer Filter
result = renderContact(result);
result = renderInstitution(result);
return result;
};
@@ -32,14 +36,13 @@ export default {
const worshipsPattern = /{{ worshipslist:(.*?) }}/g;
let result = content;
result = result.replace(worshipsPattern, (match, config) => {
const props = parseConfig(config);
const placeholderId = `worship-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
if (placeholder) {
const app = createApp({
const app = createApp({
render() {
return h(WorshipRender, props);
return h(WorshipRender, {config: JSON.parse(config) });
},
});
app.mount(placeholder);
@@ -71,18 +74,39 @@ export default {
return result;
};
const renderDownload = (content) => {
const downloadPattern = /{{ download:(.*?) }}/g;
let result = content;
result = result.replace(downloadPattern, (match, config) => {
const placeholderId = `image-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
if (placeholder) {
const app = createApp({
render() {
return h(DownloadLink, { hash: config });
},
});
app.mount(placeholder);
}
}, 0);
return `<span id="${placeholderId}"></span>`;
});
return result;
};
const renderEvent = (content) => {
const eventsPattern = /{{ events:(.*?) }}/g;
let result = content;
result = result.replace(eventsPattern, (match, config) => {
const props = parseConfig(config);
const placeholderId = `event-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
if (placeholder) {
const app = createApp({
render() {
return h(EventRender, { id: props.id, config: props });
console.log('RC', config)
return h(EventRender, {config: JSON.parse(config) });
},
});
app.mount(placeholder);
@@ -97,7 +121,7 @@ export default {
const contactPattern = /{{ contact:(.*?) }}/g;
let result = content;
result = result.replace(contactPattern, (match, config) => {
const props = JSON.parse(config);
const props = parseConfig(config);
const placeholderId = `contact-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
@@ -110,22 +134,42 @@ export default {
app.mount(placeholder);
}
}, 0);
const tag = props.style === 'box' ? 'div' : 'span'
return `<${tag} id="${placeholderId}"></${tag}>`;
return `<div id="${placeholderId}"></div>`;
});
return result;
};
const renderInstitution = (content) => {
const institutionPattern = /{{ institution:(.*?) }}/g;
let result = content;
result = result.replace(institutionPattern, (match, config) => {
const props = parseConfig(config);
const placeholderId = `institution-render-placeholder-${Math.random().toString(36).substr(2, 9)}`;
setTimeout(() => {
const placeholder = document.getElementById(placeholderId);
if (placeholder) {
const app = createApp({
render() {
return h(InstitutionRender, { config: props });
},
});
app.mount(placeholder);
}
}, 0);
return `<div id="${placeholderId}"></div>`;
});
return result;
};
const parseConfig = (configString) => {
const config = {};
const configArray = configString.split(',');
configArray.forEach((item) => {
const [key, value] = item.split('=');
if (key && value !== undefined) {
config[key.trim()] = isNaN(value) ? value.trim() : Number(value);
}
});
return config;
try {
const config = JSON.parse(configString);
return config;
} catch (error) {
console.error('Error parsing config:', error);
console.log(configString);
return {};
}
};
watch(

View File

@@ -66,7 +66,7 @@ export default {
};
const confirmWorshipConfiguration = () => {
const selectedLocationIds = selectedLocations.value.map(location => location.id).join('|');
const selectedLocationIds = JSON.stringify(selectedLocations.value.map(location => location.id));
emit('confirm', selectedLocationIds);
closeWorshipDialog();
};

View File

@@ -32,14 +32,10 @@ import { formatTime, formatDate } from '@/utils/strings';
export default {
name: 'WorshipRender',
props: {
location: {
type: Number,
config: {
type: Object,
required: true
},
orderBy: {
type: String,
default: 'date ASC'
}
},
data() {
return {
@@ -55,10 +51,7 @@ export default {
async fetchWorships() {
try {
const response = await axios.get('/worships/filtered', {
params: {
location: this.location,
orderBy: this.orderBy
}
params: this.config
});
this.worships = response.data;
} catch (error) {

View File

@@ -5,7 +5,7 @@
</template>
<script>
import { menuData } from '../../config/menuData';
import { mapState } from 'vuex';
export default {
name: 'ImageContent',
@@ -15,6 +15,9 @@ export default {
currentImage: '/images/homepage1.png'
};
},
computed: {
...mapState(['menuData']),
},
watch: {
$route: {
immediate: true,
@@ -26,6 +29,7 @@ export default {
methods: {
updateImage() {
const routePath = this.$route.path;
const menuData = this.menuData;
const menuItem = this.findMenuItemByPath(menuData, routePath);
if (menuItem && menuItem.image) {
this.currentImage = `/images/${menuItem.image}`;

View File

@@ -77,7 +77,7 @@
<div class="additional-toolbar">
<button @click="openAddEventsDialog">Events</button>
<button @click="openAddContactDialog">Kontaktpersonen</button>
<button>Institutionen</button>
<button @click="openAddInstitutionDialog">Institutionen</button>
<button @click="openWorshipDialog">Gottesdienste</button>
</div>
<div :class="['htmleditor']">
@@ -90,7 +90,7 @@
<AddEventDialog ref="addEventDialog" @confirm="insertEvent" />
<AddLinkDialog ref="addLinkDialog" @confirm="insertLink" />
<AddDownloadDialog ref="addDownloadDialog" @confirm="insertDownload" />
<AddContactDialog ref="addContactDialog" @confirm="insertContact" />
<AddInstitutionDialog ref="addInstitutionDialog" @confirm="insertInstitution" />
<input type="color" ref="colorPicker" @input="setColor" style="display: none;" />
</div>
</template>
@@ -119,8 +119,7 @@ import AddImageDialog from '@/components/AddImageDialog.vue';
import AddEventDialog from '@/components/AddEventDialog.vue';
import AddLinkDialog from '@/components/AddLinkDialog.vue';
import AddDownloadDialog from '@/components/AddDownloadDialog.vue';
import AddContactDialog from '@/components/AddContactDialog.vue';
import AddInstitutionDialog from '@/components/AddInstitutionDialog.vue';
import { BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, ListIcon, NumberedListLeftIcon, TableIcon,
Table2ColumnsIcon, ArrowDownIcon, ArrowRightIcon, TableRowsIcon, AlignTopBoxIcon, AlignLeftBoxIcon, StatsReportIcon,
OpenInWindowIcon, DownloadIcon
@@ -149,7 +148,7 @@ export default {
AddEventDialog,
AddLinkDialog,
AddDownloadDialog,
AddContactDialog,
AddInstitutionDialog,
OpenInWindowIcon,
DownloadIcon,
},
@@ -163,7 +162,7 @@ export default {
const addEventDialog = ref(null);
const addLinkDialog = ref(null);
const addDownloadDialog = ref(null);
const addContactDialog = ref(null);
const addInstitutionDialog = ref(null);
const colorPicker = ref(null);
const editor = useEditor({
@@ -280,8 +279,11 @@ export default {
const insertWorshipList = (selectedLocations) => {
if (editor.value) {
const configuration = `location=${selectedLocations},order:"date asc"`;
editor.value.chain().focus().insertContent(`{{ worshipslist:${configuration} }}`).run();
const configuration = {
location: selectedLocations,
order: "date asc",
}
editor.value.chain().focus().insertContent('{{ worshipslist:' + JSON.stringify(configuration) + ' }}').run();
}
};
@@ -315,18 +317,18 @@ export default {
addDownloadDialog.value.openAddDownloadDialog();
};
const insertDownload = ({ title, hash, extension }) => {
if (title && hash && extension && editor.value) {
const url = `/files/download/${hash}`;
editor.value.chain().focus().extendMarkRange('link').setLink({ href: url }).insertContent(title).run();
const insertDownload = ({ hash }) => {
if (hash && editor.value) {
const downloadString = '{{ download:' + hash + ' }}'
editor.value.chain().focus().insertContent(downloadString).run();
}
};
const openAddContactDialog = () => {
addContactDialog.value.openAddContactDialog();
const openAddInstitutionDialog = () => {
addInstitutionDialog.value.openAddInstitutionDialog();
};
const insertContact = (configString) => {
const insertInstitution = (configString) => {
if (editor.value) {
editor.value.chain().focus().insertContent(configString).run();
}
@@ -375,38 +377,6 @@ export default {
editor.value.chain().focus().toggleOrderedList().run();
};
const addColumnBefore = () => {
editor.value.chain().focus().addColumnBefore().run();
};
const addColumnAfter = () => {
editor.value.chain().focus().addColumnAfter().run();
};
const addRowBefore = () => {
editor.value.chain().focus().addRowBefore().run();
};
const addRowAfter = () => {
editor.value.chain().focus().addRowAfter().run();
};
const deleteColumn = () => {
editor.value.chain().focus().deleteColumn().run();
};
const deleteRow = () => {
editor.value.chain().focus().deleteRow().run();
};
const toggleHeaderColumn = () => {
editor.value.chain().focus().toggleHeaderColumn().run();
};
const toggleHeaderRow = () => {
editor.value.chain().focus().toggleHeaderRow().run();
};
return {
pages,
sortedPages,
@@ -430,9 +400,9 @@ export default {
addDownloadDialog,
openAddDownloadDialog,
insertDownload,
addContactDialog,
openAddContactDialog,
insertContact,
addInstitutionDialog,
openAddInstitutionDialog,
insertInstitution,
colorPicker,
openColorPicker,
setColor,
@@ -444,14 +414,6 @@ export default {
insertTable,
toggleBulletList,
toggleOrderedList,
addColumnBefore,
addColumnAfter,
addRowBefore,
addRowAfter,
deleteColumn,
deleteRow,
toggleHeaderColumn,
toggleHeaderRow,
};
},
};

View File

@@ -0,0 +1,11 @@
<template>
<div>
<h2>Kindergottesdiest</h2>
</div>
</template>
<script>
export default {
name: 'ChildrensWorshipContent',
};
</script>

View File

@@ -0,0 +1,11 @@
<template>
<div>
<h2>Flötenkinder</h2>
</div>
</template>
<script>
export default {
name: 'FlootChildrenContent',
};
</script>

View File

@@ -35,6 +35,7 @@ function buildMenuStructure(menuItems) {
requiresAuth: item.requires_auth,
order_id: item.order_id,
pageTitle: item.page_title,
image: item.image,
submenu: []
};
});