Compare commits

..

47 Commits

Author SHA1 Message Date
Torsten Schulz (local)
a382a07765 Enhance NavbarComponent functionality: Add click outside detection to close the menu and improve responsiveness by adjusting styles for mobile view, ensuring better user experience and accessibility.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-30 11:08:29 +02:00
Torsten Schulz (local)
ef1225c02d Refactor organizer color assignment in exportWorships function: Update the logic to dynamically set the organizer color based on the worship format, improving visual consistency in exported documents.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-30 10:52:41 +02:00
Torsten Schulz (local)
1ab5ceaac7 Update worship export colors in worshipController.js: Introduce dynamic color assignment for title, organizer, service, and organ text based on the worship format and neighbor invitation status, enhancing visual differentiation in exported documents.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-30 10:50:03 +02:00
Torsten Schulz (local)
2fd5dc0389 Update worship export logic to conditionally include internal service information: Modify exportWorships function in worshipController.js to check format before including sacristan service and organ playing details, enhancing export customization based on the output type.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-30 10:44:04 +02:00
Torsten Schulz (local)
2377caea6d Enhance worship export functionality: Add support for sacristan service and organ playing details in worshipController.js, improving the export format. Update filename generation logic in WorshipManagement.vue to handle potential server-side filename issues, ensuring accurate file naming during downloads.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-30 10:41:44 +02:00
Torsten Schulz (local)
ae0bf3d478 Add organ playing input field in WorshipManagement.vue: Introduce a new text input for organist details in the worship data form, enhancing the information captured during worship management.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-30 10:26:33 +02:00
Torsten Schulz (local)
181257ad26 Implement date filtering for worship imports in WorshipManagement.vue: Add date range filter inputs, enhance worship list display with filtered results, and improve data handling for imported worships, ensuring better user experience during worship management.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-30 09:32:56 +02:00
Torsten Schulz (local)
22f882d9d2 Implement worship organizer selection with multiselect component in WorshipManagement.vue: Replace text input with a multiselect for better user experience, add fetching logic for worship leaders, and enhance organizer handling with tagging support.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 19:55:33 +02:00
Torsten Schulz (local)
aeaf747445 Enhance worship import functionality: Add neighbor invitation and self-information fields in worshipController.js and WorshipManagement.vue. Implement logic to automatically set self-information based on neighbor invitation status, improving user experience and data handling during worship imports.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 19:49:45 +02:00
Torsten Schulz (local)
7835c2da1a Refactor resolveEventPlaceIdFromHeader in worshipController.js: Enhance location matching logic by introducing a scoring system for place names, improving accuracy in event place identification, and updating fallback mechanisms for known locations.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 19:24:34 +02:00
Torsten Schulz (local)
9626fc90cc Refactor buildWorshipTitleFromPlace in worshipController.js: Rename variables for clarity, enhance location normalization, and improve title generation logic to better handle church names and avoid incorrect titles, ensuring more accurate worship service descriptions.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 19:19:35 +02:00
Torsten Schulz (local)
dbb07ad0c3 Enhance worshipController.js with improved leader mapping and text resolution: Introduce matchEntries for better leader identification, refactor parseNbrSegment to utilize new leaderMaps structure, and add buildWorshipTitleFromPlace for dynamic title generation based on event place names, improving data parsing and clarity in worship planning.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 19:09:54 +02:00
Torsten Schulz (local)
afa9b4a6b5 Refactor text normalization in worshipController.js: Rename normalizeText to normalizeForMatch for clarity and update all references to ensure consistent text processing across various functions, enhancing code readability and maintainability.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 19:04:56 +02:00
Torsten Schulz (local)
1182426cda Refactor router navigation handling: Update beforeEach hook in router.js to prevent incorrect route matching on initial load. Ensure proper path normalization and query handling to enhance navigation reliability.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 18:58:50 +02:00
Torsten Schulz (local)
654ca22439 Improve token management in axios.js and store/index.js: Ensure headers are initialized correctly and enhance error handling for 401 responses by checking for stored tokens. Update isLoggedIn state logic to rely solely on token usability, improving authentication reliability.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 18:56:23 +02:00
Torsten Schulz (local)
0b58579258 Refactor authentication and token management: Update authController.js to use environment variable for JWT expiration. Enhance axios.js and store/index.js for improved token usability checks and cleanup on logout, ensuring a more robust authentication flow.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 18:52:16 +02:00
Torsten Schulz (local)
7d5e2526d3 Update worshipController.js to enhance worship data parsing and conflict resolution. Introduce unparsedText for better tracking of source data. Modify date handling functions for improved accuracy in event filtering. Update .gitignore to exclude generated frontend artifacts, including index.html and assets directory, to streamline deployment.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 18:47:15 +02:00
Torsten Schulz (local)
05a8229b83 Enhance deployment process: Add cleanup steps for frontend artifacts in deploy.sh to ensure a clean build environment. Update axios.js to improve token handling and response error management, ensuring proper logout flow. Update index.html with new asset references for improved caching.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 18:36:55 +02:00
Torsten Schulz (local)
7156cc141a Update asset references in index.html: Change script and stylesheet links to new hashed filenames for improved caching and performance.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 18:32:22 +02:00
Torsten Schulz (local)
ddf05bd0e0 Enhance worship import functionality: Add support for importing .xlsx files in worship management, updating UI to reflect new file type acceptance. Introduce new parsing logic for NBR planning records and update relevant routes and controllers to handle the new import process.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 18:27:58 +02:00
Torsten Schulz (local)
7f01c004c8 Add worship leaders functionality: Introduce worship leaders management by adding routes, controllers, and CSV import capabilities. Update worship management UI to support .csv file uploads for worship services, enhancing data handling and user experience.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 18:04:05 +02:00
Torsten Schulz (local)
a2b1ebdb97 Enhance event date normalization: Introduce a helper function to standardize date formats for the event form, ensuring consistent input handling. Update event data initialization to utilize this function, improving data integrity and user experience.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 16:16:16 +02:00
Torsten Schulz (local)
8bd5da35a9 Refactor event form handling: Normalize event data for form submission by extracting day of the week value and improving date mode determination logic. Introduce helper methods for better data management and clarity.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 16:12:58 +02:00
Torsten Schulz (local)
eb6f1e19a4 Refactor event date comparison: Update buildUpcomingWhere function to use CURDATE for fixed-date events, improving accuracy in event filtering. Adjust image styling in ImageContent.vue to use object-fit: contain and center positioning for better layout consistency.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 15:51:55 +02:00
Torsten Schulz (local)
b2ede3f525 Refactor upcoming event filtering: Update buildUpcomingWhere function to compare dates at the date-only level, addressing timezone issues. This change enhances the accuracy of event retrieval and improves code clarity.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 15:36:19 +02:00
Torsten Schulz (local)
59aae59b62 Refactor event retrieval logic: Extract upcoming event filtering into a separate function for improved readability and maintainability. This change simplifies the conditions for fetching events, ensuring clarity in the codebase.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 15:27:42 +02:00
Torsten Schulz (local)
d412331f8e Refactor event retrieval logic: Implement server-side filtering for past events based on user preference, enhancing performance and simplifying client-side code. Update API call in EventManagement component to include past events parameter.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 7s
2026-04-29 15:23:37 +02:00
Torsten Schulz (local)
f7e8b31fdb Update deploy script: Add conditional execution for update script after backup process, enhancing deployment reliability and error handling.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
2026-04-29 14:15:56 +02:00
Torsten Schulz (local)
4294dcb88b Enhance deploy script: Add functions to ensure required commands (node, npm, git) are available in the PATH, improving reliability in non-interactive SSH sessions. This includes bootstrapping Node.js environment using nvm if necessary.
Some checks failed
Deploy miriamgemeinde / deploy (push) Failing after 2s
2026-04-29 14:13:28 +02:00
Torsten Schulz (local)
6cccf3e1d6 Enhance deployment script: Implement conditional service restart logic for improved handling of non-root user deployments. Update CI workflow to ensure proper execution of deploy.sh after backup process.
Some checks failed
Deploy miriamgemeinde / deploy (push) Failing after 2s
2026-04-29 14:12:16 +02:00
Torsten Schulz (local)
c631f63d04 Update .gitignore: Add .codex to ignore list to prevent tracking of Codex files in the repository.
Some checks failed
Deploy miriamgemeinde / deploy (push) Failing after 7s
2026-04-29 14:01:29 +02:00
Torsten Schulz (local)
7a9444b468 Refactor EventRender component: Update image handling logic to improve visibility checks and enhance layout responsiveness. Introduce hasVisibleImage method and apply conditional class for grid layout based on media presence. 2026-04-29 13:53:23 +02:00
Torsten Schulz (local)
e44950d857 Add bulk image upload functionality: Implement new routes and methods for handling bulk image uploads in the imageController. Update ImageUpload component to support switching between single and bulk upload modes, including form handling for multiple images, base title, start number, and optional page association. Enhance user experience with improved form validation and reset functionality. 2026-04-29 13:36:35 +02:00
Torsten Schulz (local)
b47e832e45 Implement transaction handling in event deletion: Enhance deleteEvent function to manage foreign key constraints by removing associated EventContactPerson records before deleting the event. This ensures data integrity and improves error handling during the deletion process. 2026-04-29 13:11:56 +02:00
Torsten Schulz (local)
93da37dd35 Enhance worship filtering logic: Introduce legacy neighborhood configuration handling in WorshipRender component, allowing for backward compatibility with existing location parameters while ensuring neighborInvitation is set correctly for neighborhood pages. 2026-04-26 23:28:00 +02:00
Torsten Schulz (local)
64d6c3e6b4 Enhance worship filtering logic: Modify fetchWorships method to conditionally include neighborInvitation parameter for neighborhood pages, ensuring location filters do not interfere with neighborhood-specific worship retrieval. 2026-04-14 11:54:16 +02:00
Torsten Schulz (local)
6e30f739a6 Enhance worship filtering functionality: Update getFilteredWorships method to include neighborInvitation query parameter, allowing for filtering based on neighborhood invitations. This improves the granularity of worship event retrieval based on user preferences. 2026-04-14 11:48:44 +02:00
Torsten Schulz (local)
fb4f5e42d0 Enhance event management and newsletter import functionality: Introduce methods for applying drafts from a bulk queue and streamline event form handling. Update event selection logic in the newsletter import management component to support encoding and decoding of bulk selections, improving user experience and data handling. 2026-04-08 14:22:01 +02:00
Torsten Schulz (local)
1be6fe0afc Integrate PDF parsing functionality: Add 'pdf-parse' dependency to package.json and package-lock.json. Update worshipController to include logic for handling PDF imports, enhancing the event management process. Refactor routing to support new newsletter import features and improve event form handling for better user experience. 2026-04-08 13:04:38 +02:00
Torsten Schulz (local)
e6f87184b2 Update worship approval logic: Modify the import process to set the approval status based on the UI checkbox, ensuring a fallback to false if no value is provided. This enhances the clarity of the approval mechanism during worship data imports. 2026-04-08 09:57:10 +02:00
Torsten Schulz (local)
18d7c7f164 Upgrade Express to version 5.2.1 and update related dependencies in package.json and package-lock.json. Refactor server CORS configuration to accommodate Express 5 changes. Enhance routing logic in Vue components for improved path normalization and menu handling. Update HTML asset references for better loading performance and accessibility improvements in various components. 2026-04-08 09:54:41 +02:00
Torsten Schulz (local)
80eef53670 Update dependencies and refactor routing: Upgrade Tiptap extensions to version 3.22.2 in package.json and package-lock.json. Enhance router configuration by introducing route names for better maintainability and adding new core routes for home, terms, and privacy policy. Adjust HTML asset references for improved loading efficiency. 2026-04-08 09:34:51 +02:00
Torsten Schulz (local)
597c8ceffe Refactor project to use Vite: Remove Vue CLI configuration files and update package.json to integrate Vite for development and build processes. Adjust HTML structure for improved asset loading and streamline dependencies in package-lock.json. 2026-04-08 09:03:33 +02:00
Torsten Schulz (local)
99ec18c8f7 Enhance project structure and styling: Update .gitignore to exclude build artifacts and uploads, modify package.json to streamline the build process, and refactor HTML and Vue components for improved layout and accessibility. Add new CSS styles for better presentation in ContactRender, EventRender, WorshipRender, and ImageContent components. 2026-04-08 08:54:31 +02:00
Torsten Schulz (local)
7e4f2935a3 Remove multiple unused CSS files to streamline the project and reduce build size. 2026-04-08 08:54:03 +02:00
Torsten Schulz (local)
02487d44e9 Update dependencies and refactor server configuration: Upgrade @vue/cli and ESLint packages, replace moment.js with date-fns for date handling in eventController, and remove unused HTTPS server configuration in server.js. Additionally, streamline Vue.js build process by removing cache and thread loaders in vue.config.js. 2026-04-08 08:44:31 +02:00
Torsten Schulz (local)
6ffc1fedd9 Refactor database configuration and enhance server settings: Update database connection logic to utilize environment variables and improve error handling in database connection. Adjust server port configuration to prioritize BACKEND_PORT. Update HTML structure for better compatibility and add missing elements in various components. 2026-04-08 08:37:36 +02:00
186 changed files with 6783 additions and 19082 deletions

4
.eslintignore Normal file
View File

@@ -0,0 +1,4 @@
dist/
public/
node_modules/

View File

@@ -0,0 +1,55 @@
name: Deploy miriamgemeinde
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
env:
SSH_HOST: ${{ vars.PROD_HOST }}
SSH_PORT: ${{ vars.PROD_PORT }}
SSH_USER: ${{ vars.PROD_USER }}
steps:
- name: Show resolved non-secret config
run: |
echo "SSH_HOST=$SSH_HOST"
echo "SSH_PORT=$SSH_PORT"
echo "SSH_USER=$SSH_USER"
- name: Prepare SSH
run: |
set -e
mkdir -p ~/.ssh
printf '%s' "${{ secrets.PROD_SSH_KEY_B64 }}" | base64 -d > ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
ssh-keygen -l -f ~/.ssh/id_deploy
ssh-keyscan -p "$SSH_PORT" "$SSH_HOST" >> ~/.ssh/known_hosts
- name: Test SSH connection
run: |
set -e
ssh -i ~/.ssh/id_deploy \
-o StrictHostKeyChecking=no \
-o BatchMode=yes \
-o ConnectTimeout=10 \
-p "$SSH_PORT" \
"$SSH_USER@$SSH_HOST" \
"echo SSH OK"
# If you need server-side preparation (e.g. ensure /var/... exists/permissions),
# add it in the remote command before running the update script.
- name: Run deployment script
run: |
set -e
ssh -i ~/.ssh/id_deploy \
-o StrictHostKeyChecking=no \
-o BatchMode=yes \
-o ConnectTimeout=10 \
-p "$SSH_PORT" \
"$SSH_USER@$SSH_HOST" \
"bash -lc 'set -euo pipefail; TS=\$(date +\"%Y-%m-%d_%H%M%S\"); SRC=\"/var/www/miriamgemeinde/public/images\"; DEST_BASE=\"/home/torsten/miriamgemeinde/backup/\$TS\"; mkdir -p \"\$DEST_BASE\"; if [ -d \"\$SRC\" ]; then cp -a \"\$SRC\" \"\$DEST_BASE/\"; echo \"Backed up \$SRC -> \$DEST_BASE/images\"; else echo \"WARN: \$SRC does not exist; skipping backup\"; fi; if [ -f /home/torsten/update-miriamgemeinde.sh ]; then bash /home/torsten/update-miriamgemeinde.sh; else echo \"ERROR: /home/torsten/update-miriamgemeinde.sh not found\"; exit 127; fi'"

11
.gitignore vendored
View File

@@ -27,5 +27,16 @@ server.key
server.cert
public/images/uploads/1ba24ea7-f52c-4179-896f-1909269cab58.jpg
# Vue Build-Artefakte (werden beim Deploy generiert)
/public/index.html
/public/assets/
public/js/
public/css/
public/**/*.map
# Uploads/Runtime-Dateien nicht versionieren
public/images/uploads/
actualize.sh
files/uploads/GD 24.08.2025-04.01.2026 Stand 12.08.2025.docx
.codex

View File

@@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
};

View File

@@ -1,9 +1,9 @@
{
"development": {
"username": "miriamgemeinde",
"username": "miriam_user",
"password": "hitomisan",
"database": "miriamgemeinde",
"host": "localhost",
"host": "tsschulz.de",
"dialect": "mysql"
},
"test": {

View File

@@ -1,8 +1,25 @@
const { Sequelize } = require('sequelize');
require('dotenv').config();
const sequelize = new Sequelize('miriamgemeinde', 'miriamgemeinde', 'hitomisan', {
host: 'localhost',
dialect: 'mysql',
const envName = process.env.NODE_ENV || 'development';
const fileConfig = require('./config.json')[envName];
if (!fileConfig) {
throw new Error(
`[DB] Kein Eintrag in config/config.json für NODE_ENV="${envName}".`
);
}
const database = process.env.DB_NAME || fileConfig.database;
const username = process.env.DB_USER || fileConfig.username;
const password =
process.env.DB_PASSWORD === undefined ? fileConfig.password : process.env.DB_PASSWORD;
const host = process.env.DB_HOST || fileConfig.host;
const sequelizeOptions = {
host,
dialect: fileConfig.dialect || 'mysql',
dialectOptions: fileConfig.dialectOptions,
retry: {
match: [
/ConnectionError/,
@@ -11,24 +28,38 @@ const sequelize = new Sequelize('miriamgemeinde', 'miriamgemeinde', 'hitomisan',
/SequelizeHostNotFoundError/,
/SequelizeHostNotReachableError/,
/SequelizeInvalidConnectionError/,
/SequelizeConnectionTimedOutError/
/SequelizeConnectionTimedOutError/,
],
max: 5
max: 5,
},
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
idle: 10000,
},
logging: process.env.DB_LOGGING === '1' ? console.log : false,
};
if (process.env.DB_PORT) {
sequelizeOptions.port = parseInt(process.env.DB_PORT, 10);
} else if (fileConfig.port) {
sequelizeOptions.port = fileConfig.port;
}
});
const sequelize = new Sequelize(database, username, password, sequelizeOptions);
async function connectWithRetry() {
try {
await sequelize.authenticate();
console.log(`Connection has been established successfully. Database server: ${sequelize.config.host}`);
console.log(
`[DB] Verbindung OK — host=${host} database=${database} user=${username} (NODE_ENV=${envName})`
);
} catch (error) {
console.error('Unable to connect to the database:', error);
console.error('[DB] Verbindung fehlgeschlagen:', error.message);
console.error(
`[DB] Erwartete Quelle: config/config.json → "${envName}" oder Umgebungsvariablen DB_HOST, DB_USER, DB_PASSWORD, DB_NAME`
);
setTimeout(connectWithRetry, 5000);
}
}

View File

@@ -82,7 +82,11 @@ exports.login = async (req, res) => {
if (!user.active) {
return res.status(403).json({ message: 'Benutzerkonto ist nicht aktiv' });
}
const token = jwt.sign({ id: user.id, name: user.name, email: user.email }, 'zTxVgptmPl9!_dr%xxx9999(dd)', { expiresIn: '1h' });
const token = jwt.sign(
{ id: user.id, name: user.name, email: user.email },
'zTxVgptmPl9!_dr%xxx9999(dd)',
{ expiresIn: process.env.JWT_EXPIRES_IN || '12h' }
);
return res.status(200).json({ message: 'Login erfolgreich', token, 'user': user });
} catch (error) {
return res.status(500).json({ message: 'Ein Fehler ist aufgetreten' });

View File

@@ -1,17 +1,38 @@
const { Event, Institution, EventPlace, ContactPerson, EventType } = require('../models');
const { Op } = require('sequelize');
const moment = require('moment'); // Import von Moment.js
const { Event, Institution, EventPlace, ContactPerson, EventType, EventContactPerson, sequelize } = require('../models');
const { Op, fn, col, where: sequelizeWhere } = require('sequelize');
function buildUpcomingWhere() {
return {
[Op.or]: [
{ date: { [Op.eq]: null } },
// Fixed-date events: only today or future (date-only compare).
sequelizeWhere(fn('DATE', col('date')), { [Op.gte]: fn('CURDATE') }),
],
};
}
const getAllEvents = async (req, res) => {
try {
const includePast = String(req.query?.includePast || '').toLowerCase();
const wantsPast = includePast === '1' || includePast === 'true' || includePast === 'yes';
const where = wantsPast
? undefined
: buildUpcomingWhere();
const events = await Event.findAll({
where,
include: [
{ model: Institution, as: 'institution' },
{ model: EventPlace, as: 'eventPlace' },
{ model: EventType, as: 'eventType' },
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
],
order: ['name', 'date', 'time']
order: [
['date', 'ASC'],
['time', 'ASC'],
['name', 'ASC'],
],
});
res.json(events);
} catch (error) {
@@ -23,19 +44,7 @@ const getAllEvents = async (req, res) => {
const filterEvents = async (req, res) => {
try {
const request = req.body;
const where = {
[Op.or]: [
{
date: {
[Op.or]: [
{ [Op.gte]: moment().startOf('day').toDate() },
{ [Op.eq]: null }
]
}
},
{ dayOfWeek: { [Op.gte]: 0 } }
]
};
const where = buildUpcomingWhere();
const order = [
['date', 'ASC'],
['time', 'ASC']
@@ -60,7 +69,7 @@ const filterEvents = async (req, res) => {
const events = await Event.findAll({
where: {
alsoOnHomepage: 1,
date: { [Op.gte]: moment().startOf('day').toDate() }
...buildUpcomingWhere(),
},
include: [
{ model: Institution, as: 'institution' },
@@ -163,17 +172,28 @@ const updateEvent = async (req, res) => {
};
const deleteEvent = async (req, res) => {
const transaction = await sequelize.transaction();
try {
const { id } = req.params;
// Erst Zuordnungen in der Join-Tabelle löschen, damit FK-Constraints erfüllt sind.
await EventContactPerson.destroy({
where: { event_id: id },
transaction,
});
const deleted = await Event.destroy({
where: { id: id }
where: { id: id },
transaction,
});
if (deleted) {
await transaction.commit();
res.status(204).json();
} else {
await transaction.rollback();
res.status(404).json({ error: 'Event not found' });
}
} catch (error) {
await transaction.rollback();
res.status(500).json({ error: 'Failed to delete event' });
console.error(error);
}

View File

@@ -16,6 +16,7 @@ const storage = multer.diskStorage({
const upload = multer({ storage });
exports.uploadImage = upload.single('image');
exports.uploadImages = upload.array('images');
exports.getAllPages = async (req, res) => {
try {
@@ -51,6 +52,51 @@ exports.saveImageDetails = async (req, res) => {
}
};
exports.saveImageDetailsBulk = async (req, res) => {
try {
const { baseTitle, description, page, startNumber } = req.body;
const files = req.files || [];
if (!baseTitle || !String(baseTitle).trim()) {
return res.status(400).json({ error: 'Bitte einen Basis-Titel angeben.' });
}
if (files.length === 0) {
return res.status(400).json({ error: 'Bitte mindestens ein Bild auswählen.' });
}
const pageItem = page ? await Page.findAll({ where: { link: page } }) : [];
const pageId = pageItem && pageItem[0] ? pageItem[0].id : null;
const firstNumber = Number.parseInt(startNumber, 10);
const startAt = Number.isFinite(firstNumber) ? firstNumber : 1;
const createdImages = [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const runningNumber = startAt + i;
const title = `${String(baseTitle).trim()} ${runningNumber}`;
const newImage = await Image.create({
id: uuidv4(),
filename: file.filename,
title,
description: description || '',
pageId,
});
createdImages.push(newImage);
}
// Menübild nur dann setzen, wenn genau ein Bild hochgeladen wurde.
if (page && createdImages.length === 1) {
const imageUrl = `/uploads/${createdImages[0].filename}`;
await MenuItem.update({ image: imageUrl }, { where: { link: page } });
}
res.status(201).json(createdImages);
} catch (error) {
console.error('Fehler beim Bulk-Upload der Bilder:', error);
res.status(500).json({ error: 'Fehler beim Bulk-Upload der Bilder' });
}
};
exports.getImages = async (req, res) => {
try {
const images = await Image.findAll({ order: [['title', 'ASC']] });

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
const { WorshipLeader } = require('../models');
const { Op } = require('sequelize');
function normalizeLeaderPayload(body) {
const code = String(body.code || '').trim();
const name = String(body.name || '').trim();
const aliases = String(body.aliases || '').trim();
const active = body.active === undefined ? true : !!body.active;
return { code, name, aliases, active };
}
exports.getAllWorshipLeaders = async (req, res) => {
try {
const includeInactive = String(req.query?.includeInactive || '').toLowerCase();
const wantsInactive = includeInactive === '1' || includeInactive === 'true' || includeInactive === 'yes';
const where = wantsInactive ? undefined : { active: true };
const leaders = await WorshipLeader.findAll({
where,
order: [['code', 'ASC']],
});
res.json(leaders);
} catch (error) {
console.error('getAllWorshipLeaders:', error);
res.status(500).json({ error: 'Failed to fetch worship leaders' });
}
};
exports.createWorshipLeader = async (req, res) => {
try {
const payload = normalizeLeaderPayload(req.body || {});
if (!payload.code || !payload.name) {
return res.status(400).json({ message: 'code und name sind Pflichtfelder.' });
}
const existing = await WorshipLeader.findOne({ where: { code: payload.code } });
if (existing) {
return res.status(409).json({ message: `Kürzel "${payload.code}" existiert bereits.` });
}
const created = await WorshipLeader.create(payload);
res.status(201).json(created);
} catch (error) {
console.error('createWorshipLeader:', error);
res.status(500).json({ error: 'Failed to create worship leader' });
}
};
exports.updateWorshipLeader = async (req, res) => {
try {
const { id } = req.params;
const leader = await WorshipLeader.findByPk(id);
if (!leader) {
return res.status(404).json({ message: 'Worship leader not found' });
}
const payload = normalizeLeaderPayload(req.body || {});
if (!payload.code || !payload.name) {
return res.status(400).json({ message: 'code und name sind Pflichtfelder.' });
}
const codeClash = await WorshipLeader.findOne({
where: { code: payload.code, id: { [Op.ne]: id } },
});
if (codeClash) {
return res.status(409).json({ message: `Kürzel "${payload.code}" existiert bereits.` });
}
await leader.update(payload);
res.json(leader);
} catch (error) {
console.error('updateWorshipLeader:', error);
res.status(500).json({ error: 'Failed to update worship leader' });
}
};
exports.deleteWorshipLeader = async (req, res) => {
try {
const { id } = req.params;
const deleted = await WorshipLeader.destroy({ where: { id } });
if (!deleted) {
return res.status(404).json({ message: 'Worship leader not found' });
}
res.status(204).json();
} catch (error) {
console.error('deleteWorshipLeader:', error);
res.status(500).json({ error: 'Failed to delete worship leader' });
}
};

View File

@@ -9,9 +9,36 @@ NC="\033[0m"
log() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $*${NC}"; }
err() { echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] $*${NC}" 1>&2; }
ensure_command() {
local cmd="$1"
command -v "$cmd" >/dev/null 2>&1
}
bootstrap_node() {
# In non-interactive SSH sessions, node/npm might not be on PATH (e.g. nvm in .bashrc).
if ensure_command npm && ensure_command node; then
return 0
fi
if [ -s "$HOME/.nvm/nvm.sh" ]; then
# shellcheck disable=SC1090
. "$HOME/.nvm/nvm.sh"
# Prefer default alias if configured, otherwise keep current.
nvm use --silent default >/dev/null 2>&1 || true
fi
}
bootstrap_node
if ! ensure_command git; then err "git not found in PATH"; exit 127; fi
if ! ensure_command npm; then err "npm not found in PATH"; exit 127; fi
log "Fetching latest changes..."
git fetch --all --prune || { err "git fetch failed"; exit 1; }
log "Cleaning generated frontend artifacts..."
git restore -- package-lock.json package.json 2>/dev/null || true
git restore -- public/index.html 2>/dev/null || true
git clean -fd -- dist public/assets || { err "cleanup failed"; exit 1; }
log "Pulling latest changes..."
git pull --ff-only || { err "git pull failed"; exit 1; }
@@ -26,6 +53,17 @@ mkdir -p public || true
cp -R dist/* public/ || { err "copy dist failed"; exit 1; }
log "Restarting service miriamgemeinde..."
sudo systemctl restart miriamgemeinde || { err "service restart failed"; exit 1; }
if [ "${EUID:-$(id -u)}" -eq 0 ]; then
systemctl restart miriamgemeinde || { err "service restart failed"; exit 1; }
else
# Non-interactive deploys (CI) must not prompt for a sudo password.
# Configure on the server (recommended):
# sudo visudo -f /etc/sudoers.d/miriamgemeinde
# torsten ALL=NOPASSWD:/bin/systemctl restart miriamgemeinde,/bin/systemctl status miriamgemeinde
sudo -n systemctl restart miriamgemeinde || {
err "service restart failed (no password prompt). Configure passwordless sudo for 'systemctl restart miriamgemeinde' or run deploy as root."
exit 1
}
fi
log "Deployment completed successfully."

View File

@@ -0,0 +1,224 @@
# Konzept: Modernisierung von Design und Bedienbarkeit
**Projekt:** Evangelische Miriamgemeinde Frankfurt (Vue.js-Webauftritt)
**Stand:** April 2026
**Ziel:** Zeitgemäße, klare Oberfläche mit hoher Vertrauenswürdigkeit; kirchlich-seriös, ohne „Startup-Optik“.
---
## 1. Zielbild und Leitlinien
### 1.1 Positionierung
Die Website ist **Informations- und Gemeinschaftsangebot** einer evangelischen Gemeinde. Sie soll:
- **verlässlich und ruhig** wirken (kein visuelles „Rauschen“),
- **inhaltlich im Vordergrund** stehen (Typografie, Lesbarkeit, klare Hierarchie),
- **digital souverän** wirken (gute Struktur, schnelle Orientierung, respektvolle Hilfen für alle Nutzergruppen).
### 1.2 Nicht verhandelbar: EKHN-Violett
Die **Grundfarbe EKHN-Violett** bleibt die primäre Markenfarbe. Im Code aktuell u. a. als `#9400ff` mit Hover `#7a00d1` genutzt (Navigation). Diese Farbe wird **nicht ersetzt oder „neu interpretiert“**.
- Sie wird als **CSS-Design-Token** zentral definiert (z. B. `--color-ekhn-violet`, `--color-ekhn-violet-hover`), damit alle Komponenten konsistent darauf zugreifen.
- **Abstufungen** (heller für Hintergründe, transparenter für Overlays) sind **zulässig**, solange die wahrgenommene Marke **dieselbe Violett-Identität** bleibt.
- Kontrast zu Text und Icons muss **WCAG-konform** sein (siehe Abschnitt 7).
### 1.3 Seriosität vs. Modernität
| Modern (gewünscht) | Vermeiden (für kirchlichen Kontext) |
|--------------------|-------------------------------------|
| Klares Raster, viel Weißraum | Neon-Verläufe, Spielereien |
| Ruhige, lesbare Schrift | Display-Fonts, übertriebene Größen |
| Deutliche Fokuszustände (Tastatur) | Aggressive Animationen |
| Einheitliche Komponenten | Zufällige Abstände und Stile pro Seite |
| Verständliche Navigation | „Experimentelle“ Menüs ohne klare Labels |
**Leitmotiv:** *Ruhige Sachlichkeit mit warmer, einladender Sprache in der UI (Beschriftungen, Fehlermeldungen, leere Zustände).*
---
## 2. Kurze Ist-Analyse (Ausgangslage)
Aus dem aktuellen Aufbau (u. a. `AppComponent.vue`, `NavbarComponent.vue`, `HeaderComponent.vue`, `FooterComponent.vue`):
- **Typografie:** durchgängig `Arial, sans-serif` funktional, aber wenig Profil; keine skalierbare Typo-Skala.
- **Layout:** starre `min-width: 1000px` in der Hauptspalte begünstigt horizontales Scrollen auf Tablets/kleineren Viewports; Zwei-Spalten-Logik mit Breakpoints ist vorhanden, sollte aber **inhaltlich und technisch** weiterentwickelt werden.
- **Farben:** Violett in der Navigation; Footer dunkelblau (`#0b1735`); rechte Spalte hellblau (`#d9e2f3`); Header mit Schlagschatten in Lavendeltönen teils **uneinheitlich** zur Markenfarbe.
- **Navigation:** Hamburger/Menü-Button unter 768px; Dropdowns mit Hover auf Touch-Geräten und für Tastaturnutzer ist hier **Verbesserungspotenzial** (Fokus, ARIA, Touch-Targets).
- **Footer:** Login-Link in Grau auf dunklem Grund **Kontrast** prüfen und ggf. anpassen (ohne Marke zu verändern).
Diese Punkte fließen als konkrete Maßnahmen in die Phasenplanung (Abschnitt 9) ein.
---
## 3. Design-System: Farben
### 3.1 Primär (unverändert)
| Token (Vorschlag) | Verwendung | Hex (Ist) |
|-------------------|------------|-----------|
| `--color-brand-primary` | Navigationsleiste, primäre Buttons, aktive Zustände | `#9400ff` |
| `--color-brand-primary-hover` | Hover, aktive Menüpunkte | `#7a00d1` |
*Hinweis:* Falls das offizielle EKHN-Handbuch eine minimal abweichende Hex-Angabe vorsieht, **eine** kanonische Quelle festlegen und nur diese verwenden weiterhin **kein** Wechsel zu einer anderen Farbfamilie.
### 3.2 Neutrale Flächen (ergänzend, nicht markenersetzend)
- **Hintergrund Seite:** `#ffffff` oder sehr helles Neutral (`#f8f9fb`), konsistent.
- **Sekundärflächen** (Karten, rechte Spalte, Infoboxen): dezentes Grau oder ein **sehr zurückhaltendes Violett-Grau** (z. B. Mischung aus Weiß mit 36 % Primärfarbe), damit die Seite **ruhig** bleibt und nicht „bunt“ wirkt.
- **Text:** nahezu schwarz für Fließtext (`#1a1a1a` bis `#222`), sekundäre Texte etwas heller immer mit Kontrastprüfung.
### 3.3 Akzent (optional, sparsam)
- **Links** im Fließtext: z. B. unterstrichen oder klar farbig abgesetzt; Primärviolett oder eine **eine** abgestimmte dunklere Violett-Nuance für Lesbarkeit auf Weiß.
- **Erfolg/Warnung/Fehler:** Standard-Semantik (Grün/Gelb/Rot) nur für Status **nicht** als neue Hauptfarbe neben dem Violett.
### 3.4 Footer
- Dunkler Footer kann bleiben; **Links und Fokus** müssen gut lesbar sein. Primärviolett für Hover/Fokus auf dunklem Grund nur, wenn der Kontrast stimmt sonch neutrale helle Linkfarbe + sichtbarer Fokusring.
---
## 4. Typografie
### 4.1 Schriftwahl
- **Primärschrift:** eine gut lesbare **System- oder Webschrift** mit neutral-seriösem Charakter, z. B.:
- *Source Sans 3*, *Inter*, *Open Sans* oder **beibehaltene Arial** nach einheitlicher Skala Entscheidung in Phase 1 an **Performance** und **Corporate-Vorgaben** binden.
- **Überschriften:** dieselbe Familie mit klarer Gewichtsstaffelung (z. B. 600/700), keine verspielten Display-Schnitte.
### 4.2 Skala (Beispiel)
| Stufe | Verwendung | Größe (Orientierung, rem) |
|-------|------------|---------------------------|
| H1 | Seitentitel (nicht auf jeder Unterseite doppelt mit Logo-Text kollidieren) | `1.752rem` |
| H2 | Abschnitte | `1.351.5rem` |
| H3 | Unterabschnitte | `1.151.25rem` |
| Body | Fließtext | `1rem`, Zeilenlänge max. ca. 6575 Zeichen |
| Klein | Meta, Fußnoten | `0.875rem` mit ausreichend Kontrast |
### 4.3 Regeln
- **Keine** reine Großschreibung für lange Menütexte.
- **Zeilenabstand** für Fließtext mindestens ca. 1,5.
- **Kontrast** von Überschriften und Text zu Hintergrund einhalten (WCAG 2.1 AA).
---
## 5. Layout und Raster
### 5.1 Container
- Maximalbreite für Lesbarkeit (z. B. `min(100%, 72rem)`) mit **symmetrischem Innenabstand**.
- **Keine** feste `min-width` im vierstelligen Pixelbereich ohne Scroll-Alternative; stattdessen **flexibles Grid** + sinnvolle Mindestbreiten nur dort, wo nötig (Tabellen).
### 5.2 Breakpoints (Orientierung)
- **Mobil:** &lt; 640px eine Spalte, Navigation als klares Overlay oder ausklappbare Liste mit großen Touch-Zielen.
- **Tablet:** 6401024px ggf. weiterhin eine Spalte oder kompakte Sidebar.
- **Desktop:** &gt; 1024px Zwei-Spalten-Layout optional; rechte Spalte für Bilder/Termine **nicht** zwingend über volle Höhe „eingesperrt“, wenn das inhaltlich sinnvoller ist.
### 5.3 Weißraum
- Einheitliches Spacing-System (z. B. Vielfache von 4px oder 0,25rem): Abstände zwischen Blöcken, in Karten, zwischen Formularfeldern.
---
## 6. Navigation und Bedienung
### 6.1 Hauptnavigation
- **Desktop:** horizontale Leiste mit Vollfarbe EKHN-Violett; aktiver Eintrag **deutlich** (Unterstreichung, Hintergrund oder starker Kontrast weiterhin im Violett-System).
- **Touch:** Menüpunkte mindestens ca. **44×44 px** Klickfläche.
- **Untermenüs:** Hover für Maus; für Tastatur **Escape** schließt; **Fokus** sichtbar im gesamten Menübaum.
- **Mobile:** „Menü“-Button durch **Icon + Text** oder klares Label; Animationen **kurz** (&lt; 200ms).
### 6.2 Orientierung
- Optional: **Brotkrumen** bei tieferen Seiten (Gemeindeleben → Gruppen → …), dezent unterhalb des Headers.
- Seitentitel konsistent: eine H1 pro Seite, semantisch korrekt.
### 6.3 Footer
- Impressum/Datenschutz bleiben gut auffindbar; gleiche visuelle Gewichtung wie bisher, mit verbessertem Kontrast und Fokus.
---
## 7. Barrierefreiheit (WCAG 2.1 Level AA als Ziel)
- **Kontrast:** Text auf Violett/Weiß/Grau messen (Tools: axe, Lighthouse, WebAIM Contrast Checker).
- **Tastatur:** alle interaktiven Elemente erreichbar; sichtbarer `:focus-visible`.
- **Screenreader:** Landmarks (`header`, `nav`, `main`, `footer`), Überschriftenhierarchie, `aria-expanded` für Untermenüs, sinnvolle `alt`-Texte bei Bildern.
- **Bewegung:** `prefers-reduced-motion` respektieren (Animationen abschwächen oder deaktivieren).
---
## 8. Komponentenbibliothek (schrittweise)
Einheitliche Bausteine reduzieren Streuung und erleichtern Wartung:
| Komponente | Anforderungen |
|------------|----------------|
| **Primärbutton** | Violett-Hintergrund, weißer Text, Hover, disabled-Zustand, Fokusring |
| **Sekundärbutton** | Outline in Violett oder neutral, gleiche Höhe wie Primär |
| **Karte** (Termine, News) | Klarer Titel, Datum, Link „weiterlesen“, ruhiger Schatten oder Rahmen |
| **Formularfelder** | Labels sichtbar, Fehler näch am Feld, keine rein farblichen Fehlerhinweise |
| **Tabellen** (Admin) | Zeilenwechsel, ausreichend Zellpadding, horizontales Scrollen auf schmalen Screens |
Technisch: zentrale **CSS-Variablen** + ggf. wiederverwendbare Vue-Komponenten oder Utility-Klassen ohne das Projekt unnötig zu überfrachten.
---
## 9. Umsetzung in Phasen
### Phase 1 Fundament (geringes Risiko, hoher Nutzen)
- Design-Tokens (Farben, Abstände, Schriftgrößen) in einer **globalen** Styleschicht.
- Entfernen/Ersetzen problematischer Layout-Regeln (`min-width` Hauptspalte), **Responsive** testen.
- Typografie-Skala und Basisabstände vereinheitlichen.
- Kontrast Footer/Links prüfen und anpassen.
### Phase 2 Navigation & Chrome
- Navbar optisch verfeinern (Padding, aktive Zustände, Touch) bei **unverändertem** `#9400ff` / Hover.
- Header (Titelzeile): Schlagschatten/Lavendel **an Markensystem anbinden** oder reduzieren für seriösere Wirkung.
- Optional Brotkrumen für tiefe Seiten.
### Phase 3 Inhaltsmodule
- Termine, Gottesdienste, Kontakt: Kartenlayout, konsistente Datumdarstellung (`date-fns` ist bereits im Projekt).
- Bilder: feste Aspect-Ratios oder `object-fit`, damit keine Layout-Sprünge entstehen.
### Phase 4 Feinschliff
- Mikro-Interaktionen (Hover, Fokus) konsistent.
- Performance: Schriftarten, Bildgrößen, Lazy Loading wo sinnvoll.
- Finale Accessibility-Prüfung.
---
## 10. Erfolgskriterien (messbar / reviewbar)
- Keine horizontale Scrollbarkeit bei Standard-Viewports durch feste Mindestbreiten.
- Lighthouse-Accessibility-Score deutlich verbessert (Ziel: **≥ 90**, wo technisch möglich).
- **Manuelle** Tastatur- und Screenreader-Stichprobe auf Startseite, Navigation, einem Formular.
- **Visuelles Review** mit 23 Stakeholdern: „wirkt seriös, klar, kirchlich passend“ **ohne** neue Hauptfarbe neben EKHN-Violett.
---
## 11. Explizite Nicht-Ziele
- Kein Rebranding und kein Ersatz der Primärfarbe.
- Kein „Gamification“-Design oder verspielte Illustrationen als Hauptstil.
- Keine Einführung schwerer UI-Frameworks nur wegen Optik, wenn das Projekt schlank bleiben soll (abwägen mit Wartbarkeit).
---
## 12. Nächster Schritt
Umsetzung beginnt mit **Phase 1**: globale Tokens + Layout-Fixes + Kontrast. Dieses Dokument dient als **Referenz** für alle weiteren UI-Änderungen und sollte bei größeren Designentscheidungen aktualisiert werden.
---
*Dokument erstellt als Arbeitsgrundlage für die Modernisierung; bei Abweichungen von offiziellen EKHN-CD-Vorgaben immer die gültige kirchliche Markenrichtlinie Vorrang haben.*

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
<title>Miriamgemeinde</title>
</head>
<body>
<noscript>
<strong>
Diese Website funktioniert leider nicht richtig, wenn JavaScript deaktiviert ist. Bitte aktivieren Sie
JavaScript, um fortzufahren.
</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,47 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('worship_leaders', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
code: {
type: Sequelize.STRING(32),
allowNull: false,
unique: true,
},
name: {
type: Sequelize.STRING(255),
allowNull: false,
},
aliases: {
type: Sequelize.STRING(512),
allowNull: false,
defaultValue: '',
},
active: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: true,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface) {
await queryInterface.dropTable('worship_leaders');
},
};

32
models/WorshipLeader.js Normal file
View File

@@ -0,0 +1,32 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const WorshipLeader = sequelize.define('WorshipLeader', {
code: {
type: DataTypes.STRING(32),
allowNull: false,
unique: true,
},
name: {
type: DataTypes.STRING(255),
allowNull: false,
},
aliases: {
// Comma-separated list of alternative codes (kept simple to avoid join tables).
type: DataTypes.STRING(512),
allowNull: true,
defaultValue: '',
},
active: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: true,
},
}, {
tableName: 'worship_leaders',
timestamps: true,
});
return WorshipLeader;
};

View File

@@ -3,20 +3,11 @@
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const sequelize = require('../config/database');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
fs.readdirSync(__dirname)
.filter(file => {
return (
file.indexOf('.') !== 0 &&

20376
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,83 +3,81 @@
"version": "1.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build && npm run copy-dist",
"dev": "vite",
"build": "vite build && npm run copy-dist",
"preview": "vite preview",
"copy-dist": "cp -r dist/* public/",
"lint": "vue-cli-service lint"
"lint": "eslint src --ext .js,.vue",
"lint:all": "eslint . --ext .js,.vue"
},
"dependencies": {
"@iconoir/vue": "^7.7.0",
"@tiptap/extension-bold": "^2.4.0",
"@tiptap/extension-bullet-list": "^2.4.0",
"@tiptap/extension-color": "^2.4.0",
"@tiptap/extension-heading": "^2.4.0",
"@tiptap/extension-italic": "^2.4.0",
"@tiptap/extension-link": "^2.4.0",
"@tiptap/extension-ordered-list": "^2.4.0",
"@tiptap/extension-strike": "^2.4.0",
"@tiptap/extension-table": "^2.4.0",
"@tiptap/extension-table-cell": "^2.4.0",
"@tiptap/extension-table-header": "^2.4.0",
"@tiptap/extension-table-row": "^2.4.0",
"@tiptap/extension-text-style": "^2.4.0",
"@tiptap/extension-underline": "^2.4.0",
"@tiptap/starter-kit": "^2.4.0",
"@tiptap/vue-3": "^2.4.0",
"@vue/cli": "^4.2.2",
"@tiptap/extension-bold": "^3.22.2",
"@tiptap/extension-bullet-list": "^3.22.2",
"@tiptap/extension-color": "^3.22.2",
"@tiptap/extension-heading": "^3.22.2",
"@tiptap/extension-italic": "^3.22.2",
"@tiptap/extension-link": "^3.22.2",
"@tiptap/extension-ordered-list": "^3.22.2",
"@tiptap/extension-strike": "^3.22.2",
"@tiptap/extension-table": "^3.22.2",
"@tiptap/extension-table-cell": "^3.22.2",
"@tiptap/extension-table-header": "^3.22.2",
"@tiptap/extension-table-row": "^3.22.2",
"@tiptap/extension-text-style": "^3.22.2",
"@tiptap/extension-underline": "^3.22.2",
"@tiptap/starter-kit": "^3.22.2",
"@tiptap/vue-3": "^3.22.2",
"@xmldom/xmldom": "^0.8.12",
"axios": "^1.7.2",
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
"core-js": "^3.8.3",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"date-fns": "^3.6.0",
"docx": "^9.5.1",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express": "^5.2.1",
"file-saver": "^2.0.5",
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"mammoth": "^1.11.0",
"moment": "^2.30.1",
"multer": "^1.4.5-lts.1",
"mysql2": "^3.10.1",
"nodemailer": "^7.0.6",
"nodemon": "^3.1.3",
"pdf-parse": "^1.1.1",
"sequelize": "^6.37.3",
"sequelize-cli": "^6.6.2",
"uuid": "^10.0.0",
"vm-browserify": "^1.1.2",
"vue": "^3.4.30",
"vue-multiselect": "^3.0.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^4.3.3",
"vuex": "^4.0.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"crypto-browserify": "^3.12.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"os-browserify": "^0.3.0",
"path-browserify": "^1.0.1",
"stream-browserify": "^3.0.0",
"webpack": "^5.92.0"
"@vitejs/plugin-vue": "^6.0.5",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0",
"nodemon": "^3.1.3",
"vite": "^8.0.7",
"vue-eslint-parser": "^9.4.3"
},
"eslintConfig": {
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@babel/eslint-parser"
"ecmaVersion": 2022,
"sourceType": "module"
},
"rules": {}
},

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.register[data-v-4256bbfa]{max-width:400px;margin:auto}form[data-v-4256bbfa]{display:flex;flex-direction:column}label[data-v-4256bbfa]{margin-top:10px}button[data-v-4256bbfa]{margin-top:20px}

View File

@@ -1 +0,0 @@
.privacy-policy[data-v-0c3320ea]{max-width:800px;margin:auto;padding:20px}h1[data-v-0c3320ea],h2[data-v-0c3320ea],h3[data-v-0c3320ea],h4[data-v-0c3320ea],h5[data-v-0c3320ea]{margin-top:20px;color:#333}p[data-v-0c3320ea]{line-height:1.6}ul[data-v-0c3320ea]{margin:10px 0;padding-left:20px}ul li[data-v-0c3320ea]{list-style-type:disc}a[data-v-0c3320ea]{color:#007bff;text-decoration:none}a[data-v-0c3320ea]:hover{text-decoration:underline}

View File

@@ -1 +0,0 @@
.event-places-management[data-v-4e6631f7]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-4e6631f7]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-4e6631f7]{margin-top:10px}input[data-v-4e6631f7]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-4e6631f7]{margin-top:10px;padding:10px}table[data-v-4e6631f7]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-4e6631f7],th[data-v-4e6631f7]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-4e6631f7]{background-color:#f4f4f4}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}.previewinfo[data-v-9a71cbf6]{background-color:#000;color:#d00000;position:absolute;top:93px;left:0;padding:2px 10px;font-weight:700}

View File

@@ -1 +0,0 @@
div[data-v-68b32234]{padding:20px}ul[data-v-68b32234]{list-style:none;padding:0;margin:0}li[data-v-68b32234]{padding:0;margin:0}

View File

@@ -1 +0,0 @@
.upload-files[data-v-f2694614]{width:100%;margin:auto}.upload-files div[data-v-f2694614]{margin-bottom:10px}.file-list[data-v-f2694614]{list-style-type:none;padding:0;margin-top:20px}.file-list li[data-v-f2694614]{border-bottom:1px solid #ddd;padding:10px 0}.file-info[data-v-f2694614]{display:flex;justify-content:space-between;cursor:pointer}.file-title[data-v-f2694614]{font-weight:700}.file-name[data-v-f2694614]{color:#555}.file-date[data-v-f2694614]{color:#888}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.right-column[data-v-12df4c86]{background-color:#d9e2f3}.right-column h2[data-v-12df4c86]{text-align:center;color:#000}.right-column img[data-v-12df4c86]{display:block;margin:0 auto;max-width:100%;height:auto}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.forgot-password[data-v-c694cf4e]{max-width:400px;margin:auto}form[data-v-c694cf4e]{display:flex;flex-direction:column}label[data-v-c694cf4e]{margin-top:10px}button[data-v-c694cf4e]{margin-top:20px}.dialog[data-v-c694cf4e]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.4)}.dialog-content[data-v-c694cf4e]{background:#fff;padding:16px;border-radius:4px;max-width:420px;width:90%}

View File

@@ -1 +0,0 @@
.menu-management[data-v-0e6a0522]{width:100%;margin:auto}.button-container[data-v-0e6a0522]{display:inline-flex;gap:10px;margin-bottom:20px}.tree-view[data-v-0e6a0522]{margin-top:20px}.tree-view ul[data-v-0e6a0522]{list-style-type:none;padding:0}.tree-view li[data-v-0e6a0522]{margin-bottom:5px;padding-left:20px}.tree-view .menu-item[data-v-0e6a0522]{display:inline-flex;width:100%;justify-content:space-between;align-items:center}.tree-view span[data-v-0e6a0522]{cursor:pointer;color:#000}.tree-view button[data-v-0e6a0522]{border:none;height:1.6em;padding:0 .5em;margin:1px;border-radius:5px}.tree-view span[data-v-0e6a0522]:hover{text-decoration:underline}.edit-form[data-v-0e6a0522]{margin-top:20px}.edit-form label[data-v-0e6a0522]{display:block;margin-bottom:5px;font-weight:700}.edit-form input[data-v-0e6a0522]:not([type=checkbox]){display:block;margin-bottom:10px}.edit-form .checkbox-container[data-v-0e6a0522]{display:flex;flex-direction:column;margin-right:10px}.edit-form .order-id[data-v-0e6a0522]{width:50px}.edit-form button[data-v-0e6a0522]{margin-top:5px}

View File

@@ -1 +0,0 @@
.position-management[data-v-1684a375]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-1684a375]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-1684a375]{margin-top:10px}input[data-v-1684a375]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-1684a375]{margin-top:10px;padding:10px}table[data-v-1684a375]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-1684a375],th[data-v-1684a375]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-1684a375]{background-color:#f4f4f4}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.dialog-overlay[data-v-21ade8c0]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center}.dialog[data-v-21ade8c0]{background:#fff;padding:20px;border-radius:5px;max-width:400px;width:100%;text-align:center}button[data-v-21ade8c0]{margin-top:20px}.login[data-v-40a158c0]{max-width:400px;margin:auto}form[data-v-40a158c0]{display:flex;flex-direction:column}label[data-v-40a158c0]{margin-top:10px}button[data-v-40a158c0]{margin-top:20px}

View File

@@ -1 +0,0 @@
.dialog-overlay[data-v-ce9d9498]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:1000}.dialog[data-v-ce9d9498]{background:#fff;padding:30px;border-radius:8px;max-width:400px;width:90%;text-align:center;box-shadow:0 4px 6px rgba(0,0,0,.1)}.dialog h2[data-v-ce9d9498]{margin-top:0;margin-bottom:15px;color:#333;font-size:20px}.dialog p[data-v-ce9d9498]{margin:15px 0;color:#666;line-height:1.5}.dialog button[data-v-ce9d9498]{margin-top:20px;padding:10px 20px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px}.dialog button[data-v-ce9d9498]:hover{background-color:#0056b3}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
div[data-v-334e7b82]{padding:20px}

View File

@@ -1 +0,0 @@
.institution-management[data-v-ff992c44]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-ff992c44]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-ff992c44]{margin-top:10px}input[data-v-ff992c44]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-ff992c44]{margin-top:10px;padding:10px}table[data-v-ff992c44]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-ff992c44],th[data-v-ff992c44]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-ff992c44]{background-color:#f4f4f4}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.reset-password[data-v-e49a033c]{max-width:400px;margin:auto}form[data-v-e49a033c]{display:flex;flex-direction:column}label[data-v-e49a033c]{margin-top:10px}input[data-v-e49a033c]{margin-top:5px;padding:8px;border:1px solid #ddd;border-radius:4px}button[data-v-e49a033c]{margin-top:20px;padding:10px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer}button[data-v-e49a033c]:disabled{background-color:#ccc;cursor:not-allowed}.dialog[data-v-e49a033c]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.4)}.dialog-content[data-v-e49a033c]{background:#fff;padding:16px;border-radius:4px;max-width:420px;width:90%}

View File

@@ -1 +0,0 @@
.position-management[data-v-1684a375]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-1684a375]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-1684a375]{margin-top:10px}input[data-v-1684a375]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-1684a375]{margin-top:10px;padding:10px}table[data-v-1684a375]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-1684a375],th[data-v-1684a375]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-1684a375]{background-color:#f4f4f4}

View File

@@ -1 +0,0 @@
.upload-files[data-v-f2694614]{width:100%;margin:auto}.upload-files div[data-v-f2694614]{margin-bottom:10px}.file-list[data-v-f2694614]{list-style-type:none;padding:0;margin-top:20px}.file-list li[data-v-f2694614]{border-bottom:1px solid #ddd;padding:10px 0}.file-info[data-v-f2694614]{display:flex;justify-content:space-between;cursor:pointer}.file-title[data-v-f2694614]{font-weight:700}.file-name[data-v-f2694614]{color:#555}.file-date[data-v-f2694614]{color:#888}

View File

@@ -1 +0,0 @@
div[data-v-334e7b82]{padding:20px}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.user-administration[data-v-a495c756]{padding:20px}.user-administration h1[data-v-a495c756],.user-administration h2[data-v-a495c756]{margin-bottom:20px}.user-administration form[data-v-a495c756]{display:flex;flex-direction:column;margin-bottom:20px}.user-administration label[data-v-a495c756]{margin-top:10px}.user-administration input[type=email][data-v-a495c756],.user-administration input[type=password][data-v-a495c756],.user-administration input[type=text][data-v-a495c756]{padding:5px;font-size:16px}.user-administration ul[data-v-a495c756]{list-style-type:none;padding:0}.user-administration li[data-v-a495c756]{padding:10px;border-bottom:1px solid #ddd;cursor:pointer}.user-administration li[data-v-a495c756]:hover{background-color:#f0f0f0}

View File

@@ -1 +0,0 @@
.institution-management[data-v-ff992c44]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-ff992c44]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-ff992c44]{margin-top:10px}input[data-v-ff992c44]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-ff992c44]{margin-top:10px;padding:10px}table[data-v-ff992c44]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-ff992c44],th[data-v-ff992c44]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-ff992c44]{background-color:#f4f4f4}

View File

@@ -1 +0,0 @@
div[data-v-68b32234]{padding:20px}ul[data-v-68b32234]{list-style:none;padding:0;margin:0}li[data-v-68b32234]{padding:0;margin:0}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.register[data-v-63b3c0a3]{max-width:400px;margin:auto}form[data-v-63b3c0a3]{display:flex;flex-direction:column}label[data-v-63b3c0a3]{margin-top:10px}button[data-v-63b3c0a3]{margin-top:20px}.dialog[data-v-63b3c0a3]{position:fixed;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.4)}.dialog-content[data-v-63b3c0a3]{background:#fff;padding:16px;border-radius:4px;max-width:420px;width:90%}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.register[data-v-182f8976]{max-width:400px;margin:auto}form[data-v-182f8976]{display:flex;flex-direction:column}label[data-v-182f8976]{margin-top:10px}button[data-v-182f8976]{margin-top:20px}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
form div[data-v-403a0e0b]{margin-bottom:10px}.uploaded-image[data-v-403a0e0b]{display:inline-block;margin:0 0 .5em .5em;border:1px solid #e0e0e0;padding:10px}.uploaded-image input[data-v-403a0e0b],.uploaded-image textarea[data-v-403a0e0b]{width:100%;margin:5px 0}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.impressum[data-v-8b4b087a]{max-width:800px;margin:auto;padding:20px}h1[data-v-8b4b087a],h2[data-v-8b4b087a],h3[data-v-8b4b087a],h4[data-v-8b4b087a]{margin-top:20px;color:#333}p[data-v-8b4b087a]{line-height:1.6}a[data-v-8b4b087a]{color:#007bff;text-decoration:none}a[data-v-8b4b087a]:hover{text-decoration:underline}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.dialog-overlay[data-v-ce9d9498]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center;z-index:1000}.dialog[data-v-ce9d9498]{background:#fff;padding:30px;border-radius:8px;max-width:400px;width:90%;text-align:center;box-shadow:0 4px 6px rgba(0,0,0,.1)}.dialog h2[data-v-ce9d9498]{margin-top:0;margin-bottom:15px;color:#333;font-size:20px}.dialog p[data-v-ce9d9498]{margin:15px 0;color:#666;line-height:1.5}.dialog button[data-v-ce9d9498]{margin-top:20px;padding:10px 20px;background-color:#007bff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px}.dialog button[data-v-ce9d9498]:hover{background-color:#0056b3}.login[data-v-40a158c0]{max-width:400px;margin:auto}form[data-v-40a158c0]{display:flex;flex-direction:column}label[data-v-40a158c0]{margin-top:10px}button[data-v-40a158c0]{margin-top:20px}

View File

@@ -1 +0,0 @@
.menu-management[data-v-0e6a0522]{width:100%;margin:auto}.button-container[data-v-0e6a0522]{display:inline-flex;gap:10px;margin-bottom:20px}.tree-view[data-v-0e6a0522]{margin-top:20px}.tree-view ul[data-v-0e6a0522]{list-style-type:none;padding:0}.tree-view li[data-v-0e6a0522]{margin-bottom:5px;padding-left:20px}.tree-view .menu-item[data-v-0e6a0522]{display:inline-flex;width:100%;justify-content:space-between;align-items:center}.tree-view span[data-v-0e6a0522]{cursor:pointer;color:#000}.tree-view button[data-v-0e6a0522]{border:none;height:1.6em;padding:0 .5em;margin:1px;border-radius:5px}.tree-view span[data-v-0e6a0522]:hover{text-decoration:underline}.edit-form[data-v-0e6a0522]{margin-top:20px}.edit-form label[data-v-0e6a0522]{display:block;margin-bottom:5px;font-weight:700}.edit-form input[data-v-0e6a0522]:not([type=checkbox]){display:block;margin-bottom:10px}.edit-form .checkbox-container[data-v-0e6a0522]{display:flex;flex-direction:column;margin-right:10px}.edit-form .order-id[data-v-0e6a0522]{width:50px}.edit-form button[data-v-0e6a0522]{margin-top:5px}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.privacy-policy[data-v-6785ba18]{max-width:800px;margin:auto;padding:20px}h1[data-v-6785ba18],h2[data-v-6785ba18],h3[data-v-6785ba18],h4[data-v-6785ba18],h5[data-v-6785ba18]{margin-top:20px;color:#333}p[data-v-6785ba18]{line-height:1.6}ul[data-v-6785ba18]{margin:10px 0;padding-left:20px}ul li[data-v-6785ba18]{list-style-type:disc}a[data-v-6785ba18]{color:#007bff;text-decoration:none}a[data-v-6785ba18]:hover{text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.dialog-overlay[data-v-21ade8c0]{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;justify-content:center;align-items:center}.dialog[data-v-21ade8c0]{background:#fff;padding:20px;border-radius:5px;max-width:400px;width:100%;text-align:center}button[data-v-21ade8c0]{margin-top:20px}

View File

@@ -1 +0,0 @@
form div[data-v-454efcad]{margin-bottom:10px}.uploaded-image[data-v-454efcad]{display:inline-block;margin:0 0 .5em .5em;border:1px solid #e0e0e0;padding:10px}.uploaded-image input[data-v-454efcad],.uploaded-image textarea[data-v-454efcad]{width:100%;margin:5px 0}

View File

@@ -1 +0,0 @@
.service-unavailable[data-v-fd9b1088]{padding:20px}.hint[data-v-fd9b1088]{color:#444;margin-top:1rem}

View File

@@ -1 +0,0 @@
table.worships[data-v-dc6acbe6]{border-collapse:collapse;width:100%}table.worships td[data-v-dc6acbe6]{border:1px solid #000;text-align:center}h3[data-v-dc6acbe6]{margin:0}table.worships td div[data-v-dc6acbe6]{margin:5px}.highlight-time[data-v-dc6acbe6]{text-decoration:underline}.neighborhood-invitation[data-v-dc6acbe6]{font-weight:700;color:#0020e0}a[data-v-dc6acbe6]{color:#0020e0}.internal-information[data-v-dc6acbe6]{color:#e45;font-style:italic}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-a3df5f54]{font-weight:700}.event-table[data-v-a3df5f54]{border-collapse:collapse}.event-table td[data-v-a3df5f54]{border:1px solid #000}.homepage[data-v-a3df5f54]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-a3df5f54]{padding:.5em 0}.event-image>img[data-v-a3df5f54]{max-width:12em;max-height:12em}.contact-box p[data-v-1f5987da]{margin:0}.bottom-margin[data-v-1f5987da]{margin-bottom:1rem}.expiry-date[data-v-1f5987da]{font-size:.9em;color:#666;font-style:italic}span[data-v-2bbf7aa9]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.forgot-password[data-v-017249f5]{max-width:400px;margin:auto}form[data-v-017249f5]{display:flex;flex-direction:column}label[data-v-017249f5]{margin-top:10px}button[data-v-017249f5]{margin-top:20px}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.event-places-management[data-v-920e5ffc]{max-width:600px;margin:auto;padding:20px;border:1px solid #ccc;border-radius:5px}form[data-v-920e5ffc]{display:flex;flex-direction:column;margin-bottom:20px}label[data-v-920e5ffc]{margin-top:10px}input[data-v-920e5ffc]{margin-top:5px;margin-bottom:10px;padding:8px}button[data-v-920e5ffc]{margin-top:10px;padding:10px}table[data-v-920e5ffc]{width:100%;border-collapse:collapse;margin-top:20px}td[data-v-920e5ffc],th[data-v-920e5ffc]{border:1px solid #ccc;padding:10px;text-align:left}th[data-v-920e5ffc]{background-color:#f4f4f4}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
table.worships[data-v-dc6acbe6]{border-collapse:collapse;width:100%}table.worships td[data-v-dc6acbe6]{border:1px solid #000;text-align:center}h3[data-v-dc6acbe6]{margin:0}table.worships td div[data-v-dc6acbe6]{margin:5px}.highlight-time[data-v-dc6acbe6]{text-decoration:underline}.neighborhood-invitation[data-v-dc6acbe6]{font-weight:700;color:#0020e0}a[data-v-dc6acbe6]{color:#0020e0}.internal-information[data-v-dc6acbe6]{color:#e45;font-style:italic}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-a3df5f54]{font-weight:700}.event-table[data-v-a3df5f54]{border-collapse:collapse}.event-table td[data-v-a3df5f54]{border:1px solid #000}.homepage[data-v-a3df5f54]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-a3df5f54]{padding:.5em 0}.event-image>img[data-v-a3df5f54]{max-width:12em;max-height:12em}.contact-box p[data-v-1f5987da]{margin:0}.bottom-margin[data-v-1f5987da]{margin-bottom:1rem}.expiry-date[data-v-1f5987da]{font-size:.9em;color:#666;font-style:italic}span[data-v-2bbf7aa9]{cursor:pointer;color:blue;text-decoration:underline}.previewinfo[data-v-9a71cbf6]{background-color:#000;color:#d00000;position:absolute;top:93px;left:0;padding:2px 10px;font-weight:700}

View File

@@ -1 +0,0 @@
.user-administration[data-v-a495c756]{padding:20px}.user-administration h1[data-v-a495c756],.user-administration h2[data-v-a495c756]{margin-bottom:20px}.user-administration form[data-v-a495c756]{display:flex;flex-direction:column;margin-bottom:20px}.user-administration label[data-v-a495c756]{margin-top:10px}.user-administration input[type=email][data-v-a495c756],.user-administration input[type=password][data-v-a495c756],.user-administration input[type=text][data-v-a495c756]{padding:5px;font-size:16px}.user-administration ul[data-v-a495c756]{list-style-type:none;padding:0}.user-administration li[data-v-a495c756]{padding:10px;border-bottom:1px solid #ddd;cursor:pointer}.user-administration li[data-v-a495c756]:hover{background-color:#f0f0f0}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.impressum[data-v-612786fa]{max-width:800px;margin:auto;padding:20px}h1[data-v-612786fa],h2[data-v-612786fa],h3[data-v-612786fa],h4[data-v-612786fa]{margin-top:20px;color:#333}p[data-v-612786fa]{line-height:1.6}a[data-v-612786fa]{color:#007bff;text-decoration:none}a[data-v-612786fa]:hover{text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.right-column h2[data-v-d1b58e08]{text-align:center;color:#000}.right-column img[data-v-d1b58e08]{display:block;margin:0 auto;max-width:100%;height:auto}

View File

@@ -1 +0,0 @@
table.worships[data-v-0a1907cc]{border-collapse:collapse;width:100%}table.worships td[data-v-0a1907cc]{border:1px solid #000;text-align:center}h3[data-v-0a1907cc]{margin:0}table.worships td div[data-v-0a1907cc]{margin:5px}.highlight-time[data-v-0a1907cc]{text-decoration:underline}.neighborhood-invitation[data-v-0a1907cc]{font-weight:700;color:#0020e0}.image[data-v-9b711a1e]{max-width:400px;max-height:300px}.event-name[data-v-2da2977b]{font-weight:700}.event-table[data-v-2da2977b]{border-collapse:collapse}.event-table td[data-v-2da2977b]{border:1px solid #000}.homepage[data-v-2da2977b]{border:1px solid #9400ff;padding:.5em;text-align:center}.description[data-v-2da2977b]{padding:.5em 0}.contact-box p[data-v-40357d31]{margin:0}span[data-v-fa4cadae]{cursor:pointer;color:blue;text-decoration:underline}

View File

@@ -1 +0,0 @@
.navbar[data-v-47f1407d]{background-color:#9400ff;overflow:visible;min-height:31px;display:inline-flex;flex-direction:column;width:auto;margin:.1em .75em 9px .75em;box-shadow:0 0 2px 5px #9400ff}.menu-toggle[data-v-47f1407d]{background-color:#9400ff;color:#fff;border:none;padding:14px 20px;text-align:center;text-decoration:none;display:none;font-weight:700}.navbar ul[data-v-47f1407d]{list-style-type:none;margin:0;padding:0;display:flex}.navbar li[data-v-47f1407d]{position:relative}.navbar a[data-v-47f1407d],.navbar li>span[data-v-47f1407d]{display:block;color:#fff;text-align:center;padding:6px 20px;text-decoration:none;font-weight:700}.navbar a[data-v-47f1407d]:hover{background-color:#7a00d1}.menu-icon[data-v-47f1407d]{width:20px;height:20px;margin-right:5px}.dropdown-content[data-v-47f1407d]{position:absolute;background-color:#9400ff;min-width:200px;z-index:1;top:100%;left:0;opacity:0;visibility:hidden;transition:opacity .2s ease-in-out,visibility .2s ease-in-out;box-shadow:2px 2px 4px #666}.dropdown-content a[data-v-47f1407d]{color:#fff;padding:12px 16px;text-decoration:none;display:block;text-align:left}.dropdown-content a[data-v-47f1407d]:hover{background-color:#7a00d1}.navbar li:hover .dropdown-content[data-v-47f1407d]{opacity:1;visibility:visible}.fade-enter-active[data-v-47f1407d],.fade-leave-active[data-v-47f1407d]{transition:opacity .2s ease-in-out,visibility .2s ease-in-out}.fade-enter[data-v-47f1407d],.fade-leave-to[data-v-47f1407d]{opacity:0;visibility:hidden}@media (max-width:768px){.navbar ul[data-v-47f1407d],.navbar[data-v-47f1407d]{flex-direction:column}.navbar li[data-v-47f1407d]{width:100%}.navbar a[data-v-47f1407d],.navbar li>span[data-v-47f1407d]{text-align:left;padding:14px 20px}.menu-toggle[data-v-47f1407d]{display:block}.dropdown-content[data-v-47f1407d]{position:static;box-shadow:none;opacity:1;visibility:visible;display:none;padding-left:1em}.navbar li:hover .dropdown-content[data-v-47f1407d]{display:block}}.pointer[data-v-47f1407d]{cursor:pointer}.facettenkreuz[data-v-47f1407d]{max-width:30px;max-height:30px;position:fixed}.ekhnlogo[data-v-47f1407d]{width:32px}header[data-v-4e068f05]{display:flex;flex-direction:column;width:100%;background-color:#fff}.header-title[data-v-4e068f05]{display:flex;align-items:center;justify-content:space-between;width:100%;padding:.3em .5em}header h1[data-v-4e068f05]{margin:0;flex:1;text-align:center;text-shadow:2px 2px 1px #e0bfff;padding-bottom:4px}.reload-icon[data-v-4e068f05]{font-size:16px;cursor:pointer;margin-left:10px;background-color:#e0bfff;color:#fff;padding:5px;border-radius:50%}.reload-icon[data-v-4e068f05]:hover{color:#7a00d1}.footer[data-v-57063e3c]{background-color:#0b1735;bottom:0;left:0;width:100%;padding:7px;justify-content:space-between}.footer[data-v-57063e3c],.left-links[data-v-57063e3c],.right-links[data-v-57063e3c]{display:flex;align-items:center}.footer a[data-v-57063e3c]{color:#fff;padding-right:20px;text-decoration:none}.footer a.login-link[data-v-57063e3c]{color:#444}.footer a.logout-link[data-v-57063e3c]{cursor:pointer}body,html{height:100%;margin:0;padding:0;background-color:#fff;font-family:Arial,sans-serif;width:100%;overflow-x:hidden}#app{display:flex;flex-direction:column;height:100%}.content-section{flex:1;display:flex;color:#000;overflow-y:hidden}.left-column{flex:1;min-width:1000px;margin:.5em 0 .5em .5em;padding-right:.5em;background-color:#fff;overflow-y:auto}.right-column{flex:1;background-color:#d9e2f3;overflow-y:auto;margin:0 7px 7px 0}.right-column h2{text-align:center;color:#000}.right-column img{display:block;margin:0 auto;max-width:100%;height:auto}.right-column-overlay{max-height:150px;overflow-y:hidden;margin-top:10px;background-color:#d9e2f3;display:flex;justify-content:center;align-items:center}.right-column-overlay img{max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain}@media (max-width:1200px){.content-section{flex-direction:column}.left-column{padding:10px}.right-column{display:none}.right-column-overlay{display:flex;max-height:150px;background-color:#fff}.right-column-overlay img{max-height:150px;max-width:100%;-o-object-fit:contain;object-fit:contain}}@media (max-width:767px){.content-section{flex-direction:column}.left-column,.right-column{padding:10px}.right-column{display:none}.right-column-overlay{display:flex}}.htmleditor{background-color:#fff;width:calc(100% - 26px);height:31em;border:1px solid #000;margin:7px;padding:5px;overflow:auto}.htmleditor table{border:1px solid #e0e0e0;border-collapse:collapse}.htmleditor td,.htmleditor th{border:1px solid #e0e0e0}

View File

@@ -1 +0,0 @@
.navbar[data-v-7c384298]{background-color:#9400ff;overflow:visible;height:47px;display:flex;width:100%}.navbar ul[data-v-7c384298]{list-style-type:none;margin:0;padding:0;display:flex}.navbar li[data-v-7c384298]{position:relative}.navbar a[data-v-7c384298],.navbar li>span[data-v-7c384298]{display:block;color:#fff;text-align:center;padding:14px 20px;text-decoration:none;font-weight:700}.navbar a[data-v-7c384298]:hover{background-color:#7a00d1}.menu-icon[data-v-7c384298]{width:20px;height:20px;margin-right:5px}.dropdown-content[data-v-7c384298]{position:absolute;background-color:#9400ff;min-width:200px;z-index:1;top:100%;left:0;opacity:0;visibility:hidden;transition:opacity .2s ease-in-out,visibility .2s ease-in-out;box-shadow:2px 2px 4px #666}.dropdown-content a[data-v-7c384298]{color:#fff;padding:12px 16px;text-decoration:none;display:block;text-align:left}.dropdown-content a[data-v-7c384298]:hover{background-color:#7a00d1}.navbar li:hover .dropdown-content[data-v-7c384298]{opacity:1;visibility:visible}.fade-enter-active[data-v-7c384298],.fade-leave-active[data-v-7c384298]{transition:opacity .2s ease-in-out,visibility .2s ease-in-out}.fade-enter[data-v-7c384298],.fade-leave-to[data-v-7c384298]{opacity:0;visibility:hidden}header[data-v-0a99f72e]{display:flex;flex-direction:column;width:100%;background-color:#e0bfff}.header-title[data-v-0a99f72e]{display:flex;align-items:center;justify-content:space-between;width:100%;padding:.3em .5em}header h1[data-v-0a99f72e]{margin:0}.reload-icon[data-v-0a99f72e]{font-size:16px;cursor:pointer;margin-left:10px;background-color:#e0bfff;color:#fff;padding:5px;border-radius:50%}.reload-icon[data-v-0a99f72e]:hover{color:#7a00d1}.footer[data-v-cc31ea16]{background-color:#0b1735;bottom:0;left:0;width:100%;padding:7px;justify-content:space-between}.footer[data-v-cc31ea16],.left-links[data-v-cc31ea16],.right-links[data-v-cc31ea16]{display:flex;align-items:center}.footer a[data-v-cc31ea16]{color:#fff;padding-right:20px;text-decoration:none}.footer a.login-link[data-v-cc31ea16]{color:#444}.footer a.logout-link[data-v-cc31ea16]{cursor:pointer}body,html{height:100%;margin:0;padding:0;background-color:#fff;font-family:Arial,sans-serif;width:100%;overflow:hidden}#app{display:flex;flex-direction:column;height:100%}.content-section{flex:1;display:flex;color:#000;overflow:hidden}.left-column,.right-column{flex:1;overflow-y:auto}.left-column{margin:.5em 0 .5em .5em;padding-right:.5em;background-color:#fff}.right-column{background-color:#d9e2f3}.right-column h2{text-align:center;color:#000}.right-column img{display:block;margin:0 auto;max-width:100%;height:auto}@media (max-width:768px){.content-section{flex-direction:column}.left-column,.right-column{padding:10px}}.htmleditor{background-color:#fff;width:calc(100% - 26px);height:31em;border:1px solid #000;margin:7px;padding:5px;overflow:auto}.htmleditor table{border:1px solid #e0e0e0;border-collapse:collapse}.htmleditor td,.htmleditor th{border:1px solid #e0e0e0}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

View File

@@ -1 +0,0 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>miriamgemeinde</title><script defer="defer" src="/js/chunk-vendors.a58901d9.js"></script><script defer="defer" src="/js/app.2b3ac443.js"></script><link href="/css/app.c2c4030a.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors.a58901d9.js"></script><script defer="defer" src="/js/app.62331f73.js"></script><link href="/css/app.c2c4030a.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors.a58901d9.js"></script><script defer="defer" src="/js/app.f7f58406.js"></script><link href="/css/app.c2c4030a.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors.b7e76d39.js"></script><script defer="defer" src="/js/app.c50b5429.js"></script><link href="/css/app.3e68accd.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but miriamgemeinde doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[187],{8187:function(e,t,n){n.r(t),n.d(t,{default:function(){return k}});var l=n(641),a=n(3751),i=n(33);const c={class:"event-places-management"},d=["onClick"],o=["onClick"];function r(e,t,n,r,s,u){return(0,l.uX)(),(0,l.CE)("div",c,[t[16]||(t[16]=(0,l.Lk)("h2",null,"Veranstaltungsorte verwalten",-1)),(0,l.Lk)("form",{onSubmit:t[7]||(t[7]=(0,a.D$)((...e)=>u.addEventPlace&&u.addEventPlace(...e),["prevent"]))},[t[8]||(t[8]=(0,l.Lk)("label",{for:"name"},"Name:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"text",id:"name","onUpdate:modelValue":t[0]||(t[0]=e=>s.newEventPlace.name=e),placeholder:"Name",required:""},null,512),[[a.Jo,s.newEventPlace.name]]),t[9]||(t[9]=(0,l.Lk)("label",{for:"street"},"Straße:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"text",id:"street","onUpdate:modelValue":t[1]||(t[1]=e=>s.newEventPlace.street=e),placeholder:"Straße",required:""},null,512),[[a.Jo,s.newEventPlace.street]]),t[10]||(t[10]=(0,l.Lk)("label",{for:"zipcode"},"PLZ:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"text",id:"zipcode","onUpdate:modelValue":t[2]||(t[2]=e=>s.newEventPlace.zipcode=e),placeholder:"PLZ",required:""},null,512),[[a.Jo,s.newEventPlace.zipcode]]),t[11]||(t[11]=(0,l.Lk)("label",{for:"city"},"Stadt:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"text",id:"city","onUpdate:modelValue":t[3]||(t[3]=e=>s.newEventPlace.city=e),placeholder:"Stadt",required:""},null,512),[[a.Jo,s.newEventPlace.city]]),t[12]||(t[12]=(0,l.Lk)("label",{for:"city"},"Webseite:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"text",id:"website","onUpdate:modelValue":t[4]||(t[4]=e=>s.newEventPlace.website=e),placeholder:"Webseite",required:""},null,512),[[a.Jo,s.newEventPlace.website]]),t[13]||(t[13]=(0,l.Lk)("label",{for:"backgroundColor"},"Hintergrundfarbe:",-1)),(0,l.bo)((0,l.Lk)("input",{type:"color",id:"backgroundColor","onUpdate:modelValue":t[5]||(t[5]=e=>s.newEventPlace.backgroundColor=e)},null,512),[[a.Jo,s.newEventPlace.backgroundColor]]),t[14]||(t[14]=(0,l.Lk)("button",{type:"submit"},"Speichern",-1)),s.editMode?((0,l.uX)(),(0,l.CE)("button",{key:0,type:"button",onClick:t[6]||(t[6]=(...e)=>u.resetForm&&u.resetForm(...e))},"Neuen Veranstaltungsort erstellen")):(0,l.Q3)("",!0)],32),(0,l.Lk)("table",null,[t[15]||(t[15]=(0,l.Lk)("thead",null,[(0,l.Lk)("tr",null,[(0,l.Lk)("th",null,"Name"),(0,l.Lk)("th",null,"Bearbeiten"),(0,l.Lk)("th",null,"Löschen")])],-1)),(0,l.Lk)("tbody",null,[((0,l.uX)(!0),(0,l.CE)(l.FK,null,(0,l.pI)(s.eventPlaces,e=>((0,l.uX)(),(0,l.CE)("tr",{key:e.id},[(0,l.Lk)("td",null,(0,i.v_)(e.name),1),(0,l.Lk)("td",null,[(0,l.Lk)("button",{onClick:t=>u.editEventPlace(e)},"Bearbeiten",8,d)]),(0,l.Lk)("td",null,[(0,l.Lk)("button",{onClick:t=>u.deleteEventPlace(e.id)},"Löschen",8,o)])]))),128))])])])}n(4114);var s=n(4335),u={data(){return{eventPlaces:[],newEventPlace:{name:"",street:"",zipcode:"",city:"",backgroundColor:"#ffffff",website:""},editMode:!1,editId:null}},methods:{async fetchEventPlaces(){const e=await s.A.get("/event-places");this.eventPlaces=e.data},async addEventPlace(){if(this.editMode)await s.A.put(`/event-places/${this.editId}`,this.newEventPlace);else{const e=await s.A.post("/event-places",this.newEventPlace);this.eventPlaces.push(e.data)}this.resetForm(),await this.fetchEventPlaces()},async updateEventPlace(e){await s.A.put(`/event-places/${e.id}`,e),this.fetchEventPlaces()},async deleteEventPlace(e){await s.A.delete(`/event-places/${e}`),this.fetchEventPlaces()},editEventPlace(e){this.newEventPlace={...e},this.editMode=!0,this.editId=e.id},resetForm(){this.newEventPlace={name:"",street:"",zipcode:"",city:"",backgroundColor:"#ffffff",website:""},this.editMode=!1,this.editId=null}},created(){this.fetchEventPlaces()}},p=n(6262);const v=(0,p.A)(u,[["render",r],["__scopeId","data-v-4e6631f7"]]);var k=v}}]);
//# sourceMappingURL=187.80c77f03.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[23],{116:function(e,n,t){var r=t(6518),u=t(9565),i=t(2652),a=t(9306),l=t(8551),o=t(1767),d=t(9539),c=t(4549),s=c("find",TypeError);r({target:"Iterator",proto:!0,real:!0,forced:s},{find:function(e){l(this);try{a(e)}catch(r){d(this,"throw",r)}if(s)return u(s,this,e);var n=o(this),t=0;return i(n,function(n,r){if(e(n,t++))return r(n)},{IS_RECORD:!0,INTERRUPTED:!0}).result}})},2023:function(e,n,t){t.r(n),t.d(n,{default:function(){return s}});var r=t(641),u=t(33);function i(e,n,t,i,a,l){const o=(0,r.g2)("router-link");return(0,r.uX)(),(0,r.CE)("div",null,[n[0]||(n[0]=(0,r.Lk)("h1",null,"Seitenpflege",-1)),n[1]||(n[1]=(0,r.Lk)("p",null,"Herzlich Willkommen. Auf diesen Seiten können Sie die Inhalte der Webseiten pflegen.",-1)),(0,r.Lk)("ul",null,[((0,r.uX)(!0),(0,r.CE)(r.FK,null,(0,r.pI)(i.adminSubmenu,e=>((0,r.uX)(),(0,r.CE)("li",{key:e.id},[(0,r.bF)(o,{to:e.link},{default:(0,r.k6)(()=>[(0,r.eW)((0,u.v_)(e.name),1)]),_:2},1032,["to"])]))),128))])])}t(8111),t(116);var a=t(6296),l=t(953),o={name:"DefaultComponent",setup(){const e=(0,l.KR)([]),n=async()=>{try{const n=await a.A.get("/menu-data"),t=n.data,r=t.find(e=>"Admin"===e.name);r&&(e.value=r.submenu)}catch(n){console.error("Fehler beim Abrufen der Menü-Daten:",n)}};return(0,r.sV)(()=>{n()}),{adminSubmenu:e}}},d=t(6262);const c=(0,d.A)(o,[["render",i],["__scopeId","data-v-68b32234"]]);var s=c}}]);
//# sourceMappingURL=23.33b1e241.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[246],{6246:function(e,t,n){n.r(t),n.d(t,{default:function(){return h}});var i=n(641),a=n(3751),s=n(33);const p={class:"event-types-management"},r={type:"submit"},d=["onClick"],o=["onClick"];function y(e,t,n,y,l,v){return(0,i.uX)(),(0,i.CE)("div",p,[t[4]||(t[4]=(0,i.Lk)("h2",null,"Event-Typen Verwaltung",-1)),(0,i.Lk)("form",{onSubmit:t[2]||(t[2]=(0,a.D$)((...e)=>v.saveEventType&&v.saveEventType(...e),["prevent"]))},[t[3]||(t[3]=(0,i.Lk)("label",{for:"newEventType"},"Event-Typ:",-1)),(0,i.bo)((0,i.Lk)("input",{type:"text",id:"newEventType","onUpdate:modelValue":t[0]||(t[0]=e=>l.eventTypeData.caption=e),placeholder:"Event-Typ",required:""},null,512),[[a.Jo,l.eventTypeData.caption]]),(0,i.Lk)("button",r,(0,s.v_)(l.editMode?"Aktualisieren":"Hinzufügen"),1),l.editMode?((0,i.uX)(),(0,i.CE)("button",{key:0,type:"button",onClick:t[1]||(t[1]=(...e)=>v.resetForm&&v.resetForm(...e))},"Abbrechen")):(0,i.Q3)("",!0)],32),(0,i.Lk)("table",null,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(l.eventTypes,e=>((0,i.uX)(),(0,i.CE)("tr",{key:e.id},[(0,i.Lk)("td",null,(0,s.v_)(e.caption),1),(0,i.Lk)("td",null,[(0,i.Lk)("button",{onClick:t=>v.editEventType(e)},"Bearbeiten",8,d)]),(0,i.Lk)("td",null,[(0,i.Lk)("button",{onClick:t=>v.deleteEventType(e.id)},"Löschen",8,o)])]))),128))])])}n(4114);var l=n(4335),v={data(){return{eventTypes:[],eventTypeData:{caption:""},editMode:!1,editId:null}},methods:{async fetchEventTypes(){try{const e=await l.A.get("/event-types");this.eventTypes=e.data}catch(e){console.error("Fehler beim Abrufen der Event-Typen:",e)}},async saveEventType(){try{if(this.editMode)await l.A.put(`/event-types/${this.editId}`,this.eventTypeData);else{const e=await l.A.post("/event-types",this.eventTypeData);this.eventTypes.push(e.data)}this.resetForm(),await this.fetchEventTypes()}catch(e){console.error("Fehler beim Speichern des Event-Typs:",e)}},editEventType(e){this.eventTypeData={...e},this.editMode=!0,this.editId=e.id},async deleteEventType(e){try{await l.A.delete(`/event-types/${e}`),await this.fetchEventTypes()}catch(t){console.error("Fehler beim Löschen des Event-Typs:",t)}},resetForm(){this.eventTypeData={caption:""},this.editMode=!1,this.editId=null}},async created(){await this.fetchEventTypes()}},c=n(6262);const u=(0,c.A)(v,[["render",y],["__scopeId","data-v-60fe58a4"]]);var h=u}}]);
//# sourceMappingURL=246.96a28aca.js.map

Some files were not shown because too many files have changed in this diff Show More