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.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
224
docs/DESIGN-UND-BEDIENBARKEIT-KONZEPT.md
Normal file
224
docs/DESIGN-UND-BEDIENBARKEIT-KONZEPT.md
Normal 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 3–6 % 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.75–2rem` |
|
||||
| H2 | Abschnitte | `1.35–1.5rem` |
|
||||
| H3 | Unterabschnitte | `1.15–1.25rem` |
|
||||
| Body | Fließtext | `1rem`, Zeilenlänge max. ca. 65–75 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:** < 640px – eine Spalte, Navigation als klares Overlay oder ausklappbare Liste mit großen Touch-Zielen.
|
||||
- **Tablet:** 640–1024px – ggf. weiterhin eine Spalte oder kompakte Sidebar.
|
||||
- **Desktop:** > 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** (< 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 2–3 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.*
|
||||
@@ -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 &&
|
||||
|
||||
1
public/css/285.0c1baa6a.css
Normal file
1
public/css/285.0c1baa6a.css
Normal file
File diff suppressed because one or more lines are too long
1
public/css/600.5ca39395.css
Normal file
1
public/css/600.5ca39395.css
Normal file
@@ -0,0 +1 @@
|
||||
.menu-management[data-v-0d38d21e]{width:100%;margin:auto}.button-container[data-v-0d38d21e]{display:inline-flex;gap:10px;margin-bottom:20px}.tree-view[data-v-0d38d21e]{margin-top:20px}.tree-view ul[data-v-0d38d21e]{list-style-type:none;padding:0}.tree-view li[data-v-0d38d21e]{margin-bottom:5px;padding-left:20px}.tree-view .menu-item[data-v-0d38d21e]{display:inline-flex;width:100%;justify-content:space-between;align-items:center}.tree-view span[data-v-0d38d21e]{cursor:pointer;color:#000}.tree-view button[data-v-0d38d21e]{border:none;height:1.6em;padding:0 .5em;margin:1px;border-radius:5px}.tree-view span[data-v-0d38d21e]:hover{text-decoration:underline}.edit-form[data-v-0d38d21e]{margin-top:20px}.edit-form label[data-v-0d38d21e]{display:block;margin-bottom:5px;font-weight:700}.edit-form input[data-v-0d38d21e]:not([type=checkbox]){display:block;margin-bottom:10px}.edit-form .checkbox-container[data-v-0d38d21e]{display:flex;flex-direction:column;margin-right:10px}.edit-form .order-id[data-v-0d38d21e]{width:50px}.edit-form button[data-v-0d38d21e]{margin-top:5px}
|
||||
1
public/css/93.ef0b6f4a.css
Normal file
1
public/css/93.ef0b6f4a.css
Normal file
File diff suppressed because one or more lines are too long
1
public/css/app.43dcf86b.css
Normal file
1
public/css/app.43dcf86b.css
Normal file
File diff suppressed because one or more lines are too long
1
public/css/app.674aab9c.css
Normal file
1
public/css/app.674aab9c.css
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
<!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>
|
||||
<!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"><script defer="defer" src="/js/chunk-vendors.b7e76d39.js"></script><script defer="defer" src="/js/app.53c460b9.js"></script><link href="/css/app.43dcf86b.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors.b7e76d39.js"></script><script defer="defer" src="/js/app.e71748c3.js"></script><link href="/css/app.43dcf86b.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors.2da008aa.js"></script><script defer="defer" src="/js/app.e009cb77.js"></script><link href="/css/app.674aab9c.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>
|
||||
2
public/js/119.a9a1cb97.js
Normal file
2
public/js/119.a9a1cb97.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/119.a9a1cb97.js.map
Normal file
1
public/js/119.a9a1cb97.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/187.bdfdd8d0.js
Normal file
2
public/js/187.bdfdd8d0.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"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.bdfdd8d0.js.map
|
||||
1
public/js/187.bdfdd8d0.js.map
Normal file
1
public/js/187.bdfdd8d0.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/23.0a6b6bcd.js
Normal file
2
public/js/23.0a6b6bcd.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"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.0a6b6bcd.js.map
|
||||
1
public/js/23.0a6b6bcd.js.map
Normal file
1
public/js/23.0a6b6bcd.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/246.5b0c0fa9.js
Normal file
2
public/js/246.5b0c0fa9.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"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.5b0c0fa9.js.map
|
||||
1
public/js/246.5b0c0fa9.js.map
Normal file
1
public/js/246.5b0c0fa9.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/285.6923f681.js
Normal file
2
public/js/285.6923f681.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/285.6923f681.js.map
Normal file
1
public/js/285.6923f681.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/285.8dce7f6a.js
Normal file
2
public/js/285.8dce7f6a.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/285.8dce7f6a.js.map
Normal file
1
public/js/285.8dce7f6a.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/324.b84a9462.js
Normal file
2
public/js/324.b84a9462.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[324],{1324:function(e,i,s){s.r(i),s.d(i,{default:function(){return k}});var a=s(641),t=s(3751),o=s(33);const l={class:"forgot-password"},n={key:0,class:"dialog"},r={class:"dialog-content"};function d(e,i,s,d,g,u){const m=(0,a.g2)("router-link");return(0,a.uX)(),(0,a.CE)("div",l,[i[7]||(i[7]=(0,a.Lk)("h2",null,"Passwort vergessen",-1)),(0,a.Lk)("form",{onSubmit:i[1]||(i[1]=(0,t.D$)((...e)=>u.submitForgotPassword&&u.submitForgotPassword(...e),["prevent"]))},[i[3]||(i[3]=(0,a.Lk)("label",{for:"email"},"Email-Adresse:",-1)),(0,a.bo)((0,a.Lk)("input",{type:"email",id:"email","onUpdate:modelValue":i[0]||(i[0]=e=>g.email=e),required:""},null,512),[[t.Jo,g.email]]),i[4]||(i[4]=(0,a.Lk)("button",{type:"submit"},"Link zum Zurücksetzen senden",-1))],32),(0,a.Lk)("p",null,[(0,a.bF)(m,{to:"/login"},{default:(0,a.k6)(()=>[...i[5]||(i[5]=[(0,a.eW)("Login",-1)])]),_:1})]),(0,a.Lk)("p",null,[(0,a.bF)(m,{to:"/register"},{default:(0,a.k6)(()=>[...i[6]||(i[6]=[(0,a.eW)("Registrieren",-1)])]),_:1})]),g.dialogVisible?((0,a.uX)(),(0,a.CE)("div",n,[(0,a.Lk)("div",r,[(0,a.Lk)("h3",null,(0,o.v_)(g.dialogTitle),1),(0,a.Lk)("p",null,(0,o.v_)(g.dialogMessage),1),(0,a.Lk)("button",{type:"button",onClick:i[2]||(i[2]=(...e)=>u.closeDialog&&u.closeDialog(...e))},"Schließen")])])):(0,a.Q3)("",!0)])}var g=s(6296),u={name:"ForgotPassword",data(){return{email:"",dialogTitle:"",dialogMessage:"",dialogVisible:!1}},methods:{async submitForgotPassword(){try{const e=await g.A.post("/auth/forgot-password",{email:this.email});this.showDialog("E-Mail gesendet",e.data?.message||"Ein Link zum Zurücksetzen wurde an Ihre E-Mail-Adresse gesendet."),this.email=""}catch(e){const i=e?.response?.data?.message||e?.message||"Ein unbekannter Fehler ist aufgetreten";this.showDialog("Fehler",i)}},showDialog(e,i){this.dialogTitle=e,this.dialogMessage=i,this.dialogVisible=!0},closeDialog(){this.dialogVisible=!1}}},m=s(6262);const c=(0,m.A)(u,[["render",d],["__scopeId","data-v-c694cf4e"]]);var k=c}}]);
|
||||
//# sourceMappingURL=324.b84a9462.js.map
|
||||
1
public/js/324.b84a9462.js.map
Normal file
1
public/js/324.b84a9462.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/355.97e174a9.js
Normal file
2
public/js/355.97e174a9.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[355],{5355:function(e,l,t){t.r(l),t.d(l,{default:function(){return c}});var i=t(641),a=t(33);const o={key:0,class:"dialog-overlay"},n={class:"dialog"};function s(e,l,t,s,r,u){return t.modelValue?((0,i.uX)(),(0,i.CE)("div",o,[(0,i.Lk)("div",n,[(0,i.Lk)("h2",null,(0,a.v_)(t.title),1),(0,i.Lk)("p",null,(0,a.v_)(t.message),1),(0,i.Lk)("button",{onClick:l[0]||(l[0]=(...e)=>u.closeDialog&&u.closeDialog(...e))},"OK")])])):(0,i.Q3)("",!0)}var r={name:"DialogComponent",props:{title:{type:String,required:!0},message:{type:String,required:!0},modelValue:{type:Boolean,default:!1}},methods:{closeDialog(){this.$emit("update:modelValue",!1),this.$emit("close")}}},u=t(6262);const d=(0,u.A)(r,[["render",s],["__scopeId","data-v-ce9d9498"]]);var c=d}}]);
|
||||
//# sourceMappingURL=355.97e174a9.js.map
|
||||
1
public/js/355.97e174a9.js.map
Normal file
1
public/js/355.97e174a9.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"js/355.97e174a9.js","mappings":"4MACyBA,MAAM,kB,GACtBA,MAAM,U,+BADFC,EAAAC,a,WAAXC,EAAAA,EAAAA,IAMM,MANNC,EAMM,EALJC,EAAAA,EAAAA,IAIM,MAJNC,EAIM,EAHJD,EAAAA,EAAAA,IAAoB,WAAAE,EAAAA,EAAAA,IAAbN,EAAAO,OAAK,IACZH,EAAAA,EAAAA,IAAoB,UAAAE,EAAAA,EAAAA,IAAdN,EAAAQ,SAAO,IACbJ,EAAAA,EAAAA,IAAwC,UAA/BK,QAAKC,EAAA,KAAAA,EAAA,OAAAC,IAAEC,EAAAC,aAAAD,EAAAC,eAAAF,KAAa,Y,eAMnC,OACEG,KAAM,kBACNC,MAAO,CACLR,MAAO,CACLS,KAAMC,OACNC,UAAU,GAEZV,QAAS,CACPQ,KAAMC,OACNC,UAAU,GAEZjB,WAAY,CACVe,KAAMG,QACNC,SAAS,IAGbC,QAAS,CACPR,WAAAA,GACES,KAAKC,MAAM,qBAAqB,GAChCD,KAAKC,MAAM,QACb,I,UCxBJ,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,GAAQ,CAAC,YAAY,qBAEzF,O","sources":["webpack://miriamgemeinde/./src/common/components/DialogComponent.vue","webpack://miriamgemeinde/./src/common/components/DialogComponent.vue?92fc"],"sourcesContent":["<template>\n <div v-if=\"modelValue\" class=\"dialog-overlay\">\n <div class=\"dialog\">\n <h2>{{ title }}</h2>\n <p>{{ message }}</p>\n <button @click=\"closeDialog\">OK</button>\n </div>\n </div>\n</template>\n\n<script>\nexport default {\n name: 'DialogComponent',\n props: {\n title: {\n type: String,\n required: true\n },\n message: {\n type: String,\n required: true\n },\n modelValue: {\n type: Boolean,\n default: false\n }\n },\n methods: {\n closeDialog() {\n this.$emit('update:modelValue', false);\n this.$emit('close');\n }\n }\n};\n</script>\n\n<style scoped>\n.dialog-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n\n.dialog {\n background: white;\n padding: 30px;\n border-radius: 8px;\n max-width: 400px;\n width: 90%;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n.dialog h2 {\n margin-top: 0;\n margin-bottom: 15px;\n color: #333;\n font-size: 20px;\n}\n\n.dialog p {\n margin: 15px 0;\n color: #666;\n line-height: 1.5;\n}\n\n.dialog button {\n margin-top: 20px;\n padding: 10px 20px;\n background-color: #007BFF;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 16px;\n}\n\n.dialog button:hover {\n background-color: #0056b3;\n}\n</style>","import { render } from \"./DialogComponent.vue?vue&type=template&id=ce9d9498&scoped=true\"\nimport script from \"./DialogComponent.vue?vue&type=script&lang=js\"\nexport * from \"./DialogComponent.vue?vue&type=script&lang=js\"\n\nimport \"./DialogComponent.vue?vue&type=style&index=0&id=ce9d9498&scoped=true&lang=css\"\n\nimport exportComponent from \"../../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-ce9d9498\"]])\n\nexport default __exports__"],"names":["class","$props","modelValue","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString","title","message","onClick","_cache","args","$options","closeDialog","name","props","type","String","required","Boolean","default","methods","this","$emit","__exports__","render"],"ignoreList":[],"sourceRoot":""}
|
||||
2
public/js/404.e9108d34.js
Normal file
2
public/js/404.e9108d34.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[404],{3023:function(t,e,i){i.r(e),i.d(e,{default:function(){return p}});var n=i(641),o=i(3751),a=i(33);const s={class:"institution-management"},u=["onClick"],l=["onClick"];function r(t,e,i,r,d,c){return(0,n.uX)(),(0,n.CE)("div",s,[e[18]||(e[18]=(0,n.Lk)("h2",null,"Institutionenverwaltung",-1)),(0,n.Lk)("form",{onSubmit:e[8]||(e[8]=(0,o.D$)((...t)=>c.saveInstitution&&c.saveInstitution(...t),["prevent"]))},[e[9]||(e[9]=(0,n.Lk)("label",{for:"name"},"Name:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"name","onUpdate:modelValue":e[0]||(e[0]=t=>d.institutionData.name=t),required:""},null,512),[[o.Jo,d.institutionData.name]]),e[10]||(e[10]=(0,n.Lk)("label",{for:"street"},"Straße:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"street","onUpdate:modelValue":e[1]||(e[1]=t=>d.institutionData.street=t)},null,512),[[o.Jo,d.institutionData.street]]),e[11]||(e[11]=(0,n.Lk)("label",{for:"zipcode"},"PLZ:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"zipcode","onUpdate:modelValue":e[2]||(e[2]=t=>d.institutionData.zipcode=t)},null,512),[[o.Jo,d.institutionData.zipcode]]),e[12]||(e[12]=(0,n.Lk)("label",{for:"city"},"Stadt:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"city","onUpdate:modelValue":e[3]||(e[3]=t=>d.institutionData.city=t)},null,512),[[o.Jo,d.institutionData.city]]),e[13]||(e[13]=(0,n.Lk)("label",{for:"phone"},"Telefon:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"phone","onUpdate:modelValue":e[4]||(e[4]=t=>d.institutionData.phone=t)},null,512),[[o.Jo,d.institutionData.phone]]),e[14]||(e[14]=(0,n.Lk)("label",{for:"fax"},"Fax:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"fax","onUpdate:modelValue":e[5]||(e[5]=t=>d.institutionData.fax=t)},null,512),[[o.Jo,d.institutionData.fax]]),e[15]||(e[15]=(0,n.Lk)("label",{for:"email"},"Email:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"email",id:"email","onUpdate:modelValue":e[6]||(e[6]=t=>d.institutionData.email=t)},null,512),[[o.Jo,d.institutionData.email]]),e[16]||(e[16]=(0,n.Lk)("button",{type:"submit"},"Speichern",-1)),d.editMode?((0,n.uX)(),(0,n.CE)("button",{key:0,type:"button",onClick:e[7]||(e[7]=(...t)=>c.resetForm&&c.resetForm(...t))},"Neue Institution erstellen")):(0,n.Q3)("",!0)],32),(0,n.Lk)("table",null,[e[17]||(e[17]=(0,n.Lk)("thead",null,[(0,n.Lk)("tr",null,[(0,n.Lk)("th",null,"Name"),(0,n.Lk)("th",null,"Bearbeiten"),(0,n.Lk)("th",null,"Löschen")])],-1)),(0,n.Lk)("tbody",null,[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(d.institutions,t=>((0,n.uX)(),(0,n.CE)("tr",{key:t.id},[(0,n.Lk)("td",null,(0,a.v_)(t.name),1),(0,n.Lk)("td",null,[(0,n.Lk)("button",{onClick:e=>c.editInstitution(t)},"Bearbeiten",8,u)]),(0,n.Lk)("td",null,[(0,n.Lk)("button",{onClick:e=>c.deleteInstitution(t.id)},"Löschen",8,l)])]))),128))])])])}i(4114);var d=i(4335),c={name:"InstitutionManagement",data(){return{institutions:[],contactPersons:[],institutionData:{name:"",street:"",zipcode:"",city:"",phone:"",fax:"",email:""},selectedInstitution:null,showForm:!1,editMode:!1,editId:null}},created(){this.fetchInstitutions(),this.fetchContactPersons()},methods:{async fetchInstitutions(){try{const t=await d.A.get("/institutions");this.institutions=t.data}catch(t){console.error("Fehler beim Abrufen der Institutionen:",t)}},async fetchContactPersons(){try{const t=await d.A.get("/contact-persons");this.contactPersons=t.data}catch(t){console.error("Fehler beim Abrufen der Kontaktpersonen:",t)}},async saveInstitution(){try{if(this.editMode)await d.A.put(`/institutions/${this.editId}`,this.institutionData);else{const t=await d.A.post("/institutions",this.institutionData);this.institutions.push(t.data)}this.resetForm(),await this.fetchInstitutions()}catch(t){console.error("Fehler beim Speichern der Institution:",t)}},editInstitution(t){this.institutionData={...t},this.editMode=!0,this.editId=t.id,this.showForm=!0},async deleteInstitution(t){try{await d.A.delete(`/institutions/${t}`),this.fetchInstitutions()}catch(e){console.error("Fehler beim Löschen der Institution:",e)}},resetForm(){this.institutionData={name:"",street:"",zipcode:"",city:"",phone:"",fax:"",email:""},this.editMode=!1,this.editId=null,this.showForm=!1},showCreateForm(){this.resetForm(),this.showForm=!0}}},h=i(6262);const m=(0,h.A)(c,[["render",r],["__scopeId","data-v-ff992c44"]]);var p=m}}]);
|
||||
//# sourceMappingURL=404.e9108d34.js.map
|
||||
1
public/js/404.e9108d34.js.map
Normal file
1
public/js/404.e9108d34.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/414.8f14a21f.js
Normal file
2
public/js/414.8f14a21f.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/414.8f14a21f.js.map
Normal file
1
public/js/414.8f14a21f.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/423.408d1494.js
Normal file
2
public/js/423.408d1494.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[423],{1423:function(e,s,t){t.r(s),t.d(s,{default:function(){return m}});var o=t(641),i=t(3751),a=t(33);const n={class:"reset-password"},r=["disabled"],l={key:0,class:"dialog"},d={class:"dialog-content"};function u(e,s,t,u,h,c){const g=(0,o.g2)("router-link");return(0,o.uX)(),(0,o.CE)("div",n,[s[7]||(s[7]=(0,o.Lk)("h2",null,"Neues Passwort setzen",-1)),(0,o.Lk)("form",{onSubmit:s[2]||(s[2]=(0,i.D$)((...e)=>c.submitResetPassword&&c.submitResetPassword(...e),["prevent"]))},[s[4]||(s[4]=(0,o.Lk)("label",{for:"password"},"Neues Passwort:",-1)),(0,o.bo)((0,o.Lk)("input",{type:"password",id:"password","onUpdate:modelValue":s[0]||(s[0]=e=>h.password=e),required:"",minlength:"6"},null,512),[[i.Jo,h.password]]),s[5]||(s[5]=(0,o.Lk)("label",{for:"confirmPassword"},"Passwort bestätigen:",-1)),(0,o.bo)((0,o.Lk)("input",{type:"password",id:"confirmPassword","onUpdate:modelValue":s[1]||(s[1]=e=>h.confirmPassword=e),required:"",minlength:"6"},null,512),[[i.Jo,h.confirmPassword]]),(0,o.Lk)("button",{type:"submit",disabled:!c.isFormValid},"Passwort zurücksetzen",8,r)],32),(0,o.Lk)("p",null,[(0,o.bF)(g,{to:"/login"},{default:(0,o.k6)(()=>[...s[6]||(s[6]=[(0,o.eW)("Zurück zum Login",-1)])]),_:1})]),h.dialogVisible?((0,o.uX)(),(0,o.CE)("div",l,[(0,o.Lk)("div",d,[(0,o.Lk)("h3",null,(0,a.v_)(h.dialogTitle),1),(0,o.Lk)("p",null,(0,a.v_)(h.dialogMessage),1),(0,o.Lk)("button",{type:"button",onClick:s[3]||(s[3]=(...e)=>c.closeDialog&&c.closeDialog(...e))},"Schließen")])])):(0,o.Q3)("",!0)])}t(4114),t(4603),t(7566),t(8721);var h=t(6296),c={name:"ResetPasswordComponent",data(){return{password:"",confirmPassword:"",token:"",dialogTitle:"",dialogMessage:"",dialogVisible:!1}},computed:{isFormValid(){return this.password.length>=6&&this.password===this.confirmPassword&&this.token}},mounted(){const e=new URLSearchParams(window.location.search);this.token=e.get("token"),this.token||this.showDialog("Fehler","Ungültiger Reset-Link. Bitte fordern Sie einen neuen Link an.")},methods:{async submitResetPassword(){if(this.password===this.confirmPassword)try{const e=await h.A.post("/auth/reset-password",{token:this.token,password:this.password});this.showDialog("Erfolg",e.data?.message||"Passwort erfolgreich zurückgesetzt. Sie können sich jetzt anmelden."),this.password="",this.confirmPassword="",setTimeout(()=>{this.$router.push("/auth/login")},3e3)}catch(e){const s=e?.response?.data?.message||e?.message||"Ein unbekannter Fehler ist aufgetreten";this.showDialog("Fehler",s)}else this.showDialog("Fehler","Die Passwörter stimmen nicht überein.")},showDialog(e,s){this.dialogTitle=e,this.dialogMessage=s,this.dialogVisible=!0},closeDialog(){this.dialogVisible=!1}}},g=t(6262);const w=(0,g.A)(c,[["render",u],["__scopeId","data-v-e49a033c"]]);var m=w},2812:function(e){var s=TypeError;e.exports=function(e,t){if(e<t)throw new s("Not enough arguments");return e}},4603:function(e,s,t){var o=t(6840),i=t(9504),a=t(655),n=t(2812),r=URLSearchParams,l=r.prototype,d=i(l.append),u=i(l["delete"]),h=i(l.forEach),c=i([].push),g=new r("a=1&a=2&b=3");g["delete"]("a",1),g["delete"]("b",void 0),g+""!=="a=2"&&o(l,"delete",function(e){var s=arguments.length,t=s<2?void 0:arguments[1];if(s&&void 0===t)return u(this,e);var o=[];h(this,function(e,s){c(o,{key:s,value:e})}),n(s,1);var i,r=a(e),l=a(t),g=0,w=0,m=!1,p=o.length;while(g<p)i=o[g++],m||i.key===r?(m=!0,u(this,i.key)):w++;while(w<p)i=o[w++],i.key===r&&i.value===l||d(this,i.key,i.value)},{enumerable:!0,unsafe:!0})},7566:function(e,s,t){var o=t(6840),i=t(9504),a=t(655),n=t(2812),r=URLSearchParams,l=r.prototype,d=i(l.getAll),u=i(l.has),h=new r("a=1");!h.has("a",2)&&h.has("a",void 0)||o(l,"has",function(e){var s=arguments.length,t=s<2?void 0:arguments[1];if(s&&void 0===t)return u(this,e);var o=d(this,e);n(s,1);var i=a(t),r=0;while(r<o.length)if(o[r++]===i)return!0;return!1},{enumerable:!0,unsafe:!0})},8721:function(e,s,t){var o=t(3724),i=t(9504),a=t(2106),n=URLSearchParams.prototype,r=i(n.forEach);o&&!("size"in n)&&a(n,"size",{get:function(){var e=0;return r(this,function(){e++}),e},configurable:!0,enumerable:!0})}}]);
|
||||
//# sourceMappingURL=423.408d1494.js.map
|
||||
1
public/js/423.408d1494.js.map
Normal file
1
public/js/423.408d1494.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/441.ef14f2c9.js
Normal file
2
public/js/441.ef14f2c9.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[441],{3441:function(t,i,e){e.r(i),e.d(i,{default:function(){return k}});var n=e(641),o=e(3751),s=e(33);const l={class:"position-management"},d=["onClick"],a=["onClick"];function u(t,i,e,u,c,h){return(0,n.uX)(),(0,n.CE)("div",l,[i[6]||(i[6]=(0,n.Lk)("h2",null,"Verwalten der Rollen",-1)),(0,n.Lk)("form",{onSubmit:i[2]||(i[2]=(0,o.D$)((...t)=>h.addPosition&&h.addPosition(...t),["prevent"]))},[i[3]||(i[3]=(0,n.Lk)("label",{for:"caption"},"Rollenbezeichnung:",-1)),(0,n.bo)((0,n.Lk)("input",{type:"text",id:"caption","onUpdate:modelValue":i[0]||(i[0]=t=>c.newPosition.caption=t),placeholder:"Rollenbezeichnung",required:""},null,512),[[o.Jo,c.newPosition.caption]]),i[4]||(i[4]=(0,n.Lk)("button",{type:"submit"},"Speichern",-1)),c.editMode?((0,n.uX)(),(0,n.CE)("button",{key:0,type:"button",onClick:i[1]||(i[1]=(...t)=>h.resetForm&&h.resetForm(...t))},"Neue Rolle erstellen")):(0,n.Q3)("",!0)],32),(0,n.Lk)("table",null,[i[5]||(i[5]=(0,n.Lk)("thead",null,[(0,n.Lk)("tr",null,[(0,n.Lk)("th",null,"Rollenbezeichnung"),(0,n.Lk)("th",null,"Bearbeiten"),(0,n.Lk)("th",null,"Löschen")])],-1)),(0,n.Lk)("tbody",null,[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(c.positions,t=>((0,n.uX)(),(0,n.CE)("tr",{key:t.id},[(0,n.Lk)("td",null,(0,s.v_)(t.caption),1),(0,n.Lk)("td",null,[(0,n.Lk)("button",{onClick:i=>h.editPosition(t)},"Bearbeiten",8,d)]),(0,n.Lk)("td",null,[(0,n.Lk)("button",{onClick:i=>h.deletePosition(t.id)},"Löschen",8,a)])]))),128))])])])}e(4114);var c=e(4335),h={data(){return{positions:[],newPosition:{caption:""},editMode:!1,editId:null}},methods:{async fetchPositions(){const t=await c.A.get("/positions");this.positions=t.data},async addPosition(){if(this.editMode)await c.A.put(`/positions/${this.editId}`,this.newPosition);else{const t=await c.A.post("/positions",this.newPosition);this.positions.push(t.data)}this.resetForm(),await this.fetchPositions()},async updatePosition(t){await c.A.put(`/positions/${t.id}`,t),this.fetchPositions()},async deletePosition(t){await c.A.delete(`/positions/${t}`),this.fetchPositions()},editPosition(t){this.newPosition={...t},this.editMode=!0,this.editId=t.id},resetForm(){this.newPosition={caption:""},this.editMode=!1,this.editId=null}},created(){this.fetchPositions()}},r=e(6262);const p=(0,r.A)(h,[["render",u],["__scopeId","data-v-1684a375"]]);var k=p}}]);
|
||||
//# sourceMappingURL=441.ef14f2c9.js.map
|
||||
1
public/js/441.ef14f2c9.js.map
Normal file
1
public/js/441.ef14f2c9.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/446.a766133d.js
Normal file
2
public/js/446.a766133d.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[446],{446:function(e,a,l){l.r(a),l.d(a,{default:function(){return w}});var t=l(641),n=l(3751),i=l(33);const o={class:"upload-files"},r={class:"file-list"},u={class:"file-info"},d=["onClick"],s=["onClick"],c={class:"file-date"};function f(e,a,l,f,h,p){return(0,t.uX)(),(0,t.CE)("div",o,[a[5]||(a[5]=(0,t.Lk)("h2",null,"Dateien hochladen",-1)),(0,t.Lk)("div",null,[a[3]||(a[3]=(0,t.Lk)("label",{for:"file-upload"},"Datei auswählen:",-1)),(0,t.Lk)("input",{id:"file-upload",type:"file",onChange:a[0]||(a[0]=(...e)=>f.handleFileUpload&&f.handleFileUpload(...e))},null,32)]),(0,t.Lk)("div",null,[a[4]||(a[4]=(0,t.Lk)("label",{for:"file-title"},"Titel eingeben:",-1)),(0,t.bo)((0,t.Lk)("input",{id:"file-title",type:"text","onUpdate:modelValue":a[1]||(a[1]=e=>f.fileTitle=e)},null,512),[[n.Jo,f.fileTitle]])]),(0,t.Lk)("button",{onClick:a[2]||(a[2]=(...e)=>f.uploadFiles&&f.uploadFiles(...e))},"Hochladen"),(0,t.Lk)("ul",r,[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(f.uploadedFiles,e=>((0,t.uX)(),(0,t.CE)("li",{key:e.id},[(0,t.Lk)("div",u,[(0,t.Lk)("span",{class:"file-title",onClick:a=>f.downloadFile(e)},(0,i.v_)(e.title),9,d),(0,t.Lk)("span",{class:"file-name",onClick:a=>f.downloadFile(e)},(0,i.v_)(e.originalName),9,s),(0,t.Lk)("span",c,(0,i.v_)(f.formatDate(e.createdAt)),1)])]))),128))])])}l(4114),l(4603),l(7566),l(8721);var h=l(953),p=l(6296),v={name:"UploadFilesComponent",setup(){const e=(0,h.KR)(null),a=(0,h.KR)(""),l=(0,h.KR)([]),n=a=>{e.value=a.target.files[0]},i=async()=>{if(!e.value||!a.value)return void alert("Bitte wählen Sie eine Datei aus und geben Sie einen Titel ein.");const t=new FormData;t.append("file",e.value),t.append("title",a.value);try{const n=await p.A.post("/files",t,{headers:{"Content-Type":"multipart/form-data"}}),i=n.data;l.value.push({id:i.id,title:i.title,originalName:i.originalName,createdAt:i.createdAt,hash:i.hash}),e.value=null,a.value=""}catch(n){console.error("Fehler beim Hochladen der Datei:",n)}},o=async e=>{const a=e.originalName.substring(e.originalName.lastIndexOf(".")),l=await p.A.get(`/files/download/${e.hash}`,{responseType:"blob"}),t=new Blob([l.data],{type:l.data.type}),n=document.createElement("a");n.href=window.URL.createObjectURL(t),n.download=`${e.title}${a}`,n.click(),window.URL.revokeObjectURL(n.href)},r=e=>{const a={year:"numeric",month:"long",day:"numeric"};return new Date(e).toLocaleDateString(void 0,a)},u=async()=>{try{const e=await p.A.get("/files");l.value=e.data}catch(e){console.error("Fehler beim Abrufen der Dateien:",e)}};return(0,t.sV)(u),{fileToUpload:e,fileTitle:a,uploadedFiles:l,handleFileUpload:n,uploadFiles:i,downloadFile:o,formatDate:r}}},m=l(6262);const k=(0,m.A)(v,[["render",f],["__scopeId","data-v-f2694614"]]);var w=k},2812:function(e){var a=TypeError;e.exports=function(e,l){if(e<l)throw new a("Not enough arguments");return e}},4603:function(e,a,l){var t=l(6840),n=l(9504),i=l(655),o=l(2812),r=URLSearchParams,u=r.prototype,d=n(u.append),s=n(u["delete"]),c=n(u.forEach),f=n([].push),h=new r("a=1&a=2&b=3");h["delete"]("a",1),h["delete"]("b",void 0),h+""!=="a=2"&&t(u,"delete",function(e){var a=arguments.length,l=a<2?void 0:arguments[1];if(a&&void 0===l)return s(this,e);var t=[];c(this,function(e,a){f(t,{key:a,value:e})}),o(a,1);var n,r=i(e),u=i(l),h=0,p=0,v=!1,m=t.length;while(h<m)n=t[h++],v||n.key===r?(v=!0,s(this,n.key)):p++;while(p<m)n=t[p++],n.key===r&&n.value===u||d(this,n.key,n.value)},{enumerable:!0,unsafe:!0})},7566:function(e,a,l){var t=l(6840),n=l(9504),i=l(655),o=l(2812),r=URLSearchParams,u=r.prototype,d=n(u.getAll),s=n(u.has),c=new r("a=1");!c.has("a",2)&&c.has("a",void 0)||t(u,"has",function(e){var a=arguments.length,l=a<2?void 0:arguments[1];if(a&&void 0===l)return s(this,e);var t=d(this,e);o(a,1);var n=i(l),r=0;while(r<t.length)if(t[r++]===n)return!0;return!1},{enumerable:!0,unsafe:!0})},8721:function(e,a,l){var t=l(3724),n=l(9504),i=l(2106),o=URLSearchParams.prototype,r=n(o.forEach);t&&!("size"in o)&&i(o,"size",{get:function(){var e=0;return r(this,function(){e++}),e},configurable:!0,enumerable:!0})}}]);
|
||||
//# sourceMappingURL=446.a766133d.js.map
|
||||
1
public/js/446.a766133d.js.map
Normal file
1
public/js/446.a766133d.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/448.74e93fb6.js
Normal file
2
public/js/448.74e93fb6.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[448],{7448:function(e,n,i){i.r(n),i.d(n,{default:function(){return d}});var t=i(641);function r(e,n,i,r,u,a){return(0,t.uX)(),(0,t.CE)("div",null,[...n[0]||(n[0]=[(0,t.Lk)("h1",null,"Seite existiert nicht",-1),(0,t.Lk)("p",null,"Leider existiert die aufgerufene Seite nicht.",-1)])])}var u={name:"DefaultComponent"},a=i(6262);const c=(0,a.A)(u,[["render",r],["__scopeId","data-v-334e7b82"]]);var d=c}}]);
|
||||
//# sourceMappingURL=448.74e93fb6.js.map
|
||||
1
public/js/448.74e93fb6.js.map
Normal file
1
public/js/448.74e93fb6.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"js/448.74e93fb6.js","mappings":"+NACIA,EAAAA,EAAAA,IAGM,eAAAC,EAAA,KAAAA,EAAA,KAFJC,EAAAA,EAAAA,IAA8B,UAA1B,yBAAqB,IACzBA,EAAAA,EAAAA,IAAoD,SAAjD,iDAA6C,M,CAKpD,OACEC,KAAM,oB,UCFV,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,GAAQ,CAAC,YAAY,qBAEzF,O","sources":["webpack://miriamgemeinde/./src/content/DefaultComponent.vue","webpack://miriamgemeinde/./src/content/DefaultComponent.vue?e630"],"sourcesContent":["<template>\n <div>\n <h1>Seite existiert nicht</h1>\n <p>Leider existiert die aufgerufene Seite nicht.</p>\n </div>\n </template>\n \n <script>\n export default {\n name: 'DefaultComponent'\n };\n </script>\n \n <style scoped>\n div {\n padding: 20px;\n }\n </style>\n ","import { render } from \"./DefaultComponent.vue?vue&type=template&id=334e7b82&scoped=true\"\nimport script from \"./DefaultComponent.vue?vue&type=script&lang=js\"\nexport * from \"./DefaultComponent.vue?vue&type=script&lang=js\"\n\nimport \"./DefaultComponent.vue?vue&type=style&index=0&id=334e7b82&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-334e7b82\"]])\n\nexport default __exports__"],"names":["_createElementBlock","_cache","_createElementVNode","name","__exports__","render"],"ignoreList":[],"sourceRoot":""}
|
||||
2
public/js/468.c02c45c3.js
Normal file
2
public/js/468.c02c45c3.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[468],{5468:function(e,r,t){t.r(r),t.d(r,{default:function(){return k}});var s=t(641),n=t(33),i=t(3751);const a={class:"user-administration"},u=["required"],l={type:"submit"},o={key:1},c=["onClick"];function d(e,r,t,d,m,h){return(0,s.uX)(),(0,s.CE)("div",a,[r[11]||(r[11]=(0,s.Lk)("h1",null,"Benutzerverwaltung",-1)),(0,s.Lk)("h2",null,(0,n.v_)(h.formTitle),1),(0,s.Lk)("form",{onSubmit:r[4]||(r[4]=(0,i.D$)((...e)=>h.saveUser&&h.saveUser(...e),["prevent"]))},[r[7]||(r[7]=(0,s.Lk)("label",{for:"name"},"Name:",-1)),(0,s.bo)((0,s.Lk)("input",{id:"name","onUpdate:modelValue":r[0]||(r[0]=e=>m.currentUser.name=e),required:""},null,512),[[i.Jo,m.currentUser.name]]),r[8]||(r[8]=(0,s.Lk)("label",{for:"email"},"Email:",-1)),(0,s.bo)((0,s.Lk)("input",{id:"email","onUpdate:modelValue":r[1]||(r[1]=e=>m.currentUser.email=e),type:"email",required:""},null,512),[[i.Jo,m.currentUser.email]]),r[9]||(r[9]=(0,s.Lk)("label",{for:"password"},"Passwort:",-1)),(0,s.bo)((0,s.Lk)("input",{id:"password","onUpdate:modelValue":r[2]||(r[2]=e=>m.currentUser.password=e),type:"password",required:m.isCreating},null,8,u),[[i.Jo,m.currentUser.password]]),(0,s.Lk)("div",null,[r[6]||(r[6]=(0,s.Lk)("label",{for:"active"},"Aktiv:",-1)),(0,s.bo)((0,s.Lk)("input",{id:"active","onUpdate:modelValue":r[3]||(r[3]=e=>m.currentUser.active=e),type:"checkbox"},null,512),[[i.lH,m.currentUser.active]])]),(0,s.Lk)("button",l,(0,n.v_)(m.isCreating?"Erstellen":"Aktualisieren"),1)],32),m.isCreating?(0,s.Q3)("",!0):((0,s.uX)(),(0,s.CE)("button",{key:0,onClick:r[5]||(r[5]=(...e)=>h.resetForm&&h.resetForm(...e))},"Zurück zu Benutzer erstellen")),m.users.length?((0,s.uX)(),(0,s.CE)("div",o,[r[10]||(r[10]=(0,s.Lk)("h2",null,"Vorhandene Benutzer",-1)),(0,s.Lk)("ul",null,[((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(m.users,e=>((0,s.uX)(),(0,s.CE)("li",{key:e.id,onClick:r=>h.editUser(e)},(0,n.v_)(e.name)+" ("+(0,n.v_)(e.email)+") ",9,c))),128))])])):(0,s.Q3)("",!0)])}var m=t(6296),h={name:"UserAdministration",data(){return{users:[],currentUser:{name:"",email:"",password:"",active:!1},isCreating:!0}},computed:{formTitle(){return this.isCreating?"Benutzer erstellen":"Benutzer bearbeiten"}},methods:{async fetchUsers(){try{const e=await m.A.get("/users");this.users=e.data}catch(e){console.error("Fehler beim Abrufen der Benutzer:",e)}},async saveUser(){this.isCreating?await this.createUser():await this.updateUser(),this.resetForm(),this.fetchUsers()},async createUser(){try{await m.A.post("/users",this.currentUser)}catch(e){console.error("Fehler beim Erstellen des Benutzers:",e)}},async updateUser(){try{await m.A.put(`/users/${this.currentUser.id}`,this.currentUser)}catch(e){console.error("Fehler beim Aktualisieren des Benutzers:",e)}},editUser(e){this.currentUser={...e,password:""},this.isCreating=!1},resetForm(){this.currentUser={name:"",email:"",password:"",active:!1},this.isCreating=!0}},mounted(){this.fetchUsers()}},p=t(6262);const U=(0,p.A)(h,[["render",d],["__scopeId","data-v-a495c756"]]);var k=U}}]);
|
||||
//# sourceMappingURL=468.c02c45c3.js.map
|
||||
1
public/js/468.c02c45c3.js.map
Normal file
1
public/js/468.c02c45c3.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/493.716a232a.js
Normal file
2
public/js/493.716a232a.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[493],{5493:function(e,i,s){s.r(i),s.d(i,{default:function(){return h}});var a=s(641),t=s(3751),o=s(33);const l={class:"register"},r={key:0,class:"dialog"},n={class:"dialog-content"};function d(e,i,s,d,g,u){const m=(0,a.g2)("router-link");return(0,a.uX)(),(0,a.CE)("div",l,[i[11]||(i[11]=(0,a.Lk)("h2",null,"Registrieren",-1)),(0,a.Lk)("form",{onSubmit:i[3]||(i[3]=(0,t.D$)((...e)=>u.register&&u.register(...e),["prevent"]))},[i[5]||(i[5]=(0,a.Lk)("label",{for:"name"},"Name:",-1)),(0,a.bo)((0,a.Lk)("input",{type:"text",id:"name","onUpdate:modelValue":i[0]||(i[0]=e=>g.name=e),required:""},null,512),[[t.Jo,g.name]]),i[6]||(i[6]=(0,a.Lk)("label",{for:"email"},"Email-Adresse:",-1)),(0,a.bo)((0,a.Lk)("input",{type:"email",id:"email","onUpdate:modelValue":i[1]||(i[1]=e=>g.email=e),required:""},null,512),[[t.Jo,g.email]]),i[7]||(i[7]=(0,a.Lk)("label",{for:"password"},"Passwort:",-1)),(0,a.bo)((0,a.Lk)("input",{type:"password",id:"password","onUpdate:modelValue":i[2]||(i[2]=e=>g.password=e),required:""},null,512),[[t.Jo,g.password]]),i[8]||(i[8]=(0,a.Lk)("button",{type:"submit"},"Registrieren",-1))],32),(0,a.Lk)("p",null,[(0,a.bF)(m,{to:"/login"},{default:(0,a.k6)(()=>[...i[9]||(i[9]=[(0,a.eW)("Login",-1)])]),_:1})]),(0,a.Lk)("p",null,[(0,a.bF)(m,{to:"/forgot-password"},{default:(0,a.k6)(()=>[...i[10]||(i[10]=[(0,a.eW)("Passwort vergessen?",-1)])]),_:1})]),g.dialogVisible?((0,a.uX)(),(0,a.CE)("div",r,[(0,a.Lk)("div",n,[(0,a.Lk)("h3",null,(0,o.v_)(g.dialogTitle),1),(0,a.Lk)("p",null,(0,o.v_)(g.dialogMessage),1),(0,a.Lk)("button",{type:"button",onClick:i[4]||(i[4]=(...e)=>u.closeDialog&&u.closeDialog(...e))},"Schließen")])])):(0,a.Q3)("",!0)])}var g=s(6296),u={name:"RegisterComponent",components:{},data(){return{name:"",email:"",password:"",dialogTitle:"",dialogMessage:"",dialogVisible:!1}},methods:{async register(){try{const e=await g.A.post("/auth/register",{name:this.name,email:this.email,password:this.password});this.showDialog("Registrierung erfolgreich",e.data?.message||"Ihr Konto wurde erfolgreich erstellt."),this.name="",this.email="",this.password=""}catch(e){const i=e?.response?.data?.message||e?.message||"Ein unbekannter Fehler ist aufgetreten";this.showDialog("Fehler",i)}},showDialog(e,i){this.dialogTitle=e,this.dialogMessage=i,this.dialogVisible=!0},closeDialog(){this.dialogVisible=!1}}},m=s(6262);const p=(0,m.A)(u,[["render",d],["__scopeId","data-v-63b3c0a3"]]);var h=p}}]);
|
||||
//# sourceMappingURL=493.716a232a.js.map
|
||||
1
public/js/493.716a232a.js.map
Normal file
1
public/js/493.716a232a.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/562.48a24ceb.js
Normal file
2
public/js/562.48a24ceb.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/562.48a24ceb.js.map
Normal file
1
public/js/562.48a24ceb.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/600.189ab469.js
Normal file
2
public/js/600.189ab469.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/600.189ab469.js.map
Normal file
1
public/js/600.189ab469.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/600.943e691c.js
Normal file
2
public/js/600.943e691c.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/600.943e691c.js.map
Normal file
1
public/js/600.943e691c.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/636.e58bfd21.js
Normal file
2
public/js/636.e58bfd21.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/636.e58bfd21.js.map
Normal file
1
public/js/636.e58bfd21.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/698.ee1f6aff.js
Normal file
2
public/js/698.ee1f6aff.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/698.ee1f6aff.js.map
Normal file
1
public/js/698.ee1f6aff.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/702.dce87a34.js
Normal file
2
public/js/702.dce87a34.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[355,702],{5355:function(e,o,a){a.r(o),a.d(o,{default:function(){return g}});var i=a(641),l=a(33);const s={key:0,class:"dialog-overlay"},t={class:"dialog"};function n(e,o,a,n,r,d){return a.modelValue?((0,i.uX)(),(0,i.CE)("div",s,[(0,i.Lk)("div",t,[(0,i.Lk)("h2",null,(0,l.v_)(a.title),1),(0,i.Lk)("p",null,(0,l.v_)(a.message),1),(0,i.Lk)("button",{onClick:o[0]||(o[0]=(...e)=>d.closeDialog&&d.closeDialog(...e))},"OK")])])):(0,i.Q3)("",!0)}var r={name:"DialogComponent",props:{title:{type:String,required:!0},message:{type:String,required:!0},modelValue:{type:Boolean,default:!1}},methods:{closeDialog(){this.$emit("update:modelValue",!1),this.$emit("close")}}},d=a(6262);const u=(0,d.A)(r,[["render",n],["__scopeId","data-v-ce9d9498"]]);var g=u},9702:function(e,o,a){a.r(o),a.d(o,{default:function(){return p}});var i=a(641),l=a(3751);const s={class:"login"};function t(e,o,a,t,n,r){const d=(0,i.g2)("router-link"),u=(0,i.g2)("DialogComponent");return(0,i.uX)(),(0,i.CE)("div",s,[o[9]||(o[9]=(0,i.Lk)("h2",null,"Login",-1)),(0,i.Lk)("form",{onSubmit:o[2]||(o[2]=(0,l.D$)((...e)=>r.runLogin&&r.runLogin(...e),["prevent"]))},[o[4]||(o[4]=(0,i.Lk)("label",{for:"email"},"Email-Adresse:",-1)),(0,i.bo)((0,i.Lk)("input",{type:"email",id:"email","onUpdate:modelValue":o[0]||(o[0]=e=>n.email=e),required:""},null,512),[[l.Jo,n.email]]),o[5]||(o[5]=(0,i.Lk)("label",{for:"password"},"Passwort:",-1)),(0,i.bo)((0,i.Lk)("input",{type:"password",id:"password","onUpdate:modelValue":o[1]||(o[1]=e=>n.password=e),required:""},null,512),[[l.Jo,n.password]]),o[6]||(o[6]=(0,i.Lk)("button",{type:"submit"},"Login",-1))],32),(0,i.Lk)("p",null,[(0,i.bF)(d,{to:"/register"},{default:(0,i.k6)(()=>[...o[7]||(o[7]=[(0,i.eW)("Registrieren",-1)])]),_:1})]),(0,i.Lk)("p",null,[(0,i.bF)(d,{to:"/forgot-password"},{default:(0,i.k6)(()=>[...o[8]||(o[8]=[(0,i.eW)("Passwort vergessen?",-1)])]),_:1})]),(0,i.bF)(u,{title:n.dialogTitle,message:n.dialogMessage,modelValue:n.dialogVisible,"onUpdate:modelValue":o[3]||(o[3]=e=>n.dialogVisible=e),onClose:r.closeDialog},null,8,["title","message","modelValue","onClose"])])}a(4114);var n=a(4335),r=a(5355),d=a(6278),u={name:"LoginComponent",components:{DialogComponent:r["default"]},data(){return{email:"",password:"",dialogTitle:"",dialogMessage:"",dialogVisible:!1}},methods:{...(0,d.i0)(["login"]),async runLogin(){try{const e=await n.A.post("/auth/login",{email:this.email,password:this.password}),o=e.data.token,a=e.data;localStorage.setItem("token",o),this.login(a.user),n.A.defaults.headers.common["Authorization"]=`Bearer ${o}`,this.$router.push("/admin/index")}catch(e){e.response?this.showDialog("Fehler",e.response.data.message):this.showDialog("Ein Fehler ist aufgetreten",e.message)}},showDialog(e,o){this.dialogTitle=e,this.dialogMessage=o,this.dialogVisible=!0},closeDialog(){this.dialogVisible=!1}}},g=a(6262);const m=(0,g.A)(u,[["render",t],["__scopeId","data-v-40a158c0"]]);var p=m}}]);
|
||||
//# sourceMappingURL=702.dce87a34.js.map
|
||||
1
public/js/702.dce87a34.js.map
Normal file
1
public/js/702.dce87a34.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/718.900ebff1.js
Normal file
2
public/js/718.900ebff1.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/718.900ebff1.js.map
Normal file
1
public/js/718.900ebff1.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/768.d801babf.js
Normal file
2
public/js/768.d801babf.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[768],{1768:function(e,n,i){i.r(n),i.d(n,{default:function(){return o}});var r=i(641),t=i(33);const a={class:"service-unavailable"};function s(e,n,i,s,c,u){return(0,r.uX)(),(0,r.CE)("div",a,[n[0]||(n[0]=(0,r.Lk)("h1",null,"Vorübergehend nicht erreichbar",-1)),(0,r.Lk)("p",null,(0,t.v_)(u.message),1),n[1]||(n[1]=(0,r.Lk)("p",{class:"hint"}," Es liegt vermutlich ein technisches Problem vor (z. B. die Datenbank). Bitte laden Sie die Seite in einigen Minuten erneut. ",-1))])}var c=i(6278),u={name:"ServiceUnavailableComponent",computed:{...(0,c.L8)(["menuLoadError"]),message(){return this.menuLoadError||"Die Website ist vorübergehend nicht vollständig erreichbar."}}},l=i(6262);const d=(0,l.A)(u,[["render",s],["__scopeId","data-v-fd9b1088"]]);var o=d}}]);
|
||||
//# sourceMappingURL=768.d801babf.js.map
|
||||
1
public/js/768.d801babf.js.map
Normal file
1
public/js/768.d801babf.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"js/768.d801babf.js","mappings":"sMACOA,MAAM,uB,0CAAXC,EAAAA,EAAAA,IAMM,MANNC,EAMM,C,aALJC,EAAAA,EAAAA,IAAuC,UAAnC,kCAA8B,KAClCA,EAAAA,EAAAA,IAAoB,UAAAC,EAAAA,EAAAA,IAAdC,EAAAC,SAAO,G,aACbH,EAAAA,EAAAA,IAEI,KAFDH,MAAM,QAAO,iIAEhB,K,eAOJ,GACEO,KAAM,8BACNC,SAAU,KACLC,EAAAA,EAAAA,IAAW,CAAC,kBACfH,OAAAA,GACE,OACEI,KAAKC,eACL,6DAEJ,I,UCfJ,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,GAAQ,CAAC,YAAY,qBAEzF,O","sources":["webpack://miriamgemeinde/./src/content/ServiceUnavailableComponent.vue","webpack://miriamgemeinde/./src/content/ServiceUnavailableComponent.vue?7a9d"],"sourcesContent":["<template>\n <div class=\"service-unavailable\">\n <h1>Vorübergehend nicht erreichbar</h1>\n <p>{{ message }}</p>\n <p class=\"hint\">\n Es liegt vermutlich ein technisches Problem vor (z. B. die Datenbank). Bitte laden Sie die Seite in einigen Minuten erneut.\n </p>\n </div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex';\n\nexport default {\n name: 'ServiceUnavailableComponent',\n computed: {\n ...mapGetters(['menuLoadError']),\n message() {\n return (\n this.menuLoadError ||\n 'Die Website ist vorübergehend nicht vollständig erreichbar.'\n );\n },\n },\n};\n</script>\n\n<style scoped>\n.service-unavailable {\n padding: 20px;\n}\n.hint {\n color: #444;\n margin-top: 1rem;\n}\n</style>\n","import { render } from \"./ServiceUnavailableComponent.vue?vue&type=template&id=fd9b1088&scoped=true\"\nimport script from \"./ServiceUnavailableComponent.vue?vue&type=script&lang=js\"\nexport * from \"./ServiceUnavailableComponent.vue?vue&type=script&lang=js\"\n\nimport \"./ServiceUnavailableComponent.vue?vue&type=style&index=0&id=fd9b1088&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-fd9b1088\"]])\n\nexport default __exports__"],"names":["class","_createElementBlock","_hoisted_1","_createElementVNode","_toDisplayString","$options","message","name","computed","mapGetters","this","menuLoadError","__exports__","render"],"ignoreList":[],"sourceRoot":""}
|
||||
2
public/js/785.0c674ce5.js
Normal file
2
public/js/785.0c674ce5.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[785],{3149:function(n,t,e){e.r(t),e.d(t,{default:function(){return k}});var o=e(641);const r={class:"some-page"};function i(n,t,e,i,u,a){const c=(0,o.g2)("ContentComponent");return(0,o.uX)(),(0,o.CE)("div",r,[(0,o.bF)(c,{link:a.currentLink},null,8,["link"])])}var u=e(33);function a(n,t,e,r,i,a){const c=(0,o.g2)("RenderContentComponent");return(0,o.uX)(),(0,o.CE)("div",null,[(0,o.Lk)("h1",null,(0,u.v_)(i.title),1),(0,o.bF)(c,{content:i.content},null,8,["content"])])}var c=e(6296),s=e(6278),l=e(6562),m={name:"ContentComponent",components:{RenderContentComponent:l.A},props:{link:{type:String,required:!0}},data(){return{content:"",title:""}},computed:{...(0,s.aH)(["menuData"]),...(0,s.L8)(["getMenuData"])},watch:{link:{immediate:!0,handler(n){this.fetchContent(n),this.setTitle(n)}}},methods:{async fetchContent(n){try{const t=await c.A.get(`/page-content?link=${n}`);this.content=t.data.content}catch(t){console.error("Fehler beim Abrufen des Inhalts:",t)}},setTitle(n){const t=(n,e)=>{for(const o of n){if(o.link===e)return o.pageTitle||o.name;if(o.submenu&&o.submenu.length>0){const n=t(o.submenu,e);if(n)return`${n}`}}return""};this.title=t(this.menuData,n)}}},h=e(6262);const d=(0,h.A)(m,[["render",a]]);var p=d,f={name:"DefaultPage",components:{ContentComponent:p},computed:{currentLink(){return this.$route.path}}};const C=(0,h.A)(f,[["render",i]]);var k=C}}]);
|
||||
//# sourceMappingURL=785.0c674ce5.js.map
|
||||
1
public/js/785.0c674ce5.js.map
Normal file
1
public/js/785.0c674ce5.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/814.fc451eae.js
Normal file
2
public/js/814.fc451eae.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[814],{9644:function(e,n,t){t.r(n),t.d(n,{default:function(){return m}});var a=t(641),s=t(33);function u(e,n,t,u,i,o){const r=(0,a.g2)("RenderContentComponent");return(0,a.uX)(),(0,a.CE)("div",null,[n[0]||(n[0]=(0,a.Lk)("div",{class:"previewinfo"},"Dies ist eine Vorschau.",-1)),(0,a.Lk)("h1",null,(0,s.v_)(u.title),1),(0,a.bF)(r,{content:u.content},null,8,["content"])])}var i=t(6278),o=t(6562),r={name:"PagePreview",components:{RenderContentComponent:o.A},setup(){const e=(0,i.Pj)(),n=(0,a.EW)(()=>e.state.pageContent),t=(0,a.EW)(()=>e.state.selectedPage),s=(0,a.EW)(()=>e.state.menuData),u=(0,a.EW)(()=>e.state.pageTitle),o=n=>{const t=(e,n)=>{for(const a of e){if(a.link===n)return a.pageTitle||a.name;if(a.submenu&&a.submenu.length>0){const e=t(a.submenu,n);if(e)return e}}return""};e.dispatch("setPageTitle",t(s.value,n))};return(0,a.nT)(()=>{o(t.value)}),{content:n,title:u}}},c=t(6262);const l=(0,c.A)(r,[["render",u],["__scopeId","data-v-9a71cbf6"]]);var m=l}}]);
|
||||
//# sourceMappingURL=814.fc451eae.js.map
|
||||
1
public/js/814.fc451eae.js.map
Normal file
1
public/js/814.fc451eae.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"js/814.fc451eae.js","mappings":"kRACEA,EAAAA,EAAAA,IAIM,Y,aAHJC,EAAAA,EAAAA,IAAsD,OAAjDC,MAAM,eAAc,2BAAuB,KAChDD,EAAAA,EAAAA,IAAoB,WAAAE,EAAAA,EAAAA,IAAbC,EAAAC,OAAK,IACZC,EAAAA,EAAAA,IAA6CC,EAAA,CAApBC,QAASJ,EAAAI,SAAO,qB,yBAS7C,GACEC,KAAM,cACNC,WAAY,CACVC,uBAAsBA,EAAAA,GAExBC,KAAAA,GACE,MAAMC,GAAQC,EAAAA,EAAAA,MACRN,GAAUO,EAAAA,EAAAA,IAAS,IAAMF,EAAMG,MAAMC,aACrCC,GAAeH,EAAAA,EAAAA,IAAS,IAAMF,EAAMG,MAAME,cAC1CC,GAAWJ,EAAAA,EAAAA,IAAS,IAAMF,EAAMG,MAAMG,UACtCd,GAAQU,EAAAA,EAAAA,IAAS,IAAMF,EAAMG,MAAMI,WAEnCC,EAAYC,IAChB,MAAMC,EAAYA,CAACC,EAAWF,KAC5B,IAAK,MAAMG,KAAQD,EAAW,CAC5B,GAAIC,EAAKH,OAASA,EAChB,OAAOG,EAAKL,WAAaK,EAAKhB,KAEhC,GAAIgB,EAAKC,SAAWD,EAAKC,QAAQC,OAAS,EAAG,CAC3C,MAAMC,EAAQL,EAAUE,EAAKC,QAASJ,GACtC,GAAIM,EACF,OAAOA,CAEX,CACF,CACA,MAAO,IAETf,EAAMgB,SAAS,eAAgBN,EAAUJ,EAASW,MAAOR,KAO3D,OAJAS,EAAAA,EAAAA,IAAY,KACVV,EAASH,EAAaY,SAGjB,CACLtB,UACAH,QAEJ,G,UC5CF,MAAM2B,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,GAAQ,CAAC,YAAY,qBAEzF,O","sources":["webpack://miriamgemeinde/./src/content/admin/PagePreviewComponent.vue","webpack://miriamgemeinde/./src/content/admin/PagePreviewComponent.vue?4023"],"sourcesContent":["<template>\n <div>\n <div class=\"previewinfo\">Dies ist eine Vorschau.</div>\n <h1>{{ title }}</h1>\n <RenderContentComponent :content=\"content\" />\n </div>\n</template>\n\n<script>\nimport { computed, watchEffect } from 'vue';\nimport { useStore } from 'vuex';\nimport RenderContentComponent from '@/components/RenderContentComponent.vue';\n\nexport default {\n name: 'PagePreview',\n components: {\n RenderContentComponent\n },\n setup() {\n const store = useStore();\n const content = computed(() => store.state.pageContent);\n const selectedPage = computed(() => store.state.selectedPage);\n const menuData = computed(() => store.state.menuData);\n const title = computed(() => store.state.pageTitle);\n\n const setTitle = (link) => {\n const findTitle = (menuItems, link) => {\n for (const item of menuItems) {\n if (item.link === link) {\n return item.pageTitle || item.name;\n }\n if (item.submenu && item.submenu.length > 0) {\n const found = findTitle(item.submenu, link);\n if (found) {\n return found;\n }\n }\n }\n return '';\n };\n store.dispatch('setPageTitle', findTitle(menuData.value, link));\n };\n\n watchEffect(() => {\n setTitle(selectedPage.value);\n });\n\n return {\n content,\n title\n };\n }\n};\n</script>\n\n<style scoped>\n.previewinfo {\n background-color: black;\n color: #d00000;\n position: absolute;\n top: 93px;\n left: 0;\n padding: 2px 10px;\n font-weight: bold;\n}\n</style>\n","import { render } from \"./PagePreviewComponent.vue?vue&type=template&id=9a71cbf6&scoped=true\"\nimport script from \"./PagePreviewComponent.vue?vue&type=script&lang=js\"\nexport * from \"./PagePreviewComponent.vue?vue&type=script&lang=js\"\n\nimport \"./PagePreviewComponent.vue?vue&type=style&index=0&id=9a71cbf6&scoped=true&lang=css\"\n\nimport exportComponent from \"../../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-9a71cbf6\"]])\n\nexport default __exports__"],"names":["_createElementBlock","_createElementVNode","class","_toDisplayString","$setup","title","_createVNode","_component_RenderContentComponent","content","name","components","RenderContentComponent","setup","store","useStore","computed","state","pageContent","selectedPage","menuData","pageTitle","setTitle","link","findTitle","menuItems","item","submenu","length","found","dispatch","value","watchEffect","__exports__","render"],"ignoreList":[],"sourceRoot":""}
|
||||
2
public/js/93.8cb43993.js
Normal file
2
public/js/93.8cb43993.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/93.8cb43993.js.map
Normal file
1
public/js/93.8cb43993.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/93.d6ceb929.js
Normal file
2
public/js/93.d6ceb929.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/93.d6ceb929.js.map
Normal file
1
public/js/93.d6ceb929.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/957.aa15187e.js
Normal file
2
public/js/957.aa15187e.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";(self["webpackChunkmiriamgemeinde"]=self["webpackChunkmiriamgemeinde"]||[]).push([[957],{8957:function(e,t,a){a.r(t),a.d(t,{default:function(){return d}});var n=a(641);const u=["src"];function m(e,t,a,m,r,i){return(0,n.uX)(),(0,n.CE)("img",{src:r.currentImage},null,8,u)}var r=a(6278),i={name:"ImageContent",data(){return{defaultImage:"/images/homepage1.png",currentImage:"/images/homepage1.png"}},computed:{...(0,r.aH)(["menuData"])},watch:{$route:{immediate:!0,handler(){this.updateImage()}}},methods:{updateImage(){const e=this.$route.path,t=this.menuData,a=this.findMenuItemByPath(t,e);a&&a.image?this.currentImage=`/images/${a.image}`:this.currentImage=this.defaultImage},findMenuItemByPath(e,t){for(let a of e){if(a.link===t)return a;if(a.submenu){const e=this.findMenuItemByPath(a.submenu,t);if(e)return e}}return null}}},s=a(6262);const g=(0,s.A)(i,[["render",m],["__scopeId","data-v-d1b58e08"]]);var d=g}}]);
|
||||
//# sourceMappingURL=957.aa15187e.js.map
|
||||
1
public/js/957.aa15187e.js.map
Normal file
1
public/js/957.aa15187e.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"js/957.aa15187e.js","mappings":"+OACIA,EAAAA,EAAAA,IAA2B,OAArBC,IAAKC,EAAAC,cAAY,OAAAC,E,eAM3B,GACEC,KAAM,eACNC,IAAAA,GACE,MAAO,CACLC,aAAc,wBACdJ,aAAc,wBAElB,EACAK,SAAU,KACLC,EAAAA,EAAAA,IAAS,CAAC,cAEfC,MAAO,CACLC,OAAQ,CACNC,WAAW,EACXC,OAAAA,GACEC,KAAKC,aACP,IAGJC,QAAS,CACPD,WAAAA,GACE,MAAME,EAAYH,KAAKH,OAAOO,KACxBC,EAAWL,KAAKK,SAChBC,EAAWN,KAAKO,mBAAmBF,EAAUF,GAC/CG,GAAYA,EAASE,MACvBR,KAAKX,aAAe,WAAWiB,EAASE,QAExCR,KAAKX,aAAeW,KAAKP,YAE7B,EACAc,kBAAAA,CAAmBE,EAAML,GACvB,IAAK,IAAIM,KAAQD,EAAM,CACrB,GAAIC,EAAKC,OAASP,EAChB,OAAOM,EAET,GAAIA,EAAKE,QAAS,CAChB,MAAMC,EAAUb,KAAKO,mBAAmBG,EAAKE,QAASR,GACtD,GAAIS,EACF,OAAOA,CAEX,CACF,CACA,OAAO,IACT,I,UC3CJ,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,GAAQ,CAAC,YAAY,qBAEzF,O","sources":["webpack://miriamgemeinde/./src/content/ImageContent.vue","webpack://miriamgemeinde/./src/content/ImageContent.vue?ee30"],"sourcesContent":["<template>\n <img :src=\"currentImage\" />\n</template>\n\n<script>\nimport { mapState } from 'vuex';\n\nexport default {\n name: 'ImageContent',\n data() {\n return {\n defaultImage: '/images/homepage1.png',\n currentImage: '/images/homepage1.png'\n };\n },\n computed: {\n ...mapState(['menuData']),\n },\n watch: {\n $route: {\n immediate: true,\n handler() {\n this.updateImage();\n }\n }\n },\n methods: {\n updateImage() {\n const routePath = this.$route.path;\n const menuData = this.menuData;\n const menuItem = this.findMenuItemByPath(menuData, routePath);\n if (menuItem && menuItem.image) {\n this.currentImage = `/images/${menuItem.image}`;\n } else {\n this.currentImage = this.defaultImage;\n }\n },\n findMenuItemByPath(menu, path) {\n for (let item of menu) {\n if (item.link === path) {\n return item;\n }\n if (item.submenu) {\n const subItem = this.findMenuItemByPath(item.submenu, path);\n if (subItem) {\n return subItem;\n }\n }\n }\n return null;\n }\n }\n};\n</script>\n\n<style scoped>\n.right-column h2 {\n text-align: center;\n color: #000;\n}\n\n.right-column img {\n display: block;\n margin: 0 auto;\n max-width: 100%;\n height: auto;\n}\n</style>\n","import { render } from \"./ImageContent.vue?vue&type=template&id=d1b58e08&scoped=true\"\nimport script from \"./ImageContent.vue?vue&type=script&lang=js\"\nexport * from \"./ImageContent.vue?vue&type=script&lang=js\"\n\nimport \"./ImageContent.vue?vue&type=style&index=0&id=d1b58e08&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-d1b58e08\"]])\n\nexport default __exports__"],"names":["_createElementBlock","src","$data","currentImage","_hoisted_1","name","data","defaultImage","computed","mapState","watch","$route","immediate","handler","this","updateImage","methods","routePath","path","menuData","menuItem","findMenuItemByPath","image","menu","item","link","submenu","subItem","__exports__","render"],"ignoreList":[],"sourceRoot":""}
|
||||
2
public/js/app.53c460b9.js
Normal file
2
public/js/app.53c460b9.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/app.53c460b9.js.map
Normal file
1
public/js/app.53c460b9.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/app.e009cb77.js
Normal file
2
public/js/app.e009cb77.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/app.e009cb77.js.map
Normal file
1
public/js/app.e009cb77.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/app.e71748c3.js
Normal file
2
public/js/app.e71748c3.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/app.e71748c3.js.map
Normal file
1
public/js/app.e71748c3.js.map
Normal file
File diff suppressed because one or more lines are too long
37
public/js/chunk-vendors.2da008aa.js
Normal file
37
public/js/chunk-vendors.2da008aa.js
Normal file
File diff suppressed because one or more lines are too long
1
public/js/chunk-vendors.2da008aa.js.map
Normal file
1
public/js/chunk-vendors.2da008aa.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -27,7 +27,7 @@ const filesRouter = require('./routes/files');
|
||||
const liturgicalDaysRouter = require('./routes/liturgicalDays');
|
||||
|
||||
const app = express();
|
||||
const PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
const PORT = parseInt(process.env.BACKEND_PORT || process.env.PORT, 10) || 3000;
|
||||
|
||||
// CORS mit Whitelist und tolerantem Fallback für fehlende Origin-Header
|
||||
const allowedOrigins = (process.env.ALLOWED_ORIGINS || '')
|
||||
|
||||
@@ -62,49 +62,36 @@ export default {
|
||||
|
||||
<style>
|
||||
/* eslint-disable */
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #ffffff;
|
||||
font-family: Arial, sans-serif;
|
||||
width: 100%;
|
||||
overflow-x: hidden; /* Prevent horizontal scrolling */
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Layout: globale Typografie/Farben in design-tokens.css */
|
||||
.content-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
color: #000;
|
||||
color: var(--color-text);
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
flex: 1;
|
||||
min-width: 1000px;
|
||||
margin: 0.5em 0 0.5em 0.5em;
|
||||
padding-right: 0.5em;
|
||||
background-color: #ffffff;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
margin: var(--space-2) 0 var(--space-2) var(--space-2);
|
||||
padding-right: var(--space-2);
|
||||
background-color: var(--color-bg-page);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
flex: 1;
|
||||
background-color: #d9e2f3;
|
||||
min-width: 0;
|
||||
background-color: var(--color-bg-sidebar);
|
||||
overflow-y: auto;
|
||||
margin: 0 7px 7px 0;
|
||||
margin: 0 var(--space-2) var(--space-2) 0;
|
||||
}
|
||||
|
||||
.right-column h2 {
|
||||
text-align: center;
|
||||
color: #000;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.right-column img {
|
||||
@@ -117,8 +104,8 @@ body {
|
||||
.right-column-overlay {
|
||||
max-height: 150px;
|
||||
overflow-y: hidden;
|
||||
margin-top: 10px;
|
||||
background-color: #d9e2f3;
|
||||
margin-top: var(--space-3);
|
||||
background-color: var(--color-bg-sidebar);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -136,7 +123,9 @@ body {
|
||||
}
|
||||
|
||||
.left-column {
|
||||
padding: 10px;
|
||||
padding: var(--space-3);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
@@ -146,7 +135,7 @@ body {
|
||||
.right-column-overlay {
|
||||
display: flex;
|
||||
max-height: 150px;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--color-bg-page);
|
||||
}
|
||||
|
||||
.right-column-overlay img {
|
||||
@@ -163,7 +152,7 @@ body {
|
||||
|
||||
.left-column,
|
||||
.right-column {
|
||||
padding: 10px;
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
.right-column {
|
||||
|
||||
99
src/assets/css/design-tokens.css
Normal file
99
src/assets/css/design-tokens.css
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Design-Tokens Phase 1 – Farben (EKHN-Violett unverändert), Abstände, Typografie.
|
||||
* Globale Basistyles für html/body/#app.
|
||||
*/
|
||||
:root {
|
||||
/* Marke EKHN – Primärfarben fix */
|
||||
--color-brand-primary: #9400ff;
|
||||
--color-brand-primary-hover: #7a00d1;
|
||||
--color-brand-tint: #e0bfff;
|
||||
|
||||
/* Neutrale Flächen & Text */
|
||||
--color-bg-page: #ffffff;
|
||||
--color-bg-subtle: #f8f9fb;
|
||||
--color-bg-sidebar: #d9e2f3;
|
||||
--color-text: #1a1a1a;
|
||||
--color-text-muted: #4a4a4a;
|
||||
|
||||
/* Footer (dunkler Grund) */
|
||||
--color-footer-bg: #0b1735;
|
||||
--color-footer-link: #e8edf5;
|
||||
--color-footer-link-hover: #ffffff;
|
||||
|
||||
/* Abstände (4px-Raster) */
|
||||
--space-1: 0.25rem;
|
||||
--space-2: 0.5rem;
|
||||
--space-3: 0.75rem;
|
||||
--space-4: 1rem;
|
||||
--space-5: 1.25rem;
|
||||
--space-6: 1.5rem;
|
||||
--space-8: 2rem;
|
||||
|
||||
/* Typografie */
|
||||
--font-family-base: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
sans-serif;
|
||||
--font-size-body: 1rem;
|
||||
--line-height-body: 1.5;
|
||||
--font-size-h1: clamp(1.25rem, 2.5vw, 1.75rem);
|
||||
--font-size-h2: clamp(1.15rem, 2vw, 1.35rem);
|
||||
--font-size-h3: clamp(1.05rem, 1.5vw, 1.2rem);
|
||||
|
||||
--shadow-dropdown: 2px 2px 6px rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--color-bg-page);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-base);
|
||||
font-size: var(--font-size-body);
|
||||
line-height: var(--line-height-body);
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Sanfte Standard-Hierarchie; Komponenten können gezielt überschreiben */
|
||||
:where(h1) {
|
||||
font-size: var(--font-size-h1);
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
:where(h2) {
|
||||
font-size: var(--font-size-h2);
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
:where(h3) {
|
||||
font-size: var(--font-size-h3);
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-brand-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
90
src/common/components/BreadcrumbsComponent.vue
Normal file
90
src/common/components/BreadcrumbsComponent.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<nav v-if="crumbs.length" class="breadcrumbs" aria-label="Brotkrumen">
|
||||
<ol>
|
||||
<li v-for="(c, idx) in crumbs" :key="c.to + '-' + idx">
|
||||
<router-link v-if="idx < crumbs.length - 1" :to="c.to">{{ c.label }}</router-link>
|
||||
<span v-else aria-current="page">{{ c.label }}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
function findLabel(menuItems, link) {
|
||||
for (const item of menuItems) {
|
||||
if (item?.link === link) {
|
||||
return item.pageTitle || item.name || '';
|
||||
}
|
||||
if (item?.submenu?.length) {
|
||||
const found = findLabel(item.submenu, link);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'BreadcrumbsComponent',
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const store = useStore();
|
||||
|
||||
const crumbs = computed(() => {
|
||||
const path = route.path || '/';
|
||||
const list = [{ label: 'Startseite', to: '/' }];
|
||||
|
||||
if (path === '/') return [];
|
||||
|
||||
const label = findLabel(store.state.menuData || [], path);
|
||||
list.push({ label: label || 'Seite', to: path });
|
||||
return list;
|
||||
});
|
||||
|
||||
return { crumbs };
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.breadcrumbs {
|
||||
margin: 0 var(--space-3) var(--space-2) var(--space-3);
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.breadcrumbs ol {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-2);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.breadcrumbs li {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.breadcrumbs li:not(:last-child)::after {
|
||||
content: '›';
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.breadcrumbs a {
|
||||
color: var(--color-text-muted);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.breadcrumbs a:hover,
|
||||
.breadcrumbs a:focus-visible {
|
||||
color: var(--color-text);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
@@ -34,14 +34,16 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
background-color: #0b1735;
|
||||
background-color: var(--color-footer-bg);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: 7px;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.left-links {
|
||||
@@ -52,17 +54,22 @@ export default {
|
||||
.right-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
color: #fff;
|
||||
padding-right: 20px;
|
||||
color: var(--color-footer-link);
|
||||
padding-right: var(--space-5);
|
||||
text-decoration: none;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.footer a.login-link {
|
||||
color: #444;
|
||||
.footer a:hover,
|
||||
.footer a:focus-visible {
|
||||
color: var(--color-footer-link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footer a.logout-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -5,18 +5,21 @@
|
||||
<span class="reload-icon" @click="reloadMenu">⟳</span>
|
||||
</div>
|
||||
<NavbarComponent />
|
||||
<BreadcrumbsComponent />
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavbarComponent from './NavbarComponent.vue';
|
||||
import BreadcrumbsComponent from './BreadcrumbsComponent.vue';
|
||||
import { mapActions } from 'vuex';
|
||||
import router from '@/router';
|
||||
|
||||
export default {
|
||||
name: 'HeaderComponent',
|
||||
components: {
|
||||
NavbarComponent
|
||||
NavbarComponent,
|
||||
BreadcrumbsComponent,
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['loadMenuData']),
|
||||
@@ -42,7 +45,7 @@ header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--color-bg-page);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
@@ -50,28 +53,30 @@ header {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: .3em .5em;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
text-shadow: 2px 2px 1px #e0bfff;
|
||||
padding-bottom: 4px;
|
||||
text-shadow: 1px 1px 0 var(--color-brand-tint);
|
||||
padding-bottom: var(--space-1);
|
||||
}
|
||||
|
||||
.reload-icon {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
background-color: #e0bfff;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
margin-left: var(--space-3);
|
||||
background-color: var(--color-brand-tint);
|
||||
color: var(--color-bg-page);
|
||||
padding: var(--space-1) 6px;
|
||||
border-radius: 50%;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.reload-icon:hover {
|
||||
color: #7a00d1;
|
||||
.reload-icon:hover,
|
||||
.reload-icon:focus-visible {
|
||||
color: var(--color-brand-primary-hover);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,33 @@
|
||||
<template>
|
||||
<nav class="navbar">
|
||||
<button class="menu-toggle" @click="toggleMenu">
|
||||
Menü
|
||||
<button
|
||||
class="menu-toggle"
|
||||
type="button"
|
||||
@click="toggleMenu"
|
||||
:aria-expanded="String(isMenuOpen)"
|
||||
aria-controls="main-menu"
|
||||
>
|
||||
<span class="menu-toggle__icon" aria-hidden="true">≡</span>
|
||||
<span>Menü</span>
|
||||
</button>
|
||||
<ul v-if="isMenuOpen || windowWidth > 768">
|
||||
<li class="ekhnlogo"><img src="/images/facettenkreuz.png" class="facettenkreuz" /></li>
|
||||
<li v-for="item in menu" :key="item.name" @click="toggleSubmenu(item.name)">
|
||||
<router-link :to="item.link" v-if="item.link" @click="closeMenu">
|
||||
<ul id="main-menu" v-if="isMenuOpen || windowWidth > 768">
|
||||
<li class="ekhnlogo">
|
||||
<img src="/images/facettenkreuz.png" class="facettenkreuz" alt="EKHN" />
|
||||
</li>
|
||||
<li v-for="item in menu" :key="item.name">
|
||||
<router-link :to="item.link" v-if="item.link" @click="closeMenu" class="nav-link">
|
||||
{{ item.name }}
|
||||
</router-link>
|
||||
<span v-if="!item.link" class="pointer">
|
||||
<span
|
||||
v-if="!item.link"
|
||||
class="nav-link pointer"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="toggleSubmenu(item.name)"
|
||||
@keydown.enter.prevent="toggleSubmenu(item.name)"
|
||||
@keydown.space.prevent="toggleSubmenu(item.name)"
|
||||
:aria-expanded="String(!!isSubmenuOpen[item.name])"
|
||||
>
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<transition name="fade">
|
||||
@@ -38,16 +56,20 @@ export default {
|
||||
const windowWidth = ref(window.innerWidth);
|
||||
|
||||
const menu = computed(() => {
|
||||
return store.state.menuData.filter(item => {
|
||||
return (store.state.menuData || []).map((item) => {
|
||||
const submenu = Array.isArray(item.submenu)
|
||||
? item.submenu.filter(
|
||||
(subitem) => subitem.showInMenu && (!subitem.requiresAuth || store.getters.isLoggedIn)
|
||||
)
|
||||
: item.submenu;
|
||||
return { ...item, submenu };
|
||||
}).filter(item => {
|
||||
if (!item.showInMenu) {
|
||||
return false;
|
||||
}
|
||||
if (item.requiresAuth && !store.getters.isLoggedIn) {
|
||||
return false;
|
||||
}
|
||||
if (item.submenu) {
|
||||
item.submenu = item.submenu.filter(subitem => subitem.showInMenu && (!subitem.requiresAuth || store.getters.isLoggedIn));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
@@ -102,25 +124,34 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.navbar {
|
||||
background-color: #9400ff;
|
||||
background-color: var(--color-brand-primary);
|
||||
overflow: visible;
|
||||
min-height: 31px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
margin: 0.1em 0.75em 9px 0.75em;
|
||||
box-shadow: 0 0 2px 5px #9400ff;
|
||||
width: calc(100% - (var(--space-3) * 2));
|
||||
margin: var(--space-1) var(--space-3) var(--space-3) var(--space-3);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 0 2px var(--color-brand-primary);
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
background-color: #9400ff;
|
||||
color: white;
|
||||
background-color: var(--color-brand-primary);
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 14px 20px;
|
||||
text-align: center;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
display: none;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.menu-toggle__icon {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.navbar ul {
|
||||
@@ -128,24 +159,39 @@ export default {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.navbar li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-link,
|
||||
.navbar a,
|
||||
.navbar li>span {
|
||||
.navbar li > span {
|
||||
display: block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 6px 20px;
|
||||
padding: 10px 14px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 3px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.navbar a:hover {
|
||||
background-color: #7a00d1;
|
||||
.navbar a:hover,
|
||||
.nav-link:hover {
|
||||
background-color: var(--color-brand-primary-hover);
|
||||
}
|
||||
|
||||
.navbar a:focus-visible,
|
||||
.menu-toggle:focus-visible {
|
||||
outline-color: #fff;
|
||||
}
|
||||
|
||||
.navbar :deep(.router-link-exact-active) {
|
||||
background-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
@@ -156,7 +202,7 @@ export default {
|
||||
|
||||
.dropdown-content {
|
||||
position: absolute;
|
||||
background-color: #9400ff;
|
||||
background-color: var(--color-brand-primary);
|
||||
min-width: 200px;
|
||||
z-index: 1;
|
||||
top: 100%;
|
||||
@@ -164,7 +210,9 @@ export default {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
||||
box-shadow: 2px 2px 4px #666;
|
||||
box-shadow: var(--shadow-dropdown);
|
||||
border-radius: 4px;
|
||||
padding: var(--space-1);
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
@@ -176,7 +224,7 @@ export default {
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {
|
||||
background-color: #7a00d1;
|
||||
background-color: var(--color-brand-primary-hover);
|
||||
}
|
||||
|
||||
.navbar li:hover .dropdown-content {
|
||||
@@ -205,6 +253,8 @@ export default {
|
||||
|
||||
.navbar ul {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.navbar li {
|
||||
@@ -214,11 +264,12 @@ export default {
|
||||
.navbar a,
|
||||
.navbar li>span {
|
||||
text-align: left;
|
||||
padding: 14px 20px;
|
||||
padding: 14px 16px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: block;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
@@ -226,12 +277,12 @@ export default {
|
||||
box-shadow: none;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
display: none;
|
||||
padding-left: 1em;
|
||||
padding-left: var(--space-4);
|
||||
padding-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
.navbar li:hover .dropdown-content {
|
||||
display: block;
|
||||
.navbar :deep(.router-link-exact-active) {
|
||||
background-color: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,12 +291,16 @@ export default {
|
||||
}
|
||||
|
||||
.facettenkreuz {
|
||||
max-width:30px;
|
||||
max-height:30px;
|
||||
position: fixed;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: block;
|
||||
margin: 0 var(--space-2);
|
||||
}
|
||||
|
||||
.ekhnlogo {
|
||||
width: 32px;
|
||||
width: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<span class="close" @click="closeDialog">×</span>
|
||||
<h2>Datei zum Download hinzufügen</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="file-select">Datei auswählen:</label>
|
||||
@@ -16,6 +17,7 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button @click="confirm">Hinzufügen</button>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<span class="close" @click="closeDialog">×</span>
|
||||
<h2>Link hinzufügen</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="link-url">URL:</label>
|
||||
@@ -20,6 +21,7 @@
|
||||
<input id="link-text" v-model="text" type="text" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button @click="confirm">Hinzufügen</button>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<h2>Veranstaltung Formular</h2>
|
||||
<form @submit.prevent="saveEvent">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><label for="name">Name:</label></td>
|
||||
<td><input type="text" id="name" v-model="eventData.name" required></td>
|
||||
@@ -99,6 +100,7 @@
|
||||
<button type="submit">Speichern</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<select id="parent-id" v-model.number="selectedMenuItem.parent_id">
|
||||
<option value="-1">Ohne Elternelement</option>
|
||||
<option v-for="item in flattenedMenuData" :key="item.id" :value="item.id">
|
||||
<span v-html="getIndentedName(item)"></span>
|
||||
{{ getIndentedName(item) }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
@@ -204,7 +204,7 @@ export default {
|
||||
};
|
||||
|
||||
const getIndentedName = (item) => {
|
||||
return ' '.repeat(item.indent * 2) + item.name;
|
||||
return '\u00A0'.repeat(item.indent * 2) + item.name;
|
||||
};
|
||||
|
||||
const flattenedMenuData = computed(() => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import AppComponent from './AppComponent.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
import axios from './axios';
|
||||
import './assets/css/design-tokens.css';
|
||||
import './assets/css/editor.css';
|
||||
|
||||
const app = createApp(AppComponent);
|
||||
|
||||
Reference in New Issue
Block a user