forked from Kispi/Core
feat(core): add employer portal with mock data
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
c94bf147f5
commit
3e1437300f
13 changed files with 300 additions and 184 deletions
|
@ -162,88 +162,6 @@
|
||||||
"deleteRule": null,
|
"deleteRule": null,
|
||||||
"options": {}
|
"options": {}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "74ftooxenpeq14b",
|
|
||||||
"name": "accounts",
|
|
||||||
"type": "base",
|
|
||||||
"system": false,
|
|
||||||
"schema": [
|
|
||||||
{
|
|
||||||
"id": "as1gvc1r",
|
|
||||||
"name": "accountNumber",
|
|
||||||
"type": "text",
|
|
||||||
"system": false,
|
|
||||||
"required": true,
|
|
||||||
"options": {
|
|
||||||
"min": null,
|
|
||||||
"max": null,
|
|
||||||
"pattern": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "vxeq20lk",
|
|
||||||
"name": "firstName",
|
|
||||||
"type": "text",
|
|
||||||
"system": false,
|
|
||||||
"required": true,
|
|
||||||
"options": {
|
|
||||||
"min": null,
|
|
||||||
"max": null,
|
|
||||||
"pattern": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bsinpdk7",
|
|
||||||
"name": "lastName",
|
|
||||||
"type": "text",
|
|
||||||
"system": false,
|
|
||||||
"required": true,
|
|
||||||
"options": {
|
|
||||||
"min": null,
|
|
||||||
"max": null,
|
|
||||||
"pattern": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "syfivtki",
|
|
||||||
"name": "lastCheckIn",
|
|
||||||
"type": "date",
|
|
||||||
"system": false,
|
|
||||||
"required": false,
|
|
||||||
"options": {
|
|
||||||
"min": "",
|
|
||||||
"max": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "pkoynx7h",
|
|
||||||
"name": "personalData",
|
|
||||||
"type": "relation",
|
|
||||||
"system": false,
|
|
||||||
"required": false,
|
|
||||||
"options": {
|
|
||||||
"collectionId": "p0gixtx6jwria0d",
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"minSelect": null,
|
|
||||||
"maxSelect": 1,
|
|
||||||
"displayFields": [
|
|
||||||
"firstNameParent",
|
|
||||||
"lastNameParent",
|
|
||||||
"email"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"indexes": [
|
|
||||||
"CREATE UNIQUE INDEX `idx_mPdvrAQ` ON `accounts` (`accountNumber`)"
|
|
||||||
],
|
|
||||||
"listRule": "",
|
|
||||||
"viewRule": null,
|
|
||||||
"createRule": null,
|
|
||||||
"updateRule": "@request.data.id = null && @request.data.accountNumber = null && @request.data.firstName = null && @request.data.lastName = null && @request.data.created = null && @request.data.updated = null",
|
|
||||||
"deleteRule": null,
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "c3zz98wpbn7m6zw",
|
"id": "c3zz98wpbn7m6zw",
|
||||||
"name": "accountsList",
|
"name": "accountsList",
|
||||||
|
@ -358,5 +276,147 @@
|
||||||
"updateRule": null,
|
"updateRule": null,
|
||||||
"deleteRule": null,
|
"deleteRule": null,
|
||||||
"options": {}
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "s854d2w72fvyl54",
|
||||||
|
"name": "companies",
|
||||||
|
"type": "auth",
|
||||||
|
"system": false,
|
||||||
|
"schema": [],
|
||||||
|
"indexes": [],
|
||||||
|
"listRule": null,
|
||||||
|
"viewRule": null,
|
||||||
|
"createRule": null,
|
||||||
|
"updateRule": null,
|
||||||
|
"deleteRule": null,
|
||||||
|
"options": {
|
||||||
|
"allowEmailAuth": true,
|
||||||
|
"allowOAuth2Auth": true,
|
||||||
|
"allowUsernameAuth": true,
|
||||||
|
"exceptEmailDomains": null,
|
||||||
|
"manageRule": null,
|
||||||
|
"minPasswordLength": 8,
|
||||||
|
"onlyEmailDomains": null,
|
||||||
|
"requireEmail": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "74ftooxenpeq14b",
|
||||||
|
"name": "accounts",
|
||||||
|
"type": "base",
|
||||||
|
"system": false,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"id": "as1gvc1r",
|
||||||
|
"name": "accountNumber",
|
||||||
|
"type": "text",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vxeq20lk",
|
||||||
|
"name": "firstName",
|
||||||
|
"type": "text",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bsinpdk7",
|
||||||
|
"name": "lastName",
|
||||||
|
"type": "text",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "syfivtki",
|
||||||
|
"name": "lastCheckIn",
|
||||||
|
"type": "date",
|
||||||
|
"system": false,
|
||||||
|
"required": false,
|
||||||
|
"options": {
|
||||||
|
"min": "",
|
||||||
|
"max": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pkoynx7h",
|
||||||
|
"name": "personalData",
|
||||||
|
"type": "relation",
|
||||||
|
"system": false,
|
||||||
|
"required": false,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "p0gixtx6jwria0d",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": [
|
||||||
|
"firstNameParent",
|
||||||
|
"lastNameParent",
|
||||||
|
"email"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "gwrzizpu",
|
||||||
|
"name": "company",
|
||||||
|
"type": "relation",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "s854d2w72fvyl54",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "rtvjzpxw",
|
||||||
|
"name": "shift",
|
||||||
|
"type": "text",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ma5ckyk1",
|
||||||
|
"name": "wageFactor",
|
||||||
|
"type": "number",
|
||||||
|
"system": false,
|
||||||
|
"required": true,
|
||||||
|
"options": {
|
||||||
|
"min": 0,
|
||||||
|
"max": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"CREATE UNIQUE INDEX `idx_mPdvrAQ` ON `accounts` (`accountNumber`)"
|
||||||
|
],
|
||||||
|
"listRule": "",
|
||||||
|
"viewRule": null,
|
||||||
|
"createRule": null,
|
||||||
|
"updateRule": "(@request.data.id = null && @request.data.accountNumber = null && @request.data.firstName = null && @request.data.lastName = null && @request.data.created = null && @request.data.updated = null && @request.data.company = null && @request.data.shift = null && @request.data.wageFactor = null) || (@request.data.id = null && @request.data.accountNumber = null && @request.data.firstName = null && @request.data.lastName = null && @request.data.created = null && @request.data.updated = null && @request.data.company = null && @request.data.shift = null && @request.auth.id = company.id)",
|
||||||
|
"deleteRule": null,
|
||||||
|
"options": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -21,6 +21,7 @@
|
||||||
"vue-router": "4.2.2"
|
"vue-router": "4.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@types/canvas-confetti": "^1.6.0",
|
"@types/canvas-confetti": "^1.6.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||||
|
|
|
@ -28,6 +28,9 @@ dependencies:
|
||||||
version: 4.2.2(vue@3.3.4)
|
version: 4.2.2(vue@3.3.4)
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@tailwindcss/container-queries':
|
||||||
|
specifier: ^0.1.1
|
||||||
|
version: 0.1.1(tailwindcss@3.3.2)
|
||||||
'@tailwindcss/typography':
|
'@tailwindcss/typography':
|
||||||
specifier: ^0.5.9
|
specifier: ^0.5.9
|
||||||
version: 0.5.9(tailwindcss@3.3.2)
|
version: 0.5.9(tailwindcss@3.3.2)
|
||||||
|
@ -460,6 +463,14 @@ packages:
|
||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
/@tailwindcss/container-queries@0.1.1(tailwindcss@3.3.2):
|
||||||
|
resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==}
|
||||||
|
peerDependencies:
|
||||||
|
tailwindcss: '>=3.2.0'
|
||||||
|
dependencies:
|
||||||
|
tailwindcss: 3.3.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
|
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
|
||||||
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
|
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<AtomInput
|
<AtomInput
|
||||||
|
ref="input"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
type="number"
|
type="number"
|
||||||
class="pr-[5.5rem] text-right"
|
class="pr-[5.5rem] text-right"
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full overflow-x-auto rounded-lg">
|
<div
|
||||||
|
v-if="settings"
|
||||||
|
class="h-full overflow-x-auto rounded-lg"
|
||||||
|
>
|
||||||
<table class="table-pin-rows table-zebra table">
|
<table class="table-pin-rows table-zebra table">
|
||||||
<thead class="uppercase">
|
<thead class="uppercase">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -39,6 +42,17 @@
|
||||||
>
|
>
|
||||||
<CurrencyDollarIcon class="h-6 w-6" />
|
<CurrencyDollarIcon class="h-6 w-6" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
<span
|
||||||
|
v-if="header.type === TableHeaderType.WAGE"
|
||||||
|
:for="contactModalId"
|
||||||
|
class="flex items-center gap-2"
|
||||||
|
@click="$emit('open-contact-modal', entry.id)"
|
||||||
|
>
|
||||||
|
<span>{{ CurrencyService.toString(entry[header.key] * settings.minWage) }} / h</span>
|
||||||
|
<div class="btn-ghost btn-sm btn p-1">
|
||||||
|
<PencilSquareIcon class="h-5 w-5" />
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -47,10 +61,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PropType } from 'vue';
|
import { PropType, onMounted, ref } from 'vue';
|
||||||
import { DateService } from '../../services/date.service';
|
import { DateService } from '../../services/date.service';
|
||||||
import { CurrencyService } from '../../services/currency.service';
|
import { CurrencyService } from '../../services/currency.service';
|
||||||
import { CurrencyDollarIcon, DocumentTextIcon } from '@heroicons/vue/24/outline';
|
import { CurrencyDollarIcon, DocumentTextIcon, PencilSquareIcon } from '@heroicons/vue/24/outline';
|
||||||
|
import { SettingsService } from '../../services/settings.service';
|
||||||
|
import { SettingsResponse } from '../../types/pocketbase.types';
|
||||||
|
|
||||||
|
const settings = ref<SettingsResponse>();
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
tableHeaders: {
|
tableHeaders: {
|
||||||
|
@ -70,6 +88,10 @@ defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
settings.value = await SettingsService.getSettings();
|
||||||
|
});
|
||||||
|
|
||||||
defineEmits(['open-contact-modal']);
|
defineEmits(['open-contact-modal']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -81,6 +103,7 @@ export enum TableHeaderType {
|
||||||
DATETIME,
|
DATETIME,
|
||||||
BUTTON_CONTACT,
|
BUTTON_CONTACT,
|
||||||
BUTTON_ACCOUNT,
|
BUTTON_ACCOUNT,
|
||||||
|
WAGE,
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="flex place-items-center justify-between">
|
<div class="flex place-items-center justify-between">
|
||||||
<span>{{ inputLabel }}</span>
|
<span>{{ inputLabel }}</span>
|
||||||
<AtomCurrencyInput
|
<AtomCurrencyInput
|
||||||
ref="input"
|
v-model="amount"
|
||||||
class="w-4/12"
|
class="w-4/12"
|
||||||
@keyup.enter="handleSubmit()"
|
@keyup.enter="handleSubmit()"
|
||||||
@keyup.esc="abortButton.click()"
|
@keyup.esc="abortButton.click()"
|
||||||
|
@ -39,7 +39,7 @@ import { CheckCircleIcon, XCircleIcon } from '@heroicons/vue/24/outline';
|
||||||
import AtomCurrencyInput from '../atoms/AtomCurrencyInput.vue';
|
import AtomCurrencyInput from '../atoms/AtomCurrencyInput.vue';
|
||||||
import AtomModal from '../atoms/AtomModal.vue';
|
import AtomModal from '../atoms/AtomModal.vue';
|
||||||
|
|
||||||
const input = ref();
|
const amount = ref();
|
||||||
const abortButton = ref();
|
const abortButton = ref();
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
|
@ -66,16 +66,16 @@ const emit = defineEmits(['submit']);
|
||||||
function handleOpen(event: {id: string, open: boolean}) {
|
function handleOpen(event: {id: string, open: boolean}) {
|
||||||
if(event.open) {
|
if(event.open) {
|
||||||
// This is (currently) the only method to focus a input field inside a custom component.
|
// This is (currently) the only method to focus a input field inside a custom component.
|
||||||
input.value.$refs.input.$refs.input.value = '';
|
// input.value.$el.$refs.input.$refs.input.value = '';
|
||||||
input.value.$refs.input.$refs.input.focus();
|
// input.value.$el.$refs.input.$refs.input.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
if(input.value.$refs.input.$refs.input.value <= 0 || input.value.$refs.input.$refs.input.value > 100) {
|
if(amount.value <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit('submit', input.value.$refs.input.$refs.input.value);
|
emit('submit', amount.value);
|
||||||
abortButton.value.click();
|
abortButton.value.click();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -30,19 +30,24 @@ const initAccounts = ref<AccountsListResponse<number, string>[]>([]);
|
||||||
const searchQuery = ref('');
|
const searchQuery = ref('');
|
||||||
const tableHeaders = [
|
const tableHeaders = [
|
||||||
{
|
{
|
||||||
title: 'Name',
|
title: 'Vorname',
|
||||||
key: 'name',
|
key: 'firstName',
|
||||||
|
type: TableHeaderType.STRING,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Nachname',
|
||||||
|
key: 'lastName',
|
||||||
type: TableHeaderType.STRING,
|
type: TableHeaderType.STRING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Schicht',
|
title: 'Schicht',
|
||||||
key: 'lastCheckIn',
|
key: 'shift',
|
||||||
type: TableHeaderType.DATETIME,
|
type: TableHeaderType.STRING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Lohn',
|
title: 'Lohn',
|
||||||
key: 'balance',
|
key: 'wageFactor',
|
||||||
type: TableHeaderType.CURRENCY,
|
type: TableHeaderType.WAGE,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -54,7 +59,7 @@ useEventBus<boolean>('isAuthenticated').on(state => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getData() {
|
async function getData() {
|
||||||
initAccounts.value = await AccountService.getAccounts();
|
initAccounts.value = await AccountService.getAccountsByCompanyId('c09ncb3l2pi6i0u');
|
||||||
accounts.value = initAccounts.value;
|
accounts.value = initAccounts.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<OrganismAuthWrapper class="flex h-full flex-wrap gap-4 p-6">
|
<div class="@container">
|
||||||
|
<OrganismAuthWrapper class="flex h-full flex-wrap justify-center gap-4 p-6 @[832px]:justify-normal">
|
||||||
<AtomCard class="w-96">
|
<AtomCard class="w-96">
|
||||||
<template #title>
|
<template #title>
|
||||||
<WrenchScrewdriverIcon class="h-6 w-6" />Einstellungen
|
<WrenchScrewdriverIcon class="h-6 w-6" />Einstellungen
|
||||||
|
@ -84,6 +85,7 @@
|
||||||
</div>
|
</div>
|
||||||
</AtomCard>
|
</AtomCard>
|
||||||
</OrganismAuthWrapper>
|
</OrganismAuthWrapper>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -115,9 +117,10 @@ const settingsSaveError = ref<boolean>(false);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
settings.value = await SettingsService.getSettings();
|
settings.value = await SettingsService.getSettings();
|
||||||
minWage.value = settings.value.minWage;
|
minWage.value = settings.value.minWage / 100;
|
||||||
incomeTax.value = settings.value.incomeTax;
|
incomeTax.value = settings.value.incomeTax;
|
||||||
maxWageFactor.value = settings.value.maxWageFactor;
|
maxWageFactor.value = settings.value.maxWageFactor;
|
||||||
|
radioUrl.value = settings.value.radioUrl;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function saveSettings() {
|
async function saveSettings() {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { RecordSubscription, UnsubscribeFunc } from 'pocketbase';
|
import { RecordSubscription, UnsubscribeFunc } from 'pocketbase';
|
||||||
import { AccountsDataResponse, AccountsListResponse, AccountsResponse, Collections } from '../types/pocketbase.types';
|
import { AccountsDataResponse, AccountsListResponse, AccountsResponse, Collections } from '../types/pocketbase.types';
|
||||||
import { PocketbaseService } from './pocketbase.service';
|
import { PocketbaseService } from './pocketbase.service';
|
||||||
|
@ -20,6 +19,9 @@ export class AccountService {
|
||||||
public static getAccountDetails(id: string): Promise<AccountsResponse<{personalData: AccountsDataResponse}>> {
|
public static getAccountDetails(id: string): Promise<AccountsResponse<{personalData: AccountsDataResponse}>> {
|
||||||
return COLLECTION.getOne(id, { expand: 'personalData' });
|
return COLLECTION.getOne(id, { expand: 'personalData' });
|
||||||
}
|
}
|
||||||
|
public static getAccountsByCompanyId(companyId: string): Promise<AccountsListResponse<number, string>[]> {
|
||||||
|
return COLLECTION.getFullList({ filter: `company.id = "${companyId}"` });
|
||||||
|
}
|
||||||
public static async subscribeToAccountChanges(
|
public static async subscribeToAccountChanges(
|
||||||
callback: (data: RecordSubscription<AccountsResponse>)=> void,
|
callback: (data: RecordSubscription<AccountsResponse>)=> void,
|
||||||
): Promise<UnsubscribeFunc> {
|
): Promise<UnsubscribeFunc> {
|
||||||
|
|
|
@ -3,12 +3,12 @@ export class CurrencyService {
|
||||||
return `${(value / 100).toLocaleString('de-DE', {
|
return `${(value / 100).toLocaleString('de-DE', {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})} Öro`;
|
})} Batzen`;
|
||||||
}
|
}
|
||||||
public static toSignedString(value: number): string {
|
public static toSignedString(value: number): string {
|
||||||
return `${(value / 100) > 0 ? '+' : ''}${(value / 100).toLocaleString('de', {
|
return `${(value / 100) > 0 ? '+' : ''}${(value / 100).toLocaleString('de', {
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})} Öro`;
|
})} Batzen`;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ export class SettingsService {
|
||||||
return COLLECTION.getFirstListItem('', { sort: '-created' });
|
return COLLECTION.getFirstListItem('', { sort: '-created' });
|
||||||
}
|
}
|
||||||
public static async setSettings(settings: SettingsRecord): Promise<SettingsResponse> {
|
public static async setSettings(settings: SettingsRecord): Promise<SettingsResponse> {
|
||||||
|
settings.minWage = settings.minWage * 100;
|
||||||
return COLLECTION.create(settings);
|
return COLLECTION.create(settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ export enum Collections {
|
||||||
Accounts = "accounts",
|
Accounts = "accounts",
|
||||||
AccountsData = "accountsData",
|
AccountsData = "accountsData",
|
||||||
AccountsList = "accountsList",
|
AccountsList = "accountsList",
|
||||||
|
Companies = "companies",
|
||||||
Settings = "settings",
|
Settings = "settings",
|
||||||
Transactions = "transactions",
|
Transactions = "transactions",
|
||||||
}
|
}
|
||||||
|
@ -40,6 +41,9 @@ export type AccountsRecord = {
|
||||||
lastName: string
|
lastName: string
|
||||||
lastCheckIn?: IsoDateString
|
lastCheckIn?: IsoDateString
|
||||||
personalData?: RecordIdString
|
personalData?: RecordIdString
|
||||||
|
company: RecordIdString
|
||||||
|
shift: string
|
||||||
|
wageFactor: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AccountsDataRecord = {
|
export type AccountsDataRecord = {
|
||||||
|
@ -60,6 +64,8 @@ export type AccountsListRecord<Tbalance = unknown, Tname = unknown> = {
|
||||||
balance?: null | Tbalance
|
balance?: null | Tbalance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CompaniesRecord = never
|
||||||
|
|
||||||
export type SettingsRecord = {
|
export type SettingsRecord = {
|
||||||
minWage: number
|
minWage: number
|
||||||
incomeTax: number
|
incomeTax: number
|
||||||
|
@ -77,6 +83,7 @@ export type TransactionsRecord = {
|
||||||
export type AccountsResponse<Texpand = unknown> = Required<AccountsRecord> & BaseSystemFields<Texpand>
|
export type AccountsResponse<Texpand = unknown> = Required<AccountsRecord> & BaseSystemFields<Texpand>
|
||||||
export type AccountsDataResponse<Texpand = unknown> = Required<AccountsDataRecord> & BaseSystemFields<Texpand>
|
export type AccountsDataResponse<Texpand = unknown> = Required<AccountsDataRecord> & BaseSystemFields<Texpand>
|
||||||
export type AccountsListResponse<Tbalance = unknown, Tname = unknown, Texpand = unknown> = Required<AccountsListRecord<Tbalance, Tname>> & BaseSystemFields<Texpand>
|
export type AccountsListResponse<Tbalance = unknown, Tname = unknown, Texpand = unknown> = Required<AccountsListRecord<Tbalance, Tname>> & BaseSystemFields<Texpand>
|
||||||
|
export type CompaniesResponse<Texpand = unknown> = Required<CompaniesRecord> & AuthSystemFields<Texpand>
|
||||||
export type SettingsResponse<Texpand = unknown> = Required<SettingsRecord> & BaseSystemFields<Texpand>
|
export type SettingsResponse<Texpand = unknown> = Required<SettingsRecord> & BaseSystemFields<Texpand>
|
||||||
export type TransactionsResponse<Texpand = unknown> = Required<TransactionsRecord> & BaseSystemFields<Texpand>
|
export type TransactionsResponse<Texpand = unknown> = Required<TransactionsRecord> & BaseSystemFields<Texpand>
|
||||||
|
|
||||||
|
@ -86,6 +93,7 @@ export type CollectionRecords = {
|
||||||
accounts: AccountsRecord
|
accounts: AccountsRecord
|
||||||
accountsData: AccountsDataRecord
|
accountsData: AccountsDataRecord
|
||||||
accountsList: AccountsListRecord
|
accountsList: AccountsListRecord
|
||||||
|
companies: CompaniesRecord
|
||||||
settings: SettingsRecord
|
settings: SettingsRecord
|
||||||
transactions: TransactionsRecord
|
transactions: TransactionsRecord
|
||||||
}
|
}
|
||||||
|
@ -94,6 +102,7 @@ export type CollectionResponses = {
|
||||||
accounts: AccountsResponse
|
accounts: AccountsResponse
|
||||||
accountsData: AccountsDataResponse
|
accountsData: AccountsDataResponse
|
||||||
accountsList: AccountsListResponse
|
accountsList: AccountsListResponse
|
||||||
|
companies: CompaniesResponse
|
||||||
settings: SettingsResponse
|
settings: SettingsResponse
|
||||||
transactions: TransactionsResponse
|
transactions: TransactionsResponse
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ module.exports = {
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [require('@tailwindcss/typography'), require('daisyui')],
|
plugins: [require('@tailwindcss/typography'), require('daisyui'), require('@tailwindcss/container-queries')],
|
||||||
daisyui: {
|
daisyui: {
|
||||||
logs: false,
|
logs: false,
|
||||||
themes: [
|
themes: [
|
||||||
|
|
Loading…
Reference in a new issue