From 7a74d5f17e04c72a63dceff6d66c98377c1f4bb2 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 22 Aug 2025 21:47:20 -0400 Subject: [PATCH] Added labels for category and tags, utils for default times. --- .../src/components/AddValueRecordModal.vue | 8 ++--- web-app/src/components/CategoryLabel.vue | 29 +++++++++++++++++ web-app/src/components/TagLabel.vue | 31 +++++++++++++++++++ web-app/src/pages/TransactionPage.vue | 6 ++-- web-app/src/pages/UserAccountLayout.vue | 23 +++++++++----- .../src/pages/forms/EditTransactionPage.vue | 15 ++++----- web-app/src/util/time.ts | 10 ++++++ 7 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 web-app/src/components/CategoryLabel.vue create mode 100644 web-app/src/components/TagLabel.vue create mode 100644 web-app/src/util/time.ts diff --git a/web-app/src/components/AddValueRecordModal.vue b/web-app/src/components/AddValueRecordModal.vue index e8ef984..897b035 100644 --- a/web-app/src/components/AddValueRecordModal.vue +++ b/web-app/src/components/AddValueRecordModal.vue @@ -7,6 +7,7 @@ import ModalWrapper from './ModalWrapper.vue'; import AppButton from './AppButton.vue'; import { AccountApiClient, AccountValueRecordType, type Account, type AccountValueRecord, type AccountValueRecordCreationPayload } from '@/api/account'; import { useProfileStore } from '@/stores/profile-store'; +import { datetimeLocalToISO, getDatetimeLocalValueForNow } from '@/util/time'; const props = defineProps<{ account: Account }>() const profileStore = useProfileStore() @@ -19,10 +20,7 @@ const amount = ref(0) async function show(): Promise { if (!modal.value) return Promise.resolve(undefined) - const now = new Date() - const localDate = new Date(now.getTime() - now.getTimezoneOffset() * 60_000) - localDate.setMilliseconds(0) - timestamp.value = localDate.toISOString().slice(0, -1) + timestamp.value = getDatetimeLocalValueForNow() amount.value = props.account.currentBalance ?? 0 savedValueRecord.value = undefined const result = await modal.value.show() @@ -35,7 +33,7 @@ async function show(): Promise { async function addValueRecord() { if (!profileStore.state) return const payload: AccountValueRecordCreationPayload = { - timestamp: new Date(timestamp.value).toISOString(), + timestamp: datetimeLocalToISO(timestamp.value), type: AccountValueRecordType.BALANCE, value: amount.value } diff --git a/web-app/src/components/CategoryLabel.vue b/web-app/src/components/CategoryLabel.vue new file mode 100644 index 0000000..ddde284 --- /dev/null +++ b/web-app/src/components/CategoryLabel.vue @@ -0,0 +1,29 @@ + + + diff --git a/web-app/src/components/TagLabel.vue b/web-app/src/components/TagLabel.vue new file mode 100644 index 0000000..11dccff --- /dev/null +++ b/web-app/src/components/TagLabel.vue @@ -0,0 +1,31 @@ + + + diff --git a/web-app/src/pages/TransactionPage.vue b/web-app/src/pages/TransactionPage.vue index a738b50..693d413 100644 --- a/web-app/src/pages/TransactionPage.vue +++ b/web-app/src/pages/TransactionPage.vue @@ -4,7 +4,9 @@ import { formatMoney } from '@/api/data'; import { TransactionApiClient, type TransactionDetail } from '@/api/transaction'; import AppButton from '@/components/AppButton.vue'; import AppPage from '@/components/AppPage.vue'; +import CategoryLabel from '@/components/CategoryLabel.vue'; import PropertiesTable from '@/components/PropertiesTable.vue'; +import TagLabel from '@/components/TagLabel.vue'; import { useProfileStore } from '@/stores/profile-store'; import { showAlert, showConfirm } from '@/util/alert'; import { onMounted, ref, type Ref } from 'vue'; @@ -70,7 +72,7 @@ async function deleteTransaction() { Category - {{ transaction.category.name }} + @@ -88,7 +90,7 @@ async function deleteTransaction() { Tags - {{ tag }}, + diff --git a/web-app/src/pages/UserAccountLayout.vue b/web-app/src/pages/UserAccountLayout.vue index 4a2da6b..0e4820d 100644 --- a/web-app/src/pages/UserAccountLayout.vue +++ b/web-app/src/pages/UserAccountLayout.vue @@ -54,12 +54,11 @@ async function checkAuth() {

Finnow

- - Welcome, {{ authStore.state?.username }} + + - Log out
@@ -93,18 +92,26 @@ async function checkAuth() { .app-logout-button { cursor: pointer; - font-weight: bold; - margin-right: 1em; + margin-right: 0.5em; + background-color: #0099d1; + border-radius: 50%; + padding: 0.35rem; } .app-logout-button:hover { color: var(--bg-secondary); - text-decoration: underline; } .app-user-widget { - margin-right: 1em; - font-weight: bold; + margin-right: 0.5em; + cursor: pointer; + background-color: #0099d1; + border-radius: 50%; + padding: 0.35rem; +} + +.app-user-widget:hover { + color: var(--bg-secondary); } .app-header-link { diff --git a/web-app/src/pages/forms/EditTransactionPage.vue b/web-app/src/pages/forms/EditTransactionPage.vue index 2c5d395..d588012 100644 --- a/web-app/src/pages/forms/EditTransactionPage.vue +++ b/web-app/src/pages/forms/EditTransactionPage.vue @@ -20,7 +20,9 @@ import FormActions from '@/components/form/FormActions.vue'; import FormControl from '@/components/form/FormControl.vue'; import FormGroup from '@/components/form/FormGroup.vue'; import LineItemsEditor from '@/components/LineItemsEditor.vue'; +import TagLabel from '@/components/TagLabel.vue'; import { useProfileStore } from '@/stores/profile-store'; +import { getDatetimeLocalValueForNow } from '@/util/time'; import { computed, onMounted, ref, watch, type Ref } from 'vue'; import { useRoute, useRouter, } from 'vue-router'; @@ -99,6 +101,10 @@ onMounted(async () => { } finally { loading.value = false } + } else { + // Load default values. + timestamp.value = getDatetimeLocalValueForNow() + amount.value = Math.pow(10, currency.value?.fractionalDigits ?? 0) } }) @@ -210,7 +216,7 @@ function isFormValid() { * least one edit to it. Otherwise, there's no point in saving. */ function isEdited() { - if (!existingTransaction.value) return false + if (!existingTransaction.value) return true const tagsEqual = tags.value.every(t => existingTransaction.value?.tags.includes(t)) && existingTransaction.value.tags.every(t => tags.value.includes(t)) let lineItemsEqual = false @@ -308,12 +314,7 @@ function isEdited() {
- - {{ tag }} - - +