Add CMS termine editor for admin and vorstand
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"date": "2025-10-21T13:50:44.482Z",
|
||||
"date": "2025-10-21T13:54:21.835Z",
|
||||
"preset": "node-server",
|
||||
"framework": {
|
||||
"name": "nuxt",
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"id":"88cab71a-6f5e-48fa-ae20-fc874da8cdac","timestamp":1761054637518}
|
||||
{"id":"3a0403e7-f742-4a46-8731-aef781f88d6b","timestamp":1761054854878}
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"3a0403e7-f742-4a46-8731-aef781f88d6b","timestamp":1761054854878,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
||||
@@ -1 +0,0 @@
|
||||
{"id":"88cab71a-6f5e-48fa-ae20-fc874da8cdac","timestamp":1761054637518,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
||||
@@ -1,13 +1,13 @@
|
||||
const interopDefault = r => r.default || r || [];
|
||||
const styles = {
|
||||
"components/Hero.vue": () => import('./Hero-styles.03iOjY05.mjs').then(interopDefault),
|
||||
"components/PublicNews.vue": () => import('./PublicNews-styles.nhqk16g5.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),
|
||||
"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),
|
||||
"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)
|
||||
"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/PublicNews.vue": () => import('./PublicNews-styles.nhqk16g5.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)
|
||||
};
|
||||
|
||||
export { styles as default };
|
||||
|
||||
@@ -4293,7 +4293,7 @@ function _expandFromEnv(value) {
|
||||
const _inlineRuntimeConfig = {
|
||||
"app": {
|
||||
"baseURL": "/",
|
||||
"buildId": "88cab71a-6f5e-48fa-ae20-fc874da8cdac",
|
||||
"buildId": "3a0403e7-f742-4a46-8731-aef781f88d6b",
|
||||
"buildAssetsDir": "/_nuxt/",
|
||||
"cdnURL": ""
|
||||
},
|
||||
@@ -4741,555 +4741,555 @@ const assets = {
|
||||
"/data/mannschaften.csv": {
|
||||
"type": "text/csv; charset=utf-8",
|
||||
"etag": "\"858-l94GKn8Q0I5RQnhrM0ZPJsYUmcw\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 2136,
|
||||
"path": "../public/data/mannschaften.csv"
|
||||
},
|
||||
"/data/spielsysteme.csv": {
|
||||
"type": "text/csv; charset=utf-8",
|
||||
"etag": "\"9bc-4npLrNHYClsD0TKV5vSifxitfV0\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 2492,
|
||||
"path": "../public/data/spielsysteme.csv"
|
||||
},
|
||||
"/data/termine.csv": {
|
||||
"type": "text/csv; charset=utf-8",
|
||||
"etag": "\"2e8-sZtaHF6QRmOQHinTWOLAYRgo6xk\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 744,
|
||||
"path": "../public/data/termine.csv"
|
||||
},
|
||||
"/data/vereinsmeisterschaften.csv": {
|
||||
"type": "text/csv; charset=utf-8",
|
||||
"etag": "\"989-X8AB+Zegy2xUbjDtbQcXhuuyBDQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 2441,
|
||||
"path": "../public/data/vereinsmeisterschaften.csv"
|
||||
},
|
||||
"/documents/Tischtennisregeln light.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"5177b-y/88q2+Y3RRechJMqWhse21KRdQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 333691,
|
||||
"path": "../public/documents/Tischtennisregeln light.pdf"
|
||||
},
|
||||
"/documents/satzung.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"5c7cf-L0A3nT8D24T9sD57FFbij3QRpzw\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 378831,
|
||||
"path": "../public/documents/satzung.pdf"
|
||||
},
|
||||
"/spielplaene/1. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"64c6-+477M+gD/spwpWR9NO/tMJ/inCc\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 25798,
|
||||
"path": "../public/spielplaene/1. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/2. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"5bfa-DRJMHLV15iss67lEISoGqSYmZjE\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 23546,
|
||||
"path": "../public/spielplaene/2. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/3. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"7447-w933CPQdXhkWJ2AZOVdY0UgJnPo\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 29767,
|
||||
"path": "../public/spielplaene/3. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/4. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"6a9b-4TPGn1yQlFUMRj7oB43SN//Np9o\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 27291,
|
||||
"path": "../public/spielplaene/4. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/5. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"6523-5VUfCMaoiNhcwHhptHHTVJ3lSwQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 25891,
|
||||
"path": "../public/spielplaene/5. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/Jugend 11 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"52e9-3Rrk9UKUxPh80pBJ0w9oLVbe5dA\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 21225,
|
||||
"path": "../public/spielplaene/Jugend 11 2025⁄2026.pdf"
|
||||
},
|
||||
"/images/club_about_us.png": {
|
||||
"type": "image/png",
|
||||
"etag": "\"202e56-s4fLsHEgoAgKJeBRuI1qxPmqHV0\"",
|
||||
"mtime": "2025-10-21T13:50:42.009Z",
|
||||
"size": 2109014,
|
||||
"path": "../public/images/club_about_us.png"
|
||||
},
|
||||
"/_nuxt/B23trXK4.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1168-Ulrp7wDqGkKdNtiJFHTxmUmXldI\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 4456,
|
||||
"path": "../public/_nuxt/B23trXK4.js"
|
||||
},
|
||||
"/_nuxt/B3KXwwdt.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"81f-a2SnM+umqZ4dmwPE80AuhD/ofeY\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 2079,
|
||||
"path": "../public/_nuxt/B3KXwwdt.js"
|
||||
},
|
||||
"/_nuxt/B4mSF5Ac.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"185-hHs3mU4qOcQAkGQaPrUYGaG0yao\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 389,
|
||||
"path": "../public/_nuxt/B4mSF5Ac.js"
|
||||
},
|
||||
"/_nuxt/B6TEfPSg.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"faa-eKvxmyzZhwTvzR8CVB/YoBNhWPw\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 4010,
|
||||
"path": "../public/_nuxt/B6TEfPSg.js"
|
||||
},
|
||||
"/_nuxt/B94vUBDm.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"23f5-XOrzblQBbbg+gHCtcftlnEMApxI\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 9205,
|
||||
"path": "../public/_nuxt/B94vUBDm.js"
|
||||
},
|
||||
"/_nuxt/BASo1Rw1.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1a9f-AETC+kRrTxOyu6uck7TEQ709m7k\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 6815,
|
||||
"path": "../public/_nuxt/BASo1Rw1.js"
|
||||
},
|
||||
"/_nuxt/BC4PNGtJ.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"175-33lu59Ps/+kwbPv/hVeUdrq4wmI\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.357Z",
|
||||
"size": 373,
|
||||
"path": "../public/_nuxt/BC4PNGtJ.js"
|
||||
},
|
||||
"/_nuxt/BGsE9M8w.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1dc5-wDAFBA19AfN1chv6Fou4TR+Ocyk\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 7621,
|
||||
"path": "../public/_nuxt/BGsE9M8w.js"
|
||||
},
|
||||
"/_nuxt/BRhWghMt.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"16e9-77KyMLdoERbk/9I/4xig919AOCQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 5865,
|
||||
"path": "../public/_nuxt/BRhWghMt.js"
|
||||
},
|
||||
"/_nuxt/BU5mk92E.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"2029-KCj/1gSBJVISCuMvs9MA7PoIdnY\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 8233,
|
||||
"path": "../public/_nuxt/BU5mk92E.js"
|
||||
},
|
||||
"/_nuxt/BZLaJF8o.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"685-ABktMZGm1wLg51VMeeUc8FwDm3U\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 1669,
|
||||
"path": "../public/_nuxt/BZLaJF8o.js"
|
||||
},
|
||||
"/_nuxt/Bdk8d7qx.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"11e7-YYqkAkZMNacy1r/CaMWBfPJ94OU\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 4583,
|
||||
"path": "../public/_nuxt/Bdk8d7qx.js"
|
||||
},
|
||||
"/_nuxt/BjiYAScN.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"13f6-Hw3IRFNgh5L2rLxP61MG/cT8NzA\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 5110,
|
||||
"path": "../public/_nuxt/BjiYAScN.js"
|
||||
},
|
||||
"/_nuxt/Bn7G3VMx.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"16eb-6SRn6aWwajUUKphf99cu+aqdGpU\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 5867,
|
||||
"path": "../public/_nuxt/Bn7G3VMx.js"
|
||||
},
|
||||
"/_nuxt/BteKZQ9T.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1ea-kmrGdt5SPmt15EiBI7kR9gXMQM0\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 490,
|
||||
"path": "../public/_nuxt/BteKZQ9T.js"
|
||||
},
|
||||
"/_nuxt/BxR6w-Hd.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"5f0-Wm3M/7i81O9ViLRC6jPn0eQp24g\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 1520,
|
||||
"path": "../public/_nuxt/BxR6w-Hd.js"
|
||||
},
|
||||
"/_nuxt/C-bqeYjt.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"3513-AcHmeXV6b+tvCtqgBG6EnnxPL8w\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 13587,
|
||||
"path": "../public/_nuxt/C-bqeYjt.js"
|
||||
},
|
||||
"/_nuxt/C1eD6HzQ.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"abb-rmFamqyRm9KsgptRPeFJlFZ7AdI\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 2747,
|
||||
"path": "../public/_nuxt/C1eD6HzQ.js"
|
||||
},
|
||||
"/_nuxt/C5SyyWEb.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"2a5-06iX+CL3i0ysaqW9nu7Eg2YzDhQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 677,
|
||||
"path": "../public/_nuxt/C5SyyWEb.js"
|
||||
},
|
||||
"/_nuxt/C5WkR1xp.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"b10-7bTi/rXEsVv7CfCAujimlOWU3q0\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 2832,
|
||||
"path": "../public/_nuxt/C5WkR1xp.js"
|
||||
},
|
||||
"/_nuxt/C8kQt0fa.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"197-7X99z1xphxry8OnMwU7Ofs/uE0Q\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 407,
|
||||
"path": "../public/_nuxt/C8kQt0fa.js"
|
||||
},
|
||||
"/_nuxt/C9SglkVL.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"ee2-953PjDhBAep38tbBTU3/pMqFyww\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 3810,
|
||||
"path": "../public/_nuxt/C9SglkVL.js"
|
||||
},
|
||||
"/_nuxt/C9UhLsiJ.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1744-UhJxrXDy4uAkLfPpSs6j/m/gx64\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 5956,
|
||||
"path": "../public/_nuxt/C9UhLsiJ.js"
|
||||
},
|
||||
"/_nuxt/CGpRzXRB.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"37d-FnxQohNMb8l0n0XcPv+1bmf1WCE\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 893,
|
||||
"path": "../public/_nuxt/CGpRzXRB.js"
|
||||
},
|
||||
"/_nuxt/CI8YYLGa.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"d8b-SdM/XDodrfUIexPUk7MhxL0ud70\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 3467,
|
||||
"path": "../public/_nuxt/CI8YYLGa.js"
|
||||
},
|
||||
"/_nuxt/COK-PGSA.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1556-zTPwefaXANTxfUv6X27Ctd3j468\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 5462,
|
||||
"path": "../public/_nuxt/COK-PGSA.js"
|
||||
},
|
||||
"/_nuxt/CT6VfTlB.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"10bb-m3q/ne67feCvdLmlKowXgEW18XE\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 4283,
|
||||
"path": "../public/_nuxt/CT6VfTlB.js"
|
||||
},
|
||||
"/_nuxt/CTuRK0lH.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"177f-9AHJLxzT1QXHm05RkMKEx5CuaVU\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 6015,
|
||||
"path": "../public/_nuxt/CTuRK0lH.js"
|
||||
},
|
||||
"/_nuxt/CUq_0rkE.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"12d-JV4KW1fgT85/V3Ap13X4q2h9U3g\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 301,
|
||||
"path": "../public/_nuxt/CUq_0rkE.js"
|
||||
},
|
||||
"/_nuxt/CW9krljs.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"dbf-R7lqTpP/JoeELqrwiRklrTVdlP0\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 3519,
|
||||
"path": "../public/_nuxt/CW9krljs.js"
|
||||
},
|
||||
"/_nuxt/CWEkTB1z.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"198-ej4DRqc3/5nSwWU3c6wbOD3Ib9w\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 408,
|
||||
"path": "../public/_nuxt/CWEkTB1z.js"
|
||||
},
|
||||
"/_nuxt/C_U-NUAd.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"13f-zgvIssSMnG3JGf/eGC7PlZzbsiY\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 319,
|
||||
"path": "../public/_nuxt/C_U-NUAd.js"
|
||||
},
|
||||
"/_nuxt/CkzaQq3X.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"17d-+xKrHjeww4bpFFkkjUNLD/ebn5A\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 381,
|
||||
"path": "../public/_nuxt/CkzaQq3X.js"
|
||||
},
|
||||
"/_nuxt/CrCcIvVp.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"274-9U7hEMtgHqdnQopnKeJsBKqKyKw\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 628,
|
||||
"path": "../public/_nuxt/CrCcIvVp.js"
|
||||
},
|
||||
"/_nuxt/CvtlfSR0.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1860-M3/zR8vfhVWmJ6erGqFzdHXQXuE\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 6240,
|
||||
"path": "../public/_nuxt/CvtlfSR0.js"
|
||||
},
|
||||
"/_nuxt/Cx4UcKGu.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"19d-5AMD0EnFEjOkM3qKDpC/NZZzwDI\"",
|
||||
"mtime": "2025-10-21T13:50:42.005Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 413,
|
||||
"path": "../public/_nuxt/Cx4UcKGu.js"
|
||||
},
|
||||
"/_nuxt/Czdc6-TI.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"165-EMJ/yP2qajGIw0CL3y+L/hvMM/8\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 357,
|
||||
"path": "../public/_nuxt/Czdc6-TI.js"
|
||||
},
|
||||
"/_nuxt/D11oUMHK.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1d9a-l6JEyKxxIcbq3Kkksqm5qE2ZWj4\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 7578,
|
||||
"path": "../public/_nuxt/D11oUMHK.js"
|
||||
},
|
||||
"/_nuxt/D43Z0o-f.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"32c8e-LLbrtE0SvQkEnQ4ry/ZcUybqPmQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 208014,
|
||||
"path": "../public/_nuxt/D43Z0o-f.js"
|
||||
},
|
||||
"/_nuxt/D99LnZYi.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1bdb-/r79rlmI33Ifam5FH18djsiUTQ8\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 7131,
|
||||
"path": "../public/_nuxt/D99LnZYi.js"
|
||||
},
|
||||
"/_nuxt/DAACT36i.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1f9-dVOk5jAwb0VlMLJevIcT+s2NTgM\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 505,
|
||||
"path": "../public/_nuxt/DAACT36i.js"
|
||||
},
|
||||
"/_nuxt/DHQur1V-.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1827-DA/YFWxSxxRm0zvcpiuZvwwfzNE\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 6183,
|
||||
"path": "../public/_nuxt/DHQur1V-.js"
|
||||
},
|
||||
"/_nuxt/DaSgy0Cl.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"11f-soKnh1qfNJj5nvt+IcgQXYvg/z4\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 287,
|
||||
"path": "../public/_nuxt/DaSgy0Cl.js"
|
||||
},
|
||||
"/_nuxt/DdHhmCne.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"22d-uKYfhsDcUsz2NrXOJmxptUGZdyE\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 557,
|
||||
"path": "../public/_nuxt/DdHhmCne.js"
|
||||
},
|
||||
"/_nuxt/DjcJk1g8.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"201d-oQ9NMDE0anKxIZA105IRItTlM2w\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 8221,
|
||||
"path": "../public/_nuxt/DjcJk1g8.js"
|
||||
},
|
||||
"/_nuxt/DkeYb0_S.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1ce-xiaAbRvqQ+zffTXF3Gc7rq14R0U\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.358Z",
|
||||
"size": 462,
|
||||
"path": "../public/_nuxt/DkeYb0_S.js"
|
||||
},
|
||||
"/_nuxt/DlAUqK2U.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"5b-eFCz/UrraTh721pgAl0VxBNR1es\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 91,
|
||||
"path": "../public/_nuxt/DlAUqK2U.js"
|
||||
},
|
||||
"/_nuxt/DvrqIJw1.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"dfc-YqdcBHK+H9m+Gjgl+qCwmlBEIX0\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 3580,
|
||||
"path": "../public/_nuxt/DvrqIJw1.js"
|
||||
},
|
||||
"/_nuxt/Dx1KRsmK.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1d86-kU610bWwsXBL249yP4W8lasEh3c\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 7558,
|
||||
"path": "../public/_nuxt/Dx1KRsmK.js"
|
||||
},
|
||||
"/_nuxt/DxIIJuzj.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"bf0-Q7VHINZ8z6pKO1o0BhgbcvRgIr0\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 3056,
|
||||
"path": "../public/_nuxt/DxIIJuzj.js"
|
||||
},
|
||||
"/_nuxt/Harheimer TC.CKfYAfp1.svg": {
|
||||
"type": "image/svg+xml",
|
||||
"etag": "\"1d2535-Tx2lTuuFn2hBqGZOnDan3/OdRU0\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 1910069,
|
||||
"path": "../public/_nuxt/Harheimer TC.CKfYAfp1.svg"
|
||||
},
|
||||
"/_nuxt/KxVBmS-6.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"190-F0LVEAqwB2LwyGzW0v9yzLx0v/0\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 400,
|
||||
"path": "../public/_nuxt/KxVBmS-6.js"
|
||||
},
|
||||
"/_nuxt/LPF2GIYR.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"557-80ya3yG6VaGTcTbyJrpOfIs1ttU\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 1367,
|
||||
"path": "../public/_nuxt/LPF2GIYR.js"
|
||||
},
|
||||
"/_nuxt/XZ6RV9KH.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"175-xr1poEaGS4yjOp907AsRAr6XHLI\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 373,
|
||||
"path": "../public/_nuxt/XZ6RV9KH.js"
|
||||
},
|
||||
"/_nuxt/YJHbYJtA.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"19f-nQw578pUen9o8yYaMA8Bwag6xho\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 415,
|
||||
"path": "../public/_nuxt/YJHbYJtA.js"
|
||||
},
|
||||
"/_nuxt/entry.BbGskshJ.css": {
|
||||
"type": "text/css; charset=utf-8",
|
||||
"etag": "\"b49b-DhLpGn2VN/6EPp9+uW1fcsLCSBk\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 46235,
|
||||
"path": "../public/_nuxt/entry.BbGskshJ.css"
|
||||
},
|
||||
"/_nuxt/error-404.CbXQcqJW.css": {
|
||||
"type": "text/css; charset=utf-8",
|
||||
"etag": "\"97e-Ty5bTTSEudJkO/DsGUoIf37xYxc\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 2430,
|
||||
"path": "../public/_nuxt/error-404.CbXQcqJW.css"
|
||||
},
|
||||
"/_nuxt/error-500.L485xXhD.css": {
|
||||
"type": "text/css; charset=utf-8",
|
||||
"etag": "\"773-jNt1QdCa+iqaSZb1mv/IQWC5p6w\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 1907,
|
||||
"path": "../public/_nuxt/error-500.L485xXhD.css"
|
||||
},
|
||||
"/_nuxt/index.ByttcLyP.css": {
|
||||
"type": "text/css; charset=utf-8",
|
||||
"etag": "\"1db-P3imbnjv59PWVm0HNpwpfdEtAK4\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 475,
|
||||
"path": "../public/_nuxt/index.ByttcLyP.css"
|
||||
},
|
||||
"/_nuxt/jVj3QaoK.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"196-xWXv220Sy3kJeouwzrQ/gnXllWQ\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 406,
|
||||
"path": "../public/_nuxt/jVj3QaoK.js"
|
||||
},
|
||||
"/_nuxt/nrzLFm_7.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"32e3-ybdqGbfFawjPOvyY2mCJu5CTjkg\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 13027,
|
||||
"path": "../public/_nuxt/nrzLFm_7.js"
|
||||
},
|
||||
"/_nuxt/oN0_bS6A.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"1d3-DKhiaT2RUlSXk55jBttctUuTQQI\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 467,
|
||||
"path": "../public/_nuxt/oN0_bS6A.js"
|
||||
},
|
||||
"/_nuxt/rgKTeSYE.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"e71-IzPUyj76F9mR9c9DaEV7x6UlmP0\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 3697,
|
||||
"path": "../public/_nuxt/rgKTeSYE.js"
|
||||
},
|
||||
"/_nuxt/sVyj_WZX.js": {
|
||||
"type": "text/javascript; charset=utf-8",
|
||||
"etag": "\"4d4-T+i1jfWN+C61xV/Shhjh8+auLuI\"",
|
||||
"mtime": "2025-10-21T13:50:42.006Z",
|
||||
"mtime": "2025-10-21T13:54:19.359Z",
|
||||
"size": 1236,
|
||||
"path": "../public/_nuxt/sVyj_WZX.js"
|
||||
},
|
||||
"/spielplaene/1. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"64c6-+477M+gD/spwpWR9NO/tMJ/inCc\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 25798,
|
||||
"path": "../public/spielplaene/1. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/2. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"5bfa-DRJMHLV15iss67lEISoGqSYmZjE\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 23546,
|
||||
"path": "../public/spielplaene/2. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/3. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"7447-w933CPQdXhkWJ2AZOVdY0UgJnPo\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 29767,
|
||||
"path": "../public/spielplaene/3. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/4. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"6a9b-4TPGn1yQlFUMRj7oB43SN//Np9o\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 27291,
|
||||
"path": "../public/spielplaene/4. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/5. Mannschaft 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"6523-5VUfCMaoiNhcwHhptHHTVJ3lSwQ\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 25891,
|
||||
"path": "../public/spielplaene/5. Mannschaft 2025⁄2026.pdf"
|
||||
},
|
||||
"/spielplaene/Jugend 11 2025⁄2026.pdf": {
|
||||
"type": "application/pdf",
|
||||
"etag": "\"52e9-3Rrk9UKUxPh80pBJ0w9oLVbe5dA\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 21225,
|
||||
"path": "../public/spielplaene/Jugend 11 2025⁄2026.pdf"
|
||||
},
|
||||
"/images/club_about_us.png": {
|
||||
"type": "image/png",
|
||||
"etag": "\"202e56-s4fLsHEgoAgKJeBRuI1qxPmqHV0\"",
|
||||
"mtime": "2025-10-21T13:54:19.362Z",
|
||||
"size": 2109014,
|
||||
"path": "../public/images/club_about_us.png"
|
||||
},
|
||||
"/_nuxt/builds/latest.json": {
|
||||
"type": "application/json",
|
||||
"etag": "\"47-oaS8zla0HqEH/6C0JmM9Ge/P27w\"",
|
||||
"mtime": "2025-10-21T13:50:41.998Z",
|
||||
"etag": "\"47-kVYTDCXn2ek6VAK9NgAHFay0zCg\"",
|
||||
"mtime": "2025-10-21T13:54:19.351Z",
|
||||
"size": 71,
|
||||
"path": "../public/_nuxt/builds/latest.json"
|
||||
},
|
||||
"/_nuxt/builds/meta/88cab71a-6f5e-48fa-ae20-fc874da8cdac.json": {
|
||||
"/_nuxt/builds/meta/3a0403e7-f742-4a46-8731-aef781f88d6b.json": {
|
||||
"type": "application/json",
|
||||
"etag": "\"8b-y0o/k4z8GsMRwtIxOumWzGX3oHk\"",
|
||||
"mtime": "2025-10-21T13:50:41.996Z",
|
||||
"etag": "\"8b-E/F64hsLBiBq9KU6aTwdVPD8Ynk\"",
|
||||
"mtime": "2025-10-21T13:54:19.348Z",
|
||||
"size": 139,
|
||||
"path": "../public/_nuxt/builds/meta/88cab71a-6f5e-48fa-ae20-fc874da8cdac.json"
|
||||
"path": "../public/_nuxt/builds/meta/3a0403e7-f742-4a46-8731-aef781f88d6b.json"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ const news_post = defineEventHandler(async (event) => {
|
||||
});
|
||||
}
|
||||
const body = await readBody(event);
|
||||
const { id, title, content } = body;
|
||||
const { id, title, content, isPublic } = body;
|
||||
if (!title || !content) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
@@ -50,6 +50,7 @@ const news_post = defineEventHandler(async (event) => {
|
||||
id: id || void 0,
|
||||
title,
|
||||
content,
|
||||
isPublic: isPublic || false,
|
||||
author: user.name
|
||||
});
|
||||
return {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"news.post.mjs","sources":["../../../../../server/api/news.post.js"],"sourcesContent":null,"names":[],"mappings":";;;;;;;;;;;;;;;;;AAGA,kBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,KAAA,GAAA,SAAA,CAAA,KAAA,EAAA,YAAA,CAAA;AAEA,IAAA,IAAA,CAAA,KAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,OAAA,GAAA,YAAA,KAAA,CAAA;AAEA,IAAA,IAAA,CAAA,OAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,IAAA,GAAA,MAAA,WAAA,CAAA,OAAA,CAAA,EAAA,CAAA;AAGA,IAAA,IAAA,CAAA,IAAA,IAAA,IAAA,CAAA,SAAA,OAAA,IAAA,IAAA,CAAA,SAAA,UAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,IAAA,GAAA,MAAA,QAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,GAAA,IAAA;AAEA,IAAA,IAAA,CAAA,KAAA,IAAA,CAAA,OAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,QAAA,CAAA;AAAA,MACA,IAAA,EAAA,IAAA,KAAA,CAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA,IAAA,CAAA;AAAA,KACA,CAAA;AAEA,IAAA,OAAA;AAAA,MACA,OAAA,EAAA,IAAA;AAAA,MACA,OAAA,EAAA;AAAA,KACA;AAAA,EACA,SAAA,KAAA,EAAA;AACA,IAAA,OAAA,CAAA,KAAA,CAAA,mCAAA,KAAA,CAAA;AACA,IAAA,MAAA,KAAA;AAAA,EACA;AACA,CAAA,CAAA;;;;"}
|
||||
{"version":3,"file":"news.post.mjs","sources":["../../../../../server/api/news.post.js"],"sourcesContent":null,"names":[],"mappings":";;;;;;;;;;;;;;;;;AAGA,kBAAA,kBAAA,CAAA,OAAA,KAAA,KAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,KAAA,GAAA,SAAA,CAAA,KAAA,EAAA,YAAA,CAAA;AAEA,IAAA,IAAA,CAAA,KAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,OAAA,GAAA,YAAA,KAAA,CAAA;AAEA,IAAA,IAAA,CAAA,OAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,IAAA,GAAA,MAAA,WAAA,CAAA,OAAA,CAAA,EAAA,CAAA;AAGA,IAAA,IAAA,CAAA,IAAA,IAAA,IAAA,CAAA,SAAA,OAAA,IAAA,IAAA,CAAA,SAAA,UAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,IAAA,GAAA,MAAA,QAAA,CAAA,KAAA,CAAA;AACA,IAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,UAAA,GAAA,IAAA;AAEA,IAAA,IAAA,CAAA,KAAA,IAAA,CAAA,OAAA,EAAA;AACA,MAAA,MAAA,WAAA,CAAA;AAAA,QACA,UAAA,EAAA,GAAA;AAAA,QACA,OAAA,EAAA;AAAA,OACA,CAAA;AAAA,IACA;AAEA,IAAA,MAAA,QAAA,CAAA;AAAA,MACA,IAAA,EAAA,IAAA,KAAA,CAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA,QAAA,IAAA,KAAA;AAAA,MACA,QAAA,IAAA,CAAA;AAAA,KACA,CAAA;AAEA,IAAA,OAAA;AAAA,MACA,OAAA,EAAA,IAAA;AAAA,MACA,OAAA,EAAA;AAAA,KACA;AAAA,EACA,SAAA,KAAA,EAAA;AACA,IAAA,OAAA,CAAA,KAAA,CAAA,mCAAA,KAAA,CAAA;AACA,IAAA,MAAA,KAAA;AAAA,EACA;AACA,CAAA,CAAA;;;;"}
|
||||
@@ -6,122 +6,87 @@
|
||||
</h1>
|
||||
<div class="w-24 h-1 bg-primary-600 mb-8" />
|
||||
|
||||
<div class="bg-white rounded-xl shadow-lg p-8 mb-8">
|
||||
<h2 class="text-2xl font-display font-bold text-gray-900 mb-4">
|
||||
Willkommen im CMS, {{ user?.name }}!
|
||||
</h2>
|
||||
<p class="text-gray-600">
|
||||
Hier können Sie Inhalte der Website verwalten.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- CMS Modules -->
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mr-4">
|
||||
<Calendar :size="24" class="text-primary-600" />
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">Termine verwalten</h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-4">
|
||||
Termine hinzufügen, bearbeiten und löschen
|
||||
</p>
|
||||
<button class="text-sm text-primary-600 hover:text-primary-700 font-medium">
|
||||
Öffnen →
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mr-4">
|
||||
<Newspaper :size="24" class="text-primary-600" />
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">Interne News</h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-4">
|
||||
News für Mitglieder erstellen und verwalten
|
||||
</p>
|
||||
<button class="text-sm text-primary-600 hover:text-primary-700 font-medium">
|
||||
Öffnen →
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100">
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mr-4">
|
||||
<FileText :size="24" class="text-primary-600" />
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">Spielpläne</h3>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-4">
|
||||
Spielpläne hochladen und verwalten
|
||||
</p>
|
||||
<button class="text-sm text-primary-600 hover:text-primary-700 font-medium">
|
||||
Öffnen →
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Interne News -->
|
||||
<NuxtLink
|
||||
to="/cms/benutzer"
|
||||
class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition-shadow block"
|
||||
to="/mitgliederbereich/news"
|
||||
class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition-all group"
|
||||
>
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mr-4">
|
||||
<Users :size="24" class="text-primary-600" />
|
||||
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center group-hover:bg-blue-600 transition-colors">
|
||||
<Newspaper :size="24" class="text-blue-600 group-hover:text-white" />
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">Benutzerverwaltung</h3>
|
||||
<h2 class="ml-4 text-xl font-semibold text-gray-900">Interne News</h2>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-4">
|
||||
Registrierungen freischalten und Rollen verwalten
|
||||
<p class="text-gray-600">
|
||||
News für Mitglieder erstellen und verwalten
|
||||
</p>
|
||||
<span class="text-sm text-primary-600 hover:text-primary-700 font-medium">
|
||||
Öffnen →
|
||||
</span>
|
||||
</NuxtLink>
|
||||
|
||||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100">
|
||||
<!-- Termine -->
|
||||
<NuxtLink
|
||||
to="/cms/termine"
|
||||
class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition-all group"
|
||||
>
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mr-4">
|
||||
<Image :size="24" class="text-primary-600" />
|
||||
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center group-hover:bg-green-600 transition-colors">
|
||||
<Calendar :size="24" class="text-green-600 group-hover:text-white" />
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-900">Galerie</h3>
|
||||
<h2 class="ml-4 text-xl font-semibold text-gray-900">Termine</h2>
|
||||
</div>
|
||||
<p class="text-gray-600 text-sm mb-4">
|
||||
Bilder hochladen und verwalten
|
||||
<p class="text-gray-600">
|
||||
Vereinstermine erstellen und verwalten
|
||||
</p>
|
||||
<button class="text-sm text-primary-600 hover:text-primary-700 font-medium">
|
||||
Öffnen →
|
||||
</button>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Mitglieder -->
|
||||
<NuxtLink
|
||||
to="/mitgliederbereich/mitglieder"
|
||||
class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition-all group"
|
||||
>
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center group-hover:bg-purple-600 transition-colors">
|
||||
<Users :size="24" class="text-purple-600 group-hover:text-white" />
|
||||
</div>
|
||||
<h2 class="ml-4 text-xl font-semibold text-gray-900">Mitglieder</h2>
|
||||
</div>
|
||||
<p class="text-gray-600">
|
||||
Mitgliederliste bearbeiten
|
||||
</p>
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Benutzerverwaltung (nur für Admin) -->
|
||||
<NuxtLink
|
||||
v-if="authStore.role === 'admin'"
|
||||
to="/cms/benutzer"
|
||||
class="bg-white p-6 rounded-xl shadow-lg border border-gray-100 hover:shadow-xl transition-all group"
|
||||
>
|
||||
<div class="flex items-center mb-4">
|
||||
<div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center group-hover:bg-yellow-600 transition-colors">
|
||||
<UserCog :size="24" class="text-yellow-600 group-hover:text-white" />
|
||||
</div>
|
||||
<h2 class="ml-4 text-xl font-semibold text-gray-900">Benutzerverwaltung</h2>
|
||||
</div>
|
||||
<p class="text-gray-600">
|
||||
Benutzer freischalten und verwalten
|
||||
</p>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Calendar, Newspaper, FileText, Users, Image } from 'lucide-vue-next'
|
||||
import { Newspaper, Calendar, Users, UserCog } from 'lucide-vue-next'
|
||||
|
||||
const user = ref(null)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const response = await $fetch('/api/auth/status')
|
||||
if (response.isLoggedIn) {
|
||||
user.value = response.user
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der Benutzerdaten:', error)
|
||||
}
|
||||
})
|
||||
const authStore = useAuthStore()
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'auth'
|
||||
middleware: 'auth',
|
||||
layout: 'default'
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: 'CMS - Harheimer TC',
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
286
pages/cms/termine.vue
Normal file
286
pages/cms/termine.vue
Normal file
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div class="min-h-full py-16 bg-gray-50">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-2">
|
||||
Termine verwalten
|
||||
</h1>
|
||||
<div class="w-24 h-1 bg-primary-600 mb-4" />
|
||||
</div>
|
||||
<button
|
||||
@click="openAddModal"
|
||||
class="flex items-center px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
<Plus :size="20" class="mr-2" />
|
||||
Termin hinzufügen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="isLoading" class="flex items-center justify-center py-12">
|
||||
<Loader2 :size="40" class="animate-spin text-primary-600" />
|
||||
</div>
|
||||
|
||||
<!-- Termine Table -->
|
||||
<div v-else class="bg-white rounded-xl shadow-lg overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Datum</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Titel</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Beschreibung</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Kategorie</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr v-for="termin in termine" :key="termin.id" class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900">
|
||||
{{ formatDate(termin.datum) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm font-medium text-gray-900">
|
||||
{{ termin.titel }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-600">
|
||||
{{ termin.beschreibung || '-' }}
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
<span
|
||||
:class="{
|
||||
'bg-blue-100 text-blue-800': termin.kategorie === 'Training',
|
||||
'bg-green-100 text-green-800': termin.kategorie === 'Punktspiel',
|
||||
'bg-purple-100 text-purple-800': termin.kategorie === 'Turnier',
|
||||
'bg-yellow-100 text-yellow-800': termin.kategorie === 'Veranstaltung',
|
||||
'bg-gray-100 text-gray-800': termin.kategorie === 'Sonstiges'
|
||||
}"
|
||||
class="px-2 py-1 text-xs font-medium rounded-full"
|
||||
>
|
||||
{{ termin.kategorie }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-right text-sm font-medium">
|
||||
<button
|
||||
@click="confirmDelete(termin)"
|
||||
class="text-red-600 hover:text-red-900"
|
||||
title="Löschen"
|
||||
>
|
||||
<Trash2 :size="18" />
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-if="termine.length === 0" class="text-center py-12 text-gray-500">
|
||||
Keine Termine vorhanden.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Modal -->
|
||||
<div
|
||||
v-if="showModal"
|
||||
class="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4"
|
||||
@click.self="closeModal"
|
||||
>
|
||||
<div class="bg-white rounded-xl shadow-2xl max-w-2xl w-full p-8">
|
||||
<h2 class="text-2xl font-display font-bold text-gray-900 mb-6">
|
||||
Termin hinzufügen
|
||||
</h2>
|
||||
|
||||
<form @submit.prevent="saveTermin" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Datum *</label>
|
||||
<input
|
||||
v-model="formData.datum"
|
||||
type="date"
|
||||
required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
:disabled="isSaving"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Kategorie *</label>
|
||||
<select
|
||||
v-model="formData.kategorie"
|
||||
required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
:disabled="isSaving"
|
||||
>
|
||||
<option value="Training">Training</option>
|
||||
<option value="Punktspiel">Punktspiel</option>
|
||||
<option value="Turnier">Turnier</option>
|
||||
<option value="Veranstaltung">Veranstaltung</option>
|
||||
<option value="Sonstiges">Sonstiges</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Titel *</label>
|
||||
<input
|
||||
v-model="formData.titel"
|
||||
type="text"
|
||||
required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
:disabled="isSaving"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Beschreibung</label>
|
||||
<textarea
|
||||
v-model="formData.beschreibung"
|
||||
rows="3"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
:disabled="isSaving"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="errorMessage" class="flex items-center p-3 rounded-md bg-red-50 text-red-700 text-sm">
|
||||
<AlertCircle :size="20" class="mr-2" />
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-4 pt-4">
|
||||
<button
|
||||
type="button"
|
||||
@click="closeModal"
|
||||
class="px-6 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
|
||||
:disabled="isSaving"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="px-6 py-2 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-lg transition-colors flex items-center"
|
||||
:disabled="isSaving"
|
||||
>
|
||||
<Loader2 v-if="isSaving" :size="20" class="animate-spin mr-2" />
|
||||
<span>{{ isSaving ? 'Speichert...' : 'Speichern' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Calendar, Plus, Trash2, Loader2, AlertCircle } from 'lucide-vue-next'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
|
||||
const isLoading = ref(true)
|
||||
const isSaving = ref(false)
|
||||
const termine = ref([])
|
||||
const showModal = ref(false)
|
||||
const errorMessage = ref('')
|
||||
|
||||
const formData = ref({
|
||||
datum: '',
|
||||
titel: '',
|
||||
beschreibung: '',
|
||||
kategorie: 'Sonstiges'
|
||||
})
|
||||
|
||||
const loadTermine = async () => {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const response = await $fetch('/api/termine-manage')
|
||||
termine.value = response.termine
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der Termine:', error)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const openAddModal = () => {
|
||||
formData.value = {
|
||||
datum: '',
|
||||
titel: '',
|
||||
beschreibung: '',
|
||||
kategorie: 'Sonstiges'
|
||||
}
|
||||
showModal.value = true
|
||||
errorMessage.value = ''
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
showModal.value = false
|
||||
errorMessage.value = ''
|
||||
}
|
||||
|
||||
const saveTermin = async () => {
|
||||
isSaving.value = true
|
||||
errorMessage.value = ''
|
||||
|
||||
try {
|
||||
await $fetch('/api/termine-manage', {
|
||||
method: 'POST',
|
||||
body: formData.value
|
||||
})
|
||||
|
||||
closeModal()
|
||||
await loadTermine()
|
||||
} catch (error) {
|
||||
errorMessage.value = error.data?.message || 'Fehler beim Speichern des Termins.'
|
||||
} finally {
|
||||
isSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const confirmDelete = async (termin) => {
|
||||
if (!confirm(`Möchten Sie den Termin "${termin.titel}" wirklich löschen?`)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
datum: termin.datum,
|
||||
titel: termin.titel,
|
||||
beschreibung: termin.beschreibung || '',
|
||||
kategorie: termin.kategorie || 'Sonstiges'
|
||||
})
|
||||
|
||||
await $fetch(`/api/termine-manage?${params.toString()}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
await loadTermine()
|
||||
} catch (error) {
|
||||
alert('Fehler beim Löschen des Termins.')
|
||||
}
|
||||
}
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
if (!dateString) return ''
|
||||
const date = new Date(dateString)
|
||||
return date.toLocaleDateString('de-DE', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadTermine()
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'auth',
|
||||
layout: 'default'
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: 'Termine verwalten - Harheimer TC',
|
||||
})
|
||||
</script>
|
||||
|
||||
60
server/api/termine-manage.delete.js
Normal file
60
server/api/termine-manage.delete.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import { verifyToken, getUserById } from '../utils/auth.js'
|
||||
import { deleteTermin } from '../utils/termine.js'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const token = getCookie(event, 'auth_token')
|
||||
|
||||
if (!token) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Nicht authentifiziert.'
|
||||
})
|
||||
}
|
||||
|
||||
const decoded = verifyToken(token)
|
||||
|
||||
if (!decoded) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Ungültiges Token.'
|
||||
})
|
||||
}
|
||||
|
||||
const user = await getUserById(decoded.id)
|
||||
|
||||
// Only admin and vorstand can delete termine
|
||||
if (!user || (user.role !== 'admin' && user.role !== 'vorstand')) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
message: 'Keine Berechtigung zum Löschen von Terminen.'
|
||||
})
|
||||
}
|
||||
|
||||
const query = getQuery(event)
|
||||
const { datum, titel, beschreibung, kategorie } = query
|
||||
|
||||
if (!datum || !titel) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: 'Datum und Titel sind erforderlich.'
|
||||
})
|
||||
}
|
||||
|
||||
await deleteTermin({
|
||||
datum,
|
||||
titel,
|
||||
beschreibung: beschreibung || '',
|
||||
kategorie: kategorie || 'Sonstiges'
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Termin erfolgreich gelöscht.'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Löschen des Termins:', error)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
45
server/api/termine-manage.get.js
Normal file
45
server/api/termine-manage.get.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import { verifyToken, getUserById } from '../utils/auth.js'
|
||||
import { readTermine } from '../utils/termine.js'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const token = getCookie(event, 'auth_token')
|
||||
|
||||
if (!token) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Nicht authentifiziert.'
|
||||
})
|
||||
}
|
||||
|
||||
const decoded = verifyToken(token)
|
||||
|
||||
if (!decoded) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Ungültiges Token.'
|
||||
})
|
||||
}
|
||||
|
||||
const user = await getUserById(decoded.id)
|
||||
|
||||
// Only admin and vorstand can manage termine
|
||||
if (!user || (user.role !== 'admin' && user.role !== 'vorstand')) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
message: 'Keine Berechtigung zum Verwalten von Terminen.'
|
||||
})
|
||||
}
|
||||
|
||||
const termine = await readTermine()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
termine
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Termine:', error)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
60
server/api/termine-manage.post.js
Normal file
60
server/api/termine-manage.post.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import { verifyToken, getUserById } from '../utils/auth.js'
|
||||
import { saveTermin } from '../utils/termine.js'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const token = getCookie(event, 'auth_token')
|
||||
|
||||
if (!token) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Nicht authentifiziert.'
|
||||
})
|
||||
}
|
||||
|
||||
const decoded = verifyToken(token)
|
||||
|
||||
if (!decoded) {
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
message: 'Ungültiges Token.'
|
||||
})
|
||||
}
|
||||
|
||||
const user = await getUserById(decoded.id)
|
||||
|
||||
// Only admin and vorstand can create termine
|
||||
if (!user || (user.role !== 'admin' && user.role !== 'vorstand')) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
message: 'Keine Berechtigung zum Erstellen von Terminen.'
|
||||
})
|
||||
}
|
||||
|
||||
const body = await readBody(event)
|
||||
const { datum, titel, beschreibung, kategorie } = body
|
||||
|
||||
if (!datum || !titel) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
message: 'Datum und Titel sind erforderlich.'
|
||||
})
|
||||
}
|
||||
|
||||
await saveTermin({
|
||||
datum,
|
||||
titel,
|
||||
beschreibung: beschreibung || '',
|
||||
kategorie: kategorie || 'Sonstiges'
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Termin erfolgreich gespeichert.'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern des Termins:', error)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"title": "Wir starten durch!",
|
||||
"content": "Endlich ist es so weit! Willkommen.",
|
||||
"author": "Admin",
|
||||
"isPublic": false,
|
||||
"isPublic": true,
|
||||
"created": "2025-10-21T13:34:28.915Z",
|
||||
"updated": "2025-10-21T13:53:16.820Z"
|
||||
"updated": "2025-10-21T13:54:57.247Z"
|
||||
},
|
||||
{
|
||||
"id": "660e8400-e29b-41d4-a716-446655440002",
|
||||
|
||||
133
server/utils/termine.js
Normal file
133
server/utils/termine.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { randomUUID } from 'crypto'
|
||||
|
||||
// Handle both dev and production paths
|
||||
const getDataPath = (filename) => {
|
||||
const cwd = process.cwd()
|
||||
|
||||
// In production (.output/server), working dir is .output
|
||||
if (cwd.endsWith('.output')) {
|
||||
return path.join(cwd, '../public/data', filename)
|
||||
}
|
||||
|
||||
// In development, working dir is project root
|
||||
return path.join(cwd, 'public/data', filename)
|
||||
}
|
||||
|
||||
const TERMINE_FILE = getDataPath('termine.csv')
|
||||
|
||||
// Parse CSV to array of objects
|
||||
export async function readTermine() {
|
||||
try {
|
||||
const data = await fs.readFile(TERMINE_FILE, 'utf-8')
|
||||
const lines = data.split('\n').filter(line => line.trim() !== '')
|
||||
|
||||
if (lines.length < 2) return []
|
||||
|
||||
// Parse CSV with quote handling
|
||||
const termine = []
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const values = []
|
||||
let current = ''
|
||||
let inQuotes = false
|
||||
|
||||
for (let j = 0; j < lines[i].length; j++) {
|
||||
const char = lines[i][j]
|
||||
|
||||
if (char === '"') {
|
||||
inQuotes = !inQuotes
|
||||
} else if (char === ',' && !inQuotes) {
|
||||
values.push(current.trim())
|
||||
current = ''
|
||||
} else {
|
||||
current += char
|
||||
}
|
||||
}
|
||||
values.push(current.trim())
|
||||
|
||||
if (values.length >= 4) {
|
||||
termine.push({
|
||||
id: randomUUID(), // Generate ID on-the-fly for editing
|
||||
datum: values[0],
|
||||
titel: values[1],
|
||||
beschreibung: values[2],
|
||||
kategorie: values[3]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return termine
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
return []
|
||||
}
|
||||
console.error('Fehler beim Lesen der Termine:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// Write array of objects to CSV
|
||||
export async function writeTermine(termine) {
|
||||
try {
|
||||
let csv = '"datum","titel","beschreibung","kategorie"\n'
|
||||
|
||||
for (const termin of termine) {
|
||||
const datum = termin.datum || ''
|
||||
const titel = termin.titel || ''
|
||||
const beschreibung = termin.beschreibung || ''
|
||||
const kategorie = termin.kategorie || ''
|
||||
|
||||
// Escape quotes in values
|
||||
const escapedDatum = datum.replace(/"/g, '""')
|
||||
const escapedTitel = titel.replace(/"/g, '""')
|
||||
const escapedBeschreibung = beschreibung.replace(/"/g, '""')
|
||||
const escapedKategorie = kategorie.replace(/"/g, '""')
|
||||
|
||||
csv += `"${escapedDatum}","${escapedTitel}","${escapedBeschreibung}","${escapedKategorie}"\n`
|
||||
}
|
||||
|
||||
await fs.writeFile(TERMINE_FILE, csv, 'utf-8')
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Schreiben der Termine:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Add or update termin
|
||||
export async function saveTermin(terminData) {
|
||||
const termine = await readTermine()
|
||||
|
||||
// Always add as new (CSV doesn't have persistent IDs)
|
||||
const newTermin = {
|
||||
datum: terminData.datum,
|
||||
titel: terminData.titel,
|
||||
beschreibung: terminData.beschreibung || '',
|
||||
kategorie: terminData.kategorie || 'Sonstiges'
|
||||
}
|
||||
|
||||
termine.push(newTermin)
|
||||
|
||||
// Sort by date
|
||||
termine.sort((a, b) => new Date(a.datum) - new Date(b.datum))
|
||||
|
||||
await writeTermine(termine)
|
||||
return true
|
||||
}
|
||||
|
||||
// Delete termin by matching all fields (since we don't have persistent IDs)
|
||||
export async function deleteTermin(terminData) {
|
||||
let termine = await readTermine()
|
||||
|
||||
termine = termine.filter(t =>
|
||||
!(t.datum === terminData.datum &&
|
||||
t.titel === terminData.titel &&
|
||||
t.beschreibung === terminData.beschreibung &&
|
||||
t.kategorie === terminData.kategorie)
|
||||
)
|
||||
|
||||
await writeTermine(termine)
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user