Compare commits

...

2 Commits

Author SHA1 Message Date
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
41 changed files with 211 additions and 335 deletions

102
package-lock.json generated
View File

@ -8,6 +8,7 @@
"@inertiajs/inertia": "^0.11.0",
"@inertiajs/inertia-vue": "^0.8.0",
"@tailwindcss/typography": "^0.5.9",
"change-case": "^4.1.2",
"leaflet": "^1.9.3",
"lodash": "^4.17.21",
"merge": "^2.1.1",
@ -3551,7 +3552,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true,
"dependencies": {
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
@ -3593,6 +3593,16 @@
}
]
},
"node_modules/capital-case": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz",
"integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3",
"upper-case-first": "^2.0.2"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@ -3609,6 +3619,25 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/change-case": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz",
"integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==",
"dependencies": {
"camel-case": "^4.1.2",
"capital-case": "^1.0.4",
"constant-case": "^3.0.4",
"dot-case": "^3.0.4",
"header-case": "^2.0.4",
"no-case": "^3.0.4",
"param-case": "^3.0.4",
"pascal-case": "^3.1.2",
"path-case": "^3.0.4",
"sentence-case": "^3.0.4",
"snake-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
@ -3969,6 +3998,16 @@
"node": ">= 0.10.0"
}
},
"node_modules/constant-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz",
"integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3",
"upper-case": "^2.0.2"
}
},
"node_modules/constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@ -4632,7 +4671,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
@ -5658,6 +5696,15 @@
"he": "bin/he"
}
},
"node_modules/header-case": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz",
"integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==",
"dependencies": {
"capital-case": "^1.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@ -6646,7 +6693,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"dependencies": {
"tslib": "^2.0.3"
}
@ -6980,7 +7026,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
@ -7295,7 +7340,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true,
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
@ -7357,7 +7401,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
@ -7369,6 +7412,15 @@
"integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
"dev": true
},
"node_modules/path-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz",
"integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -8839,6 +8891,16 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"node_modules/sentence-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz",
"integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3",
"upper-case-first": "^2.0.2"
}
},
"node_modules/serialize-javascript": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
@ -9046,6 +9108,15 @@
"node": ">=8"
}
},
"node_modules/snake-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/sockjs": {
"version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@ -9564,8 +9635,7 @@
"node_modules/tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
"dev": true
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/tty-browserify": {
"version": "0.0.0",
@ -9694,6 +9764,22 @@
"browserslist": ">= 4.21.0"
}
},
"node_modules/upper-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz",
"integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/upper-case-first": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz",
"integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View File

@ -28,6 +28,7 @@
"@inertiajs/inertia": "^0.11.0",
"@inertiajs/inertia-vue": "^0.8.0",
"@tailwindcss/typography": "^0.5.9",
"change-case": "^4.1.2",
"leaflet": "^1.9.3",
"lodash": "^4.17.21",
"merge": "^2.1.1",

54
resources/js/app.js vendored
View File

@ -1,62 +1,42 @@
import Vue from 'vue';
import {App as InertiaApp, plugin, Link as ILink} from '@inertiajs/inertia-vue';
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 axios from 'axios';
import VueAxios from 'vue-axios';
import Toasted from 'vue-toasted';
import VTooltip from 'v-tooltip';
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';
// ---------------------------------- Plugins ----------------------------------
Vue.use(plugin);
Vue.use(PortalVue);
Vue.use(VTooltip);
Vue.use(Toasted);
Vue.use(VueAxios, axios);
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('full-page-heading', () => import(/* webpackChunkName: "full" */ './components/Full/PageHeading.vue'));
Vue.component('SvgSprite', () => import('./components/SvgSprite.js'));
Vue.component('ILink', ILink);
// ------------------------------- UI Components -------------------------------
Vue.component('ui-button', () => import(/* webpackChunkName: "ui" */ './components/Ui/Button.vue'));
Vue.component('ui-spinner', () => import(/* webpackChunkName: "ui" */ './components/Ui/Spinner.vue'));
// ---------------------------------- mixins -----------------------------------
Vue.mixin(hasModule);
Vue.mixin(hasFlash);
// -------------------------------- Components ---------------------------------
requireModules(require.context('./components/form', false, /\.vue$/, 'lazy'), Vue, 'f');
requireModules(require.context('./components/ui', false, /\.vue$/, 'lazy'), Vue, 'ui');
requireModules(require.context('./components/page', false, /\.vue$/, 'lazy'), Vue, 'page');
// ----------------------------------- init ------------------------------------
const el = document.getElementById('app');
const pinia = createPinia();
Vue.mixin(hasModule);
Vue.mixin(hasFlash);
Vue.component('ILink', ILink);
Inertia.on('start', (event) => window.dispatchEvent(new Event('inertiaStart')));
new Vue({

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,7 +1,7 @@
<template>
<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">
<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>
</div>
<main :class="{'mt-2': heading, [containerClass]: true}">

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

@ -0,0 +1,10 @@
import {paramCase} from 'change-case';
export default function (context, Vue, prefix) {
context.keys().forEach((file) => {
let componentName = paramCase(`${prefix}${file.replace(/^\.\/(.*?)\.vue$/g, '$1')}`);
console.log(componentName);
Vue.component(componentName, () => context(file));
});
}

View File

@ -1,7 +1,7 @@
<template>
<div>
<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">
<p>Bitte gib deine NaMi-Zugangsdaten ein,<br />um eine erste Synchronisation durchzuführen.</p>
</div>
@ -12,7 +12,7 @@
</form>
</div>
<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">
<div class="prose prose-invert max-w-none col-span-full">
<p>
@ -105,13 +105,13 @@
</table>
<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>
</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 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">
<p>Bitte gib hier deine Standard-Gruppierungsnummer ein.</p>
<p>Dieser Gruppierung werden Mitglieder automatisch zugeordnet,<br />falls nichts anderes angegeben wurde.</p>
@ -123,7 +123,7 @@
</form>
</div>
<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">
<p>Wir werden nun die Mitgliederdaten anhand deiner festgelegten Kriterien abrufen.</p>
<p>Per Klick auf "Abschließen" gelangst du zum Dashboard</p>

View File

@ -4,7 +4,7 @@
<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>
</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>
</template>

View File

@ -1,19 +1,19 @@
<template>
<page-layout>
<div class="flex" slot="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>
<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>
</popup>
</ui-popup>
<div class="flex space-x-3">
<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>
</div>
<div class="flex space-x-3 items-center mt-6 mb-2">
<checkboxes-label>Untertätigkeiten</checkboxes-label>
<icon-button icon="plus" v-if="mode === 'edit'" @click.prevent="currentSubactivity = inner.subactivity_model">Neu</icon-button>
<f-checkboxes-label>Untertätigkeiten</f-checkboxes-label>
<ui-icon-button icon="plus" v-if="mode === 'edit'" @click.prevent="currentSubactivity = inner.subactivity_model">Neu</ui-icon-button>
</div>
<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">
@ -32,7 +32,7 @@
></f-switch>
</div>
</div>
<save-button form="actionform"></save-button>
<f-save-button form="actionform"></f-save-button>
</form>
</page-layout>
</template>
@ -54,9 +54,7 @@ export default {
},
components: {
'checkboxes-label': () => import('../../components/Form/CheckboxesLabel'),
'subactivity-form': () => import('./SubactivityForm.vue'),
'popup': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
},
methods: {

View File

@ -1,9 +1,9 @@
<template>
<page-layout page-class="pb-6">
<div class="flex" slot="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>
<popup heading="Bitte bestätigen" v-if="deleting !== null">
<ui-popup heading="Bitte bestätigen" v-if="deleting !== null">
<div>
<p class="mt-4">Diese Aktivität löschen?</p>
<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>
</div>
</div>
</popup>
</ui-popup>
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table">
<thead>
<th>Name</th>
@ -30,7 +30,7 @@
</table>
<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>
</page-layout>
</template>
@ -58,10 +58,6 @@ export default {
},
},
components: {
popup: () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
},
mixins: [indexHelpers],
};
</script>

View File

@ -1,57 +1,57 @@
<template>
<page-layout>
<div class="flex" slot="toolbar">
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button>
<toolbar-button :href="data.links.edit" color="warning" icon="pencil">bearbeiten</toolbar-button>
<page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
<page-toolbar-button :href="data.links.edit" color="warning" icon="pencil">bearbeiten</page-toolbar-button>
</div>
<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>
</box>
<box heading="Kontakt" class="area-kontakt hidden xl:block">
</ui-box>
<ui-box heading="Kontakt" class="area-kontakt hidden xl:block">
<kontakt :inner="inner"></kontakt>
</box>
<box class="area-stammkontakt block xl:hidden">
</ui-box>
<ui-box class="area-stammkontakt block xl:hidden">
<tabs v-model="tabs.stammkontakt">
<stamm v-show="tabs.stammkontakt.active === 'stamm'" :inner="inner"></stamm>
<kontakt v-show="tabs.stammkontakt.active === 'kontakt'" :inner="inner"></kontakt>
</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>
</box>
<box heading="System" class="area-system hidden xl:block">
</ui-box>
<ui-box heading="System" class="area-system hidden xl:block">
<system :inner="inner"></system>
</box>
<box class="area-praesystem block xl:hidden">
</ui-box>
<ui-box class="area-praesystem block xl:hidden">
<tabs v-model="tabs.praesystem">
<prae v-show="tabs.praesystem.active === 'prae'" :inner="inner"></prae>
<system v-show="tabs.praesystem.active === 'system'" :inner="inner"></system>
</tabs>
</box>
</ui-box>
<box class="area-membershipcourse hidden xl:block">
<ui-box class="area-membershipcourse hidden xl:block">
<tabs v-model="tabs.membershipcourse">
<courses v-show="tabs.membershipcourse.active === 'course'" :value="inner.courses"></courses>
<memberships v-show="tabs.membershipcourse.active === 'membership'" :value="inner.memberships"></memberships>
</tabs>
</box>
<box heading="Ausbildungen" class="area-courses xl:hidden">
</ui-box>
<ui-box heading="Ausbildungen" class="area-courses xl:hidden">
<courses :value="inner.courses"></courses>
</box>
<box heading="Mitgliedschaften" class="area-memberships xl:hidden">
</ui-box>
<ui-box heading="Mitgliedschaften" class="area-memberships xl:hidden">
<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>
</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>
<div class="h-full flex items-center justify-center text-gray-400 text-center" v-else>Keine Karte vorhanden</div>
</box>
</ui-box>
</div>
</page-layout>
</template>

View File

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

View File

@ -1,12 +1,12 @@
<template>
<page-layout>
<div class="flex" slot="toolbar">
<toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</toolbar-button>
<toolbar-button v-if="mode === 'edit'" :href="data.links.show" color="primary" icon="eye">anschauen</toolbar-button>
<page-toolbar-button :href="meta.links.index" color="primary" icon="undo">zurück</page-toolbar-button>
<page-toolbar-button v-if="mode === 'edit'" :href="data.links.show" color="primary" icon="eye">anschauen</page-toolbar-button>
</div>
<form class="flex grow relative" id="memberedit" @submit.prevent="submit">
<save-button form="memberedit"></save-button>
<popup heading="Ein Konflikt ist aufgetreten" v-if="conflict === true">
<f-save-button form="memberedit"></f-save-button>
<ui-popup heading="Ein Konflikt ist aufgetreten" v-if="conflict === true">
<div>
<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>
@ -15,11 +15,11 @@
<a href="#" @click.prevent="forceWrite" class="text-center btn btn-danger">Änderungen schreiben</a>
</div>
</div>
</popup>
</ui-popup>
<!-- ***************************** Hauptbereich ****************************** -->
<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 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>
@ -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-text id="other_country" v-model="inner.other_country" label="Andere Staatsangehörigkeit" size="sm"></f-text>
</div>
</box>
<box heading="Kontakt">
</ui-box>
<ui-box heading="Kontakt">
<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="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-textarea class="sm:col-span-2" rows="3" id="letter_address" v-model="inner.letter_address" label="Brief-Adresse" size="sm"></f-textarea>
</div>
</box>
<box heading="System">
</ui-box>
<ui-box heading="System">
<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.subscriptions" id="subscription_id" v-model="inner.subscription_id" label="Beitrag" name="subscription_id" size="sm"></f-select>
@ -80,8 +80,8 @@
></f-select>
</div>
</div>
</box>
<box heading="Prävention">
</ui-box>
<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 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>
@ -112,7 +112,7 @@
<f-switch id="multiply_more_pv" v-model="inner.multiply_more_pv" label="Multiplikator*in Vertierungsschulung" size="sm"></f-switch>
</div>
</div>
</box>
</ui-box>
</div>
</form>
</page-layout>
@ -155,10 +155,6 @@ export default {
forceWrite() {},
},
components: {
popup: () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
},
computed: {
hasEfz: issetComputed('efz'),
hasPs: issetComputed('ps_at'),

View File

@ -1,24 +1,24 @@
<template>
<page-layout page-class="pb-6">
<div class="flex" slot="toolbar">
<toolbar-button :href="data.meta.links.create" color="primary" icon="plus">Mitglied anlegen</toolbar-button>
<toolbar-button :href="data.meta.links.allpayment" color="primary" icon="invoice" v-if="hasModule('bill')">Rechnungen erstellen</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.create" color="primary" icon="plus">Mitglied anlegen</page-toolbar-button>
<page-toolbar-button :href="data.meta.links.allpayment" color="primary" icon="invoice" v-if="hasModule('bill')">Rechnungen erstellen</page-toolbar-button>
<page-toolbar-button :href="data.meta.links.sendpayment" color="info" icon="envelope" v-if="hasModule('bill')">Rechnungen versenden</page-toolbar-button>
</div>
<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>
<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>
<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>
<note class="mt-5" type="danger" v-if="deleting.member.has_nami">
<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>
<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.
</note>
</ui-note>
<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.reject()" class="text-center btn btn-primary">Abbrechen</a>
</div>
</div>
</popup>
</ui-popup>
<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-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 class="hidden xl:table-cell" v-text="member.age"></td>
<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 v-show="hasModule('bill')">
<v-label :value="member.pending_payment" fallback="---"></v-label>
<ui-label :value="member.pending_payment" fallback="---"></ui-label>
</td>
<td>
<actions :member="member" @sidebar="openSidebar(index, $event)" @remove="remove(member)"></actions>
@ -90,24 +90,24 @@
</table>
<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">
<age-groups class="ml-2" :member="member" icon-class="w-4 h-4"></age-groups>
</div>
<div class="text-xs text-gray-200" v-text="member.full_address"></div>
<div class="flex items-center mt-1 space-x-4">
<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>
<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">
<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>
</box>
</ui-box>
</div>
<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>
<transition name="sidebar">
@ -156,8 +156,6 @@ export default {
'age-groups': () => import(/* webpackChunkName: "member" */ './AgeGroups'),
'tags': () => import(/* webpackChunkName: "member" */ './Tags'),
'actions': () => import(/* webpackChunkName: "member" */ './index/Actions'),
'popup': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Popup.vue'),
'note': () => import(/* webpackChunkName: "ui" */ '../../components/Ui/Note.vue'),
},
methods: {

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<template>
<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 (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>

View File

@ -1,7 +1,7 @@
<template>
<page-layout>
<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>
</div>
</page-layout>
@ -14,9 +14,6 @@ export default {
innerActive: 0,
};
},
components: {
'v-tabs': () => import('../../components/VTabs.vue'),
},
computed: {
active: {
get() {

View File

@ -1,6 +1,6 @@
<template>
<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">
<p class="text-sm">
Scoutrobot kann automatisch Mailinglisten erstellen, wenn es mit einem existierenden

View File

@ -1,19 +1,19 @@
<template>
<page-layout>
<div class="flex" slot="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>
<form id="subedit" class="p-3 grid gap-3" @submit.prevent="submit">
<save-button form="subedit"></save-button>
<box heading="Beitrag">
<f-save-button form="subedit"></f-save-button>
<ui-box heading="Beitrag">
<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-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="for_promise" label="Für Versprechen benutzen" v-model="inner.for_promise" size="sm"></f-switch>
</div>
</box>
<box heading="Positionen">
</ui-box>
<ui-box heading="Positionen">
<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">
<f-text :id="`name-${index}`" v-model="pos.name" label="Name" size="sm" required></f-text>
@ -27,7 +27,7 @@
Position hinzufügen
</a>
</div>
</box>
</ui-box>
</form>
</page-layout>
</template>

View File

@ -1,7 +1,7 @@
<template>
<page-layout>
<div class="flex" slot="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>
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm">
<thead>