Compare commits

...

20 Commits

Author SHA1 Message Date
Philipp Lang 9e1fe63c33 Fix svg sprite
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2023-06-01 11:31:12 +02:00
Philipp Lang 1d8b5b4670 Mod gitignore 2023-06-01 11:07:48 +02:00
Philipp Lang 526f2d3a6c add vite config 2023-06-01 11:05:24 +02:00
Philipp Lang fbb501519a add vite script 2023-06-01 11:05:13 +02:00
Philipp Lang 3485832262 fix component names 2023-06-01 11:05:03 +02:00
Philipp Lang 4bece4a761 Remove tailwind component layer 2023-06-01 11:03:59 +02:00
Philipp Lang b2b53c558e Lint 2023-06-01 11:03:53 +02:00
Philipp Lang 2e5385b565 Add vite package 2023-06-01 11:03:14 +02:00
Philipp Lang 754e3a0a82 ignore build folder 2023-06-01 11:02:55 +02:00
philipp lang 4e27dbfe67 Move other components
continuous-integration/drone/push Build is failing Details
2023-05-20 02:48:08 +02:00
philipp lang c68f1e00c4 Move boolean display 2023-05-20 02:44:41 +02:00
philipp lang d78740d508 Add new slot scope syntax 2023-05-20 02:38:38 +02:00
philipp lang 641f3a1098 Lint 2023-05-20 01:59:20 +02:00
philipp lang dbbe6f6171 Remove links 2023-05-20 01:46:59 +02:00
philipp lang e26b572575 Move page header component 2023-05-20 01:45:43 +02:00
philipp lang a526683082 Add tooltip slot to sidebar header 2023-05-20 01:12:53 +02:00
philipp lang 07d309f606 Update Tailwindcss 2023-05-20 00:57:57 +02:00
philipp lang 234380120e Load page components synchronously 2023-05-20 00:57:05 +02:00
Philipp Lang 72375affee Move components
continuous-integration/drone/push Build is passing Details
2023-05-19 01:07:34 +02:00
Philipp Lang d01322b1ad Move component subfolders 2023-05-18 23:22:45 +02:00
64 changed files with 1181 additions and 7073 deletions

View File

@ -24,7 +24,7 @@ steps:
- name: node - name: node
image: node:17.9.0-slim image: node:17.9.0-slim
commands: commands:
- npm ci && npm run prod && npm run img && rm -R node_modules - npm ci && npm run img && npm run prod && rm -R node_modules
- name: phpunit_tests - name: phpunit_tests
image: php:8.1.6 image: php:8.1.6

10
.gitignore vendored
View File

@ -1,11 +1,7 @@
/node_modules /node_modules
/public/build
/public/sprite.svg
/public/hot /public/hot
/public/storage
/public/js
/public/css
/public/fonts
/public/img
/public/images
/storage/*.key /storage/*.key
/vendor /vendor
.env .env
@ -17,14 +13,12 @@ Homestead.yaml
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
tags tags
/public/vendor
/storage/temp /storage/temp
# Temporary files # Temporary files
*.swp *.swp
*.swo *.swo
*.swm *.swm
/public/mix-manifest.json
resources/img/sprite.svg resources/img/sprite.svg
/.php-cs-fixer.cache /.php-cs-fixer.cache
/data /data

7185
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,12 +2,12 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "npm run development", "dev": "npm run development",
"development": "npx mix build", "development": "npx vite",
"watch": "npx mix watch", "watch": "npx vite",
"hot": "npx mix watch --hot", "hot": "npx vite",
"prod": "npx mix build --production", "prod": "npx vite build",
"production": "npm run prod", "production": "npm run prod",
"img": "rm -R public/img && cd resources/img/svg && npx svg-sprite -s --symbol-dest=sprite *.svg && mv sprite/svg/sprite.css.svg ../sprite.svg && rm -R sprite && cd ../../../ && cp -R resources/img public/img", "img": "cd resources/img/svg && npx svg-sprite -s --symbol-dest=sprite *.svg && mv sprite/svg/sprite.css.svg ../../../public/sprite.svg && rm -R sprite",
"lint": "eslint \"resources/js/**/*.{js,vue}\"", "lint": "eslint \"resources/js/**/*.{js,vue}\"",
"fix": "eslint \"resources/js/**/*.{js,vue}\" --fix" "fix": "eslint \"resources/js/**/*.{js,vue}\" --fix"
}, },
@ -16,9 +16,8 @@
"axios": "^1.3.4", "axios": "^1.3.4",
"eslint": "^8.9.0", "eslint": "^8.9.0",
"eslint-plugin-vue": "^8.4.1", "eslint-plugin-vue": "^8.4.1",
"laravel-mix": "^6.0.1",
"postcss": "^8.4.6", "postcss": "^8.4.6",
"tailwindcss": "^3.2", "tailwindcss": "^3.3",
"vue": "2.7", "vue": "2.7",
"vue-axios": "^3.5.2", "vue-axios": "^3.5.2",
"vue-loader": "^15.9.8", "vue-loader": "^15.9.8",
@ -28,6 +27,9 @@
"@inertiajs/inertia": "^0.11.0", "@inertiajs/inertia": "^0.11.0",
"@inertiajs/inertia-vue": "^0.8.0", "@inertiajs/inertia-vue": "^0.8.0",
"@tailwindcss/typography": "^0.5.9", "@tailwindcss/typography": "^0.5.9",
"@vitejs/plugin-vue2": "^2.2.0",
"change-case": "^4.1.2",
"laravel-vite-plugin": "^0.7.7",
"leaflet": "^1.9.3", "leaflet": "^1.9.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"merge": "^2.1.1", "merge": "^2.1.1",
@ -36,6 +38,7 @@
"postcss-import": "^14.0.1", "postcss-import": "^14.0.1",
"svg-sprite": "^2.0.2", "svg-sprite": "^2.0.2",
"v-tooltip": "^2.1.3", "v-tooltip": "^2.1.3",
"vite": "^4.3.8",
"vue-toasted": "^1.1.28", "vue-toasted": "^1.1.28",
"vue2-leaflet": "^2.7.1", "vue2-leaflet": "^2.7.1",
"wnumb": "^1.2.0" "wnumb": "^1.2.0"

10
postcss.config.js vendored Normal file
View File

@ -0,0 +1,10 @@
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
'tailwindcss': {},
'autoprefixer': {},
},
};

22
resources/css/app.css vendored
View File

@ -2,15 +2,13 @@
@import 'tailwindcss/components'; @import 'tailwindcss/components';
@import 'tailwindcss/utilities'; @import 'tailwindcss/utilities';
@layer components { @import 'base.css';
@import 'base'; @import 'switch';
@import 'switch'; @import 'layout';
@import 'layout'; @import 'buttons';
@import 'buttons'; @import 'table';
@import 'table'; @import 'sidebar';
@import 'sidebar'; @import 'bool';
@import 'bool'; @import 'form';
@import 'form'; @import 'tooltip';
@import 'tooltip'; @import 'leaflet';
@import 'leaflet';
}

View File

@ -7,7 +7,6 @@
@apply mb-4; @apply mb-4;
} }
.form-control-font { .form-control-font {
@apply leading-tight text-gray-600 text-sm; @apply leading-tight text-gray-600 text-sm;
} }
@ -18,7 +17,8 @@
top: 34px; top: 34px;
transition: color 02s, padding-bottom 02s, font-size 02s, top 02s; transition: color 02s, padding-bottom 02s, font-size 02s, top 02s;
} }
.field-wrapperfocused label-placeholder, label-placeholder-focused { .field-wrapperfocused label-placeholder,
label-placeholder-focused {
top: 0; top: 0;
@apply text-sm text-gray-600; @apply text-sm text-gray-600;
padding-bottom: 10px; padding-bottom: 10px;
@ -42,24 +42,25 @@
@apply py-2; @apply py-2;
} }
input, select { input,
select {
outline: none; outline: none;
} }
input[type="date"], input[type='date'],
input[type="datetime-local"], input[type='datetime-local'],
input[type="time"], input[type='time'],
input[type="month"], input[type='month'],
select, select,
input[type="week"] { input[type='week'] {
height: 37px; height: 37px;
&::-webkit-inner-spin-button { &::-webkit-inner-spin-button {
display: none; display: none;
} }
} }
input[type="date"]::-webkit-inner-spin-button, input[type='date']::-webkit-inner-spin-button,
input[type="date"]::-webkit-calendar-picker-indicator { input[type='date']::-webkit-calendar-picker-indicator {
display: none; display: none;
-webkit-appearance: none; -webkit-appearance: none;
} }

View File

@ -82,10 +82,8 @@
} }
&.popover { &.popover {
$color: #f9f9f9;
.popover-inner { .popover-inner {
background: $color; background: #f9f9f9;
color: black; color: black;
padding: 24px; padding: 24px;
border-radius: 5px; border-radius: 5px;
@ -93,7 +91,7 @@
} }
.popover-arrow { .popover-arrow {
border-color: $color; border-color: #f9f9f9;
} }
} }

62
resources/js/app.js vendored
View File

@ -1,64 +1,50 @@
import Vue from 'vue'; import Vue from 'vue';
import {App as InertiaApp, plugin, Link as ILink} from '@inertiajs/inertia-vue'; import {App as InertiaApp, plugin, Link as ILink} from '@inertiajs/inertia-vue';
import {Inertia} from '@inertiajs/inertia'; import {Inertia} from '@inertiajs/inertia';
import SvgSprite from './components/SvgSprite.js';
import VPages from './components/VPages.vue';
import VLabel from './components/VLabel.vue';
import VBool from './components/VBool.vue';
import Box from './components/Box.vue';
import Heading from './components/Heading.vue';
import IconButton from './components/Ui/IconButton.vue';
import ToolbarButton from './components/Ui/ToolbarButton.vue';
import PageLayout from './components/Page/Layout.vue';
import AppLayout from './layouts/AppLayout.vue';
import VTooltip from 'v-tooltip';
import hasModule from './mixins/hasModule.js';
import hasFlash from './mixins/hasFlash.js';
import PortalVue from 'portal-vue'; import PortalVue from 'portal-vue';
import axios from 'axios'; import axios from 'axios';
import VueAxios from 'vue-axios'; import VueAxios from 'vue-axios';
import Toasted from 'vue-toasted'; import Toasted from 'vue-toasted';
import VTooltip from 'v-tooltip';
import {createPinia, PiniaVuePlugin} from 'pinia'; import {createPinia, PiniaVuePlugin} from 'pinia';
import requireModules from './lib/requireModules.js';
import AppLayout from './layouts/AppLayout.vue';
import hasModule from './mixins/hasModule.js';
import hasFlash from './mixins/hasFlash.js';
import '../css/app.css';
// ---------------------------------- Assets -----------------------------------
import.meta.glob(['../img/**']);
// ---------------------------------- Plugins ----------------------------------
Vue.use(plugin); Vue.use(plugin);
Vue.use(PortalVue); Vue.use(PortalVue);
Vue.use(VTooltip); Vue.use(VTooltip);
Vue.use(Toasted); Vue.use(Toasted);
Vue.use(VueAxios, axios); Vue.use(VueAxios, axios);
Vue.use(PiniaVuePlugin); Vue.use(PiniaVuePlugin);
Vue.component('f-text', () => import(/* webpackChunkName: "form" */ './components/FText'));
Vue.component('f-switch', () => import(/* webpackChunkName: "form" */ './components/FSwitch'));
Vue.component('f-select', () => import(/* webpackChunkName: "form" */ './components/FSelect'));
Vue.component('f-textarea', () => import(/* webpackChunkName: "form" */ './components/FTextarea'));
Vue.component('SvgSprite', SvgSprite);
Vue.component('VPages', VPages);
Vue.component('v-bool', VBool);
Vue.component('v-label', VLabel);
Vue.component('box', Box);
Vue.component('heading', Heading);
Vue.component('icon-button', IconButton);
Vue.component('toolbar-button', ToolbarButton);
Vue.component('page-layout', PageLayout);
Vue.component('save-button', () => import(/* webpackChunkName: "form" */ './components/SaveButton'));
// ------------------------------ Full components ------------------------------ Vue.component('SvgSprite', () => import('./components/SvgSprite.js'));
Vue.component('full-page-heading', () => import(/* webpackChunkName: "full" */ './components/Full/PageHeading.vue')); Vue.component('ILink', ILink);
// ------------------------------- UI Components ------------------------------- // -------------------------------- Components ---------------------------------
Vue.component('ui-button', () => import(/* webpackChunkName: "ui" */ './components/Ui/Button.vue')); requireModules(import.meta.glob('./components/form/*.vue'), Vue, 'f');
Vue.component('ui-spinner', () => import(/* webpackChunkName: "ui" */ './components/Ui/Spinner.vue')); requireModules(import.meta.glob('./components/ui/*.vue'), Vue, 'ui');
requireModules(import.meta.glob('./components/page/*.vue', {eager: true}), Vue, 'page');
// ---------------------------------- mixins -----------------------------------
Vue.mixin(hasModule);
Vue.mixin(hasFlash);
// ----------------------------------- init ------------------------------------ // ----------------------------------- init ------------------------------------
const el = document.getElementById('app'); const el = document.getElementById('app');
const pinia = createPinia(); const pinia = createPinia();
Vue.mixin(hasModule);
Vue.mixin(hasFlash);
Vue.component('ILink', ILink);
Inertia.on('start', (event) => window.dispatchEvent(new Event('inertiaStart'))); Inertia.on('start', (event) => window.dispatchEvent(new Event('inertiaStart')));
let views = import.meta.glob('./views/**/*.vue');
new Vue({ new Vue({
pinia, pinia,
render: (h) => render: (h) =>
@ -66,7 +52,7 @@ new Vue({
props: { props: {
initialPage: JSON.parse(el.dataset.page), initialPage: JSON.parse(el.dataset.page),
resolveComponent: async (name) => { resolveComponent: async (name) => {
var page = (await import(`./views/${name}`)).default; var page = (await views[`./views/${name}.vue`]()).default;
if (page.layout === undefined) { if (page.layout === undefined) {
page.layout = AppLayout; page.layout = AppLayout;

View File

@ -1,144 +0,0 @@
<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}"
>
<svg-sprite src="check" class="w-4 h-4 check-icon text-white"></svg-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,
},
},
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, 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>

View File

@ -1,9 +0,0 @@
<template>
<div class="font-semibold text-gray-300">
<slot></slot>
</div>
</template>
<script>
export default {};
</script>

View File

@ -1,48 +0,0 @@
<template>
<div class="h-16 px-6 flex justify-between items-center border-b border-solid border-gray-500">
<div class="flex items-center">
<span class="mr-1 text-xl font-semibold leading-none text-white" v-html="title"></span>
<a
v-for="(link, index) in links.filter((link) => link.icon === undefined)"
:key="index"
@click.prevent="$emit(link.event)"
href="#"
class="btn label btn-primary-light"
>
<span v-if="link.label" v-text="link.label"></span>
<svg-sprite v-if="link.icon" :src="link.icon"></svg-sprite>
</a>
<a
v-for="(link, index) in links.filter((link) => link.icon !== undefined)"
:key="index"
:href="link.href"
class="btn label icon btn-primary-light ml-1"
>
<span v-if="link.label" v-text="link.label"></span>
<svg-sprite v-if="link.icon" :src="link.icon"></svg-sprite>
</a>
</div>
<div class="flex ml-4">
<a href="#" @click.prevent="$emit('close')" class="btn label btn-primary-light icon">
<svg-sprite class="w-3 h-3" src="close"></svg-sprite>
</a>
</div>
</div>
</template>
<script>
export default {
props: {
links: {
default: function () {
return [];
},
},
title: {
default: function () {
return '';
},
},
},
};
</script>

View File

@ -1,17 +1,25 @@
export default { export default {
props: { props: {
src: { required: true, type: String } src: {required: true, type: String},
}, },
render: function(createElement) { render: function (createElement) {
var attr = this.$attrs.class ? this.$attrs.class : ''; var attr = this.$attrs.class ? this.$attrs.class : '';
return createElement('svg', { return createElement(
class: attr + ' fill-current' 'svg',
}, [ {
createElement('use', { class: attr + ' fill-current',
'attrs': { },
'xlink:href': `/img/sprite.svg#${this.$props.src}` [
} createElement(
}, '') 'use',
] ); {
} attrs: {
'xlink:href': `/sprite.svg#${this.$props.src}`,
},
},
''
),
]
);
},
}; };

View File

@ -0,0 +1,27 @@
<template>
<div class="h-16 px-6 flex items-center justify-between border-b border-solid border-gray-600 group-[.is-bright]:border-gray-500">
<div class="flex items-center space-x-2">
<slot name="before-title"></slot>
<page-title>{{ title }}</page-title>
<slot name="toolbar"></slot>
</div>
<div class="flex items-center space-x-2 ml-2">
<a href="#" v-if="$listeners.close" @click.prevent="$emit('close')" class="btn label btn-primary-light icon">
<svg-sprite class="w-3 h-3" src="close"></svg-sprite>
</a>
<slot name="right"></slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
default: function () {
return '';
},
},
},
};
</script>

View File

@ -1,16 +1,18 @@
<template> <template>
<div class="grow bg-gray-900 flex flex-col transition-all" :class="{'ml-56': menuStore.visible, 'ml-0': !menuStore.visible}"> <div class="grow bg-gray-900 flex flex-col transition-all" :class="{'ml-56': menuStore.visible, 'ml-0': !menuStore.visible}">
<div class="h-16 px-6 flex items-center space-x-3 border-b border-gray-600"> <page-header :title="$page.props.title">
<a href="#" @click.prevent="menuStore.toggle()" class="lg:hidden"> <template #before-title>
<svg-sprite src="menu" class="text-gray-100 w-5 h-5"></svg-sprite> <a href="#" @click.prevent="menuStore.toggle()" class="mr-2 lg:hidden">
</a> <svg-sprite src="menu" class="text-gray-100 w-5 h-5"></svg-sprite>
<span class="text-sm md:text-xl font-semibold text-white leading-none" v-html="$page.props.title"></span> </a>
<slot name="toolbar"></slot> </template>
<div class="flex grow justify-between"> <template #toolbar>
<portal-target name="toolbar-left"> </portal-target> <slot name="toolbar"></slot>
</template>
<template #right>
<portal-target name="toolbar-right"> </portal-target> <portal-target name="toolbar-right"> </portal-target>
</div> </template>
</div> </page-header>
<div :class="pageClass" class="grow flex flex-col"> <div :class="pageClass" class="grow flex flex-col">
<slot></slot> <slot></slot>

View File

@ -0,0 +1,7 @@
<template>
<span class="text-sm md:text-xl font-semibold leading-none text-white"><slot></slot></span>
</template>
<script>
export default {};
</script>

View File

@ -1,5 +1,5 @@
<template> <template>
<i-link :href="href" class="btn label mr-2" :class="colors[color]" v-tooltip="menuStore.tooltipsVisible ? $slots.default[0].text : ''"> <i-link :href="href" v-on="$listeners" class="btn label" :class="colors[color]" v-tooltip="menuStore.tooltipsVisible ? $slots.default[0].text : ''">
<svg-sprite v-show="icon" class="w-3 h-3 xl:mr-2" :src="icon"></svg-sprite> <svg-sprite v-show="icon" class="w-3 h-3 xl:mr-2" :src="icon"></svg-sprite>
<span class="hidden xl:inline"><slot></slot></span> <span class="hidden xl:inline"><slot></slot></span>
</i-link> </i-link>

View File

@ -1,14 +1,7 @@
<template> <template>
<div v-tooltip="longLabel" class="flex space-x-2 items-center"> <div v-tooltip="longLabel" class="flex space-x-2 items-center">
<div <div class="border-2 rounded-full w-5 h-5 flex items-center justify-center" :class="value ? 'border-green-700' : 'border-red-700'">
class="border-2 rounded-full w-4 h-4 flex items-center justify-center" <svg-sprite :src="value ? 'check' : 'close'" :class="value ? 'text-green-800' : 'text-red-800'" class="w-3 h-3 flex-none"></svg-sprite>
:class="value ? 'border-green-700' : 'border-red-700'"
>
<svg-sprite
:src="value ? 'check' : 'close'"
:class="value ? 'text-green-800' : 'text-red-800'"
class="w-3 h-3 flex-none"
></svg-sprite>
</div> </div>
<div class="text-gray-400 text-xs" v-text="label"></div> <div class="text-gray-400 text-xs" v-text="label"></div>
</div> </div>

View File

@ -1,7 +1,7 @@
<template> <template>
<section class="p-3 rounded-lg flex flex-col" :class="{'bg-gray-800': second === false, 'bg-gray-700': second === true}"> <section class="p-3 rounded-lg flex flex-col" :class="{'bg-gray-800': second === false, 'bg-gray-700': second === true}">
<div class="flex items-center"> <div class="flex items-center">
<heading class="col-span-full" v-if="heading">{{ heading }}</heading> <div class="col-span-full font-semibold text-gray-300" v-if="heading" v-text="heading"></div>
<slot name="in-title"></slot> <slot name="in-title"></slot>
</div> </div>
<main :class="{'mt-2': heading, [containerClass]: true}"> <main :class="{'mt-2': heading, [containerClass]: true}">

9
resources/js/lib/requireModules.js vendored Normal file
View File

@ -0,0 +1,9 @@
import {paramCase} from 'change-case';
export default function (context, Vue, prefix) {
for (const file in context) {
let componentName = paramCase(`${prefix}${file.replace(/^.*\/(.*?)\.vue$/g, '$1')}`);
Vue.component(componentName, typeof context[file] === 'function' ? context[file] : context[file].default);
}
}

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div v-if="step === 0"> <div v-if="step === 0">
<full-page-heading>Willkommen im Adrema-Setup.<br /></full-page-heading> <page-full-heading>Willkommen im Adrema-Setup.<br /></page-full-heading>
<div class="prose prose-invert"> <div class="prose prose-invert">
<p>Bitte gib deine NaMi-Zugangsdaten ein,<br />um eine erste Synchronisation durchzuführen.</p> <p>Bitte gib deine NaMi-Zugangsdaten ein,<br />um eine erste Synchronisation durchzuführen.</p>
</div> </div>
@ -12,7 +12,7 @@
</form> </form>
</div> </div>
<div v-if="step === 1" class="grid grid-cols-5 w-full gap-3"> <div v-if="step === 1" class="grid grid-cols-5 w-full gap-3">
<full-page-heading class="col-span-full !mb-0">Suchkriterien festlegen</full-page-heading> <page-full-heading class="col-span-full !mb-0">Suchkriterien festlegen</page-full-heading>
<form @submit.prevent="storeSearch" class="border-2 border-primary-800 border-solid p-3 rounded-lg grid gap-3 col-span-2"> <form @submit.prevent="storeSearch" class="border-2 border-primary-800 border-solid p-3 rounded-lg grid gap-3 col-span-2">
<div class="prose prose-invert max-w-none col-span-full"> <div class="prose prose-invert max-w-none col-span-full">
<p> <p>
@ -105,13 +105,13 @@
</table> </table>
<div v-if="preview !== null" class="px-6"> <div v-if="preview !== null" class="px-6">
<v-pages class="mt-4" :value="preview" @reload="reloadPage"></v-pages> <ui-pagination class="mt-4" :value="preview" @reload="reloadPage"></ui-pagination>
</div> </div>
</section> </section>
<section class="col-span-3 items-center justify-center flex text-xl text-gray-200 border-2 border-primary-800 border-solid p-3 rounded-lg mt-4" v-else>Keine Mitglieder gefunden</section> <section class="col-span-3 items-center justify-center flex text-xl text-gray-200 border-2 border-primary-800 border-solid p-3 rounded-lg mt-4" v-else>Keine Mitglieder gefunden</section>
</div> </div>
<div v-if="step === 2"> <div v-if="step === 2">
<full-page-heading>Standard-Gruppierung</full-page-heading> <page-full-heading>Standard-Gruppierung</page-full-heading>
<div class="prose prose-invert"> <div class="prose prose-invert">
<p>Bitte gib hier deine Standard-Gruppierungsnummer ein.</p> <p>Bitte gib hier deine Standard-Gruppierungsnummer ein.</p>
<p>Dieser Gruppierung werden Mitglieder automatisch zugeordnet,<br />falls nichts anderes angegeben wurde.</p> <p>Dieser Gruppierung werden Mitglieder automatisch zugeordnet,<br />falls nichts anderes angegeben wurde.</p>
@ -123,7 +123,7 @@
</form> </form>
</div> </div>
<div v-if="step === 3"> <div v-if="step === 3">
<full-page-heading>Einrichtung abgeschlossen</full-page-heading> <page-full-heading>Einrichtung abgeschlossen</page-full-heading>
<div class="prose prose-invert"> <div class="prose prose-invert">
<p>Wir werden nun die Mitgliederdaten anhand deiner festgelegten Kriterien abrufen.</p> <p>Wir werden nun die Mitgliederdaten anhand deiner festgelegten Kriterien abrufen.</p>
<p>Per Klick auf "Abschließen" gelangst du zum Dashboard</p> <p>Per Klick auf "Abschließen" gelangst du zum Dashboard</p>

View File

@ -2,7 +2,7 @@
<form @submit.prevent="submit"> <form @submit.prevent="submit">
<div class="h-24 p-6 md:px-10 bg-primary-800 flex justify-between items-center w-full"> <div class="h-24 p-6 md:px-10 bg-primary-800 flex justify-between items-center w-full">
<span class="text-primary-500 text-xl">Login</span> <span class="text-primary-500 text-xl">Login</span>
<img src="/img/dpsg.gif" class="w-24" /> <img src="../../img/dpsg.gif" class="w-24" />
</div> </div>
<div class="p-6 md:p-10 grid gap-5"> <div class="p-6 md:p-10 grid gap-5">
<f-text id="email" label="E-Mail-Adresse" v-model="values.email"></f-text> <f-text id="email" label="E-Mail-Adresse" v-model="values.email"></f-text>
@ -13,7 +13,7 @@
</template> </template>
<script> <script>
import FullLayout from '../layouts/FullLayout'; import FullLayout from '../layouts/FullLayout.vue';
export default { export default {
layout: FullLayout, layout: FullLayout,

View File

@ -4,7 +4,7 @@
<f-text size="sm" id="name" v-model="model.name" label="Name" required></f-text> <f-text size="sm" id="name" v-model="model.name" label="Name" required></f-text>
<f-switch size="sm" v-model="model.is_filterable" name="subactivity_is_filterable" id="subactivity_is_filterable" label="Filterbar"></f-switch> <f-switch size="sm" v-model="model.is_filterable" name="subactivity_is_filterable" id="subactivity_is_filterable" label="Filterbar"></f-switch>
</div> </div>
<icon-button class="mt-3" icon="save" @click.prevent="store">Speichern</icon-button> <ui-icon-button class="mt-3" icon="save" @click.prevent="store">Speichern</ui-icon-button>
</div> </div>
</template> </template>

View File

@ -1,19 +1,19 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button> <page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
</div> </template>
<form id="actionform" class="grow p-3" @submit.prevent="submit"> <form id="actionform" class="grow p-3" @submit.prevent="submit">
<popup heading="Neue Untertätigkeit" v-if="mode === 'edit' && currentSubactivity !== null" @close="currentSubactivity = null"> <ui-popup heading="Neue Untertätigkeit" v-if="mode === 'edit' && currentSubactivity !== null" @close="currentSubactivity = null">
<subactivity-form class="mt-4" v-if="currentSubactivity" :value="currentSubactivity" @stored="reloadSubactivities" @updated="mergeSubactivity"></subactivity-form> <subactivity-form class="mt-4" v-if="currentSubactivity" :value="currentSubactivity" @stored="reloadSubactivities" @updated="mergeSubactivity"></subactivity-form>
</popup> </ui-popup>
<div class="flex space-x-3"> <div class="flex space-x-3">
<f-text id="name" v-model="inner.name" label="Name" required></f-text> <f-text id="name" v-model="inner.name" label="Name" required></f-text>
<f-switch v-model="inner.is_filterable" name="is_filterable" id="is_filterable" label="Filterbar"></f-switch> <f-switch v-model="inner.is_filterable" name="is_filterable" id="is_filterable" label="Filterbar"></f-switch>
</div> </div>
<div class="flex space-x-3 items-center mt-6 mb-2"> <div class="flex space-x-3 items-center mt-6 mb-2">
<checkboxes-label>Untertätigkeiten</checkboxes-label> <f-checkboxes-label>Untertätigkeiten</f-checkboxes-label>
<icon-button icon="plus" v-if="mode === 'edit'" @click.prevent="currentSubactivity = inner.subactivity_model">Neu</icon-button> <ui-icon-button icon="plus" v-if="mode === 'edit'" @click.prevent="currentSubactivity = inner.subactivity_model">Neu</ui-icon-button>
</div> </div>
<div class="grid gap-2 sm:grid-cols-2 md:grid-cols-4"> <div class="grid gap-2 sm:grid-cols-2 md:grid-cols-4">
<div v-for="option in subactivities" class="flex items-center space-x-2"> <div v-for="option in subactivities" class="flex items-center space-x-2">
@ -32,7 +32,7 @@
></f-switch> ></f-switch>
</div> </div>
</div> </div>
<save-button form="actionform"></save-button> <f-save-button form="actionform"></f-save-button>
</form> </form>
</page-layout> </page-layout>
</template> </template>
@ -54,9 +54,7 @@ export default {
}, },
components: { components: {
'checkboxes-label': () => import('../../components/Form/CheckboxesLabel'),
'subactivity-form': () => import('./SubactivityForm.vue'), 'subactivity-form': () => import('./SubactivityForm.vue'),
'popup': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
}, },
methods: { methods: {

View File

@ -1,9 +1,9 @@
<template> <template>
<page-layout page-class="pb-6"> <page-layout page-class="pb-6">
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Tätigkeit erstellen</toolbar-button> <page-toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Tätigkeit erstellen</page-toolbar-button>
</div> </template>
<popup heading="Bitte bestätigen" v-if="deleting !== null"> <ui-popup heading="Bitte bestätigen" v-if="deleting !== null">
<div> <div>
<p class="mt-4">Diese Aktivität löschen?</p> <p class="mt-4">Diese Aktivität löschen?</p>
<div class="grid grid-cols-2 gap-3 mt-6"> <div class="grid grid-cols-2 gap-3 mt-6">
@ -11,7 +11,7 @@
<a href="#" @click.prevent="deleting = null" class="text-center btn btn-primary">Abbrechen</a> <a href="#" @click.prevent="deleting = null" class="text-center btn btn-primary">Abbrechen</a>
</div> </div>
</div> </div>
</popup> </ui-popup>
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table"> <table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table">
<thead> <thead>
<th>Name</th> <th>Name</th>
@ -30,7 +30,7 @@
</table> </table>
<div class="px-6"> <div class="px-6">
<v-pages class="mt-4" :value="data.meta" :only="['data']"></v-pages> <ui-pagination class="mt-4" :value="data.meta" :only="['data']"></ui-pagination>
</div> </div>
</page-layout> </page-layout>
</template> </template>
@ -58,10 +58,6 @@ export default {
}, },
}, },
components: {
popup: () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
},
mixins: [indexHelpers], mixins: [indexHelpers],
}; };
</script> </script>

View File

@ -16,7 +16,7 @@ export default {
}, },
components: { components: {
'VBlock': () => import('./VBlock'), 'VBlock': () => import('./VBlock.vue'),
'age-group-count': () => import('./AgeGroupCount.vue'), 'age-group-count': () => import('./AgeGroupCount.vue'),
'efz-pending': () => import('./EfzPending.vue'), 'efz-pending': () => import('./EfzPending.vue'),
'ps-pending': () => import('./PsPending.vue'), 'ps-pending': () => import('./PsPending.vue'),

View File

@ -1,25 +1,15 @@
<template> <template>
<div class="sidebar flex flex-col"> <div class="sidebar flex flex-col group is-bright">
<sidebar-header <page-header @close="$emit('close')" title="Ausbildungen">
:links="indexLinks" <template #toolbar>
@close="$emit('close')" <page-toolbar-button @click.prevent="create" color="primary" icon="plus" v-if="single === null">Neue Ausbildung</page-toolbar-button>
@create=" <page-toolbar-button @click.prevent="cancel" color="primary" icon="undo" v-if="single !== null">Zurück</page-toolbar-button>
mode = 'create'; </template>
single = {}; </page-header>
"
title="Ausbildungen"
></sidebar-header>
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit"> <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<f-text id="completed_at" type="date" v-model="single.completed_at" label="Datum" required></f-text> <f-text id="completed_at" type="date" v-model="single.completed_at" label="Datum" required></f-text>
<f-select <f-select id="course_id" name="course_id" :options="courses" v-model="single.course_id" label="Baustein" required></f-select>
id="course_id"
name="course_id"
:options="courses"
v-model="single.course_id"
label="Baustein"
required
></f-select>
<f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required></f-text> <f-text id="event_name" v-model="single.event_name" label="Veranstaltung" required></f-text>
<f-text id="organizer" v-model="single.organizer" label="Veranstalter" required></f-text> <f-text id="organizer" v-model="single.organizer" label="Veranstalter" required></f-text>
<button type="submit" class="btn btn-primary">Absenden</button> <button type="submit" class="btn btn-primary">Absenden</button>
@ -50,9 +40,7 @@
class="inline-flex btn btn-warning btn-sm" class="inline-flex btn btn-warning btn-sm"
><svg-sprite src="pencil"></svg-sprite ><svg-sprite src="pencil"></svg-sprite
></a> ></a>
<i-link href="#" @click.prevent="remove(course)" class="inline-flex btn btn-danger btn-sm" <i-link href="#" @click.prevent="remove(course)" class="inline-flex btn btn-danger btn-sm"><svg-sprite src="trash"></svg-sprite></i-link>
><svg-sprite src="trash"></svg-sprite
></i-link>
</td> </td>
</tr> </tr>
</table> </table>
@ -61,14 +49,11 @@
</template> </template>
<script> <script>
import SidebarHeader from '../../components/SidebarHeader.vue';
export default { export default {
data: function () { data: function () {
return { return {
mode: null, mode: null,
single: null, single: null,
indexLinks: [{event: 'create', label: 'Neuer Kurs'}],
}; };
}, },
@ -77,9 +62,14 @@ export default {
value: {}, value: {},
}, },
components: {SidebarHeader},
methods: { methods: {
create() {
this.mode = 'create';
this.single = {};
},
cancel() {
this.mode = this.single = null;
},
remove(payment) { remove(payment) {
this.$inertia.delete(`/member/${this.value.id}/course/${payment.id}`); this.$inertia.delete(`/member/${this.value.id}/course/${payment.id}`);
}, },

View File

@ -1,34 +1,15 @@
<template> <template>
<div class="sidebar flex flex-col"> <div class="sidebar flex flex-col group is-bright">
<sidebar-header <page-header @close="$emit('close')" title="Mitgliedschaften">
:links="links" <template #toolbar>
@create=" <page-toolbar-button @click.prevent="create" color="primary" icon="plus" v-if="single === null">Neue Mitgliedschaft</page-toolbar-button>
mode = 'create'; <page-toolbar-button @click.prevent="cancel" color="primary" icon="undo" v-if="single !== null">Zurück</page-toolbar-button>
single = {...def}; </template>
" </page-header>
@close="$emit('close')"
title="Mitgliedschaften"
></sidebar-header>
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit"> <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<f-select <f-select id="group_id" name="group_id" :options="groups" v-model="single.group_id" label="Gruppierung" size="sm" required></f-select>
id="group_id" <f-select id="activity_id" name="activity_id" :options="activities" v-model="single.activity_id" label="Tätigkeit" size="sm" required></f-select>
name="group_id"
:options="groups"
v-model="single.group_id"
label="Gruppierung"
size="sm"
required
></f-select>
<f-select
id="activity_id"
name="activity_id"
:options="activities"
v-model="single.activity_id"
label="Tätigkeit"
size="sm"
required
></f-select>
<f-select <f-select
v-if="single.activity_id" v-if="single.activity_id"
name="subactivity_id" name="subactivity_id"
@ -38,21 +19,8 @@
label="Untertätigkeit" label="Untertätigkeit"
size="sm" size="sm"
></f-select> ></f-select>
<f-switch <f-switch id="has_promise" :items="single.promised_at !== null" @input="single.promised_at = $event ? '2000-02-02' : null" size="sm" label="Hat Versprechen"></f-switch>
id="has_promise" <f-text v-show="single.promised_at !== null" type="date" id="promised_at" v-model="single.promised_at" label="Versprechensdatum" size="sm"></f-text>
:items="single.promised_at !== null"
@input="single.promised_at = $event ? '2000-02-02' : null"
size="sm"
label="Hat Versprechen"
></f-switch>
<f-text
v-show="single.promised_at !== null"
type="date"
id="promised_at"
v-model="single.promised_at"
label="Versprechensdatum"
size="sm"
></f-text>
<button type="submit" class="btn btn-primary">Absenden</button> <button type="submit" class="btn btn-primary">Absenden</button>
</form> </form>
@ -79,9 +47,7 @@
class="inline-flex btn btn-warning btn-sm" class="inline-flex btn btn-warning btn-sm"
><svg-sprite src="pencil"></svg-sprite ><svg-sprite src="pencil"></svg-sprite
></a> ></a>
<i-link href="#" @click.prevent="remove(membership)" class="inline-flex btn btn-danger btn-sm" <i-link href="#" @click.prevent="remove(membership)" class="inline-flex btn btn-danger btn-sm"><svg-sprite src="trash"></svg-sprite></i-link>
><svg-sprite src="trash"></svg-sprite
></i-link>
</td> </td>
</tr> </tr>
</table> </table>
@ -90,31 +56,33 @@
</template> </template>
<script> <script>
import SidebarHeader from '../../components/SidebarHeader.vue';
export default { export default {
data: function () { data: function () {
return { return {
mode: null, mode: null,
single: null, single: null,
links: [{event: 'create', label: 'Neu'}],
}; };
}, },
components: {SidebarHeader},
computed: { computed: {
def() { def() {
return { return {
group_id: this.value.group_id, group_id: this.value.group_id,
activity_id: null, activity_id: null,
subactivity_id: null, subactivity_id: null,
promised_at: null promised_at: null,
}; };
} },
}, },
methods: { methods: {
create() {
this.mode = 'create';
this.single = {...this.def};
},
cancel() {
this.mode = this.single = null;
},
remove(membership) { remove(membership) {
this.$inertia.delete(`/member/${this.value.id}/membership/${membership.id}`); this.$inertia.delete(`/member/${this.value.id}/membership/${membership.id}`);
}, },

View File

@ -1,33 +1,16 @@
<template> <template>
<div class="sidebar flex flex-col"> <div class="sidebar flex flex-col group is-bright">
<sidebar-header <page-header @close="$emit('close')" title="Zahlungen">
:links="indexLinks" <template #toolbar>
@close="$emit('close')" <page-toolbar-button @click.prevent="create" color="primary" icon="plus" v-if="single === null">Neue Zahlung</page-toolbar-button>
@create=" <page-toolbar-button @click.prevent="cancel" color="primary" icon="undo" v-if="single !== null">Zurück</page-toolbar-button>
mode = 'create'; </template>
single = {}; </page-header>
"
title="Zahlungen"
></sidebar-header>
<form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit"> <form v-if="single" class="p-6 grid gap-4 justify-start" @submit.prevent="submit">
<f-text id="nr" v-model="single.nr" label="Jahr" required></f-text> <f-text id="nr" v-model="single.nr" label="Jahr" required></f-text>
<f-select <f-select id="subscription_id" name="subscription_id" :options="subscriptions" v-model="single.subscription_id" label="Beitrag" required></f-select>
id="subscription_id" <f-select id="status_id" name="status_id" :options="statuses" v-model="single.status_id" label="Status" required></f-select>
name="subscription_id"
:options="subscriptions"
v-model="single.subscription_id"
label="Beitrag"
required
></f-select>
<f-select
id="status_id"
name="status_id"
:options="statuses"
v-model="single.status_id"
label="Status"
required
></f-select>
<button type="submit" class="btn btn-primary">Absenden</button> <button type="submit" class="btn btn-primary">Absenden</button>
</form> </form>
@ -54,16 +37,8 @@
class="inline-flex btn btn-warning btn-sm" class="inline-flex btn btn-warning btn-sm"
><svg-sprite src="pencil"></svg-sprite ><svg-sprite src="pencil"></svg-sprite
></a> ></a>
<i-link <i-link v-show="!payment.is_accepted" href="#" @click.prevent="accept(payment)" class="inline-flex btn btn-success btn-sm"><svg-sprite src="check"></svg-sprite></i-link>
v-show="!payment.is_accepted" <i-link href="#" @click.prevent="remove(payment)" class="inline-flex btn btn-danger btn-sm"><svg-sprite src="trash"></svg-sprite></i-link>
href="#"
@click.prevent="accept(payment)"
class="inline-flex btn btn-success btn-sm"
><svg-sprite src="check"></svg-sprite
></i-link>
<i-link href="#" @click.prevent="remove(payment)" class="inline-flex btn btn-danger btn-sm"
><svg-sprite src="trash"></svg-sprite
></i-link>
</td> </td>
</tr> </tr>
</table> </table>
@ -84,20 +59,22 @@
</template> </template>
<script> <script>
import SidebarHeader from '../../components/SidebarHeader.vue';
export default { export default {
data: function () { data: function () {
return { return {
mode: null, mode: null,
single: null, single: null,
indexLinks: [{event: 'create', label: 'Neue Zahlung'}],
}; };
}, },
components: {SidebarHeader},
methods: { methods: {
create() {
this.mode = 'create';
this.single = {};
},
cancel() {
this.mode = this.single = null;
},
remove(payment) { remove(payment) {
this.$inertia.delete(`/member/${this.value.id}/payment/${payment.id}`); this.$inertia.delete(`/member/${this.value.id}/payment/${payment.id}`);
}, },

View File

@ -1,57 +1,57 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button> <page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
<toolbar-button :href="data.links.edit" color="warning" icon="pencil">bearbeiten</toolbar-button> <page-toolbar-button :href="data.links.edit" color="warning" icon="pencil">bearbeiten</page-toolbar-button>
</div> </template>
<div class="p-3 grid gap-3 this-grid grow"> <div class="p-3 grid gap-3 this-grid grow">
<box heading="Stammdaten" class="area-stamm hidden xl:block"> <ui-box heading="Stammdaten" class="area-stamm hidden xl:block">
<stamm :inner="inner"></stamm> <stamm :inner="inner"></stamm>
</box> </ui-box>
<box heading="Kontakt" class="area-kontakt hidden xl:block"> <ui-box heading="Kontakt" class="area-kontakt hidden xl:block">
<kontakt :inner="inner"></kontakt> <kontakt :inner="inner"></kontakt>
</box> </ui-box>
<box class="area-stammkontakt block xl:hidden"> <ui-box class="area-stammkontakt block xl:hidden">
<tabs v-model="tabs.stammkontakt"> <tabs v-model="tabs.stammkontakt">
<stamm v-show="tabs.stammkontakt.active === 'stamm'" :inner="inner"></stamm> <stamm v-show="tabs.stammkontakt.active === 'stamm'" :inner="inner"></stamm>
<kontakt v-show="tabs.stammkontakt.active === 'kontakt'" :inner="inner"></kontakt> <kontakt v-show="tabs.stammkontakt.active === 'kontakt'" :inner="inner"></kontakt>
</tabs> </tabs>
</box> </ui-box>
<box container-class="" heading="Prävention" class="area-praev hidden xl:block"> <ui-box container-class="" heading="Prävention" class="area-praev hidden xl:block">
<prae :inner="inner"></prae> <prae :inner="inner"></prae>
</box> </ui-box>
<box heading="System" class="area-system hidden xl:block"> <ui-box heading="System" class="area-system hidden xl:block">
<system :inner="inner"></system> <system :inner="inner"></system>
</box> </ui-box>
<box class="area-praesystem block xl:hidden"> <ui-box class="area-praesystem block xl:hidden">
<tabs v-model="tabs.praesystem"> <tabs v-model="tabs.praesystem">
<prae v-show="tabs.praesystem.active === 'prae'" :inner="inner"></prae> <prae v-show="tabs.praesystem.active === 'prae'" :inner="inner"></prae>
<system v-show="tabs.praesystem.active === 'system'" :inner="inner"></system> <system v-show="tabs.praesystem.active === 'system'" :inner="inner"></system>
</tabs> </tabs>
</box> </ui-box>
<box class="area-membershipcourse hidden xl:block"> <ui-box class="area-membershipcourse hidden xl:block">
<tabs v-model="tabs.membershipcourse"> <tabs v-model="tabs.membershipcourse">
<courses v-show="tabs.membershipcourse.active === 'course'" :value="inner.courses"></courses> <courses v-show="tabs.membershipcourse.active === 'course'" :value="inner.courses"></courses>
<memberships v-show="tabs.membershipcourse.active === 'membership'" :value="inner.memberships"></memberships> <memberships v-show="tabs.membershipcourse.active === 'membership'" :value="inner.memberships"></memberships>
</tabs> </tabs>
</box> </ui-box>
<box heading="Ausbildungen" class="area-courses xl:hidden"> <ui-box heading="Ausbildungen" class="area-courses xl:hidden">
<courses :value="inner.courses"></courses> <courses :value="inner.courses"></courses>
</box> </ui-box>
<box heading="Mitgliedschaften" class="area-memberships xl:hidden"> <ui-box heading="Mitgliedschaften" class="area-memberships xl:hidden">
<memberships :value="inner.memberships"></memberships> <memberships :value="inner.memberships"></memberships>
</box> </ui-box>
<box heading="Zahlungen" class="area-payments"> <ui-box heading="Zahlungen" class="area-payments">
<payments :value="inner.payments"></payments> <payments :value="inner.payments"></payments>
</box> </ui-box>
<box heading="Karte" container-class="grow" class="area-map hidden xl:flex"> <ui-box heading="Karte" container-class="grow" class="area-map hidden xl:flex">
<vmap v-if="inner.lat && inner.lon" :value="[inner.lat, inner.lon]"></vmap> <vmap v-if="inner.lat && inner.lon" :value="[inner.lat, inner.lon]"></vmap>
<div class="h-full flex items-center justify-center text-gray-400 text-center" v-else>Keine Karte vorhanden</div> <div class="h-full flex items-center justify-center text-gray-400 text-center" v-else>Keine Karte vorhanden</div>
</box> </ui-box>
</div> </div>
</page-layout> </page-layout>
</template> </template>
@ -95,15 +95,15 @@ export default {
}, },
components: { components: {
stamm: () => import(/* webpackChunkName: "member" */ './boxes/Stamm'), stamm: () => import(/* webpackChunkName: "member" */ './boxes/Stamm.vue'),
kontakt: () => import(/* webpackChunkName: "member" */ './boxes/Kontakt'), kontakt: () => import(/* webpackChunkName: "member" */ './boxes/Kontakt.vue'),
prae: () => import(/* webpackChunkName: "member" */ './boxes/Prae'), prae: () => import(/* webpackChunkName: "member" */ './boxes/Prae.vue'),
courses: () => import(/* webpackChunkName: "member" */ './boxes/Courses'), courses: () => import(/* webpackChunkName: "member" */ './boxes/Courses.vue'),
system: () => import(/* webpackChunkName: "member" */ './boxes/System'), system: () => import(/* webpackChunkName: "member" */ './boxes/System.vue'),
payments: () => import(/* webpackChunkName: "member" */ './boxes/Payments'), payments: () => import(/* webpackChunkName: "member" */ './boxes/Payments.vue'),
memberships: () => import(/* webpackChunkName: "member" */ './boxes/Memberships'), memberships: () => import(/* webpackChunkName: "member" */ './boxes/Memberships.vue'),
vmap: () => import(/* webpackChunkName: "member" */ './boxes/Vmap'), vmap: () => import(/* webpackChunkName: "member" */ './boxes/Vmap.vue'),
tabs: () => import(/* webpackChunkName: "member" */ './Tabs'), tabs: () => import(/* webpackChunkName: "member" */ './Tabs.vue'),
}, },
created() { created() {

View File

@ -1,14 +1,7 @@
<template> <template>
<div class="bool-row"> <div class="bool-row">
<v-bool <ui-bool true-comment="Mittendrin abonniert" false-comment="Mittendrin nicht abonníert" v-model="member.send_newspaper">M</ui-bool>
true-comment="Mittendrin abonniert" <ui-bool true-comment="In NaMi eingetragen" false-comment="Nicht in NaMi eingetragen" v-model="member.has_nami">N</ui-bool>
false-comment="Mittendrin nicht abonníert"
v-model="member.send_newspaper"
>M</v-bool
>
<v-bool true-comment="In NaMi eingetragen" false-comment="Nicht in NaMi eingetragen" v-model="member.has_nami"
>N</v-bool
>
</div> </div>
</template> </template>

View File

@ -1,12 +1,12 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button> <page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
<toolbar-button v-if="mode === 'edit'" :href="data.links.show" color="primary" icon="eye">anschauen</toolbar-button> <page-toolbar-button v-if="mode === 'edit'" :href="data.links.show" color="primary" icon="eye">anschauen</page-toolbar-button>
</div> </template>
<form class="flex grow relative" id="memberedit" @submit.prevent="submit"> <form class="flex grow relative" id="memberedit" @submit.prevent="submit">
<save-button form="memberedit"></save-button> <f-save-button form="memberedit"></f-save-button>
<popup heading="Ein Konflikt ist aufgetreten" v-if="conflict === true"> <ui-popup heading="Ein Konflikt ist aufgetreten" v-if="conflict === true">
<div> <div>
<p class="mt-4">Dieses Mitglied wurde vorher bereits aktualisiert. Daher könnte ein Update zu Datenverlust führen.</p> <p class="mt-4">Dieses Mitglied wurde vorher bereits aktualisiert. Daher könnte ein Update zu Datenverlust führen.</p>
<p class="mt-2">Wir empfehlen, die Daten aus NaMi zunächst neu zu synchronisieren und dann die Änderungen hier in der Adrema erneut vorzunehmen.</p> <p class="mt-2">Wir empfehlen, die Daten aus NaMi zunächst neu zu synchronisieren und dann die Änderungen hier in der Adrema erneut vorzunehmen.</p>
@ -15,11 +15,11 @@
<a href="#" @click.prevent="forceWrite" class="text-center btn btn-danger">Änderungen schreiben</a> <a href="#" @click.prevent="forceWrite" class="text-center btn btn-danger">Änderungen schreiben</a>
</div> </div>
</div> </div>
</popup> </ui-popup>
<!-- ***************************** Hauptbereich ****************************** --> <!-- ***************************** Hauptbereich ****************************** -->
<div class="grow grid md:grid-cols-2 gap-3 p-3"> <div class="grow grid md:grid-cols-2 gap-3 p-3">
<box heading="Stammdaten"> <ui-box heading="Stammdaten">
<div class="grid sm:grid-cols-2 gap-3"> <div class="grid sm:grid-cols-2 gap-3">
<div class="grid grid-cols-2 gap-3"> <div class="grid grid-cols-2 gap-3">
<f-select id="gender_id" name="gender_id" :options="meta.genders" v-model="inner.gender_id" label="Geschlecht" size="sm"></f-select> <f-select id="gender_id" name="gender_id" :options="meta.genders" v-model="inner.gender_id" label="Geschlecht" size="sm"></f-select>
@ -37,8 +37,8 @@
<f-select :options="meta.countries" id="country_id" v-model="inner.country_id" label="Land" name="country_id" size="sm" required></f-select> <f-select :options="meta.countries" id="country_id" v-model="inner.country_id" label="Land" name="country_id" size="sm" required></f-select>
<f-text id="other_country" v-model="inner.other_country" label="Andere Staatsangehörigkeit" size="sm"></f-text> <f-text id="other_country" v-model="inner.other_country" label="Andere Staatsangehörigkeit" size="sm"></f-text>
</div> </div>
</box> </ui-box>
<box heading="Kontakt"> <ui-box heading="Kontakt">
<div class="grid gap-3 sm:grid-cols-2"> <div class="grid gap-3 sm:grid-cols-2">
<f-text id="main_phone" v-model="inner.main_phone" size="sm" label="Telefon (Eltern)"></f-text> <f-text id="main_phone" v-model="inner.main_phone" size="sm" label="Telefon (Eltern)"></f-text>
<f-text id="mobile_phone" v-model="inner.mobile_phone" size="sm" label="Handy (Eltern)"></f-text> <f-text id="mobile_phone" v-model="inner.mobile_phone" size="sm" label="Handy (Eltern)"></f-text>
@ -49,8 +49,8 @@
<f-text id="fax" v-model="inner.fax" size="sm" label="Fax"></f-text> <f-text id="fax" v-model="inner.fax" size="sm" label="Fax"></f-text>
<f-textarea class="sm:col-span-2" rows="3" id="letter_address" v-model="inner.letter_address" label="Brief-Adresse" size="sm"></f-textarea> <f-textarea class="sm:col-span-2" rows="3" id="letter_address" v-model="inner.letter_address" label="Brief-Adresse" size="sm"></f-textarea>
</div> </div>
</box> </ui-box>
<box heading="System"> <ui-box heading="System">
<div class="grid gap-3"> <div class="grid gap-3">
<f-select :options="meta.billKinds" id="bill_kind" v-model="inner.bill_kind" label="Rechnung versenden über" name="bill_kind" size="sm"></f-select> <f-select :options="meta.billKinds" id="bill_kind" v-model="inner.bill_kind" label="Rechnung versenden über" name="bill_kind" size="sm"></f-select>
<f-select :options="meta.subscriptions" id="subscription_id" v-model="inner.subscription_id" label="Beitrag" name="subscription_id" size="sm"></f-select> <f-select :options="meta.subscriptions" id="subscription_id" v-model="inner.subscription_id" label="Beitrag" name="subscription_id" size="sm"></f-select>
@ -80,8 +80,8 @@
></f-select> ></f-select>
</div> </div>
</div> </div>
</box> </ui-box>
<box heading="Prävention"> <ui-box heading="Prävention">
<div class="grid sm:grid-cols-[minmax(min-content,max-content)_minmax(min-content,max-content)] gap-2"> <div class="grid sm:grid-cols-[minmax(min-content,max-content)_minmax(min-content,max-content)] gap-2">
<div class="grid grid-cols-[minmax(min-content,max-content)_8rem] gap-1"> <div class="grid grid-cols-[minmax(min-content,max-content)_8rem] gap-1">
<f-switch id="has_efz" v-model="hasEfz" size="sm" label="Führungszeugnis eingesehen"></f-switch> <f-switch id="has_efz" v-model="hasEfz" size="sm" label="Führungszeugnis eingesehen"></f-switch>
@ -112,7 +112,7 @@
<f-switch id="multiply_more_pv" v-model="inner.multiply_more_pv" label="Multiplikator*in Vertierungsschulung" size="sm"></f-switch> <f-switch id="multiply_more_pv" v-model="inner.multiply_more_pv" label="Multiplikator*in Vertierungsschulung" size="sm"></f-switch>
</div> </div>
</div> </div>
</box> </ui-box>
</div> </div>
</form> </form>
</page-layout> </page-layout>
@ -155,10 +155,6 @@ export default {
forceWrite() {}, forceWrite() {},
}, },
components: {
popup: () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
},
computed: { computed: {
hasEfz: issetComputed('efz'), hasEfz: issetComputed('efz'),
hasPs: issetComputed('ps_at'), hasPs: issetComputed('ps_at'),

View File

@ -1,24 +1,24 @@
<template> <template>
<page-layout page-class="pb-6"> <page-layout page-class="pb-6">
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Mitglied anlegen</toolbar-button> <page-toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Mitglied anlegen</page-toolbar-button>
<toolbar-button :href="data.meta.links.allpayment" color="primary" icon="invoice" v-if="hasModule('bill')">Rechnungen erstellen</toolbar-button> <page-toolbar-button :href="data.meta.links.allpayment" color="primary" icon="invoice" v-if="hasModule('bill')">Rechnungen erstellen</page-toolbar-button>
<toolbar-button :href="data.meta.links.sendpayment" color="info" icon="envelope" v-if="hasModule('bill')">Rechnungen versenden</toolbar-button> <page-toolbar-button :href="data.meta.links.sendpayment" color="info" icon="envelope" v-if="hasModule('bill')">Rechnungen versenden</page-toolbar-button>
</div> </template>
<popup heading="Mitglied löschen?" v-if="deleting !== null" @close="deleting.reject()"> <ui-popup heading="Mitglied löschen?" v-if="deleting !== null" @close="deleting.reject()">
<div> <div>
<p class="mt-4">Das Mitglied "{{ deleting.member.fullname }}" löschen?</p> <p class="mt-4">Das Mitglied "{{ deleting.member.fullname }}" löschen?</p>
<p class="mt-2">Alle Zuordnungen (Ausbildungen, Rechnungen, Zahlungen, Tätigkeiten) werden ebenfalls entfernt.</p> <p class="mt-2">Alle Zuordnungen (Ausbildungen, Rechnungen, Zahlungen, Tätigkeiten) werden ebenfalls entfernt.</p>
<note class="mt-5" type="warning" v-if="!deleting.member.has_nami"> Dieses Mitglied ist nicht in NaMi vorhanden und wird daher nur in der AdReMa gelöscht werden. </note> <ui-note class="mt-5" type="warning" v-if="!deleting.member.has_nami"> Dieses Mitglied ist nicht in NaMi vorhanden und wird daher nur in der AdReMa gelöscht werden. </ui-note>
<note class="mt-5" type="danger" v-if="deleting.member.has_nami"> <ui-note class="mt-5" type="danger" v-if="deleting.member.has_nami">
Dieses Mitglied ist in NaMi vorhanden und wird daher in NaMi abgemeldet werden. Sofern "Datenweiterverwendung" eingeschaltet ist, wird das Mitglied auf inaktiv gesetzt. Dieses Mitglied ist in NaMi vorhanden und wird daher in NaMi abgemeldet werden. Sofern "Datenweiterverwendung" eingeschaltet ist, wird das Mitglied auf inaktiv gesetzt.
</note> </ui-note>
<div class="grid grid-cols-2 gap-3 mt-6"> <div class="grid grid-cols-2 gap-3 mt-6">
<a href="#" @click.prevent="deleting.resolve()" class="text-center btn btn-danger">Mitglied loschen</a> <a href="#" @click.prevent="deleting.resolve()" class="text-center btn btn-danger">Mitglied loschen</a>
<a href="#" @click.prevent="deleting.reject()" class="text-center btn btn-primary">Abbrechen</a> <a href="#" @click.prevent="deleting.reject()" class="text-center btn btn-primary">Abbrechen</a>
</div> </div>
</div> </div>
</popup> </ui-popup>
<div class="px-6 py-2 flex border-b border-gray-600 items-center space-x-3"> <div class="px-6 py-2 flex border-b border-gray-600 items-center space-x-3">
<f-text :value="getFilter('search')" @input="setFilter('search', $event)" id="search" name="search" label="Suchen …" size="sm"></f-text> <f-text :value="getFilter('search')" @input="setFilter('search', $event)" id="search" name="search" label="Suchen …" size="sm"></f-text>
<f-switch v-show="hasModule('bill')" id="ausstand" @input="setFilter('ausstand', $event)" :items="getFilter('ausstand')" label="Nur Ausstände" size="sm"></f-switch> <f-switch v-show="hasModule('bill')" id="ausstand" @input="setFilter('ausstand', $event)" :items="getFilter('ausstand')" label="Nur Ausstände" size="sm"></f-switch>
@ -78,10 +78,10 @@
<td><tags :member="member"></tags></td> <td><tags :member="member"></tags></td>
<td class="hidden xl:table-cell" v-text="member.age"></td> <td class="hidden xl:table-cell" v-text="member.age"></td>
<td class="hidden xl:table-cell" v-show="hasModule('bill')"> <td class="hidden xl:table-cell" v-show="hasModule('bill')">
<v-label :value="member.bill_kind_name" fallback="kein"></v-label> <ui-label :value="member.bill_kind_name" fallback="kein"></ui-label>
</td> </td>
<td v-show="hasModule('bill')"> <td v-show="hasModule('bill')">
<v-label :value="member.pending_payment" fallback="---"></v-label> <ui-label :value="member.pending_payment" fallback="---"></ui-label>
</td> </td>
<td> <td>
<actions :member="member" @sidebar="openSidebar(index, $event)" @remove="remove(member)"></actions> <actions :member="member" @sidebar="openSidebar(index, $event)" @remove="remove(member)"></actions>
@ -90,24 +90,24 @@
</table> </table>
<div class="md:hidden p-3 grid gap-3"> <div class="md:hidden p-3 grid gap-3">
<box class="relative" :heading="member.fullname" v-for="(member, index) in data.data" :key="index"> <ui-box class="relative" :heading="member.fullname" v-for="(member, index) in data.data" :key="index">
<div slot="in-title"> <div slot="in-title">
<age-groups class="ml-2" :member="member" icon-class="w-4 h-4"></age-groups> <age-groups class="ml-2" :member="member" icon-class="w-4 h-4"></age-groups>
</div> </div>
<div class="text-xs text-gray-200" v-text="member.full_address"></div> <div class="text-xs text-gray-200" v-text="member.full_address"></div>
<div class="flex items-center mt-1 space-x-4"> <div class="flex items-center mt-1 space-x-4">
<tags :member="member"></tags> <tags :member="member"></tags>
<v-label class="text-gray-100 block" v-show="hasModule('bill')" :value="member.pending_payment" fallback=""></v-label> <ui-label class="text-gray-100 block" v-show="hasModule('bill')" :value="member.pending_payment" fallback=""></ui-label>
</div> </div>
<actions class="mt-2" :member="member" @sidebar="openSidebar(index, $event)" @remove="remove(member)"></actions> <actions class="mt-2" :member="member" @sidebar="openSidebar(index, $event)" @remove="remove(member)"></actions>
<div class="absolute right-0 top-0 h-full flex items-center mr-2"> <div class="absolute right-0 top-0 h-full flex items-center mr-2">
<i-link :href="member.links.show" v-tooltip="`Details`"><svg-sprite src="chevron-down" class="w-6 h-6 text-teal-100 -rotate-90"></svg-sprite></i-link> <i-link :href="member.links.show" v-tooltip="`Details`"><svg-sprite src="chevron-down" class="w-6 h-6 text-teal-100 -rotate-90"></svg-sprite></i-link>
</div> </div>
</box> </ui-box>
</div> </div>
<div class="px-6"> <div class="px-6">
<v-pages class="mt-4" :value="data.meta" :only="['data']"></v-pages> <ui-pagination class="mt-4" :value="data.meta" :only="['data']"></ui-pagination>
</div> </div>
<transition name="sidebar"> <transition name="sidebar">
@ -153,11 +153,9 @@ export default {
MemberMemberships, MemberMemberships,
MemberPayments, MemberPayments,
MemberCourses, MemberCourses,
'age-groups': () => import(/* webpackChunkName: "member" */ './AgeGroups'), 'age-groups': () => import('./AgeGroups.vue'),
'tags': () => import(/* webpackChunkName: "member" */ './Tags'), 'tags': () => import('./Tags.vue'),
'actions': () => import(/* webpackChunkName: "member" */ './index/Actions'), 'actions': () => import('./index/Actions.vue'),
'popup': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
'note': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Note.vue'),
}, },
methods: { methods: {

View File

@ -1,12 +1,6 @@
<template> <template>
<div> <div>
<table <table cellspacing="0" cellpadding="0" border="0" class="hidden md:table custom-table overflow-auto custom-table-sm text-sm" v-if="inner.length">
cellspacing="0"
cellpadding="0"
border="0"
class="hidden md:table custom-table overflow-auto custom-table-sm text-sm"
v-if="inner.length"
>
<thead> <thead>
<th>Datum</th> <th>Datum</th>
<th>Baustein</th> <th>Baustein</th>
@ -22,17 +16,11 @@
</table> </table>
<div class="py-3 text-gray-400 text-center" v-else>Keine Ausbildungen vorhanden</div> <div class="py-3 text-gray-400 text-center" v-else>Keine Ausbildungen vorhanden</div>
<div class="md:hidden grid gap-3"> <div class="md:hidden grid gap-3">
<box <ui-box class="relative" :heading="course.course.short_name" v-for="(course, index) in inner" :key="index" second>
class="relative"
:heading="course.course.short_name"
v-for="(course, index) in inner"
:key="index"
second
>
<div class="text-xs text-gray-200" v-text="course.event_name"></div> <div class="text-xs text-gray-200" v-text="course.event_name"></div>
<div class="text-xs text-gray-200" v-text="course.completed_at_human"></div> <div class="text-xs text-gray-200" v-text="course.completed_at_human"></div>
<div class="text-xs text-gray-200" v-text="course.organizer"></div> <div class="text-xs text-gray-200" v-text="course.organizer"></div>
</box> </ui-box>
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,27 +1,12 @@
<template> <template>
<div class="grid gap-3"> <div class="grid gap-3">
<key-value v-show="inner.main_phone" label="Telefon Eltern" :value="inner.main_phone" type="tel"></key-value> <ui-text-display v-show="inner.main_phone" label="Telefon Eltern" :value="inner.main_phone" type="tel"></ui-text-display>
<key-value v-show="inner.mobile_phone" label="Handy Eltern" :value="inner.mobile_phone" type="tel"></key-value> <ui-text-display v-show="inner.mobile_phone" label="Handy Eltern" :value="inner.mobile_phone" type="tel"></ui-text-display>
<key-value <ui-text-display v-show="inner.work_phone" label="Telefon Eltern geschäftlich" :value="inner.work_phone" type="tel"></ui-text-display>
v-show="inner.work_phone" <ui-text-display v-show="inner.children_phone" label="Telefon Kind" :value="inner.children_phone" type="tel"></ui-text-display>
label="Telefon Eltern geschäftlich" <ui-text-display v-show="inner.email" label="E-Mail-Adresse Kind" :value="inner.email" type="email"></ui-text-display>
:value="inner.work_phone" <ui-text-display v-show="inner.email_parents" label="E-Mail-Adresse Eltern" :value="inner.email_parents" type="email"></ui-text-display>
type="tel" <ui-text-display v-show="inner.fax" label="Fax" :value="inner.fax" type="tel"></ui-text-display>
></key-value>
<key-value
v-show="inner.children_phone"
label="Telefon Kind"
:value="inner.children_phone"
type="tel"
></key-value>
<key-value v-show="inner.email" label="E-Mail-Adresse Kind" :value="inner.email" type="email"></key-value>
<key-value
v-show="inner.email_parents"
label="E-Mail-Adresse Eltern"
:value="inner.email_parents"
type="email"
></key-value>
<key-value v-show="inner.fax" label="Fax" :value="inner.fax" type="tel"></key-value>
</div> </div>
</template> </template>
@ -30,8 +15,5 @@ export default {
props: { props: {
inner: {}, inner: {},
}, },
components: {
'key-value': () => import(/* webpackChunkName: "member" */ '../KeyValue'),
},
}; };
</script> </script>

View File

@ -1,11 +1,6 @@
<template> <template>
<div> <div>
<table <table cellspacing="0" cellpadding="0" border="0" class="hidden md:table custom-table overflow-auto custom-table-sm text-sm">
cellspacing="0"
cellpadding="0"
border="0"
class="hidden md:table custom-table overflow-auto custom-table-sm text-sm"
>
<thead> <thead>
<th>Tätigkeit</th> <th>Tätigkeit</th>
<th>Untertätigkeit</th> <th>Untertätigkeit</th>
@ -19,16 +14,10 @@
</table> </table>
<div class="md:hidden grid gap-3"> <div class="md:hidden grid gap-3">
<box <ui-box class="relative" :heading="membership.activity_name" v-for="(membership, index) in inner" :key="index" second>
class="relative"
:heading="membership.activity_name"
v-for="(membership, index) in inner"
:key="index"
second
>
<div class="text-xs text-gray-200" v-text="membership.subactivity_name"></div> <div class="text-xs text-gray-200" v-text="membership.subactivity_name"></div>
<div class="text-xs text-gray-200" v-text="membership.human_date"></div> <div class="text-xs text-gray-200" v-text="membership.human_date"></div>
</box> </ui-box>
</div> </div>
</div> </div>
</template> </template>

View File

@ -14,13 +14,10 @@
</table> </table>
<div class="md:hidden grid gap-3"> <div class="md:hidden grid gap-3">
<box class="relative" :heading="payment.nr" v-for="(payment, index) in inner" :key="index" second> <ui-box class="relative" :heading="payment.nr" v-for="(payment, index) in inner" :key="index" second>
<div <div class="text-xs text-gray-200" v-text="`${payment.subscription.name} (${payment.subscription.amount_human})`"></div>
class="text-xs text-gray-200"
v-text="`${payment.subscription.name} (${payment.subscription.amount_human})`"
></div>
<div class="text-xs text-gray-200" v-text="payment.status_name"></div> <div class="text-xs text-gray-200" v-text="payment.status_name"></div>
</box> </ui-box>
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,45 +1,17 @@
<template> <template>
<div class="flex gap-3"> <div class="flex gap-3">
<div class="grid gap-3"> <div class="grid gap-3">
<key-value <ui-text-display class="col-start-1" label="Führungszeugnis eingesehen" :value="inner.efz_human ? inner.efz_human : 'nie'"></ui-text-display>
class="col-start-1" <ui-text-display class="col-start-1" label="Präventionsschulung" :value="inner.ps_at_human ? inner.ps_at_human : 'nie'"></ui-text-display>
label="Führungszeugnis eingesehen" <ui-text-display class="col-start-1" label="Vertiefungsschulung" :value="inner.more_ps_at_human ? inner.more_ps_at_human : 'nie'"></ui-text-display>
:value="inner.efz_human ? inner.efz_human : 'nie'" <ui-text-display class="col-start-1" label="Einsatz ohne Schulung" :value="inner.without_education_at_human ? inner.without_education_at_human : 'nie'"></ui-text-display>
></key-value> <ui-text-display class="col-start-1" label="Einsatz ohne EFZ" :value="inner.without_efz_at_human ? inner.without_efz_at_human : 'nie'"></ui-text-display>
<key-value
class="col-start-1"
label="Präventionsschulung"
:value="inner.ps_at_human ? inner.ps_at_human : 'nie'"
></key-value>
<key-value
class="col-start-1"
label="Vertiefungsschulung"
:value="inner.more_ps_at_human ? inner.more_ps_at_human : 'nie'"
></key-value>
<key-value
class="col-start-1"
label="Einsatz ohne Schulung"
:value="inner.without_education_at_human ? inner.without_education_at_human : 'nie'"
></key-value>
<key-value
class="col-start-1"
label="Einsatz ohne EFZ"
:value="inner.without_efz_at_human ? inner.without_efz_at_human : 'nie'"
></key-value>
</div> </div>
<div class="grid gap-3 content-start"> <div class="grid gap-3 content-start">
<boolean :value="inner.has_vk" long-label="Verhaltenskodex unterschrieben" label="VK"></boolean> <ui-boolean-display :value="inner.has_vk" long-label="Verhaltenskodex unterschrieben" label="VK"></ui-boolean-display>
<boolean :value="inner.has_svk" long-label="SVK unterschrieben" label="SVK"></boolean> <ui-boolean-display :value="inner.has_svk" long-label="SVK unterschrieben" label="SVK"></ui-boolean-display>
<boolean <ui-boolean-display :value="inner.multiply_pv" long-label="Multiplikator*in Präventionsschulung" label="Multipl. PS"></ui-boolean-display>
:value="inner.multiply_pv" <ui-boolean-display :value="inner.multiply_more_pv" long-label="Multiplikator*in Vertierungsschulung" label="Multipl. VS"></ui-boolean-display>
long-label="Multiplikator*in Präventionsschulung"
label="Multipl. PS"
></boolean>
<boolean
:value="inner.multiply_more_pv"
long-label="Multiplikator*in Vertierungsschulung"
label="Multipl. VS"
></boolean>
</div> </div>
</div> </div>
</template> </template>
@ -49,9 +21,5 @@ export default {
props: { props: {
inner: {}, inner: {},
}, },
components: {
'key-value': () => import(/* webpackChunkName: "member" */ '../KeyValue'),
'boolean': () => import(/* webpackChunkName: "member" */ '../Boolean'),
},
}; };
</script> </script>

View File

@ -1,16 +1,12 @@
<template> <template>
<div class="grid grid-cols-2 gap-3"> <div class="grid grid-cols-2 gap-3">
<key-value class="col-span-2" label="Name" :value="inner.fullname"></key-value> <ui-text-display class="col-span-2" label="Name" :value="inner.fullname"></ui-text-display>
<key-value class="col-span-2" label="Adresse" :value="inner.full_address"></key-value> <ui-text-display class="col-span-2" label="Adresse" :value="inner.full_address"></ui-text-display>
<key-value label="Geburtsdatum" :value="inner.birthday_human"></key-value> <ui-text-display label="Geburtsdatum" :value="inner.birthday_human"></ui-text-display>
<key-value label="Alter" :value="inner.age"></key-value> <ui-text-display label="Alter" :value="inner.age"></ui-text-display>
<key-value label="Bundesland" :value="inner.region.name"></key-value> <ui-text-display label="Bundesland" :value="inner.region.name"></ui-text-display>
<key-value label="Nationalität" :value="inner.nationality.name"></key-value> <ui-text-display label="Nationalität" :value="inner.nationality.name"></ui-text-display>
<key-value <ui-text-display v-show="inner.other_country" label="Andere Staatsangehörigkeit" :value="inner.other_country"></ui-text-display>
v-show="inner.other_country"
label="Andere Staatsangehörigkeit"
:value="inner.other_country"
></key-value>
</div> </div>
</template> </template>
@ -19,8 +15,5 @@ export default {
props: { props: {
inner: {}, inner: {},
}, },
components: {
'key-value': () => import(/* webpackChunkName: "member" */ '../KeyValue'),
},
}; };
</script> </script>

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="grid gap-3"> <div class="grid gap-3">
<key-value v-show="inner.nami_id" label="NaMi ID" :value="inner.nami_id"></key-value> <ui-text-display v-show="inner.nami_id" label="NaMi ID" :value="inner.nami_id"></ui-text-display>
<key-value v-show="inner.nami_id" label="NaMi Mitgliedsnummer" :value="inner.mitgliedsnr"></key-value> <ui-text-display v-show="inner.nami_id" label="NaMi Mitgliedsnummer" :value="inner.mitgliedsnr"></ui-text-display>
<key-value label="Beitrag" :value="inner.subscription ? inner.subscription.name : 'kein'"></key-value> <ui-text-display label="Beitrag" :value="inner.subscription ? inner.subscription.name : 'kein'"></ui-text-display>
<key-value v-if="inner.joined_at_human" label="Eintrittsdatum" :value="inner.joined_at_human"></key-value> <ui-text-display v-if="inner.joined_at_human" label="Eintrittsdatum" :value="inner.joined_at_human"></ui-text-display>
<key-value v-if="inner.bill_kind_name" label="Rechnung" :value="inner.bill_kind_name"></key-value> <ui-text-display v-if="inner.bill_kind_name" label="Rechnung" :value="inner.bill_kind_name"></ui-text-display>
<boolean :value="inner.send_newspaper" label="Mittendrin versenden"></boolean> <ui-boolean-display :value="inner.send_newspaper" label="Mittendrin versenden"></ui-boolean-display>
</div> </div>
</template> </template>
@ -14,9 +14,5 @@ export default {
props: { props: {
inner: {}, inner: {},
}, },
components: {
'key-value': () => import(/* webpackChunkName: "member" */ '../KeyValue'),
'boolean': () => import(/* webpackChunkName: "member" */ '../Boolean'),
},
}; };
</script> </script>

View File

@ -1,6 +1,6 @@
<template> <template>
<form id="billsettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit"> <form id="billsettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit">
<save-button form="billsettingform"></save-button> <f-save-button form="billsettingform"></f-save-button>
<f-text label="Absender" hint="Absender-Name in Kurzform, i.d.R. der kurze Stammesname" name="from" id="from" v-model="inner.from"></f-text> <f-text label="Absender" hint="Absender-Name in Kurzform, i.d.R. der kurze Stammesname" name="from" id="from" v-model="inner.from"></f-text>
<f-text label="Absender (lang)" v-model="inner.from_long" name="from_long" id="from_long" hint="Absender-Name in Langform, i.d.R. der Stammesname"></f-text> <f-text label="Absender (lang)" v-model="inner.from_long" name="from_long" id="from_long" hint="Absender-Name in Langform, i.d.R. der Stammesname"></f-text>
<h2 class="text-lg font-semibold text-gray-300 col-span-2 mt-5">Kontaktdaten</h2> <h2 class="text-lg font-semibold text-gray-300 col-span-2 mt-5">Kontaktdaten</h2>

View File

@ -1,7 +1,7 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex grow relative"> <div class="flex grow relative">
<v-tabs v-model="active" :entries="$page.props.setting_menu"></v-tabs> <ui-tabs v-model="active" :entries="$page.props.setting_menu"></ui-tabs>
<slot></slot> <slot></slot>
</div> </div>
</page-layout> </page-layout>
@ -14,9 +14,6 @@ export default {
innerActive: 0, innerActive: 0,
}; };
}, },
components: {
'v-tabs': () => import('../../components/VTabs.vue'),
},
computed: { computed: {
active: { active: {
get() { get() {

View File

@ -1,6 +1,6 @@
<template> <template>
<form id="mailmansettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit"> <form id="mailmansettingform" class="grow p-6 grid grid-cols-2 gap-3 items-start content-start" @submit.prevent="submit">
<save-button form="mailmansettingform"></save-button> <f-save-button form="mailmansettingform"></f-save-button>
<div class="col-span-full text-gray-100 mb-3"> <div class="col-span-full text-gray-100 mb-3">
<p class="text-sm"> <p class="text-sm">
Scoutrobot kann automatisch Mailinglisten erstellen, wenn es mit einem existierenden Scoutrobot kann automatisch Mailinglisten erstellen, wenn es mit einem existierenden

View File

@ -1,19 +1,19 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button> <page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
</div> </template>
<form id="subedit" class="p-3 grid gap-3" @submit.prevent="submit"> <form id="subedit" class="p-3 grid gap-3" @submit.prevent="submit">
<save-button form="subedit"></save-button> <f-save-button form="subedit"></f-save-button>
<box heading="Beitrag"> <ui-box heading="Beitrag">
<div class="grid gap-4 sm:grid-cols-2"> <div class="grid gap-4 sm:grid-cols-2">
<f-text id="name" v-model="inner.name" label="Name" size="sm" required></f-text> <f-text id="name" v-model="inner.name" label="Name" size="sm" required></f-text>
<f-select id="fee_id" name="fee_id" :options="fees" v-model="inner.fee_id" label="Nami-Beitrag" size="sm" required></f-select> <f-select id="fee_id" name="fee_id" :options="fees" v-model="inner.fee_id" label="Nami-Beitrag" size="sm" required></f-select>
<f-switch id="split" label="Rechnung aufsplitten" v-model="inner.split" size="sm"></f-switch> <f-switch id="split" label="Rechnung aufsplitten" v-model="inner.split" size="sm"></f-switch>
<f-switch id="for_promise" label="Für Versprechen benutzen" v-model="inner.for_promise" size="sm"></f-switch> <f-switch id="for_promise" label="Für Versprechen benutzen" v-model="inner.for_promise" size="sm"></f-switch>
</div> </div>
</box> </ui-box>
<box heading="Positionen"> <ui-box heading="Positionen">
<div class="flex flex-col space-y-4"> <div class="flex flex-col space-y-4">
<div v-for="(pos, index) in inner.children" :key="index" class="flex space-x-2 items-end"> <div v-for="(pos, index) in inner.children" :key="index" class="flex space-x-2 items-end">
<f-text :id="`name-${index}`" v-model="pos.name" label="Name" size="sm" required></f-text> <f-text :id="`name-${index}`" v-model="pos.name" label="Name" size="sm" required></f-text>
@ -27,7 +27,7 @@
Position hinzufügen Position hinzufügen
</a> </a>
</div> </div>
</box> </ui-box>
</form> </form>
</page-layout> </page-layout>
</template> </template>

View File

@ -1,8 +1,8 @@
<template> <template>
<page-layout> <page-layout>
<div class="flex" slot="toolbar"> <template #toolbar>
<toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Beitrag hinzufügen</toolbar-button> <page-toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Beitrag hinzufügen</page-toolbar-button>
</div> </template>
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm"> <table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm">
<thead> <thead>
<th>Name</th> <th>Name</th>

View File

@ -4,8 +4,7 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="socketport" content="{{env('SOCKET_PORT')}}" /> <meta name="socketport" content="{{env('SOCKET_PORT')}}" />
<link href="{{ mix('/css/app.css') }}" rel="stylesheet" /> @vite('resources/js/app.js')
<script src="{{ mix('/js/app.js') }}" defer></script>
</head> </head>
<body class="min-h-full flex flex-col"> <body class="min-h-full flex flex-col">
@inertia @inertia

27
vite.config.js vendored Normal file
View File

@ -0,0 +1,27 @@
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue2';
export default defineConfig({
plugins: [
laravel(['resources/js/app.js']),
vue({
template: {
transformAssetUrls: {
// The Vue plugin will re-write asset URLs, when referenced
// in Single File Components, to point to the Laravel web
// server. Setting this to `null` allows the Laravel plugin
// to instead re-write asset URLs to point to the Vite
// server instead.
base: null,
// The Vue plugin will parse absolute URLs and treat them
// as absolute paths to files on disk. Setting this to
// `false` will leave absolute URLs un-touched so they can
// reference assets in the public directory as expected.
includeAbsolute: false,
},
},
}),
],
});