1
0
Fork 0
forked from Kispi/Core

feat(webapp): add modal for bank operations

This commit is contained in:
Simon Giesel 2022-07-13 19:57:41 +02:00
parent 8151cad10b
commit 4555ca1140
5 changed files with 234 additions and 7 deletions

View file

@ -0,0 +1,20 @@
<template>
<div>
<AtomInput
ref="input"
type="number"
class="text-right pr-16"
step="1"
/>
<span class="text-sm opacity-50 absolute -ml-16 top-2/4 -mt-8 pointer-events-none">,00 Öro</span>
</div>
</template>
<script lang="ts" setup>
import AtomInput from './AtomInput.vue';
</script>
<style lang="scss" scoped>
</style>

View file

@ -0,0 +1,32 @@
<template>
<input
ref="input"
:type="type"
:placeholder="placeholder"
class="input input-bordered w-full max-w-xs"
/>
</template>
<script lang="ts" setup>
defineProps({
type: {
type: String,
default: 'text',
},
placeholder: {
type: String,
default: '',
},
});
</script>
<style lang="scss" scoped>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
</style>

View file

@ -0,0 +1,38 @@
<template>
<Teleport to="body">
<input
:id="id"
type="checkbox"
class="modal-toggle"
@change="$emit('open', {id, open: ($event.target as HTMLInputElement).checked})"
/>
<div class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">{{ title }}</h3>
<p class="py-4"><slot /></p>
<div class="modal-action">
<slot name="action" />
</div>
</div>
</div>
</Teleport>
</template>
<script lang="ts" setup>
defineProps({
id: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
});
defineEmits(['open']);
</script>
<style lang="scss" scoped>
</style>

View file

@ -0,0 +1,82 @@
<template>
<AtomModal
:id="id"
:title="title"
@open="handleOpen"
>
<div class="flex justify-between place-items-center">
<span>{{ inputLabel }}</span>
<AtomCurrencyInput
ref="input"
class="w-4/12"
@keyup.enter="handleSubmit()"
@keyup.esc="abortButton.click()"
/>
</div>
<template #action>
<label
ref="abortButton"
class="btn gap-2"
:for="id"
>
<XCircleIcon class="w-6 h-6" />
Abbrechen
</label>
<button
class="btn gap-2"
@click="handleSubmit()"
>
<CheckCircleIcon class="w-6 h-6" />
{{ actionLabel }}
</button>
</template>
</AtomModal>
</template>
<script lang="ts" setup>
import { CheckCircleIcon, XCircleIcon } from '@heroicons/vue/outline';
import AtomModal from '../atoms/AtomModal.vue';
import AtomCurrencyInput from '../atoms/AtomCurrencyInput.vue';
import { ref } from 'vue';
const input = ref();
const abortButton = ref();
defineProps({
id: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
actionLabel: {
type: String,
required: true,
},
inputLabel: {
type: String,
required: true,
},
});
const emit = defineEmits(['submit']);
function handleOpen(event: {id: string, open: boolean}) {
if(event.open) {
// This is (currently) the only method to focus a input field inside a custom component.
input.value.$refs.input.$refs.input.value = '';
input.value.$refs.input.$refs.input.focus();
}
}
function handleSubmit() {
emit('submit', input.value.$refs.input.$refs.input.value);
abortButton.value.click();
}
</script>
<style lang="scss" scoped>
</style>

View file

@ -10,27 +10,62 @@
/> />
</div> </div>
<div class="sticky flex place-content-center lg:gap-32 gap-16 bg-base-100 bottom-0 w-100 p-5"> <div class="sticky flex place-content-center lg:gap-32 gap-16 bg-base-100 bottom-0 w-100 p-5">
<button class="btn gap-2"> <MoleculeInputModal
:id="depositModalId"
title="Einzahlung"
action-label="Einzahlen"
input-label="Einzuzahlender Betrag:"
@submit="handleDeposit"
/>
<label
class="btn gap-2"
:for="depositModalId"
>
<ChevronUpIcon class="w-6 h-6 text-success" /> <ChevronUpIcon class="w-6 h-6 text-success" />
Einzahlen Einzahlen
</button> </label>
<button class="btn gap-2"> <MoleculeInputModal
:id="salaryModalId"
title="Gehalt"
action-label="Gehalt hinzufügen"
input-label="Gehalt Betrag:"
@submit="handleSalary"
/>
<label
class="btn gap-2"
:for="salaryModalId"
>
<CurrencyDollarIcon class="w-6 h-6 text-warning" /> <CurrencyDollarIcon class="w-6 h-6 text-warning" />
Gehalt Gehalt
</button> </label>
<button class="btn gap-2"> <MoleculeInputModal
:id="withdrawModalId"
title="Auszahlung"
action-label="Auszahlen"
input-label="Auszuzahlender Betrag:"
@submit="handleWithdraw"
/>
<label
class="btn gap-2"
:for="withdrawModalId"
>
<ChevronDownIcon class="w-6 h-6 text-error" /> <ChevronDownIcon class="w-6 h-6 text-error" />
Auszahlen Auszahlen
</button> </label>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ITransaction } from '../../interfaces/transaction.interface'; import { ITransaction } from '../../interfaces/transaction.interface';
import { CurrencyService } from '../services/currency.service'; import { CurrencyService } from '../services/currency.service';
import MoleculeTransactionTable from '../molecules/MoleculeTransactionTable.vue';
import { CurrencyDollarIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/outline'; import { CurrencyDollarIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/outline';
import MoleculeTransactionTable from '../molecules/MoleculeTransactionTable.vue';
import MoleculeInputModal from '../molecules/MoleculeInputModal.vue';
import { onKeyStroke } from '@vueuse/core';
const depositModalId = 'deposit-modal';
const salaryModalId = 'salary-modal';
const withdrawModalId = 'withdraw-modal';
const balance = 13500; const balance = 13500;
const transactions: ITransaction[] = [ const transactions: ITransaction[] = [
{ {
@ -99,6 +134,26 @@ const transactions: ITransaction[] = [
amount: -2000, amount: -2000,
}, },
].sort((a, b) => b.date.getTime() - a.date.getTime()); ].sort((a, b) => b.date.getTime() - a.date.getTime());
onKeyStroke('e', (e) => {
e.preventDefault();
console.log('e pressed');
// TODO: open deposit modal
});
function handleDeposit(amount: number) {
console.log('Deposit:', amount);
}
function handleSalary(amount: number) {
console.log('Salary:', amount);
}
function handleWithdraw(amount: number) {
console.log('Withdraw:', amount);
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>