From eed92b5ac3e695f1cd8278d8ea680e36d8d5dfc0 Mon Sep 17 00:00:00 2001 From: Knee Cola Date: Wed, 26 Nov 2025 20:10:18 +0100 Subject: [PATCH 1/3] Replace seenByTenant boolean with seenByTenantAt timestamp field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update location tracking to record when tenant views a location rather than just whether they've seen it. This provides better audit trail and enables future features like viewing history. Changes: - Convert seenByTenant (boolean) to seenByTenantAt (Date) in database schema - Update setSeenByTenantAt action to store timestamp instead of boolean flag - Modify LocationCard UI to display when location was seen by tenant - Update all references across locationActions, monthActions, and view components - Remove unused imports from ViewLocationCard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../share/location/[id]/LocationViewPage.tsx | 4 +- app/lib/actions/locationActions.ts | 16 ++-- app/lib/actions/monthActions.ts | 2 +- app/lib/db-types.ts | 2 +- app/ui/LocationCard.tsx | 73 +++++++++++-------- app/ui/ViewLocationCard.tsx | 4 +- 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/app/[locale]/share/location/[id]/LocationViewPage.tsx b/app/[locale]/share/location/[id]/LocationViewPage.tsx index a962b5d..aacae50 100644 --- a/app/[locale]/share/location/[id]/LocationViewPage.tsx +++ b/app/[locale]/share/location/[id]/LocationViewPage.tsx @@ -1,5 +1,5 @@ import { ViewLocationCard } from '@/app/ui/ViewLocationCard'; -import { fetchLocationById, setSeenByTenant } from '@/app/lib/actions/locationActions'; +import { fetchLocationById, setSeenByTenantAt } from '@/app/lib/actions/locationActions'; import { getUserSettingsByUserId } from '@/app/lib/actions/userSettingsActions'; import { notFound } from 'next/navigation'; import { myAuth } from '@/app/lib/auth'; @@ -20,7 +20,7 @@ export default async function LocationViewPage({ locationId }: { locationId:stri // If the page is not visited by the owner, mark it as seen by tenant if (!isOwner) { - await setSeenByTenant(locationId); + await setSeenByTenantAt(locationId); } return (); diff --git a/app/lib/actions/locationActions.ts b/app/lib/actions/locationActions.ts index cbe0e17..7be5986 100644 --- a/app/lib/actions/locationActions.ts +++ b/app/lib/actions/locationActions.ts @@ -428,7 +428,7 @@ export const fetchAllLocations = withUser(async (user:AuthenticatedUser, year:nu "yearMonth.year": 1, "yearMonth.month": 1, "bills": 1, - "seenByTenant": 1, + "seenByTenantAt": 1, // "bills.attachment": 0, // "bills.notes": 0, // "bills.hub3aText": 1, @@ -555,7 +555,7 @@ export const deleteLocationById = withUser(async (user:AuthenticatedUser, locati }) /** - * Sets the `seenByTenant` flag to true for a specific location. + * Sets the `seenByTenantAt` flag to true for a specific location. * * This function marks a location as viewed by the tenant. It first checks if the flag * is already set to true to avoid unnecessary database updates. @@ -564,17 +564,17 @@ export const deleteLocationById = withUser(async (user:AuthenticatedUser, locati * @returns {Promise} * * @example - * await setSeenByTenant("507f1f77bcf86cd799439011"); + * await setseenByTenantAt("507f1f77bcf86cd799439011"); */ -export const setSeenByTenant = async (locationID: string): Promise => { +export const setSeenByTenantAt = async (locationID: string): Promise => { const dbClient = await getDbClient(); - // First check if the location exists and if seenByTenant is already true + // First check if the location exists and if seenByTenantAt is already true const location = await dbClient.collection("lokacije") .findOne({ _id: locationID }); - // If location doesn't exist or seenByTenant is already true, no update needed - if (!location || location.seenByTenant === true) { + // If location doesn't exist or seenByTenantAt is already true, no update needed + if (!location || location.seenByTenantAt) { return; } @@ -582,7 +582,7 @@ export const setSeenByTenant = async (locationID: string): Promise => { await dbClient.collection("lokacije") .updateOne( { _id: locationID }, - { $set: { seenByTenant: true } } + { $set: { seenByTenantAt: new Date() } } ); } diff --git a/app/lib/actions/monthActions.ts b/app/lib/actions/monthActions.ts index d33d929..ead6e66 100644 --- a/app/lib/actions/monthActions.ts +++ b/app/lib/actions/monthActions.ts @@ -40,7 +40,7 @@ export const addMonth = withUser(async (user:AuthenticatedUser, { year, month }: // copy all the properties from the previous location ...prevLocation, // clear properties specific to the month - seenByTenant: undefined, + seenByTenantAt: undefined, utilBillsProofOfPaymentUploadedAt: undefined, utilBillsProofOfPaymentAttachment: undefined, // assign a new ID diff --git a/app/lib/db-types.ts b/app/lib/db-types.ts index 330c832..a61f0a9 100644 --- a/app/lib/db-types.ts +++ b/app/lib/db-types.ts @@ -74,7 +74,7 @@ export interface BillingLocation { /** (optional) monthly rent amount in cents */ rentAmount?: number | null; /** (optional) whether the location has been seen by tenant */ - seenByTenant?: boolean | null; + seenByTenantAt?: Date | null; /** (optional) utility bills proof of payment attachment */ utilBillsProofOfPaymentAttachment?: BillAttachment|null; /** (optional) date when utility bills proof of payment was uploaded */ diff --git a/app/ui/LocationCard.tsx b/app/ui/LocationCard.tsx index a434b35..95654a8 100644 --- a/app/ui/LocationCard.tsx +++ b/app/ui/LocationCard.tsx @@ -9,6 +9,7 @@ import { formatCurrency } from "../lib/formatStrings"; import Link from "next/link"; import { useLocale, useTranslations } from "next-intl"; import { toast } from "react-toastify"; +import { get } from "http"; export interface LocationCardProps { location: BillingLocation; @@ -21,7 +22,7 @@ export const LocationCard: FC = ({ location, currency }) => { name, yearMonth, bills, - seenByTenant, + seenByTenantAt, // NOTE: only the fileName is projected from the DB to reduce data transfer utilBillsProofOfPaymentUploadedAt } = location; @@ -63,37 +64,47 @@ export const LocationCard: FC = ({ location, currency }) => { - {monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentUploadedAt ? - <> -
{t("monthly-statement-legend")}
- { - monthlyExpense > 0 ? -
- - {t("payed-total-label")} {formatCurrency(monthlyExpense, currency ?? "EUR")} - -
- : null - } - {seenByTenant && ( -
- - {t("seen-by-tenant-label")} - + { monthlyExpense > 0 || seenByTenantAt || utilBillsProofOfPaymentUploadedAt ? + <> +
+
+
+ { + monthlyExpense > 0 ? +
+ + + {t("payed-total-label")} {formatCurrency(monthlyExpense, currency ?? "EUR")} + + +
+ : null + } + {seenByTenantAt && ( +
+ + + {t("seen-by-tenant-label")} at {seenByTenantAt.toLocaleString()} + + +
+ )} + {utilBillsProofOfPaymentUploadedAt && ( + + + + {t("download-proof-of-payment-label")} + + + + )}
- )} - {utilBillsProofOfPaymentUploadedAt && ( - - - {t("download-proof-of-payment-label")} - - - )} - : null +
+ + : null }
diff --git a/app/ui/ViewLocationCard.tsx b/app/ui/ViewLocationCard.tsx index 7bd0948..8a6bb0e 100644 --- a/app/ui/ViewLocationCard.tsx +++ b/app/ui/ViewLocationCard.tsx @@ -1,7 +1,7 @@ 'use client'; -import { FC, useEffect, useMemo, useState } from "react"; -import { BillAttachment, BilledTo, BillingLocation, UserSettings } from "../lib/db-types"; +import { FC, useMemo, useState } from "react"; +import { BilledTo, BillingLocation, UserSettings } from "../lib/db-types"; import { formatYearMonth } from "../lib/format"; import { formatCurrency, formatIban } from "../lib/formatStrings"; import { useTranslations } from "next-intl"; From 4f38fa44964b981277f00f55d3097d29dc4da1f7 Mon Sep 17 00:00:00 2001 From: Knee Cola Date: Wed, 26 Nov 2025 20:31:41 +0100 Subject: [PATCH 2/3] Add expand and fade-in animations to conditional form sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add smooth animations to form sections that appear when toggles are enabled, improving user experience with visual feedback. Changes: - Add expandFadeIn keyframe animation to Tailwind config - Apply expand-fade-in animation to UserSettingsForm payment sections - Apply expand-fade-in animation to LocationEditForm conditional fields - Update account page HomeIcon color from green to white for consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/[locale]/home/account/page.tsx | 2 +- app/ui/LocationEditForm.tsx | 8 ++++---- app/ui/UserSettingsForm.tsx | 8 ++++---- tailwind.config.ts | 13 +++++++++++++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/[locale]/home/account/page.tsx b/app/[locale]/home/account/page.tsx index 257f59c..d1371d7 100644 --- a/app/[locale]/home/account/page.tsx +++ b/app/[locale]/home/account/page.tsx @@ -17,7 +17,7 @@ const Page: FC = async () => {

{t('title')}

- {t('goto-home-button-label')} + {t('goto-home-button-label')} {t('goto-settings-button-label')}
diff --git a/app/ui/LocationEditForm.tsx b/app/ui/LocationEditForm.tsx index 00bf303..d63c4cb 100644 --- a/app/ui/LocationEditForm.tsx +++ b/app/ui/LocationEditForm.tsx @@ -119,7 +119,7 @@ export const LocationEditForm: FC = ({ location, yearMont {formValues.tenantPaymentMethod === "iban" && userSettings?.enableIbanPayment ? ( - <> +
{t("iban-payment--form-title")}
- +
) : // ELSE include hidden inputs to preserve existing values <> = ({ location, yearMont {formValues.rentDueNotification && ( - <> +
{t("rent-due-day-label")} = ({ userSettings, errors, message }) => {
{ formValues.enableRevolutPayment ? ( - <> +
{t("revolut-form-title")}
{t("payment-additional-notes")} - +
) : // ELSE include hidden input to preserve existing value <> diff --git a/tailwind.config.ts b/tailwind.config.ts index 2889b2d..bbe32ba 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -18,6 +18,9 @@ const config: Config = { 600: '#2F6FEB', }, }, + animation: { + 'expand-fade-in': 'expandFadeIn 0.3s ease-in-out forwards', + }, }, keyframes: { shimmer: { @@ -37,6 +40,16 @@ const config: Config = { maxHeight: '200px', }, }, + expandFadeIn: { + '0%': { + opacity: '0', + transform: 'scaleY(0.95)', + }, + '100%': { + opacity: '1', + transform: 'scaleY(1)', + }, + }, }, }, plugins: [ From 08b35648105a3b30c4c2b23d07f8a13c0ccd1297 Mon Sep 17 00:00:00 2001 From: Knee Cola Date: Wed, 26 Nov 2025 20:33:20 +0100 Subject: [PATCH 3/3] 2.9.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bb9389..1fc5ad4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "evidencija-rezija", - "version": "2.8.0", + "version": "2.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "version": "2.8.0", + "version": "2.9.0", "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", diff --git a/package.json b/package.json index d5367b3..bd61506 100644 --- a/package.json +++ b/package.json @@ -59,5 +59,5 @@ "engines": { "node": ">=18.17.0" }, - "version": "2.8.0" + "version": "2.9.0" }