Update timestamps in nitro.json and latest.json; modify client manifest for asset management; enhance history and rules editing features in CMS with new templates and improved toolbar layout.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"date": "2025-10-23T13:09:34.497Z",
|
"date": "2025-10-23T13:58:10.357Z",
|
||||||
"preset": "node-server",
|
"preset": "node-server",
|
||||||
"framework": {
|
"framework": {
|
||||||
"name": "nuxt",
|
"name": "nuxt",
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"id":"6c41349c-774f-41fd-adb4-5ff53d7cd5dd","timestamp":1761224966199}
|
{"id":"5eacfda6-f6ed-4268-8599-129783c464db","timestamp":1761227881976}
|
||||||
@@ -318,7 +318,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "BSqQ6E0R.js",
|
"file": "BBtX9g-c.js",
|
||||||
"name": "entry",
|
"name": "entry",
|
||||||
"src": "node_modules/nuxt/dist/app/entry.js",
|
"src": "node_modules/nuxt/dist/app/entry.js",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
@@ -328,14 +328,14 @@ const client_manifest = {
|
|||||||
"node_modules/nuxt/dist/app/components/error-500.vue"
|
"node_modules/nuxt/dist/app/components/error-500.vue"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
"entry.D0FDDuVR.css"
|
"entry.WJcUQO4N.css"
|
||||||
],
|
],
|
||||||
"assets": [
|
"assets": [
|
||||||
"Harheimer TC.CKfYAfp1.svg"
|
"Harheimer TC.CKfYAfp1.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"entry.D0FDDuVR.css": {
|
"entry.WJcUQO4N.css": {
|
||||||
"file": "entry.D0FDDuVR.css",
|
"file": "entry.WJcUQO4N.css",
|
||||||
"resourceType": "style",
|
"resourceType": "style",
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true
|
"preload": true
|
||||||
@@ -365,7 +365,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "CtoHBsGq.js",
|
"file": "D7wLfWza.js",
|
||||||
"name": "benutzer",
|
"name": "benutzer",
|
||||||
"src": "pages/cms/benutzer.vue",
|
"src": "pages/cms/benutzer.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -435,7 +435,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "-SibdntI.js",
|
"file": "XVGNuni0.js",
|
||||||
"name": "mitgliedschaftsantraege",
|
"name": "mitgliedschaftsantraege",
|
||||||
"src": "pages/cms/mitgliedschaftsantraege.vue",
|
"src": "pages/cms/mitgliedschaftsantraege.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -463,7 +463,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "BP5itt78.js",
|
"file": "CHELWMKR.js",
|
||||||
"name": "termine",
|
"name": "termine",
|
||||||
"src": "pages/cms/termine.vue",
|
"src": "pages/cms/termine.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -481,7 +481,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "C8Sqpv2D.js",
|
"file": "lwS618zS.js",
|
||||||
"name": "tt-regeln",
|
"name": "tt-regeln",
|
||||||
"src": "pages/cms/tt-regeln.vue",
|
"src": "pages/cms/tt-regeln.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -719,7 +719,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "CmqI4hAm.js",
|
"file": "BSvOuZsL.js",
|
||||||
"name": "mitglieder",
|
"name": "mitglieder",
|
||||||
"src": "pages/mitgliederbereich/mitglieder.vue",
|
"src": "pages/mitgliederbereich/mitglieder.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -742,7 +742,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "DNeqJiJt.js",
|
"file": "DwIxbZay.js",
|
||||||
"name": "news",
|
"name": "news",
|
||||||
"src": "pages/mitgliederbereich/news.vue",
|
"src": "pages/mitgliederbereich/news.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
@@ -781,7 +781,7 @@ const client_manifest = {
|
|||||||
"module": true,
|
"module": true,
|
||||||
"prefetch": true,
|
"prefetch": true,
|
||||||
"preload": true,
|
"preload": true,
|
||||||
"file": "B5_KRoyE.js",
|
"file": "D9eqLvUd.js",
|
||||||
"name": "mitgliedschaft",
|
"name": "mitgliedschaft",
|
||||||
"src": "pages/mitgliedschaft.vue",
|
"src": "pages/mitgliedschaft.vue",
|
||||||
"isDynamicEntry": true,
|
"isDynamicEntry": true,
|
||||||
|
|||||||
@@ -521,7 +521,7 @@ const _routes = [
|
|||||||
name: "cms-tt-regeln",
|
name: "cms-tt-regeln",
|
||||||
path: "/cms/tt-regeln",
|
path: "/cms/tt-regeln",
|
||||||
meta: { "middleware": "auth" },
|
meta: { "middleware": "auth" },
|
||||||
component: () => import('./tt-regeln-CzdSgLJc.mjs')
|
component: () => import('./tt-regeln-CMXBlU5A.mjs')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "cms-ueber-uns",
|
name: "cms-ueber-uns",
|
||||||
@@ -642,7 +642,7 @@ const _routes = [
|
|||||||
{
|
{
|
||||||
name: "cms-mitgliedschaftsantraege",
|
name: "cms-mitgliedschaftsantraege",
|
||||||
path: "/cms/mitgliedschaftsantraege",
|
path: "/cms/mitgliedschaftsantraege",
|
||||||
component: () => import('./mitgliedschaftsantraege-UTBvvWQL.mjs')
|
component: () => import('./mitgliedschaftsantraege-DnRsAaeb.mjs')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mitgliederbereich-mitglieder",
|
name: "mitgliederbereich-mitglieder",
|
||||||
@@ -1462,7 +1462,7 @@ function normalizeSlot(slot, data) {
|
|||||||
return slotContent.length === 1 ? h(slotContent[0]) : h(Fragment, void 0, slotContent);
|
return slotContent.length === 1 ? h(slotContent[0]) : h(Fragment, void 0, slotContent);
|
||||||
}
|
}
|
||||||
const _imports_1 = "" + __buildAssetsURL("Harheimer TC.CKfYAfp1.svg");
|
const _imports_1 = "" + __buildAssetsURL("Harheimer TC.CKfYAfp1.svg");
|
||||||
const _sfc_main$4 = {
|
const _sfc_main$5 = {
|
||||||
__name: "Navigation",
|
__name: "Navigation",
|
||||||
__ssrInlineRender: true,
|
__ssrInlineRender: true,
|
||||||
setup(__props) {
|
setup(__props) {
|
||||||
@@ -2736,14 +2736,14 @@ const _sfc_main$4 = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const _sfc_setup$4 = _sfc_main$4.setup;
|
const _sfc_setup$5 = _sfc_main$5.setup;
|
||||||
_sfc_main$4.setup = (props, ctx) => {
|
_sfc_main$5.setup = (props, ctx) => {
|
||||||
const ssrContext = useSSRContext();
|
const ssrContext = useSSRContext();
|
||||||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/Navigation.vue");
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/Navigation.vue");
|
||||||
return _sfc_setup$4 ? _sfc_setup$4(props, ctx) : void 0;
|
return _sfc_setup$5 ? _sfc_setup$5(props, ctx) : void 0;
|
||||||
};
|
};
|
||||||
const Navigation = Object.assign(_sfc_main$4, { __name: "Navigation" });
|
const Navigation = Object.assign(_sfc_main$5, { __name: "Navigation" });
|
||||||
const _sfc_main$3 = {
|
const _sfc_main$4 = {
|
||||||
__name: "Footer",
|
__name: "Footer",
|
||||||
__ssrInlineRender: true,
|
__ssrInlineRender: true,
|
||||||
setup(__props) {
|
setup(__props) {
|
||||||
@@ -2859,13 +2859,74 @@ const _sfc_main$3 = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const _sfc_setup$4 = _sfc_main$4.setup;
|
||||||
|
_sfc_main$4.setup = (props, ctx) => {
|
||||||
|
const ssrContext = useSSRContext();
|
||||||
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/Footer.vue");
|
||||||
|
return _sfc_setup$4 ? _sfc_setup$4(props, ctx) : void 0;
|
||||||
|
};
|
||||||
|
const Footer = Object.assign(_sfc_main$4, { __name: "Footer" });
|
||||||
|
const _sfc_main$3 = {
|
||||||
|
__name: "ModalDialog",
|
||||||
|
__ssrInlineRender: true,
|
||||||
|
setup(__props) {
|
||||||
|
const showSuccess = ref(false);
|
||||||
|
const showError2 = ref(false);
|
||||||
|
const showConfirm = ref(false);
|
||||||
|
const successTitle = ref("");
|
||||||
|
const successMessage = ref("");
|
||||||
|
const errorTitle = ref("");
|
||||||
|
const errorMessage = ref("");
|
||||||
|
const confirmTitle = ref("");
|
||||||
|
const confirmMessage = ref("");
|
||||||
|
const confirmAction = ref(null);
|
||||||
|
const showSuccessModal = (title, message) => {
|
||||||
|
successTitle.value = title;
|
||||||
|
successMessage.value = message;
|
||||||
|
showSuccess.value = true;
|
||||||
|
};
|
||||||
|
const showErrorModal = (title, message) => {
|
||||||
|
errorTitle.value = title;
|
||||||
|
errorMessage.value = message;
|
||||||
|
showError2.value = true;
|
||||||
|
};
|
||||||
|
const showConfirmModal = (title, message, action) => {
|
||||||
|
confirmTitle.value = title;
|
||||||
|
confirmMessage.value = message;
|
||||||
|
confirmAction.value = action;
|
||||||
|
showConfirm.value = true;
|
||||||
|
};
|
||||||
|
provide("showSuccessModal", showSuccessModal);
|
||||||
|
provide("showErrorModal", showErrorModal);
|
||||||
|
provide("showConfirmModal", showConfirmModal);
|
||||||
|
return (_ctx, _push, _parent, _attrs) => {
|
||||||
|
_push(`<!--[-->`);
|
||||||
|
if (showSuccess.value) {
|
||||||
|
_push(`<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"><div class="bg-white rounded-lg max-w-md w-full p-6"><div class="flex items-center mb-4"><div class="flex-shrink-0 w-10 h-10 mx-auto bg-green-100 rounded-full flex items-center justify-center"><svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg></div></div><div class="text-center"><h3 class="text-lg font-medium text-gray-900 mb-2">${ssrInterpolate(successTitle.value)}</h3><p class="text-sm text-gray-600 mb-6">${ssrInterpolate(successMessage.value)}</p><div class="flex justify-center"><button class="px-6 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors"> OK </button></div></div></div></div>`);
|
||||||
|
} else {
|
||||||
|
_push(`<!---->`);
|
||||||
|
}
|
||||||
|
if (showError2.value) {
|
||||||
|
_push(`<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"><div class="bg-white rounded-lg max-w-md w-full p-6"><div class="flex items-center mb-4"><div class="flex-shrink-0 w-10 h-10 mx-auto bg-red-100 rounded-full flex items-center justify-center"><svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg></div></div><div class="text-center"><h3 class="text-lg font-medium text-gray-900 mb-2">${ssrInterpolate(errorTitle.value)}</h3><p class="text-sm text-gray-600 mb-6">${ssrInterpolate(errorMessage.value)}</p><div class="flex justify-center"><button class="px-6 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors"> OK </button></div></div></div></div>`);
|
||||||
|
} else {
|
||||||
|
_push(`<!---->`);
|
||||||
|
}
|
||||||
|
if (showConfirm.value) {
|
||||||
|
_push(`<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"><div class="bg-white rounded-lg max-w-md w-full p-6"><div class="flex items-center mb-4"><div class="flex-shrink-0 w-10 h-10 mx-auto bg-yellow-100 rounded-full flex items-center justify-center"><svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path></svg></div></div><div class="text-center"><h3 class="text-lg font-medium text-gray-900 mb-2">${ssrInterpolate(confirmTitle.value)}</h3><p class="text-sm text-gray-600 mb-6">${ssrInterpolate(confirmMessage.value)}</p><div class="flex space-x-3 justify-center"><button class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"> Abbrechen </button><button class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors"> Bestätigen </button></div></div></div></div>`);
|
||||||
|
} else {
|
||||||
|
_push(`<!---->`);
|
||||||
|
}
|
||||||
|
_push(`<!--]-->`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
const _sfc_setup$3 = _sfc_main$3.setup;
|
const _sfc_setup$3 = _sfc_main$3.setup;
|
||||||
_sfc_main$3.setup = (props, ctx) => {
|
_sfc_main$3.setup = (props, ctx) => {
|
||||||
const ssrContext = useSSRContext();
|
const ssrContext = useSSRContext();
|
||||||
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/Footer.vue");
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/ModalDialog.vue");
|
||||||
return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0;
|
return _sfc_setup$3 ? _sfc_setup$3(props, ctx) : void 0;
|
||||||
};
|
};
|
||||||
const Footer = Object.assign(_sfc_main$3, { __name: "Footer" });
|
const ModalDialog = Object.assign(_sfc_main$3, { __name: "ModalDialog" });
|
||||||
const _sfc_main$2 = {
|
const _sfc_main$2 = {
|
||||||
__name: "app",
|
__name: "app",
|
||||||
__ssrInlineRender: true,
|
__ssrInlineRender: true,
|
||||||
@@ -2878,6 +2939,7 @@ const _sfc_main$2 = {
|
|||||||
_push(ssrRenderComponent(_component_NuxtPage, null, null, _parent));
|
_push(ssrRenderComponent(_component_NuxtPage, null, null, _parent));
|
||||||
_push(`</main>`);
|
_push(`</main>`);
|
||||||
_push(ssrRenderComponent(Footer, null, null, _parent));
|
_push(ssrRenderComponent(Footer, null, null, _parent));
|
||||||
|
_push(ssrRenderComponent(ModalDialog, null, null, _parent));
|
||||||
_push(`</div>`);
|
_push(`</div>`);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"server.mjs","sources":["../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Ffetch.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fglobal-polyfills.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fnuxt.config.mjs","../../../../node_modules/nuxt/dist/app/nuxt.js","../../../../node_modules/nuxt/dist/app/components/injections.js","../../../../node_modules/nuxt/dist/app/utils.js","../../../../node_modules/nuxt/dist/app/composables/router.js","../../../../node_modules/nuxt/dist/app/composables/error.js","../../../../node_modules/nuxt/dist/app/composables/manifest.js","../../../../node_modules/nuxt/dist/app/composables/payload.js","../../../../node_modules/@pinia/nuxt/dist/runtime/payload-plugin.js","../../../../node_modules/nuxt/dist/head/runtime/plugins/unhead.js","../../../../node_modules/nuxt/dist/pages/runtime/utils.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Froutes.mjs","../../../../node_modules/nuxt/dist/app/components/utils.js","../../../../node_modules/nuxt/dist/pages/runtime/router.options.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Frouter.options.mjs","../../../../node_modules/nuxt/dist/pages/runtime/validate.js","../../../../stores/auth.js","../../../../middleware/auth.global.js","../../../../node_modules/nuxt/dist/app/middleware/manifest-route-rule.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fmiddleware.mjs","../../../../node_modules/nuxt/dist/pages/runtime/plugins/router.js","../../../../node_modules/nuxt/dist/app/plugins/revive-payload.server.js","../../../../node_modules/nuxt/dist/app/components/server-placeholder.js","../../../../node_modules/nuxt/dist/app/components/client-only.js","../../../../node_modules/nuxt/dist/app/components/nuxt-link.js","../../../../node_modules/@pinia/nuxt/dist/runtime/plugin.vue3.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fcomponents.plugin.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fplugins.server.mjs","../../../../node_modules/nuxt/dist/app/components/route-provider.js","../../../../node_modules/nuxt/dist/pages/runtime/page.js","../../../../assets/images/logos/Harheimer TC.svg","../../../../components/Navigation.vue","../../../../components/Footer.vue","../../../../app.vue","../../../../node_modules/nuxt/dist/app/components/nuxt-error-page.vue","../../../../node_modules/nuxt/dist/app/components/nuxt-root.vue","../../../../node_modules/nuxt/dist/app/entry.js"],"sourcesContent":null,"names":["$fetch","plugin","provide","plugins","createH3Error","createRadixRouter","login1RYyYL8mxx17qR_nmdKvywxx7lKOLXMFu8pTLfvTLYwMeta","indexBAhz9QmEiLA6QGDd6cSKraFX9E0RhZLvBUZorkJgAVkMeta","termineaIqWCm431cOVikspmAA3_6UhrHiffuFLM_t95ydtEd4Meta","einstellungen3Fhl_VQPzY4eklctozY70Drhj8cWMt_FVlyEKQh9aAAMeta","newsPHTXuxdDl4fgPHQQbukE_XsTEemyPOWVSYs64f8qjC4Meta","indexqVbusfljIJ04j42RIA_KP4bSP7XytQIXdqcVfR3kPUAMeta","profilyVBy_UvZ8KvchY44_0SJbB0NHOad6MC_S9C8wfDdUWEMeta","mitglieder9TWncRC_sSS_zPWzxBDlRiNjjFojXSJny_uernMe_tAMeta","__executeAsync","createRouter","entry","payload_plugin_1_bEQpMjikuQhbV8UJ0PxUqmSvPdmV1jDa5DURnKW4M","router_GNCWhvtYfLTYRZZ135CdFAEjxdMexN0ixiUYCAN_tpw","plugin_vue3_CQ_pO3THrTGIeYc0dvC91V75hY8qpo9B_8yZzOW5SFs","useRoute","_ssrRenderAttrs","_mergeProps","_push","_parent","_ssrRenderAttr","_imports_0","_createVNode","_ssrRenderClass","_unref","_ssrRenderList","_ssrInterpolate","_createTextVNode","_toDisplayString","useRouter","_ssrRenderComponent","ErrorComponent","RootComponent"],"mappings":"","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,20,21,22,23,24,25,26,27,28,29,30,31,36,37,38]}
|
{"version":3,"file":"server.mjs","sources":["../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Ffetch.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fglobal-polyfills.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fnuxt.config.mjs","../../../../node_modules/nuxt/dist/app/nuxt.js","../../../../node_modules/nuxt/dist/app/components/injections.js","../../../../node_modules/nuxt/dist/app/utils.js","../../../../node_modules/nuxt/dist/app/composables/router.js","../../../../node_modules/nuxt/dist/app/composables/error.js","../../../../node_modules/nuxt/dist/app/composables/manifest.js","../../../../node_modules/nuxt/dist/app/composables/payload.js","../../../../node_modules/@pinia/nuxt/dist/runtime/payload-plugin.js","../../../../node_modules/nuxt/dist/head/runtime/plugins/unhead.js","../../../../node_modules/nuxt/dist/pages/runtime/utils.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Froutes.mjs","../../../../node_modules/nuxt/dist/app/components/utils.js","../../../../node_modules/nuxt/dist/pages/runtime/router.options.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Frouter.options.mjs","../../../../node_modules/nuxt/dist/pages/runtime/validate.js","../../../../stores/auth.js","../../../../middleware/auth.global.js","../../../../node_modules/nuxt/dist/app/middleware/manifest-route-rule.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fmiddleware.mjs","../../../../node_modules/nuxt/dist/pages/runtime/plugins/router.js","../../../../node_modules/nuxt/dist/app/plugins/revive-payload.server.js","../../../../node_modules/nuxt/dist/app/components/server-placeholder.js","../../../../node_modules/nuxt/dist/app/components/client-only.js","../../../../node_modules/nuxt/dist/app/components/nuxt-link.js","../../../../node_modules/@pinia/nuxt/dist/runtime/plugin.vue3.js","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fcomponents.plugin.mjs","../../../../virtual:nuxt:%2Fmnt%2Fshare%2Ftorsten%2FPrograms%2Fharheimertc%2Fnode_modules%2F.cache%2Fnuxt%2F.nuxt%2Fplugins.server.mjs","../../../../node_modules/nuxt/dist/app/components/route-provider.js","../../../../node_modules/nuxt/dist/pages/runtime/page.js","../../../../assets/images/logos/Harheimer TC.svg","../../../../components/Navigation.vue","../../../../components/Footer.vue","../../../../components/ModalDialog.vue","../../../../app.vue","../../../../node_modules/nuxt/dist/app/components/nuxt-error-page.vue","../../../../node_modules/nuxt/dist/app/components/nuxt-root.vue","../../../../node_modules/nuxt/dist/app/entry.js"],"sourcesContent":null,"names":["$fetch","plugin","provide","plugins","createH3Error","createRadixRouter","login1RYyYL8mxx17qR_nmdKvywxx7lKOLXMFu8pTLfvTLYwMeta","indexBAhz9QmEiLA6QGDd6cSKraFX9E0RhZLvBUZorkJgAVkMeta","termineaIqWCm431cOVikspmAA3_6UhrHiffuFLM_t95ydtEd4Meta","einstellungen3Fhl_VQPzY4eklctozY70Drhj8cWMt_FVlyEKQh9aAAMeta","newsPHTXuxdDl4fgPHQQbukE_XsTEemyPOWVSYs64f8qjC4Meta","indexqVbusfljIJ04j42RIA_KP4bSP7XytQIXdqcVfR3kPUAMeta","profilyVBy_UvZ8KvchY44_0SJbB0NHOad6MC_S9C8wfDdUWEMeta","mitglieder9TWncRC_sSS_zPWzxBDlRiNjjFojXSJny_uernMe_tAMeta","__executeAsync","createRouter","entry","payload_plugin_1_bEQpMjikuQhbV8UJ0PxUqmSvPdmV1jDa5DURnKW4M","router_GNCWhvtYfLTYRZZ135CdFAEjxdMexN0ixiUYCAN_tpw","plugin_vue3_CQ_pO3THrTGIeYc0dvC91V75hY8qpo9B_8yZzOW5SFs","useRoute","_ssrRenderAttrs","_mergeProps","_push","_parent","_ssrRenderAttr","_imports_0","_createVNode","_ssrRenderClass","_unref","_ssrRenderList","_ssrInterpolate","_createTextVNode","_toDisplayString","useRouter","_ssrRenderComponent","showError","ErrorComponent","RootComponent"],"mappings":"","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,20,21,22,23,24,25,26,27,28,29,30,31,37,38,39]}
|
||||||
@@ -2,10 +2,10 @@ const interopDefault = r => r.default || r || [];
|
|||||||
const styles = {
|
const styles = {
|
||||||
"node_modules/nuxt/dist/app/components/error-404.vue": () => import('./error-404-styles.BsF5Lbhq.mjs').then(interopDefault),
|
"node_modules/nuxt/dist/app/components/error-404.vue": () => import('./error-404-styles.BsF5Lbhq.mjs').then(interopDefault),
|
||||||
"node_modules/nuxt/dist/app/components/error-500.vue": () => import('./error-500-styles.Dccc6iq5.mjs').then(interopDefault),
|
"node_modules/nuxt/dist/app/components/error-500.vue": () => import('./error-500-styles.Dccc6iq5.mjs').then(interopDefault),
|
||||||
"node_modules/nuxt/dist/app/components/error-404.vue?vue&type=style&index=0&scoped=b728498f&lang.css": () => import('./error-404-styles.BsF5Lbhq.mjs').then(interopDefault),
|
|
||||||
"node_modules/nuxt/dist/app/components/error-500.vue?vue&type=style&index=0&scoped=70d84538&lang.css": () => import('./error-500-styles.Dccc6iq5.mjs').then(interopDefault),
|
|
||||||
"components/Hero.vue": () => import('./Hero-styles.03iOjY05.mjs').then(interopDefault),
|
"components/Hero.vue": () => import('./Hero-styles.03iOjY05.mjs').then(interopDefault),
|
||||||
"components/PublicNews.vue": () => import('./PublicNews-styles.nhqk16g5.mjs').then(interopDefault),
|
"components/PublicNews.vue": () => import('./PublicNews-styles.nhqk16g5.mjs').then(interopDefault),
|
||||||
|
"node_modules/nuxt/dist/app/components/error-404.vue?vue&type=style&index=0&scoped=b728498f&lang.css": () => import('./error-404-styles.BsF5Lbhq.mjs').then(interopDefault),
|
||||||
|
"node_modules/nuxt/dist/app/components/error-500.vue?vue&type=style&index=0&scoped=70d84538&lang.css": () => import('./error-500-styles.Dccc6iq5.mjs').then(interopDefault),
|
||||||
"components/Hero.vue?vue&type=style&index=0&scoped=779d39d7&lang.css": () => import('./Hero-styles.03iOjY05.mjs').then(interopDefault),
|
"components/Hero.vue?vue&type=style&index=0&scoped=779d39d7&lang.css": () => import('./Hero-styles.03iOjY05.mjs').then(interopDefault),
|
||||||
"components/PublicNews.vue?vue&type=style&index=0&scoped=f894f108&lang.css": () => import('./PublicNews-styles.nhqk16g5.mjs').then(interopDefault)
|
"components/PublicNews.vue?vue&type=style&index=0&scoped=f894f108&lang.css": () => import('./PublicNews-styles.nhqk16g5.mjs').then(interopDefault)
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -272,7 +272,7 @@ async function renderInlineStyles(usedModules) {
|
|||||||
|
|
||||||
const renderSSRHeadOptions = {"omitLineBreaks":true};
|
const renderSSRHeadOptions = {"omitLineBreaks":true};
|
||||||
|
|
||||||
const entryFileName = "BSqQ6E0R.js";
|
const entryFileName = "BBtX9g-c.js";
|
||||||
|
|
||||||
globalThis.__buildAssetsURL = buildAssetsURL;
|
globalThis.__buildAssetsURL = buildAssetsURL;
|
||||||
globalThis.__publicAssetsURL = publicAssetsURL;
|
globalThis.__publicAssetsURL = publicAssetsURL;
|
||||||
|
|||||||
@@ -13,18 +13,38 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fixed Toolbar below header -->
|
<!-- Fixed Toolbar below header -->
|
||||||
<div class="fixed top-28 sm:top-32 left-0 right-0 z-30 bg-white border-b border-gray-200 shadow-sm">
|
<div class="fixed left-0 right-0 z-30 bg-white border-b border-gray-200 shadow-sm" style="top: 9.5rem;">
|
||||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex flex-wrap items-center gap-1 sm:gap-2 py-1.5 sm:py-2">
|
<div class="flex flex-wrap items-center gap-1 sm:gap-2 py-1.5 sm:py-2">
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('bold')"><strong>B</strong></button>
|
<!-- Formatierung -->
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('italic')"><em>I</em></button>
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(1)">H1</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('bold')"><strong>B</strong></button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(2)">H2</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('italic')"><em>I</em></button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(3)">H3</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(1)">H1</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertUnorderedList')">•</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(2)">H2</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertOrderedList')">1.</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(3)">H3</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="createLink()">Link</button>
|
</div>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="removeFormat()">Clear</button>
|
|
||||||
|
<!-- Listen -->
|
||||||
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertUnorderedList')">•</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertOrderedList')">1.</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Schnellzugriff für Geschichts-Abschnitte -->
|
||||||
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-gray-100 hover:bg-gray-200 text-gray-700 text-xs sm:text-sm" @click="insertHistoryTemplate('generic')">Neuer Abschnitt</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-blue-100 hover:bg-blue-200 text-blue-700 text-xs sm:text-sm" @click="insertHistoryTemplate('founding')">Gründung</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-green-100 hover:bg-green-200 text-green-700 text-xs sm:text-sm" @click="insertHistoryTemplate('milestone')">Meilenstein</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-yellow-100 hover:bg-yellow-200 text-yellow-700 text-xs sm:text-sm" @click="insertHistoryTemplate('achievement')">Erfolg</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-red-100 hover:bg-red-200 text-red-700 text-xs sm:text-sm" @click="deleteCurrentSection()">Abschnitt löschen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Weitere Tools -->
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="createLink()">Link</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="removeFormat()">Clear</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,5 +108,235 @@ function removeFormat() {
|
|||||||
document.execCommand('removeFormat', false, null)
|
document.execCommand('removeFormat', false, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function insertHistoryTemplate(type) {
|
||||||
|
const editorElement = editor.value
|
||||||
|
if (!editorElement) return
|
||||||
|
|
||||||
|
let template = ''
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'generic':
|
||||||
|
template = `
|
||||||
|
<div class="bg-gray-50/30 p-6 rounded-xl shadow-lg border-l-4 border-primary-600">
|
||||||
|
<h3 class="text-xl font-display font-bold text-gray-900 mb-3">Neuer Geschichts-Abschnitt</h3>
|
||||||
|
<p class="text-gray-600 mb-3"><strong>Zeitraum:</strong> [Jahr oder Zeitraum]<br><strong>Ereignis:</strong> [Was ist passiert?]<br><strong>Bedeutung:</strong> [Warum war das wichtig?]</p>
|
||||||
|
<p class="text-gray-600"><strong>Details:</strong> [Weitere Informationen hier eingeben...]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
break
|
||||||
|
case 'founding':
|
||||||
|
template = `
|
||||||
|
<div class="bg-blue-50/30 p-6 rounded-xl shadow-lg border-l-4 border-primary-600">
|
||||||
|
<h3 class="text-xl font-display font-bold text-gray-900 mb-3">Gründung des Vereins</h3>
|
||||||
|
<p class="text-gray-600 mb-3"><strong>Datum:</strong> [Gründungsdatum]<br><strong>Gründer:</strong> [Wer hat den Verein gegründet?]<br><strong>Zweck:</strong> [Was war das Ziel?]</p>
|
||||||
|
<p class="text-gray-600"><strong>Gründungsgeschichte:</strong> [Wie kam es zur Gründung? Was waren die Umstände?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
break
|
||||||
|
case 'milestone':
|
||||||
|
template = `
|
||||||
|
<div class="bg-green-50/30 p-6 rounded-xl shadow-lg border-l-4 border-primary-600">
|
||||||
|
<h3 class="text-xl font-display font-bold text-gray-900 mb-3">Wichtiger Meilenstein</h3>
|
||||||
|
<p class="text-gray-600 mb-3"><strong>Jahr:</strong> [Wann ist das passiert?]<br><strong>Ereignis:</strong> [Was war der Meilenstein?]<br><strong>Auswirkung:</strong> [Wie hat das den Verein verändert?]</p>
|
||||||
|
<p class="text-gray-600"><strong>Hintergrund:</strong> [Was führte zu diesem Ereignis? Wie wurde es erreicht?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
break
|
||||||
|
case 'achievement':
|
||||||
|
template = `
|
||||||
|
<div class="bg-yellow-50/30 p-6 rounded-xl shadow-lg border-l-4 border-primary-600">
|
||||||
|
<h3 class="text-xl font-display font-bold text-gray-900 mb-3">Großer Erfolg</h3>
|
||||||
|
<p class="text-gray-600 mb-3"><strong>Jahr:</strong> [Wann war der Erfolg?]<br><strong>Erfolg:</strong> [Was wurde erreicht?]<br><strong>Beteiligte:</strong> [Wer war daran beteiligt?]</p>
|
||||||
|
<p class="text-gray-600"><strong>Details:</strong> [Wie wurde der Erfolg erreicht? Was war besonders bemerkenswert?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editor fokussieren
|
||||||
|
editorElement.focus()
|
||||||
|
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection.rangeCount > 0) {
|
||||||
|
const range = selection.getRangeAt(0)
|
||||||
|
|
||||||
|
// Prüfen ob der Cursor im Editor ist
|
||||||
|
if (editorElement.contains(range.commonAncestorContainer) || editorElement === range.commonAncestorContainer) {
|
||||||
|
// Aktuelles Element finden
|
||||||
|
let currentElement = range.commonAncestorContainer
|
||||||
|
|
||||||
|
// Falls es ein Text-Node ist, zum Parent-Element gehen
|
||||||
|
if (currentElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
currentElement = currentElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zum Geschichts-Abschnitt navigieren (div mit border-l-4 border-primary-600)
|
||||||
|
let sectionElement = currentElement
|
||||||
|
while (sectionElement && sectionElement !== editorElement) {
|
||||||
|
if (sectionElement.classList &&
|
||||||
|
sectionElement.classList.contains('border-l-4') &&
|
||||||
|
sectionElement.classList.contains('border-primary-600')) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sectionElement = sectionElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sectionElement && sectionElement !== editorElement &&
|
||||||
|
sectionElement.classList.contains('border-l-4') &&
|
||||||
|
sectionElement.classList.contains('border-primary-600')) {
|
||||||
|
|
||||||
|
// Wir sind in einem Geschichts-Abschnitt - neuen Abschnitt danach einfügen
|
||||||
|
const tempDiv = document.createElement('div')
|
||||||
|
tempDiv.innerHTML = template
|
||||||
|
|
||||||
|
// Suche nach dem ersten Element-Node (nicht Text-Node)
|
||||||
|
let newSection = null
|
||||||
|
for (let i = 0; i < tempDiv.childNodes.length; i++) {
|
||||||
|
if (tempDiv.childNodes[i].nodeType === Node.ELEMENT_NODE) {
|
||||||
|
newSection = tempDiv.childNodes[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSection) {
|
||||||
|
// Nach dem aktuellen Abschnitt einfügen
|
||||||
|
if (sectionElement.nextSibling) {
|
||||||
|
sectionElement.parentElement.insertBefore(newSection, sectionElement.nextSibling)
|
||||||
|
} else {
|
||||||
|
sectionElement.parentElement.appendChild(newSection)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cursor in das neue Element setzen
|
||||||
|
const newRange = document.createRange()
|
||||||
|
const titleElement = newSection.querySelector('h3')
|
||||||
|
if (titleElement) {
|
||||||
|
newRange.setStart(titleElement, 0)
|
||||||
|
newRange.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(newRange)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('No valid element found in template');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Kein Geschichts-Abschnitt gefunden - suche nach dem nächsten Geschichts-Abschnitt
|
||||||
|
let nextSection = null
|
||||||
|
let walker = document.createTreeWalker(
|
||||||
|
editorElement,
|
||||||
|
NodeFilter.SHOW_ELEMENT,
|
||||||
|
{
|
||||||
|
acceptNode: function(node) {
|
||||||
|
if (node.classList &&
|
||||||
|
node.classList.contains('border-l-4') &&
|
||||||
|
node.classList.contains('border-primary-600')) {
|
||||||
|
return NodeFilter.FILTER_ACCEPT
|
||||||
|
}
|
||||||
|
return NodeFilter.FILTER_SKIP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Finde den ersten Geschichts-Abschnitt nach dem aktuellen Element
|
||||||
|
let node = walker.nextNode()
|
||||||
|
while (node) {
|
||||||
|
if (currentElement.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING) {
|
||||||
|
nextSection = node
|
||||||
|
break
|
||||||
|
}
|
||||||
|
node = walker.nextNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempDiv = document.createElement('div')
|
||||||
|
tempDiv.innerHTML = template
|
||||||
|
|
||||||
|
// Suche nach dem ersten Element-Node (nicht Text-Node)
|
||||||
|
let newSection = null
|
||||||
|
for (let i = 0; i < tempDiv.childNodes.length; i++) {
|
||||||
|
if (tempDiv.childNodes[i].nodeType === Node.ELEMENT_NODE) {
|
||||||
|
newSection = tempDiv.childNodes[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSection) {
|
||||||
|
if (nextSection) {
|
||||||
|
// Vor dem nächsten Geschichts-Abschnitt einfügen
|
||||||
|
nextSection.parentElement.insertBefore(newSection, nextSection)
|
||||||
|
} else {
|
||||||
|
// Kein nächster Abschnitt gefunden - am Ende einfügen
|
||||||
|
editorElement.appendChild(newSection)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cursor in das neue Element setzen
|
||||||
|
const newRange = document.createRange()
|
||||||
|
const titleElement = newSection.querySelector('h3')
|
||||||
|
if (titleElement) {
|
||||||
|
newRange.setStart(titleElement, 0)
|
||||||
|
newRange.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(newRange)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('No valid element found in template');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Cursor ist nicht im Editor - Template am Ende einfügen
|
||||||
|
editorElement.innerHTML += template
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Keine Auswahl - Template am Ende einfügen
|
||||||
|
editorElement.innerHTML += template
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteCurrentSection() {
|
||||||
|
const editorElement = editor.value
|
||||||
|
if (!editorElement) return
|
||||||
|
|
||||||
|
// Editor fokussieren
|
||||||
|
editorElement.focus()
|
||||||
|
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection.rangeCount > 0) {
|
||||||
|
const range = selection.getRangeAt(0)
|
||||||
|
|
||||||
|
// Prüfen ob der Cursor im Editor ist
|
||||||
|
if (editorElement.contains(range.commonAncestorContainer) || editorElement === range.commonAncestorContainer) {
|
||||||
|
// Aktuelles Element finden
|
||||||
|
let currentElement = range.commonAncestorContainer
|
||||||
|
|
||||||
|
// Falls es ein Text-Node ist, zum Parent-Element gehen
|
||||||
|
if (currentElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
currentElement = currentElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zum Geschichts-Abschnitt navigieren (div mit border-l-4 border-primary-600)
|
||||||
|
let sectionElement = currentElement
|
||||||
|
while (sectionElement && !(sectionElement.classList.contains('border-l-4') && sectionElement.classList.contains('border-primary-600'))) {
|
||||||
|
sectionElement = sectionElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sectionElement && sectionElement.classList.contains('border-l-4') && sectionElement.classList.contains('border-primary-600')) {
|
||||||
|
// Geschichts-Abschnitt gefunden - löschen
|
||||||
|
sectionElement.remove()
|
||||||
|
|
||||||
|
// Cursor in das nächste Element setzen
|
||||||
|
const nextElement = editorElement.querySelector('.border-l-4.border-primary-600')
|
||||||
|
if (nextElement) {
|
||||||
|
const titleElement = nextElement.querySelector('h3')
|
||||||
|
if (titleElement) {
|
||||||
|
const newRange = document.createRange()
|
||||||
|
newRange.setStart(titleElement, 0)
|
||||||
|
newRange.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(newRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(load)
|
onMounted(load)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -13,33 +13,71 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fixed Toolbar below header -->
|
<!-- Fixed Toolbar below header -->
|
||||||
<div class="fixed top-28 sm:top-32 left-0 right-0 z-30 bg-white border-b border-gray-200 shadow-sm">
|
<div class="fixed left-0 right-0 z-30 bg-white border-b border-gray-200 shadow-sm" style="top: 9.5rem;">
|
||||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex flex-wrap items-center gap-1 sm:gap-2 py-1.5 sm:py-2">
|
<div class="flex flex-wrap items-center gap-1 sm:gap-2 py-1.5 sm:py-2">
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('bold')"><strong>B</strong></button>
|
<!-- Formatierung -->
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('italic')"><em>I</em></button>
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(1)">H1</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('bold')"><strong>B</strong></button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(2)">H2</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('italic')"><em>I</em></button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(3)">H3</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(1)">H1</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertUnorderedList')">•</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(2)">H2</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertOrderedList')">1.</button>
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="formatHeader(3)">H3</button>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="createLink()">Link</button>
|
</div>
|
||||||
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="removeFormat()">Clear</button>
|
|
||||||
|
<!-- Listen -->
|
||||||
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertUnorderedList')">•</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="format('insertOrderedList')">1.</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Schnellzugriff für Regeln -->
|
||||||
|
<div class="flex items-center gap-1 border-r pr-2 mr-2">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-gray-100 hover:bg-gray-200 text-gray-700 text-xs sm:text-sm" @click="insertRuleTemplate('generic')">Neue Regel</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-blue-100 hover:bg-blue-200 text-blue-700 text-xs sm:text-sm" @click="insertRuleTemplate('basic')">Grundregel</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-green-100 hover:bg-green-200 text-green-700 text-xs sm:text-sm" @click="insertRuleTemplate('penalty')">Strafregel</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-yellow-100 hover:bg-yellow-200 text-yellow-700 text-xs sm:text-sm" @click="insertRuleTemplate('service')">Aufschlag</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded bg-red-100 hover:bg-red-200 text-red-700 text-xs sm:text-sm" @click="deleteCurrentRule()">Regel löschen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Weitere Tools -->
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="createLink()">Link</button>
|
||||||
|
<button class="px-2 py-1 sm:px-3 sm:py-1 rounded border hover:bg-gray-50 text-xs sm:text-sm" @click="removeFormat()">Clear</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content with top padding -->
|
<!-- Content with top padding -->
|
||||||
<div class="pt-36 sm:pt-44 pb-16">
|
<div class="pb-16" style="padding-top: 12rem;">
|
||||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
|
||||||
|
<!-- Hilfe-Sektion -->
|
||||||
|
<div class="mb-6 bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||||
|
<h3 class="text-lg font-semibold text-blue-900 mb-2">💡 So arbeiten Sie mit Regel-Kästchen:</h3>
|
||||||
|
<div class="text-sm text-blue-800 space-y-2">
|
||||||
|
<p><strong>1. Neue Kästchen hinzufügen:</strong> Klicken Sie in ein bestehendes Kästchen und verwenden Sie die Buttons:</p>
|
||||||
|
<ul class="ml-4 space-y-1">
|
||||||
|
<li>• <span class="bg-gray-100 px-2 py-1 rounded text-xs">Neue Regel</span> - Graues Kästchen</li>
|
||||||
|
<li>• <span class="bg-blue-100 px-2 py-1 rounded text-xs">Grundregel</span> - Blaues Kästchen</li>
|
||||||
|
<li>• <span class="bg-green-100 px-2 py-1 rounded text-xs">Strafregel</span> - Grünes Kästchen</li>
|
||||||
|
<li>• <span class="bg-yellow-100 px-2 py-1 rounded text-xs">Aufschlag</span> - Gelbes Kästchen</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>2. Kästchen löschen:</strong> Klicken Sie in ein Kästchen und dann auf <span class="bg-red-100 px-2 py-1 rounded text-xs">Regel löschen</span></p>
|
||||||
|
<p><strong>3. Kästchen bearbeiten:</strong> Klicken Sie direkt in die Texte und bearbeiten Sie sie</p>
|
||||||
|
<p><strong>4. Grid-Layout:</strong> Kästchen werden automatisch im Grid-Layout angeordnet</p>
|
||||||
|
<p class="text-xs text-blue-600 mt-2">💡 <strong>Tipp:</strong> Neue Kästchen werden automatisch in das bestehende Grid eingefügt!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-3 sm:p-4">
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-3 sm:p-4">
|
||||||
<div
|
<div
|
||||||
ref="editor"
|
ref="editor"
|
||||||
class="min-h-[320px] p-3 sm:p-4 outline-none prose max-w-none text-sm sm:text-base"
|
class="min-h-[320px] p-3 sm:p-4 outline-none prose max-w-none text-sm sm:text-base"
|
||||||
contenteditable
|
contenteditable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,5 +126,172 @@ function removeFormat() {
|
|||||||
document.execCommand('removeFormat', false, null)
|
document.execCommand('removeFormat', false, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function insertRuleTemplate(type) {
|
||||||
|
const editorElement = editor.value
|
||||||
|
if (!editorElement) return
|
||||||
|
|
||||||
|
let template = ''
|
||||||
|
let bgColor = 'bg-gray-50'
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'generic':
|
||||||
|
template = `
|
||||||
|
<div class="text-center p-6 bg-gray-50 rounded-lg">
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900 mb-2">Neue Regel</h3>
|
||||||
|
<p class="text-gray-600 text-sm">[Regeltext hier eingeben]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
bgColor = 'bg-gray-50'
|
||||||
|
break
|
||||||
|
case 'basic':
|
||||||
|
template = `
|
||||||
|
<div class="text-center p-6 bg-blue-50 rounded-lg">
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900 mb-2">Neue Grundregel</h3>
|
||||||
|
<p class="text-gray-600 text-sm"><strong>Regel:</strong> [Regeltext hier eingeben]<br><strong>Beschreibung:</strong> [Detaillierte Beschreibung hier eingeben]<br><strong>Anwendung:</strong> [Wann gilt diese Regel?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
bgColor = 'bg-blue-50'
|
||||||
|
break
|
||||||
|
case 'penalty':
|
||||||
|
template = `
|
||||||
|
<div class="text-center p-6 bg-green-50 rounded-lg">
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900 mb-2">Neue Strafregel</h3>
|
||||||
|
<p class="text-gray-600 text-sm"><strong>Verstoß:</strong> [Was ist der Verstoß?]<br><strong>Strafe:</strong> [Welche Strafe wird verhängt?]<br><strong>Häufigkeit:</strong> [Bei wiederholten Verstößen?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
bgColor = 'bg-green-50'
|
||||||
|
break
|
||||||
|
case 'service':
|
||||||
|
template = `
|
||||||
|
<div class="text-center p-6 bg-yellow-50 rounded-lg">
|
||||||
|
<h3 class="text-xl font-semibold text-gray-900 mb-2">Neue Aufschlagregel</h3>
|
||||||
|
<p class="text-gray-600 text-sm"><strong>Regel:</strong> [Aufschlagregel hier eingeben]<br><strong>Technik:</strong> [Wie muss der Aufschlag ausgeführt werden?]<br><strong>Fehler:</strong> [Was gilt als Fehler?]</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
bgColor = 'bg-yellow-50'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editor fokussieren
|
||||||
|
editorElement.focus()
|
||||||
|
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection.rangeCount > 0) {
|
||||||
|
const range = selection.getRangeAt(0)
|
||||||
|
|
||||||
|
// Prüfen ob der Cursor im Editor ist
|
||||||
|
if (editorElement.contains(range.commonAncestorContainer) || editorElement === range.commonAncestorContainer) {
|
||||||
|
// Aktuelles Element finden
|
||||||
|
let currentElement = range.commonAncestorContainer
|
||||||
|
|
||||||
|
// Falls es ein Text-Node ist, zum Parent-Element gehen
|
||||||
|
if (currentElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
currentElement = currentElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zum spezifischen Container navigieren mit den Klassen "grid md:grid-cols-2 lg:grid-cols-3 gap-6"
|
||||||
|
let targetContainer = currentElement
|
||||||
|
while (targetContainer && !targetContainer.classList.contains('grid')) {
|
||||||
|
targetContainer = targetContainer.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüfen ob es der richtige Container ist
|
||||||
|
if (targetContainer &&
|
||||||
|
targetContainer.classList.contains('md:grid-cols-2') &&
|
||||||
|
targetContainer.classList.contains('lg:grid-cols-3') &&
|
||||||
|
targetContainer.classList.contains('gap-6')) {
|
||||||
|
|
||||||
|
// Wir sind im richtigen Container - neues Kästchen hinzufügen
|
||||||
|
const tempDiv = document.createElement('div')
|
||||||
|
tempDiv.innerHTML = template
|
||||||
|
|
||||||
|
// Neues Kästchen in den Container einfügen
|
||||||
|
// Suche nach dem ersten Element-Node (nicht Text-Node)
|
||||||
|
let newCard = null
|
||||||
|
for (let i = 0; i < tempDiv.childNodes.length; i++) {
|
||||||
|
if (tempDiv.childNodes[i].nodeType === Node.ELEMENT_NODE) {
|
||||||
|
newCard = tempDiv.childNodes[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newCard) {
|
||||||
|
targetContainer.appendChild(newCard)
|
||||||
|
|
||||||
|
// Cursor in das neue Kästchen setzen
|
||||||
|
const newRange = document.createRange()
|
||||||
|
const titleElement = newCard.querySelector('h3')
|
||||||
|
if (titleElement) {
|
||||||
|
newRange.setStart(titleElement, 0)
|
||||||
|
newRange.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(newRange)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('No valid element found in template');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Spezifischer Container nicht gefunden - am Ende einfügen
|
||||||
|
editorElement.innerHTML += template
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Cursor ist nicht im Editor - Template am Ende einfügen
|
||||||
|
editorElement.innerHTML += template
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Keine Auswahl - Template am Ende einfügen
|
||||||
|
editorElement.innerHTML += template
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteCurrentRule() {
|
||||||
|
const editorElement = editor.value
|
||||||
|
if (!editorElement) return
|
||||||
|
|
||||||
|
// Editor fokussieren
|
||||||
|
editorElement.focus()
|
||||||
|
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection.rangeCount > 0) {
|
||||||
|
const range = selection.getRangeAt(0)
|
||||||
|
|
||||||
|
// Prüfen ob der Cursor im Editor ist
|
||||||
|
if (editorElement.contains(range.commonAncestorContainer) || editorElement === range.commonAncestorContainer) {
|
||||||
|
// Aktuelles Element finden
|
||||||
|
let currentElement = range.commonAncestorContainer
|
||||||
|
|
||||||
|
// Falls es ein Text-Node ist, zum Parent-Element gehen
|
||||||
|
if (currentElement.nodeType === Node.TEXT_NODE) {
|
||||||
|
currentElement = currentElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zum Grid-Kästchen navigieren
|
||||||
|
let cardElement = currentElement
|
||||||
|
while (cardElement && !cardElement.classList.contains('text-center')) {
|
||||||
|
cardElement = cardElement.parentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardElement && cardElement.classList.contains('text-center')) {
|
||||||
|
// Grid-Kästchen gefunden - löschen
|
||||||
|
cardElement.remove()
|
||||||
|
|
||||||
|
// Cursor in das nächste Kästchen oder Grid setzen
|
||||||
|
const gridContainer = editorElement.querySelector('.grid')
|
||||||
|
if (gridContainer && gridContainer.children.length > 0) {
|
||||||
|
const firstCard = gridContainer.firstElementChild
|
||||||
|
const titleElement = firstCard.querySelector('h3')
|
||||||
|
if (titleElement) {
|
||||||
|
const newRange = document.createRange()
|
||||||
|
newRange.setStart(titleElement, 0)
|
||||||
|
newRange.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(newRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(load)
|
onMounted(load)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user