Update login page
This commit is contained in:
parent
58291d9d0e
commit
504238844b
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
|
@ -10,31 +10,21 @@
|
|||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.19",
|
||||
"bootstrap": "^4.0.0",
|
||||
"cross-env": "^7.0",
|
||||
"jquery": "^3.2",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"lodash": "^4.17.13",
|
||||
"popper.js": "^1.12",
|
||||
"resolve-url-loader": "^2.3.1",
|
||||
"sass": "^1.20.1",
|
||||
"sass-loader": "^8.0.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
"laravel-mix": "^6.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"vue": "^2.6.12",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@inertiajs/inertia": "^0.1.7",
|
||||
"@inertiajs/inertia-vue": "^0.1.2",
|
||||
"@inertiajs/inertia": "^0.8.6",
|
||||
"@inertiajs/inertia-vue": "^0.5.10",
|
||||
"agnoster": "file:resources/js/libs/agnoster",
|
||||
"font-awesome": "^4.7.0",
|
||||
"js-modules": "file:resources/js/libs/js-modules",
|
||||
"laravel-echo": "^1.7.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
"query-string": "^6.12.1",
|
||||
"socket.io-client": "^2.3.0",
|
||||
"tailwindcss": "^1.2.0",
|
||||
"vue-inputmask": "^0.2.1",
|
||||
"vuex": "^3.1.3"
|
||||
"laravel-echo": "^1.10.0",
|
||||
"postcss-import": "^14.0.1",
|
||||
"query-string": "^7.0.0",
|
||||
"socket.io-client": "^4.0.1",
|
||||
"tailwindcss": "^2.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"/js/app.js": "/js/app.js",
|
||||
"/img/dpsg.gif": "/img/dpsg.gif",
|
||||
"/css/app.css": "/css/app.css"
|
||||
}
|
||||
|
|
|
@ -4,79 +4,79 @@
|
|||
}
|
||||
|
||||
.form-group {
|
||||
@apply .mb-4;
|
||||
@apply mb-4;
|
||||
}
|
||||
|
||||
.label-font {
|
||||
@apply .form-control-font;
|
||||
}
|
||||
|
||||
.form-control-font {
|
||||
@apply .leading-tight .text-gray-600 .text-sm;
|
||||
@apply leading-tight text-gray-600 text-sm;
|
||||
}
|
||||
|
||||
|
||||
.label-placeholder {
|
||||
position: relative;
|
||||
@apply .py-2 .cursor-text;
|
||||
@apply py-2 cursor-text;
|
||||
top: 34px;
|
||||
transition: color 0.2s, padding-bottom 0.2s, font-size 0.2s, top 0.2s;
|
||||
transition: color 02s, padding-bottom 02s, font-size 02s, top 02s;
|
||||
}
|
||||
.field-wrapper.focused .label-placeholder, .label-placeholder-focused {
|
||||
.field-wrapperfocused label-placeholder, label-placeholder-focused {
|
||||
top: 0;
|
||||
@apply .text-sm .text-gray-600;
|
||||
@apply text-sm text-gray-600;
|
||||
padding-bottom: 10px;
|
||||
transition: color 0.2s, padding-bottom 0.2s, font-size 0.2s, top 0.2s;
|
||||
transition: color 02s, padding-bottom 02s, font-size 02s, top 02s;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
@apply .py-2 .appearance-none .border-b .border-solid .form-control-font;
|
||||
@apply py-2 appearance-none border-b border-solid form-control-font;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.label-font {
|
||||
@apply form-control-font;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply .px-3 .py-2 .uppercase .no-underline .text-sm .rounded .text-white;
|
||||
@apply px-3 py-2 uppercase no-underline text-sm rounded text-white;
|
||||
}
|
||||
.btn-sm {
|
||||
@apply .text-xs !important;
|
||||
@apply text-xs !important;
|
||||
}
|
||||
.btn.p-0 {
|
||||
.btnp-0 {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.btn-primary {
|
||||
@apply .bg-primary;
|
||||
@apply bg-primary;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
@apply .bg-primary-light;
|
||||
@apply bg-primary-light;
|
||||
}
|
||||
.btn-danger {
|
||||
@apply .bg-danger;
|
||||
@apply bg-danger;
|
||||
}
|
||||
.btn-danger:hover {
|
||||
@apply .bg-danger-light;
|
||||
@apply bg-danger-light;
|
||||
}
|
||||
.btn-default {
|
||||
@apply .bg-gray-600;
|
||||
@apply bg-gray-600;
|
||||
}
|
||||
.btn-primary-light {
|
||||
@apply .bg-primary-light;
|
||||
@apply bg-primary-light;
|
||||
}
|
||||
.btn-default:hover {
|
||||
@apply .bg-gray-600;
|
||||
@apply bg-gray-600;
|
||||
}
|
||||
|
||||
.field-wrapper {
|
||||
@apply .flex .flex-col;
|
||||
@apply flex flex-col;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
@apply .font-bold .text-gray-700 .text-lg;
|
||||
@apply font-bold text-gray-700 text-lg;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
@apply .subtitle .text-xl .font-semibold .mt-6 .font-thin .uppercase .text-gray-600;
|
||||
@apply text-xl font-semibold mt-6 font-thin uppercase text-gray-600;
|
||||
}
|
||||
|
||||
.mainnav > div > a {
|
||||
@apply .py-2;
|
||||
@apply py-2;
|
||||
}
|
||||
|
|
|
@ -1,30 +1,22 @@
|
|||
import Vue from 'vue';
|
||||
import { modules, init } from 'agnoster';
|
||||
import { Checkbox } from 'js-modules';
|
||||
import { InertiaApp } from '@inertiajs/inertia-vue'
|
||||
import store from './store.js';
|
||||
import { App, plugin } from '@inertiajs/inertia-vue'
|
||||
import 'font-awesome/css/font-awesome.css';
|
||||
import Echo from 'laravel-echo';
|
||||
window.io = require('socket.io-client');
|
||||
|
||||
Vue.use(modules);
|
||||
Vue.use(init);
|
||||
Vue.use(InertiaApp);
|
||||
Vue.component('checkbox', Checkbox);
|
||||
import FText from './components/FText.vue';
|
||||
|
||||
const app = document.getElementById('app')
|
||||
Vue.use(plugin)
|
||||
Vue.component('f-text', FText);
|
||||
|
||||
window.Echo = new Echo({
|
||||
broadcaster: 'socket.io',
|
||||
host: window.location.hostname+':'+document.querySelector('meta[name=socketport]').getAttribute('content'),
|
||||
});
|
||||
const el = document.getElementById('app')
|
||||
|
||||
new Vue({
|
||||
render: h => h(InertiaApp, {
|
||||
props: {
|
||||
initialPage: JSON.parse(app.dataset.page),
|
||||
resolveComponent: name => require(`./views/${name}`).default,
|
||||
},
|
||||
}),
|
||||
store
|
||||
}).$mount(app)
|
||||
render: h => h(App, {
|
||||
props: {
|
||||
initialPage: JSON.parse(el.dataset.page),
|
||||
resolveComponent: name => require(`./views/${name}`).default,
|
||||
},
|
||||
}),
|
||||
}).$mount(el);
|
||||
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<label class="flex flex-col relative field-checkbox cursor-pointer" :for="id" :class="{[`size-${size}`]: true}">
|
||||
<span v-if="label && inset" class="z-10 absolute top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700">{{ label }}</span>
|
||||
<div class="relative flex items-start">
|
||||
<input :id="id" type="checkbox" v-model="v" :disabled="disabled" class="invisible absolute" />
|
||||
<span class="display-wrapper flex items-center">
|
||||
<span class="relative cursor-pointer flex flex-none justify-center items-center display" :class="{'bg-terminoto-2': v === true, 'bg-white': v === false}">
|
||||
<sprite src="check" class="w-4 h-4 check-icon text-white"></sprite>
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="label && !inset" class="text-sm leading-tight ml-3 text-gray-700 checkbox-label flex items-center">
|
||||
<span>
|
||||
<span v-text="label" v-if="!html"></span>
|
||||
<span v-html="label" v-if="html"></span>
|
||||
<span v-show="required" class="font-semibold text-red-700">*</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
model: {
|
||||
prop: 'items',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
html: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
inset: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
default: null,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
required: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
default: false
|
||||
},
|
||||
label: {
|
||||
default: false
|
||||
},
|
||||
items: {
|
||||
default: undefined
|
||||
},
|
||||
size: {
|
||||
default: null,
|
||||
type: String
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
v: {
|
||||
set(v) {
|
||||
if (this.disabled === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof this.items === 'boolean') {
|
||||
this.$emit('input', v);
|
||||
return;
|
||||
}
|
||||
|
||||
var a = this.items.filter(i => i !== this.value);
|
||||
if (v) {
|
||||
a.push(this.value);
|
||||
}
|
||||
|
||||
this.$emit('input', a);
|
||||
},
|
||||
get() {
|
||||
if (typeof this.items === 'boolean') {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
if (typeof this.items === 'undefined') {
|
||||
return this.$emit('input', false);
|
||||
}
|
||||
|
||||
return this.items.indexOf(this.value) !== -1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (typeof this.items === 'undefined') {
|
||||
this.$emit('input', false);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
:root {
|
||||
--checkbox-width: 30px;
|
||||
--margin: 0.2rem;
|
||||
}
|
||||
|
||||
.field-checkbox {
|
||||
input:checked + span {
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.display-wrapper, .checkbox-label {
|
||||
min-height: 34px;
|
||||
}
|
||||
|
||||
.display {
|
||||
width: var(--checkbox-width);
|
||||
height: var(--checkbox-width);
|
||||
border-radius: 0.3rem;
|
||||
border: solid 2px hsl(60.0, 1.8%, 10.8%);
|
||||
.check-icon {
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
}
|
||||
input:checked + .display-wrapper .display .check-icon {
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,112 @@
|
|||
<template>
|
||||
<label class="flex flex-col relative" :for="id" :class="{['h-field-'+size]: inset === true}">
|
||||
<div class="relative h-full flex flex-col">
|
||||
<span v-if="label && !inset" class="font-semibold relative z-10 text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}<span v-show="required" class="text-red-800"> *</span></span>
|
||||
<span v-if="label && inset" class="absolute z-10 top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}" v-text="label"></span>
|
||||
<div class="relative h-full" :class="{['h-field-'+size]: inset === false}">
|
||||
<select :value="value" @change="trigger"
|
||||
class="border-gray-400 border-solid bg-white w-full appearance-none outline-none h-full"
|
||||
:class="{
|
||||
'rounded-lg text-sm border-2 p-2 text-gray-800': size === null,
|
||||
'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
|
||||
}"
|
||||
>
|
||||
<option v-if="placeholder" v-html="placeholder" :value="null"></option>
|
||||
|
||||
<option v-for="(option, key) in parsedOptions" :key="key"
|
||||
v-html="option" :value="key"
|
||||
></option>
|
||||
</select>
|
||||
|
||||
<div class="absolute pointer-events-none top-0 right-0 -mx-1 flex items-center h-full mr-4 cursor-pointer">
|
||||
<div v-if="hint" v-tooltip="hint" class="px-1">
|
||||
<sprite src="info-button" class="w-5 h-5 text-indigo-200"></sprite>
|
||||
</div>
|
||||
<div class="px-1 relative">
|
||||
<sprite class="w-3 h-3 fill-current" src="chevron-down"></sprite>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
id: {},
|
||||
inset: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
default: function() { return null; }
|
||||
},
|
||||
emptyLabel: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
},
|
||||
value: {
|
||||
default: undefined
|
||||
},
|
||||
label: {
|
||||
default: null
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
default: '--kein--',
|
||||
type: String
|
||||
},
|
||||
def: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
hint: {},
|
||||
options: {
|
||||
default: function() { return []; }
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
parsedOptions() {
|
||||
return this.options;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
trigger(v) {
|
||||
this.$emit('input', isNaN(parseInt(v.target.value))
|
||||
? (v.target.value ? v.target.value : null)
|
||||
: parseInt(v.target.value)
|
||||
);
|
||||
},
|
||||
clear() {
|
||||
this.$emit('input', null);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.def !== -1 && typeof this.value === 'undefined') {
|
||||
this.$emit('input', this.def);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.placeholder && typeof this.value === 'undefined') {
|
||||
this.$emit('input', null);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.inset-bg {
|
||||
background: linear-gradient(to bottom, hsl(247.5, 66.7%, 97.6%) 0%, hsl(247.5, 66.7%, 97.6%) 41%, hsl(0deg 0% 100%) 41%, hsl(180deg 0% 100%) 100%);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,219 @@
|
|||
<template>
|
||||
<label class="flex flex-col relative field-switch cursor-pointer" :for="id" :class="{[`size-${outerSize}`]: true}">
|
||||
<span v-if="label && !inset" class="font-semibold leading-none text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}</span>
|
||||
<span v-if="label && inset" class="z-10 absolute top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}</span>
|
||||
<div class="relative inner-field" :class="`h-field-${fieldSize}`">
|
||||
<input :id="id" type="checkbox" v-model="v" :disabled="disabled" class="invisible absolute" />
|
||||
<span class="relative cursor-pointer flex flex-grow display" :class="{'bg-primary': v === true, 'bg-gray-400': v === false}">
|
||||
<span><sprite class="relative text-white flex-none" :class="{'w-2 h-2': size === 'sm' || size == 'xs', 'w-6 h-6': size === null}" src="check"></sprite></span>
|
||||
<span><sprite class="relative text-white flex-none" :class="{'w-2 h-2': size === 'sm' || size == 'xs', 'w-6 h-6': size === null}" src="close"></sprite></span>
|
||||
<var class="absolute overlay bg-white rounded top-0"></var>
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
model: {
|
||||
prop: 'items',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
inset: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
size: {
|
||||
default: null,
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
required: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
default: false
|
||||
},
|
||||
label: {
|
||||
default: false
|
||||
},
|
||||
items: {
|
||||
default: undefined
|
||||
},
|
||||
size: {
|
||||
default: null,
|
||||
type: String
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
v: {
|
||||
set(v) {
|
||||
if (this.disabled === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof this.items === 'boolean') {
|
||||
this.$emit('input', v);
|
||||
return;
|
||||
}
|
||||
|
||||
var a = this.items.filter(i => i !== this.value);
|
||||
if (v) {
|
||||
a.push(this.value);
|
||||
}
|
||||
|
||||
this.$emit('input', a);
|
||||
},
|
||||
get() {
|
||||
if (typeof this.items === 'boolean') {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
if (typeof this.items === 'undefined') {
|
||||
return this.$emit('input', false);
|
||||
}
|
||||
|
||||
return this.items.indexOf(this.value) !== -1;
|
||||
}
|
||||
},
|
||||
fieldSize() {
|
||||
var sizes = ['xxs', 'xs', 'sm', 'md', 'lg'];
|
||||
|
||||
var sizeIndex = sizes.findIndex(s => s === this.size);
|
||||
return sizes[this.inset ? sizeIndex : sizeIndex - 1];
|
||||
},
|
||||
outerSize() {
|
||||
var sizes = ['xxs', 'xs', 'sm', 'md', 'lg'];
|
||||
|
||||
var sizeIndex = sizes.findIndex(s => s === this.size);
|
||||
if (!this.label || this.inset) { sizeIndex--; }
|
||||
return sizes[sizeIndex];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
:root {
|
||||
--margin: 0.2rem;
|
||||
--n-width: 2.5rem;
|
||||
--sm-width: 35px;
|
||||
--sm-margin: 0.2rem;
|
||||
--xs-width: 23px;
|
||||
--xs-margin: 0.2rem;
|
||||
}
|
||||
|
||||
.field-switch {
|
||||
input:checked + span {
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.display {
|
||||
width: calc(var(--n-width) * 2);
|
||||
height: var(--n-width);
|
||||
border-radius: 0.3rem;
|
||||
var {
|
||||
width: calc(var(--n-width) - var(--margin) * 2);
|
||||
height: calc(var(--n-width) - var(--margin) * 2);
|
||||
top: var(--margin);
|
||||
left: var(--margin);
|
||||
transition: left 0.3s;
|
||||
}
|
||||
& > span:nth-of-type(1) {
|
||||
position: absolute;
|
||||
width: calc(var(--n-width) - var(--margin));
|
||||
height: calc(var(--n-width) - var(--margin) * 2);
|
||||
top: var(--margin);
|
||||
left: var(--margin);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
& > span:nth-of-type(2) {
|
||||
position: absolute;
|
||||
width: calc(var(--n-width) - var(--margin));
|
||||
height: calc(var(--n-width) - var(--margin) * 2);
|
||||
top: var(--margin);
|
||||
left: calc(100% - var(--n-width));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
input:checked + .display var {
|
||||
left: calc(var(--n-width) + var(--margin));
|
||||
transition: left 0.3s;
|
||||
}
|
||||
|
||||
/* --------------------------------- small size ---------------------------------- */
|
||||
.inner-field.h-field-sm {
|
||||
input:checked + .display var {
|
||||
left: calc(var(--sm-width) + var(--sm-margin));
|
||||
}
|
||||
|
||||
.display {
|
||||
width: calc(var(--sm-width) * 2);
|
||||
height: var(--sm-width);
|
||||
var {
|
||||
width: calc(var(--sm-width) - var(--sm-margin) * 2);
|
||||
height: calc(var(--sm-width) - var(--sm-margin) * 2);
|
||||
top: var(--sm-margin);
|
||||
left: var(--sm-margin);
|
||||
}
|
||||
& > span:nth-of-type(1) {
|
||||
width: calc(var(--sm-width) - var(--sm-margin));
|
||||
height: calc(var(--sm-width) - var(--sm-margin) * 2);
|
||||
top: var(--sm-margin);
|
||||
left: var(--sm-margin);
|
||||
}
|
||||
& > span:nth-of-type(2) {
|
||||
width: calc(var(--sm-width) - var(--sm-margin));
|
||||
height: calc(var(--sm-width) - var(--sm-margin) * 2);
|
||||
top: var(--sm-margin);
|
||||
left: calc(100% - var(--sm-width));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ very small size -------------------------------- */
|
||||
.inner-field.h-field-xs {
|
||||
input:checked + .display var {
|
||||
left: calc(var(--xs-width) + var(--xs-margin));
|
||||
}
|
||||
|
||||
.display {
|
||||
width: calc(var(--xs-width) * 2);
|
||||
height: var(--xs-width);
|
||||
var {
|
||||
width: calc(var(--xs-width) - var(--xs-margin) * 2);
|
||||
height: calc(var(--xs-width) - var(--xs-margin) * 2);
|
||||
top: var(--xs-margin);
|
||||
left: var(--xs-margin);
|
||||
}
|
||||
& > span:nth-of-type(1) {
|
||||
width: calc(var(--xs-width) - var(--xs-margin));
|
||||
height: calc(var(--xs-width) - var(--xs-margin) * 2);
|
||||
top: var(--xs-margin);
|
||||
left: var(--xs-margin);
|
||||
}
|
||||
& > span:nth-of-type(2) {
|
||||
width: calc(var(--xs-width) - var(--xs-margin));
|
||||
height: calc(var(--xs-width) - var(--xs-margin) * 2);
|
||||
top: var(--xs-margin);
|
||||
left: calc(100% - var(--xs-width));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,245 @@
|
|||
<template>
|
||||
<label class="flex flex-col relative" :for="id" :class="{['h-field-'+size]: inset === true}">
|
||||
<div class="relative h-full flex flex-col">
|
||||
<span v-if="label && !inset" class="font-semibold relative z-10 text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}<span v-show="required" class="text-red-800"> *</span></span>
|
||||
<span v-if="label && inset" class="absolute z-10 top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}" v-text="label"></span>
|
||||
<div class="relative h-full" :class="{['h-field-'+size]: inset === false}">
|
||||
<input :type="type" :name="name" :value="transformedValue" @input="onInput" @change="onChange" :disabled="disabled" :placeholder="placeholder"
|
||||
@focus="onFocus" @blur="onBlur"
|
||||
class="border-gray-400 border-solid bg-white w-full appearance-none outline-none h-full"
|
||||
:class="{
|
||||
'rounded-lg text-sm border-2 p-2 text-gray-800': size === null,
|
||||
'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
|
||||
}"
|
||||
/>
|
||||
<div class="absolute top-0 right-0 -mx-1 flex items-center h-full cursor-pointer">
|
||||
<div v-if="hint" class="absolute top-0 right-0 h-full items-center mr-2 flex w-6" v-tooltip="hint">
|
||||
<sprite src="info-button" class="w-5 h-5 text-indigo-200"></sprite>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wNumb from 'wnumb';
|
||||
|
||||
var numb = {
|
||||
natural: wNumb({
|
||||
mark: ',',
|
||||
thousand: '.',
|
||||
decimals: 0,
|
||||
decoder(a) {
|
||||
return a * 100;
|
||||
},
|
||||
encoder(a) {
|
||||
return a / 100;
|
||||
}
|
||||
}),
|
||||
naturalRaw: wNumb({
|
||||
mark: '',
|
||||
thousand: '',
|
||||
decimals: 0,
|
||||
decoder(a) {
|
||||
return a * 100;
|
||||
},
|
||||
encoder(a) {
|
||||
return a / 100;
|
||||
}
|
||||
}),
|
||||
area: wNumb({
|
||||
mark: ',',
|
||||
thousand: '.',
|
||||
decimals: 2,
|
||||
decoder(a) {
|
||||
return a * 100;
|
||||
},
|
||||
encoder(a) {
|
||||
return a / 100;
|
||||
}
|
||||
}),
|
||||
twoDecimalRaw: wNumb({
|
||||
mark: ',',
|
||||
thousand: '',
|
||||
decimals: 2,
|
||||
decoder(a) {
|
||||
return a * 100;
|
||||
},
|
||||
encoder(a) {
|
||||
return a / 100;
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
var transformers = {
|
||||
none: {
|
||||
display: {
|
||||
to(v) { return v; },
|
||||
from(v) { return v; }
|
||||
},
|
||||
edit: {
|
||||
to(v) { return v; },
|
||||
from(v) { return v; }
|
||||
}
|
||||
},
|
||||
natural: {
|
||||
display: {
|
||||
to(v) { return isNaN(parseInt(v)) ? '' : numb.natural.to(v); },
|
||||
from(v) { return v === '' ? null : numb.natural.from(v); }
|
||||
},
|
||||
edit: {
|
||||
to(v) { return isNaN(parseInt(v)) ? '' : numb.naturalRaw.to(v); },
|
||||
from(v) { return v === '' ? null : numb.naturalRaw.from(v); }
|
||||
}
|
||||
},
|
||||
area: {
|
||||
display: {
|
||||
to(v) { return v === null ? '' : numb.area.to(v); },
|
||||
from(v) { return v === '' ? null : numb.area.from(v); }
|
||||
},
|
||||
edit: {
|
||||
to(v) {
|
||||
if (v === null) { return ''; }
|
||||
if (Math.round(v / 100) * 100 === v) { return numb.naturalRaw.to(v); }
|
||||
return numb.twoDecimalRaw.to(v);
|
||||
},
|
||||
from(v) {
|
||||
if (v === '') { return null; }
|
||||
if (v.indexOf(',') === -1) { return numb.naturalRaw.from(v); }
|
||||
|
||||
return numb.twoDecimalRaw.from(v);
|
||||
}
|
||||
}
|
||||
},
|
||||
currency: {
|
||||
display: {
|
||||
to(v) { return v === null ? '' : numb.area.to(v); },
|
||||
from(v) { return v === '' ? null : numb.area.from(v); }
|
||||
},
|
||||
edit: {
|
||||
to(v) {
|
||||
if (v === null) { return ''; }
|
||||
if (Math.round(v / 100) * 100 === v) { return numb.naturalRaw.to(v); }
|
||||
return numb.twoDecimalRaw.to(v);
|
||||
},
|
||||
from(v) {
|
||||
if (v === '') { return null; }
|
||||
if (v.indexOf(',') === -1) { return numb.naturalRaw.from(v); }
|
||||
|
||||
return numb.twoDecimalRaw.from(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
data: function() {
|
||||
return {
|
||||
focus: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
default: function() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
default: function() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
default: {},
|
||||
mode: {
|
||||
default: function() { return 'none'; }
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
inset: {
|
||||
default: function() {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
size: {
|
||||
default: null
|
||||
},
|
||||
id: {
|
||||
required: true
|
||||
},
|
||||
hint: {
|
||||
default: null
|
||||
},
|
||||
value: {
|
||||
default: undefined
|
||||
},
|
||||
mask: {
|
||||
default: undefined
|
||||
},
|
||||
label: {
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
required: false,
|
||||
default: function() { return 'text'; }
|
||||
},
|
||||
disabled: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onFocus() {
|
||||
this.focus = true;
|
||||
},
|
||||
onBlur() {
|
||||
this.focus = false;
|
||||
},
|
||||
onChange(v) {
|
||||
if (this.mode !== 'none') {
|
||||
this.transformedValue = v.target.value;
|
||||
}
|
||||
},
|
||||
onInput(v) {
|
||||
if (this.mode === 'none') {
|
||||
this.transformedValue = v.target.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
transformedValue: {
|
||||
get() {
|
||||
return transformers[this.mode][this.focus ? 'edit' : 'display'].to(this.value);
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', transformers[this.mode][this.focus ? 'edit' : 'display'].from(v));
|
||||
}
|
||||
},
|
||||
insetClass() {
|
||||
if (this.inset === '') { return 'bg-inset'; }
|
||||
if (this.inset === undefined) { return null; }
|
||||
|
||||
return `bg-${this.inset}`;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (typeof this.value === 'undefined') {
|
||||
this.$emit('input', this.default === undefined ? '' : this.default);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.bg-inset {
|
||||
background: linear-gradient(to bottom, hsl(247.5, 66.7%, 97.6%) 0%, hsl(247.5, 66.7%, 97.6%) 41%, hsl(0deg 0% 100%) 41%, hsl(180deg 0% 100%) 100%);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<label class="flex flex-col relative">
|
||||
<span v-if="label && !inset" class="font-semibold text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}<span v-show="required" class="text-red-800"> *</span></span>
|
||||
<span v-if="label && inset" class="absolute top-0 left-0 -mt-2 px-1 ml-3 inset-bg font-semibold text-gray-700" :class="{
|
||||
'text-xs': size == 'sm',
|
||||
'text-sm': size === null
|
||||
}">{{ label }}<span v-show="required" class="text-red-800"> *</span></span>
|
||||
<textarea v-text="value" @input="trigger" :placeholder="placeholder"
|
||||
class="h-full outline-none border-gray-400 border-solid" :rows="rows"
|
||||
:class="{
|
||||
'rounded-lg text-sm border-2 p-2 text-gray-800': size === null,
|
||||
'rounded-lg py-2 px-2 text-xs border-2 text-gray-800': size == 'sm'
|
||||
}"
|
||||
></textarea>
|
||||
<div v-if="hint" v-tooltip="hint" class="absolute right-0 top-0 mr-2 mt-2">
|
||||
<sprite src="info-button" class="w-5 h-5 text-indigo-200"></sprite>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: function() {
|
||||
return {
|
||||
focus: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
inset: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
},
|
||||
size: {
|
||||
default: null
|
||||
},
|
||||
rows: {
|
||||
default: function() {
|
||||
return 4;
|
||||
}
|
||||
},
|
||||
id: {
|
||||
required: true
|
||||
},
|
||||
hint: {
|
||||
default: null
|
||||
},
|
||||
value: {
|
||||
default: undefined
|
||||
},
|
||||
mask: {
|
||||
default: undefined
|
||||
},
|
||||
label: {
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
required: false,
|
||||
default: function() { return 'text'; }
|
||||
},
|
||||
placeholder: {
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
trigger(v) {
|
||||
this.$emit('input', v.target.value);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (typeof this.value === 'undefined') {
|
||||
this.$emit('input', '');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.inset-bg {
|
||||
background: linear-gradient(to bottom, hsl(247.5, 66.7%, 97.6%) 0%, hsl(247.5, 66.7%, 97.6%) 41%, hsl(0deg 0% 100%) 41%, hsl(180deg 0% 100%) 100%);
|
||||
}
|
||||
</style>
|
|
@ -1,35 +1,12 @@
|
|||
<template>
|
||||
<div class="app font-sans flex flex-col flex-grow">
|
||||
<notification :errors="$page.errors"></notification>
|
||||
<process></process>
|
||||
<wrapper
|
||||
admin-toolbar="adminToolbar"
|
||||
profile-toolbar="profileToolbar"
|
||||
search-background="bg-primary-600"
|
||||
>
|
||||
<template slot="mainnav">
|
||||
<mainnav name="main" sm></mainnav>
|
||||
</template>
|
||||
|
||||
<template slot="main">
|
||||
<slot />
|
||||
</template>
|
||||
</wrapper>
|
||||
<div class="font-sans flex flex-col flex-grow">
|
||||
<div>
|
||||
dfsfdsf
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Notification from 'agnoster/components/Notification.vue';
|
||||
import Process from 'agnoster/components/Progress.vue';
|
||||
import Wrapper from 'agnoster/components/Wrapper.vue';
|
||||
import Mainnav from 'agnoster/components/Mainnav.vue';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
title() {
|
||||
return this.$store.getters.title;
|
||||
}
|
||||
},
|
||||
components: { Notification, Wrapper, Mainnav, Process }
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
<template>
|
||||
<div id="app" class="font-sans flex flex-col flex-grow">
|
||||
<notification :errors="$page.errors"></notification>
|
||||
<fullpage>
|
||||
<div slot="brand-icon" slot-scope="{ cls }" :class="cls" class="py-2 flex justify-between items-center w-full">
|
||||
<span class="text-primary-200 text-lg">Login über NaMi</span>
|
||||
<img src="img/dpsg.gif" class="w-24">
|
||||
</div>
|
||||
<slot />
|
||||
</fullpage>
|
||||
<div id="app" class="bg-gray-200 font-sans flex flex-col flex-grow items-center justify-center">
|
||||
<div class="w-96 bg-white rounded-xl overflow-hidden shadow-lg">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Notification from 'agnoster/components/Notification.vue';
|
||||
import Fullpage from 'agnoster/components/Fullpage.vue';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
title() {
|
||||
return this.$store.getters.title;
|
||||
}
|
||||
},
|
||||
components: { Notification, Fullpage }
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
<template>
|
||||
<form @submit.prevent="submit">
|
||||
<grid fullsize>
|
||||
<item>
|
||||
<f-text label="Mitgliedsnummer" v-model="values.mglnr"></f-text>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<f-password label="Passwort" v-model="values.password"></f-password>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<f-text label="Gruppierungsnummer" v-model="values.groupid"></f-text>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<f-submit data-cy="submit" primary>Login</f-submit>
|
||||
</item>
|
||||
</grid>
|
||||
<div class="h-24 px-10 bg-primary flex justify-between items-center w-full">
|
||||
<span class="text-primary-200 text-lg">Login über NaMi</span>
|
||||
<img src="/img/dpsg.gif" class="w-24">
|
||||
</div>
|
||||
<div class="p-10 grid gap-5">
|
||||
<f-text id="mglnr" label="Mitgliedsnummer" v-model="values.mglnr"></f-text>
|
||||
<f-text id="password" type="password" label="Passwort" v-model="values.password"></f-text>
|
||||
<f-text id="groupid" name="groupid" label="Gruppierungsnummer" v-model="values.groupid"></f-text>
|
||||
<button type="submit" class="btn btn-primary">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -28,11 +21,7 @@ export default {
|
|||
|
||||
data: function() {
|
||||
return {
|
||||
values: {
|
||||
mglnr: 90166,
|
||||
password: 'ibm0g',
|
||||
groupid: 100105
|
||||
}
|
||||
values: {}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html class="h-full">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||
|
@ -7,7 +7,7 @@
|
|||
<link href="{{ mix('/css/app.css') }}" rel="stylesheet" />
|
||||
<script src="{{ mix('/js/app.js') }}" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="min-h-full flex flex-col">
|
||||
@inertia
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const mix = require('laravel-mix');
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const atImport = require("postcss-import");
|
||||
const nested = require('postcss-nested');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -14,9 +15,11 @@ const atImport = require("postcss-import");
|
|||
*/
|
||||
|
||||
mix.js('resources/js/app.js', 'public/js')
|
||||
.vue({ version: 2 })
|
||||
.postCss('resources/css/app.css', 'public/css', [
|
||||
atImport(),
|
||||
tailwindcss('./tailwind.config.js'),
|
||||
nested(),
|
||||
])
|
||||
.copy('resources/img', 'public/img')
|
||||
.sourceMaps();
|
||||
|
|
Loading…
Reference in New Issue