mirror of
				https://git.schule.click/GymSedan/SISSy.git
				synced 2025-11-04 00:49:21 +01:00 
			
		
		
		
	Erse Version des Lehrerinfobildschirms mit Vertretungsplan und News
This commit is contained in:
		
							parent
							
								
									c713629edf
								
							
						
					
					
						commit
						209454e313
					
				
					 12 changed files with 498 additions and 49 deletions
				
			
		
							
								
								
									
										62
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										62
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -10,11 +10,11 @@
 | 
			
		|||
      "dependencies": {
 | 
			
		||||
        "core-js": "^3.6.5",
 | 
			
		||||
        "vue": "^2.6.11",
 | 
			
		||||
        "vue-papa-parse": "^3.0.1",
 | 
			
		||||
        "vue-router": "^3.2.0",
 | 
			
		||||
        "vuetify": "^2.4.0"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@mdi/font": "^6.5.95",
 | 
			
		||||
        "@mdi/js": "^6.4.95",
 | 
			
		||||
        "@vue/cli-plugin-babel": "~4.5.0",
 | 
			
		||||
        "@vue/cli-plugin-eslint": "~4.5.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,7 @@
 | 
			
		|||
        "sass": "~1.32.0",
 | 
			
		||||
        "sass-loader": "^10.0.0",
 | 
			
		||||
        "vue-cli-plugin-vuetify": "~2.4.3",
 | 
			
		||||
        "vue-papa-parse": "^3.0.3",
 | 
			
		||||
        "vue-template-compiler": "^2.6.11",
 | 
			
		||||
        "vuetify-loader": "^1.7.0"
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -1694,6 +1695,12 @@
 | 
			
		|||
        "webpack": "^4.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@mdi/font": {
 | 
			
		||||
      "version": "6.5.95",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-6.5.95.tgz",
 | 
			
		||||
      "integrity": "sha512-ES5rj6J39FUkHe/b3C9SJs8bqIungYhuU7rBINTBaHOv/Ce4RCb3Gw08CZVl32W33UEkgRkzyWaIedV4at+QHg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@mdi/js": {
 | 
			
		||||
      "version": "6.4.95",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@mdi/js/-/js-6.4.95.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -10121,7 +10128,8 @@
 | 
			
		|||
    "node_modules/papaparse": {
 | 
			
		||||
      "version": "5.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.1.tgz",
 | 
			
		||||
      "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA=="
 | 
			
		||||
      "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/parallel-transform": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -14313,12 +14321,15 @@
 | 
			
		|||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/vue-papa-parse": {
 | 
			
		||||
      "version": "3.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vue-papa-parse/-/vue-papa-parse-3.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-NYBXn9duiUFj7ku8QYuNtSfRQxBenHFhnj4Qvda/fNC/Ypd4G2a55BFIpyTmEFOEufMa3rJmUYFKUw42mCXi8Q==",
 | 
			
		||||
      "version": "3.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vue-papa-parse/-/vue-papa-parse-3.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-xnm0maOfsAiRHCw//Dv1xtQ8/NN8WWXMJ9hO7JMEQc+/i0885inkDPjL0rXy8OtzvntP8Oz7l5q6wQNVNJxxpg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "papaparse": "^5.3.0",
 | 
			
		||||
        "vue": "^2.6.0"
 | 
			
		||||
        "papaparse": "^5.3.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "vue": "^2.6.0 || >=3.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/vue-router": {
 | 
			
		||||
| 
						 | 
				
			
			@ -16778,6 +16789,12 @@
 | 
			
		|||
        "postcss": "^7.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@mdi/font": {
 | 
			
		||||
      "version": "6.5.95",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-6.5.95.tgz",
 | 
			
		||||
      "integrity": "sha512-ES5rj6J39FUkHe/b3C9SJs8bqIungYhuU7rBINTBaHOv/Ce4RCb3Gw08CZVl32W33UEkgRkzyWaIedV4at+QHg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "@mdi/js": {
 | 
			
		||||
      "version": "6.4.95",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@mdi/js/-/js-6.4.95.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -17258,7 +17275,8 @@
 | 
			
		|||
      "version": "4.5.15",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.15.tgz",
 | 
			
		||||
      "integrity": "sha512-fqap+4HN+w+InDxlA3hZTOGE0tzBTgXhKLoDydhywqgmhQ1D9JA6Feh94ze6tG8DsWX58/ujYUqA8jAz17FJtg==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "@vue/cli-service": {
 | 
			
		||||
      "version": "4.5.15",
 | 
			
		||||
| 
						 | 
				
			
			@ -17412,7 +17430,8 @@
 | 
			
		|||
      "version": "1.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
 | 
			
		||||
      "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "@vue/web-component-wrapper": {
 | 
			
		||||
      "version": "1.3.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -17627,7 +17646,8 @@
 | 
			
		|||
      "version": "5.3.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
 | 
			
		||||
      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "acorn-walk": {
 | 
			
		||||
      "version": "7.2.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -17657,13 +17677,15 @@
 | 
			
		|||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "ajv-keywords": {
 | 
			
		||||
      "version": "3.5.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
 | 
			
		||||
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "alphanum-sort": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
| 
						 | 
				
			
			@ -23525,7 +23547,8 @@
 | 
			
		|||
    "papaparse": {
 | 
			
		||||
      "version": "5.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.1.tgz",
 | 
			
		||||
      "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA=="
 | 
			
		||||
      "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "parallel-transform": {
 | 
			
		||||
      "version": "1.2.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -26991,12 +27014,12 @@
 | 
			
		|||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "vue-papa-parse": {
 | 
			
		||||
      "version": "3.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vue-papa-parse/-/vue-papa-parse-3.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-NYBXn9duiUFj7ku8QYuNtSfRQxBenHFhnj4Qvda/fNC/Ypd4G2a55BFIpyTmEFOEufMa3rJmUYFKUw42mCXi8Q==",
 | 
			
		||||
      "version": "3.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vue-papa-parse/-/vue-papa-parse-3.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-xnm0maOfsAiRHCw//Dv1xtQ8/NN8WWXMJ9hO7JMEQc+/i0885inkDPjL0rXy8OtzvntP8Oz7l5q6wQNVNJxxpg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "papaparse": "^5.3.0",
 | 
			
		||||
        "vue": "^2.6.0"
 | 
			
		||||
        "papaparse": "^5.3.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "vue-router": {
 | 
			
		||||
| 
						 | 
				
			
			@ -27041,7 +27064,8 @@
 | 
			
		|||
    "vuetify": {
 | 
			
		||||
      "version": "2.5.14",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.5.14.tgz",
 | 
			
		||||
      "integrity": "sha512-3efk3WnOvh+r9muZ4Ie0FVfFVmPS/ag+l/20qGA45lXZAJuyLeYxJ5gXs5xnCpml1g8xmJfDQPvi8xC6DDuCdg=="
 | 
			
		||||
      "integrity": "sha512-3efk3WnOvh+r9muZ4Ie0FVfFVmPS/ag+l/20qGA45lXZAJuyLeYxJ5gXs5xnCpml1g8xmJfDQPvi8xC6DDuCdg==",
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "vuetify-loader": {
 | 
			
		||||
      "version": "1.7.3",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,11 +10,11 @@
 | 
			
		|||
  "dependencies": {
 | 
			
		||||
    "core-js": "^3.6.5",
 | 
			
		||||
    "vue": "^2.6.11",
 | 
			
		||||
    "vue-papa-parse": "^3.0.1",
 | 
			
		||||
    "vue-router": "^3.2.0",
 | 
			
		||||
    "vuetify": "^2.4.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@mdi/font": "^6.5.95",
 | 
			
		||||
    "@mdi/js": "^6.4.95",
 | 
			
		||||
    "@vue/cli-plugin-babel": "~4.5.0",
 | 
			
		||||
    "@vue/cli-plugin-eslint": "~4.5.0",
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,7 @@
 | 
			
		|||
    "sass": "~1.32.0",
 | 
			
		||||
    "sass-loader": "^10.0.0",
 | 
			
		||||
    "vue-cli-plugin-vuetify": "~2.4.3",
 | 
			
		||||
    "vue-papa-parse": "^3.0.3",
 | 
			
		||||
    "vue-template-compiler": "^2.6.11",
 | 
			
		||||
    "vuetify-loader": "^1.7.0"
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,8 +6,6 @@
 | 
			
		|||
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
 | 
			
		||||
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
 | 
			
		||||
    <title><%= htmlWebpackPlugin.options.title %></title>
 | 
			
		||||
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <noscript>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/App.vue
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/App.vue
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,17 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div id="app">
 | 
			
		||||
  <v-app>
 | 
			
		||||
    <router-view/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
  </v-app>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  * {
 | 
			
		||||
    -webkit-touch-callout: none; /* iOS Safari */
 | 
			
		||||
    -webkit-user-select: none; /* Safari */
 | 
			
		||||
     -khtml-user-select: none; /* Konqueror HTML */
 | 
			
		||||
       -moz-user-select: none; /* Old versions of Firefox */
 | 
			
		||||
        -ms-user-select: none; /* Internet Explorer/Edge */
 | 
			
		||||
            user-select: none; /* Non-prefixed version, currently
 | 
			
		||||
                                  supported by Chrome, Edge, Opera and Firefox */
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="about">
 | 
			
		||||
  <div class="HomeScreen">
 | 
			
		||||
    <h1>SISSy – Sedan Informations- und Stundenplansystem</h1>
 | 
			
		||||
    <router-link to="/">Home</router-link> |
 | 
			
		||||
    <router-link to="/ids">Infodisplay Schüler</router-link>|
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										86
									
								
								src/components/Newsreader.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/components/Newsreader.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div id="newsreader">
 | 
			
		||||
    <v-carousel v-model="newsitem"
 | 
			
		||||
      cycle
 | 
			
		||||
      interval="10000"
 | 
			
		||||
      progress
 | 
			
		||||
      progress-color="indigo"
 | 
			
		||||
      height="400"
 | 
			
		||||
      hide-delimiters
 | 
			
		||||
      :show-arrows="false"
 | 
			
		||||
    >
 | 
			
		||||
      <v-carousel-item
 | 
			
		||||
        v-for="(item, i) in items"
 | 
			
		||||
        :key="i"
 | 
			
		||||
      >
 | 
			
		||||
        <v-card
 | 
			
		||||
          flat
 | 
			
		||||
          height="100%"
 | 
			
		||||
        >
 | 
			
		||||
          <v-card-title>{{ item.title }}</v-card-title>
 | 
			
		||||
          <v-card-text class="news-text" v-html="item.text"></v-card-text>
 | 
			
		||||
        </v-card>
 | 
			
		||||
      </v-carousel-item>
 | 
			
		||||
    </v-carousel>
 | 
			
		||||
    <v-toolbar 
 | 
			
		||||
      flat
 | 
			
		||||
      rounded="lg"
 | 
			
		||||
    >
 | 
			
		||||
      <v-btn @click="newsitem--" rounded><v-icon>mdi-chevron-left</v-icon></v-btn>
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
      <v-btn @click="newsitem++" rounded><v-icon>mdi-chevron-right</v-icon></v-btn>
 | 
			
		||||
    </v-toolbar>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Newsreader',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      items: [],
 | 
			
		||||
      newsitem: 0,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    feedUrls: Array
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    reload() {
 | 
			
		||||
      // items zurücksetzen
 | 
			
		||||
      this.items = []
 | 
			
		||||
      // items laden
 | 
			
		||||
      for (var i = 0; i < this.feedUrls.length; i++) {
 | 
			
		||||
        fetch(this.feedUrls[i])
 | 
			
		||||
          .then(response => response.text())
 | 
			
		||||
          .then(str => new window.DOMParser().parseFromString(str, 'text/xml'))
 | 
			
		||||
          .then(data => {
 | 
			
		||||
            const elements = data.querySelectorAll('item');
 | 
			
		||||
            elements.forEach(el => {
 | 
			
		||||
              // item bauen
 | 
			
		||||
              const item = {
 | 
			
		||||
                'title': el.querySelector('title').innerHTML.replace(/<!-*\[CDATA\[([\s\S]*)\]\]>/, '$1'),
 | 
			
		||||
                'text': el.querySelector('description').innerHTML.replace(/<!-*\[CDATA[^<]*([\s\S]*)\]\]>/, '$1'), 
 | 
			
		||||
                'date': el.querySelector('pubDate').innerHTML,
 | 
			
		||||
                'feedUrl': this.feedUrls[i]
 | 
			
		||||
              }
 | 
			
		||||
              // Links entfernen (TODO: Link-Handler einbauen)
 | 
			
		||||
              item.text = item.text.replace(/<a[^>]*href=["']*([^'"]*)[^>]*>([^<]*)<\/a>/g, '$2')
 | 
			
		||||
              // item auf Array pushen
 | 
			
		||||
              this.items.push(item)
 | 
			
		||||
            })
 | 
			
		||||
          })
 | 
			
		||||
          .catch(error => console.error(error))
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created() {this.reload()}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  div.news-text {
 | 
			
		||||
    height: calc(100% - 6px);
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										239
									
								
								src/components/Vertretungsplan.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								src/components/Vertretungsplan.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,239 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div id="vertretungsplan">
 | 
			
		||||
    <v-data-table
 | 
			
		||||
      :headers="headers"
 | 
			
		||||
      :fixed-header="true"
 | 
			
		||||
      class="overflow-y-auto"
 | 
			
		||||
      height="85vh"
 | 
			
		||||
      :items="vp"
 | 
			
		||||
      :items-per-page="10000"
 | 
			
		||||
      item-key="nr"
 | 
			
		||||
      sort-by="stunde"
 | 
			
		||||
      group-by="lehrkraft_vertretung"
 | 
			
		||||
      flat
 | 
			
		||||
      hide-default-footer
 | 
			
		||||
      :expanded.sync="expanded"
 | 
			
		||||
      :single-expand="true"
 | 
			
		||||
    >
 | 
			
		||||
      <!-- Titelzeile -->
 | 
			
		||||
      <template v-slot:top>
 | 
			
		||||
        <v-toolbar
 | 
			
		||||
          flat
 | 
			
		||||
        >
 | 
			
		||||
          <v-toolbar-title>Vertretungsplan für den </v-toolbar-title>
 | 
			
		||||
           
 | 
			
		||||
          <v-menu
 | 
			
		||||
            v-model="datepicker"
 | 
			
		||||
            :close-on-content-click="false"
 | 
			
		||||
            :nudge-right="40"
 | 
			
		||||
            transition="scale-transition"
 | 
			
		||||
            offset-y
 | 
			
		||||
            min-width="auto"
 | 
			
		||||
          >
 | 
			
		||||
            <template v-slot:activator="{ on, attrs }">
 | 
			
		||||
              <v-btn
 | 
			
		||||
                v-bind="attrs"
 | 
			
		||||
                v-on="on"
 | 
			
		||||
                rounded
 | 
			
		||||
                :class="(today) ? '' : 'red'"
 | 
			
		||||
              ><v-icon :color="(today) ? '' : 'white'">mdi-calendar</v-icon><span :class="(today) ? '' : 'white--text'">{{ vpDatum.getDate() }}.{{ vpDatum.getMonth() + 1 }}.{{ vpDatum.getFullYear() }}</span></v-btn>
 | 
			
		||||
            </template>
 | 
			
		||||
            <v-date-picker
 | 
			
		||||
              v-model="neuesDatum"
 | 
			
		||||
              @input="datepicker = false"
 | 
			
		||||
            ></v-date-picker>
 | 
			
		||||
          </v-menu>
 | 
			
		||||
          <v-spacer></v-spacer>
 | 
			
		||||
        </v-toolbar>
 | 
			
		||||
      </template> 
 | 
			
		||||
 | 
			
		||||
      <!-- Kopfzeile für Gruppen -->
 | 
			
		||||
      <template v-slot:group.header="{ group, headers, isOpen, toggle }">
 | 
			
		||||
        <td :colspan="headers.length">
 | 
			
		||||
          <v-btn @click="toggle" v-if="isOpen"><v-icon color="grey">mdi-account</v-icon>{{ group }}</v-btn>
 | 
			
		||||
          <v-btn @click="toggle" v-if="!isOpen"><v-icon color="grey">mdi-account-outline</v-icon>{{ group }}</v-btn>
 | 
			
		||||
        </td>
 | 
			
		||||
      </template> 
 | 
			
		||||
 | 
			
		||||
      <!-- Darstellung des Datumsfelds -->
 | 
			
		||||
      <template v-slot:item.datum></template> 
 | 
			
		||||
      <template v-slot:header.datum></template> 
 | 
			
		||||
 | 
			
		||||
      <!-- Darstellung der Vertretungsart -->
 | 
			
		||||
      <template v-slot:item.art_vertretung="{ item }">
 | 
			
		||||
        {{ vertretungsart(item.art_vertretung) }}
 | 
			
		||||
      </template> 
 | 
			
		||||
 | 
			
		||||
      <!-- Button für Anmerkungen -->
 | 
			
		||||
      <template v-slot:item.expand="{ item }">
 | 
			
		||||
        <v-btn @click="expanded = [item]" v-if="item.anmerkung !== '' && !expanded.includes(item)"><v-icon>mdi-comment-plus</v-icon></v-btn>
 | 
			
		||||
        <v-btn @click="expanded = []" v-if="item.anmerkung !== '' && expanded.includes(item)"><v-icon>mdi-comment-minus</v-icon></v-btn>
 | 
			
		||||
      </template> 
 | 
			
		||||
  
 | 
			
		||||
      <!-- Anmerkungen -->
 | 
			
		||||
      <template v-slot:expanded-item="{ headers, item }">
 | 
			
		||||
        <td :colspan="headers.length" v-if="item.anmerkung !== ''">
 | 
			
		||||
          <pre>{{item.anmerkung}}</pre>
 | 
			
		||||
        </td>
 | 
			
		||||
      </template>
 | 
			
		||||
    </v-data-table>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script> 
 | 
			
		||||
var vertretungsarten = {
 | 
			
		||||
  'T': 'verlegt',
 | 
			
		||||
  'F': 'verlegt von',
 | 
			
		||||
  'W': 'Tausch',
 | 
			
		||||
  'S': 'Betreuung',
 | 
			
		||||
  'A': 'Sondereinsatz',
 | 
			
		||||
  'C': 'Entfall',
 | 
			
		||||
  'L': 'Freisetzung',
 | 
			
		||||
  'P': 'Teil_vertretung',
 | 
			
		||||
  'R': 'Raumvertretung',
 | 
			
		||||
  'B': 'Pausenaufsicht',
 | 
			
		||||
  '~': 'Lehrertausch',
 | 
			
		||||
  'E': 'Klausur',
 | 
			
		||||
  '': 'Vertretung'      
 | 
			
		||||
}
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Vertretungsplan',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      vp: [],
 | 
			
		||||
      headers: [
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Datum',
 | 
			
		||||
          value: 'datum',
 | 
			
		||||
          sortable: false,
 | 
			
		||||
          width: 0,
 | 
			
		||||
          // nur ausgewähltes Datum
 | 
			
		||||
          filter: value => {
 | 
			
		||||
            if (value !== this.datumIso) {
 | 
			
		||||
              return false
 | 
			
		||||
            } else {
 | 
			
		||||
              return true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Stunde',
 | 
			
		||||
          value: 'stunde',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Durch',
 | 
			
		||||
          value: 'lehrkraft_vertretung',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Klasse(n)',
 | 
			
		||||
          value: 'klassen',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Fach (neu)',
 | 
			
		||||
          value: 'fach_vertretung',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Raum (neu)',
 | 
			
		||||
          value: 'raum_vertretung',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Für',
 | 
			
		||||
          value: 'lehrkraft',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Fach',
 | 
			
		||||
          value: 'fach',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Raum',
 | 
			
		||||
          value: 'raum',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Durch',
 | 
			
		||||
          value: 'lehrkraft_vertretung',
 | 
			
		||||
          sortable: false,
 | 
			
		||||
          // nur Zeilen mit Vertreter
 | 
			
		||||
          filter: value => {
 | 
			
		||||
            if (value === '') {
 | 
			
		||||
              return false
 | 
			
		||||
            } else {
 | 
			
		||||
              return true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Art',
 | 
			
		||||
          value: 'art_vertretung',
 | 
			
		||||
          sortable: false
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Anmerkung',
 | 
			
		||||
          value: 'expand',
 | 
			
		||||
          sortable: false,
 | 
			
		||||
          align: 'end'
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      expanded:[],
 | 
			
		||||
      datepicker: false,
 | 
			
		||||
      vpDatum: new Date()
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    vpUrl: String, // URL der GPU014,
 | 
			
		||||
    startDatum: Date
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    datumIso () {
 | 
			
		||||
      return this.vpDatum.getFullYear() + "" + (this.vpDatum.getMonth() + 1) + "" + this.vpDatum.getDate()
 | 
			
		||||
    },
 | 
			
		||||
    neuesDatum: {
 | 
			
		||||
      get: function () {
 | 
			
		||||
        return this.vpDatum.toISOString().substr(0, 10)
 | 
			
		||||
      },
 | 
			
		||||
      set: function (val) {
 | 
			
		||||
        this.vpDatum = new Date(val)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    today () {
 | 
			
		||||
      var d = new Date()
 | 
			
		||||
      return d.toDateString() === this.vpDatum.toDateString()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    async reload () {
 | 
			
		||||
      // Feldnamen definieren
 | 
			
		||||
      const vpHeader  = 'nr,datum,stunde,absenznr,id_unterricht,lehrkraft,lehrkraft_vertretung,fach,fach_statistik_id,fach_vertretung,fach_vertretung_statistik_id,raum,raum_vertretung,statistik_id,klassen,absenzgrund,anmerkung,art,klassen_vertretung,art_vertretung,letzte_aenderung,extra\n'
 | 
			
		||||
      // Abrufen
 | 
			
		||||
      const res = await fetch(this.vpUrl)
 | 
			
		||||
      // Text extrahieren und Feldnamen hinzufügen
 | 
			
		||||
      const vpText = vpHeader + await res.text()
 | 
			
		||||
      // Parsen und Array in Daten ablegen
 | 
			
		||||
      this.vp = this.$papa.parse(vpText, {'header': 'true', 'skipEmptyLines': 'greedy'}).data 
 | 
			
		||||
    },
 | 
			
		||||
    vertretungsart (code) {
 | 
			
		||||
      return vertretungsarten[code]
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
    // Startdatum festlegen
 | 
			
		||||
    if (typeof this.startDatum !== 'undefined') this.vpDatum = this.startDatum
 | 
			
		||||
    // Vertretungsplan neu laden
 | 
			
		||||
    this.reload()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  div.news-text {
 | 
			
		||||
    height: calc(100% - 6px);
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,11 @@
 | 
			
		|||
import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import Vuetify from 'vuetify/lib/framework';
 | 
			
		||||
 | 
			
		||||
Vue.use(Vuetify);
 | 
			
		||||
 | 
			
		||||
export default new Vuetify({
 | 
			
		||||
  icons: {
 | 
			
		||||
    iconfont: 'mdi'
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,9 @@
 | 
			
		|||
import Vue from 'vue'
 | 
			
		||||
import VueRouter from 'vue-router'
 | 
			
		||||
 | 
			
		||||
import VuePapaParse from 'vue-papa-parse'
 | 
			
		||||
Vue.use(VuePapaParse)
 | 
			
		||||
 | 
			
		||||
Vue.use(VueRouter)
 | 
			
		||||
 | 
			
		||||
const routes = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,37 +1,110 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="ids">
 | 
			
		||||
    <v-app-bar
 | 
			
		||||
      app
 | 
			
		||||
      color="indigo"
 | 
			
		||||
      dark
 | 
			
		||||
    >
 | 
			
		||||
      <v-img
 | 
			
		||||
        alt="Logo"
 | 
			
		||||
        class="shrink mr-2"
 | 
			
		||||
        contain
 | 
			
		||||
        src="@/assets/logo.svg"
 | 
			
		||||
        transition="scale-transition"
 | 
			
		||||
        width="40"
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
 | 
			
		||||
      <v-tabs>
 | 
			
		||||
        <v-tab
 | 
			
		||||
          v-for="link in links"
 | 
			
		||||
          :key="link"
 | 
			
		||||
        >
 | 
			
		||||
          {{ link }}
 | 
			
		||||
        </v-tab>
 | 
			
		||||
      </v-tabs>
 | 
			
		||||
 | 
			
		||||
  <v-app>
 | 
			
		||||
    <v-navigation-drawer app>
 | 
			
		||||
      <!-- -->
 | 
			
		||||
    </v-navigation-drawer>
 | 
			
		||||
  
 | 
			
		||||
    <v-app-bar app>
 | 
			
		||||
      <!-- -->
 | 
			
		||||
    </v-app-bar>
 | 
			
		||||
  
 | 
			
		||||
    <!-- Sizes your content based upon application components -->
 | 
			
		||||
 | 
			
		||||
    <v-main>
 | 
			
		||||
  
 | 
			
		||||
      <!-- Provides the application the proper gutter -->
 | 
			
		||||
      <v-container fluid>
 | 
			
		||||
  
 | 
			
		||||
        <!-- If using vue-router -->
 | 
			
		||||
        <router-view></router-view>
 | 
			
		||||
        <v-row dense>
 | 
			
		||||
 | 
			
		||||
          <v-col
 | 
			
		||||
            cols="8"
 | 
			
		||||
          >
 | 
			
		||||
            <v-sheet
 | 
			
		||||
              min-height="70vh"
 | 
			
		||||
              rounded="lg"
 | 
			
		||||
              elevation="2"
 | 
			
		||||
            >
 | 
			
		||||
              <Vertretungsplan
 | 
			
		||||
                vpUrl="/stundenplan/proxy.php?file=G014"
 | 
			
		||||
                :startDatum="startDatum"
 | 
			
		||||
              />
 | 
			
		||||
            </v-sheet>
 | 
			
		||||
          </v-col>
 | 
			
		||||
 | 
			
		||||
          <v-col
 | 
			
		||||
            cols="4"
 | 
			
		||||
          >
 | 
			
		||||
            <v-sheet
 | 
			
		||||
              rounded="lg"
 | 
			
		||||
              min-height="268"
 | 
			
		||||
              elevation="2"
 | 
			
		||||
            >
 | 
			
		||||
              <Newsreader
 | 
			
		||||
                :feedUrls="['/stundenplan/proxy.php?file=rsslul', '/stundenplan/proxy.php?file=rsssul']"
 | 
			
		||||
              />
 | 
			
		||||
            </v-sheet>
 | 
			
		||||
<!--
 | 
			
		||||
            <v-sheet
 | 
			
		||||
              rounded="lg"
 | 
			
		||||
              min-height="268"
 | 
			
		||||
              elevation="2"
 | 
			
		||||
            >
 | 
			
		||||
 | 
			
		||||
            </v-sheet> -->
 | 
			
		||||
          </v-col>
 | 
			
		||||
        </v-row>
 | 
			
		||||
      </v-container>
 | 
			
		||||
    </v-main>
 | 
			
		||||
  
 | 
			
		||||
    <v-footer app>
 | 
			
		||||
      <!-- -->
 | 
			
		||||
    </v-footer>
 | 
			
		||||
  </v-app>
 | 
			
		||||
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Newsreader from '@/components/Newsreader'
 | 
			
		||||
import Vertretungsplan from '@/components/Vertretungsplan'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'InfodisplayLehrer',
 | 
			
		||||
 | 
			
		||||
  data: () => ({
 | 
			
		||||
    links: [
 | 
			
		||||
      'Vertretungsplan',
 | 
			
		||||
      'Stundenpläne'
 | 
			
		||||
    ],
 | 
			
		||||
    startDatum: new Date()
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  props: {
 | 
			
		||||
    msg: String
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  components: {
 | 
			
		||||
    Newsreader,
 | 
			
		||||
    Vertretungsplan
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  created: function () {
 | 
			
		||||
    if (this.startDatum.getDay() === 6) {
 | 
			
		||||
      // Samstag => Montag
 | 
			
		||||
      this.startDatum.setDate(this.startDatum.getDate() + 2)
 | 
			
		||||
    } else if (this.startDatum.getDay() === 0) {
 | 
			
		||||
      // Sonntag => Montag
 | 
			
		||||
      this.startDatum.setDate(this.startDatum.getDate() + 1)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="hello">
 | 
			
		||||
  <div class="ids grey lighten-3">
 | 
			
		||||
    <h1>Schueler</h1>
 | 
			
		||||
    {{ msg }}
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -13,3 +13,9 @@ export default {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  div.ids {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,8 @@
 | 
			
		|||
module.exports = {
 | 
			
		||||
  transpileDependencies: [
 | 
			
		||||
    'vuetify'
 | 
			
		||||
  ]
 | 
			
		||||
  ],
 | 
			
		||||
  devServer: {
 | 
			
		||||
    proxy: 'https://dsp.uber.space/',
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue