release v2.0.0 #4
|
@ -0,0 +1,9 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
|
@ -0,0 +1,7 @@
|
||||||
|
/dist
|
||||||
|
/src-bex/www
|
||||||
|
/src-capacitor
|
||||||
|
/src-cordova
|
||||||
|
/.quasar
|
||||||
|
/node_modules
|
||||||
|
/src-ssr
|
|
@ -0,0 +1,86 @@
|
||||||
|
const { resolve } = require('path');
|
||||||
|
module.exports = {
|
||||||
|
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
|
||||||
|
// This option interrupts the configuration hierarchy at this file
|
||||||
|
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
|
||||||
|
root: true,
|
||||||
|
|
||||||
|
// https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
|
||||||
|
// Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
|
||||||
|
// `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
|
||||||
|
parserOptions: {
|
||||||
|
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
|
||||||
|
// https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint
|
||||||
|
// Needed to make the parser take into account 'vue' files
|
||||||
|
extraFileExtensions: ['.vue'],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
project: resolve(__dirname, './tsconfig.json'),
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
|
||||||
|
sourceType: 'module' // Allows for the use of imports
|
||||||
|
},
|
||||||
|
|
||||||
|
env: {
|
||||||
|
browser: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// Rules order is important, please avoid shuffling them
|
||||||
|
extends: [
|
||||||
|
// Base ESLint recommended rules
|
||||||
|
// 'eslint:recommended',
|
||||||
|
|
||||||
|
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
|
||||||
|
// ESLint typescript rules
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
// consider disabling this class of rules if linting takes too long
|
||||||
|
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||||
|
|
||||||
|
// Uncomment any of the lines below to choose desired strictness,
|
||||||
|
// but leave only one uncommented!
|
||||||
|
// See https://eslint.vuejs.org/rules/#available-rules
|
||||||
|
'plugin:vue/essential', // Priority A: Essential (Error Prevention)
|
||||||
|
// 'plugin:vue/strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
|
||||||
|
// 'plugin:vue/recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
|
||||||
|
|
||||||
|
// https://github.com/prettier/eslint-config-prettier#installation
|
||||||
|
// usage with Prettier, provided by 'eslint-config-prettier'.
|
||||||
|
'prettier',
|
||||||
|
'prettier/@typescript-eslint',
|
||||||
|
'prettier/vue'
|
||||||
|
],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
// required to apply rules which need type information
|
||||||
|
'@typescript-eslint',
|
||||||
|
|
||||||
|
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
|
||||||
|
// required to lint *.vue files
|
||||||
|
'vue',
|
||||||
|
|
||||||
|
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
|
||||||
|
// Prettier has not been included as plugin to avoid performance impact
|
||||||
|
// add it as an extension for your IDE
|
||||||
|
],
|
||||||
|
|
||||||
|
globals: {
|
||||||
|
ga: true, // Google Analytics
|
||||||
|
cordova: true,
|
||||||
|
__statics: true,
|
||||||
|
process: true,
|
||||||
|
Capacitor: true,
|
||||||
|
chrome: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// add your custom rules here
|
||||||
|
rules: {
|
||||||
|
'prefer-promise-reject-errors': 'off',
|
||||||
|
|
||||||
|
// TypeScript
|
||||||
|
quotes: ['warn', 'single', { avoidEscape: true }],
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
|
||||||
|
// allow debugger during development only
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,24 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.thumbs.db
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# Quasar core related directories
|
||||||
|
.quasar
|
||||||
/dist
|
/dist
|
||||||
|
|
||||||
# local env files
|
# Cordova related directories and files
|
||||||
.env.local
|
/src-cordova/node_modules
|
||||||
.env.*.local
|
/src-cordova/platforms
|
||||||
|
/src-cordova/plugins
|
||||||
|
/src-cordova/www
|
||||||
|
|
||||||
|
# Capacitor related directories and files
|
||||||
|
/src-capacitor/www
|
||||||
|
/src-capacitor/node_modules
|
||||||
|
|
||||||
|
# BEX related directories and files
|
||||||
|
/src-bex/www
|
||||||
|
/src-bex/js/core
|
||||||
|
|
||||||
# Log files
|
# Log files
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
@ -13,9 +27,7 @@ yarn-error.log*
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
// to edit target browsers: use "browserslist" field in package.json
|
||||||
|
require('autoprefixer')
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"semi": true
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"octref.vetur"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"hookyqr.beautify",
|
||||||
|
"dbaeumer.jshint",
|
||||||
|
"ms-vscode.vscode-typescript-tslint-plugin"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"vetur.validation.template": false,
|
||||||
|
"vetur.format.enable": false,
|
||||||
|
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
|
"vetur.experimental.templateInterpolationService": true
|
||||||
|
}
|
32
README.md
|
@ -1,24 +1,26 @@
|
||||||
# newgruecht-vue
|
# Flaschengeist (flaschengeist-frontend)
|
||||||
|
|
||||||
## Project setup
|
Dynamischen Managementsystem für Studentenclubs
|
||||||
```
|
|
||||||
|
## Install the dependencies
|
||||||
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and hot-reloads for development
|
### Start the app in development mode (hot-code reloading, error reporting, etc.)
|
||||||
```
|
```bash
|
||||||
npm run serve
|
quasar dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and minifies for production
|
### Lint the files
|
||||||
```
|
```bash
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Lints and fixes files
|
|
||||||
```
|
|
||||||
npm run lint
|
npm run lint
|
||||||
```
|
```
|
||||||
|
|
||||||
### Customize configuration
|
### Build the app for production
|
||||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
```bash
|
||||||
|
quasar build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize the configuration
|
||||||
|
See [Configuring quasar.conf.js](https://quasar.dev/quasar-cli/quasar-conf-js).
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
/* eslint-env node */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/cli-plugin-babel/preset'
|
'@quasar/babel-preset-app'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDazCCAlOgAwIBAgIJAJGH2ozWvd1RMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
|
|
||||||
BAYTAkRFMQ8wDQYDVQQIDAZTYXhvbnkxEDAOBgNVBAcMB0RyZXNkZW4xITAfBgNV
|
|
||||||
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAxMTcwOTA0MDFaFw0z
|
|
||||||
MDAxMDQwOTA0MDFaMEQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZTYXhvbnkxEDAO
|
|
||||||
BgNVBAcMB0RyZXNkZW4xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN
|
|
||||||
AQEBBQADggEPADCCAQoCggEBALlkr1UOQypLKicESRnse52d5mAX9MjZQpH0/Y5u
|
|
||||||
V5WxpPSasmOpt4MRj5MWTfTK2ukj/jLtPAMsggUh7wMXb1uytHj7T5mtiahXBM0H
|
|
||||||
1sUi2nScXR6doQZlmqKWDGrVS7WHULM01WhirsnxI8S8e6Evpk4F5/RafKA8FgYI
|
|
||||||
Ongg6S1B16+7T0e/FnILoMjKr1jpgzXnVkPFIneu/qVevSNco5/aw+bc6sjeS/ZA
|
|
||||||
65dXFGpDlw0lPRHLT5/CgNyMyiLYov7KwMycZw7uxa1ynO+73tqe5tvO/DiMpAPJ
|
|
||||||
EkrSz/StYBsGJxDhwq5RT31tHVtHhTf0rk1BmaoQJ0Aq7iECAwEAAaNRME8wHwYD
|
|
||||||
VR0jBBgwFoAUt8P5gBfN9hCUAiWhtPH5fTWnctAwCQYDVR0TBAIwADALBgNVHQ8E
|
|
||||||
BAMCBPAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCD
|
|
||||||
fBByVq8AbV1DMrY+MElb/nZA5/cuGnUpBpjSlk5OnYHWtywuQk6veiiJ0S2fNfqf
|
|
||||||
RzwOFuZDHKmIcH0574VssLfUynMKP3w3xb2ZNic3AxAdhzZ6LXLx6+qF5tYcL7oC
|
|
||||||
UWmj5Mo9SkX5HZLEGamQlVyGOGKNatxep4liyoSeKXr0AOHYfB4AkDhVZn7yQc/v
|
|
||||||
But42fLBg4mE+rk4UBYOHA4XdoFwqgTCNZq2RxKzvG9LIcok6lOc6gDnfTsH8GqE
|
|
||||||
byGpfIIQAXF8aftCm4dGXxtzMh8C5d0t2Ell9g+Rr8i/enebT2nJ9B9ptldDjhcZ
|
|
||||||
7I0ywGsXwrh0EwFsX74/
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,28 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5ZK9VDkMqSyon
|
|
||||||
BEkZ7HudneZgF/TI2UKR9P2ObleVsaT0mrJjqbeDEY+TFk30ytrpI/4y7TwDLIIF
|
|
||||||
Ie8DF29bsrR4+0+ZrYmoVwTNB9bFItp0nF0enaEGZZqilgxq1Uu1h1CzNNVoYq7J
|
|
||||||
8SPEvHuhL6ZOBef0WnygPBYGCDp4IOktQdevu09HvxZyC6DIyq9Y6YM151ZDxSJ3
|
|
||||||
rv6lXr0jXKOf2sPm3OrI3kv2QOuXVxRqQ5cNJT0Ry0+fwoDcjMoi2KL+ysDMnGcO
|
|
||||||
7sWtcpzvu97anubbzvw4jKQDyRJK0s/0rWAbBicQ4cKuUU99bR1bR4U39K5NQZmq
|
|
||||||
ECdAKu4hAgMBAAECggEABoMQ3Y34sf2d52zxHGYAGZM4SlvND1kCS5otZdleXjW1
|
|
||||||
M5pTdci6V3JAdswrxNNzSQkonqVSnFHt5zw/5v3lvXTTfgRl0WIVGcKkuobx9k65
|
|
||||||
Gat8YdzrkQv0mI1otj/zvtaX8ROEA3yj4xgDR5/PP+QqlUcD1MNw6TfzFhcn5pxB
|
|
||||||
/RDPmvarMhzMdDW60Uub6Z7e/kVPuXWrW4bDyULd1d1NoSibnFZi+vGY0Lc1ctDW
|
|
||||||
2Vl7A8RFTcQi6Cjx/FwgPGJTBE4UMjIBO3wnoPQBMrsSxeGhcarerqIlEafgT4XN
|
|
||||||
p9BMtRyaXE7TTb1BXc35ZYNJLDLJKQxABhrEHtFreQKBgQDpiGwuKAFK8BLPlbAx
|
|
||||||
zkShhKd9fhlwm2bfRv3cojPQZsxn0BjefmtrISbKCD79Ivyn7TnOyYAoKAxdp2q9
|
|
||||||
wtz94aAXV2lfhUw2lhcb/aw4sXuY/s1XnVyoglOO8pYRCUN0o80pKuWFsaDyy/uL
|
|
||||||
LhINff1oMNCa7vmMdu8Ccz0o/wKBgQDLOqdTQhSFs4f1yhlDDH3pqT6eKvtFNeRJ
|
|
||||||
usxYDnAyRXHRqwhQ86z1nBZIgwXqq7PfO9V5Y/l6/2HmmA2ufjS8aBTNpCUMuvJk
|
|
||||||
y98Z4hTjKRdnVlMUjHq9ahCixJVQ8pcCnWRFdeAwSKhHQiJEFLYeYOIrUeCIYJI4
|
|
||||||
FiCshSPI3wKBgGU0ErWZ7p18FprRIs8itYlNhIwUxo+POPCPwloIDO5GblSa0Pwy
|
|
||||||
yvhdIIMzOaDXtahMXN3pYtmEKX+4msBrnvuC+K7E2cxkZtfNCWy+7RCQkaCG45QR
|
|
||||||
hOMdv3pWVIRDgHEevz0U8uySQs6VaYgySe6A5/1sEiriX1DpBcEJEbsfAoGAKUCb
|
|
||||||
rGvSbJ1XsM24OQL1IBQJsON6o77fuxOe3RT5M0sjYnL8OipsZmKrp0ZpUgxOc7ba
|
|
||||||
i0x+3LewMLWWuV/G5qOd7WwvVRkxkMJNZByfLskthf1g2d/2HjLEc7XBtW+4tYAr
|
|
||||||
VWoq+sIU3noPKJCnsxzpa++vyx8HLzlWoo5YCDMCgYBJvGH2zMgInlQNO/2XY5nl
|
|
||||||
E53EZMex+RDq8Wzr4tRM3IrCGc2t8WKEQ/9teKNH0tg9xib0vhqqmiGl1xNfqJVo
|
|
||||||
ePJyfgFabeUx9goG3mgTdV9woSRlBJso62dM0DAC/jsJoHnVzgokysR4/BfW9Da+
|
|
||||||
AYTxRZSNbfmsTHawXqG8Fw==
|
|
||||||
-----END PRIVATE KEY-----
|
|
85
package.json
|
@ -1,61 +1,46 @@
|
||||||
{
|
{
|
||||||
"name": "newgruecht-vue",
|
"name": "flaschengeist-frontend",
|
||||||
"version": "1.1.0",
|
"version": "0.0.1",
|
||||||
|
"description": "Dynamischen Managementsystem für Studentenclubs",
|
||||||
|
"productName": "Flaschengeist",
|
||||||
|
"author": "Tim Gröger <tim@groeger-clan.de>",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"lint": "eslint --ext .js,.ts,.vue ./",
|
||||||
"build": "vue-cli-service build",
|
"test": "echo \"No test specified\" && exit 0"
|
||||||
"lint": "vue-cli-service lint"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "^4.9.95",
|
"@quasar/extras": "^1.0.0",
|
||||||
"@mdi/js": "^4.9.95",
|
"@vue/composition-api": "^0.6.4",
|
||||||
|
"axios": "^0.18.1",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"vue": "^2.6.10",
|
"quasar": "^1.0.0"
|
||||||
"vue-router": "^3.2.0",
|
|
||||||
"vuetify": "^2.3.8",
|
|
||||||
"vuex": "^3.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^4.3.1",
|
"@quasar/app": "^2.0.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
"@types/node": "^10.17.15",
|
||||||
"@vue/cli-plugin-router": "^4.3.1",
|
"@typescript-eslint/eslint-plugin": "^3.3.0",
|
||||||
"@vue/cli-plugin-vuex": "^4.3.1",
|
"@typescript-eslint/parser": "^3.3.0",
|
||||||
"@vue/cli-service": "^4.3.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"eslint": "^6.8.0",
|
||||||
"axios": "^0.19.2",
|
"eslint-config-prettier": "^6.9.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"eslint-loader": "^3.0.3",
|
||||||
"eslint": "^5.16.0",
|
"eslint-plugin-vue": "^6.1.2"
|
||||||
"eslint-plugin-prettier": "^3.1.3",
|
|
||||||
"eslint-plugin-vue": "^5.0.0",
|
|
||||||
"material-design-icons-iconfont": "^5.0.1",
|
|
||||||
"prettier": "^1.19.1",
|
|
||||||
"sass": "^1.26.5",
|
|
||||||
"sass-loader": "^8.0.2",
|
|
||||||
"vue-cli-plugin-vuetify": "^2.0.5",
|
|
||||||
"vue-template-compiler": "^2.6.10",
|
|
||||||
"vuetify-loader": "^1.4.4"
|
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"root": true,
|
|
||||||
"env": {
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"plugin:vue/essential",
|
|
||||||
"plugin:prettier/recommended",
|
|
||||||
"@vue/prettier",
|
|
||||||
"eslint:recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"no-console": "off"
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"parser": "babel-eslint"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"last 10 Chrome versions",
|
||||||
"last 2 versions"
|
"last 10 Firefox versions",
|
||||||
]
|
"last 4 Edge versions",
|
||||||
|
"last 7 Safari versions",
|
||||||
|
"last 8 Android versions",
|
||||||
|
"last 8 ChromeAndroid versions",
|
||||||
|
"last 8 FirefoxAndroid versions",
|
||||||
|
"last 10 iOS versions",
|
||||||
|
"last 5 Opera versions"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.18.1",
|
||||||
|
"npm": ">= 6.13.4",
|
||||||
|
"yarn": ">= 1.21.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 555 B |
After Width: | Height: | Size: 998 B |
After Width: | Height: | Size: 3.2 KiB |
|
@ -1,19 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
||||||
<link rel="icon" href="<%= BASE_URL %>wuicon.ico">
|
|
||||||
<title>Flaschengeist</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>
|
|
||||||
<strong>We're sorry but newgruecht-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
|
||||||
</noscript>
|
|
||||||
<div id="app"></div>
|
|
||||||
<!-- built files will be auto injected -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Before Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* This file runs in a Node context (it's NOT transpiled by Babel), so use only
|
||||||
|
* the ES6 features that are supported by your Node version. https://node.green/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Configuration for your app
|
||||||
|
// https://quasar.dev/quasar-cli/quasar-conf-js
|
||||||
|
/* eslint-env node */
|
||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
|
const { configure } = require('quasar/wrappers');
|
||||||
|
|
||||||
|
module.exports = configure(function (ctx) {
|
||||||
|
return {
|
||||||
|
// https://quasar.dev/quasar-cli/supporting-ts
|
||||||
|
supportTS: {
|
||||||
|
tsCheckerConfig: {
|
||||||
|
eslint: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/prefetch-feature
|
||||||
|
// preFetch: true,
|
||||||
|
|
||||||
|
// app boot file (/src/boot)
|
||||||
|
// --> boot files are part of "main.js"
|
||||||
|
// https://quasar.dev/quasar-cli/boot-files
|
||||||
|
boot: [
|
||||||
|
'composition-api',
|
||||||
|
'axios',
|
||||||
|
],
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
|
||||||
|
css: [
|
||||||
|
'app.scss'
|
||||||
|
],
|
||||||
|
|
||||||
|
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||||
|
extras: [
|
||||||
|
// 'ionicons-v4',
|
||||||
|
// 'mdi-v5',
|
||||||
|
// 'fontawesome-v5',
|
||||||
|
// 'eva-icons',
|
||||||
|
// 'themify',
|
||||||
|
// 'line-awesome',
|
||||||
|
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
|
||||||
|
|
||||||
|
'roboto-font', // optional, you are not bound to it
|
||||||
|
'material-icons', // optional, you are not bound to it
|
||||||
|
],
|
||||||
|
|
||||||
|
// Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
|
||||||
|
build: {
|
||||||
|
vueRouterMode: 'hash', // available values: 'hash', 'history'
|
||||||
|
|
||||||
|
// transpile: false,
|
||||||
|
|
||||||
|
// Add dependencies for transpiling with Babel (Array of string/regex)
|
||||||
|
// (from node_modules, which are by default not transpiled).
|
||||||
|
// Applies only if "transpile" is set to true.
|
||||||
|
// transpileDependencies: [],
|
||||||
|
|
||||||
|
// rtl: false, // https://quasar.dev/options/rtl-support
|
||||||
|
// preloadChunks: true,
|
||||||
|
// showProgress: false,
|
||||||
|
// gzip: true,
|
||||||
|
// analyze: true,
|
||||||
|
|
||||||
|
// Options below are automatically set depending on the env, set them if you want to override
|
||||||
|
// extractCSS: false,
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/handling-webpack
|
||||||
|
extendWebpack (cfg) {
|
||||||
|
// linting is slow in TS projects, we execute it only for production builds
|
||||||
|
if (ctx.prod) {
|
||||||
|
cfg.module.rules.push({
|
||||||
|
enforce: 'pre',
|
||||||
|
test: /\.(js|vue)$/,
|
||||||
|
loader: 'eslint-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer
|
||||||
|
devServer: {
|
||||||
|
https: false,
|
||||||
|
port: 8080,
|
||||||
|
open: true // opens browser window automatically
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
|
||||||
|
framework: {
|
||||||
|
iconSet: 'material-icons', // Quasar icon set
|
||||||
|
lang: 'en-us', // Quasar language pack
|
||||||
|
config: {},
|
||||||
|
|
||||||
|
// Possible values for "importStrategy":
|
||||||
|
// * 'auto' - (DEFAULT) Auto-import needed Quasar components & directives
|
||||||
|
// * 'all' - Manually specify what to import
|
||||||
|
importStrategy: 'auto',
|
||||||
|
|
||||||
|
// For special cases outside of where "auto" importStrategy can have an impact
|
||||||
|
// (like functional components as one of the examples),
|
||||||
|
// you can manually specify Quasar components/directives to be available everywhere:
|
||||||
|
//
|
||||||
|
// components: [],
|
||||||
|
// directives: [],
|
||||||
|
|
||||||
|
// Quasar plugins
|
||||||
|
plugins: []
|
||||||
|
},
|
||||||
|
|
||||||
|
// animations: 'all', // --- includes all animations
|
||||||
|
// https://quasar.dev/options/animations
|
||||||
|
animations: [],
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr
|
||||||
|
ssr: {
|
||||||
|
pwa: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa
|
||||||
|
pwa: {
|
||||||
|
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
|
||||||
|
workboxOptions: {}, // only for GenerateSW
|
||||||
|
manifest: {
|
||||||
|
name: 'Flaschengeist',
|
||||||
|
short_name: 'Flaschengeist',
|
||||||
|
description: 'Dynamischen Managementsystem für Studentenclubs',
|
||||||
|
display: 'standalone',
|
||||||
|
orientation: 'portrait',
|
||||||
|
background_color: '#ffffff',
|
||||||
|
theme_color: '#027be3',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: 'icons/icon-128x128.png',
|
||||||
|
sizes: '128x128',
|
||||||
|
type: 'image/png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'icons/icon-192x192.png',
|
||||||
|
sizes: '192x192',
|
||||||
|
type: 'image/png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'icons/icon-256x256.png',
|
||||||
|
sizes: '256x256',
|
||||||
|
type: 'image/png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'icons/icon-384x384.png',
|
||||||
|
sizes: '384x384',
|
||||||
|
type: 'image/png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'icons/icon-512x512.png',
|
||||||
|
sizes: '512x512',
|
||||||
|
type: 'image/png'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
|
||||||
|
cordova: {
|
||||||
|
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
|
||||||
|
},
|
||||||
|
|
||||||
|
// Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
|
||||||
|
capacitor: {
|
||||||
|
hideSplashscreen: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
|
||||||
|
electron: {
|
||||||
|
bundler: 'packager', // 'packager' or 'builder'
|
||||||
|
|
||||||
|
packager: {
|
||||||
|
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
|
||||||
|
|
||||||
|
// OS X / Mac App Store
|
||||||
|
// appBundleId: '',
|
||||||
|
// appCategoryType: '',
|
||||||
|
// osxSign: '',
|
||||||
|
// protocol: 'myapp://path',
|
||||||
|
|
||||||
|
// Windows only
|
||||||
|
// win32metadata: { ... }
|
||||||
|
},
|
||||||
|
|
||||||
|
builder: {
|
||||||
|
// https://www.electron.build/configuration/configuration
|
||||||
|
|
||||||
|
appId: 'flaschengeist-frontend'
|
||||||
|
},
|
||||||
|
|
||||||
|
// More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
|
||||||
|
nodeIntegration: true,
|
||||||
|
|
||||||
|
extendWebpack (/* cfg */) {
|
||||||
|
// do something with Electron main process Webpack cfg
|
||||||
|
// chainWebpack also available besides this extendWebpack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
230
src/App.vue
|
@ -1,232 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<v-app>
|
<div id="q-app">
|
||||||
<TitleBar />
|
|
||||||
<router-view />
|
<router-view />
|
||||||
<v-footer app>
|
|
||||||
<span class="px-4 d-none d-sm-flex"
|
|
||||||
>© {{ new Date().getFullYear() }}
|
|
||||||
<v-btn x-small text class="text-none subtitle-1" href="https://wu5.de">
|
|
||||||
Studentenclub Wu5 e.V.
|
|
||||||
</v-btn>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<v-btn text x-small href="https://wu5.de/impressum">
|
|
||||||
Impressum
|
|
||||||
</v-btn>
|
|
||||||
<v-btn text x-small href="https://wu5.de/datenschutz">
|
|
||||||
Datenschutzerklärung
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
x-small
|
|
||||||
v-if="isLoggedIn"
|
|
||||||
href="https://groeger-clan.duckdns.org/redmine/projects/geruecht/issues/new"
|
|
||||||
>
|
|
||||||
Bugs?
|
|
||||||
</v-btn>
|
|
||||||
</span>
|
|
||||||
<v-spacer />
|
|
||||||
<div v-if="isLoggedIn && !change" :key="render">
|
|
||||||
<v-hover
|
|
||||||
v-slot:default="{ hover }"
|
|
||||||
open-delay="200"
|
|
||||||
close-delay="200"
|
|
||||||
class="d-none d-sm-flex"
|
|
||||||
>
|
|
||||||
<v-sheet
|
|
||||||
:elevation="hover ? 16 : 0"
|
|
||||||
color="#f5f5f5"
|
|
||||||
@click="change = !change"
|
|
||||||
>{{ calcTime }}</v-sheet
|
|
||||||
>
|
|
||||||
</v-hover>
|
|
||||||
<v-hover
|
|
||||||
v-slot:default="{ hover }"
|
|
||||||
open-delay="200"
|
|
||||||
close-delay="200"
|
|
||||||
class="d-flex d-sm-none"
|
|
||||||
>
|
|
||||||
<v-sheet
|
|
||||||
:elevation="hover ? 16 : 0"
|
|
||||||
color="#f5f5f5"
|
|
||||||
@click="change = !change"
|
|
||||||
>{{ calcTimeLittle }}</v-sheet
|
|
||||||
>
|
|
||||||
</v-hover>
|
|
||||||
</div>
|
</div>
|
||||||
<v-dialog v-model="change" max-width="300">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Zeit bis zum Logout ändern
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-combobox
|
|
||||||
solo
|
|
||||||
:items="lifeTimes"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
v-model="selectLifetime"
|
|
||||||
return-object
|
|
||||||
/>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="change = false">Abbrechen</v-btn>
|
|
||||||
<v-btn color="primary" text @click="save()">Speichern</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</v-footer>
|
|
||||||
</v-app>
|
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from '@vue/composition-api';
|
||||||
|
|
||||||
<script>
|
export default defineComponent({
|
||||||
import TitleBar from './components/TitleBar'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: { TitleBar },
|
});
|
||||||
data: () => ({
|
|
||||||
render: 0,
|
|
||||||
timer: null,
|
|
||||||
change: false,
|
|
||||||
selectLifetime: { text: '30 Minuten', value: 1800 },
|
|
||||||
lifeTimes: [
|
|
||||||
{
|
|
||||||
text: '5 Minuten',
|
|
||||||
value: 300
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '10 Minuten',
|
|
||||||
value: 600
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '15 Minuten',
|
|
||||||
value: 900
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '30 Minuten',
|
|
||||||
value: 1800
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '1 Stunde',
|
|
||||||
value: 3600
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '2 Stunden',
|
|
||||||
value: 7200
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '3 Stunden',
|
|
||||||
value: 10800
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '1 Tag',
|
|
||||||
value: 86400
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '2 Tage',
|
|
||||||
value: 172800
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '1 Woche',
|
|
||||||
value: 604800
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '1 Monat',
|
|
||||||
value: 2678400
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
created() {
|
|
||||||
if (this.isLoggedIn) {
|
|
||||||
this.getLifetime()
|
|
||||||
}
|
|
||||||
this.timer = setInterval(this.test, 1000)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions(['setLifetime', 'saveLifetime', 'logout', 'getLifetime']),
|
|
||||||
test() {
|
|
||||||
if (this.isLoggedIn) {
|
|
||||||
if (this.lifeTime == 0) this.logout()
|
|
||||||
this.setLifetime(this.lifeTime - 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.saveLifetime(this.selectLifetime.value)
|
|
||||||
this.change = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['isLoggedIn', 'lifeTime', 'getMinute', 'getSeconds']),
|
|
||||||
calcTime() {
|
|
||||||
var minutes = this.lifeTime / 60
|
|
||||||
var seconds = this.lifeTime % 60
|
|
||||||
var minutesString =
|
|
||||||
minutes < 10 ? '0' + Math.floor(minutes % 60) : Math.floor(minutes % 60)
|
|
||||||
var secondsString =
|
|
||||||
seconds < 10 ? '0' + Math.floor(seconds) : Math.floor(seconds)
|
|
||||||
if (minutes > 60) {
|
|
||||||
var hours = minutes / 60
|
|
||||||
if (hours > 24) {
|
|
||||||
var days = hours / 24
|
|
||||||
var now = new Date()
|
|
||||||
var dayMonth = new Date(
|
|
||||||
now.getFullYear(),
|
|
||||||
now.getMonth() + 1,
|
|
||||||
0
|
|
||||||
).getDate()
|
|
||||||
if (days >= dayMonth) {
|
|
||||||
return Math.floor(days / dayMonth) + ' Monate bis zum Logout'
|
|
||||||
} else {
|
|
||||||
return Math.floor(days) + ' Tage bis zum Logout'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
Math.floor(hours) +
|
|
||||||
':' +
|
|
||||||
minutesString +
|
|
||||||
':' +
|
|
||||||
secondsString +
|
|
||||||
' Stunden bis zum Logout'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return minutesString + ':' + secondsString + ' Minuten bis zum Logout'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calcTimeLittle() {
|
|
||||||
var minutes = this.lifeTime / 60
|
|
||||||
var seconds = this.lifeTime % 60
|
|
||||||
var minutesString =
|
|
||||||
minutes < 10 ? '0' + Math.floor(minutes % 60) : Math.floor(minutes % 60)
|
|
||||||
var secondsString =
|
|
||||||
seconds < 10 ? '0' + Math.floor(seconds) : Math.floor(seconds)
|
|
||||||
if (minutes > 60) {
|
|
||||||
var hours = minutes / 60
|
|
||||||
if (hours > 24) {
|
|
||||||
var days = hours / 24
|
|
||||||
var now = new Date()
|
|
||||||
var dayMonth = new Date(
|
|
||||||
now.getFullYear(),
|
|
||||||
now.getMonth() + 1,
|
|
||||||
0
|
|
||||||
).getDate()
|
|
||||||
if (days >= dayMonth) {
|
|
||||||
return Math.floor(days / dayMonth) + 'M'
|
|
||||||
} else {
|
|
||||||
return Math.floor(days) + 'D'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Math.floor(hours) + ':' + minutesString + ':' + secondsString
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return minutesString + ':' + secondsString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 322 KiB |
Before Width: | Height: | Size: 6.7 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
|
|
Before Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,191 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="67.407623mm"
|
||||||
|
height="62.908276mm"
|
||||||
|
viewBox="0 0 238.84591 222.90334"
|
||||||
|
id="svg3570"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="quasar-logo-full.svg">
|
||||||
|
<defs
|
||||||
|
id="defs3572" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="-39.753589"
|
||||||
|
inkscape:cy="27.706388"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="g4895-4-4"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1056"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata3575">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-277.71988,-312.33911)">
|
||||||
|
<g
|
||||||
|
id="g4895-4-4"
|
||||||
|
transform="translate(1419.0442,398.9018)">
|
||||||
|
<g
|
||||||
|
transform="translate(-29.620665,-4)"
|
||||||
|
id="g4579-2-20">
|
||||||
|
<g
|
||||||
|
id="g4445-2-0"
|
||||||
|
transform="translate(12.499948,7.809312)">
|
||||||
|
<g
|
||||||
|
inkscape:export-ydpi="44.860481"
|
||||||
|
inkscape:export-xdpi="44.860481"
|
||||||
|
inkscape:export-filename="/home/emanuele/Desktop/logo1.png"
|
||||||
|
transform="translate(-712.85583,-503.26814)"
|
||||||
|
id="g4561-6-7-0">
|
||||||
|
<g
|
||||||
|
transform="translate(16.233481,0)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:50.25774765px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#263238;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="flowRoot4513-6-6-08">
|
||||||
|
<path
|
||||||
|
d="m -402.73125,631.46823 q -0.6125,0.0438 -1.3125,0.0875 -0.65625,0 -1.4,0 l -9.31875,0 q -12.81875,0 -12.81875,-8.44375 l 0,-13.475 q 0,-8.26875 12.6,-8.26875 l 9.75625,0 q 12.6,0 12.6,8.26875 l 0,13.475 q 0,5.03125 -4.4625,7.04375 l 3.10625,2.14375 q 1.35625,0.83125 1.35625,1.70625 0,0.875 -0.7,1.3125 -0.65625,0.48125 -1.88125,0.48125 -0.30625,0 -0.7875,-0.13125 -0.4375,-0.0875 -1.05,-0.48125 l -5.6875,-3.71875 z m 5.38125,-21.74375 q 0,-4.76875 -7.9625,-4.76875 l -9.58125,0 q -7.9625,0 -7.9625,4.76875 l 0,13.3875 q 0,4.94375 8.3125,4.94375 l 8.88125,0 q 8.3125,0 8.3125,-4.94375 l 0,-13.3875 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3428" />
|
||||||
|
<path
|
||||||
|
d="m -368.0585,631.64323 q -11.2875,0 -11.2875,-6.9125 l 0,-12.73125 q 0,-1.8375 2.31875,-1.8375 2.31875,0 2.31875,1.8375 l 0,12.775 q 0,3.325 6.475,3.325 l 8.3125,0 q 6.475,0 6.475,-3.325 l 0,-12.775 q 0,-1.8375 2.31875,-1.8375 2.3625,0 2.3625,1.8375 l 0,12.73125 q 0,6.9125 -11.2875,6.9125 l -8.00625,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3430" />
|
||||||
|
<path
|
||||||
|
d="m -327.2833,631.64323 q -9.3625,0 -9.3625,-5.81875 l 0,-2.49375 q 0,-5.775 9.3625,-5.775 l 18.59375,0 0,-0.65625 q 0,-3.0625 -5.38125,-3.0625 l -6.16875,0 q -2.1875,0 -2.1875,-1.70625 0,-1.75 2.1875,-1.75 l 6.16875,0 q 9.93125,0 9.93125,6.51875 l 0,8.575 q 0,6.16875 -9.5375,6.16875 l -13.60625,0 z m 13.34375,-3.4125 q 5.25,0 5.25,-2.8875 l 0,-4.76875 -18.24375,0 q -5.11875,0 -5.11875,2.66875 l 0,2.275 q 0,2.7125 5.11875,2.7125 l 12.99375,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3432" />
|
||||||
|
<path
|
||||||
|
d="m -262.77031,626.74323 q 0,4.9 -9.975,4.9 l -17.0625,0 q -2.1875,0 -2.1875,-1.70625 0,-1.70625 2.1875,-1.70625 l 17.0625,0 q 5.38125,0 5.38125,-1.4875 l 0,-2.45 q 0,-1.4875 -5.38125,-1.4875 l -9.0125,0 q -9.975,0 -9.975,-4.76875 l 0,-2.05625 q 0,-5.6 10.28125,-5.6 l 5.99375,0 q 2.23125,0 2.23125,1.75 0,0.875 -0.6125,1.3125 -0.56875,0.39375 -1.61875,0.39375 l -5.99375,0 q -5.73125,0 -5.73125,2.14375 l 0,1.925 q 0,1.79375 5.6875,1.79375 l 9.0125,0 q 9.7125,0 9.7125,4.4625 l 0,2.58125 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3434" />
|
||||||
|
<path
|
||||||
|
d="m -241.91709,631.64323 q -9.3625,0 -9.3625,-5.81875 l 0,-2.49375 q 0,-5.775 9.3625,-5.775 l 18.59375,0 0,-0.65625 q 0,-3.0625 -5.38125,-3.0625 l -6.16875,0 q -2.1875,0 -2.1875,-1.70625 0,-1.75 2.1875,-1.75 l 6.16875,0 q 9.93125,0 9.93125,6.51875 l 0,8.575 q 0,6.16875 -9.5375,6.16875 l -13.60625,0 z m 13.34375,-3.4125 q 5.25,0 5.25,-2.8875 l 0,-4.76875 -18.24375,0 q -5.11875,0 -5.11875,2.66875 l 0,2.275 q 0,2.7125 5.11875,2.7125 l 12.99375,0 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3436" />
|
||||||
|
<path
|
||||||
|
d="m -205.62285,617.33698 q 0,-6.95625 11.2875,-6.95625 l 3.36875,0 q 2.23125,0 2.23125,1.79375 0,1.79375 -2.23125,1.79375 l -3.54375,0 q -6.475,0 -6.475,3.28125 l 0,12.775 q 0,1.8375 -2.31875,1.8375 -2.31875,0 -2.31875,-1.8375 l 0,-12.6875 z"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
|
||||||
|
id="path3438" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g5443-0-1-5-1-9"
|
||||||
|
transform="matrix(0.55595317,0,0,0.55595317,-521.93484,-328.66104)"
|
||||||
|
inkscape:export-filename="/home/emanuele/Desktop/logo1.png"
|
||||||
|
inkscape:export-xdpi="44.860481"
|
||||||
|
inkscape:export-ydpi="44.860481">
|
||||||
|
<g
|
||||||
|
inkscape:export-ydpi="3.4165223"
|
||||||
|
inkscape:export-xdpi="3.4165223"
|
||||||
|
transform="matrix(0.09527033,0,0,0.09527033,-1695.2716,706.62921)"
|
||||||
|
id="g8856-6-1-1-9-0-1-9">
|
||||||
|
<circle
|
||||||
|
r="1485"
|
||||||
|
cy="-1361.2571"
|
||||||
|
cx="8317.3574"
|
||||||
|
id="circle8858-1-3-7-6-5-3-0"
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:50;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
inkscape:export-xdpi="10.031387"
|
||||||
|
inkscape:export-ydpi="10.031387" />
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="10.031387"
|
||||||
|
inkscape:export-xdpi="10.031387"
|
||||||
|
style="opacity:1;fill:#263238;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 8560.3823,-1361.3029 a 242.947,242.947 0 0 1 -242.947,242.948 242.947,242.947 0 0 1 -242.947,-242.948 242.947,242.947 0 0 1 242.947,-242.946 242.947,242.947 0 0 1 242.947,242.946 z"
|
||||||
|
id="path8860-5-4-8-2-9-0-9"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path8862-5-5-9-1-3-6-3"
|
||||||
|
d="m 9395.8755,-1984.028 a 1245.372,1245.372 0 0 0 -190.8415,-249.4971 l -280.8618,162.1556 c -87.542,-74.7796 -187.0349,-132.0588 -293.2407,-169.9527 -95.8868,97.1766 -172.0602,205.7604 -226.9672,323.8487 312.6411,-21.2772 635.5313,91.8725 935.2898,326.0721 l 176.7612,-102.0532 a 1245.372,1245.372 0 0 0 -120.1398,-290.5734 z"
|
||||||
|
clip-path="none"
|
||||||
|
mask="none"
|
||||||
|
style="fill:#1976d2;fill-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-x="-514.04855"
|
||||||
|
inkscape:transform-center-y="-444.04649" />
|
||||||
|
<path
|
||||||
|
inkscape:transform-center-y="265.80217"
|
||||||
|
inkscape:transform-center-x="-689.63727"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#42a5f5;fill-opacity:1"
|
||||||
|
mask="none"
|
||||||
|
clip-path="none"
|
||||||
|
d="m 9395.9474,-738.70387 a 1245.372,1245.372 0 0 0 120.6501,-290.02213 l -280.8618,-162.1557 c 20.99,-113.2034 20.8488,-228.0063 0.563,-338.9302 -132.1008,-34.4521 -264.2238,-46.1283 -393.9448,-34.635 174.7471,260.1165 238.2017,596.32248 185.2582,973.02076 l 176.7612,102.05309 a 1245.372,1245.372 0 0 0 191.5741,-249.33082 z"
|
||||||
|
id="path8864-4-8-1-2-4-4-4" />
|
||||||
|
<path
|
||||||
|
id="path8866-7-5-5-0-6-4-7"
|
||||||
|
d="m 8317.501,-115.97954 a 1245.372,1245.372 0 0 0 311.4916,-40.52501 l 0,-324.31131 c 108.5321,-38.42382 207.8837,-95.94755 293.8037,-168.97752 -36.214,-131.6287 -92.1636,-251.88868 -166.9776,-358.48372 -137.894,281.39369 -397.3296,504.44998 -750.0316,646.9487 l 0,204.10623 a 1245.372,1245.372 0 0 0 311.7139,41.24263 z"
|
||||||
|
clip-path="none"
|
||||||
|
mask="none"
|
||||||
|
style="fill:#1976d2;fill-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-x="-117.49007"
|
||||||
|
inkscape:transform-center-y="639.34029" />
|
||||||
|
<path
|
||||||
|
inkscape:transform-center-y="444.04652"
|
||||||
|
inkscape:transform-center-x="514.04857"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#42a5f5;fill-opacity:1"
|
||||||
|
mask="none"
|
||||||
|
clip-path="none"
|
||||||
|
d="m 7238.9827,-738.57936 a 1245.372,1245.372 0 0 0 190.8415,249.49714 l 280.8618,-162.15566 c 87.5421,74.77965 187.0349,132.05879 293.2407,169.95271 95.8868,-97.17659 172.0602,-205.76036 226.9672,-323.8487 -312.6411,21.27714 -635.5313,-91.87254 -935.2898,-326.07203 l -176.7612,102.0531 a 1245.372,1245.372 0 0 0 120.1398,290.57344 z"
|
||||||
|
id="path8868-6-7-4-7-2-7-3" />
|
||||||
|
<path
|
||||||
|
id="path8870-5-3-9-3-5-5-1"
|
||||||
|
d="m 7238.9108,-1983.9035 a 1245.372,1245.372 0 0 0 -120.6501,290.0221 l 280.8618,162.1557 c -20.99,113.2035 -20.8488,228.0063 -0.563,338.9302 132.1008,34.4521 264.2238,46.1283 393.9448,34.635 -174.7471,-260.1165 -238.2017,-596.3225 -185.2582,-973.0207 l -176.7612,-102.0532 a 1245.372,1245.372 0 0 0 -191.5741,249.3309 z"
|
||||||
|
clip-path="none"
|
||||||
|
mask="none"
|
||||||
|
style="fill:#1976d2;fill-opacity:1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-x="689.63729"
|
||||||
|
inkscape:transform-center-y="-265.80221" />
|
||||||
|
<path
|
||||||
|
inkscape:transform-center-y="-639.34032"
|
||||||
|
inkscape:transform-center-x="117.49005"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#42a5f5;fill-opacity:1"
|
||||||
|
mask="none"
|
||||||
|
clip-path="none"
|
||||||
|
d="m 8317.3572,-2606.6279 a 1245.372,1245.372 0 0 0 -311.4915,40.525 l -1e-4,324.3113 c -108.5321,38.4239 -207.8837,95.9476 -293.8037,168.9776 36.214,131.6287 92.1637,251.8886 166.9776,358.4837 137.894,-281.3937 397.3296,-504.45 750.0316,-646.9487 l 1e-4,-204.1063 a 1245.372,1245.372 0 0 0 -311.714,-41.2426 z"
|
||||||
|
id="path8872-6-3-2-1-3-3-7" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,13 @@
|
||||||
|
import axios, { AxiosInstance } from 'axios';
|
||||||
|
import { boot } from 'quasar/wrappers';
|
||||||
|
|
||||||
|
declare module 'vue/types/vue' {
|
||||||
|
interface Vue {
|
||||||
|
$axios: AxiosInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default boot(({ Vue }) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
|
Vue.prototype.$axios = axios;
|
||||||
|
});
|
|
@ -0,0 +1,6 @@
|
||||||
|
import VueCompositionApi from '@vue/composition-api';
|
||||||
|
import { boot } from 'quasar/wrappers';
|
||||||
|
|
||||||
|
export default boot(({ Vue }) => {
|
||||||
|
Vue.use(VueCompositionApi);
|
||||||
|
});
|
|
@ -0,0 +1,59 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p>{{ title }}</p>
|
||||||
|
<ul>
|
||||||
|
<li v-for="todo in todos" :key="todo.id" @click="increment">
|
||||||
|
{{ todo.id }} - {{ todo.content }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Count: {{ todoCount }} / {{ meta.totalCount }}</p>
|
||||||
|
<p>Active: {{ active ? 'yes' : 'no' }}</p>
|
||||||
|
<p>Clicks on todos: {{ clickCount }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
defineComponent, PropType, computed, ref, toRef, Ref,
|
||||||
|
} from '@vue/composition-api';
|
||||||
|
import { Todo, Meta } from './models';
|
||||||
|
|
||||||
|
function useClickCount() {
|
||||||
|
const clickCount = ref(0);
|
||||||
|
function increment() {
|
||||||
|
clickCount.value += 1
|
||||||
|
return clickCount.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { clickCount, increment };
|
||||||
|
}
|
||||||
|
|
||||||
|
function useDisplayTodo(todos: Ref<Todo[]>) {
|
||||||
|
const todoCount = computed(() => todos.value.length);
|
||||||
|
return { todoCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'CompositionComponent',
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
todos: {
|
||||||
|
type: (Array as unknown) as PropType<Todo[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
type: (Object as unknown) as PropType<Meta>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return { ...useClickCount(), ...useDisplayTodo(toRef(props, 'todos')) };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,40 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-snackbar :timeout="0" color="error" :value="visible" top>
|
|
||||||
<v-list color="error" dense>
|
|
||||||
<v-list-item v-for="(error, index) in errors" :key="index" dense>
|
|
||||||
<v-list-item-title class="caption" style="color: white;">
|
|
||||||
{{error.message}}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
<v-btn icon color="white" @click="deleteErrors">
|
|
||||||
<v-icon>
|
|
||||||
mdi-close
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: "ConnectionError",
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
deleteErrors: 'connectionError/deleteErrors'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
errors: 'connectionError/errors',
|
|
||||||
visible: 'connectionError/visible'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,48 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-bottom-sheet persistent v-model="show" hide-overlay>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Cookie und Local Storage Hinweis
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
Diese Webseite benutzt den Local Storage. Dabei werden Daten in ihm
|
|
||||||
gespeichert, welche notwendig sind um sich einzuloggen und eingeloggt zu
|
|
||||||
bleiben. Außerdem sind diese Daten notwendig um mit dem Server zu
|
|
||||||
kommunizieren. Dabei wird ein Key 'user' angelegt, in welchem ein
|
|
||||||
Accesstoken, Benutzername, sowie der Name des Benutzers und deren Rechte
|
|
||||||
gespeichert. Dazu kommt ein Key 'cookie:accepted', falls sie diesem
|
|
||||||
zustimmen. Diese Daten bleiben solange erhalten bis Sie sich ausloggen
|
|
||||||
oder der Accesstoken abgelaufen ist und Sie ausgeloggt werden.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="disableNotification()">Ablehnen</v-btn>
|
|
||||||
<v-btn text color="primary" @click="acceptNotification()">Akzeptieren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-bottom-sheet>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'CookieNotification',
|
|
||||||
methods: {
|
|
||||||
...mapActions(['acceptNotification', 'disableNotification', 'getCookieAccepted'])
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getCookieAccepted()
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
model: 'cookieNotification',
|
|
||||||
cookie: 'cookieAccepted'
|
|
||||||
}),
|
|
||||||
show() {
|
|
||||||
return !this.cookie ? this.model : false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
tag="a"
|
||||||
|
target="_blank"
|
||||||
|
:href="link"
|
||||||
|
>
|
||||||
|
<q-item-section
|
||||||
|
v-if="icon"
|
||||||
|
avatar
|
||||||
|
>
|
||||||
|
<q-icon :name="icon" />
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ title }}</q-item-label>
|
||||||
|
<q-item-label caption>
|
||||||
|
{{ caption }}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from '@vue/composition-api';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'EssentialLink',
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
|
||||||
|
caption: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
link: {
|
||||||
|
type: String,
|
||||||
|
default: '#'
|
||||||
|
},
|
||||||
|
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,146 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-content>
|
|
||||||
<v-container class="fill-height" fluid>
|
|
||||||
<v-row align="center" justify="center">
|
|
||||||
<v-col cols="12" sm="8" md="4">
|
|
||||||
<v-card class="elevation-12">
|
|
||||||
<v-toolbar color="blue accent-4" dark flat dense>
|
|
||||||
<v-toolbar-title>Password vergessen</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
</v-toolbar>
|
|
||||||
<v-card-text>
|
|
||||||
<v-form lazy-validation ref="reset">
|
|
||||||
<v-text-field
|
|
||||||
label="E-Mail oder Nutzername"
|
|
||||||
v-model="input"
|
|
||||||
hint="Hier bitte deinen Nutzernamen oder deine E-Mail angeben. Sollte eins der beiden Daten gefunden werden, wird an deine hinterlegte E-Mail ein Password zum Zurücksetzen gesendet."
|
|
||||||
persistent-hint
|
|
||||||
:prepend-icon="prependIcon"
|
|
||||||
required
|
|
||||||
:rules="[notEmpty, isMail ? email : true]"
|
|
||||||
@keyup.enter="resetPassword()"
|
|
||||||
>
|
|
||||||
</v-text-field>
|
|
||||||
</v-form>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
color="primary"
|
|
||||||
@click="resetPassword()"
|
|
||||||
@submit.prevent="resetPassword()"
|
|
||||||
>
|
|
||||||
Zurücksetzen
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
<v-snackbar bottom :timeout="0" :value="response.value" :color="response.error? 'error' : 'success'">
|
|
||||||
{{ response.message }}
|
|
||||||
<v-btn icon @click="response.value = false">
|
|
||||||
<v-icon color="white">
|
|
||||||
mdi-close
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-snackbar>
|
|
||||||
</v-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import axios from 'axios'
|
|
||||||
import url from '@/plugins/routes'
|
|
||||||
export default {
|
|
||||||
name: 'ResetPassword',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
input: '',
|
|
||||||
response: {
|
|
||||||
error: false,
|
|
||||||
value: false,
|
|
||||||
message: null
|
|
||||||
},
|
|
||||||
defaultResponse: {
|
|
||||||
error: false,
|
|
||||||
value: false,
|
|
||||||
message: null
|
|
||||||
},
|
|
||||||
notEmpty: data => {
|
|
||||||
return data ? true : 'Darf nicht leer sein.'
|
|
||||||
},
|
|
||||||
email: value => {
|
|
||||||
if (value.length > 0) {
|
|
||||||
const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
||||||
return pattern.test(value) || 'keine gültige E-Mail'
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
resetPassword() {
|
|
||||||
if (this.$refs.reset.validate()) {
|
|
||||||
console.log(this.input, this.isMail)
|
|
||||||
if (this.isMail) {
|
|
||||||
axios
|
|
||||||
.post(url.resetPassword, { mail: this.input })
|
|
||||||
.then(data => {
|
|
||||||
console.log(data)
|
|
||||||
this.setMessage(data.data.mail, false)
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
this.setMessage(error, true)
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.$refs.reset.reset()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
axios
|
|
||||||
.post(url.resetPassword, { username: this.input })
|
|
||||||
.then(data => {
|
|
||||||
console.log(data)
|
|
||||||
this.setMessage(data.data.mail, false)
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
this.setMessage(error, true)
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.$refs.reset.reset()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setMessage(mail, error) {
|
|
||||||
if (error) {
|
|
||||||
this.response.error = true
|
|
||||||
this.response.value = true
|
|
||||||
this.response.message =
|
|
||||||
'Es ist ein Fehler aufgetreten. Wende dich an einen Administrator oder probiere es erneut.'
|
|
||||||
} else {
|
|
||||||
this.response.error = false
|
|
||||||
this.response.value = true
|
|
||||||
this.response.message = `Es wurde ein neues Password an ${mail} versendet`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
prependIcon() {
|
|
||||||
if (this.input) {
|
|
||||||
return this.input.includes('@') ? 'mdi-email' : 'mdi-account'
|
|
||||||
}
|
|
||||||
return 'mdi-account'
|
|
||||||
},
|
|
||||||
isMail() {
|
|
||||||
if (this.input) {
|
|
||||||
return this.input.includes('@')
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,94 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-app-bar
|
|
||||||
app
|
|
||||||
clipped-left
|
|
||||||
clipped-right
|
|
||||||
color="blue accent-4"
|
|
||||||
class="elevation-4"
|
|
||||||
dark
|
|
||||||
dense
|
|
||||||
>
|
|
||||||
<v-btn icon @click="reload()">
|
|
||||||
<v-img src="@/assets/logo-64.png" contain height="40"></v-img>
|
|
||||||
</v-btn>
|
|
||||||
<v-toolbar-title>Flaschengeist <span class="caption">v1.1.0 beta 0</span></v-toolbar-title>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-btn icon v-if="getRouteName == 'resetPassword'" @click="goTo('login')">
|
|
||||||
<v-icon>
|
|
||||||
mdi-home
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon v-if="getRouteName == 'priceListNoLogin'" @click="goBack()">
|
|
||||||
<v-icon>
|
|
||||||
{{ back }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon v-if="isFinanzer" :disabled="locked" @click="goTo('overview')">
|
|
||||||
<v-icon>{{ attach_money }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon v-if="isGastro" :disabled="locked" @click="goTo('gastroPricelist')">
|
|
||||||
<v-icon>{{ gastro }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon v-if="isBar" @click="goTo('geruecht')">
|
|
||||||
<v-icon>{{ local_bar }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon v-if="isUser" :disabled="locked" @click="goTo('add')">
|
|
||||||
<v-icon>{{ person }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon @click="goTo('priceListNoLogin')">
|
|
||||||
<v-icon>{{ list }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-app-bar>
|
|
||||||
<ConnectionError/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
import {
|
|
||||||
mdiCurrencyEur,
|
|
||||||
mdiGlassCocktail,
|
|
||||||
mdiAccount,
|
|
||||||
mdiFileMultiple,
|
|
||||||
mdiFoodForkDrink,
|
|
||||||
mdiArrowLeftBoldCircle
|
|
||||||
} from '@mdi/js'
|
|
||||||
import ConnectionError from "@/components/ConnectionError";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'TitleBar',
|
|
||||||
components: {ConnectionError},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
attach_money: mdiCurrencyEur,
|
|
||||||
local_bar: mdiGlassCocktail,
|
|
||||||
person: mdiAccount,
|
|
||||||
list: mdiFileMultiple,
|
|
||||||
gastro: mdiFoodForkDrink,
|
|
||||||
back: mdiArrowLeftBoldCircle
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['isBar', 'isFinanzer', 'isUser', 'isLoggedIn', 'isGastro']),
|
|
||||||
...mapGetters({locked: 'barUsers/locked'}),
|
|
||||||
getRouteName() {
|
|
||||||
return this.$route.name
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions(['logout']),
|
|
||||||
reload() {
|
|
||||||
location.reload()
|
|
||||||
},
|
|
||||||
goTo(name) {
|
|
||||||
this.$router.push({name: name})
|
|
||||||
},
|
|
||||||
goBack() {
|
|
||||||
window.history.length > 1 ? this.$router.go(-1) : this.$router.push({name: 'main'})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,446 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-container v-if="!first_loading">
|
|
||||||
<v-card class="mx-auto" outlined :loading="loading">
|
|
||||||
<v-card-title>
|
|
||||||
<div class="title">Dienstgetränke</div>
|
|
||||||
<v-chip class="ma-2" color="red" text-color="white" v-if="locked"
|
|
||||||
>Gesperrt</v-chip
|
|
||||||
>
|
|
||||||
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-subtitle v-if="limit - free_drink_list_history_job_credit > 0">
|
|
||||||
Noch
|
|
||||||
{{ ((limit - free_drink_list_history_job_credit) / 100).toFixed(2) }}
|
|
||||||
€ übrig!!
|
|
||||||
</v-card-subtitle>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row v-if="!first_loading">
|
|
||||||
<v-col cols="12">
|
|
||||||
<v-row>
|
|
||||||
<v-col
|
|
||||||
v-for="freeDrink in free_drink_list_config_job"
|
|
||||||
:key="freeDrink.id"
|
|
||||||
cols="6"
|
|
||||||
xs="3"
|
|
||||||
sm="4"
|
|
||||||
class="drinkCol"
|
|
||||||
>
|
|
||||||
<v-btn
|
|
||||||
class="drinkBtn"
|
|
||||||
block
|
|
||||||
:disabled="locked"
|
|
||||||
:color="color"
|
|
||||||
@click="addAmount(freeDrink, freeDrinkTypeJob)"
|
|
||||||
>{{ freeDrink.label }}</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row v-if="!first_loading" class="justify-end">
|
|
||||||
<v-col cols="3">
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text :class="getColor()">
|
|
||||||
{{
|
|
||||||
(free_drink_list_history_job_credit / 100).toFixed(2)
|
|
||||||
}}
|
|
||||||
€
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card class="mx-auto" outlined :loading="loading">
|
|
||||||
<v-card-title>
|
|
||||||
<div class="title">Bandgetränke</div>
|
|
||||||
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row v-if="!first_loading">
|
|
||||||
<v-col cols="12">
|
|
||||||
<v-row>
|
|
||||||
<v-col
|
|
||||||
v-for="freeDrink in free_drink_list_config_band"
|
|
||||||
:key="freeDrink.id"
|
|
||||||
cols="6"
|
|
||||||
xs="3"
|
|
||||||
sm="4"
|
|
||||||
class="drinkCol"
|
|
||||||
>
|
|
||||||
<v-btn
|
|
||||||
class="drinkBtn"
|
|
||||||
block
|
|
||||||
:color="color_fix"
|
|
||||||
@click="addAmount(freeDrink, freeDrinkTypeBand)"
|
|
||||||
>{{ freeDrink.label }}</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row v-if="!first_loading" class="justify-end">
|
|
||||||
<v-col cols="3">
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text class="title">
|
|
||||||
{{
|
|
||||||
(free_drink_list_history_band_without_canceled_price/100).toFixed(2)
|
|
||||||
}} €
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-container>
|
|
||||||
|
|
||||||
<v-navigation-drawer v-model="isMenuShow" right app clipped>
|
|
||||||
<v-list-item-group :key="componentRenderer">
|
|
||||||
<v-list-item inactive>
|
|
||||||
<v-list-item-title class="headline">Verlauf</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<div
|
|
||||||
v-for="freeDrinkHistory in free_drink_list_history_bar"
|
|
||||||
:key="freeDrinkHistory.id"
|
|
||||||
>
|
|
||||||
<v-list-item
|
|
||||||
three-line
|
|
||||||
inactive
|
|
||||||
@click="canceledAmount(freeDrinkHistory)"
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title>{{
|
|
||||||
now(freeDrinkHistory.timestamp)
|
|
||||||
}}</v-list-item-title>
|
|
||||||
<v-list-item-subtitle
|
|
||||||
>{{ freeDrinkHistory.free_drink_type.name }}:
|
|
||||||
{{ freeDrinkHistory.free_drink_config.label }} wurde für
|
|
||||||
{{
|
|
||||||
(freeDrinkHistory.free_drink_config.price / 100).toFixed(2)
|
|
||||||
}}
|
|
||||||
€ hinzugefügt.
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle
|
|
||||||
class="red--text"
|
|
||||||
v-if="freeDrinkHistory.canceled"
|
|
||||||
>STORNIERT!!!</v-list-item-subtitle
|
|
||||||
>
|
|
||||||
<v-list-item-action-text
|
|
||||||
v-if="
|
|
||||||
isStronoEnabled(freeDrinkHistory.timestamp) &&
|
|
||||||
!freeDrinkHistory.canceled
|
|
||||||
"
|
|
||||||
>Klicken um zu Stornieren</v-list-item-action-text
|
|
||||||
>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</div>
|
|
||||||
</v-list-item-group>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-dialog v-model="showConfirmCanceledDialog" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Willst du wirklich??</v-card-title>
|
|
||||||
<v-card-text v-if="canceledMessage">
|
|
||||||
{{ canceledMessage.free_drink_type.name }}: Willst du wirklich ein
|
|
||||||
{{ canceledMessage.free_drink_config.label }} im Wert von
|
|
||||||
{{ (canceledMessage.free_drink_config.price / 100).toFixed(2) }} €
|
|
||||||
stornieren?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancelCanceled">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="acceptCanceled">Stornieren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<v-container v-if="first_loading">
|
|
||||||
<AddAmountSkeleton />
|
|
||||||
</v-container>
|
|
||||||
<v-snackbar
|
|
||||||
:color="
|
|
||||||
snackbar_messages.length > 0
|
|
||||||
? snackbar_messages[0].error
|
|
||||||
? 'error'
|
|
||||||
: 'success'
|
|
||||||
: 'success'
|
|
||||||
"
|
|
||||||
bottom
|
|
||||||
:timeout="0"
|
|
||||||
:multi-line="true"
|
|
||||||
:value="snackbar_messages.length > 0 ? snackbar_messages[0].visible : null"
|
|
||||||
vertical
|
|
||||||
>
|
|
||||||
<v-list-item
|
|
||||||
v-for="(message, index) in snackbar_messages"
|
|
||||||
:key="index"
|
|
||||||
:style="
|
|
||||||
message.error
|
|
||||||
? 'background-color: #FF5252;'
|
|
||||||
: 'background-color: #4CAF50;'
|
|
||||||
"
|
|
||||||
v-show="message.visible"
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title style="color: white">
|
|
||||||
{{ createMessage(message) }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
<v-list-item-action v-if="message.error">
|
|
||||||
<v-btn icon @click="message.visible = false">
|
|
||||||
<v-icon color="white">
|
|
||||||
mdi-close
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item-action>
|
|
||||||
</v-list-item>
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
import AddAmountSkeleton from '../user/Skeleton/AddAmountSkeleton'
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
import { mdiPlus, mdiMenu } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'BarFreedrinks',
|
|
||||||
components: { AddAmountSkeleton },
|
|
||||||
created() {
|
|
||||||
this.timer = setInterval(() => (this.componentRenderer += 1), 1000)
|
|
||||||
this.get_free_drink_list_config()
|
|
||||||
this.get_free_drink_list_history()
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
plus: mdiPlus,
|
|
||||||
menuIcon: mdiMenu,
|
|
||||||
showConfirmCanceledDialog: false,
|
|
||||||
canceledMessage: null,
|
|
||||||
limit: 1000,
|
|
||||||
amount: 0,
|
|
||||||
customValue: null,
|
|
||||||
color: 'green accent-4',
|
|
||||||
color_fix: 'green accent-4',
|
|
||||||
timer: '',
|
|
||||||
componentRenderer: 0,
|
|
||||||
isMenuShow: false,
|
|
||||||
freeDrinkTypeJob: 1,
|
|
||||||
freeDrinkTypeBand: 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('freeDrinkList', [
|
|
||||||
'get_free_drink_list_config',
|
|
||||||
'get_free_drink_list_history',
|
|
||||||
'set_free_drink_list_history',
|
|
||||||
'update_free_drink_list_history'
|
|
||||||
]),
|
|
||||||
output() {
|
|
||||||
console.log(this.free_drink_list_config)
|
|
||||||
},
|
|
||||||
addAmount(freeDrink, free_drink_type_id) {
|
|
||||||
this.set_free_drink_list_history({ ...freeDrink, free_drink_type_id })
|
|
||||||
/*if (amount) {
|
|
||||||
this.amount += amount
|
|
||||||
this.generateMessage(amount)
|
|
||||||
}
|
|
||||||
this.checkLocked()*/
|
|
||||||
},
|
|
||||||
canceledAmount(historyElement) {
|
|
||||||
if (!this.isStronoEnabled(historyElement.timestamp)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.showConfirmCanceledDialog = true
|
|
||||||
this.canceledMessage = historyElement
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelCanceled() {
|
|
||||||
this.showConfirmCanceledDialog = null
|
|
||||||
this.canceledMessage = null
|
|
||||||
},
|
|
||||||
generateMessage(amount) {
|
|
||||||
this.messages.push({
|
|
||||||
date: new Date(),
|
|
||||||
canceled: false,
|
|
||||||
amount: amount,
|
|
||||||
error: false,
|
|
||||||
visible: true
|
|
||||||
})
|
|
||||||
},
|
|
||||||
createMessage(message) {
|
|
||||||
var text = ''
|
|
||||||
if (message.error) {
|
|
||||||
text =
|
|
||||||
'ERROR: ' + message.free_drink_type.name +': Konnte ' + message.label + ' für ' +
|
|
||||||
(message.price / 100).toFixed(2) +
|
|
||||||
'€ nicht hinzufügen.'
|
|
||||||
} else if (message.canceled) {
|
|
||||||
text = `${message.free_drink_type.name}: ${message.label} wurde für ${(message.price/100).toFixed(2)}€ storniert.`
|
|
||||||
} else {
|
|
||||||
text = message.free_drink_type.name + ': ' + message.label + ' wurde für ' + (message.price / 100).toFixed(2) + '€ hinzugefügt.'
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
},
|
|
||||||
checkLocked() {
|
|
||||||
this.locked = this.limit - this.amount <= 0
|
|
||||||
},
|
|
||||||
getColor() {
|
|
||||||
return this.locked ? 'title red--text' : 'title'
|
|
||||||
},
|
|
||||||
acceptCanceled() {
|
|
||||||
this.canceledMessage.canceled = true
|
|
||||||
this.update_free_drink_list_history(this.canceledMessage)
|
|
||||||
this.cancelCanceled()
|
|
||||||
},
|
|
||||||
acceptStorno() {
|
|
||||||
this.stornoMessage.storno = true
|
|
||||||
this.amount -= this.stornoMessage.amount
|
|
||||||
console.log(this.amount, this.stornoMessage)
|
|
||||||
this.cancelStorno()
|
|
||||||
},
|
|
||||||
stornoAmount(message) {
|
|
||||||
if (!this.isStronoEnabled(message.date) || message.storno) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showConfirmStornoDialog = true
|
|
||||||
this.stornoMessage = message
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelStorno() {
|
|
||||||
this.showConfirmStornoDialog = null
|
|
||||||
this.stornoMessage = null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', [
|
|
||||||
'free_drink_list_config_job',
|
|
||||||
'free_drink_list_config_band',
|
|
||||||
'free_drink_list_history',
|
|
||||||
'free_drink_list_history_job_credit',
|
|
||||||
'free_drink_list_history_band',
|
|
||||||
'free_drink_list_history_band_without_canceled',
|
|
||||||
'loading',
|
|
||||||
'snackbar_messages'
|
|
||||||
]),
|
|
||||||
now() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
var zero = new Date(0)
|
|
||||||
var date = new Date(actual - now)
|
|
||||||
if (date.getFullYear() === zero.getFullYear()) {
|
|
||||||
if (date.getMonth() === zero.getMonth()) {
|
|
||||||
if (date.getDate() === zero.getDate()) {
|
|
||||||
if (date.getHours() === zero.getDate()) {
|
|
||||||
if (date.getMinutes() < 1) {
|
|
||||||
return 'vor ' + date.getSeconds() + ' Sekunden'
|
|
||||||
} else if (date.getMinutes() < 10) {
|
|
||||||
return 'vor ' + date.getMinutes() + ' Minuten'
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
now.getDate() +
|
|
||||||
'.' +
|
|
||||||
now.getMonth() +
|
|
||||||
'.' +
|
|
||||||
now.getFullYear() +
|
|
||||||
' ' +
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isStronoEnabled() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
return actual - now < 60000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
locked() {
|
|
||||||
return this.free_drink_list_history_job_credit >= 1000
|
|
||||||
},
|
|
||||||
first_loading() {
|
|
||||||
return (
|
|
||||||
this.loading &&
|
|
||||||
this.free_drink_list_history.length == 0 &&
|
|
||||||
this.free_drink_list_config_band.length == 0 &&
|
|
||||||
this.free_drink_list_config_job.length == 0
|
|
||||||
)
|
|
||||||
},
|
|
||||||
free_drink_list_history_band_without_canceled_price() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_band_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
free_drink_list_history_bar() {
|
|
||||||
return this.free_drink_list_history.filter(item => {
|
|
||||||
return item.free_drink_type.id == 1 || item.free_drink_type.id == 3
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.drinkBtn {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.drinkCol {
|
|
||||||
padding: 6px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: calc(100% - 135px);
|
|
||||||
min-width: 150px;
|
|
||||||
font-size: 1.25rem !important;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 2rem;
|
|
||||||
letter-spacing: 0.0125em !important;
|
|
||||||
font-family: 'Roboto', sans-serif !important;
|
|
||||||
}
|
|
||||||
.menuBtn {
|
|
||||||
right: 15px;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.history-item {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item link :to="{name: 'geruecht'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ glass_mug_variant }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Geruecht
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{name: 'baruserFreedrinks'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ beer }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Freigetränke
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiGlassMugVariant,mdiBeer } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'BarNavigation',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
glass_mug_variant: mdiGlassMugVariant,
|
|
||||||
beer: mdiBeer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,595 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-dialog v-model="checkValidate" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Willst du wirklich??
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text v-if="stornoMessage">
|
|
||||||
Willst du wirklich den Betrag
|
|
||||||
{{ (stornoMessage.amount / 100).toFixed(2) }}€ von
|
|
||||||
{{ stornoMessage.user.firstname }}
|
|
||||||
{{ stornoMessage.user.lastname }} stornieren?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancelStorno">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="acceptStorno">Stornieren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog v-model="dialog" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="headline"
|
|
||||||
>Transaktion ist länger als 1 Minute her!</v-card-title
|
|
||||||
>
|
|
||||||
<v-card-text>
|
|
||||||
Da die Transaktion länger als 1 Minuter her ist, kann eine Stornierung
|
|
||||||
nicht durchgeführt werden. Wende dich bitte an den Finanzer.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="dialog = false">
|
|
||||||
Verstanden
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog
|
|
||||||
v-if="overLimitUser"
|
|
||||||
v-model="overLimitUser"
|
|
||||||
max-width="290"
|
|
||||||
persistent
|
|
||||||
>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Warnung</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
{{ overLimitUser.firstname }} {{ overLimitUser.lastname }} übersteigt
|
|
||||||
das Anschreibelimit von
|
|
||||||
{{ (overLimitUser.limit / 100).toFixed(2) }} €. Danach kann dieses
|
|
||||||
Mitglied nichts mehr anschreiben. Will er das wirklich?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancel()">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="continueAdd(overLimitUser)">Anschreiben</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog
|
|
||||||
v-if="overOverLimit"
|
|
||||||
v-model="overOverLimit"
|
|
||||||
max-width="290"
|
|
||||||
persistent
|
|
||||||
>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Anschreiben nicht möglich</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
{{ overOverLimit.firstname }}
|
|
||||||
{{ overOverLimit.lastname }} überschreitet das Anschreibelimit zuviel.
|
|
||||||
Das Anschreiben wurde daher gestoppt und zurückgesetzt.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn text @click="overOverLimit = null">Verstanden</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-progress-linear v-if="loading && users.length !== 0" indeterminate />
|
|
||||||
<v-container>
|
|
||||||
<AddAmountSkeleton v-if="loading && users.length === 0" />
|
|
||||||
</v-container>
|
|
||||||
<v-navigation-drawer v-model="menu" right app clipped>
|
|
||||||
<v-list-item-group :key="componentRenderer">
|
|
||||||
<v-list-item inactive>
|
|
||||||
<v-list-item-title class="headline">
|
|
||||||
Verlauf
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<div
|
|
||||||
v-for="message in messages"
|
|
||||||
three-line
|
|
||||||
:key="messages.indexOf(message)"
|
|
||||||
>
|
|
||||||
<v-list-item three-line inactive @click="storno(message)">
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-progress-linear indeterminate v-if="message.loading" />
|
|
||||||
<v-list-item-title>{{ now(message.date) }}</v-list-item-title>
|
|
||||||
<v-list-item-subtitle>{{
|
|
||||||
createMessage(message)
|
|
||||||
}}</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle class="red--text" v-if="message.storno">
|
|
||||||
STORNIERT!!!
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle class="red--text" v-else-if="message.error">
|
|
||||||
ERROR!
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-action-text v-if="under5minutes(message.date)"
|
|
||||||
>Klicken um zu Stornieren
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</div>
|
|
||||||
</v-list-item-group>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
<div v-for="user in users" :key="users.indexOf(user)">
|
|
||||||
<div v-if="isFiltered(user) && calcLastSeen(user)">
|
|
||||||
<v-container>
|
|
||||||
<v-card :loading="user.loading">
|
|
||||||
<v-card-title>
|
|
||||||
<v-list-item-title class="title"
|
|
||||||
>{{ user.firstname }} {{ user.lastname }}</v-list-item-title
|
|
||||||
>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-subtitle v-if="user.limit + user.amount > 0">
|
|
||||||
Nur noch {{ ((user.limit + user.amount) / 100).toFixed(2) }} €
|
|
||||||
übrig!!
|
|
||||||
</v-card-subtitle>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row v-if="!user.locked">
|
|
||||||
<v-col cols="10">
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 200)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>2 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 100)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>1 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 50)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,50 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 40)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,40 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 20)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,20 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" xs="5" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(user, 10)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,10 €
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="8">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
type="number"
|
|
||||||
v-model="user.value"
|
|
||||||
label="Benutzerdefinierter Betrag"
|
|
||||||
:disabled="user.locked"
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="4">
|
|
||||||
<v-btn
|
|
||||||
fab
|
|
||||||
:color="color"
|
|
||||||
@click="addAmountMore(user)"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plus }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center">
|
|
||||||
<v-row>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text :class="getColor(user.type)"
|
|
||||||
>{{ (user.amount / 100).toFixed(2) }}
|
|
||||||
€
|
|
||||||
</v-list-item-action-text>
|
|
||||||
<v-list-item-action-text v-if="user.toSetAmount">
|
|
||||||
- {{ (user.toSetAmount / 100).toFixed(2) }}
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col class="hidden-sm-and-down" cols="80">
|
|
||||||
<v-alert v-if="user.locked" type="error"
|
|
||||||
>{{ user.firstname }} darf nicht mehr anschreiben.
|
|
||||||
{{ user.firstname }} sollte sich lieber mal beim Finanzer
|
|
||||||
melden.
|
|
||||||
</v-alert>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center" v-if="user.locked">
|
|
||||||
<v-row>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text :class="getColor(user.type)"
|
|
||||||
>{{ (user.amount / 100).toFixed(2) }}
|
|
||||||
€
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-snackbar
|
|
||||||
:color="
|
|
||||||
messages.length > 0
|
|
||||||
? messages[0].error
|
|
||||||
? 'error'
|
|
||||||
: 'success'
|
|
||||||
: 'success'
|
|
||||||
"
|
|
||||||
bottom
|
|
||||||
:timeout="0"
|
|
||||||
:multi-line="true"
|
|
||||||
:value="messages.length > 0 ? messages[0].visible : test"
|
|
||||||
vertical
|
|
||||||
>
|
|
||||||
<v-list-item
|
|
||||||
v-for="message in messages"
|
|
||||||
:key="messages.indexOf(message)"
|
|
||||||
:style="
|
|
||||||
message.error
|
|
||||||
? 'background-color: #FF5252;'
|
|
||||||
: 'background-color: #4CAF50;'
|
|
||||||
"
|
|
||||||
v-show="message.visible"
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title style="color: white">
|
|
||||||
{{ createMessage(message) }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
<v-list-item-action v-if="message.error">
|
|
||||||
<v-btn icon @click="message.visible = false">
|
|
||||||
<v-icon color="white">
|
|
||||||
mdi-close
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item-action>
|
|
||||||
</v-list-item>
|
|
||||||
</v-snackbar>
|
|
||||||
</v-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiPlus } from '@mdi/js'
|
|
||||||
import AddAmountSkeleton from '../user/Skeleton/AddAmountSkeleton'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'CreditLists',
|
|
||||||
components: { AddAmountSkeleton },
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
plus: mdiPlus,
|
|
||||||
value: null,
|
|
||||||
color: 'green accent-4',
|
|
||||||
menu: true,
|
|
||||||
dialog: false,
|
|
||||||
componentRenderer: 0,
|
|
||||||
timer: '',
|
|
||||||
stornoMessage: null,
|
|
||||||
checkValidate: false,
|
|
||||||
test: null,
|
|
||||||
overLimitUser: null,
|
|
||||||
overOverLimit: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.menu = this.menu_from_store
|
|
||||||
this.getUsers()
|
|
||||||
this.timer = setInterval(this.forceRender, 1000)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
addAmount: 'barUsers/addAmount',
|
|
||||||
getUsers: 'barUsers/getUsers',
|
|
||||||
deactivate: 'barUsers/deactivateMenu',
|
|
||||||
commitStorno: 'barUsers/storno'
|
|
||||||
}),
|
|
||||||
continueAdd(user) {
|
|
||||||
this.overLimitUser = null
|
|
||||||
user.checkedOverLimit = true
|
|
||||||
if (user.value) {
|
|
||||||
this.addAmount({
|
|
||||||
username: user.username,
|
|
||||||
amount: Math.round(Math.abs(user.value * 100)),
|
|
||||||
user: user
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
user.value = null
|
|
||||||
user.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
} else {
|
|
||||||
user.timeout = setTimeout(() => {
|
|
||||||
this.addAmount({
|
|
||||||
username: user.username,
|
|
||||||
amount: user.toSetAmount,
|
|
||||||
user: user
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
user.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.overLimitUser.toSetAmount = null
|
|
||||||
this.overLimitUser.value = null
|
|
||||||
this.overLimitUser = null
|
|
||||||
},
|
|
||||||
checkOverLimitIsValid(user) {
|
|
||||||
console.log(user)
|
|
||||||
if (user.toSetAmount && user.autoLock) {
|
|
||||||
if (
|
|
||||||
(user.amount - Number.parseInt(user.toSetAmount)) <
|
|
||||||
-(user.limit + 500)
|
|
||||||
) {
|
|
||||||
this.overOverLimit = user
|
|
||||||
user.toSetAmount = null
|
|
||||||
user.value = null
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
checkOverLimit(user) {
|
|
||||||
console.log(user)
|
|
||||||
if (user.toSetAmount) {
|
|
||||||
if ((user.amount - user.toSetAmount) < -user.limit) {
|
|
||||||
return user.checkedOverLimit ? false : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
addingAmount(user, amount) {
|
|
||||||
clearTimeout(user.timeout)
|
|
||||||
user.toSetAmount = user.toSetAmount ? user.toSetAmount + amount : amount
|
|
||||||
if (this.checkOverLimitIsValid(user)) {
|
|
||||||
if (this.checkOverLimit(user) && user.autoLock) {
|
|
||||||
this.overLimitUser = user
|
|
||||||
} else {
|
|
||||||
user.timeout = setTimeout(() => {
|
|
||||||
this.addAmount({
|
|
||||||
username: user.username,
|
|
||||||
amount: user.toSetAmount,
|
|
||||||
user: user
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
user.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
forceRender() {
|
|
||||||
this.componentRenderer += 1
|
|
||||||
},
|
|
||||||
getColor(type) {
|
|
||||||
return type === 'credit' ? 'title green--text' : 'title red--text'
|
|
||||||
},
|
|
||||||
isFiltered(user) {
|
|
||||||
try {
|
|
||||||
var filters = this.filter.split(' ')
|
|
||||||
if (filters.length === 1) {
|
|
||||||
if (
|
|
||||||
user.firstname.toLowerCase().includes(filters[0].toLowerCase()) ||
|
|
||||||
user.lastname.toLowerCase().includes(filters[0].toLowerCase())
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else if (filters.length > 1) {
|
|
||||||
if (
|
|
||||||
user.firstname.toLowerCase().includes(filters[0].toLowerCase()) &&
|
|
||||||
user.lastname.toLowerCase().includes(filters[1].toLowerCase())
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
} catch (e) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addAmountMore(user) {
|
|
||||||
user.toSetAmount = user.toSetAmount
|
|
||||||
? user.toSetAmount + Math.round(Math.abs(user.value * 100))
|
|
||||||
: Math.round(Math.abs(user.value * 100))
|
|
||||||
if (this.checkOverLimitIsValid(user)) {
|
|
||||||
if (this.checkOverLimit(user) && user.autoLock) {
|
|
||||||
this.overLimitUser = user
|
|
||||||
} else {
|
|
||||||
this.addAmount({
|
|
||||||
username: user.username,
|
|
||||||
amount: Math.round(Math.abs(user.value * 100)),
|
|
||||||
user: user
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
user.value = null
|
|
||||||
user.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
storno(message) {
|
|
||||||
if (!message.error) {
|
|
||||||
if (!this.under5minutes(message.date)) this.dialog = true
|
|
||||||
else {
|
|
||||||
this.checkValidate = true
|
|
||||||
this.stornoMessage = message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
acceptStorno() {
|
|
||||||
this.commitStorno({
|
|
||||||
username: this.stornoMessage.user.username,
|
|
||||||
amount: this.stornoMessage.amount,
|
|
||||||
date: this.stornoMessage.date
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.cancelStorno()
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
cancelStorno() {
|
|
||||||
this.stornoMessage = null
|
|
||||||
this.checkValidate = null
|
|
||||||
},
|
|
||||||
createMessage(message) {
|
|
||||||
var text = ''
|
|
||||||
if (message.error) {
|
|
||||||
text =
|
|
||||||
'ERROR: Konnte ' +
|
|
||||||
(message.amount / 100).toFixed(2) +
|
|
||||||
'€ nicht zu ' +
|
|
||||||
message.user.firstname +
|
|
||||||
' ' +
|
|
||||||
message.user.lastname +
|
|
||||||
' hinzufügen.'
|
|
||||||
} else {
|
|
||||||
text =
|
|
||||||
'' +
|
|
||||||
(message.amount / 100).toFixed(2) +
|
|
||||||
'€ wurde zu ' +
|
|
||||||
message.user.firstname +
|
|
||||||
' ' +
|
|
||||||
message.user.lastname +
|
|
||||||
' hinzugefügt.'
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
},
|
|
||||||
calcLastSeen(user) {
|
|
||||||
if (user.last_seen) {
|
|
||||||
let date = new Date()
|
|
||||||
if ((date - user.last_seen) / 1000 / 60 / 60 < 72) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
users: 'barUsers/users',
|
|
||||||
filter: 'barUsers/filter',
|
|
||||||
loading: 'barUsers/usersLoading',
|
|
||||||
messages: 'barUsers/messages',
|
|
||||||
menu_from_store: 'barUsers/menu'
|
|
||||||
}),
|
|
||||||
under5minutes() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
return actual - now < 60000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
now() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
var zero = new Date(0)
|
|
||||||
var date = new Date(actual - now)
|
|
||||||
if (date.getFullYear() === zero.getFullYear()) {
|
|
||||||
if (date.getMonth() === zero.getMonth()) {
|
|
||||||
if (date.getDate() === zero.getDate()) {
|
|
||||||
if (date.getHours() === zero.getDate()) {
|
|
||||||
if (date.getMinutes() < 1) {
|
|
||||||
return 'vor ' + date.getSeconds() + ' Sekunden'
|
|
||||||
} else if (date.getMinutes() < 10) {
|
|
||||||
return 'vor ' + date.getMinutes() + ' Minuten'
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
now.getDate() +
|
|
||||||
'.' +
|
|
||||||
now.getMonth() +
|
|
||||||
'.' +
|
|
||||||
now.getFullYear() +
|
|
||||||
' ' +
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
menu(newValue) {
|
|
||||||
if (!newValue) this.deactivate()
|
|
||||||
},
|
|
||||||
menu_from_store() {
|
|
||||||
this.menu = this.menu_from_store
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.creditBtn {
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,133 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-toolbar>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-autocomplete
|
|
||||||
outlined
|
|
||||||
return-object
|
|
||||||
v-model="user"
|
|
||||||
style="margin-top: 3px"
|
|
||||||
placeholder="Suche Person"
|
|
||||||
:items="allUsers"
|
|
||||||
item-text="fullName"
|
|
||||||
full-width
|
|
||||||
:loading="loading"
|
|
||||||
:search-input.sync="filter"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<template v-slot:prepend-inner>
|
|
||||||
<v-icon>{{ search_person }}</v-icon>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item="data">
|
|
||||||
<v-list-item-icon v-if="getLocked(data.item)">
|
|
||||||
<v-icon>mdi-alert</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-content>
|
|
||||||
{{data.item.fullName}}
|
|
||||||
<v-spacer/>
|
|
||||||
{{(getCredit(data.item)/100).toFixed(2)}} €
|
|
||||||
</v-list-item-content>
|
|
||||||
</template>
|
|
||||||
</v-autocomplete>
|
|
||||||
<v-btn text @click="addUser">Hinzufügen</v-btn>
|
|
||||||
<v-btn v-if="!locked" text @click="lock">Sperren</v-btn>
|
|
||||||
<v-btn v-else text @click="overlay = true">Entsperren</v-btn>
|
|
||||||
<v-btn @click="clickMenu" icon>
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-dialog v-model="overlay">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Entsperre Baransicht</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-text-field outlined type="password" label="Passwort" v-model="password"></v-text-field>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-btn text @click="overlay = false">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="doUnlock">Entsperren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiAccountSearch, mdiMenu, mdiAlert } from '@mdi/js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SearchBar',
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
user: null,
|
|
||||||
filter: '',
|
|
||||||
search_person: mdiAccountSearch,
|
|
||||||
menuIcon: mdiMenu,
|
|
||||||
alert: mdiAlert,
|
|
||||||
overlay: false,
|
|
||||||
password: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getAllUsers()
|
|
||||||
this.getLocked()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getAllUsers: 'barUsers/getAllUsers',
|
|
||||||
addCreditList: 'barUsers/addCreditList',
|
|
||||||
setFilter: 'barUsers/setFilter',
|
|
||||||
activateMenu: 'barUsers/activateMenu',
|
|
||||||
deactivateMenu: 'barUsers/deactivateMenu',
|
|
||||||
lock: 'barUsers/setLocked',
|
|
||||||
unlock: 'barUsers/unlock',
|
|
||||||
getLocked: 'barUsers/getLocked'
|
|
||||||
}),
|
|
||||||
addUser() {
|
|
||||||
this.addCreditList(this.user)
|
|
||||||
},
|
|
||||||
clickMenu() {
|
|
||||||
if (this.menu) this.deactivateMenu()
|
|
||||||
else this.activateMenu()
|
|
||||||
},
|
|
||||||
doUnlock() {
|
|
||||||
this.unlock(this.password)
|
|
||||||
this.password = ''
|
|
||||||
this.overlay = false
|
|
||||||
},
|
|
||||||
getCredit(user) {
|
|
||||||
let retUser = this.users.find(item => {
|
|
||||||
return item.username === user.username
|
|
||||||
})
|
|
||||||
return retUser ? retUser.amount : 0
|
|
||||||
},
|
|
||||||
getLocked(user) {
|
|
||||||
if(!user) return
|
|
||||||
let retUser = this.users.find(item => {
|
|
||||||
return item.username === user.username
|
|
||||||
})
|
|
||||||
return retUser ? retUser.locked : false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
allUsers: 'barUsers/allUsers',
|
|
||||||
users: 'barUsers/users',
|
|
||||||
loading: 'barUsers/allUsersLoading',
|
|
||||||
menu: 'barUsers/menu',
|
|
||||||
locked: 'barUsers/locked'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
filter(val) {
|
|
||||||
this.setFilter(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,49 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item class="title" link :to="{name: 'overview'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{home}}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Gesamtübersicht</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
<v-divider />
|
|
||||||
<v-list>
|
|
||||||
<div v-for="user in users" v-bind:key="users.indexOf(user)">
|
|
||||||
<v-list-item
|
|
||||||
:to="{ name: 'activeUser', params: { id: user.username } }"
|
|
||||||
link
|
|
||||||
>
|
|
||||||
<v-list-item-title
|
|
||||||
>{{ user.lastname }}, {{ user.firstname }}</v-list-item-title
|
|
||||||
>
|
|
||||||
</v-list-item>
|
|
||||||
</div>
|
|
||||||
<v-list-item>
|
|
||||||
<v-progress-circular indeterminate color="grey" v-if="loading" />
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
import {mdiHome} from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'FinanzerNavigation',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
home: mdiHome
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
users: 'finanzerUsers/users',
|
|
||||||
loading: 'finanzerUsers/usersLoading'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,400 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-content>
|
|
||||||
<v-toolbar tile>
|
|
||||||
<v-toolbar-title>Gesamtübersicht</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn text icon @click="countYear(false)">
|
|
||||||
<v-icon>{{keyboard_arrow_left}}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-title class="title">{{ year }}</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-btn text icon @click="countYear(true)" :disabled="isActualYear">
|
|
||||||
<v-icon>{{keyboard_arrow_right}}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn text @click="sendMails">Emails senden</v-btn>
|
|
||||||
<v-autocomplete
|
|
||||||
outlined
|
|
||||||
return-object
|
|
||||||
v-model="user"
|
|
||||||
style="margin-top: 3px"
|
|
||||||
placeholder="Suche Person"
|
|
||||||
:items="allUsers"
|
|
||||||
item-text="fullName"
|
|
||||||
full-width
|
|
||||||
:loading="allUsersLoading"
|
|
||||||
:search-input.sync="filter"
|
|
||||||
@change="addToUser(user)"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend-inner>
|
|
||||||
<v-icon>{{search_person}}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-expand-transition>
|
|
||||||
<v-card style="margin-top: 3px" v-show="errorMails">
|
|
||||||
<v-row>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
icon
|
|
||||||
style="margin-right: 5px"
|
|
||||||
@click="errorExpand ? (errorExpand = false) : (errorExpand = true)"
|
|
||||||
>
|
|
||||||
<v-icon :class="isExpand(errorExpand)" dense>$expand</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
<v-expand-transition>
|
|
||||||
<div v-show="errorExpand">
|
|
||||||
<v-alert
|
|
||||||
v-for="error in errorMails"
|
|
||||||
:key="errorMails.indexOf(error)"
|
|
||||||
dense
|
|
||||||
:type="computeError(error.error)"
|
|
||||||
>{{ errorMessage(error) }}</v-alert
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</v-expand-transition>
|
|
||||||
</v-card>
|
|
||||||
</v-expand-transition>
|
|
||||||
<v-progress-linear v-if="loading && users.length !== 0" indeterminate />
|
|
||||||
<TableSkeleton v-if="loading && users.length === 0" />
|
|
||||||
<div v-for="user in users" :key="users.indexOf(user)">
|
|
||||||
<v-card
|
|
||||||
v-if="user.creditList[year] && isFiltered(user)"
|
|
||||||
style="margin-top: 3px"
|
|
||||||
:loading="user.loading"
|
|
||||||
>
|
|
||||||
<v-card-title>
|
|
||||||
{{ user.lastname }}, {{ user.firstname }}
|
|
||||||
</v-card-title>
|
|
||||||
<Table v-bind:user="user" v-bind:year="year" />
|
|
||||||
<v-container fluid>
|
|
||||||
<v-row align="start" align-content="start">
|
|
||||||
<v-col>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Vorjahr:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
:text-color="getLastColor(user.creditList[year][1].last)"
|
|
||||||
>{{
|
|
||||||
(user.creditList[year][1].last / 100).toFixed(2)
|
|
||||||
}}</v-chip
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Gesamt:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
x-large
|
|
||||||
:text-color="
|
|
||||||
getLastColor(
|
|
||||||
getAllSum(
|
|
||||||
user.creditList[year][2].sum,
|
|
||||||
user.creditList[year][1].last
|
|
||||||
)
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
(
|
|
||||||
getAllSum(
|
|
||||||
user.creditList[year][2].sum,
|
|
||||||
user.creditList[year][1].last
|
|
||||||
) / 100
|
|
||||||
).toFixed(2)
|
|
||||||
}}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Status:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip outlined :text-color="getLockedColor(user.locked)">{{
|
|
||||||
user.locked ? 'Gesperrt' : 'nicht Gesperrt'
|
|
||||||
}}</v-chip>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-card outlined>
|
|
||||||
<v-row>
|
|
||||||
<v-card-title class="subtitle-2"
|
|
||||||
>Geld transferieren</v-card-title
|
|
||||||
>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
icon
|
|
||||||
style="margin-right: 5px"
|
|
||||||
@click="setExpand(user)"
|
|
||||||
>
|
|
||||||
<v-icon :class="isExpand(user.expand)" dense
|
|
||||||
>$expand</v-icon
|
|
||||||
>
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
<v-expand-transition>
|
|
||||||
<v-card-text v-show="user.expand">
|
|
||||||
<v-form style="margin-left: 15px; margin-right: 15px">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-text-field
|
|
||||||
:rules="[isNumber]"
|
|
||||||
label="Betrag"
|
|
||||||
v-model="amount"
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="type"
|
|
||||||
label="Typ"
|
|
||||||
:items="[
|
|
||||||
{ value: 'amount', text: 'Schulden' },
|
|
||||||
{ value: 'credit', text: 'Guthaben' }
|
|
||||||
]"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="selectedYear"
|
|
||||||
label="Jahr"
|
|
||||||
:items="years"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="selectedMonth"
|
|
||||||
label="Monat"
|
|
||||||
:items="months"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
<v-btn block @click="add(user)">Hinzufügen</v-btn>
|
|
||||||
</v-card-text>
|
|
||||||
</v-expand-transition>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Table from './Table'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import TableSkeleton from './Skeleton/TableSkeleton'
|
|
||||||
import {mdiChevronLeft, mdiChevronRight, mdiAccountSearch} from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'Overview',
|
|
||||||
components: { TableSkeleton, Table },
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
keyboard_arrow_left: mdiChevronLeft,
|
|
||||||
keyboard_arrow_right: mdiChevronRight,
|
|
||||||
search_person: mdiAccountSearch,
|
|
||||||
errorExpand: false,
|
|
||||||
|
|
||||||
filter: '',
|
|
||||||
user: null,
|
|
||||||
|
|
||||||
amount: null,
|
|
||||||
isNumber: value => !isNaN(value) || 'Betrag muss eine Zahl sein.',
|
|
||||||
type: { value: 'credit', text: 'Guthaben' },
|
|
||||||
selectedYear: {
|
|
||||||
value: new Date().getFullYear(),
|
|
||||||
text: new Date().getFullYear()
|
|
||||||
},
|
|
||||||
selectedMonth: {
|
|
||||||
value: new Date().getMonth() + 1,
|
|
||||||
text: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
][new Date().getMonth()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
createYears: 'finanzerUsers/createYears',
|
|
||||||
addAmount: 'finanzerUsers/addAmount',
|
|
||||||
addCredit: 'finanzerUsers/addCredit',
|
|
||||||
countYear: 'finanzerUsers/countYear',
|
|
||||||
sendMails: 'finanzerUsers/sendMails',
|
|
||||||
addUser: 'finanzerUsers/addUser'
|
|
||||||
}),
|
|
||||||
async getData(promise) {
|
|
||||||
return await promise
|
|
||||||
},
|
|
||||||
getLastColor(value) {
|
|
||||||
return value < 0 ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
getAllSum(sum, lastYear) {
|
|
||||||
return lastYear + sum
|
|
||||||
},
|
|
||||||
getLockedColor(value) {
|
|
||||||
return value ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
computeError(error) {
|
|
||||||
if (error) return 'error'
|
|
||||||
else return 'success'
|
|
||||||
},
|
|
||||||
errorMessage(error) {
|
|
||||||
if (error.error)
|
|
||||||
return (
|
|
||||||
'Konnte Email an ' +
|
|
||||||
error.user.firstname +
|
|
||||||
' ' +
|
|
||||||
error.user.lastname +
|
|
||||||
' nicht senden!'
|
|
||||||
)
|
|
||||||
else
|
|
||||||
return (
|
|
||||||
'Email wurde an ' +
|
|
||||||
error.user.firstname +
|
|
||||||
' ' +
|
|
||||||
error.user.lastname +
|
|
||||||
' versandt.'
|
|
||||||
)
|
|
||||||
},
|
|
||||||
setExpand(user) {
|
|
||||||
user.expand ? (user.expand = false) : (user.expand = true)
|
|
||||||
},
|
|
||||||
isExpand(value) {
|
|
||||||
return value ? 'rotate' : ''
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
add(user) {
|
|
||||||
if (this.type.value === 'amount') {
|
|
||||||
this.addAmount({
|
|
||||||
user: user,
|
|
||||||
amount: this.amount,
|
|
||||||
year: this.selectedYear.value,
|
|
||||||
month: this.selectedMonth.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (this.type.value === 'credit') {
|
|
||||||
this.addCredit({
|
|
||||||
user: user,
|
|
||||||
credit: this.amount,
|
|
||||||
year: this.selectedYear.value,
|
|
||||||
month: this.selectedMonth.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.createDefault(
|
|
||||||
this.amount,
|
|
||||||
this.type,
|
|
||||||
this.selectedYear,
|
|
||||||
this.selectedMonth
|
|
||||||
)
|
|
||||||
},
|
|
||||||
isFiltered(user) {
|
|
||||||
try {
|
|
||||||
var filters = this.filter.split(' ')
|
|
||||||
for (var filter in filters) {
|
|
||||||
if (
|
|
||||||
user.firstname.toLowerCase().includes(filters[filter].toLowerCase()) ||
|
|
||||||
user.lastname.toLowerCase().includes(filters[filter].toLowerCase())
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
} catch (e) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addToUser(user) {
|
|
||||||
this.addUser(user)
|
|
||||||
this.$router.push({name: 'activeUser', params: {id: user.username}})
|
|
||||||
},
|
|
||||||
createDefault() {
|
|
||||||
this.amount = null
|
|
||||||
this.type = { value: 'credit', text: 'Guthaben' }
|
|
||||||
this.selectedYear = {
|
|
||||||
value: new Date().getFullYear(),
|
|
||||||
text: new Date().getFullYear()
|
|
||||||
}
|
|
||||||
this.selectedMonth = {
|
|
||||||
value: new Date().getMonth() + 1,
|
|
||||||
text: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
][new Date().getMonth()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isActualYear() {
|
|
||||||
return this.year === new Date().getFullYear()
|
|
||||||
},
|
|
||||||
...mapGetters({
|
|
||||||
users: 'finanzerUsers/users',
|
|
||||||
allUsers: 'finanzerUsers/allUsers',
|
|
||||||
errorMails: 'finanzerUsers/errorMails',
|
|
||||||
year: 'finanzerUsers/year',
|
|
||||||
years: 'finanzerUsers/years',
|
|
||||||
months: 'finanzerUsers/months',
|
|
||||||
loading: 'finanzerUsers/usersLoading',
|
|
||||||
allUsersLoading: 'finanzerUsers/allUsersLoading'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.rotate {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-card style="margin-top: 3px">
|
|
||||||
<v-card-title>
|
|
||||||
<v-skeleton-loader type="heading" />
|
|
||||||
</v-card-title>
|
|
||||||
<v-container>
|
|
||||||
<v-skeleton-loader type="table-thead"/>
|
|
||||||
<v-skeleton-loader type="table-row-divider@3"/>
|
|
||||||
</v-container>
|
|
||||||
<v-container fluid>
|
|
||||||
<v-row align="start" align-content="start">
|
|
||||||
<v-col>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip"/>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-card outlined>
|
|
||||||
<v-row>
|
|
||||||
<v-card-title>
|
|
||||||
<v-skeleton-loader style="margin: 3px; margin-left: 10px" type="chip"/>
|
|
||||||
</v-card-title>
|
|
||||||
</v-row>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'TableSkeleton'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,82 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-toolbar tile>
|
|
||||||
<v-toolbar-title>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-card style="margin-top: 3px;">
|
|
||||||
<v-card-title><v-skeleton-loader type="heading"/></v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-form style="margin-left: 15px; margin-right: 15px">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-divider style="margin-bottom: 15px;" />
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card style="margin-top: 3px;">
|
|
||||||
<v-card-title><v-skeleton-loader type="chip"/></v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-form style="margin-left: 15px; margin-right: 15px">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'UserSkeleton'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,125 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-data-table dense :headers="headers" :items="user.creditList[year]" :hide-default-footer="true">
|
|
||||||
<template v-slot:item.jan_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.jan_amount)">
|
|
||||||
{{(item.jan_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.feb_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.feb_amount)">
|
|
||||||
{{(item.feb_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.maer_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.maer_amount)">
|
|
||||||
{{(item.maer_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.apr_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.apr_amount)">
|
|
||||||
{{(item.apr_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.mai_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.mai_amount)">
|
|
||||||
{{(item.mai_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.jun_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.jun_amount)">
|
|
||||||
{{(item.jun_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.jul_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.jul_amount)">
|
|
||||||
{{(item.jul_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.aug_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.aug_amount)">
|
|
||||||
{{(item.aug_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.sep_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.sep_amount)">
|
|
||||||
{{(item.sep_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.okt_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.okt_amount)">
|
|
||||||
{{(item.okt_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.nov_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.nov_amount)">
|
|
||||||
{{(item.nov_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.dez_amount="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.dez_amount)">
|
|
||||||
{{(item.dez_amount /
|
|
||||||
100).toFixed(2)}}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.sum="{ item }">
|
|
||||||
<v-chip outlined :text-color="getColor(item, item.sum)">{{(item.sum / 100).toFixed(2)}}</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'Table',
|
|
||||||
props: {
|
|
||||||
user: Object,
|
|
||||||
year: Number
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
text: 'Schulden / Guthaben',
|
|
||||||
align: 'left',
|
|
||||||
sortable: false,
|
|
||||||
value: 'type'
|
|
||||||
},
|
|
||||||
{ text: 'Januar in EUR', value: 'jan_amount' },
|
|
||||||
{ text: 'Februar in EUR', value: 'feb_amount' },
|
|
||||||
{ text: 'März in EUR', value: 'maer_amount' },
|
|
||||||
{ text: 'April in EUR', value: 'apr_amount' },
|
|
||||||
{ text: 'Mai in EUR', value: 'mai_amount' },
|
|
||||||
{ text: 'Juni in EUR', value: 'jun_amount' },
|
|
||||||
{ text: 'Juli in EUR', value: 'jul_amount' },
|
|
||||||
{ text: 'August in EUR', value: 'aug_amount' },
|
|
||||||
{ text: 'September in EUR', value: 'sep_amount' },
|
|
||||||
{ text: 'Oktober in EUR', value: 'okt_amount' },
|
|
||||||
{ text: 'November in EUR', value: 'nov_amount' },
|
|
||||||
{ text: 'Dezember in EUR', value: 'dez_amount' },
|
|
||||||
{ text: 'Summe in EUR', value: 'sum' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getColor(item, value) {
|
|
||||||
if (item.type === 'Summe') {
|
|
||||||
return value < 0 ? 'red' : 'green'
|
|
||||||
}
|
|
||||||
return item.type === 'Guthaben' ? 'green' : 'red'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
|
@ -1,363 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-content v-if="loading" >
|
|
||||||
<UserSkeleton />
|
|
||||||
</v-content>
|
|
||||||
<v-content v-if="activeUser">
|
|
||||||
<v-toolbar tile>
|
|
||||||
<v-toolbar-title
|
|
||||||
>{{ activeUser.lastname }},
|
|
||||||
{{ activeUser.firstname }}</v-toolbar-title
|
|
||||||
>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn @click="sendMail({ username: activeUser.username })" text
|
|
||||||
>Email senden</v-btn
|
|
||||||
>
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-progress-linear v-if="activeUser.loading" indeterminate />
|
|
||||||
<v-expand-transition>
|
|
||||||
<v-card style="margin-top: 3px" v-show="errorMail">
|
|
||||||
<v-alert dense :type="computeError(errorMail)">
|
|
||||||
{{ errorMessage(errorMail) }}
|
|
||||||
</v-alert>
|
|
||||||
</v-card>
|
|
||||||
</v-expand-transition>
|
|
||||||
<v-card style="margin-top: 3px;">
|
|
||||||
<v-card-title>Konfiguration</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-form style="margin-left: 15px; margin-right: 15px">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Status:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip outlined :text-color="getLockedColor(activeUser.locked)"
|
|
||||||
>{{ activeUser.locked ? 'Gesperrt' : 'nicht Gesperrt' }}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-btn
|
|
||||||
@click="
|
|
||||||
doLock({ user: activeUser, locked: !activeUser.locked })
|
|
||||||
"
|
|
||||||
>{{ activeUser.locked ? 'Entperren' : 'Sperren' }}
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-divider style="margin-bottom: 15px;" />
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-text-field
|
|
||||||
:rules="[isNumber]"
|
|
||||||
label="Betrag des Sperrlimits in € (EURO)"
|
|
||||||
v-model="limit"
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="autoLock"
|
|
||||||
label="Automatische Sperre"
|
|
||||||
:items="[
|
|
||||||
{ value: true, text: 'Aktiviert' },
|
|
||||||
{ value: false, text: 'Deaktiviert' }
|
|
||||||
]"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-btn
|
|
||||||
block
|
|
||||||
@click="
|
|
||||||
saveConfig({
|
|
||||||
user: activeUser,
|
|
||||||
limit: limit,
|
|
||||||
autoLock: autoLock.value
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>Speichern
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card style="margin-top: 3px;">
|
|
||||||
<v-card-title>Geld transferieren</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-form style="margin-left: 15px; margin-right: 15px">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-text-field
|
|
||||||
:rules="[isNumber]"
|
|
||||||
label="Betrag"
|
|
||||||
v-model="amount"
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="type"
|
|
||||||
label="Typ"
|
|
||||||
:items="[
|
|
||||||
{ value: 'amount', text: 'Schulden' },
|
|
||||||
{ value: 'credit', text: 'Guthaben' }
|
|
||||||
]"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="selectedYear"
|
|
||||||
label="Jahr"
|
|
||||||
:items="selectYears"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-select
|
|
||||||
return-object
|
|
||||||
v-model="selectedMonth"
|
|
||||||
label="Monat"
|
|
||||||
:items="months"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
></v-select>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
<v-btn block @click="add">Hinzufügen</v-btn>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<div v-for="year in years" :key="years.indexOf(year)">
|
|
||||||
<v-card style="margin-top: 3px;">
|
|
||||||
<v-card-title>{{ year }}</v-card-title>
|
|
||||||
<Table v-bind:user="activeUser" v-bind:year="year" />
|
|
||||||
<v-container fluid>
|
|
||||||
<v-col>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Vorjahr:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
:text-color="
|
|
||||||
getLastColor(activeUser.creditList[year][1].last)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ (activeUser.creditList[year][1].last / 100).toFixed(2) }}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Gesamt:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
x-large
|
|
||||||
:text-color="
|
|
||||||
getLastColor(
|
|
||||||
getAllSum(
|
|
||||||
activeUser.creditList[year][2].sum,
|
|
||||||
activeUser.creditList[year][1].last
|
|
||||||
)
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
(
|
|
||||||
getAllSum(
|
|
||||||
activeUser.creditList[year][2].sum,
|
|
||||||
activeUser.creditList[year][1].last
|
|
||||||
) / 100
|
|
||||||
).toFixed(2)
|
|
||||||
}}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-content>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Table from './Table'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import UserSkeleton from "./Skeleton/UserSkeleton";
|
|
||||||
export default {
|
|
||||||
name: 'User',
|
|
||||||
props: {
|
|
||||||
id: String
|
|
||||||
},
|
|
||||||
components: {UserSkeleton, Table },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isNumber: value => !isNaN(value) || 'Betrag muss eine Zahl sein.',
|
|
||||||
limit: null,
|
|
||||||
autoLock: null,
|
|
||||||
amount: null,
|
|
||||||
type: { value: 'credit', text: 'Guthaben' },
|
|
||||||
selectedYear: {
|
|
||||||
value: new Date().getFullYear(),
|
|
||||||
text: new Date().getFullYear()
|
|
||||||
},
|
|
||||||
selectedMonth: {
|
|
||||||
value: new Date().getMonth() + 1,
|
|
||||||
text: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
][new Date().getMonth()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.setActiveUser(this.$route.params.id)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
addAmount: 'finanzerUsers/addAmount',
|
|
||||||
addCredit: 'finanzerUsers/addCredit',
|
|
||||||
sendMail: 'finanzerUsers/sendMail',
|
|
||||||
doLock: 'finanzerUsers/doLock',
|
|
||||||
saveConfig: 'finanzerUsers/saveConfig',
|
|
||||||
setActiveUser: 'finanzerUsers/setActiveUser'
|
|
||||||
}),
|
|
||||||
getLastColor(value) {
|
|
||||||
return value < 0 ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
getAllSum(sum, lastYear) {
|
|
||||||
return lastYear + sum
|
|
||||||
},
|
|
||||||
getLockedColor(value) {
|
|
||||||
return value ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
add() {
|
|
||||||
if (this.type.value === 'amount') {
|
|
||||||
this.addAmount({
|
|
||||||
user: this.activeUser,
|
|
||||||
amount: this.amount,
|
|
||||||
year: this.selectedYear.value,
|
|
||||||
month: this.selectedMonth.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (this.type.value === 'credit') {
|
|
||||||
this.addCredit({
|
|
||||||
user: this.activeUser,
|
|
||||||
credit: this.amount,
|
|
||||||
year: this.selectedYear.value,
|
|
||||||
month: this.selectedMonth.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.createDefault()
|
|
||||||
},
|
|
||||||
createDefault() {
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let year = new Date().getFullYear()
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let month = new Date().getMonth()
|
|
||||||
this.amount = null
|
|
||||||
this.type = { value: 'credit', text: 'Guthaben' }
|
|
||||||
this.selectedYear = {
|
|
||||||
value: new Date().getFullYear(),
|
|
||||||
text: new Date().getFullYear()
|
|
||||||
}
|
|
||||||
this.selectedMonth = {
|
|
||||||
value: new Date().getMonth() + 1,
|
|
||||||
text: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
][new Date().getMonth()]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computeError(error) {
|
|
||||||
if (error) {
|
|
||||||
if (error.error) return 'error'
|
|
||||||
else return 'success'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
errorMessage(error) {
|
|
||||||
if (error) {
|
|
||||||
if (error.error)
|
|
||||||
return (
|
|
||||||
'Konnte Email an ' +
|
|
||||||
error.user.firstname +
|
|
||||||
' ' +
|
|
||||||
error.user.lastname +
|
|
||||||
' nicht senden!'
|
|
||||||
)
|
|
||||||
else
|
|
||||||
return (
|
|
||||||
'Email wurde an ' +
|
|
||||||
error.user.firstname +
|
|
||||||
' ' +
|
|
||||||
error.user.lastname +
|
|
||||||
' versandt.'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
years() {
|
|
||||||
let years = []
|
|
||||||
for (let year in this.activeUser.creditList) {
|
|
||||||
years.unshift(parseInt(year))
|
|
||||||
}
|
|
||||||
return years
|
|
||||||
},
|
|
||||||
...mapGetters({
|
|
||||||
activeUser: 'finanzerUsers/activeUser',
|
|
||||||
errorMail: 'finanzerUsers/errorMail',
|
|
||||||
months: 'finanzerUsers/months',
|
|
||||||
selectYears: 'finanzerUsers/selectYears',
|
|
||||||
loading: 'finanzerUsers/addUserLoading'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
activeUser(newVal) {
|
|
||||||
this.limit = (newVal.limit / 100).toFixed(2)
|
|
||||||
this.autoLock = {
|
|
||||||
value: newVal.autoLock,
|
|
||||||
text: newVal.autoLock ? 'Aktiviert' : 'Deaktiviert'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
id(newVal) {
|
|
||||||
this.setActiveUser(newVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item class="title" link :to="{name: 'gastroPricelist'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{list}}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Preisliste
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiFileMultiple } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: "GastroNavigation",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
list: mdiFileMultiple
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
export interface Todo {
|
||||||
|
id: number;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Meta {
|
||||||
|
totalCount: number;
|
||||||
|
}
|
|
@ -1,497 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-data-table
|
|
||||||
:headers="headers"
|
|
||||||
:items="priceList"
|
|
||||||
:search="search"
|
|
||||||
:loading="priceListLoading || typesLoading"
|
|
||||||
>
|
|
||||||
<template v-slot:top>
|
|
||||||
<v-toolbar flat color="white">
|
|
||||||
<v-toolbar-title>Preisliste</v-toolbar-title>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
label="Suche Getränk"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
>
|
|
||||||
<template v-slot:append>
|
|
||||||
<v-icon>{{ searchIcon }}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
<v-dialog v-model="dialog" v-if="isGastro && isGastroPage">
|
|
||||||
<template v-slot:activator="{ on }">
|
|
||||||
<v-btn
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="primary"
|
|
||||||
class="mb-2"
|
|
||||||
v-on="on"
|
|
||||||
style="margin: 5px"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plus }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</template>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
<span class="headline">{{ formTitle }}</span>
|
|
||||||
</v-card-title>
|
|
||||||
|
|
||||||
<v-card-text>
|
|
||||||
<v-container>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.name"
|
|
||||||
label="Name"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-autocomplete
|
|
||||||
return-object
|
|
||||||
v-model="editedItem.type"
|
|
||||||
label="Kategorie"
|
|
||||||
item-text="name"
|
|
||||||
item-value="id"
|
|
||||||
:items="types"
|
|
||||||
outlined
|
|
||||||
:search-input.sync="searchType"
|
|
||||||
no-data-text="Kategorie nicht vorhanden."
|
|
||||||
>
|
|
||||||
<template v-slot:append-item>
|
|
||||||
<v-list-item v-if="!inType(searchType)">
|
|
||||||
<v-list-item-title>
|
|
||||||
{{ searchType }}
|
|
||||||
</v-list-item-title>
|
|
||||||
<v-btn
|
|
||||||
dark
|
|
||||||
x-small
|
|
||||||
color="blue darken-1"
|
|
||||||
@click="addType()"
|
|
||||||
:disabled="inType(searchType)"
|
|
||||||
fab
|
|
||||||
>
|
|
||||||
<v-icon>
|
|
||||||
{{ plus }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item>
|
|
||||||
</template>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.price"
|
|
||||||
label="Preis in €"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.price_big"
|
|
||||||
label="Preis groß in €"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.price_club"
|
|
||||||
label="Preis Club in €"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.price_club_big"
|
|
||||||
label="Preis Club groß in €"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col col="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.premium"
|
|
||||||
label="Aufpreis in €"
|
|
||||||
outlined
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.premium_club"
|
|
||||||
label="Aufpreis Club in €"
|
|
||||||
outlined
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="4">
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.price_extern_club"
|
|
||||||
label="Preis extern Club in €"
|
|
||||||
outlined
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-card-text>
|
|
||||||
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn color="blue darken-1" text @click="close"
|
|
||||||
>Abbrechen</v-btn
|
|
||||||
>
|
|
||||||
<v-btn color="blue darken-1" text @click="save"
|
|
||||||
>Speichern</v-btn
|
|
||||||
>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</v-toolbar>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.type="{ item }">
|
|
||||||
{{ computeType(item.type) }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.price="{ item }">
|
|
||||||
{{ item.price ? (item.price / 100).toFixed(2) : '' }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.price_big="{ item }">
|
|
||||||
{{ item.price_big ? (item.price_big / 100).toFixed(2) : '' }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.price_club="{ item }">
|
|
||||||
{{
|
|
||||||
item.name.toLowerCase() == 'long island ice tea'.toLowerCase()
|
|
||||||
? 'Ein Klubmitglied bestellt keinen Long Island Icetea'
|
|
||||||
: item.price_club
|
|
||||||
? (item.price_club / 100).toFixed(2)
|
|
||||||
: ''
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.price_club_big="{ item }">
|
|
||||||
{{ item.price_club_big ? (item.price_club_big / 100).toFixed(2) : '' }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.premium="{ item }">
|
|
||||||
{{ item.premium ? (item.premium / 100).toFixed(2) : '' }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.premium_club="{ item }">
|
|
||||||
{{ item.premium_club ? (item.premium_club / 100).toFixed(2) : '' }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.price_extern_club="{ item }">
|
|
||||||
{{
|
|
||||||
item.price_extern_club
|
|
||||||
? (item.price_extern_club / 100).toFixed(2)
|
|
||||||
: ''
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.action="{ item }">
|
|
||||||
<v-icon small class="mr-2" @click="editItem(item)">
|
|
||||||
{{ editIcon }}
|
|
||||||
</v-icon>
|
|
||||||
<v-icon small @click="deleteItem(item)">
|
|
||||||
{{ deleteIcon }}
|
|
||||||
</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
<v-card tile v-if="isGastro && isGastroPage" :loading="typesLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Kategorien
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn fab x-small @click="dialogType = true" color="primary">
|
|
||||||
<v-icon>{{ plus }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<div tile v-for="type in types" :key="type.id">
|
|
||||||
<v-card tile>
|
|
||||||
<v-card-text class="black--text">
|
|
||||||
<v-row class="ml-3 mr-3">
|
|
||||||
{{ type.name }}
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn icon @click="editType(type)">
|
|
||||||
<v-icon>
|
|
||||||
{{ editIcon }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn icon @click="deleteType(type)">
|
|
||||||
<v-icon>
|
|
||||||
{{ deleteIcon }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</v-card-text>
|
|
||||||
<v-dialog v-model="dialogType">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
{{ dialogTypeTitle }}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-container>
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedType.name"
|
|
||||||
outlined
|
|
||||||
label="Name der Kategorie"
|
|
||||||
/>
|
|
||||||
</v-container>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text color="blue darken-1" @click="closeType()">
|
|
||||||
Abbrechen
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
color="blue darken-1"
|
|
||||||
@click="saveType()"
|
|
||||||
:disabled="inType(editedType.name)"
|
|
||||||
>
|
|
||||||
Speichern
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiMagnify, mdiPlus, mdiPencil, mdiDelete } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'PriceList',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
editIcon: mdiPencil,
|
|
||||||
deleteIcon: mdiDelete,
|
|
||||||
searchIcon: mdiMagnify,
|
|
||||||
plus: mdiPlus,
|
|
||||||
searchType: null,
|
|
||||||
search: null,
|
|
||||||
dialog: null,
|
|
||||||
dialogType: null,
|
|
||||||
editedIndex: -1,
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
text: 'Name',
|
|
||||||
value: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Kategorie',
|
|
||||||
value: 'type'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis in €',
|
|
||||||
value: 'price'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis groß in €',
|
|
||||||
value: 'price_big'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis Club in €',
|
|
||||||
value: 'price_club'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis groß Club in €',
|
|
||||||
value: 'price_club_big'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Aufpreis in €',
|
|
||||||
value: 'premium'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Aufpreis Club in €',
|
|
||||||
value: 'premium_club'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis Club extern in €',
|
|
||||||
value: 'price_extern_club'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
editedItem: {
|
|
||||||
name: null,
|
|
||||||
type: { id: -1, name: null },
|
|
||||||
price: null,
|
|
||||||
price_big: null,
|
|
||||||
price_club: null,
|
|
||||||
price_club_big: null,
|
|
||||||
premium: null,
|
|
||||||
premium_club: null,
|
|
||||||
price_extern_club: null
|
|
||||||
},
|
|
||||||
defaultItem: {
|
|
||||||
name: null,
|
|
||||||
type: { id: -1, name: null },
|
|
||||||
price: null,
|
|
||||||
price_big: null,
|
|
||||||
price_club: null,
|
|
||||||
price_club_big: null,
|
|
||||||
premium: null,
|
|
||||||
premium_club: null,
|
|
||||||
price_extern_club: null
|
|
||||||
},
|
|
||||||
editedType: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
defaultType: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getPriceList: 'priceList/getPriceList',
|
|
||||||
getTypes: 'priceList/getTypes',
|
|
||||||
setDrink: 'priceList/setDrink',
|
|
||||||
updateDrink: 'priceList/updateDrink',
|
|
||||||
deleteDrink: 'priceList/deleteDrink',
|
|
||||||
setDrinkType: 'priceList/setDrinkType',
|
|
||||||
updateDrinkType: 'priceList/updateDrinkType',
|
|
||||||
deleteDrinkType: 'priceList/deleteDrinkType'
|
|
||||||
}),
|
|
||||||
editType(item) {
|
|
||||||
this.editedType = Object.assign({}, item)
|
|
||||||
this.dialogType = true
|
|
||||||
},
|
|
||||||
closeType() {
|
|
||||||
this.dialogType = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.editedType = Object.assign({}, this.defaultType)
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
saveType() {
|
|
||||||
this.editedType.id === -1
|
|
||||||
? this.setDrinkType(this.editedType)
|
|
||||||
: this.updateDrinkType(this.editedType)
|
|
||||||
this.closeType()
|
|
||||||
},
|
|
||||||
deleteType(item) {
|
|
||||||
confirm('Bist du sicher, dass du diese Kategorie entfernen willst?') &&
|
|
||||||
this.deleteDrinkType({ id: item.id })
|
|
||||||
},
|
|
||||||
addType() {
|
|
||||||
this.setDrinkType({ name: this.searchType })
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.dialog = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
this.editedIndex = -1
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
editItem(item) {
|
|
||||||
this.editedIndex = item.id
|
|
||||||
this.editedItem = Object.assign({}, item)
|
|
||||||
for (let i in this.editedItem) {
|
|
||||||
this.editedItem[i] = isNaN(this.editedItem[i])
|
|
||||||
? this.editedItem[i]
|
|
||||||
: this.editedItem[i] == null || this.editedItem[i] == 0
|
|
||||||
? null
|
|
||||||
: (this.editedItem[i] / 100).toFixed(2)
|
|
||||||
}
|
|
||||||
this.editedItem.type = Object.assign(
|
|
||||||
{},
|
|
||||||
this.types.find(a => a.id == item.type)
|
|
||||||
)
|
|
||||||
this.dialog = true
|
|
||||||
},
|
|
||||||
|
|
||||||
deleteItem(item) {
|
|
||||||
confirm('Bist du sicher, dass die dieses Getränk entfernen wills?') &&
|
|
||||||
this.deleteDrink({ id: item.id })
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
var drink = {
|
|
||||||
id: this.editedIndex,
|
|
||||||
name: this.editedItem.name,
|
|
||||||
type: this.editedItem.type.id,
|
|
||||||
price: !isNaN(this.editedItem.price)
|
|
||||||
? this.editedItem.price * 100
|
|
||||||
: null,
|
|
||||||
price_big: !isNaN(this.editedItem.price_big)
|
|
||||||
? this.editedItem.price_big * 100
|
|
||||||
: null,
|
|
||||||
price_club: !isNaN(this.editedItem.price_club)
|
|
||||||
? this.editedItem.price_club * 100
|
|
||||||
: null,
|
|
||||||
price_club_big: !isNaN(this.editedItem.price_club_big)
|
|
||||||
? this.editedItem.price_club_big * 100
|
|
||||||
: null,
|
|
||||||
premium: !isNaN(this.editedItem.premium)
|
|
||||||
? this.editedItem.premium * 100
|
|
||||||
: null,
|
|
||||||
premium_club: !isNaN(this.editedItem.premium_club)
|
|
||||||
? this.editedItem.premium_club * 100
|
|
||||||
: null,
|
|
||||||
price_extern_club: !isNaN(this.editedItem.price_extern_club)
|
|
||||||
? this.editedItem.price_extern_club * 100
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
drink.id === -1 ? this.setDrink(drink) : this.updateDrink(drink)
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
this.close()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
priceList: 'priceList/priceList',
|
|
||||||
types: 'priceList/types',
|
|
||||||
priceListLoading: 'priceList/priceListLoading',
|
|
||||||
typesLoading: 'priceList/typesLoading',
|
|
||||||
isGastro: 'isGastro'
|
|
||||||
}),
|
|
||||||
isGastroPage() {
|
|
||||||
return this.$route.name === 'gastroPricelist'
|
|
||||||
},
|
|
||||||
formTitle() {
|
|
||||||
return this.editedIndex === -1 ? 'Neues Getränk' : 'Bearbeite Getränk'
|
|
||||||
},
|
|
||||||
inType() {
|
|
||||||
return text => {
|
|
||||||
return !!this.types.find(a => {
|
|
||||||
if (a.name === null || text === null) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return a.name.toLowerCase() === text.toLowerCase()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dialogTypeTitle() {
|
|
||||||
return this.editedType.id === -1
|
|
||||||
? 'Neue Kategorie'
|
|
||||||
: 'Bearbeite Kategorie'
|
|
||||||
},
|
|
||||||
computeType() {
|
|
||||||
return id => {
|
|
||||||
const type = this.types.find(a => {
|
|
||||||
return a.id === id
|
|
||||||
})
|
|
||||||
return type ? type.name : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getPriceList()
|
|
||||||
this.getTypes()
|
|
||||||
if (this.isGastro && this.isGastroPage) {
|
|
||||||
this.headers.push({
|
|
||||||
text: 'Aktion',
|
|
||||||
value: 'action',
|
|
||||||
sortable: false,
|
|
||||||
filterable: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
console.log(this.$route)
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
dialog(val) {
|
|
||||||
val || this.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,497 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-container>
|
|
||||||
<v-dialog v-model="checkValidate" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Willst du wirklich??
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text v-if="stornoMessage">
|
|
||||||
Willst du wirklich den Betrag
|
|
||||||
{{ (stornoMessage.amount / 100).toFixed(2) }}€ von
|
|
||||||
{{ stornoMessage.user.firstname }}
|
|
||||||
{{ stornoMessage.user.lastname }} stornieren?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancelStorno">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="acceptStorno">Stornieren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog v-model="dialog" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="headline"
|
|
||||||
>Transaktion ist länger als 15 Sekunden her!</v-card-title
|
|
||||||
>
|
|
||||||
<v-card-text>
|
|
||||||
Da die Transaktion länger als 15 Sekunden her ist, kann eine
|
|
||||||
Stornierung nicht durchgeführt werden. Wende dich bitte an den
|
|
||||||
Finanzer.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="dialog = false">
|
|
||||||
Verstanden
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog
|
|
||||||
v-if="overLimitUser"
|
|
||||||
v-model="overLimitUser"
|
|
||||||
max-width="290"
|
|
||||||
persistent
|
|
||||||
>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Warnung</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
{{ overLimitUser.firstname }} {{ overLimitUser.lastname }} übersteigt
|
|
||||||
das Anschreibelimit von
|
|
||||||
{{ (overLimitUser.limit / 100).toFixed(2) }} €. Danach kann dieses
|
|
||||||
Mitglied nichts mehr anschreiben. Will er das wirklich?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancel()">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="continueAdd(overLimitUser)">Anschreiben</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-dialog v-if="overOverLimit" v-model="overOverLimit" max-width="290" persistent>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Anschreiben nicht möglich</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
{{ overOverLimit.firstname }}
|
|
||||||
{{ overOverLimit.lastname }} überschreitet das Anschreibelimit zuviel.
|
|
||||||
Das Anschreiben wurde daher gestoppt und zurückgesetzt.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn text @click="overOverLimit = null">Verstanden</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<AddAmountSkeleton v-if="loading" />
|
|
||||||
<v-navigation-drawer v-model="menu" right app clipped>
|
|
||||||
<v-list-item-group :key="componentRenderer">
|
|
||||||
<v-list-item inactive>
|
|
||||||
<v-list-item-title class="headline">
|
|
||||||
Verlauf
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<div
|
|
||||||
v-for="message in messages"
|
|
||||||
three-line
|
|
||||||
:key="messages.indexOf(message)"
|
|
||||||
>
|
|
||||||
<div v-if="message">
|
|
||||||
<v-list-item three-line inactive @click="storno(message)">
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-progress-linear indeterminate v-if="message.loading" />
|
|
||||||
<v-list-item-title>{{ now(message.date) }}</v-list-item-title>
|
|
||||||
<v-list-item-subtitle>
|
|
||||||
{{ createSum(message) }} {{ createMessage(message) }}
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle class="red--text" v-if="message.storno"
|
|
||||||
>STORNIERT!!!
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle class="red--text" v-else-if="message.error">
|
|
||||||
ERROR!
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-action-text v-if="under5minutes(message.date) && !message.error"
|
|
||||||
>Klicken um zu Stornieren
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-list-item-group>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
<v-card v-if="!loading" :loading="addLoading">
|
|
||||||
<v-card-title>
|
|
||||||
{{ user.firstname }} {{ user.lastname }}
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn @click="menu = !menu" icon>
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-subtitle v-if="user.limit + getAllSum() > 0">
|
|
||||||
Nur noch {{ ((user.limit + getAllSum()) / 100).toFixed(2) }} €
|
|
||||||
übrig!!
|
|
||||||
</v-card-subtitle>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="10">
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(200)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>2 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(100)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>1 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(50)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,50 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(40)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,40 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(20)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,20 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="6" sm="4">
|
|
||||||
<v-btn
|
|
||||||
class="creditBtn"
|
|
||||||
block
|
|
||||||
@click="addingAmount(10)"
|
|
||||||
:color="color"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>0,10 €</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="8">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
type="number"
|
|
||||||
v-model="value"
|
|
||||||
label="Benutzerdefinierter Betrag"
|
|
||||||
:disabled="user.locked"
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="4">
|
|
||||||
<v-btn
|
|
||||||
fab
|
|
||||||
:color="color"
|
|
||||||
@click="addAmountMore()"
|
|
||||||
:disabled="user.locked"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plus }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center">
|
|
||||||
<v-row>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text :class="getColor(getAllSum())"
|
|
||||||
>{{ (getAllSum() / 100).toFixed(2) }}
|
|
||||||
€
|
|
||||||
</v-list-item-action-text>
|
|
||||||
<v-list-item-action-text v-if="toSetAmount">
|
|
||||||
- {{ (toSetAmount / 100).toFixed(2) }}
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-alert v-if="user.locked" type="error"
|
|
||||||
>{{ user.firstname }} darf nicht mehr anschreiben.
|
|
||||||
{{ user.firstname }} sollte sich lieber mal beim Finanzer
|
|
||||||
melden.</v-alert
|
|
||||||
>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-snackbar
|
|
||||||
v-for="message in messages"
|
|
||||||
:key="messages.indexOf(message)"
|
|
||||||
:color="message.error ? 'error' : 'success'"
|
|
||||||
bottom
|
|
||||||
:timeout="0"
|
|
||||||
:multi-line="true"
|
|
||||||
v-model="message.visible"
|
|
||||||
vertical
|
|
||||||
>
|
|
||||||
<div class="title">
|
|
||||||
<p style="font-size: 5em; margin: 20px">{{ createSum(message) }}</p>
|
|
||||||
{{ createMessage(message) }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ now(message.date) }}
|
|
||||||
</div>
|
|
||||||
<v-btn color="white" icon @click="message.visible = false">
|
|
||||||
<v-icon>
|
|
||||||
{{ close }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-snackbar>
|
|
||||||
<ConnectionError/>
|
|
||||||
</v-container>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
import { mdiMenu, mdiPlus, mdiClose } from '@mdi/js'
|
|
||||||
import AddAmountSkeleton from './Skeleton/AddAmountSkeleton'
|
|
||||||
import ConnectionError from "@/components/ConnectionError";
|
|
||||||
export default {
|
|
||||||
name: 'AddAmount',
|
|
||||||
components: {ConnectionError, AddAmountSkeleton },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
color: 'green accent-4',
|
|
||||||
value: null,
|
|
||||||
plus: mdiPlus,
|
|
||||||
menu: false,
|
|
||||||
dialog: false,
|
|
||||||
componentRenderer: 0,
|
|
||||||
timer: '',
|
|
||||||
menuIcon: mdiMenu,
|
|
||||||
close: mdiClose,
|
|
||||||
checkValidate: false,
|
|
||||||
stornoMessage: null,
|
|
||||||
timeout: null,
|
|
||||||
toSetAmount: null,
|
|
||||||
overLimitUser: null,
|
|
||||||
overOverLimit: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.timer = setInterval(this.forceRender, 1000)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
addAmount: 'user/addAmount',
|
|
||||||
commitStorno: 'user/storno'
|
|
||||||
}),
|
|
||||||
continueAdd(user) {
|
|
||||||
this.overLimitUser = null
|
|
||||||
user.checkedOverLimit = true
|
|
||||||
if (this.value) {
|
|
||||||
this.addAmount(Math.round(Math.abs(this.value * 100)))
|
|
||||||
setTimeout(() => {
|
|
||||||
this.value = null
|
|
||||||
this.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
} else {
|
|
||||||
user.timeout = setTimeout(() => {
|
|
||||||
this.addAmount(this.toSetAmount)
|
|
||||||
setTimeout(() => {
|
|
||||||
this.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.toSetAmount = null
|
|
||||||
this.value = null
|
|
||||||
this.overLimitUser = null
|
|
||||||
},
|
|
||||||
checkOverLimitIsValid(user) {
|
|
||||||
if (this.toSetAmount && user.autoLock) {
|
|
||||||
if ((this.getAllSum() - Number.parseInt(this.toSetAmount)) < -(user.limit + 500)) {
|
|
||||||
this.overOverLimit = user
|
|
||||||
this.toSetAmount = null
|
|
||||||
this.value = null
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
checkOverLimit(user) {
|
|
||||||
if (this.toSetAmount) {
|
|
||||||
if (( this.getAllSum() - this.toSetAmount) < -user.limit) {
|
|
||||||
return user.checkedOverLimit ? false : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
addingAmount(amount) {
|
|
||||||
clearTimeout(this.timeout)
|
|
||||||
this.toSetAmount = this.toSetAmount ? this.toSetAmount + amount : amount
|
|
||||||
if (this.checkOverLimitIsValid(this.user)) {
|
|
||||||
if (this.checkOverLimit(this.user) && this.user.autoLock) {
|
|
||||||
this.overLimitUser = this.user
|
|
||||||
} else {
|
|
||||||
this.timeout = setTimeout(() => {
|
|
||||||
this.addAmount(this.toSetAmount)
|
|
||||||
setTimeout(() => {
|
|
||||||
this.toSetAmount = null
|
|
||||||
}, 300)
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
forceRender() {
|
|
||||||
this.componentRenderer += 1
|
|
||||||
},
|
|
||||||
getColor(value) {
|
|
||||||
return value >= 0 ? 'title green--text' : 'title red--text'
|
|
||||||
},
|
|
||||||
getAllSum() {
|
|
||||||
if (this.user)
|
|
||||||
return (
|
|
||||||
this.user.creditList[this.year][2].sum +
|
|
||||||
this.user.creditList[this.year][1].last
|
|
||||||
)
|
|
||||||
return 0
|
|
||||||
},
|
|
||||||
storno(message) {
|
|
||||||
if (!message.error) {
|
|
||||||
if (!this.under5minutes(message.date)) this.dialog = true
|
|
||||||
else {
|
|
||||||
this.checkValidate = true
|
|
||||||
this.stornoMessage = message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
acceptStorno() {
|
|
||||||
this.commitStorno({
|
|
||||||
amount: this.stornoMessage.amount,
|
|
||||||
date: this.stornoMessage.date
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.cancelStorno()
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
cancelStorno() {
|
|
||||||
this.stornoMessage = null
|
|
||||||
this.checkValidate = null
|
|
||||||
},
|
|
||||||
addAmountMore() {
|
|
||||||
this.toSetAmount = this.toSetAmount
|
|
||||||
? this.toSetAmount + Math.round(Math.abs(this.value * 100))
|
|
||||||
: Math.round(Math.abs(this.value * 100))
|
|
||||||
if (this.checkOverLimitIsValid(this.user)) {
|
|
||||||
if (this.checkOverLimit(this.user) && this.user.autoLock) {
|
|
||||||
this.overLimitUser = this.user
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.addAmount(Math.abs(this.value * 100))
|
|
||||||
setTimeout(() => {
|
|
||||||
this.value = null
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
createSum(message) {
|
|
||||||
var text = '' + (message.amount / 100).toFixed(2) + '€'
|
|
||||||
return text
|
|
||||||
},
|
|
||||||
createMessage(message) {
|
|
||||||
var text = ''
|
|
||||||
if (message.error) {
|
|
||||||
text =
|
|
||||||
' konnten nicht zu ' +
|
|
||||||
message.user.firstname +
|
|
||||||
' ' +
|
|
||||||
message.user.lastname +
|
|
||||||
' hinzufügen.'
|
|
||||||
} else {
|
|
||||||
text =
|
|
||||||
' wurde zu ' +
|
|
||||||
message.user.firstname +
|
|
||||||
' ' +
|
|
||||||
message.user.lastname +
|
|
||||||
' hinzugefügt.'
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
user: 'user/user',
|
|
||||||
year: 'user/year',
|
|
||||||
loading: 'user/loading',
|
|
||||||
addLoading: 'user/addLoading',
|
|
||||||
messages: 'user/messages'
|
|
||||||
}),
|
|
||||||
under5minutes() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
return actual - now < 15000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
now() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
var zero = new Date(0)
|
|
||||||
var date = new Date(actual - now)
|
|
||||||
if (date.getFullYear() === zero.getFullYear()) {
|
|
||||||
if (date.getMonth() === zero.getMonth()) {
|
|
||||||
if (date.getDate() === zero.getDate()) {
|
|
||||||
if (date.getHours() === zero.getDate()) {
|
|
||||||
if (date.getMinutes() < 1) {
|
|
||||||
return 'vor ' + date.getSeconds() + ' Sekunden'
|
|
||||||
} else if (date.getMinutes() < 10) {
|
|
||||||
return 'vor ' + date.getMinutes() + ' Minuten'
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
now.getDate() +
|
|
||||||
'.' +
|
|
||||||
now.getMonth() +
|
|
||||||
'.' +
|
|
||||||
now.getFullYear() +
|
|
||||||
' ' +
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,458 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-card v-if="user" :loading="loading" style="margin-top: 3px">
|
|
||||||
<v-card-title>{{ user.firstname }} {{ user.lastname }}</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Vornamen"
|
|
||||||
:placeholder="user.firstname"
|
|
||||||
v-model="firstname"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Nachname"
|
|
||||||
:placeholder="user.lastname"
|
|
||||||
v-model="lastname"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Benutzername"
|
|
||||||
:placeholder="user.username"
|
|
||||||
v-model="username"
|
|
||||||
readonly
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-text-field
|
|
||||||
ref="mail"
|
|
||||||
outlined
|
|
||||||
label="E-Mail"
|
|
||||||
:placeholder="user.mail"
|
|
||||||
v-model="mail"
|
|
||||||
readonly
|
|
||||||
></v-text-field>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="neues Password"
|
|
||||||
type="password"
|
|
||||||
v-model="password"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6">
|
|
||||||
<v-form ref="newPassword">
|
|
||||||
<v-text-field
|
|
||||||
ref="password"
|
|
||||||
v-model="controlPassword"
|
|
||||||
outlined
|
|
||||||
label="neues Password bestätigen"
|
|
||||||
type="password"
|
|
||||||
:disabled="!password"
|
|
||||||
:rules="[equal_password]"
|
|
||||||
/>
|
|
||||||
</v-form>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-divider />
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="4">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Sperrlimit"
|
|
||||||
readonly
|
|
||||||
:value="(user.limit / 100).toFixed(2).toString() + '€'"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="4">
|
|
||||||
<v-combobox
|
|
||||||
outlined
|
|
||||||
label="Sperrstatus"
|
|
||||||
v-model="lock"
|
|
||||||
append-icon
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-chip :color="lockColor">
|
|
||||||
{{ data.item }}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-combobox>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="4">
|
|
||||||
<v-combobox
|
|
||||||
outlined
|
|
||||||
label="Autosperre"
|
|
||||||
v-model="autoLock"
|
|
||||||
readonly
|
|
||||||
append-icon
|
|
||||||
>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-chip :color="autoLockColor">
|
|
||||||
{{ data.item }}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-combobox>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-combobox
|
|
||||||
outlined
|
|
||||||
multiple
|
|
||||||
label="Gruppen"
|
|
||||||
readonly
|
|
||||||
v-model="user.group"
|
|
||||||
append-icon
|
|
||||||
>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-icon class="ma-2">{{
|
|
||||||
data.item === 'user'
|
|
||||||
? person
|
|
||||||
: data.item === 'bar'
|
|
||||||
? bar
|
|
||||||
: data.item === 'moneymaster'
|
|
||||||
? finanzer
|
|
||||||
: data.item === 'gastro'
|
|
||||||
? gastro
|
|
||||||
: ''
|
|
||||||
}}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-combobox>
|
|
||||||
</v-col>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
:value="computeStatus"
|
|
||||||
readonly
|
|
||||||
label="Mitgliedsstatus"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
:value="user.voting ? 'ja' : 'nein'"
|
|
||||||
readonly
|
|
||||||
label="Stimmrecht"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-combobox
|
|
||||||
chips
|
|
||||||
outlined
|
|
||||||
multiple
|
|
||||||
label="Arbeitsgruppen"
|
|
||||||
readonly
|
|
||||||
v-model="user.workgroups"
|
|
||||||
item-value="id"
|
|
||||||
item-text="name"
|
|
||||||
append-icon
|
|
||||||
>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-chip>{{ data.item.name }}</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-combobox>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<div class="subtitle-1">
|
|
||||||
Gespeicherte Sessions
|
|
||||||
</div>
|
|
||||||
<v-card v-for="token in tokens" :key="token.id" outlined>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-col>
|
|
||||||
Betriebssystem
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon>
|
|
||||||
{{
|
|
||||||
token.platform === 'macos' || token.platform === 'iphone'
|
|
||||||
? apple
|
|
||||||
: token.platform === 'windows'
|
|
||||||
? windows
|
|
||||||
: token.platform === 'android'
|
|
||||||
? android
|
|
||||||
: token.platform === 'linux'
|
|
||||||
? linux
|
|
||||||
: token.platfrom
|
|
||||||
}}
|
|
||||||
</v-icon>
|
|
||||||
<v-icon
|
|
||||||
v-if="
|
|
||||||
token.platform === 'macos' || token.platform === 'iphone'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ token.platform === 'macos' ? mac : iphone }}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-col>
|
|
||||||
Browser
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon>
|
|
||||||
{{
|
|
||||||
token.browser === 'chrome'
|
|
||||||
? chrome
|
|
||||||
: token.browser === 'firefox'
|
|
||||||
? firefox
|
|
||||||
: token.browser === 'opera'
|
|
||||||
? opera
|
|
||||||
: token.browser === 'safari'
|
|
||||||
? safari
|
|
||||||
: token.browser === 'msie'
|
|
||||||
? msie
|
|
||||||
: token.browser
|
|
||||||
}}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-col>
|
|
||||||
Letzte Aktualisierung
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
{{ token.timestamp.day }}.{{ token.timestamp.month }}.{{
|
|
||||||
token.timestamp.year
|
|
||||||
}}
|
|
||||||
um
|
|
||||||
{{
|
|
||||||
10 > token.timestamp.hour
|
|
||||||
? '0' + String(token.timestamp.hour)
|
|
||||||
: token.timestamp.hour
|
|
||||||
}}:{{
|
|
||||||
10 > token.timestamp.minute
|
|
||||||
? '0' + String(token.timestamp.minute)
|
|
||||||
: token.timestamp.minute
|
|
||||||
}}:{{
|
|
||||||
10 > token.timestamp.second
|
|
||||||
? '0' + String(token.timestamp.second)
|
|
||||||
: token.timestamp.second
|
|
||||||
}}</v-col
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-col>
|
|
||||||
Lebenszeit
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
{{ calcLifefime(token.lifetime) }}
|
|
||||||
</v-col>
|
|
||||||
</v-col>
|
|
||||||
<v-col class="text-right">
|
|
||||||
<v-btn icon @click="deleteToken(token)">
|
|
||||||
<v-icon>
|
|
||||||
{{ trashCan }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-form ref="acceptedPasswordTest">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Passwort"
|
|
||||||
v-model="acceptedPassword"
|
|
||||||
type="password"
|
|
||||||
ref="acceptedPassword"
|
|
||||||
:rules="[empty_password]"
|
|
||||||
></v-text-field>
|
|
||||||
</v-form>
|
|
||||||
<v-btn text color="primary" @click="save">Speichern</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
<v-snackbar
|
|
||||||
v-if="error ? error.value : false"
|
|
||||||
:color="error ? (error.error ? 'error' : 'success') : ''"
|
|
||||||
:value="error"
|
|
||||||
v-model="error"
|
|
||||||
:timeout="0"
|
|
||||||
>
|
|
||||||
{{ error ? error.value : null }}
|
|
||||||
</v-snackbar>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
mdiAccount,
|
|
||||||
mdiGlassCocktail,
|
|
||||||
mdiCurrencyEur,
|
|
||||||
mdiFoodForkDrink,
|
|
||||||
mdiApple,
|
|
||||||
mdiGoogleChrome,
|
|
||||||
mdiFirefox,
|
|
||||||
mdiOpera,
|
|
||||||
mdiInternetExplorer,
|
|
||||||
mdiAppleSafari,
|
|
||||||
mdiLaptopMac,
|
|
||||||
mdiCellphoneIphone,
|
|
||||||
mdiTrashCan,
|
|
||||||
mdiAndroid,
|
|
||||||
mdiWindows,
|
|
||||||
mdiLinux
|
|
||||||
} from '@mdi/js'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'Config',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
apple: mdiApple,
|
|
||||||
mac: mdiLaptopMac,
|
|
||||||
iphone: mdiCellphoneIphone,
|
|
||||||
android: mdiAndroid,
|
|
||||||
windows: mdiWindows,
|
|
||||||
linux: mdiLinux,
|
|
||||||
chrome: mdiGoogleChrome,
|
|
||||||
firefox: mdiFirefox,
|
|
||||||
opera: mdiOpera,
|
|
||||||
msie: mdiInternetExplorer,
|
|
||||||
safari: mdiAppleSafari,
|
|
||||||
person: mdiAccount,
|
|
||||||
bar: mdiGlassCocktail,
|
|
||||||
finanzer: mdiCurrencyEur,
|
|
||||||
gastro: mdiFoodForkDrink,
|
|
||||||
username: null,
|
|
||||||
mail: null,
|
|
||||||
firstname: null,
|
|
||||||
lastname: null,
|
|
||||||
password: null,
|
|
||||||
controlPassword: null,
|
|
||||||
trashCan: mdiTrashCan,
|
|
||||||
isFulllineText: false,
|
|
||||||
acceptedPassword: null,
|
|
||||||
passError: null,
|
|
||||||
equal_password: value =>
|
|
||||||
this.password === value || 'Passwörter sind nicht identisch.',
|
|
||||||
email: value => {
|
|
||||||
if (value.length > 0) {
|
|
||||||
const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
||||||
return pattern.test(value) || 'keine gültige E-Mail'
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
empty_password: data => {
|
|
||||||
return !!data || 'Password wird bentögigt'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$nextTick(function() {
|
|
||||||
window.addEventListener('resize', this.getWindowWidth)
|
|
||||||
this.getWindowWidth()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
saveConfig: 'user/saveConfig',
|
|
||||||
getStatus: 'user/getStatus',
|
|
||||||
getTokens: 'user/getTokens',
|
|
||||||
deleteToken: 'user/deleteToken'
|
|
||||||
}),
|
|
||||||
getWindowWidth() {
|
|
||||||
this.isFulllineText = document.documentElement.clientWidth <= 600
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
let user = {}
|
|
||||||
if (this.firstname) user.firstname = this.firstname
|
|
||||||
if (this.lastname) user.lastname = this.lastname
|
|
||||||
if (this.username) user.username = this.username
|
|
||||||
if (this.$refs.mail.validate()) {
|
|
||||||
if (this.mail) user.mail = this.mail
|
|
||||||
}
|
|
||||||
if (this.$refs.newPassword.validate()) {
|
|
||||||
if (this.password) user.password = this.password
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
console.log(this.$refs.acceptedPasswordTest.validate())
|
|
||||||
if (this.$refs.acceptedPasswordTest.validate()) {
|
|
||||||
this.saveConfig({
|
|
||||||
oldUsername: user.username,
|
|
||||||
...user,
|
|
||||||
acceptedPassword: this.acceptedPassword
|
|
||||||
})
|
|
||||||
this.$refs.acceptedPassword.reset()
|
|
||||||
} else {
|
|
||||||
this.passError = 'Du musst dein Password eingeben'
|
|
||||||
}
|
|
||||||
this.password = null
|
|
||||||
this.controlPassword = null
|
|
||||||
},
|
|
||||||
calcLifefime(time) {
|
|
||||||
if (time < 60) return String(time) + 'Sekunden'
|
|
||||||
time = Math.round(time / 60)
|
|
||||||
if (time < 60) return String(time) + 'Minuten'
|
|
||||||
time = Math.round(time / 60)
|
|
||||||
if (time < 24) return String(time) + 'Stunden'
|
|
||||||
time = Math.round(time / 24)
|
|
||||||
if (time < 7) return String(time) + 'Tage'
|
|
||||||
time = Math.round(time / 7)
|
|
||||||
if (time < 30) return String(time) + 'Wochen'
|
|
||||||
time = Math.round(time / 30)
|
|
||||||
if (time < 12) return String(time) + 'Monate'
|
|
||||||
time = Math.round(time / 12)
|
|
||||||
return String(time) + 'Jahre'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
user: 'user/user',
|
|
||||||
error: 'user/error',
|
|
||||||
loading: 'user/loading',
|
|
||||||
status: 'user/status',
|
|
||||||
tokens: 'user/tokens'
|
|
||||||
}),
|
|
||||||
lock() {
|
|
||||||
return this.user.locked ? 'gesperrt' : 'nicht gesperrt'
|
|
||||||
},
|
|
||||||
lockColor() {
|
|
||||||
return this.user.locked ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
autoLock() {
|
|
||||||
return this.user.autoLock ? 'aktiviert' : 'deaktiviert'
|
|
||||||
},
|
|
||||||
autoLockColor() {
|
|
||||||
return this.user.autoLock ? 'green' : 'red'
|
|
||||||
},
|
|
||||||
computeStatus() {
|
|
||||||
try {
|
|
||||||
return this.status.find(a => a.id == this.user.statusgroup).name
|
|
||||||
} catch (e) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getStatus()
|
|
||||||
this.getTokens()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.fulllineText {
|
|
||||||
flex-basis: unset;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,116 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-toolbar>
|
|
||||||
<v-toolbar-title>Gesamtübersicht</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-text-field
|
|
||||||
v-model="filter"
|
|
||||||
style="margin-top: 3px"
|
|
||||||
outlined
|
|
||||||
type="number"
|
|
||||||
:rules="[isNumber]"
|
|
||||||
>
|
|
||||||
<template v-slot:append>
|
|
||||||
<v-icon>{{magnify}}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<CreditOverviewSkeleton v-if="loading" />
|
|
||||||
<div v-for="year in years" :key="years.indexOf(year)">
|
|
||||||
<v-card style="margin-top: 3px" v-if="isFiltered(year)">
|
|
||||||
<v-card-title>{{ year }}</v-card-title>
|
|
||||||
<Table v-bind:user="user" v-bind:year="year" />
|
|
||||||
<v-container fluid>
|
|
||||||
<v-col>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Vorjahr:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
:text-color="getLastColor(user.creditList[year][1].last)"
|
|
||||||
>{{ (user.creditList[year][1].last / 100).toFixed(2) }}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-label>Gesamt:</v-label>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-chip
|
|
||||||
outlined
|
|
||||||
x-large
|
|
||||||
:text-color="
|
|
||||||
getLastColor(
|
|
||||||
getAllSum(
|
|
||||||
user.creditList[year][2].sum,
|
|
||||||
user.creditList[year][1].last
|
|
||||||
)
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
(
|
|
||||||
getAllSum(
|
|
||||||
user.creditList[year][2].sum,
|
|
||||||
user.creditList[year][1].last
|
|
||||||
) / 100
|
|
||||||
).toFixed(2)
|
|
||||||
}}
|
|
||||||
</v-chip>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
import Table from '../finanzer/Table'
|
|
||||||
import CreditOverviewSkeleton from './Skeleton/CreditOverviewSkeleton'
|
|
||||||
import { mdiMagnify } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'CreditOverview',
|
|
||||||
components: { CreditOverviewSkeleton, Table },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isNumber: value => Number.isInteger(parseInt(value === '' ? 0 : value)) || "Muss eine Zahl sein.",
|
|
||||||
filter: '',
|
|
||||||
magnify: mdiMagnify
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getLastColor(value) {
|
|
||||||
return value < 0 ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
getAllSum(sum, lastYear) {
|
|
||||||
return lastYear + sum
|
|
||||||
},
|
|
||||||
isFiltered(value) {
|
|
||||||
return value.toString().includes(this.filter)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
user: 'user/user',
|
|
||||||
loading: 'user/loading'
|
|
||||||
}),
|
|
||||||
years() {
|
|
||||||
let years = []
|
|
||||||
if (this.user) {
|
|
||||||
for (let year in this.user.creditList) {
|
|
||||||
years.unshift(parseInt(year))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return years
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,208 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-card tile :loading="jobInvitesLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Eingehende Einladungen
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expansion-panels>
|
|
||||||
<v-expansion-panel
|
|
||||||
v-for="jobInvite in jobInvitesToMe"
|
|
||||||
:key="jobInvite.id"
|
|
||||||
@click.once="seenJobIvnite(jobInvite)"
|
|
||||||
>
|
|
||||||
<v-expansion-panel-header>
|
|
||||||
<div>
|
|
||||||
{{ jobInvite.on_date.getDate() }}.{{
|
|
||||||
jobInvite.on_date.getMonth() + 1
|
|
||||||
}}.{{ jobInvite.on_date.getFullYear() }} von
|
|
||||||
<v-badge dot :value="!jobInvite.watched" color="red">
|
|
||||||
{{ jobInvite.from_user.firstname }}
|
|
||||||
{{ jobInvite.from_user.lastname }}
|
|
||||||
</v-badge>
|
|
||||||
</div>
|
|
||||||
<v-row class="text-right" style="margin-right: 5px">
|
|
||||||
<v-col>
|
|
||||||
<v-progress-circular
|
|
||||||
indeterminate
|
|
||||||
v-if="jobInvitesLoading"
|
|
||||||
></v-progress-circular>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon color="green" v-show="userInWorker(jobInvite)">
|
|
||||||
{{ check }}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-expansion-panel-header>
|
|
||||||
<v-expansion-panel-content :eager="true">
|
|
||||||
<v-row class="text-right">
|
|
||||||
<v-col>
|
|
||||||
<v-btn icon @click="updatingJobInvite(jobInvite)">
|
|
||||||
<v-icon>
|
|
||||||
{{ jobInvite.watched ? seen : notSeen }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<Day
|
|
||||||
:day="jobInvite.day"
|
|
||||||
:long="true"
|
|
||||||
:loading="jobInvite.day.loading"
|
|
||||||
@addingJob="addingJob(jobInvite, $event)"
|
|
||||||
@deletingJob="deletingJob(jobInvite, $event)"
|
|
||||||
@sendInvites="setJobInvites"
|
|
||||||
@sendRequests="setJobRequests"
|
|
||||||
@deleteJobInvite="deleteInvite"
|
|
||||||
@deleteJobRequest="deleteRequest"
|
|
||||||
/>
|
|
||||||
</v-expansion-panel-content>
|
|
||||||
</v-expansion-panel>
|
|
||||||
</v-expansion-panels>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card tile :loading="jobInvitesLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Versendete Einladungen
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expansion-panels>
|
|
||||||
<v-expansion-panel
|
|
||||||
v-for="jobInvite in jobInvitesFromMe"
|
|
||||||
:key="jobInvite.id"
|
|
||||||
@click.once="seenJobIvnite(jobInvite)"
|
|
||||||
>
|
|
||||||
<v-expansion-panel-header>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{{ jobInvite.on_date.getDate() }}.{{
|
|
||||||
jobInvite.on_date.getMonth() + 1
|
|
||||||
}}.{{ jobInvite.on_date.getFullYear() }} an
|
|
||||||
<v-badge :value="jobInvite.watched" icon="mdi-eye" color="grey" inline>
|
|
||||||
{{ jobInvite.to_user.firstname }}
|
|
||||||
{{ jobInvite.to_user.lastname }}
|
|
||||||
</v-badge>
|
|
||||||
</div>
|
|
||||||
<v-row class="text-right" style="margin-right: 5px">
|
|
||||||
<v-col>
|
|
||||||
<v-progress-circular
|
|
||||||
indeterminate
|
|
||||||
v-if="jobInvitesLoading"
|
|
||||||
></v-progress-circular>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon color="green" v-show="userInWorker(jobInvite)">
|
|
||||||
{{ check }}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-expansion-panel-header>
|
|
||||||
<v-expansion-panel-content :eager="true">
|
|
||||||
<v-row class="text-right">
|
|
||||||
<v-col>
|
|
||||||
<v-btn icon @click="deleteInvite(jobInvite)">
|
|
||||||
<v-icon>
|
|
||||||
{{trashCan}}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<Day
|
|
||||||
:day="jobInvite.day"
|
|
||||||
:long="true"
|
|
||||||
:loading="jobInvite.day.loading"
|
|
||||||
@addingJob="addingJob(jobInvite, $event)"
|
|
||||||
@deletingJob="deletingJob(jobInvite, $event)"
|
|
||||||
@sendInvites="setJobInvites"
|
|
||||||
@sendRequests="setJobRequests"
|
|
||||||
@deleteJobInvite="deleteInvite"
|
|
||||||
@deleteJobRequest="deleteRequest"
|
|
||||||
/>
|
|
||||||
</v-expansion-panel-content>
|
|
||||||
</v-expansion-panel>
|
|
||||||
</v-expansion-panels>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
import { mdiEyeOff, mdiEyeCheck, mdiCheck, mdiTrashCan } from '@mdi/js'
|
|
||||||
import Day from '@/components/user/Jobs/Day'
|
|
||||||
export default {
|
|
||||||
name: 'JobInvites',
|
|
||||||
components: { Day },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
notSeen: mdiEyeOff,
|
|
||||||
seen: mdiEyeCheck,
|
|
||||||
check: mdiCheck,
|
|
||||||
trashCan: mdiTrashCan,
|
|
||||||
showNotSeen: false,
|
|
||||||
showSeen: false,
|
|
||||||
update: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getJobInvites: 'jobInvites/getJobInvites',
|
|
||||||
addJob: 'jobInvites/addJob',
|
|
||||||
setJobInvites: 'jobInvites/setJobInvites',
|
|
||||||
updateJobInviteToMe: 'jobInvites/updateJobInviteToMe',
|
|
||||||
deleteJob: 'jobInvites/deleteJob',
|
|
||||||
setJobRequests: 'jobRequests/setJobRequests',
|
|
||||||
deleteInvite: 'jobInvites/deleteJobInviteFromMe',
|
|
||||||
deleteRequest: 'jobRequests/deleteJobRequestFromMe'
|
|
||||||
}),
|
|
||||||
forceRender() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.update += 0
|
|
||||||
}, 500)
|
|
||||||
},
|
|
||||||
updatingJobInvite(jobInvite) {
|
|
||||||
jobInvite.watched = !jobInvite.watched
|
|
||||||
this.updateJobInviteToMe(jobInvite)
|
|
||||||
},
|
|
||||||
seenJobIvnite(jobInvite) {
|
|
||||||
if (!jobInvite.watched) {
|
|
||||||
jobInvite.watched = true
|
|
||||||
this.updateJobInviteToMe(jobInvite)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addingJob(jobInvite, event) {
|
|
||||||
this.seenJobIvnite(jobInvite)
|
|
||||||
this.addJob(event)
|
|
||||||
this.forceRender()
|
|
||||||
},
|
|
||||||
deletingJob(jobInvite, event) {
|
|
||||||
this.seenJobIvnite(jobInvite)
|
|
||||||
this.deleteJob(event)
|
|
||||||
this.forceRender()
|
|
||||||
},
|
|
||||||
userInWorker(jobinvite) {
|
|
||||||
var jobkinddate = jobinvite.day.jobkinddate.find(item => {
|
|
||||||
return item.worker.find(workeritem => {
|
|
||||||
return workeritem.id === jobinvite.to_user.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return !!jobkinddate
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
jobInvitesFromMe: 'jobInvites/jobInvitesFromMe',
|
|
||||||
jobInvitesToMe: 'jobInvites/jobInvitesToMe',
|
|
||||||
jobInvitesLoading: 'jobInvites/jobInvitesLoading',
|
|
||||||
activeUser: 'user/user'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.getJobInvites(new Date())
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,224 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-card tile :loading="jobRequestsLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Eingehende Anfragen
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expansion-panels>
|
|
||||||
<v-expansion-panel
|
|
||||||
v-for="(jobrequest, index) in jobRequestsToMe"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<v-expansion-panel-header @click.once="seenJobRequest(jobrequest)">
|
|
||||||
<div>
|
|
||||||
{{ jobrequest.on_date.getDate() }}.{{
|
|
||||||
jobrequest.on_date.getMonth() + 1
|
|
||||||
}}.{{ jobrequest.on_date.getFullYear() }} von
|
|
||||||
<v-badge dot :value="!jobrequest.watched" color="red">
|
|
||||||
{{ jobrequest.from_user.firstname }}
|
|
||||||
{{ jobrequest.from_user.lastname }}
|
|
||||||
</v-badge>
|
|
||||||
</div>
|
|
||||||
<v-row class="text-right" style="margin-right: 5px">
|
|
||||||
<v-col>
|
|
||||||
<v-progress-circular
|
|
||||||
indeterminate
|
|
||||||
v-if="jobRequestsLoading"
|
|
||||||
></v-progress-circular>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon color="green" v-show="userInWorker(jobrequest)">
|
|
||||||
{{ check }}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-expansion-panel-header>
|
|
||||||
<v-expansion-panel-content>
|
|
||||||
<v-row class="text-right">
|
|
||||||
<v-col>
|
|
||||||
<v-btn icon @click="updatingSeenJobRequest(jobrequest)">
|
|
||||||
<v-icon>
|
|
||||||
{{ jobrequest.watched ? seen : notSeen }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<Day
|
|
||||||
:day="jobrequest.day"
|
|
||||||
:long="true"
|
|
||||||
@sendRequests="sendingJobRequests(jobrequest, $event)"
|
|
||||||
@addingJob="addJob"
|
|
||||||
@deletingJob="deleteJob"
|
|
||||||
@sendInvites="setJobInvites"
|
|
||||||
@deleteJobInvite="deleteInvite"
|
|
||||||
@deleteJobRequest="deleteJobRequestFromMe"
|
|
||||||
/>
|
|
||||||
<v-row class="text-right">
|
|
||||||
<v-col>
|
|
||||||
<v-btn
|
|
||||||
v-show="!jobrequest.answered"
|
|
||||||
text
|
|
||||||
@click="updatingAcceptedJobRequest(jobrequest)"
|
|
||||||
>Annehmen</v-btn
|
|
||||||
>
|
|
||||||
<div v-show="jobrequest.answered && !jobrequest.accepted">
|
|
||||||
Dieser Dienst wurde schon übertragen.
|
|
||||||
</div>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-expansion-panel-content>
|
|
||||||
</v-expansion-panel>
|
|
||||||
</v-expansion-panels>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card tile :loading="jobRequestsLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Ausgehende Anfragen
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expansion-panels>
|
|
||||||
<v-expansion-panel
|
|
||||||
v-for="(jobrequest, index) in jobRequestsFromMe"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<v-expansion-panel-header>
|
|
||||||
<div>
|
|
||||||
{{ jobrequest.on_date.getDate() }}.{{
|
|
||||||
jobrequest.on_date.getMonth() + 1
|
|
||||||
}}.{{ jobrequest.on_date.getFullYear() }} an
|
|
||||||
<v-badge :value="jobrequest.watched" icon="mdi-eye" color="grey" inline>
|
|
||||||
{{ jobrequest.to_user.firstname }}
|
|
||||||
{{ jobrequest.to_user.lastname }}
|
|
||||||
</v-badge>
|
|
||||||
</div>
|
|
||||||
<v-row class="text-right" style="margin-right: 5px">
|
|
||||||
<v-col>
|
|
||||||
<v-progress-circular
|
|
||||||
indeterminate
|
|
||||||
v-if="jobRequestsLoading"
|
|
||||||
></v-progress-circular>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-icon color="green" v-show="jobrequest.accepted">
|
|
||||||
{{ check }}
|
|
||||||
</v-icon>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-expansion-panel-header>
|
|
||||||
<v-expansion-panel-content>
|
|
||||||
<v-row class="text-right">
|
|
||||||
<v-col>
|
|
||||||
<v-btn icon @click="deleteJobRequestFromMe(jobrequest)">
|
|
||||||
<v-icon>
|
|
||||||
{{trashCan}}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<Day
|
|
||||||
:day="jobrequest.day"
|
|
||||||
:long="true"
|
|
||||||
@sendRequests="sendingJobRequests(jobrequest, $event)"
|
|
||||||
@addingJob="addJob"
|
|
||||||
@deletingJob="deleteJob"
|
|
||||||
@sendInvites="setJobInvites"
|
|
||||||
@deleteJobInvite="deleteInvite"
|
|
||||||
@deleteJobRequest="deleteJobRequestFromMe"
|
|
||||||
/>
|
|
||||||
</v-expansion-panel-content>
|
|
||||||
</v-expansion-panel>
|
|
||||||
</v-expansion-panels>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiEyeOff, mdiEyeCheck, mdiCheck, mdiTrashCan } from '@mdi/js'
|
|
||||||
import Day from '@/components/user/Jobs/Day'
|
|
||||||
export default {
|
|
||||||
name: 'JobTransfer',
|
|
||||||
components: { Day },
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
notSeen: mdiEyeOff,
|
|
||||||
seen: mdiEyeCheck,
|
|
||||||
check: mdiCheck,
|
|
||||||
trashCan: mdiTrashCan,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getJobRequests: 'jobRequests/getJobRequests',
|
|
||||||
updateJobRequestToMe: 'jobRequests/updateJobRequestToMe',
|
|
||||||
setJobRequests: 'jobRequests/setJobRequests',
|
|
||||||
deleteJobRequestFromMe: 'jobRequests/deleteJobRequestFromMe',
|
|
||||||
deleteInvite: 'jobInvites/deleteJobInviteFromMe',
|
|
||||||
getJobInvites: 'jobInvites/getJobInvites',
|
|
||||||
addJob: 'jobInvites/addJob',
|
|
||||||
setJobInvites: 'jobInvites/setJobInvites',
|
|
||||||
updateJobInviteToMe: 'jobInvites/updateJobInviteToMe',
|
|
||||||
deleteJob: 'jobInvites/deleteJob',
|
|
||||||
}),
|
|
||||||
updatingAcceptedJobRequest(jobRequest) {
|
|
||||||
jobRequest.accepted = true
|
|
||||||
jobRequest.answered = true
|
|
||||||
this.updateJobRequestToMe({ ...jobRequest })
|
|
||||||
setTimeout(() => {
|
|
||||||
this.getJobRequests(), 200
|
|
||||||
})
|
|
||||||
},
|
|
||||||
updatingSeenJobRequest(jobRequest) {
|
|
||||||
jobRequest.watched = !jobRequest.watched
|
|
||||||
this.updateJobRequestToMe({ ...jobRequest })
|
|
||||||
},
|
|
||||||
seenJobRequest(jobRequest) {
|
|
||||||
if (!jobRequest.watched) {
|
|
||||||
jobRequest.watched = true
|
|
||||||
this.updateJobRequestToMe(jobRequest)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
userInWorker(jobrequest) {
|
|
||||||
var jobkinddate = jobrequest.day.jobkinddate.find(item => {
|
|
||||||
return item.worker.find(workeritem => {
|
|
||||||
return workeritem.id === this.activeUser.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return !!jobkinddate
|
|
||||||
},
|
|
||||||
sendingJobRequests(jobrequest, event) {
|
|
||||||
this.seenJobRequest(jobrequest)
|
|
||||||
this.setJobRequests(event)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
jobRequestsToMe: 'jobRequests/jobRequestsToMe',
|
|
||||||
jobRequestsFromMe: 'jobRequests/jobRequestsFromMe',
|
|
||||||
jobRequestsLoading: 'jobRequests/jobRequestsLoading',
|
|
||||||
loading: 'user/loading',
|
|
||||||
activeUser: 'user/user'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (!this.loading) {
|
|
||||||
this.getJobRequests()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
loading(newValue) {
|
|
||||||
if (!newValue) {
|
|
||||||
this.getJobRequests()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
jobRequestsLoading(newValue, oldValue) {
|
|
||||||
console.log(newValue, oldValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,192 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-toolbar>
|
|
||||||
<v-toolbar-title>Dienstübersicht</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
icon
|
|
||||||
:to="{
|
|
||||||
name: 'userJobs',
|
|
||||||
params: { year: date.getFullYear(), month: date.getMonth() }
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<v-icon>{{ keyboard_arrow_left }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-title class="title">
|
|
||||||
{{ monthArray[date.getMonth()] }}
|
|
||||||
{{ date.getFullYear() }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
icon
|
|
||||||
:to="{
|
|
||||||
name: 'userJobs',
|
|
||||||
params: { year: date.getFullYear(), month: date.getMonth() + 2 }
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<v-icon>{{ keyboard_arrow_right }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
<v-spacer />
|
|
||||||
</v-toolbar>
|
|
||||||
<v-card v-for="week in month" :key="month.indexOf(week)" flat tile>
|
|
||||||
<v-card-title class="subtitle-1 font-weight-bold">
|
|
||||||
Woche vom {{ week.startDate.getDate() }}.{{
|
|
||||||
week.startDate.getMonth() + 1
|
|
||||||
}}.{{ week.startDate.getFullYear() }} bis
|
|
||||||
{{ week.endDate.getDate() }}.{{ week.endDate.getMonth() + 1 }}.{{
|
|
||||||
week.endDate.getFullYear()
|
|
||||||
}}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row justify="start" align="start">
|
|
||||||
<div v-for="day in week.days" :key="day.id">
|
|
||||||
<v-col cols="12">
|
|
||||||
<Day
|
|
||||||
:day="day"
|
|
||||||
:long="false"
|
|
||||||
@addingJob="addJob"
|
|
||||||
@sendInvites="setJobInvites"
|
|
||||||
@deletingJob="deleteJob"
|
|
||||||
@sendRequests="setJobRequests"
|
|
||||||
@deleteJobInvite="deleteInvite"
|
|
||||||
@deleteJobRequest="deleteRequest"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</div>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiChevronLeft, mdiChevronRight } from '@mdi/js'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import Day from '@/components/user/Jobs/Day'
|
|
||||||
export default {
|
|
||||||
name: 'Jobs',
|
|
||||||
components: { Day },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
keyboard_arrow_left: mdiChevronLeft,
|
|
||||||
keyboard_arrow_right: mdiChevronRight,
|
|
||||||
date: new Date(this.$route.params.year, this.$route.params.month - 1, 1),
|
|
||||||
monthArray: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getActiveUser()
|
|
||||||
this.getAllJobKinds()
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getDBUsers()
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getActiveUser: 'user/getUser',
|
|
||||||
createMonth: 'jobs/createMonth',
|
|
||||||
getUsers: 'jobs/getUsers',
|
|
||||||
getDBUsers: 'usermanager/getUsers',
|
|
||||||
getAllJobKinds: 'jkm/getAllJobKinds',
|
|
||||||
addJob: 'jobs/addJob',
|
|
||||||
deleteJob: 'jobs/deleteJob',
|
|
||||||
setJobInvites: 'jobInvites/setJobInvites',
|
|
||||||
getJobInvites: 'jobInvites/getJobInvites',
|
|
||||||
getJobRequests: 'jobRequests/getJobRequests',
|
|
||||||
setJobRequests: 'jobRequests/setJobRequests',
|
|
||||||
deleteInvite: 'jobInvites/deleteJobInviteFromMe',
|
|
||||||
deleteRequest: 'jobRequests/deleteJobRequestFromMe'
|
|
||||||
}),
|
|
||||||
changeMonth(value) {
|
|
||||||
if (value === -1) {
|
|
||||||
this.date = new Date(this.date.getFullYear(), this.date.getMonth() - 1)
|
|
||||||
} else {
|
|
||||||
this.date = new Date(this.date.getFullYear(), this.date.getMonth() + 1)
|
|
||||||
}
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
month: 'jobs/month',
|
|
||||||
startDate: 'jobs/getStartDate',
|
|
||||||
endDate: 'jobs/getEndDate',
|
|
||||||
loading: 'user/loading'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
$route() {
|
|
||||||
this.getActiveUser()
|
|
||||||
this.date = new Date(
|
|
||||||
this.$route.params.year,
|
|
||||||
this.$route.params.month - 1,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
this.getAllJobKinds()
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getDBUsers()
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loading(newValue) {
|
|
||||||
if (!newValue) {
|
|
||||||
this.getJobInvites()
|
|
||||||
this.getJobRequests()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,438 +0,0 @@
|
||||||
<template>
|
|
||||||
<div v-if="day">
|
|
||||||
<v-card :color="color(day)" :max-width="long ? '' : '20em'">
|
|
||||||
<v-card-title v-if="day.date" class="subtitle-1 font-weight-bold">
|
|
||||||
{{ name }} den {{ day.date.getDate() }}.{{ day.date.getMonth() + 1 }}.{{
|
|
||||||
day.date.getFullYear()
|
|
||||||
}}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expand-transition>
|
|
||||||
<v-row align="center" justify="center" v-if="day.loading">
|
|
||||||
<v-progress-circular indeterminate color="grey" />
|
|
||||||
</v-row>
|
|
||||||
</v-expand-transition>
|
|
||||||
<v-expand-transition>
|
|
||||||
<div v-show="!day.loading">
|
|
||||||
<div
|
|
||||||
v-for="(jobkinddateitem, index) in day.jobkinddate"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<div class="title black--text text-sm-center">
|
|
||||||
{{ jobkinddateitem.job_kind.name }}
|
|
||||||
</div>
|
|
||||||
<v-combobox
|
|
||||||
multiple
|
|
||||||
filled
|
|
||||||
disabled
|
|
||||||
readonly
|
|
||||||
:counter="jobkinddateitem.maxpersons"
|
|
||||||
v-model="jobkinddateitem.worker"
|
|
||||||
:item-text="item => item.firstname + ' ' + item.lastname"
|
|
||||||
item-value="username"
|
|
||||||
chips
|
|
||||||
append-icon=""
|
|
||||||
>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-chip
|
|
||||||
>{{ data.item.firstname }} {{ data.item.lastname }}</v-chip
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</v-combobox>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-expand-transition>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions class="text--secondary" v-if="!day.loading" :key="update">
|
|
||||||
<v-spacer />
|
|
||||||
<v-menu
|
|
||||||
v-model="menu"
|
|
||||||
open-on-hover
|
|
||||||
close-on-click
|
|
||||||
close-on-content-click
|
|
||||||
offset-y
|
|
||||||
>
|
|
||||||
<template v-slot:activator="{ on }">
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
v-on="on"
|
|
||||||
v-show="filterAddJob.length > 0 && !userInWorker() && !day.locked"
|
|
||||||
>
|
|
||||||
Eintragen
|
|
||||||
</v-btn>
|
|
||||||
</template>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item
|
|
||||||
v-for="(jobkinddateitem, index) in filterAddJob"
|
|
||||||
:key="index"
|
|
||||||
@click="addingJob(jobkinddateitem)"
|
|
||||||
>
|
|
||||||
<v-list-item-title>
|
|
||||||
{{ jobkinddateitem.job_kind.name }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-menu>
|
|
||||||
<v-menu v-model="menu_invite" :close-on-content-click="false" offset-y>
|
|
||||||
<template v-slot:activator="{ on }">
|
|
||||||
<v-btn
|
|
||||||
v-show="
|
|
||||||
jobkindWithSpace.length !== 0 && !day.locked && userInWorker()
|
|
||||||
"
|
|
||||||
text
|
|
||||||
v-on="on"
|
|
||||||
>Einladen</v-btn
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
<v-card :loading="jobInvitesLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Einladungen
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-div
|
|
||||||
bottom
|
|
||||||
v-for="(invite, index) in getInvites(day.date)"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<v-chip style="margin: 5px">
|
|
||||||
{{ invite.to_user.firstname }}
|
|
||||||
{{ invite.to_user.lastname }}
|
|
||||||
</v-chip>
|
|
||||||
</v-div>
|
|
||||||
<v-divider style="margin-bottom: 5px" />
|
|
||||||
<v-autocomplete
|
|
||||||
v-model="job_invites"
|
|
||||||
label="Einladungen senden an"
|
|
||||||
return-object
|
|
||||||
multiple
|
|
||||||
filled
|
|
||||||
:item-text="item => item.firstname + ' ' + item.lastname"
|
|
||||||
item-value="id"
|
|
||||||
chips
|
|
||||||
deletable-chips
|
|
||||||
:items="filteredDBUsers()"
|
|
||||||
>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
text
|
|
||||||
:disabled="job_invites.length === 0"
|
|
||||||
@click="sendInvites()"
|
|
||||||
>
|
|
||||||
{{ job_invites.length >= 1 ? 'Einladungen' : 'Einladung' }}
|
|
||||||
senden
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-menu>
|
|
||||||
<v-menu
|
|
||||||
v-model="menu_request"
|
|
||||||
:close-on-content-click="false"
|
|
||||||
offset-y
|
|
||||||
v-if="day.locked && userInWorker()"
|
|
||||||
>
|
|
||||||
<template v-slot:activator="{ on }">
|
|
||||||
<v-btn v-show="day.locked && userInWorker()" text v-on="on">
|
|
||||||
Abgeben
|
|
||||||
</v-btn>
|
|
||||||
</template>
|
|
||||||
<v-card :loading="jobRequestsLoading">
|
|
||||||
<v-card-title>
|
|
||||||
Dienstabgabenanfrage
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<div v-if="jobRequestsLoading">
|
|
||||||
<v-progress-circular indeterminate />
|
|
||||||
</div>
|
|
||||||
<div v-if="!jobRequestsLoading">
|
|
||||||
<v-div
|
|
||||||
bottom
|
|
||||||
v-for="(request, index) in getRequests(day.date)"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<v-chip style="margin: 5px">
|
|
||||||
{{ request.to_user.firstname }}
|
|
||||||
{{ request.to_user.lastname }}
|
|
||||||
</v-chip>
|
|
||||||
</v-div>
|
|
||||||
</div>
|
|
||||||
<v-divider style="margin-bottom: 5px" />
|
|
||||||
<v-autocomplete
|
|
||||||
v-model="job_requests"
|
|
||||||
label="Anfragen senden an"
|
|
||||||
return-object
|
|
||||||
multiple
|
|
||||||
filled
|
|
||||||
:item-text="item => item.firstname + ' ' + item.lastname"
|
|
||||||
item-value="id"
|
|
||||||
chips
|
|
||||||
deletable-chips
|
|
||||||
:items="filteredDBUsersWithJobKind()"
|
|
||||||
>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="sendRequests()">
|
|
||||||
Anfragen
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-menu>
|
|
||||||
<v-btn
|
|
||||||
v-show="!day.locked && userInWorker()"
|
|
||||||
text
|
|
||||||
@click="deletingJob()"
|
|
||||||
>Austragen</v-btn
|
|
||||||
>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiAccountPlus } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'Day',
|
|
||||||
props: {
|
|
||||||
day: Object,
|
|
||||||
long: Boolean,
|
|
||||||
loading: Boolean
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
account_add: mdiAccountPlus,
|
|
||||||
searchInput: null,
|
|
||||||
requestUser: null,
|
|
||||||
menu: false,
|
|
||||||
menu_invite: false,
|
|
||||||
menu_request: false,
|
|
||||||
update: 0,
|
|
||||||
job_invites: [],
|
|
||||||
job_requests: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
//setInterval(() => {console.log(this.day.loading)},100)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({}),
|
|
||||||
sendInvites() {
|
|
||||||
var sendData = []
|
|
||||||
this.job_invites.forEach(item => {
|
|
||||||
sendData.push({
|
|
||||||
from_user: this.activeUser,
|
|
||||||
to_user: item,
|
|
||||||
date: {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.$emit('sendInvites', sendData)
|
|
||||||
setTimeout(() => {
|
|
||||||
this.job_invites = []
|
|
||||||
}, 200)
|
|
||||||
this.menu_invite = false
|
|
||||||
},
|
|
||||||
sendRequests() {
|
|
||||||
var sendData = []
|
|
||||||
this.job_requests.forEach(item => {
|
|
||||||
sendData.push({
|
|
||||||
from_user: this.activeUser,
|
|
||||||
to_user: item,
|
|
||||||
date: {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
},
|
|
||||||
job_kind: this.getJob_Kind()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.$emit('sendRequests', sendData)
|
|
||||||
setTimeout(() => {
|
|
||||||
this.job_requests = []
|
|
||||||
}, 200)
|
|
||||||
this.menu_request = false
|
|
||||||
},
|
|
||||||
color: day => {
|
|
||||||
if (day) {
|
|
||||||
if (day.date.getDay() === 0 || day.date.getDay() === 1) {
|
|
||||||
return 'grey lighten-4'
|
|
||||||
} else {
|
|
||||||
var retVal = 'yellow'
|
|
||||||
retVal = 'light-green'
|
|
||||||
for (var jobkind in day.jobkinddate) {
|
|
||||||
if (
|
|
||||||
day.jobkinddate[jobkind].worker.length >=
|
|
||||||
day.jobkinddate[jobkind].maxpersons
|
|
||||||
)
|
|
||||||
retVal = 'light-green'
|
|
||||||
else return 'yellow'
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 'grey lighten-4'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user(worker) {
|
|
||||||
return worker.username === this.activeUser.username
|
|
||||||
},
|
|
||||||
addingJob(jobkinddateitem) {
|
|
||||||
this.$emit('addingJob', {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate(),
|
|
||||||
job_kind: jobkinddateitem.job_kind
|
|
||||||
})
|
|
||||||
this.menu = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.update += 1
|
|
||||||
}, 200)
|
|
||||||
},
|
|
||||||
deletingJob() {
|
|
||||||
this.$emit('deletingJob', {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.update += 1
|
|
||||||
})
|
|
||||||
},
|
|
||||||
userInWorker() {
|
|
||||||
var jobkinddate = this.day.jobkinddate.find(item => {
|
|
||||||
return item.worker.find(workeritem => {
|
|
||||||
return workeritem.id === this.activeUser.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return !!jobkinddate
|
|
||||||
},
|
|
||||||
deletingInvite(jobInvite) {
|
|
||||||
let sendData = { ...jobInvite }
|
|
||||||
sendData.on_date = {
|
|
||||||
year: sendData.on_date.getFullYear(),
|
|
||||||
month: sendData.on_date.getMonth() + 1,
|
|
||||||
day: sendData.on_date.getDate()
|
|
||||||
}
|
|
||||||
this.$emit('deleteJobInvite', sendData)
|
|
||||||
},
|
|
||||||
deletingRequest(jobRequest) {
|
|
||||||
let sendData = { ...jobRequest }
|
|
||||||
sendData.on_date = {
|
|
||||||
year: sendData.on_date.getFullYear(),
|
|
||||||
month: sendData.on_date.getMonth() + 1,
|
|
||||||
day: sendData.on_date.getDate()
|
|
||||||
}
|
|
||||||
this.$emit('deleteJobRequest', sendData)
|
|
||||||
this.menu_request = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.menu_request = true
|
|
||||||
}, 200)
|
|
||||||
},
|
|
||||||
getJob_Kind() {
|
|
||||||
var jobkinddate = this.day.jobkinddate.find(item => {
|
|
||||||
return item.worker.find(user => {
|
|
||||||
return this.activeUser.id === user.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return jobkinddate.job_kind
|
|
||||||
},
|
|
||||||
filteredDBUsersWithJobKind() {
|
|
||||||
var retVal = this.filteredDBUsers()
|
|
||||||
var job_kind = this.getJob_Kind()
|
|
||||||
|
|
||||||
retVal = retVal.filter(user => {
|
|
||||||
if (job_kind.workgroup ? job_kind.workgroup.if === null : true) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
if (user.workgroups ? user.workgroups.length > 0 : false) {
|
|
||||||
return user.workgroups.find(wg => {
|
|
||||||
return wg.id === job_kind.workgroup.id
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
},
|
|
||||||
filteredDBUsers() {
|
|
||||||
var retVal = this.allUsers.filter(user => {
|
|
||||||
var test = this.day.jobkinddate.find(item => {
|
|
||||||
return item.worker.find(workeritem => {
|
|
||||||
return workeritem.id === user.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return !test
|
|
||||||
})
|
|
||||||
retVal = retVal.filter(user => {
|
|
||||||
let getedDay = this.getDay(this.day.date)
|
|
||||||
let test = getedDay
|
|
||||||
? getedDay.find(day => {
|
|
||||||
return day.to_user.id === user.id
|
|
||||||
})
|
|
||||||
: false
|
|
||||||
return !test
|
|
||||||
})
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
activeUser: 'user/user',
|
|
||||||
allUsers: 'usermanager/users',
|
|
||||||
getDay: 'jobInvites/getDayFromMe',
|
|
||||||
getInvites: 'jobInvites/getDayWorkerFromMe',
|
|
||||||
getRequests: 'jobRequests/getDayWorkerFromMe',
|
|
||||||
jobInvitesLoading: 'jobInvites/jobInvitesLoading',
|
|
||||||
jobRequestsLoading: 'jobRequests/jobRequestsLoading'
|
|
||||||
}),
|
|
||||||
jobkindWithSpace() {
|
|
||||||
var retVal = this.day.jobkinddate.filter(item => {
|
|
||||||
if (item.maxpersons <= item.worker.length) return false
|
|
||||||
else return true
|
|
||||||
})
|
|
||||||
return retVal
|
|
||||||
},
|
|
||||||
filterAddJob() {
|
|
||||||
var retVal = this.day.jobkinddate.filter(item => {
|
|
||||||
if (item.maxpersons <= item.worker.length) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!item.job_kind.workgroup) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
if (this.activeUser.workgroups) {
|
|
||||||
return this.activeUser.workgroups.find(workgroup => {
|
|
||||||
return workgroup.id === item.job_kind.workgroup.id
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return retVal
|
|
||||||
},
|
|
||||||
|
|
||||||
name() {
|
|
||||||
const name = this.day.date.getDay()
|
|
||||||
if (name === 0) return 'Sonntag'
|
|
||||||
else if (name === 1) return 'Montag'
|
|
||||||
else if (name === 2) return 'Dienstag'
|
|
||||||
else if (name === 3) return 'Mittwoch'
|
|
||||||
else if (name == 4) return 'Donnerstag'
|
|
||||||
else if (name === 5) return 'Freitag'
|
|
||||||
else return 'Samstag'
|
|
||||||
},
|
|
||||||
dayLoading() {
|
|
||||||
return this.loading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,55 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-bottom-navigation v-model="bottom_nav">
|
|
||||||
<v-btn :to="{ name: 'jobRequests', params: { kind: 'jobInvites' } }">
|
|
||||||
<v-badge color="red" :content="newsInvite" :value="newsInvite !== 0">
|
|
||||||
Diensteinladungen
|
|
||||||
</v-badge>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn :to="{ name: 'jobRequests', params: { kind: 'jobTransfer' } }">
|
|
||||||
<v-badge color="red" :content="newsRequest" :value="newsRequest !== 0">Dienstübertragung</v-badge>
|
|
||||||
</v-btn>
|
|
||||||
</v-bottom-navigation>
|
|
||||||
<JobInvites v-if="kind === 'jobInvites'"></JobInvites>
|
|
||||||
<JobTransfer v-if="kind === 'jobTransfer'"></JobTransfer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import JobInvites from '@/components/user/JobRequests/JobInvites'
|
|
||||||
import JobTransfer from '@/components/user/JobRequests/JobTransfer'
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'JobsRequest',
|
|
||||||
components: { JobTransfer, JobInvites },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
bottom_nav: true,
|
|
||||||
kind: this.$route.params.kind
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getUser: 'user/getUser',
|
|
||||||
getDBUsers: 'usermanager/getUsers',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
newsInvite: 'jobInvites/news',
|
|
||||||
newsRequest: 'jobRequests/news'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getUser()
|
|
||||||
this.getDBUsers()
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
$route() {
|
|
||||||
this.kind = this.$route.params.kind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,50 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
<v-skeleton-loader type="heading" />
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="10">
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="button" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
<v-col align-self="center">
|
|
||||||
<v-row>
|
|
||||||
<v-list-item>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-list-item>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'AddAmountSkeleton'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-card style="margin-top: 3px">
|
|
||||||
<v-card-title><v-skeleton-loader type="heading"/></v-card-title>
|
|
||||||
<v-container>
|
|
||||||
<v-skeleton-loader type="table-thead" />
|
|
||||||
<v-skeleton-loader type="table-row-divider@3" />
|
|
||||||
</v-container>
|
|
||||||
<v-container fluid>
|
|
||||||
<v-col>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-skeleton-loader type="chip" />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-container>
|
|
||||||
</v-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'CreditOverviewSkeleton'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,107 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item link to="/main/user/add">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ account }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Home</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{ name: 'freedrinkUser' }">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ beer }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Freigetränk buchen</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{ name: 'userOverview' }">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ bank }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Finanzübersicht</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item
|
|
||||||
link
|
|
||||||
:to="{
|
|
||||||
name: 'userJobs',
|
|
||||||
params: {
|
|
||||||
year: new Date().getFullYear(),
|
|
||||||
month: new Date().getMonth() + 1
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ briefcase }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Dienstübersicht</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{ name: 'jobRequests', params: { kind: 'jobInvites' } }">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-badge overlap color="red" :content="news" :value="news !== 0">
|
|
||||||
<v-icon>{{ switchAccount }}</v-icon>
|
|
||||||
</v-badge>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Dienstanfragen</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{ name: 'userConfig' }">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{ account_card_details }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>Einstellung</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
mdiAccountCardDetails,
|
|
||||||
mdiHome,
|
|
||||||
mdiBank,
|
|
||||||
mdiBriefcase,
|
|
||||||
mdiAccountSwitch,
|
|
||||||
mdiBeer
|
|
||||||
} from '@mdi/js'
|
|
||||||
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'UserNavigation',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
account_card_details: mdiAccountCardDetails,
|
|
||||||
account: mdiHome,
|
|
||||||
bank: mdiBank,
|
|
||||||
briefcase: mdiBriefcase,
|
|
||||||
switchAccount: mdiAccountSwitch,
|
|
||||||
beer: mdiBeer
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getJobInvites: 'jobInvites/getJobInvites',
|
|
||||||
getJobRequests: 'jobRequests/getJobRequests',
|
|
||||||
getUser: 'user/getUser'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
newsInvite: 'jobInvites/news',
|
|
||||||
newsRequest: 'jobRequests/news',
|
|
||||||
loading: 'user/loading'
|
|
||||||
}),
|
|
||||||
news() {
|
|
||||||
return this.newsInvite + this.newsRequest
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getUser()
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
loading(newValue) {
|
|
||||||
if (!newValue) {
|
|
||||||
this.getJobInvites()
|
|
||||||
this.getJobRequests()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,474 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-container>
|
|
||||||
<v-card class="mx-auto" outlined v-if="!first_loading" :loading="loading">
|
|
||||||
<v-card-title>
|
|
||||||
<div class="title">Freigetränk für Versammlungen/Arbeit</div>
|
|
||||||
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row v-if="!first_loading">
|
|
||||||
<v-col cols="12">
|
|
||||||
<v-row>
|
|
||||||
<v-col
|
|
||||||
v-for="freeDrink in free_drink_list_config_workgroup"
|
|
||||||
:key="freeDrink.id"
|
|
||||||
cols="6"
|
|
||||||
xs="3"
|
|
||||||
sm="4"
|
|
||||||
class="drinkCol"
|
|
||||||
>
|
|
||||||
<v-btn
|
|
||||||
class="drinkBtn"
|
|
||||||
block
|
|
||||||
:color="color_fix"
|
|
||||||
@click="addAmount(freeDrink, freeDrinkTypeWorkgroup)"
|
|
||||||
>{{ freeDrink.label }}</v-btn
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row v-if="!first_loading" class="justify-end">
|
|
||||||
<v-col cols="3">
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-content class="text-center">
|
|
||||||
<v-list-item-action-text class="title">
|
|
||||||
{{
|
|
||||||
free_drink_list_history_workgroup_without_canceled.length
|
|
||||||
}}
|
|
||||||
Getränke
|
|
||||||
</v-list-item-action-text>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-container>
|
|
||||||
|
|
||||||
<v-navigation-drawer v-model="isMenuShow" right app clipped>
|
|
||||||
<v-list-item-group :key="componentRenderer">
|
|
||||||
<v-list-item inactive>
|
|
||||||
<v-list-item-title class="headline">Verlauf</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider />
|
|
||||||
<div
|
|
||||||
v-for="freeDrinkHistory in free_drink_list_history_workgroup"
|
|
||||||
:key="freeDrinkHistory.id"
|
|
||||||
>
|
|
||||||
<v-list-item
|
|
||||||
three-line
|
|
||||||
inactive
|
|
||||||
@click="canceledAmount(freeDrinkHistory)"
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title>{{
|
|
||||||
now(freeDrinkHistory.timestamp)
|
|
||||||
}}</v-list-item-title>
|
|
||||||
<v-list-item-subtitle>
|
|
||||||
{{ freeDrinkHistory.free_drink_config.label }} wurde für
|
|
||||||
{{
|
|
||||||
(freeDrinkHistory.free_drink_config.price / 100).toFixed(2)
|
|
||||||
}}
|
|
||||||
€ hinzugefügt.
|
|
||||||
</v-list-item-subtitle>
|
|
||||||
<v-list-item-subtitle
|
|
||||||
class="red--text"
|
|
||||||
v-if="freeDrinkHistory.canceled"
|
|
||||||
>STORNIERT!!!</v-list-item-subtitle
|
|
||||||
>
|
|
||||||
<v-list-item-action-text
|
|
||||||
v-if="
|
|
||||||
isStronoEnabled(freeDrinkHistory.timestamp) &&
|
|
||||||
!freeDrinkHistory.canceled
|
|
||||||
"
|
|
||||||
>Klicken um zu Stornieren</v-list-item-action-text
|
|
||||||
>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</div>
|
|
||||||
</v-list-item-group>
|
|
||||||
</v-navigation-drawer>
|
|
||||||
|
|
||||||
<v-dialog v-model="showConfirmCanceledDialog" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Willst du wirklich??</v-card-title>
|
|
||||||
<v-card-text v-if="canceledMessage">
|
|
||||||
{{ canceledMessage.free_drink_type.name }}: Willst du wirklich ein
|
|
||||||
{{ canceledMessage.free_drink_config.label }} im Wert von
|
|
||||||
{{ (canceledMessage.free_drink_config.price / 100).toFixed(2) }} €
|
|
||||||
stornieren?
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancelCanceled">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="acceptCanceled">Stornieren</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<v-dialog v-model="showReasonDialog" max-width="290">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>Willst du wirklich??</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-combobox
|
|
||||||
v-model="selectedReason"
|
|
||||||
:items="free_drink_list_reasons"
|
|
||||||
item-value="id"
|
|
||||||
item-text="name"
|
|
||||||
label="Grund fürs Getränk"
|
|
||||||
></v-combobox>
|
|
||||||
<v-textarea
|
|
||||||
label="Beschreibung"
|
|
||||||
v-model="reasonDescription"
|
|
||||||
></v-textarea>
|
|
||||||
<v-text-field
|
|
||||||
type="number"
|
|
||||||
label="Anzahl der Getränke"
|
|
||||||
v-model="drinkCount"
|
|
||||||
></v-text-field>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="cancelFreedrink">Abbrechen</v-btn>
|
|
||||||
<v-btn text @click="confirmFreeDrink">Bestätigen</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<v-container v-if="first_loading">
|
|
||||||
<AddAmountSkeleton />
|
|
||||||
</v-container>
|
|
||||||
|
|
||||||
<v-snackbar
|
|
||||||
:color="
|
|
||||||
snackbar_messages.length > 0
|
|
||||||
? snackbar_messages[0].error
|
|
||||||
? 'error'
|
|
||||||
: 'success'
|
|
||||||
: 'success'
|
|
||||||
"
|
|
||||||
bottom
|
|
||||||
:timeout="0"
|
|
||||||
:multi-line="true"
|
|
||||||
:value="
|
|
||||||
snackbar_messages.length > 0 ? snackbar_messages[0].visible : null
|
|
||||||
"
|
|
||||||
vertical
|
|
||||||
>
|
|
||||||
<v-list-item
|
|
||||||
v-for="(message, index) in snackbar_messages"
|
|
||||||
:key="index"
|
|
||||||
:style="
|
|
||||||
message.error
|
|
||||||
? 'background-color: #FF5252;'
|
|
||||||
: 'background-color: #4CAF50;'
|
|
||||||
"
|
|
||||||
v-show="message.visible"
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<v-list-item-title style="color: white">
|
|
||||||
{{ createMessage(message) }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
<v-list-item-action v-if="message.error">
|
|
||||||
<v-btn icon @click="message.visible = false">
|
|
||||||
<v-icon color="white">
|
|
||||||
mdi-close
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item-action>
|
|
||||||
</v-list-item>
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
import AddAmountSkeleton from '../Skeleton/AddAmountSkeleton'
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiPlus, mdiMenu } from '@mdi/js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'FreedrinkUserView',
|
|
||||||
components: { AddAmountSkeleton },
|
|
||||||
created() {
|
|
||||||
// this.timer = setInterval(() => (this.componentRenderer += 1), 1000)
|
|
||||||
this.get_free_drink_list_config()
|
|
||||||
this.get_free_drink_list_history()
|
|
||||||
this.get_free_drink_list_reasons()
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
plus: mdiPlus,
|
|
||||||
menuIcon: mdiMenu,
|
|
||||||
locked: false,
|
|
||||||
showConfirmCanceledDialog: false,
|
|
||||||
showReasonDialog: false,
|
|
||||||
customValue: null,
|
|
||||||
color: 'green accent-4',
|
|
||||||
color_fix: 'green accent-4',
|
|
||||||
messages: [],
|
|
||||||
amount: 0,
|
|
||||||
free_drink: null,
|
|
||||||
free_drink_type_id: null,
|
|
||||||
selectedDrink: null,
|
|
||||||
drinkCount: 1,
|
|
||||||
timer: '',
|
|
||||||
componentRenderer: 0,
|
|
||||||
isMenuShow: false,
|
|
||||||
selectedReason: null,
|
|
||||||
reasonDescription: null,
|
|
||||||
freeDrinkTypeWorkgroup: 2,
|
|
||||||
snackbarTimeout: 3000,
|
|
||||||
canceledMessage: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('freeDrinkList', [
|
|
||||||
'get_free_drink_list_config',
|
|
||||||
'get_free_drink_list_history',
|
|
||||||
'get_free_drink_list_reasons',
|
|
||||||
'set_free_drink_list_history',
|
|
||||||
'update_free_drink_list_history'
|
|
||||||
]),
|
|
||||||
getReason() {
|
|
||||||
const reasonArray = []
|
|
||||||
if (!this.user) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.user.group.includes('user')) {
|
|
||||||
reasonArray.push('AG-Besprechung')
|
|
||||||
reasonArray.push('AGDSN')
|
|
||||||
}
|
|
||||||
if (this.user.group.includes('bar')) {
|
|
||||||
reasonArray.push('Dienstantrittsschnaps')
|
|
||||||
}
|
|
||||||
if (this.user.group.includes('vorstand')) {
|
|
||||||
reasonArray.push('Vorstandssitzung')
|
|
||||||
reasonArray.push('Vermietungsgespräch')
|
|
||||||
}
|
|
||||||
if (this.user.group.includes('gastro')) {
|
|
||||||
reasonArray.push('Helmke-Fahrern')
|
|
||||||
reasonArray.push('Vertretergespräch')
|
|
||||||
}
|
|
||||||
|
|
||||||
return reasonArray
|
|
||||||
},
|
|
||||||
addAmount(free_drink, free_drink_type_id) {
|
|
||||||
if (free_drink) {
|
|
||||||
this.showReasonDialog = true
|
|
||||||
this.free_drink = free_drink
|
|
||||||
this.free_drink_type_id = free_drink_type_id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stornoAmount(message) {
|
|
||||||
if (!this.isStronoEnabled(message.date) || message.storno) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showConfirmStornoDialog = true
|
|
||||||
this.stornoMessage = message
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelStorno() {
|
|
||||||
this.showConfirmStornoDialog = null
|
|
||||||
this.stornoMessage = null
|
|
||||||
},
|
|
||||||
|
|
||||||
confirmFreeDrink() {
|
|
||||||
if (this.drinkCount >= 0) {
|
|
||||||
this.set_free_drink_list_history({
|
|
||||||
...this.free_drink,
|
|
||||||
free_drink_type_id: this.free_drink_type_id,
|
|
||||||
free_drink_list_reason_id: this.selectedReason.id,
|
|
||||||
description: this.reasonDescription,
|
|
||||||
count: this.drinkCount
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.cancelFreedrink()
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelFreedrink() {
|
|
||||||
this.showReasonDialog = false
|
|
||||||
this.amount = null
|
|
||||||
this.selectedReason = null
|
|
||||||
this.reasonDescription = null
|
|
||||||
this.drinkCount = 1
|
|
||||||
this.free_drink_type_id = null
|
|
||||||
this.free_drink = null
|
|
||||||
},
|
|
||||||
generateMessage() {
|
|
||||||
this.messages.push({
|
|
||||||
date: new Date(),
|
|
||||||
storno: false,
|
|
||||||
amount: this.amount,
|
|
||||||
reasonDescription: this.reasonDescription,
|
|
||||||
selectedReason: this.selectedReason,
|
|
||||||
drinkCount: this.drinkCount
|
|
||||||
})
|
|
||||||
},
|
|
||||||
createMessage(message) {
|
|
||||||
var text = ''
|
|
||||||
if (message.error) {
|
|
||||||
text =
|
|
||||||
'ERROR: ' +
|
|
||||||
message.free_drink_type.name +
|
|
||||||
': Konnte ' +
|
|
||||||
message.label +
|
|
||||||
' für ' +
|
|
||||||
(message.price / 100).toFixed(2) +
|
|
||||||
'€ nicht hinzufügen.'
|
|
||||||
} else if (message.canceled) {
|
|
||||||
text = `${message.free_drink_type.name}: ${message.label} wurde für ${(message.price/100).toFixed(2)}€ storniert.`
|
|
||||||
} else {
|
|
||||||
text =
|
|
||||||
message.free_drink_type.name +
|
|
||||||
': ' +
|
|
||||||
message.label +
|
|
||||||
' wurde für ' +
|
|
||||||
(message.price / 100).toFixed(2) +
|
|
||||||
'€ hinzugefügt.'
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
},
|
|
||||||
checkLocked() {
|
|
||||||
this.locked = this.limit - this.amount <= 0
|
|
||||||
},
|
|
||||||
getColor() {
|
|
||||||
return this.locked ? 'title red--text' : 'title'
|
|
||||||
},
|
|
||||||
acceptStorno() {
|
|
||||||
this.stornoMessage.storno = true
|
|
||||||
this.amount -= this.stornoMessage.amount
|
|
||||||
console.log(this.amount, this.stornoMessage)
|
|
||||||
this.cancelStorno()
|
|
||||||
},
|
|
||||||
acceptCanceled() {
|
|
||||||
this.canceledMessage.canceled = true
|
|
||||||
this.update_free_drink_list_history(this.canceledMessage)
|
|
||||||
this.cancelCanceled()
|
|
||||||
},
|
|
||||||
canceledAmount(historyElement) {
|
|
||||||
if (!this.isStronoEnabled(historyElement.timestamp)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.showConfirmCanceledDialog = true
|
|
||||||
this.canceledMessage = historyElement
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelCanceled() {
|
|
||||||
this.showConfirmCanceledDialog = null
|
|
||||||
this.canceledMessage = null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
user: 'user/user'
|
|
||||||
}),
|
|
||||||
...mapGetters('freeDrinkList', [
|
|
||||||
'free_drink_list_config_workgroup',
|
|
||||||
'free_drink_list_history',
|
|
||||||
'loading',
|
|
||||||
'free_drink_list_reasons',
|
|
||||||
'free_drink_list_reasons_loading',
|
|
||||||
'free_drink_list_history_workgroup_without_canceled',
|
|
||||||
'free_drink_list_history_workgroup',
|
|
||||||
'snackbar_messages'
|
|
||||||
]),
|
|
||||||
now() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
var zero = new Date(0)
|
|
||||||
var date = new Date(actual - now)
|
|
||||||
if (date.getFullYear() === zero.getFullYear()) {
|
|
||||||
if (date.getMonth() === zero.getMonth()) {
|
|
||||||
if (date.getDate() === zero.getDate()) {
|
|
||||||
if (date.getHours() === zero.getDate()) {
|
|
||||||
if (date.getMinutes() < 1) {
|
|
||||||
return 'vor ' + date.getSeconds() + ' Sekunden'
|
|
||||||
} else if (date.getMinutes() < 10) {
|
|
||||||
return 'vor ' + date.getMinutes() + ' Minuten'
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
now.getDate() +
|
|
||||||
'.' +
|
|
||||||
now.getMonth() +
|
|
||||||
'.' +
|
|
||||||
now.getFullYear() +
|
|
||||||
' ' +
|
|
||||||
(now.getHours() < 10 ? '0' : '') +
|
|
||||||
now.getHours() +
|
|
||||||
':' +
|
|
||||||
(now.getMinutes() < 10 ? '0' : '') +
|
|
||||||
now.getMinutes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isStronoEnabled() {
|
|
||||||
return now => {
|
|
||||||
var actual = new Date()
|
|
||||||
return actual - now < 60000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
first_loading() {
|
|
||||||
return (
|
|
||||||
this.loading &&
|
|
||||||
this.free_drink_list_history.length == 0 &&
|
|
||||||
this.free_drink_list_config_workgroup.length == 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.drinkBtn {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.drinkCol {
|
|
||||||
padding: 6px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: calc(100% - 135px);
|
|
||||||
min-width: 150px;
|
|
||||||
font-size: 1.25rem !important;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 2rem;
|
|
||||||
letter-spacing: 0.0125em !important;
|
|
||||||
font-family: 'Roboto', sans-serif !important;
|
|
||||||
}
|
|
||||||
.menuBtn {
|
|
||||||
right: 15px;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.history-item {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,138 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-bottom-navigation v-model="bottom_nav" horizontal>
|
|
||||||
<v-btn link :to="{ name: 'freeDrinkListMain' }">
|
|
||||||
<span>Übersicht</span>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn link :to="{name: 'freeDrinkListJob'}">
|
|
||||||
<span>Dienstgetränke</span>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn link :to="{name: 'freeDrinkListWorkgroup'}">
|
|
||||||
<span>AG-Getränke</span>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn link :to="{name: 'freeDrinkListBand'}">
|
|
||||||
<span>Bandgetränke</span>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn link :to="{ name: 'freeDrinkListConfig' }">
|
|
||||||
<span>Einstellungen</span>
|
|
||||||
<v-icon>mdi-cogs</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-bottom-navigation>
|
|
||||||
<v-toolbar v-if="$route.name != 'freeDrinkListConfig'" flat dense>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn icon @click="change_month(-1)">
|
|
||||||
<v-icon>mdi-chevron-left</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-item>
|
|
||||||
<v-list-item-title>
|
|
||||||
{{month[date.getMonth()]}} {{date.getFullYear()}}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-item>
|
|
||||||
<v-btn icon @click="change_month(1)">
|
|
||||||
<v-icon>mdi-chevron-right</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
<v-spacer/>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-progress-linear indeterminate v-if="loading" />
|
|
||||||
<div>
|
|
||||||
<router-view />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'FreeDrinkList',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
bottom_nav: true,
|
|
||||||
date: new Date(),
|
|
||||||
month: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.get_free_drink_list_reasons()
|
|
||||||
this.get_free_drink_list_config()
|
|
||||||
this.get_free_drink_list_history_from_to({
|
|
||||||
from_date: {
|
|
||||||
year: this.from_date.getFullYear(),
|
|
||||||
month: this.from_date.getMonth() + 1,
|
|
||||||
day: 1
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.to_date.getFullYear(),
|
|
||||||
month: this.to_date.getMonth() + 1,
|
|
||||||
day: 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.get_free_drink_types()
|
|
||||||
this.getPriceList()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('freeDrinkList', [
|
|
||||||
'get_free_drink_list_config',
|
|
||||||
'get_free_drink_list_history_from_to',
|
|
||||||
'get_free_drink_list_reasons',
|
|
||||||
'get_free_drink_types',
|
|
||||||
]),
|
|
||||||
...mapActions('priceList', ['getPriceList']),
|
|
||||||
change_month(payload) {
|
|
||||||
this.date = new Date(this.date.getFullYear(), this.date.getMonth() + payload, 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', [
|
|
||||||
'free_drink_list_config_loading',
|
|
||||||
'free_drink_list_history_loading',
|
|
||||||
'free_drink_list_reasons_loading',
|
|
||||||
'free_drink_types_loading'
|
|
||||||
]),
|
|
||||||
...mapGetters('priceList', [
|
|
||||||
'priceListLoading'
|
|
||||||
]),
|
|
||||||
to_date() {
|
|
||||||
return new Date(this.date.getFullYear(), this.date.getMonth()+1,1)
|
|
||||||
},
|
|
||||||
from_date() {
|
|
||||||
return new Date(this.date.getFullYear(), this.date.getMonth(), 1)
|
|
||||||
},
|
|
||||||
loading() {
|
|
||||||
return this.free_drink_types_loading || this.free_drink_list_reasons_loading || this.free_drink_list_history_loading || this.free_drink_list_config_loading || this.priceListLoading
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
date() {
|
|
||||||
this.get_free_drink_list_history_from_to({
|
|
||||||
from_date: {
|
|
||||||
year: this.from_date.getFullYear(),
|
|
||||||
month: this.from_date.getMonth() + 1,
|
|
||||||
day: 1
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.to_date.getFullYear(),
|
|
||||||
month: this.to_date.getMonth() + 1,
|
|
||||||
day: 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-row justify="space-around">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{free_drink_list_history_band_without_canceled.length}}
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ (sum/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-row>
|
|
||||||
<v-data-table :headers="header" :items="table"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListBand",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
header: [
|
|
||||||
{
|
|
||||||
text: 'Datum',
|
|
||||||
value: 'date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Label Freigetränk',
|
|
||||||
value: 'label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Freigetränk',
|
|
||||||
value: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Anzahl',
|
|
||||||
value: 'count'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis pro Getränk',
|
|
||||||
value: 'pricepro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis gesamt',
|
|
||||||
value: 'sum'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', ['free_drink_list_history_band_without_canceled', 'free_drink_list_config']),
|
|
||||||
sum() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_band_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
table() {
|
|
||||||
if (this.free_drink_list_history_band_without_canceled.length == 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
let retVal = []
|
|
||||||
const date_month = this.free_drink_list_history_band_without_canceled[0].timestamp
|
|
||||||
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
|
|
||||||
for (let day = 1; day <= days; day++) {
|
|
||||||
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
|
|
||||||
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
|
|
||||||
let history_of_date = this.free_drink_list_history_band_without_canceled.filter(item => {
|
|
||||||
return item.timestamp >= from && item.timestamp <= to && !item.canceled
|
|
||||||
})
|
|
||||||
this.free_drink_list_config.forEach(drink_config => {
|
|
||||||
let history_of_config = history_of_date.filter(item => {
|
|
||||||
return item.free_drink_config_id == drink_config.id
|
|
||||||
})
|
|
||||||
if (history_of_config.length > 0) {
|
|
||||||
retVal.push({
|
|
||||||
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
|
|
||||||
label: drink_config.label,
|
|
||||||
name: drink_config.drink.name,
|
|
||||||
count: history_of_config.length,
|
|
||||||
pricepro: (drink_config.price / 100).toFixed(2),
|
|
||||||
sum: (drink_config.price / 100 * history_of_config.length).toFixed(2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,212 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-card tile>
|
|
||||||
<v-card-title>
|
|
||||||
Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-list>
|
|
||||||
<template
|
|
||||||
v-for="(free_drink_config, index) in free_drink_list_config">
|
|
||||||
<v-list-item
|
|
||||||
:key="free_drink_config.label"
|
|
||||||
dense
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<FreeDrinkListConfigConfigItem :free_drink_config="free_drink_config" @save="save" @delete_free_drink_list_config="delete_free_drink_config" />
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider
|
|
||||||
v-if="(index + 1 < free_drink_list_config.length) || new_free_drink_list_config"
|
|
||||||
:key="index"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<v-list-item v-if="new_free_drink_list_config">
|
|
||||||
<v-list-item-content>
|
|
||||||
<FreeDrinkListConfigConfigItem :free_drink_config="default_model" @save="save" @delete_free_drink_config="new_free_drink_list_config=false"/>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions dense>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn fab small color="success" @click="new_free_drink_list_config=true" v-if="!new_free_drink_list_config">
|
|
||||||
<v-icon>mdi-plus</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
<v-card tile>
|
|
||||||
<v-card-title>Gründe für Freigetränke</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-list>
|
|
||||||
<template
|
|
||||||
v-for="(free_drink_reason, index) in free_drink_list_reasons">
|
|
||||||
<v-list-item
|
|
||||||
:key="free_drink_reason.name"
|
|
||||||
dense
|
|
||||||
>
|
|
||||||
<v-list-item-content>
|
|
||||||
<FreeDrinkListConfigReasonItem :free_drink_reason="free_drink_reason" @save="save_reason" @delete_free_drink_list_reason="delete_free_drink_reason" />
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
<v-divider
|
|
||||||
v-if="(index + 1 < free_drink_list_reasons.length) || new_free_drink_list_reason"
|
|
||||||
:key="index"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<v-list-item v-if="new_free_drink_list_reason">
|
|
||||||
<v-list-item-content>
|
|
||||||
<FreeDrinkListConfigReasonItem :free_drink_reason="default_model_reason" @save="save_reason" @delete_free_drink_reason="new_free_drink_list_reason=false"/>
|
|
||||||
</v-list-item-content>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions dense>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn fab small color="success" @click="new_free_drink_list_reason=true" v-if="!new_free_drink_list_reason">
|
|
||||||
<v-icon>mdi-plus</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
|
|
||||||
<v-dialog v-model="check_delete_free_drink_list_config" max-width="400">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Wirklich löschen?
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
Willst du wirklich <span class="font-weight-black">{{check_model.label}}</span> mit dem Getränk <span class="font-weight-black">{{check_model.drink.name}}</span> löschen?
|
|
||||||
Wenn du dies löscht, wird auch der ganze Verlauf gelöscht. Dh. es ist nicht mehr vollständig nachvollziehbar, was getrunken wurde.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-btn @click="cancel_delete()">Abbrechen</v-btn>
|
|
||||||
<v-btn @click="accept_delete()" color="error">Löschen</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<v-dialog v-model="check_delete_free_drink_list_reason" max-width="400">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Wirklich löschen?
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
Willst du wirklich den Grund <span class="font-weight-black">{{check_model_reason.name}}</span> löschen?
|
|
||||||
Wenn du dies löscht, wird auch der im Verlauf alle dieser Gründe gelöscht.. Dh. es ist nicht mehr vollständig nachvollziehbar, aus welchem Grund ein Freigetränk rausgegeben wurde.
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-btn @click="cancel_delete_reason()">Abbrechen</v-btn>
|
|
||||||
<v-btn @click="accept_delete_reason()" color="error">Löschen</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions} from 'vuex'
|
|
||||||
import FreeDrinkListConfigConfigItem
|
|
||||||
from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfigComponents/FreeDrinkListConfigConfigItem'
|
|
||||||
import FreeDrinkListConfigReasonItem
|
|
||||||
from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfigComponents/FreeDrinkListConfigReasonItem'
|
|
||||||
export default {
|
|
||||||
name: 'FreeDrinkListConfig',
|
|
||||||
components: { FreeDrinkListConfigConfigItem, FreeDrinkListConfigReasonItem },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
new_free_drink_list_config: false,
|
|
||||||
new_free_drink_list_reason: false,
|
|
||||||
default_model: {
|
|
||||||
id: -1,
|
|
||||||
label: null,
|
|
||||||
free_drink_types: null,
|
|
||||||
drink: null,
|
|
||||||
price: null
|
|
||||||
},
|
|
||||||
check_model: {
|
|
||||||
label: null,
|
|
||||||
drink: {name: null}
|
|
||||||
},
|
|
||||||
default_check_model: {
|
|
||||||
label: null,
|
|
||||||
drink: {name: null}
|
|
||||||
},
|
|
||||||
check_delete_free_drink_list_config: false,
|
|
||||||
check_delete_free_drink_list_reason: false,
|
|
||||||
default_model_reason: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
check_model_reason: {
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
default_check_model_reason: {
|
|
||||||
name: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions('freeDrinkList', ['set_free_drink_list_config', 'delete_free_drink_list_config', 'update_free_drink_list_config', 'set_free_drink_list_reason', 'update_free_drink_list_reason', 'delete_free_drink_list_reason']),
|
|
||||||
log() {
|
|
||||||
console.log(this.free_drink_list_config)
|
|
||||||
},
|
|
||||||
reset(free_drink_config) {
|
|
||||||
let data = this.model.find(item => {
|
|
||||||
return item.id == free_drink_config.id
|
|
||||||
})
|
|
||||||
this.set_free_drink_config(data.origin)
|
|
||||||
this.model.splice(this.model.indexOf(data), 1)
|
|
||||||
|
|
||||||
},
|
|
||||||
cancel_delete() {
|
|
||||||
this.check_delete_free_drink_list_config = false
|
|
||||||
this.check_model = Object.assign({}, this.default_check_model)
|
|
||||||
},
|
|
||||||
accept_delete() {
|
|
||||||
this.delete_free_drink_list_config(this.check_model)
|
|
||||||
this.cancel_delete()
|
|
||||||
},
|
|
||||||
delete_free_drink_config(free_drink_config) {
|
|
||||||
Object.assign(this.check_model, free_drink_config)
|
|
||||||
this.check_delete_free_drink_list_config = true
|
|
||||||
console.log(this.check_delete_free_drink_list_config)
|
|
||||||
},
|
|
||||||
save(free_drink_config) {
|
|
||||||
if (free_drink_config.id > 0) {
|
|
||||||
this.update_free_drink_list_config(free_drink_config)
|
|
||||||
} else {
|
|
||||||
this.set_free_drink_list_config(free_drink_config)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
delete_free_drink_reason(free_drink_reason) {
|
|
||||||
Object.assign(this.check_model_reason, free_drink_reason)
|
|
||||||
this.check_delete_free_drink_list_reason = true
|
|
||||||
},
|
|
||||||
save_reason(free_drink_reason) {
|
|
||||||
if (free_drink_reason.id > 0) {
|
|
||||||
this.update_free_drink_list_reason(free_drink_reason)
|
|
||||||
} else {
|
|
||||||
this.set_free_drink_list_reason(free_drink_reason)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancel_delete_reason() {
|
|
||||||
this.check_delete_free_drink_list_reason = false
|
|
||||||
this.check_model_reason = Object.assign({}, this.default_check_model_reason)
|
|
||||||
},
|
|
||||||
accept_delete_reason() {
|
|
||||||
this.delete_free_drink_list_reason(this.check_model_reason)
|
|
||||||
this.cancel_delete_reason()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', [
|
|
||||||
'free_drink_list_config',
|
|
||||||
'free_drink_list_reasons'
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,120 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-form :ref="free_drink_config.id">
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12" sm="6" md="3">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Label"
|
|
||||||
:value="free_drink_config.label"
|
|
||||||
@change="set_model($event, 'label')"
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="3">
|
|
||||||
<v-autocomplete
|
|
||||||
outlined
|
|
||||||
label="Zugeordnetes Getränk"
|
|
||||||
:items="priceList"
|
|
||||||
:item-text="item => {return item.name + '/' + (item.price_club/100).toFixed(2) + '€'}"
|
|
||||||
item-value="id"
|
|
||||||
:value="free_drink_config.drink"
|
|
||||||
@change="set_model($event, 'drink')"
|
|
||||||
return-object
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="3">
|
|
||||||
<v-autocomplete
|
|
||||||
outlined
|
|
||||||
label="Freigetränkaufnahme"
|
|
||||||
multiple
|
|
||||||
:items="free_drink_types"
|
|
||||||
item-text="name"
|
|
||||||
item-value="id"
|
|
||||||
:value="free_drink_config.free_drink_types"
|
|
||||||
return-object
|
|
||||||
@change="set_model($event, 'free_drink_types')"
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" sm="6" md="3">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Preis in €"
|
|
||||||
type="number"
|
|
||||||
:value="(free_drink_config.price/100).toFixed(2)"
|
|
||||||
@change="set_model(Math.round($event*100), 'price')"
|
|
||||||
dense
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-form>
|
|
||||||
<v-row justify="end">
|
|
||||||
<v-btn
|
|
||||||
v-if="free_drink_config.id > 0"
|
|
||||||
icon
|
|
||||||
class="mr-3"
|
|
||||||
@click="$emit('delete_free_drink_list_config', free_drink_config)">
|
|
||||||
<v-icon>mdi-delete</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-else
|
|
||||||
fab
|
|
||||||
color="error"
|
|
||||||
x-small
|
|
||||||
class="mr-4"
|
|
||||||
@click="$emit('delete_free_drink_config')"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-minus</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-if="!is_same || free_drink_config.id < 0"
|
|
||||||
class="mr-3"
|
|
||||||
color="success"
|
|
||||||
@click="() => {$emit('save', model); $emit('delete_free_drink_config'); model = null}"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListConfigConfigItem",
|
|
||||||
props: ['free_drink_config'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
model: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
set_model(event, type) {
|
|
||||||
console.log(!!this.model)
|
|
||||||
if (!this.model) {
|
|
||||||
this.model = Object.assign({}, this.free_drink_config)
|
|
||||||
}
|
|
||||||
if (type == 'drink') {
|
|
||||||
this.model.drink_id = event.id
|
|
||||||
}
|
|
||||||
this.model[type] = event
|
|
||||||
console.log(this.model)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', [
|
|
||||||
'free_drink_types']),
|
|
||||||
...mapGetters('priceList', ["priceList"]),
|
|
||||||
is_same() {
|
|
||||||
console.log(this.model ? 'yo': 'no')
|
|
||||||
return this.model ? JSON.stringify(this.model) == JSON.stringify(this.free_drink_config) : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,70 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Name"
|
|
||||||
:value="free_drink_reason.name"
|
|
||||||
@change="set_model($event)"
|
|
||||||
dense />
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row justify="end">
|
|
||||||
<v-btn
|
|
||||||
v-if="free_drink_reason.id > 0"
|
|
||||||
icon
|
|
||||||
class="mr-3"
|
|
||||||
@click="$emit('delete_free_drink_list_reason', free_drink_reason)">
|
|
||||||
<v-icon>mdi-delete</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-else
|
|
||||||
fab
|
|
||||||
color="error"
|
|
||||||
x-small
|
|
||||||
class="mr-4"
|
|
||||||
@click="$emit('delete_free_drink_reason')"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-minus</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-if="!is_same || free_drink_reason.id < 0"
|
|
||||||
class="mr-3"
|
|
||||||
color="success"
|
|
||||||
@click="() => {$emit('save', model); $emit('delete_free_drink_reason'); model = null}"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListConfigReason",
|
|
||||||
props: ['free_drink_reason'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
model: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
set_model(event) {
|
|
||||||
if (!this.model) {
|
|
||||||
this.model = Object.assign({}, this.free_drink_reason)
|
|
||||||
}
|
|
||||||
this.model.name = event
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
is_same() {
|
|
||||||
return this.model ? JSON.stringify(this.model) == JSON.stringify(this.free_drink_reason): true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-row justify="space-around">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{free_drink_list_history_job_without_canceled.length}}
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ (sum/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-row>
|
|
||||||
<v-data-table :headers="header" :items="table"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListJob",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
header: [
|
|
||||||
{
|
|
||||||
text: 'Datum',
|
|
||||||
value: 'date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Label Freigetränk',
|
|
||||||
value: 'label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Freigetränk',
|
|
||||||
value: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Anzahl',
|
|
||||||
value: 'count'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis pro Getränk',
|
|
||||||
value: 'pricepro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis gesamt',
|
|
||||||
value: 'sum'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', ['free_drink_list_history_job_without_canceled', 'free_drink_list_config']),
|
|
||||||
sum() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_job_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
table() {
|
|
||||||
if (this.free_drink_list_history_job_without_canceled.length == 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
let retVal = []
|
|
||||||
const date_month = this.free_drink_list_history_job_without_canceled[0].timestamp
|
|
||||||
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
|
|
||||||
for (let day = 1; day <= days; day++) {
|
|
||||||
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
|
|
||||||
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
|
|
||||||
let history_of_date = this.free_drink_list_history_job_without_canceled.filter(item => {
|
|
||||||
return item.timestamp >= from && item.timestamp <= to && !item.canceled
|
|
||||||
})
|
|
||||||
this.free_drink_list_config.forEach(drink_config => {
|
|
||||||
let history_of_config = history_of_date.filter(item => {
|
|
||||||
return item.free_drink_config_id == drink_config.id
|
|
||||||
})
|
|
||||||
if (history_of_config.length > 0) {
|
|
||||||
retVal.push({
|
|
||||||
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
|
|
||||||
label: drink_config.label,
|
|
||||||
name: drink_config.drink.name,
|
|
||||||
count: history_of_config.length,
|
|
||||||
pricepro: (drink_config.price / 100).toFixed(2),
|
|
||||||
sum: (drink_config.price / 100 * history_of_config.length).toFixed(2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,166 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-row justify="space-around">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{free_drink_list_history_without_canceled.length}}
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ (sum/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Dienstgetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ free_drink_list_history_job_without_canceled.length }}
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Dienstgetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{(sumJob/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl AG-Getränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ free_drink_list_history_workgroup_without_canceled.length }}
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe AG-Getränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{(sumWorkgroup/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Bandgetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ free_drink_list_history_band_without_canceled.length }}
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Bandgetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{(sumBand/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-row>
|
|
||||||
<v-data-table :headers="header" :items="table"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListMain",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
header: [
|
|
||||||
{
|
|
||||||
text: 'Datum',
|
|
||||||
value: 'date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Label Freigetränk',
|
|
||||||
value: 'label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Freigetränk',
|
|
||||||
value: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Anzahl',
|
|
||||||
value: 'count'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis pro Getränk',
|
|
||||||
value: 'pricepro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis gesamt',
|
|
||||||
value: 'sum'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', ['free_drink_list_history_without_canceled', 'free_drink_list_config', 'free_drink_list_history_job_without_canceled', 'free_drink_list_history_band_without_canceled', 'free_drink_list_history_workgroup_without_canceled']),
|
|
||||||
sum() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
sumJob() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_job_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
sumWorkgroup() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_workgroup_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
sumBand() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_band_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
table() {
|
|
||||||
if (this.free_drink_list_history_without_canceled.length == 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
let retVal = []
|
|
||||||
const date_month = this.free_drink_list_history_without_canceled[0].timestamp
|
|
||||||
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
|
|
||||||
for (let day = 1; day <= days; day++) {
|
|
||||||
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
|
|
||||||
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
|
|
||||||
let history_of_date = this.free_drink_list_history_without_canceled.filter(item => {
|
|
||||||
return item.timestamp >= from && item.timestamp <= to && !item.canceled
|
|
||||||
})
|
|
||||||
this.free_drink_list_config.forEach(drink_config => {
|
|
||||||
let history_of_config = history_of_date.filter(item => {
|
|
||||||
return item.free_drink_config_id == drink_config.id
|
|
||||||
})
|
|
||||||
if (history_of_config.length > 0) {
|
|
||||||
retVal.push({
|
|
||||||
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
|
|
||||||
label: drink_config.label,
|
|
||||||
name: drink_config.drink.name,
|
|
||||||
count: history_of_config.length,
|
|
||||||
pricepro: (drink_config.price/100).toFixed(2),
|
|
||||||
sum: (drink_config.price/100*history_of_config.length).toFixed(2)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,112 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-row justify="space-around">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Anzahl Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{free_drink_list_history_workgroup_without_canceled.length}}
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title class="text-center">
|
|
||||||
Summe Freigetränke
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text class="text-h2 text-center">
|
|
||||||
{{ (sum/100).toFixed(2)}} €
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-row>
|
|
||||||
<v-data-table :headers="header" :items="table"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "FreeDrinkListWorkgroup",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
header: [
|
|
||||||
{
|
|
||||||
text: 'Datum',
|
|
||||||
value: 'date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Label Freigetränk',
|
|
||||||
value: 'label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Freigetränk',
|
|
||||||
value: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'User',
|
|
||||||
value: 'user'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Preis',
|
|
||||||
value: 'pricepro'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Grund',
|
|
||||||
value: 'reason'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Beschreibung',
|
|
||||||
value: 'description'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('freeDrinkList', ['free_drink_list_history_workgroup_without_canceled', 'free_drink_list_config']),
|
|
||||||
sum() {
|
|
||||||
let sum = 0
|
|
||||||
this.free_drink_list_history_workgroup_without_canceled.forEach(item => {
|
|
||||||
sum += item.free_drink_config.price
|
|
||||||
})
|
|
||||||
return sum
|
|
||||||
},
|
|
||||||
table() {
|
|
||||||
if (this.free_drink_list_history_workgroup_without_canceled.length == 0) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
let retVal = []
|
|
||||||
const date_month = this.free_drink_list_history_workgroup_without_canceled[0].timestamp
|
|
||||||
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
|
|
||||||
for (let day = 1; day <= days; day++) {
|
|
||||||
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
|
|
||||||
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
|
|
||||||
let history_of_date = this.free_drink_list_history_workgroup_without_canceled.filter(item => {
|
|
||||||
return item.timestamp >= from && item.timestamp <= to && !item.canceled
|
|
||||||
})
|
|
||||||
this.free_drink_list_config.forEach(drink_config => {
|
|
||||||
let history_of_config = history_of_date.filter(item => {
|
|
||||||
return item.free_drink_config_id == drink_config.id
|
|
||||||
})
|
|
||||||
console.log(history_of_config)
|
|
||||||
history_of_config.forEach(history_config => {
|
|
||||||
retVal.push({
|
|
||||||
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
|
|
||||||
label: drink_config.label,
|
|
||||||
name: drink_config.drink.name,
|
|
||||||
user: `${history_config.user.firstname} ${history_config.user.lastname}`,
|
|
||||||
reason: history_config.free_drink_list_reason ? history_config.free_drink_list_reason.name : null,
|
|
||||||
description: history_config.description,
|
|
||||||
pricepro: (drink_config.price / 100).toFixed(2)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,171 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-data-table
|
|
||||||
:items="jobkinds"
|
|
||||||
:headers="header"
|
|
||||||
:loading="jobkindsLoading || workgroupsLoading"
|
|
||||||
:search="search"
|
|
||||||
>
|
|
||||||
<template v-slot:top>
|
|
||||||
<v-toolbar flat color="white">
|
|
||||||
<v-toolbar-title>
|
|
||||||
Dienstarten
|
|
||||||
</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
label="Suche Dienstart"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
>
|
|
||||||
<template v-slot:append>
|
|
||||||
<v-icon>{{ searchIcon }}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
<v-btn fab small color="primary" @click="add()">
|
|
||||||
<v-icon>{{ plusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.workgroup="{ item }">
|
|
||||||
{{ item.workgroup === null ? 'Alle' : item.workgroup.name }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.actions="{item}">
|
|
||||||
<v-icon x-small @click="editJobKind(item)">{{editIcon}}</v-icon>
|
|
||||||
<v-icon x-small @click="deleteJobKind(item)">{{deleteIcon}}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
<v-dialog v-model="dialog">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
{{ title }}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-text-field outlined label="Name" v-model="editedItem.name" />
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-autocomplete
|
|
||||||
outlined
|
|
||||||
return-object
|
|
||||||
label="Arbeitsgruppe"
|
|
||||||
v-model="editedItem.workgroup"
|
|
||||||
item-text="name"
|
|
||||||
item-value="id"
|
|
||||||
:items="[...workgroups, { id: -1, name: 'Alle' }]"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text color="primary" @click="close()">Abbrechen</v-btn>
|
|
||||||
<v-btn text color="primary" @click="save()">Speichern</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiPencil, mdiDelete, mdiPlus, mdiMagnify } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'JobKindManager',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
search: null,
|
|
||||||
editIcon: mdiPencil,
|
|
||||||
deleteIcon: mdiDelete,
|
|
||||||
plusIcon: mdiPlus,
|
|
||||||
searchIcon: mdiMagnify,
|
|
||||||
dialog: false,
|
|
||||||
header: [
|
|
||||||
{ text: 'Name', value: 'name' },
|
|
||||||
{ text: 'Zugewiesene Arbeitsgruppe', value: 'workgroup' },
|
|
||||||
{
|
|
||||||
text: 'Aktionen',
|
|
||||||
value: 'actions',
|
|
||||||
filterable: false,
|
|
||||||
sortable: false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
editedItem: {
|
|
||||||
id: -1,
|
|
||||||
name: null,
|
|
||||||
workgroup: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defaultItem: {
|
|
||||||
id: -1,
|
|
||||||
name: null,
|
|
||||||
workgroup: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getAllJobKinds: 'jkm/getAllJobKinds',
|
|
||||||
addingJobKind: 'jkm/addJobKind',
|
|
||||||
updateJobKind: 'jkm/updateJobKind',
|
|
||||||
deletingJobKind: 'jkm/deleteJobKind',
|
|
||||||
getAllWorkgroups: 'wm/getAllWorkgroups'
|
|
||||||
}),
|
|
||||||
add() {
|
|
||||||
this.dialog = true
|
|
||||||
},
|
|
||||||
editJobKind(jobkind) {
|
|
||||||
this.dialog = true
|
|
||||||
this.editedItem = Object.assign({}, jobkind)
|
|
||||||
if (this.editedItem.workgroup === null) {
|
|
||||||
this.editedItem.workgroup = Object.assign({}, this.defaultItem.workgroup)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deleteJobKind(jobkind) {
|
|
||||||
confirm('Willst du diese Dienstart wirklich löschen') &&
|
|
||||||
this.deletingJobKind(jobkind)
|
|
||||||
this.close()
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
this.dialog = false
|
|
||||||
}, 200)
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
if (this.editedItem.workgroup.id === -1)
|
|
||||||
this.editedItem.workgroup = null
|
|
||||||
this.editedItem.id === -1
|
|
||||||
? this.addingJobKind(this.editedItem)
|
|
||||||
: this.updateJobKind(this.editedItem)
|
|
||||||
this.close()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
jobkinds: 'jkm/jobkinds',
|
|
||||||
jobkindsLoading: 'jkm/jobkindsLoading',
|
|
||||||
workgroups: 'wm/workgroups',
|
|
||||||
workgroupsLoading: 'wm/workgroupLoading'
|
|
||||||
}),
|
|
||||||
title() {
|
|
||||||
return this.editedItem.id === -1
|
|
||||||
? 'Neue Dienstart erstellen'
|
|
||||||
: 'Dienstart bearbeiten'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getAllJobKinds()
|
|
||||||
this.getAllWorkgroups()
|
|
||||||
console.log(this.jobkinds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-list>
|
|
||||||
<v-list-item link :to="{name: 'serviceManagement', params: {year: new Date().getFullYear(), month: new Date().getMonth() + 1}}"> <v-list-item-icon>
|
|
||||||
<v-icon>{{ work }}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Dienstverwaltung
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{name: 'userManager'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{list}}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Benutzerliste
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{name: 'workgroupManagement'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{group}}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Arbeitsgruppen
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{name: 'jobkindManagement'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>{{jobs}}</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Dienstarten
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item link :to="{name: 'freeDrinkList'}">
|
|
||||||
<v-list-item-icon>
|
|
||||||
<v-icon>mdi-beer</v-icon>
|
|
||||||
</v-list-item-icon>
|
|
||||||
<v-list-item-title>
|
|
||||||
Freigetränke
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiBriefcase, mdiAccountMultiple, mdiAccountGroup, mdiAccountNetwork } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'ManagementNavigation',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
work: mdiBriefcase,
|
|
||||||
list: mdiAccountMultiple,
|
|
||||||
group: mdiAccountGroup,
|
|
||||||
jobs: mdiAccountNetwork
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,169 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-toolbar>
|
|
||||||
<v-toolbar-title>Dienstverwaltung</v-toolbar-title>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn text icon :to="{name: 'serviceManagement', params: {year: date.getFullYear(), month: date.getMonth()}}">
|
|
||||||
<v-icon>{{ keyboard_arrow_left }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-list-item>
|
|
||||||
<v-list-item-title class="title">
|
|
||||||
{{ monthArray[date.getMonth()] }}
|
|
||||||
{{ date.getFullYear() }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-btn text icon :to="{name: 'serviceManagement', params: {year: date.getFullYear(), month: date.getMonth() + 2}}">
|
|
||||||
<v-icon>{{ keyboard_arrow_right }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
<v-spacer />
|
|
||||||
<v-toolbar-items>
|
|
||||||
<v-btn text @click="lockDays(true)">Monat sperren</v-btn>
|
|
||||||
<v-btn text @click="lockDays(false)">Monat freigeben</v-btn>
|
|
||||||
</v-toolbar-items>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-card v-for="week in month" :key="month.indexOf(week)" tile flat>
|
|
||||||
<v-card-title class="subtitle-1 font-weight-bold">
|
|
||||||
Woche vom {{ week.startDate.getDate() }}.{{
|
|
||||||
week.startDate.getMonth() + 1
|
|
||||||
}}.{{ week.startDate.getFullYear() }} bis
|
|
||||||
{{ week.endDate.getDate() }}.{{ week.endDate.getMonth() + 1 }}.{{
|
|
||||||
week.endDate.getFullYear()
|
|
||||||
}}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row justify="start" align="start">
|
|
||||||
<div v-for="day in week.days" :key="day.id">
|
|
||||||
<v-col>
|
|
||||||
<Day v-bind:day="day" />
|
|
||||||
</v-col>
|
|
||||||
</div>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiChevronLeft, mdiChevronRight } from '@mdi/js'
|
|
||||||
import Day from './ServiceManagementComponents/Day'
|
|
||||||
export default {
|
|
||||||
name: 'ServiceManagement',
|
|
||||||
components: { Day },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
keyboard_arrow_left: mdiChevronLeft,
|
|
||||||
keyboard_arrow_right: mdiChevronRight,
|
|
||||||
id: 0,
|
|
||||||
date: new Date(this.$route.params.year, this.$route.params.month -1, 1),
|
|
||||||
monthArray: [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'Juli',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getAllJobKinds()
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getAllUsers()
|
|
||||||
this.getDBUsers()
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
createMonth: 'sm/createMonth',
|
|
||||||
getAllUsers: 'sm/getAllUsers',
|
|
||||||
getUsers: 'sm/getUsers',
|
|
||||||
lockDay: 'sm/lockDay',
|
|
||||||
getDBUsers: 'usermanager/getUsersWithExtern',
|
|
||||||
getAllJobKinds: 'jkm/getAllJobKinds',
|
|
||||||
}),
|
|
||||||
changeMonth(value) {
|
|
||||||
if (value === -1) {
|
|
||||||
this.date = new Date(this.date.getFullYear(), this.date.getMonth() - 1)
|
|
||||||
} else {
|
|
||||||
this.date = new Date(this.date.getFullYear(), this.date.getMonth() + 1)
|
|
||||||
}
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
lockDays(value) {
|
|
||||||
for (var week in this.month) {
|
|
||||||
for (var dayint in this.month[week].days) {
|
|
||||||
var day = this.month[week].days[dayint]
|
|
||||||
this.lockDay({
|
|
||||||
year: day.date.getFullYear(),
|
|
||||||
month: day.date.getMonth() + 1,
|
|
||||||
day: day.date.getDate(),
|
|
||||||
locked: value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
month: 'sm/month',
|
|
||||||
startDate: 'sm/getStartDate',
|
|
||||||
endDate: 'sm/getEndDate'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
$route() {
|
|
||||||
this.date = new Date(this.$route.params.year, this.$route.params.month - 1, 1)
|
|
||||||
this.getAllJobKinds()
|
|
||||||
this.createMonth(this.date)
|
|
||||||
this.getAllUsers()
|
|
||||||
this.getDBUsers()
|
|
||||||
this.getUsers({
|
|
||||||
from_date: {
|
|
||||||
year: this.startDate.getFullYear(),
|
|
||||||
month: this.startDate.getMonth() + 1,
|
|
||||||
day: this.startDate.getDate()
|
|
||||||
},
|
|
||||||
to_date: {
|
|
||||||
year: this.endDate.getFullYear(),
|
|
||||||
month: this.endDate.getMonth() + 1,
|
|
||||||
day: this.endDate.getDate()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,518 +0,0 @@
|
||||||
<template>
|
|
||||||
<div v-if="day">
|
|
||||||
<v-card :color="color(day)" max-width="20em">
|
|
||||||
<v-card-title v-if="day.date" class="subtitle-1 font-weight-bold">
|
|
||||||
{{ day.name }} {{ day.date.getDate() }}.{{ day.date.getMonth() + 1 }}.{{
|
|
||||||
day.date.getFullYear()
|
|
||||||
}}
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn icon small @click="dialog = true">
|
|
||||||
<v-icon>{{ menuIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-expand-transition>
|
|
||||||
<v-row align="center" justify="center" v-if="day.loading">
|
|
||||||
<v-progress-circular indeterminate color="grey" />
|
|
||||||
</v-row>
|
|
||||||
</v-expand-transition>
|
|
||||||
|
|
||||||
<div v-for="(jobkinddateitem, index) in day.jobkinddate" :key="index">
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
jobkinddateitem.job_kind
|
|
||||||
? jobkinddateitem.job_kind.id !== 0
|
|
||||||
: false
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<v-expand-transition>
|
|
||||||
<div v-show="!day.loading">
|
|
||||||
<v-autocomplete
|
|
||||||
chips
|
|
||||||
return-object
|
|
||||||
multiple
|
|
||||||
:counter="jobkinddateitem.maxpersons"
|
|
||||||
v-model="jobkinddateitem.worker"
|
|
||||||
:items="filterUser(jobkinddateitem.job_kind)"
|
|
||||||
:item-text="item => item.firstname + ' ' + item.lastname"
|
|
||||||
:label="jobkinddateitem.job_kind.name"
|
|
||||||
filled
|
|
||||||
color="green"
|
|
||||||
@blur="focused = false"
|
|
||||||
@focus="focused = true"
|
|
||||||
:key="update"
|
|
||||||
@change="forceRenderer(jobkinddateitem)"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend-inner>
|
|
||||||
<v-icon>{{ account_add }}</v-icon>
|
|
||||||
</template>
|
|
||||||
<template v-slot:selection="data">
|
|
||||||
<v-chip
|
|
||||||
v-bind="data.attrs"
|
|
||||||
:input-value="data.selected"
|
|
||||||
close
|
|
||||||
@click="data.select"
|
|
||||||
@click:close="remove(jobkinddateitem, data.item)"
|
|
||||||
>{{ data.item.firstname }} {{ data.item.lastname }}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-autocomplete>
|
|
||||||
</div>
|
|
||||||
</v-expand-transition>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions v-if="!day.loading">
|
|
||||||
<v-chip class="text-uppercase" :color="lockedColor">{{
|
|
||||||
lockedText
|
|
||||||
}}</v-chip>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text @click="lock">{{ lockedTextBtn }}</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
<v-dialog v-model="dialog">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
Bearbeite Tag
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<div>
|
|
||||||
<v-row v-if="!isBarDienstIn">
|
|
||||||
<v-col cols="8">
|
|
||||||
<v-text-field readonly outlined value="Bardienst" />
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="2">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Maximale Personen"
|
|
||||||
type="number"
|
|
||||||
v-model="maxpersons"
|
|
||||||
@change="createBarJobKindDate(maxpersons)"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="2"> </v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row
|
|
||||||
v-for="(jobkinddateitem, index) in day.jobkinddate"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<v-col cols="8">
|
|
||||||
<v-text-field
|
|
||||||
v-if="!jobkinddateitem.new"
|
|
||||||
readonly
|
|
||||||
outlined
|
|
||||||
:value="jobkinddateitem.job_kind.name"
|
|
||||||
/>
|
|
||||||
<v-autocomplete
|
|
||||||
v-else
|
|
||||||
outlined
|
|
||||||
:items="filterJobKinds(jobkinddateitem, index)"
|
|
||||||
:rules="rules"
|
|
||||||
item-text="name"
|
|
||||||
item-value="id"
|
|
||||||
v-model="jobkinddateitem.job_kind"
|
|
||||||
return-object
|
|
||||||
></v-autocomplete>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="2">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
label="Maximale Personen"
|
|
||||||
type="number"
|
|
||||||
v-model="jobkinddateitem.maxpersons"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="2">
|
|
||||||
<div v-if="jobkinddateitem.job_kind !== null">
|
|
||||||
<div v-if="jobkinddateitem.job_kind.id !== 1">
|
|
||||||
<v-btn
|
|
||||||
v-if="jobkinddateitem.id === 0"
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="green"
|
|
||||||
@click="undoDelteJobKindDate(index)"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-else
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="red"
|
|
||||||
@click="deleteJobKindDate(index)"
|
|
||||||
>
|
|
||||||
<v-icon>{{ minusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<v-btn
|
|
||||||
v-if="jobkinddateitem.id === 0"
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="green"
|
|
||||||
@click="undoDelteJobKindDate(index)"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-else
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="red"
|
|
||||||
@click="deleteJobKindDate(index)"
|
|
||||||
>
|
|
||||||
<v-icon>{{ minusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
</v-col>
|
|
||||||
<v-row v-if="jobkinddateitem.id === 0">
|
|
||||||
<v-col>
|
|
||||||
<v-alert dense type="info"
|
|
||||||
>{{ jobkinddateitem.job_kind.name }} wird beim Speichern
|
|
||||||
gelöscht.</v-alert
|
|
||||||
>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-row>
|
|
||||||
</div>
|
|
||||||
<v-row>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn
|
|
||||||
fab
|
|
||||||
small
|
|
||||||
color="green darken-1"
|
|
||||||
@click="addJobKindDate()"
|
|
||||||
:disabled="disableAddBtn"
|
|
||||||
>
|
|
||||||
<v-icon>{{ plusIcon }}</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn text color="primary" @click="dialog = false">
|
|
||||||
Abbrechen
|
|
||||||
</v-btn>
|
|
||||||
<v-btn text color="primary" @click="saveJobKind()">
|
|
||||||
Speichern
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
|
||||||
import { mdiAccountPlus, mdiDotsVertical, mdiPlus, mdiMinus } from '@mdi/js'
|
|
||||||
export default {
|
|
||||||
name: 'Day',
|
|
||||||
props: {
|
|
||||||
day: Object
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
account_add: mdiAccountPlus,
|
|
||||||
menuIcon: mdiDotsVertical,
|
|
||||||
plusIcon: mdiPlus,
|
|
||||||
minusIcon: mdiMinus,
|
|
||||||
searchInput: null,
|
|
||||||
focused: false,
|
|
||||||
dialog: false,
|
|
||||||
update: 0,
|
|
||||||
maxpersons: 2,
|
|
||||||
rules: [
|
|
||||||
data => {
|
|
||||||
if (data === null) return false
|
|
||||||
var list = this.day.jobkinddate.filter(a => {
|
|
||||||
if (a.job_kind === null) return false
|
|
||||||
else {
|
|
||||||
return a.job_kind.id === data.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return list.length > 1 ? data.name + 'ist schon vorhanden' : false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
backup: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.setLoading(this.day.date)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
addUser: 'sm/addUser',
|
|
||||||
deleteUser: 'sm/deleteUser',
|
|
||||||
setLoading: 'sm/setDayLoading',
|
|
||||||
setNotLoading: 'sm/setDayNotLoading',
|
|
||||||
lockDay: 'sm/lockDay',
|
|
||||||
updateJobKindDate: 'sm/updateJobKindDate'
|
|
||||||
}),
|
|
||||||
forceRenderer(jobkind) {
|
|
||||||
this.update += 1
|
|
||||||
if (jobkind.backupWorker !== jobkind.worker && this.focused) {
|
|
||||||
let addedUser = null
|
|
||||||
for (let user in jobkind.worker) {
|
|
||||||
if (!jobkind.backupWorker.includes(jobkind.worker[user])) {
|
|
||||||
addedUser = jobkind.worker[user]
|
|
||||||
this.addUser({
|
|
||||||
date: this.day.date.getTime() / 1000,
|
|
||||||
user: addedUser,
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate(),
|
|
||||||
job_kind: jobkind.job_kind
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let deletedUser = null
|
|
||||||
for (let user in jobkind.backupWorker) {
|
|
||||||
if (!jobkind.worker.includes(jobkind.backupWorker[user])) {
|
|
||||||
deletedUser = jobkind.backupWorker[user]
|
|
||||||
this.deleteUser({
|
|
||||||
startdatetime: this.day.date,
|
|
||||||
date: this.day.date.getTime() / 1000,
|
|
||||||
user: deletedUser,
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jobkind.backupWorker = [...jobkind.worker]
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
remove(jobkind, deletedUser) {
|
|
||||||
jobkind.worker.indexOf()
|
|
||||||
const obj = jobkind.worker.find(a => {
|
|
||||||
return a.username === deletedUser.username
|
|
||||||
})
|
|
||||||
const index = jobkind.worker.indexOf(obj)
|
|
||||||
if (index >= 0) jobkind.worker.splice(index, 1)
|
|
||||||
this.forceRenderer(jobkind)
|
|
||||||
},
|
|
||||||
color(day) {
|
|
||||||
if (day) {
|
|
||||||
if (day.date.getDay() === 0 || day.date.getDay() === 1) {
|
|
||||||
return 'grey lighten-4'
|
|
||||||
} else {
|
|
||||||
var retVal = 'yellow'
|
|
||||||
retVal = 'light-green'
|
|
||||||
for (var jobkind in day.jobkinddate) {
|
|
||||||
if (
|
|
||||||
day.jobkinddate[jobkind].worker.length >=
|
|
||||||
day.jobkinddate[jobkind].maxpersons
|
|
||||||
)
|
|
||||||
retVal = 'light-green'
|
|
||||||
else return 'yellow'
|
|
||||||
}
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 'grey lighten-4'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lock() {
|
|
||||||
this.lockDay({
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate(),
|
|
||||||
locked: !this.day.locked
|
|
||||||
})
|
|
||||||
},
|
|
||||||
createBarJobKindDate(maxpersons) {
|
|
||||||
this.day.jobkinddate.push({
|
|
||||||
id: -1,
|
|
||||||
job_kind: Object.assign(
|
|
||||||
{},
|
|
||||||
this.jobkinds.find(a => {
|
|
||||||
return a.id === 1
|
|
||||||
})
|
|
||||||
),
|
|
||||||
maxpersons: maxpersons,
|
|
||||||
daydate: {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
},
|
|
||||||
worker: [],
|
|
||||||
backupWorker: []
|
|
||||||
})
|
|
||||||
},
|
|
||||||
addJobKindDate() {
|
|
||||||
this.day.jobkinddate.push({
|
|
||||||
id: -1,
|
|
||||||
job_kind: null,
|
|
||||||
maxpersons: 2,
|
|
||||||
new: true,
|
|
||||||
daydate: {
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
},
|
|
||||||
worker: [],
|
|
||||||
backupWorker: []
|
|
||||||
})
|
|
||||||
},
|
|
||||||
mop(jobkind) {
|
|
||||||
console.log(jobkind.worker)
|
|
||||||
},
|
|
||||||
deleteJobKindDate(index) {
|
|
||||||
if (this.day.jobkinddate[index].id === -1) {
|
|
||||||
this.day.jobkinddate.splice(index, 1)
|
|
||||||
} else {
|
|
||||||
this.day.jobkinddate[index].backupid = this.day.jobkinddate[index].id
|
|
||||||
this.day.jobkinddate[index].id = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
undoDelteJobKindDate(index) {
|
|
||||||
this.day.jobkinddate[index].id = this.day.jobkinddate[index].backupid
|
|
||||||
},
|
|
||||||
saveJobKind() {
|
|
||||||
this.updateJobKindDate({
|
|
||||||
data: this.day.jobkinddate,
|
|
||||||
date: this.day.date
|
|
||||||
})
|
|
||||||
this.dialog = false
|
|
||||||
},
|
|
||||||
|
|
||||||
filterUser(jobkind) {
|
|
||||||
var filtered = this.dbUsers.filter(user => {
|
|
||||||
var userInOther = this.day.jobkinddate.find(item => {
|
|
||||||
if (item.job_kind === null) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (item.job_kind.id === jobkind.id) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return item.worker.find(work => {
|
|
||||||
return work.id === user.id
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if (userInOther) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (jobkind.id === 1 || !jobkind.workgroup) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
if (user.workgroups ? user.workgroups.length > 0 : false) {
|
|
||||||
return user.workgroups.find(wg => {
|
|
||||||
return wg.id === jobkind.workgroup.id
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return filtered
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
filterJobKinds(jobkinddateitem, index) {
|
|
||||||
var retVal = this.jobkinds.filter(jobkind => {
|
|
||||||
return jobkind.id !== 1
|
|
||||||
})
|
|
||||||
retVal = retVal.filter(jobkind => {
|
|
||||||
return !this.day.jobkinddate.find(item => {
|
|
||||||
if (item.job_kind === jobkinddateitem.job_kind) {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
if (item.job_kind !== null && jobkind !== null)
|
|
||||||
if (item.job_kind.id === jobkind.id) return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return retVal
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
allUsers: 'sm/allUsers',
|
|
||||||
dbUsers: 'usermanager/users',
|
|
||||||
disabled: 'sm/disabled',
|
|
||||||
jobkinds: 'jkm/jobkinds'
|
|
||||||
}),
|
|
||||||
worker() {
|
|
||||||
return this.day.worker
|
|
||||||
},
|
|
||||||
tada() {
|
|
||||||
return this.day.jobkinddate
|
|
||||||
},
|
|
||||||
lockedColor() {
|
|
||||||
return this.day.locked ? 'red' : 'green'
|
|
||||||
},
|
|
||||||
lockedText() {
|
|
||||||
return this.day.locked ? 'gesperrt' : 'frei'
|
|
||||||
},
|
|
||||||
lockedTextBtn() {
|
|
||||||
return this.day.locked ? 'freigeben' : 'sperren'
|
|
||||||
},
|
|
||||||
isBarDienstIn() {
|
|
||||||
for (var jobkinddate in this.day.jobkinddate) {
|
|
||||||
if (!(this.day.jobkinddate[jobkinddate].job_kind === null))
|
|
||||||
if (this.day.jobkinddate[jobkinddate].job_kind.id === 1) return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
existJobKinds() {
|
|
||||||
var retVal = [...this.jobkinds]
|
|
||||||
retVal.splice(
|
|
||||||
retVal.findIndex(a => {
|
|
||||||
return a.id === 1
|
|
||||||
}),
|
|
||||||
1
|
|
||||||
)
|
|
||||||
return retVal
|
|
||||||
},
|
|
||||||
disableAddBtn() {
|
|
||||||
var barset = this.isBarDienstIn ? 0 : 1
|
|
||||||
return this.day.jobkinddate.length === this.jobkinds.length - barset
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
worker(newValue, oldValue) {
|
|
||||||
if (oldValue !== newValue && this.focused) {
|
|
||||||
let addedUser = null
|
|
||||||
for (let user in newValue) {
|
|
||||||
if (!oldValue.includes(newValue[user])) {
|
|
||||||
addedUser = newValue[user]
|
|
||||||
this.addUser({
|
|
||||||
date: this.day.date.getTime() / 1000,
|
|
||||||
user: addedUser,
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let deletedUser = null
|
|
||||||
for (let user in oldValue) {
|
|
||||||
if (!newValue.includes(oldValue[user])) {
|
|
||||||
deletedUser = oldValue[user]
|
|
||||||
this.deleteUser({
|
|
||||||
startdatetime: this.day.date,
|
|
||||||
date: this.day.date.getTime() / 1000,
|
|
||||||
user: deletedUser,
|
|
||||||
year: this.day.date.getFullYear(),
|
|
||||||
month: this.day.date.getMonth() + 1,
|
|
||||||
day: this.day.date.getDate()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dialog(newValue) {
|
|
||||||
if (newValue) {
|
|
||||||
this.backup = [...this.day.jobkinddate]
|
|
||||||
} else {
|
|
||||||
this.day.jobkinddate = [...this.backup]
|
|
||||||
this.backup = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,320 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-dialog v-model="editUser">
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
{{
|
|
||||||
this.editedItem.firstname +
|
|
||||||
' ' +
|
|
||||||
this.editedItem.lastname +
|
|
||||||
' bearbeiten'
|
|
||||||
}}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-container>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-autocomplete
|
|
||||||
v-model="editedItem.statusgroup"
|
|
||||||
label="Status"
|
|
||||||
outlined
|
|
||||||
:items="status"
|
|
||||||
item-value="id"
|
|
||||||
item-text="name"
|
|
||||||
return-object
|
|
||||||
@change="clickItem(editedItem.statusgroup)"
|
|
||||||
>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-col>
|
|
||||||
<v-col>
|
|
||||||
<v-autocomplete
|
|
||||||
v-model="editedItem.voting"
|
|
||||||
label="Stimmrecht"
|
|
||||||
outlined
|
|
||||||
:items="[
|
|
||||||
{ value: true, text: 'ja' },
|
|
||||||
{ value: false, text: 'nein' }
|
|
||||||
]"
|
|
||||||
item-text="text"
|
|
||||||
item-value="value"
|
|
||||||
:disabled="disableVoting"
|
|
||||||
return-object
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
<v-row>
|
|
||||||
<v-col>
|
|
||||||
<v-autocomplete
|
|
||||||
chips
|
|
||||||
multiple
|
|
||||||
v-model="editedItem.workgroups"
|
|
||||||
label="AG's"
|
|
||||||
outlined
|
|
||||||
:items="workgroups"
|
|
||||||
item-value="id"
|
|
||||||
item-text="name"
|
|
||||||
return-object
|
|
||||||
></v-autocomplete>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer />
|
|
||||||
<v-btn color="primary" text @click="close()">Abbrechen</v-btn>
|
|
||||||
<v-btn color="primary" text @click="save()">Speichern</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
<v-data-table
|
|
||||||
:headers="header"
|
|
||||||
:items="users"
|
|
||||||
:search="search"
|
|
||||||
:loading="usersLoading || statusLoading"
|
|
||||||
:items-per-page="100"
|
|
||||||
>
|
|
||||||
<template v-slot:top>
|
|
||||||
<v-toolbar flat color="white">
|
|
||||||
<v-toolbar-title>Mitgliederliste</v-toolbar-title>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
label="Sucher Mitglied"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
>
|
|
||||||
<template v-slot:append>
|
|
||||||
<v-icon>{{ searchIcon }}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
</v-toolbar>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.workgroups="{ item }">
|
|
||||||
<div>
|
|
||||||
<v-chip v-for="group in item.workgroups" :key="group.id" x-small>
|
|
||||||
{{ group.name }}
|
|
||||||
</v-chip>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.statusgroup="{ item }">
|
|
||||||
{{ computeStatus(item.statusgroup) }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.voting="{ item }">
|
|
||||||
<v-chip small :color="item.voting ? 'green' : 'red'">
|
|
||||||
{{ item.voting ? 'ja' : 'nein' }}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.actions="{ item }">
|
|
||||||
<v-icon small @click="editItem(item)">{{ editIcon }}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
<v-divider />
|
|
||||||
<v-card>
|
|
||||||
<v-card-text>
|
|
||||||
<v-container>
|
|
||||||
<v-row>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
:value="users.length"
|
|
||||||
label="Anzahl aller Mitglieder"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
:value="allActiveUsers"
|
|
||||||
label="Anzahl aller aktiven Mitglieder"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col v-bind:class="{ fulllineText: isFulllineText }">
|
|
||||||
<v-text-field
|
|
||||||
outlined
|
|
||||||
:value="allVotings"
|
|
||||||
label="Anzahl aller Stimmberechtigten"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiPencil, mdiMagnify } from '@mdi/js'
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'UserManager',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
editIcon: mdiPencil,
|
|
||||||
searchIcon: mdiMagnify,
|
|
||||||
isFulllineText: false,
|
|
||||||
editUser: false,
|
|
||||||
disableVoting: null,
|
|
||||||
search: null,
|
|
||||||
header: [
|
|
||||||
{ text: 'Nachname', value: 'lastname' },
|
|
||||||
{ text: 'Vorname(n)', value: 'firstname' },
|
|
||||||
{ text: "AG's", value: 'workgroups' },
|
|
||||||
{ text: 'Status', value: 'statusgroup' },
|
|
||||||
{ text: 'Stimmrecht', value: 'voting' },
|
|
||||||
{
|
|
||||||
text: 'Aktionen',
|
|
||||||
value: 'actions',
|
|
||||||
sortable: false,
|
|
||||||
filterable: false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
editedItem: {
|
|
||||||
id: -1,
|
|
||||||
firstname: null,
|
|
||||||
lastname: null,
|
|
||||||
username: null,
|
|
||||||
workgroups: [],
|
|
||||||
statusgroup: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
voting: {
|
|
||||||
value: false,
|
|
||||||
text: 'nein'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defaultItem: {
|
|
||||||
id: -1,
|
|
||||||
username: null,
|
|
||||||
workgroups: [],
|
|
||||||
statusgroup: {
|
|
||||||
id: -1,
|
|
||||||
name: null
|
|
||||||
},
|
|
||||||
voting: {
|
|
||||||
value: false,
|
|
||||||
text: 'nein'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.$nextTick(function() {
|
|
||||||
window.addEventListener('resize', this.getWindowWidth)
|
|
||||||
this.getWindowWidth()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getUsers: 'usermanager/getUsers',
|
|
||||||
getStatus: 'usermanager/getStatus',
|
|
||||||
updateStatusUser: 'usermanager/updateStatusUser',
|
|
||||||
updateVoting: 'usermanager/updateVoting',
|
|
||||||
updateWorkgroups: 'usermanager/updateWorkgroups',
|
|
||||||
getAllWorkgroups: 'wm/getAllWorkgroups'
|
|
||||||
}),
|
|
||||||
getWindowWidth() {
|
|
||||||
this.isFulllineText = document.documentElement.clientWidth <= 750
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.editUser = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
editItem(item) {
|
|
||||||
this.editedItem = Object.assign({}, item)
|
|
||||||
this.editedItem.statusgroup = Object.assign(
|
|
||||||
{},
|
|
||||||
this.status.find(a => a.id == item.statusgroup)
|
|
||||||
)
|
|
||||||
this.editedItem.voting = Object.assign(
|
|
||||||
{},
|
|
||||||
item.voting
|
|
||||||
? { value: true, text: 'ja' }
|
|
||||||
: { value: false, text: 'nein' }
|
|
||||||
)
|
|
||||||
this.clickItem(this.editedItem.statusgroup)
|
|
||||||
this.editUser = true
|
|
||||||
},
|
|
||||||
clickItem(item) {
|
|
||||||
switch (item.id) {
|
|
||||||
case 1:
|
|
||||||
this.editedItem.voting = { value: true, text: 'ja' }
|
|
||||||
this.disableVoting = true
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
this.disableVoting = false
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
this.disableVoting = true
|
|
||||||
this.editedItem.voting = { value: false, text: 'nein' }
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
this.editedItem.voting = { value: false, text: 'nein' }
|
|
||||||
this.disableVoting = true
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
this.editedItem.voting = { value: false, text: 'nein' }
|
|
||||||
this.disableVoting = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.updateStatusUser({
|
|
||||||
username: this.editedItem.username,
|
|
||||||
status: this.editedItem.statusgroup
|
|
||||||
})
|
|
||||||
this.updateVoting({
|
|
||||||
username: this.editedItem.username,
|
|
||||||
voting: this.editedItem.voting.value
|
|
||||||
})
|
|
||||||
this.updateWorkgroups(this.editedItem)
|
|
||||||
this.close()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
users: 'usermanager/users',
|
|
||||||
status: 'usermanager/status',
|
|
||||||
usersLoading: 'usermanager/usersLoading',
|
|
||||||
statusLoading: 'usermanager/statusLoading',
|
|
||||||
workgroups: 'wm/workgroups'
|
|
||||||
}),
|
|
||||||
computeStatus() {
|
|
||||||
return id => {
|
|
||||||
let status = this.status.find(a => {
|
|
||||||
return a.id === id
|
|
||||||
})
|
|
||||||
return status ? status.name : null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
allVotings() {
|
|
||||||
return this.users.filter(a => {
|
|
||||||
return a.voting
|
|
||||||
}).length
|
|
||||||
},
|
|
||||||
|
|
||||||
allActiveUsers() {
|
|
||||||
return this.users.filter(a => {
|
|
||||||
return a.statusgroup === 1
|
|
||||||
}).length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getUsers()
|
|
||||||
this.getStatus()
|
|
||||||
this.getAllWorkgroups()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.fulllineText {
|
|
||||||
flex-basis: unset;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,190 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<v-data-table
|
|
||||||
:headers="header"
|
|
||||||
:items="workgroups"
|
|
||||||
:loading="workgroupLoading"
|
|
||||||
:search="search"
|
|
||||||
>
|
|
||||||
<template v-slot:top>
|
|
||||||
<v-toolbar flat color="white">
|
|
||||||
<v-toolbar-title>Arbeitsgruppen</v-toolbar-title>
|
|
||||||
<v-spacer> </v-spacer>
|
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
label="Suche Arbeitsgrupp"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
>
|
|
||||||
<template v-slot:append>
|
|
||||||
<v-icon>{{ searchIcon }}</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
<v-dialog v-model="dialog">
|
|
||||||
<template v-slot:activator="{ on }">
|
|
||||||
<v-btn
|
|
||||||
fab
|
|
||||||
x-small
|
|
||||||
color="primary"
|
|
||||||
class="mb-2"
|
|
||||||
v-on="on"
|
|
||||||
style="margin: 5px"
|
|
||||||
>
|
|
||||||
<v-icon>
|
|
||||||
{{ plusIcon }}
|
|
||||||
</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</template>
|
|
||||||
<v-card>
|
|
||||||
<v-card-title>
|
|
||||||
<span class="headline">{{ formTitle }}</span>
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-container>
|
|
||||||
<v-text-field
|
|
||||||
v-model="editedItem.name"
|
|
||||||
label="Name"
|
|
||||||
outlined
|
|
||||||
></v-text-field>
|
|
||||||
<v-autocomplete
|
|
||||||
v-model="editedItem.boss"
|
|
||||||
label="AG-Leiter"
|
|
||||||
:items="users"
|
|
||||||
:item-text="item => item.firstname + ' ' + item.lastname"
|
|
||||||
item-value="username"
|
|
||||||
:loading="usersLoading"
|
|
||||||
outlined
|
|
||||||
return-object
|
|
||||||
>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-container>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn color="blue darken-1" text @click="close"
|
|
||||||
>Abbreche</v-btn
|
|
||||||
>
|
|
||||||
<v-btn color="blue darken-1" text @click="save"
|
|
||||||
>Speichern</v-btn
|
|
||||||
>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</v-toolbar>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.boss="{ item }">
|
|
||||||
<div v-if="item.boss != null">
|
|
||||||
{{ item.boss.firstname }} {{ item.boss.lastname }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-slot:item.actions="{ item }">
|
|
||||||
<v-icon small class="mr-2" @click="editItem(item)">
|
|
||||||
{{ editIcon }}
|
|
||||||
</v-icon>
|
|
||||||
<v-icon small class="mr-2" @click="deleteItem(item)">
|
|
||||||
{{ deleteIcon }}
|
|
||||||
</v-icon>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mdiPencil, mdiMagnify, mdiDelete, mdiPlus } from '@mdi/js'
|
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'WorkgroupManagement',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
editIcon: mdiPencil,
|
|
||||||
searchIcon: mdiMagnify,
|
|
||||||
deleteIcon: mdiDelete,
|
|
||||||
plusIcon: mdiPlus,
|
|
||||||
search: null,
|
|
||||||
dialog: false,
|
|
||||||
header: [
|
|
||||||
{ text: 'AG-Name', value: 'name' },
|
|
||||||
{ text: 'AG-Leiter', value: 'boss' },
|
|
||||||
{
|
|
||||||
text: 'Aktionen',
|
|
||||||
value: 'actions',
|
|
||||||
sortable: false,
|
|
||||||
filterable: false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
editedItem: {
|
|
||||||
id: -1,
|
|
||||||
username: null,
|
|
||||||
boss: {
|
|
||||||
username: null,
|
|
||||||
firstname: null,
|
|
||||||
lastname: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defaultItem: {
|
|
||||||
id: -1,
|
|
||||||
username: null,
|
|
||||||
boss: {
|
|
||||||
name: null,
|
|
||||||
firstname: null,
|
|
||||||
lastname: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editedIndex: -1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions({
|
|
||||||
getAllWorkgroups: 'wm/getAllWorkgroups',
|
|
||||||
setWorkgroup: 'wm/setWorkgroup',
|
|
||||||
updateWorkgroup: 'wm/updateWorkgroup',
|
|
||||||
getAllUsers: 'usermanager/getUsers',
|
|
||||||
deleteWorkgroup: 'wm/deleteWorkgroup'
|
|
||||||
}),
|
|
||||||
editItem(item) {
|
|
||||||
this.editedIndex = item.id
|
|
||||||
this.editedItem = Object.assign({}, item)
|
|
||||||
this.dialog = true
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.editedItem.id === -1
|
|
||||||
? this.setWorkgroup(this.editedItem)
|
|
||||||
: this.updateWorkgroup(this.editedItem)
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
this.close()
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.dialog = false
|
|
||||||
setTimeout(() => {
|
|
||||||
this.editedItem = Object.assign({}, this.defaultItem)
|
|
||||||
this.editedIndex = -1
|
|
||||||
}, 300)
|
|
||||||
},
|
|
||||||
deleteItem(item) {
|
|
||||||
confirm(
|
|
||||||
'Bist du sicher, dass du diese Arbeitsgruppe entfernen willst?'
|
|
||||||
) && this.deleteWorkgroup(item)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
workgroupLoading: 'wm/workgroupLoading',
|
|
||||||
workgroups: 'wm/workgroups',
|
|
||||||
users: 'usermanager/users',
|
|
||||||
usersLoading: 'usermanager/usersLoading'
|
|
||||||
}),
|
|
||||||
formTitle() {
|
|
||||||
return this.editedIndex === -1
|
|
||||||
? 'Neue Arbeitsgruppe'
|
|
||||||
: 'Bearbeite Arbeitsgruppe'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getAllWorkgroups()
|
|
||||||
this.getAllUsers()
|
|
||||||
console.log(this.users)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -0,0 +1 @@
|
||||||
|
// app global css in SCSS form
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Quasar SCSS (& Sass) Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
// To customize the look and feel of this app, you can override
|
||||||
|
// the Sass/SCSS variables found in Quasar's source Sass/SCSS files.
|
||||||
|
|
||||||
|
// Check documentation for full list of Quasar variables
|
||||||
|
|
||||||
|
// Your own variables (that are declared here) and Quasar's own
|
||||||
|
// ones will be available out of the box in your .vue/.scss/.sass files
|
||||||
|
|
||||||
|
// It's highly recommended to change the default colors
|
||||||
|
// to match your app's branding.
|
||||||
|
// Tip: Use the "Theme Builder" on Quasar's documentation website.
|
||||||
|
|
||||||
|
$primary : #1976D2;
|
||||||
|
$secondary : #26A69A;
|
||||||
|
$accent : #9C27B0;
|
||||||
|
|
||||||
|
$dark : #1D1D1D;
|
||||||
|
|
||||||
|
$positive : #21BA45;
|
||||||
|
$negative : #C10015;
|
||||||
|
$info : #31CCEC;
|
||||||
|
$warning : #F2C037;
|
|
@ -0,0 +1,7 @@
|
||||||
|
declare namespace NodeJS {
|
||||||
|
interface ProcessEnv {
|
||||||
|
NODE_ENV: string;
|
||||||
|
VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined;
|
||||||
|
VUE_ROUTER_BASE: string | undefined;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%= productName %></title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="description" content="<%= productDescription %>">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||||
|
<link rel="icon" type="image/ico" href="favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- DO NOT touch the following DIV -->
|
||||||
|
<div id="q-app"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,109 @@
|
||||||
|
<template>
|
||||||
|
<q-layout view="lHh Lpr lFf">
|
||||||
|
<q-header elevated>
|
||||||
|
<q-toolbar>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
icon="menu"
|
||||||
|
aria-label="Menu"
|
||||||
|
@click="leftDrawerOpen = !leftDrawerOpen"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<q-toolbar-title>
|
||||||
|
Quasar App
|
||||||
|
</q-toolbar-title>
|
||||||
|
|
||||||
|
<div>Quasar v{{ $q.version }}</div>
|
||||||
|
</q-toolbar>
|
||||||
|
</q-header>
|
||||||
|
|
||||||
|
<q-drawer
|
||||||
|
v-model="leftDrawerOpen"
|
||||||
|
show-if-above
|
||||||
|
bordered
|
||||||
|
content-class="bg-grey-1"
|
||||||
|
>
|
||||||
|
<q-list>
|
||||||
|
<q-item-label
|
||||||
|
header
|
||||||
|
class="text-grey-8"
|
||||||
|
>
|
||||||
|
Essential Links
|
||||||
|
</q-item-label>
|
||||||
|
<EssentialLink
|
||||||
|
v-for="link in essentialLinks"
|
||||||
|
:key="link.title"
|
||||||
|
v-bind="link"
|
||||||
|
/>
|
||||||
|
</q-list>
|
||||||
|
</q-drawer>
|
||||||
|
|
||||||
|
<q-page-container>
|
||||||
|
<router-view />
|
||||||
|
</q-page-container>
|
||||||
|
</q-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import EssentialLink from 'components/EssentialLink.vue'
|
||||||
|
|
||||||
|
const linksData = [
|
||||||
|
{
|
||||||
|
title: 'Docs',
|
||||||
|
caption: 'quasar.dev',
|
||||||
|
icon: 'school',
|
||||||
|
link: 'https://quasar.dev'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Github',
|
||||||
|
caption: 'github.com/quasarframework',
|
||||||
|
icon: 'code',
|
||||||
|
link: 'https://github.com/quasarframework'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Discord Chat Channel',
|
||||||
|
caption: 'chat.quasar.dev',
|
||||||
|
icon: 'chat',
|
||||||
|
link: 'https://chat.quasar.dev'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Forum',
|
||||||
|
caption: 'forum.quasar.dev',
|
||||||
|
icon: 'record_voice_over',
|
||||||
|
link: 'https://forum.quasar.dev'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Twitter',
|
||||||
|
caption: '@quasarframework',
|
||||||
|
icon: 'rss_feed',
|
||||||
|
link: 'https://twitter.quasar.dev'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Facebook',
|
||||||
|
caption: '@QuasarFramework',
|
||||||
|
icon: 'public',
|
||||||
|
link: 'https://facebook.quasar.dev'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Quasar Awesome',
|
||||||
|
caption: 'Community Quasar projects',
|
||||||
|
icon: 'favorite',
|
||||||
|
link: 'https://awesome.quasar.dev'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
import { defineComponent, ref } from '@vue/composition-api';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'MainLayout',
|
||||||
|
components: { EssentialLink },
|
||||||
|
setup() {
|
||||||
|
const leftDrawerOpen = ref(false);
|
||||||
|
const essentialLinks = ref(linksData);
|
||||||
|
|
||||||
|
return {leftDrawerOpen, essentialLinks}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
14
src/main.js
|
@ -1,14 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import App from './App.vue'
|
|
||||||
import router from './router'
|
|
||||||
import store from './store'
|
|
||||||
import vuetify from './plugins/vuetify'
|
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
|
||||||
|
|
||||||
new Vue({
|
|
||||||
router,
|
|
||||||
store,
|
|
||||||
vuetify,
|
|
||||||
render: h => h(App)
|
|
||||||
}).$mount('#app')
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<template>
|
||||||
|
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
|
||||||
|
<div>
|
||||||
|
<div style="font-size: 30vh">
|
||||||
|
404
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-h2" style="opacity:.4">
|
||||||
|
Oops. Nothing here...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
class="q-mt-xl"
|
||||||
|
color="white"
|
||||||
|
text-color="blue"
|
||||||
|
unelevated
|
||||||
|
to="/"
|
||||||
|
label="Go Home"
|
||||||
|
no-caps
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from '@vue/composition-api';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Error404',
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<template>
|
||||||
|
<q-page class="row items-center justify-evenly">
|
||||||
|
<example-component
|
||||||
|
title="Example component"
|
||||||
|
active
|
||||||
|
:todos="todos"
|
||||||
|
:meta="meta"
|
||||||
|
></example-component>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Todo, Meta } from 'components/models';
|
||||||
|
import ExampleComponent from 'components/CompositionComponent.vue';
|
||||||
|
import { defineComponent, ref } from '@vue/composition-api';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'PageIndex',
|
||||||
|
components: { ExampleComponent },
|
||||||
|
setup() {
|
||||||
|
const todos = ref<Todo[]>([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
content: 'ct1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
content: 'ct2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
content: 'ct3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
content: 'ct4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
content: 'ct5'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const meta = ref<Meta>({
|
||||||
|
totalCount: 1200
|
||||||
|
});
|
||||||
|
return { todos, meta };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,103 +0,0 @@
|
||||||
//const main = 'https://192.168.5.128:5000/'
|
|
||||||
const main = 'http://localhost:5000/'
|
|
||||||
//const main = 'http://192.168.5.118:5000/'
|
|
||||||
//const main = 'https://groeger-clan.duckdns.org:5000/'
|
|
||||||
//const main = 'https://flaschengeist.wu5.de:5000/'
|
|
||||||
|
|
||||||
const url = {
|
|
||||||
login: main + 'login',
|
|
||||||
logout: main + 'logout',
|
|
||||||
getUsers: main + 'getUsers',
|
|
||||||
pricelist: main + 'pricelist',
|
|
||||||
getTypes: main + 'drinkTypes',
|
|
||||||
getFinanzerMain: main + 'getFinanzerMain',
|
|
||||||
bar: main + 'bar',
|
|
||||||
barGetUser: main + 'barGetUser',
|
|
||||||
barAddAmount: main + 'baradd',
|
|
||||||
finanzerAddAmount: main + 'finanzerAddAmount',
|
|
||||||
finanzerAddCredit: main + 'finanzerAddCredit',
|
|
||||||
searchUser: main + 'search',
|
|
||||||
getAllUser: main + 'barGetUsers',
|
|
||||||
lockUser: main + 'finanzerLock',
|
|
||||||
finanzerSetConfig: main + 'finanzerSetConfig',
|
|
||||||
finanzerAddUser: main + 'finanzerAddUser',
|
|
||||||
finanzerSendAllMail: main + 'finanzerSendAllMail',
|
|
||||||
finanzerSendOneMail: main + 'finanzerSendOneMail',
|
|
||||||
userMain: main + 'user/main',
|
|
||||||
userAddAmount: main + 'user/addAmount',
|
|
||||||
saveLifetime: main + 'setLifetime',
|
|
||||||
getLifetime: main + 'getLifetime',
|
|
||||||
resetPassword: main + 'passwordReset',
|
|
||||||
freeDrinkListConfig: main + 'freeDrinkListConfig',
|
|
||||||
freeDrinkListHistory: main + 'freeDrinkListHistory',
|
|
||||||
freeDrinkListHistoryFromTo: main + 'freeDrinkListHistoryFromTo',
|
|
||||||
deleteDrinkListHistory: main + 'deleteDrinkListHistory',
|
|
||||||
freeDrinkListReasons: main + 'freeDrinkListReasons',
|
|
||||||
deleteFreeDrinkListReason: main + 'deleteFreeDrinkListReason',
|
|
||||||
freeDrinkTypes: main + 'freeDrinkTypes',
|
|
||||||
deleteFreeDrinkListConfig: main + 'deleteFreeDrinkListConfig',
|
|
||||||
vorstand: {
|
|
||||||
sm: {
|
|
||||||
addUser: main + 'sm/addUser',
|
|
||||||
deleteUser: main + 'sm/deleteUser',
|
|
||||||
getUser: main + 'sm/getUser',
|
|
||||||
getUsers: main + 'user/jobs',
|
|
||||||
lockDay: main + 'sm/lockDay',
|
|
||||||
searchUser: main + 'sm/searchWithExtern',
|
|
||||||
jobkind: main + 'sm/JobKind',
|
|
||||||
getAllJobKindsbKinds: main + 'sm/getAllJobKinds',
|
|
||||||
getJobKind: main + 'sm/getJobKind',
|
|
||||||
deleteJobKind: main + 'sm/deleteJobKind',
|
|
||||||
updateJobKindDates: main + 'jk/JobKindDate',
|
|
||||||
getJobKindDates: main + 'jk/JobKindDate'
|
|
||||||
},
|
|
||||||
um: {
|
|
||||||
setStatus: main + 'um/setStatus',
|
|
||||||
updateStatus: main + 'um/updateStatus',
|
|
||||||
deleteStatus: main + 'um/deleteStatus',
|
|
||||||
updateStatusUser: main + 'um/updateStatusUser',
|
|
||||||
updateVoting: main + 'um/updateVoting',
|
|
||||||
updateWorkgroups: main + 'um/updateWorkgroups'
|
|
||||||
},
|
|
||||||
wm: {
|
|
||||||
workgroup: main + 'wgm/workgroup',
|
|
||||||
getWorkgroup: main + 'wgm/getWorkgroup',
|
|
||||||
getAllWorkgroups: main + 'wgm/getAllWorkgroups',
|
|
||||||
deleteWorkgroup: main + 'wgm/deleteWorkgroup'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
config: main + 'user/saveConfig',
|
|
||||||
job: main + 'user/job',
|
|
||||||
jobs: main + 'user/jobs',
|
|
||||||
addJob: main + 'user/addJob',
|
|
||||||
getJobOnDates: main + 'user/jobsOnDates',
|
|
||||||
deleteJob: main + 'user/deleteJob',
|
|
||||||
getJobInvites: main + 'user/getJobInvites',
|
|
||||||
setJobInvites: main + 'user/JobInvites',
|
|
||||||
deletJobInvite: main + 'user/deleteJobInvite',
|
|
||||||
getJobRequests: main + 'user/getJobRequests',
|
|
||||||
setJobRequests: main + 'user/JobRequests',
|
|
||||||
deletJobRequest: main + 'user/deleteJobRequest',
|
|
||||||
storno: main + 'user/storno',
|
|
||||||
getAllStatus: main + 'getAllStatus',
|
|
||||||
getStatus: main + 'getStatus',
|
|
||||||
valid: main + 'valid',
|
|
||||||
getAccessTokens: main + 'user/getAccessTokens'
|
|
||||||
},
|
|
||||||
barU: {
|
|
||||||
storno: main + 'bar/storno',
|
|
||||||
lock: main + 'bar/lock',
|
|
||||||
addUser: main + 'bar/addUser'
|
|
||||||
},
|
|
||||||
gastro: {
|
|
||||||
setDrink: main + 'gastro/setDrink',
|
|
||||||
updateDrink: main + 'gastro/updateDrink',
|
|
||||||
deleteDrink: main + 'gastro/deleteDrink',
|
|
||||||
setType: main + 'gastro/setDrinkType',
|
|
||||||
updateType: main + 'gastro/updateDrinkType',
|
|
||||||
deleteType: main + 'gastro/deleteDrinkType'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default url
|
|
|
@ -1,10 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuetify from 'vuetify/lib'
|
|
||||||
|
|
||||||
Vue.use(Vuetify)
|
|
||||||
|
|
||||||
export default new Vuetify({
|
|
||||||
icons: {
|
|
||||||
iconfont: 'mdiSvg'
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1,274 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import VueRouter from 'vue-router'
|
|
||||||
import FinanzerView from '@/views/FinanzerView'
|
|
||||||
import Login from '@/views/Login'
|
|
||||||
import store from '@/store/index'
|
|
||||||
import GeruechteView from '../views/contents/GeruechteView'
|
|
||||||
import BarFreedrinksView from '../views/contents/BarFreedrinksView'
|
|
||||||
import AddAmount from '../components/user/AddAmount'
|
|
||||||
import CreditOverview from '../components/user/CreditOverview'
|
|
||||||
import MainView from '../views/MainView'
|
|
||||||
import UserView from '../views/UserView'
|
|
||||||
import BarView from '../views/BarView'
|
|
||||||
import UserNavigation from '../components/user/UserNavigation'
|
|
||||||
import BarNavigation from '../components/baruser/BarNavigation'
|
|
||||||
import FinanzerNavigation from '../components/finanzer/FinanzerNavigation'
|
|
||||||
import Overview from '../components/finanzer/Overview'
|
|
||||||
import User from '../components/finanzer/User'
|
|
||||||
import ServiceManagement from '../components/vorstand/ServiceManagement'
|
|
||||||
import Config from '@/components/user/Config'
|
|
||||||
import FreedrinkUserView from '@/components/user/freedrink/freedrinkUserView'
|
|
||||||
import Jobs from '@/components/user/Jobs'
|
|
||||||
import PriceList from '@/components/pricelist/PriceList'
|
|
||||||
import ManagementNavigation from '@/components/vorstand/ManagementNavigation'
|
|
||||||
import GastroNavigation from '@/components/gastro/GastroNavigation'
|
|
||||||
import PriceListView from '@/views/contents/PriceListView'
|
|
||||||
import UserManager from '@/components/vorstand/UserManager'
|
|
||||||
import WorkgroupManagement from '@/components/vorstand/WorkgroupManagement'
|
|
||||||
import JobKindManager from '@/components/vorstand/JobKindManager'
|
|
||||||
import JobsRequest from '@/components/user/JobsRequest'
|
|
||||||
import ResetPassword from '@/components/ResetPassword'
|
|
||||||
import FreeDrinkList from '@/components/vorstand/FreeDrinkList'
|
|
||||||
import FreeDrinkListMain from '@/components/vorstand/FreeDrinkList/FreeDrinkListMain'
|
|
||||||
import FreeDrinkListConfig from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfig'
|
|
||||||
import FreeDrinkListJob from '@/components/vorstand/FreeDrinkList/FreeDrinkListJob'
|
|
||||||
import FreeDrinkListWorkgroup from '@/components/vorstand/FreeDrinkList/FreeDrinkListWorkgroup'
|
|
||||||
import FreeDrinkListBand from '@/components/vorstand/FreeDrinkList/FreeDrinkListBand'
|
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
|
||||||
|
|
||||||
const rootPath = ''
|
|
||||||
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: rootPath + '/resetPassword',
|
|
||||||
name: 'resetPassword',
|
|
||||||
component: ResetPassword
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: rootPath + '/cookies',
|
|
||||||
name: 'cookies'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: rootPath + '/pricelist',
|
|
||||||
name: 'priceListNoLogin',
|
|
||||||
component: PriceListView
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: rootPath + '/login',
|
|
||||||
name: 'login',
|
|
||||||
component: Login
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: rootPath + '/main',
|
|
||||||
name: 'main',
|
|
||||||
component: MainView,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'management',
|
|
||||||
name: 'management',
|
|
||||||
components: { nav: ManagementNavigation, default: BarView },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'serviceManagement',
|
|
||||||
path: 'servicemanagement/:year/:month',
|
|
||||||
component: ServiceManagement
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'usermanager',
|
|
||||||
name: 'userManager',
|
|
||||||
component: UserManager
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'workgroupmanagement',
|
|
||||||
name: 'workgroupManagement',
|
|
||||||
component: WorkgroupManagement
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'jobkindmanagement',
|
|
||||||
name: 'jobkindManagement',
|
|
||||||
component: JobKindManager
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'freeDrinkList',
|
|
||||||
name: 'freeDrinkList',
|
|
||||||
component: FreeDrinkList,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'main',
|
|
||||||
name: 'freeDrinkListMain',
|
|
||||||
component: FreeDrinkListMain
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'config',
|
|
||||||
name: 'freeDrinkListConfig',
|
|
||||||
component: FreeDrinkListConfig
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'freeDrinkListJob',
|
|
||||||
name: 'freeDrinkListJob',
|
|
||||||
component: FreeDrinkListJob
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'freeDrinkListWorkgroup',
|
|
||||||
name: 'freeDrinkListWorkgroup',
|
|
||||||
component: FreeDrinkListWorkgroup
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'freeDrinkListBand',
|
|
||||||
name: 'freeDrinkListBand',
|
|
||||||
component: FreeDrinkListBand
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'user',
|
|
||||||
name: 'user',
|
|
||||||
components: { nav: UserNavigation, default: UserView },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'add',
|
|
||||||
name: 'add',
|
|
||||||
component: AddAmount
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'freedrinkUser',
|
|
||||||
name: 'freedrinkUser',
|
|
||||||
component: FreedrinkUserView
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'overview',
|
|
||||||
name: 'userOverview',
|
|
||||||
component: CreditOverview
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'config',
|
|
||||||
name: 'userConfig',
|
|
||||||
component: Config
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'jobs/:year/:month',
|
|
||||||
name: 'userJobs',
|
|
||||||
component: Jobs
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'jobRequests/:kind',
|
|
||||||
name: 'jobRequests',
|
|
||||||
component: JobsRequest
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'bar',
|
|
||||||
name: 'bar',
|
|
||||||
components: { nav: BarNavigation, default: BarView },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'geruecht',
|
|
||||||
name: 'geruecht',
|
|
||||||
component: GeruechteView
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'baruserFreedrinks',
|
|
||||||
name: 'baruserFreedrinks',
|
|
||||||
component: BarFreedrinksView
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'finanzer',
|
|
||||||
name: 'finanzer',
|
|
||||||
components: { default: FinanzerView, nav: FinanzerNavigation },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'overview',
|
|
||||||
name: 'overview',
|
|
||||||
component: Overview
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'user/:id',
|
|
||||||
name: 'activeUser',
|
|
||||||
props: true,
|
|
||||||
component: User
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'gastro',
|
|
||||||
name: 'gastro',
|
|
||||||
components: { nav: GastroNavigation, default: BarView },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'pricelist',
|
|
||||||
name: 'gastroPricelist',
|
|
||||||
component: PriceList
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '*',
|
|
||||||
redirect: {
|
|
||||||
name: 'login'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const router = new VueRouter({
|
|
||||||
mode: 'history',
|
|
||||||
base: process.env.BASE_URL,
|
|
||||||
routes
|
|
||||||
})
|
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
|
||||||
store.dispatch('fetchAccessToken')
|
|
||||||
if (to.name === 'main') {
|
|
||||||
if (
|
|
||||||
to.name === 'finanzer' ||
|
|
||||||
to.name === 'overview' ||
|
|
||||||
to.name === 'activeUser'
|
|
||||||
) {
|
|
||||||
if (!store.state.login.user.group.includes('moneymaster')) {
|
|
||||||
next({ name: 'login' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (to.name === 'bar' || to.name === 'geruecht') {
|
|
||||||
if (!store.state.login.user.group.includes('bar')) {
|
|
||||||
next({ name: 'login' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
to.name === 'user' ||
|
|
||||||
to.name === 'userOverview' ||
|
|
||||||
to.name === 'userConfig' ||
|
|
||||||
to.name === 'userJobs' ||
|
|
||||||
to.name === 'jobRequests'
|
|
||||||
) {
|
|
||||||
if (!store.state.login.user.group.includes('user')) {
|
|
||||||
next({ name: 'login' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!store.state.login.user.accessToken) {
|
|
||||||
next({ name: 'login' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (to.name === 'login') {
|
|
||||||
if (store.state.login.user.accessToken) {
|
|
||||||
if (store.state.login.user.group.includes('moneymaster')) {
|
|
||||||
next({ name: 'overview' })
|
|
||||||
} else if (store.state.login.user.group.includes('bar')) {
|
|
||||||
next({ name: 'geruecht' })
|
|
||||||
} else if (store.state.login.user.group.includes('user')) {
|
|
||||||
next({ name: 'add' })
|
|
||||||
} else if (store.state.login.user.group.includes('extern')) {
|
|
||||||
next({ name: 'main' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next()
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { route } from 'quasar/wrappers';
|
||||||
|
import VueRouter from 'vue-router';
|
||||||
|
import { Store } from 'vuex';
|
||||||
|
import { StateInterface } from '../store';
|
||||||
|
import routes from './routes';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not building with SSR mode, you can
|
||||||
|
* directly export the Router instantiation
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default route<Store<StateInterface>>(function ({ Vue }) {
|
||||||
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
|
const Router = new VueRouter({
|
||||||
|
scrollBehavior: () => ({ x: 0, y: 0 }),
|
||||||
|
routes,
|
||||||
|
|
||||||
|
// Leave these as is and change from quasar.conf.js instead!
|
||||||
|
// quasar.conf.js -> build -> vueRouterMode
|
||||||
|
// quasar.conf.js -> build -> publicPath
|
||||||
|
mode: process.env.VUE_ROUTER_MODE,
|
||||||
|
base: process.env.VUE_ROUTER_BASE
|
||||||
|
});
|
||||||
|
|
||||||
|
return Router;
|
||||||
|
})
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { RouteConfig } from 'vue-router';
|
||||||
|
|
||||||
|
const routes: RouteConfig[] = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
component: () => import('layouts/MainLayout.vue'),
|
||||||
|
children: [
|
||||||
|
{ path: '', component: () => import('pages/Index.vue') }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// Always leave this as last one,
|
||||||
|
// but you can also remove it
|
||||||
|
{
|
||||||
|
path: '*',
|
||||||
|
component: () => import('pages/Error404.vue')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Mocks all files ending in `.vue` showing them as plain Vue instances
|
||||||
|
declare module '*.vue' {
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue;
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuex from 'vuex'
|
|
||||||
import login from './modules/login'
|
|
||||||
import finanzerUsers from './modules/finanzerUsers'
|
|
||||||
import barUsers from '@/store/modules/barUsers'
|
|
||||||
import user from '@/store/modules/user'
|
|
||||||
import sm from '@/store/modules/serviceManagement'
|
|
||||||
import jobs from '@/store/modules/jobs'
|
|
||||||
import priceList from '@/store/modules/pricelist'
|
|
||||||
import usermanager from '@/store/modules/userManager'
|
|
||||||
import wm from '@/store/modules/workgroupManagement'
|
|
||||||
import jkm from '@/store/modules/jobkindManager'
|
|
||||||
import jobInvites from '@/store/modules/jobInvites'
|
|
||||||
import jobRequests from '@/store/modules/jobRequests'
|
|
||||||
import connectionError from '@/store/modules/connectionError'
|
|
||||||
import freeDrinkList from '@/store/modules/freeDrinkList'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
|
||||||
modules: {
|
|
||||||
login,
|
|
||||||
finanzerUsers,
|
|
||||||
barUsers,
|
|
||||||
user,
|
|
||||||
sm,
|
|
||||||
jobs,
|
|
||||||
priceList,
|
|
||||||
usermanager,
|
|
||||||
wm,
|
|
||||||
jkm,
|
|
||||||
jobInvites,
|
|
||||||
jobRequests,
|
|
||||||
connectionError,
|
|
||||||
freeDrinkList
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { store } from 'quasar/wrappers';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
|
// import example from './module-example';
|
||||||
|
// import { ExampleStateInterface } from './module-example/state';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not building with SSR mode, you can
|
||||||
|
* directly export the Store instantiation
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface StateInterface {
|
||||||
|
// Define your own store structure, using submodules if needed
|
||||||
|
// example: ExampleStateInterface;
|
||||||
|
// Declared as unknown to avoid linting issue. Best to strongly type as per the line above.
|
||||||
|
example: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default store(function ({ Vue }) {
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
const Store = new Vuex.Store<StateInterface>({
|
||||||
|
modules: {
|
||||||
|
// example
|
||||||
|
},
|
||||||
|
|
||||||
|
// enable strict mode (adds overhead!)
|
||||||
|
// for dev mode only
|
||||||
|
strict: !!process.env.DEV
|
||||||
|
});
|
||||||
|
|
||||||
|
return Store;
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ActionTree } from 'vuex';
|
||||||
|
import { StateInterface } from '../index';
|
||||||
|
import { ExampleStateInterface } from './state';
|
||||||
|
|
||||||
|
const actions: ActionTree<ExampleStateInterface, StateInterface> = {
|
||||||
|
someAction (/* context */) {
|
||||||
|
// your code
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actions;
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { GetterTree } from 'vuex';
|
||||||
|
import { StateInterface } from '../index';
|
||||||
|
import { ExampleStateInterface } from './state';
|
||||||
|
|
||||||
|
const getters: GetterTree<ExampleStateInterface, StateInterface> = {
|
||||||
|
someAction (/* context */) {
|
||||||
|
// your code
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getters;
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Module } from 'vuex';
|
||||||
|
import { StateInterface } from '../index';
|
||||||
|
import state, { ExampleStateInterface } from './state';
|
||||||
|
import actions from './actions';
|
||||||
|
import getters from './getters';
|
||||||
|
import mutations from './mutations';
|
||||||
|
|
||||||
|
const exampleModule: Module<ExampleStateInterface, StateInterface> = {
|
||||||
|
namespaced: true,
|
||||||
|
actions,
|
||||||
|
getters,
|
||||||
|
mutations,
|
||||||
|
state
|
||||||
|
};
|
||||||
|
|
||||||
|
export default exampleModule;
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { MutationTree } from 'vuex';
|
||||||
|
import { ExampleStateInterface } from './state';
|
||||||
|
|
||||||
|
const mutation: MutationTree<ExampleStateInterface> = {
|
||||||
|
someMutation (/* state: ExampleStateInterface */) {
|
||||||
|
// your code
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default mutation;
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface ExampleStateInterface {
|
||||||
|
prop: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state: ExampleStateInterface = {
|
||||||
|
prop: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default state;
|
|
@ -1,411 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
import url from '@/plugins/routes'
|
|
||||||
const timeout = 5000
|
|
||||||
const state = {
|
|
||||||
users: [],
|
|
||||||
allUsers: [],
|
|
||||||
filter: '',
|
|
||||||
usersLoading: false,
|
|
||||||
allUsersLoading: false,
|
|
||||||
messages: [],
|
|
||||||
menu: false,
|
|
||||||
locked: false
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutations = {
|
|
||||||
setAllUsers: (state, users) => {
|
|
||||||
state.allUsers = []
|
|
||||||
state.allUsers = users
|
|
||||||
for (let i = 0; i < state.allUsers.length; i++) {
|
|
||||||
state.allUsers[i].fullName =
|
|
||||||
state.allUsers[i].firstname + ' ' + state.allUsers[i].lastname
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setUsers: (state, users) => {
|
|
||||||
for (let user in users) {
|
|
||||||
let existuser = state.users.find(a => {
|
|
||||||
return user === a.username
|
|
||||||
})
|
|
||||||
if (users[user].last_seen != null || users[user].last_seen != undefined) {
|
|
||||||
users[user].last_seen = new Date(
|
|
||||||
users[user].last_seen.year,
|
|
||||||
users[user].last_seen.month - 1,
|
|
||||||
users[user].last_seen.day,
|
|
||||||
users[user].last_seen.hour,
|
|
||||||
users[user].last_seen.minute,
|
|
||||||
users[user].last_seen.second
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (existuser) {
|
|
||||||
existuser.sername = users[user].username
|
|
||||||
existuser.firstname = users[user].firstname
|
|
||||||
existuser.lastname = users[user].lastname
|
|
||||||
existuser.locked = users[user].locked
|
|
||||||
existuser.amount = users[user].amount
|
|
||||||
existuser.type = users[user].type
|
|
||||||
existuser.limit = users[user].limit
|
|
||||||
existuser.last_seen = users[user].last_seen
|
|
||||||
existuser.autoLock = users[user].autoLock
|
|
||||||
? users[user].autoLock
|
|
||||||
: existuser.autoLock
|
|
||||||
} else {
|
|
||||||
state.users.push({
|
|
||||||
username: users[user].username,
|
|
||||||
firstname: users[user].firstname,
|
|
||||||
lastname: users[user].lastname,
|
|
||||||
locked: users[user].locked,
|
|
||||||
amount: users[user].amount,
|
|
||||||
type: users[user].type,
|
|
||||||
loading: false,
|
|
||||||
limit: users[user].limit,
|
|
||||||
last_seen: users[user].last_seen,
|
|
||||||
autoLock: users[user].autoLock
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutations.sortUsers(state)
|
|
||||||
},
|
|
||||||
updateUser: (state, data) => {
|
|
||||||
let index = state.users.indexOf(
|
|
||||||
state.users.find(a => {
|
|
||||||
return a.username === data.username
|
|
||||||
})
|
|
||||||
)
|
|
||||||
if (data.loading !== undefined) state.users[index].loading = data.loading
|
|
||||||
if (data.last_seen !== undefined)
|
|
||||||
state.users[index].last_seen = data.last_seen
|
|
||||||
},
|
|
||||||
sortUsers: state => {
|
|
||||||
state.users = state.users.sort((a, b) => {
|
|
||||||
if (a.lastname > b.lastname) return 1
|
|
||||||
if (a.lastname < b.lastname) return -1
|
|
||||||
if (a.firstname > b.firstname) return 1
|
|
||||||
if (a.firstname < b.firstname) return -1
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setFilter: (state, filter) => {
|
|
||||||
state.filter = filter
|
|
||||||
},
|
|
||||||
setUsersLoading: (state, value) => {
|
|
||||||
state.usersLoading = value
|
|
||||||
},
|
|
||||||
setAllUsersLoading: (state, value) => {
|
|
||||||
state.allUsersLoading = value
|
|
||||||
},
|
|
||||||
addMessage: (state, data) => {
|
|
||||||
var message = null
|
|
||||||
if (state.messages.length > 0) {
|
|
||||||
if (
|
|
||||||
state.messages[0].user.username === data.user.username &&
|
|
||||||
!data.error
|
|
||||||
) {
|
|
||||||
message = state.messages[0]
|
|
||||||
if ((new Date() - state.messages[0].date) / 1000 < 2) {
|
|
||||||
clearTimeout(message.timeout)
|
|
||||||
message.amount = message.amount + data.amount
|
|
||||||
message.visible = true
|
|
||||||
message.date = new Date()
|
|
||||||
message.timeout = setTimeout(() => {
|
|
||||||
if (!message.error) {
|
|
||||||
message.visible = false
|
|
||||||
}
|
|
||||||
}, 5000)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
message.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let message2 = {
|
|
||||||
user: data.user,
|
|
||||||
error: data.error,
|
|
||||||
storno: false,
|
|
||||||
loading: false,
|
|
||||||
visible: true,
|
|
||||||
amount: data.amount,
|
|
||||||
date: new Date(),
|
|
||||||
timeout: setTimeout(() => {
|
|
||||||
if (!message2.error) {
|
|
||||||
message2.visible = false
|
|
||||||
}
|
|
||||||
}, 5000)
|
|
||||||
}
|
|
||||||
state.messages.unshift(message2)
|
|
||||||
},
|
|
||||||
updateMessage: (state, data) => {
|
|
||||||
var message = state.messages.find(msg => {
|
|
||||||
return msg.date - data.date === 0 ? true : false
|
|
||||||
})
|
|
||||||
if (message) {
|
|
||||||
if (data.storno !== undefined) message.storno = data.storno
|
|
||||||
if (data.loading !== undefined) message.loading = data.loading
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setMenu: (state, value) => {
|
|
||||||
state.menu = value
|
|
||||||
},
|
|
||||||
setLocked: (satet, value) => {
|
|
||||||
state.locked = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
async getUsers({ commit, rootState, dispatch }) {
|
|
||||||
commit('setUsersLoading', true)
|
|
||||||
try {
|
|
||||||
const response = await axios.get(url.bar, {
|
|
||||||
headers: { Token: rootState.login.user.accessToken },
|
|
||||||
timeout
|
|
||||||
})
|
|
||||||
commit('setUsers', response.data)
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commit('setUsersLoading', false)
|
|
||||||
},
|
|
||||||
async addAmount({ commit, rootState, dispatch }, data) {
|
|
||||||
try {
|
|
||||||
commit('updateUser', { username: data.username, loading: true })
|
|
||||||
} catch (e) {
|
|
||||||
//error
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = await axios.post(
|
|
||||||
url.barAddAmount,
|
|
||||||
{ userId: data.username, amount: data.amount },
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken }, timeout }
|
|
||||||
)
|
|
||||||
commit('setUsers', { [response.data.username]: response.data })
|
|
||||||
commit('addMessage', {
|
|
||||||
user: data.user,
|
|
||||||
amount: data.amount,
|
|
||||||
error: false
|
|
||||||
})
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
} catch (e) {
|
|
||||||
console.log(typeof e)
|
|
||||||
for (const [key, value] of Object.entries(e)) {
|
|
||||||
console.log(`${key}: ${value}`)
|
|
||||||
}
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
commit('addMessage', {
|
|
||||||
user: data.user,
|
|
||||||
amount: data.amount,
|
|
||||||
error: true
|
|
||||||
})
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
commit('updateUser', { username: data.username, loading: false })
|
|
||||||
} catch (e) {
|
|
||||||
//error
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async addCreditList({ commit, rootState, dispatch }, data) {
|
|
||||||
try {
|
|
||||||
commit('updateUser', { username: data.username, loading: true })
|
|
||||||
} catch (e) {
|
|
||||||
//error
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = await axios.post(
|
|
||||||
url.barGetUser,
|
|
||||||
{ userId: data.username },
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken }, timeout }
|
|
||||||
)
|
|
||||||
commit('setUsers', { [response.data.username]: response.data })
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
commit('updateUser', {
|
|
||||||
username: data.username,
|
|
||||||
loading: false,
|
|
||||||
last_seen: new Date()
|
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
// error
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getAllUsers({ commit, rootState, dispatch }) {
|
|
||||||
commit('setAllUsersLoading', true)
|
|
||||||
try {
|
|
||||||
const response = await axios.get(url.searchUser, {
|
|
||||||
headers: { Token: rootState.login.user.accessToken },
|
|
||||||
timeout
|
|
||||||
})
|
|
||||||
commit('setAllUsers', response.data)
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.data === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commit('setAllUsersLoading', false)
|
|
||||||
},
|
|
||||||
async storno({ commit, rootState, dispatch }, data) {
|
|
||||||
commit('updateMessage', { date: data.date, loading: true })
|
|
||||||
try {
|
|
||||||
const response = await axios.post(
|
|
||||||
url.barU.storno,
|
|
||||||
{
|
|
||||||
userId: data.username,
|
|
||||||
amount: data.amount
|
|
||||||
},
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken }, timeout }
|
|
||||||
)
|
|
||||||
commit('setUsers', { [response.data.username]: response.data })
|
|
||||||
commit('updateMessage', { date: data.date, storno: true })
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commit('updateMessage', { date: data.date, loading: false })
|
|
||||||
},
|
|
||||||
async getLocked({ commit, rootState, dispatch }) {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(url.barU.lock, {
|
|
||||||
headers: { Token: rootState.login.user.accessToken },
|
|
||||||
timeout
|
|
||||||
})
|
|
||||||
commit('setLocked', response.data.value)
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async setLocked({ commit, rootState, dispatch }) {
|
|
||||||
try {
|
|
||||||
const response = await axios.post(
|
|
||||||
url.barU.lock,
|
|
||||||
{ value: true },
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken }, timeout }
|
|
||||||
)
|
|
||||||
commit('setLocked', response.data.value)
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async unlock({ commit, rootState, dispatch }, password) {
|
|
||||||
try {
|
|
||||||
const valid = await axios.post(
|
|
||||||
url.user.valid,
|
|
||||||
{ password: password },
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken }, timeout }
|
|
||||||
)
|
|
||||||
if (valid.data.ok === 'ok') {
|
|
||||||
const response = await axios.post(
|
|
||||||
url.barU.lock,
|
|
||||||
{ value: false },
|
|
||||||
{ headers: { Token: rootState.login.user.accessToken } }
|
|
||||||
)
|
|
||||||
commit('setLocked', response.data.value)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (e.message == 'Network Error') {
|
|
||||||
dispatch('connectionError/addError', null, { root: true })
|
|
||||||
}
|
|
||||||
if (e.response)
|
|
||||||
if (e.response.status === 401) {
|
|
||||||
dispatch('getLifetime', null, { root: true })
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setLockStatus({ commit }, status) {
|
|
||||||
commit('setLocked', status)
|
|
||||||
},
|
|
||||||
setFilter({ commit }, data) {
|
|
||||||
commit('setFilter', data)
|
|
||||||
},
|
|
||||||
activateMenu({ commit }) {
|
|
||||||
commit('setMenu', true)
|
|
||||||
},
|
|
||||||
deactivateMenu({ commit }) {
|
|
||||||
commit('setMenu', false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getters = {
|
|
||||||
users: state => {
|
|
||||||
return state.users
|
|
||||||
},
|
|
||||||
allUsers: state => {
|
|
||||||
return state.allUsers
|
|
||||||
},
|
|
||||||
filter: state => {
|
|
||||||
return state.filter
|
|
||||||
},
|
|
||||||
usersLoading: state => {
|
|
||||||
return state.usersLoading
|
|
||||||
},
|
|
||||||
allUsersLoading: state => {
|
|
||||||
return state.allUsersLoading
|
|
||||||
},
|
|
||||||
messages: state => {
|
|
||||||
return state.messages
|
|
||||||
},
|
|
||||||
menu: state => {
|
|
||||||
return state.menu
|
|
||||||
},
|
|
||||||
locked: state => {
|
|
||||||
return state.locked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions,
|
|
||||||
getters
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
const state = {
|
|
||||||
errors: []
|
|
||||||
}
|
|
||||||
|
|
||||||
const mutations = {
|
|
||||||
addError: state => {
|
|
||||||
state.errors.push({
|
|
||||||
message: 'Connection Error: Server nicht verfügbar!',
|
|
||||||
visible: true
|
|
||||||
})
|
|
||||||
},
|
|
||||||
deleteErrors: state => {
|
|
||||||
state.errors = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
addError: ({ commit }) => {
|
|
||||||
commit('addError')
|
|
||||||
},
|
|
||||||
deleteErrors: ({ commit }) => {
|
|
||||||
commit('deleteErrors')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getters = {
|
|
||||||
errors: state => {
|
|
||||||
return state.errors
|
|
||||||
},
|
|
||||||
visible: state => {
|
|
||||||
return state.errors.find(error => {
|
|
||||||
return error.visible
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
mutations,
|
|
||||||
actions,
|
|
||||||
getters
|
|
||||||
}
|
|