564 lines
12 KiB
Vue
564 lines
12 KiB
Vue
<template>
|
|
<q-page>
|
|
<div class="row">
|
|
<div class="col-6">
|
|
<q-card class="q-ma-md">
|
|
<q-card-section>
|
|
<div class="text-h6">
|
|
Person hinzufügen
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-card-section>
|
|
<q-input
|
|
v-model="personenNamensEingabeFeld"
|
|
label="Name"
|
|
maxlength="32"
|
|
counter
|
|
outlined
|
|
/>
|
|
</q-card-section>
|
|
|
|
<q-card-actions vertical>
|
|
<q-btn
|
|
color="primary"
|
|
label="Hinzufügen"
|
|
:disabled="personenNamensEingabeFeld === ''"
|
|
@click="personHinzufügen"
|
|
/>
|
|
</q-card-actions>
|
|
|
|
<q-card-section>
|
|
<q-checkbox
|
|
v-model="witzigeEffekte"
|
|
label="Witzige Effekte"
|
|
/>
|
|
<q-slider
|
|
v-model="FAULERDISKORUTSCHER"
|
|
:min="100"
|
|
:max="2000"
|
|
:step="50"
|
|
:disable="!witzigeEffekte"
|
|
snap
|
|
label
|
|
:label-value="FAULERDISKORUTSCHER + 'ms'"
|
|
@change="faulerWert => { DISKORUTSCHER = faulerWert }"
|
|
/>
|
|
</q-card-section>
|
|
</q-card>
|
|
</div>
|
|
|
|
<div class="col">
|
|
<q-card class="q-ma-md">
|
|
<q-card-section>
|
|
<div class="text-h6">
|
|
Blechstatus
|
|
</div>
|
|
<div class="text-subtitle2">
|
|
Geteilt auf {{ tabellenReihen.length }} Personen
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-table
|
|
class="witzigeTabelleMitKlebendemHeader"
|
|
dense
|
|
:rows="tabellenReihen"
|
|
:columns="tabellenSpalten"
|
|
separator="cell"
|
|
row-key="name"
|
|
:rows-per-page-options="[0]"
|
|
virtual-scroll
|
|
>
|
|
<template #body-cell-name="props">
|
|
<q-td
|
|
:props="props"
|
|
>
|
|
<q-btn
|
|
flat
|
|
color="red"
|
|
size="small"
|
|
padding="xs"
|
|
icon="delete"
|
|
:disabled="!wirdDieShiftTasteGehalten"
|
|
@click="personRausschmeißen(props.value)"
|
|
/>
|
|
{{ props.value }}
|
|
</q-td>
|
|
</template>
|
|
<template #body-cell-geblecht="props">
|
|
<q-td
|
|
v-if="props.row.geblecht.length"
|
|
:props="props"
|
|
class="cursor-pointer"
|
|
:class="{
|
|
ichGehInDieDisko: witzigeEffekte
|
|
}"
|
|
@click="blechGesprächÖffnen(props.key)"
|
|
>
|
|
{{ props.value }}
|
|
</q-td>
|
|
<q-td
|
|
v-else
|
|
:props="props"
|
|
>
|
|
{{ props.value }}
|
|
</q-td>
|
|
</template>
|
|
</q-table>
|
|
</q-card>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<q-card class="q-ma-md">
|
|
<q-card-section>
|
|
<div class="text-h6">
|
|
Geld blechen
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-card-section>
|
|
<q-select
|
|
v-model="personenAuswähler"
|
|
class="q-my-md"
|
|
label="Person"
|
|
outlined
|
|
:options="personenAuswahlMöglichkeiten"
|
|
/>
|
|
|
|
<q-input
|
|
v-model.number="grundEingabeFeld"
|
|
class="q-my-md"
|
|
label="Grund / Ausgabe"
|
|
maxlength="32"
|
|
counter
|
|
outlined
|
|
/>
|
|
|
|
<q-input
|
|
v-model.number="geldEingabeFeld"
|
|
class="q-my-md"
|
|
label="Geld"
|
|
maxlength="8"
|
|
counter
|
|
outlined
|
|
/>
|
|
|
|
<q-select
|
|
v-model="schuldnerAuswähler"
|
|
multiple
|
|
class="q-my-md"
|
|
label="Schuldnerauswahl"
|
|
outlined
|
|
use-chips
|
|
:options="personenAuswahlMöglichkeiten"
|
|
/>
|
|
</q-card-section>
|
|
|
|
<q-card-actions vertical>
|
|
<q-btn
|
|
color="primary"
|
|
label="Blechen"
|
|
:disabled="!personenAuswähler"
|
|
@click="geldBlechen"
|
|
/>
|
|
</q-card-actions>
|
|
</q-card>
|
|
</div>
|
|
|
|
<div class="col">
|
|
<q-card class="q-ma-md">
|
|
<q-card-section>
|
|
<div class="text-h6">
|
|
Gequetschter Blechstatus
|
|
</div>
|
|
<div class="text-subtitle2">
|
|
Geteilt auf {{ tabellenReihen.length }} Personen
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-table
|
|
class="witzigeTabelleMitKlebendemHeader"
|
|
dense
|
|
:rows="gequetschteTabellenReihen"
|
|
:columns="tabellenSpalten"
|
|
separator="cell"
|
|
row-key="name"
|
|
:rows-per-page-options="[0]"
|
|
virtual-scroll
|
|
>
|
|
<template #body-cell-geblecht="props">
|
|
<q-td
|
|
v-if="props.row.geblecht.length"
|
|
:props="props"
|
|
class="cursor-pointer"
|
|
:class="{
|
|
ichGehInDieDisko: witzigeEffekte
|
|
}"
|
|
@click="blechGesprächÖffnen(props.key)"
|
|
>
|
|
{{ props.value }}
|
|
</q-td>
|
|
<q-td
|
|
v-else
|
|
:props="props"
|
|
>
|
|
{{ props.value }}
|
|
</q-td>
|
|
</template>
|
|
</q-table>
|
|
</q-card>
|
|
</div>
|
|
</div>
|
|
</q-page>
|
|
|
|
<q-dialog
|
|
v-model="blechGespräch"
|
|
full-width
|
|
>
|
|
<q-card full-width>
|
|
<q-card-section class="row items-center q-pb-none">
|
|
<q-space />
|
|
<q-btn
|
|
v-close-popup
|
|
icon="close"
|
|
flat
|
|
round
|
|
dense
|
|
/>
|
|
</q-card-section>
|
|
|
|
<q-table
|
|
class="witzigeTabelleMitKlebendemHeader"
|
|
dense
|
|
:rows="blechGesprächZeilen"
|
|
:columns="blechGesprächSpalten"
|
|
separator="cell"
|
|
row-key="grund"
|
|
:rows-per-page-options="[0]"
|
|
virtual-scroll
|
|
>
|
|
<template #body-cell-grund="props">
|
|
<q-td
|
|
:props="props"
|
|
>
|
|
<q-btn
|
|
flat
|
|
color="red"
|
|
size="small"
|
|
padding="xs"
|
|
icon="delete"
|
|
:disabled="!wirdDieShiftTasteGehalten"
|
|
@click="blechungLöschen(props.rowIndex)"
|
|
/>
|
|
{{ props.value }}
|
|
</q-td>
|
|
</template>
|
|
</q-table>
|
|
</q-card>
|
|
</q-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { usePersonenStore } from '@/stores/personen-store';
|
|
import { computed, ref, watch } from 'vue';
|
|
import { useRoute } from 'vue-router';
|
|
import { Loading } from 'quasar';
|
|
|
|
const route = useRoute();
|
|
|
|
Loading.show();
|
|
const personenStore = usePersonenStore();
|
|
await personenStore.loadRemote(route.params.slug as string);
|
|
Loading.hide();
|
|
|
|
const personenNamensEingabeFeld = ref('');
|
|
const personenAuswähler = ref('');
|
|
|
|
const schuldnerAuswähler: Ref<string[] | null> = ref(null);
|
|
|
|
watch(personenAuswähler, () => {
|
|
schuldnerAuswähler.value = personenAuswahlMöglichkeiten.value;
|
|
});
|
|
|
|
const blechungLöschen = (reihenNummerDerBlechung: number) => {
|
|
const person = personenStore.personen[blechGesprächPerson.value];
|
|
|
|
person.geblecht.splice(reihenNummerDerBlechung, 1);
|
|
|
|
if (!person.geblecht.length) {
|
|
blechGespräch.value = false;
|
|
}
|
|
};
|
|
|
|
const geldEingabeFeld = ref(0.0);
|
|
const grundEingabeFeld = ref('');
|
|
|
|
const blechGespräch = ref(false);
|
|
const blechGesprächPerson = ref('');
|
|
|
|
const witzigeEffekte = ref(false);
|
|
const FAULERDISKORUTSCHER = ref(1000);
|
|
const DISKORUTSCHER = ref(1000);
|
|
|
|
const blechDiskoGeschwindigkeit = computed(() => {
|
|
return `${DISKORUTSCHER.value * 5}ms`;
|
|
});
|
|
|
|
const schuldenDiskoGeschwindigkeit = computed(() => {
|
|
return `${DISKORUTSCHER.value}ms`;
|
|
});
|
|
|
|
const blechGesprächÖffnen = (nameDerPerson: string) => {
|
|
blechGespräch.value = true;
|
|
blechGesprächPerson.value = nameDerPerson;
|
|
};
|
|
|
|
const blechGesprächZeilen = computed(() => {
|
|
if (!blechGesprächPerson.value) return [];
|
|
|
|
const person = personenStore.personen[blechGesprächPerson.value];
|
|
|
|
return person.geblecht;
|
|
});
|
|
|
|
const wirdDieShiftTasteGehalten = ref(false);
|
|
document.onkeydown = event => {
|
|
wirdDieShiftTasteGehalten.value = event.shiftKey;
|
|
};
|
|
document.onkeyup = event => {
|
|
wirdDieShiftTasteGehalten.value = event.shiftKey;
|
|
};
|
|
|
|
function speicherLeute () {
|
|
// personenStore.save();
|
|
}
|
|
|
|
function personHinzufügen () {
|
|
const name = personenNamensEingabeFeld.value;
|
|
|
|
personenStore.personen[name] = {
|
|
name,
|
|
geblecht: [],
|
|
};
|
|
|
|
personenNamensEingabeFeld.value = '';
|
|
|
|
speicherLeute();
|
|
}
|
|
|
|
function personRausschmeißen (personenName: string) {
|
|
delete personenStore.personen[personenName];
|
|
|
|
speicherLeute();
|
|
}
|
|
|
|
function geldBlechen () {
|
|
const p = personenStore.personen[personenAuswähler.value];
|
|
|
|
p.geblecht.push({
|
|
grund: grundEingabeFeld.value,
|
|
geld: geldEingabeFeld.value,
|
|
schuldner: schuldnerAuswähler.value,
|
|
});
|
|
|
|
grundEingabeFeld.value = '';
|
|
geldEingabeFeld.value = 0.0;
|
|
|
|
speicherLeute();
|
|
}
|
|
|
|
function blechSumme (blechListe: any[], nameDerPerson = '') {
|
|
let gesamtBlechGeld = 0;
|
|
|
|
for (const blech of blechListe) {
|
|
if (!nameDerPerson) {
|
|
gesamtBlechGeld += blech.geld;
|
|
continue;
|
|
}
|
|
|
|
if (!blech.schuldner.includes(nameDerPerson)) continue;
|
|
|
|
gesamtBlechGeld += blech.geld / blech.schuldner.length;
|
|
}
|
|
|
|
return gesamtBlechGeld;
|
|
}
|
|
|
|
const blechGesprächSpalten = [
|
|
{
|
|
name: 'grund',
|
|
required: true,
|
|
label: 'Grund / Ausgabe',
|
|
align: 'left',
|
|
field: 'grund',
|
|
sortable: true,
|
|
},
|
|
{
|
|
name: 'geld',
|
|
label: 'Geld / Kosten',
|
|
field: 'geld',
|
|
sortable: true,
|
|
format: (reihenWert: string) => reihenWert ? `${gleitzahlenAnalysierer(reihenWert) || '0.00'} €` : '',
|
|
},
|
|
{
|
|
name: 'schuldner',
|
|
label: 'Schuldner',
|
|
field: 'schuldner',
|
|
sortable: false,
|
|
format: (reihenWert: any) => reihenWert.join(', '),
|
|
},
|
|
] as any;
|
|
|
|
const tabellenSpalten = computed(() => {
|
|
const cols = [
|
|
{
|
|
name: 'name',
|
|
required: true,
|
|
label: 'Name',
|
|
align: 'left',
|
|
field: 'name',
|
|
sortable: true,
|
|
},
|
|
{
|
|
name: 'geblecht',
|
|
label: 'Geblecht',
|
|
field: 'geblecht',
|
|
sortable: true,
|
|
format: (reihenWert: any[]) => reihenWert ? `${gleitzahlenAnalysierer(blechSumme(reihenWert)) || '0.00'} €` : '',
|
|
},
|
|
] as any;
|
|
|
|
for(const [name] of Object.entries(personenStore.personen)) {
|
|
cols.push({
|
|
name: `an-${name}`,
|
|
label: `An ${name}`,
|
|
// classes: (reihe: any) => witzigeEffekte.value && reihe.an[name] ? 'duMusstNochGeldZahlenDuLackaffe' : '',
|
|
// field: (reihe: any) => reihe.an[name],
|
|
// format: (reihenWert: any) => reihenWert ? `${gleitzahlenAnalysierer(reihenWert) || '0.00'} €` : '',
|
|
});
|
|
}
|
|
|
|
return cols;
|
|
});
|
|
|
|
function gleitzahlenAnalysierer (wert: string | number) {
|
|
return parseFloat(`${wert}`).toFixed(2);
|
|
}
|
|
|
|
function reihenRechner () {
|
|
const reihenResultate = [];
|
|
const personenEinträge: [string, any][] = Object.entries(personenStore.personen);
|
|
|
|
for(const [name, datenDerPerson] of personenEinträge) {
|
|
const personenObjekt = {
|
|
name,
|
|
geblecht: datenDerPerson.geblecht,
|
|
an: {},
|
|
} as any;
|
|
|
|
for(const [nameDerAnderenPerson, datenDerAnderenPerson] of personenEinträge) {
|
|
if (name === nameDerAnderenPerson) continue;
|
|
|
|
const blechTeiler = blechSumme(datenDerAnderenPerson.geblecht, name); // / Object.keys(personenStore.personen).length;
|
|
personenObjekt.an[nameDerAnderenPerson] = blechTeiler;
|
|
}
|
|
|
|
reihenResultate.push(personenObjekt);
|
|
}
|
|
return reihenResultate;
|
|
}
|
|
|
|
const tabellenReihen = computed(() => {
|
|
return reihenRechner();
|
|
});
|
|
|
|
const gequetschteTabellenReihen = computed(() => {
|
|
const neueZeilen = [];
|
|
const leuteKlon = reihenRechner();
|
|
|
|
for (const klonPersonObjekt of leuteKlon) {
|
|
const personenObjekt = {
|
|
name: klonPersonObjekt.name,
|
|
geblecht: klonPersonObjekt.geblecht,
|
|
an: klonPersonObjekt.an,
|
|
};
|
|
|
|
for (const person of leuteKlon) {
|
|
const name = person.name;
|
|
|
|
if (name === personenObjekt.name) continue;
|
|
|
|
const unserAn = personenObjekt.an[name];
|
|
const anderAn = person.an[personenObjekt.name];
|
|
|
|
if (unserAn < anderAn) continue;
|
|
|
|
personenObjekt.an[name] = unserAn - anderAn;
|
|
person.an[personenObjekt.name] = 0;
|
|
}
|
|
|
|
neueZeilen.push(klonPersonObjekt);
|
|
}
|
|
|
|
return neueZeilen;
|
|
});
|
|
|
|
const personenAuswahlMöglichkeiten = computed(() => {
|
|
const auswahlMöglichkeiten = [];
|
|
for(const [name] of Object.entries(personenStore.personen)) {
|
|
auswahlMöglichkeiten.push(name);
|
|
}
|
|
return auswahlMöglichkeiten;
|
|
});
|
|
|
|
</script>
|
|
|
|
<style>
|
|
.witzigeTabelleMitKlebendemHeader {
|
|
height: 400px;
|
|
}
|
|
|
|
.witzigeTabelleMitKlebendemHeader thead tr th {
|
|
position: sticky;
|
|
z-index: 1;
|
|
}
|
|
|
|
.witzigeTabelleMitKlebendemHeader thead tr:first-child th {
|
|
top: 0;
|
|
background-color: #323232;
|
|
}
|
|
|
|
.ichGehInDieDisko {
|
|
animation: diskoNeu v-bind(blechDiskoGeschwindigkeit) linear infinite;
|
|
background: linear-gradient(238deg, #7c4200, #760043, #4c007e, #001f86, #005a68, #194830);
|
|
background-size: 1200% 1200%;
|
|
}
|
|
|
|
/* .ICHBINSOHARTINDERDISKOBRUDIALTERDIGGA {
|
|
animation: diskoNeu 1s linear infinite;
|
|
background: linear-gradient(238deg, #7c4200, #760043, #4c007e, #001f86, #005a68, #194830);
|
|
background-size: 1200% 1200%;
|
|
} */
|
|
|
|
.duMusstNochGeldZahlenDuLackaffe {
|
|
animation: schuldenDisko v-bind(schuldenDiskoGeschwindigkeit) linear infinite;
|
|
}
|
|
|
|
/* .ZAHLMIRENDLICHDASGELDDUAFFE {
|
|
animation: schuldenDisko 0.25s linear infinite;
|
|
} */
|
|
|
|
@keyframes diskoNeu {
|
|
0% { background-position: 0% 50% }
|
|
50% { background-position: 100% 50% }
|
|
100% { background-position: 0% 50% }
|
|
}
|
|
|
|
@keyframes schuldenDisko {
|
|
0% { background-color: rgb(100, 0, 0); }
|
|
50% { background-color: black; }
|
|
100% { background-color: rgb(100, 0, 0); }
|
|
}
|
|
</style>
|