Replace seenByTenant boolean with seenByTenantAt timestamp field

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 <noreply@anthropic.com>
This commit is contained in:
Knee Cola
2025-11-26 20:10:18 +01:00
parent 4139e29de8
commit eed92b5ac3
6 changed files with 56 additions and 45 deletions

View File

@@ -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<LocationCardProps> = ({ 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<LocationCardProps> = ({ location, currency }) => {
</Link>
<ShareIcon className="h-[1em] w-[1em] cursor-pointer text-2xl inline hover:text-red-500" title="create sharable link" onClick={handleCopyLinkClick} />
</div>
{monthlyExpense > 0 || seenByTenant || utilBillsProofOfPaymentUploadedAt ?
<>
<div className="divider m-0 font-bold uppercase">{t("monthly-statement-legend")}</div>
{
monthlyExpense > 0 ?
<div className="flex items-center gap-2 ml-2">
<BanknotesIcon className="h-5 w-5" />
{t("payed-total-label")} <strong>{formatCurrency(monthlyExpense, currency ?? "EUR")}</strong>
<CheckCircleIcon className="h-5 w-5 text-success" />
</div>
: null
}
{seenByTenant && (
<div className="flex items-center gap-2 mt-[-0.2rem] ml-2">
<EyeIcon className="h-5 w-5" />
<span className="text-sm">{t("seen-by-tenant-label")}</span>
<CheckCircleIcon className="h-5 w-5 text-success" />
{ monthlyExpense > 0 || seenByTenantAt || utilBillsProofOfPaymentUploadedAt ?
<>
<div className="flex ml-1">
<div className="divider divider-horizontal p-0 m-0"></div>
<div className="card rounded-box grid grow place-items-left place-items-top p-0">
{
monthlyExpense > 0 ?
<div className="flex ml-1">
<span className="w-5 min-w-5 mr-2"><BanknotesIcon className="mt-[.1rem]" /></span>
<span>
{t("payed-total-label")}&nbsp;<strong>{formatCurrency(monthlyExpense, currency ?? "EUR")}</strong>
<CheckCircleIcon className="h-5 w-5 ml-1 mt-[-.2rem] text-success inline-block" />
</span>
</div>
: null
}
{seenByTenantAt && (
<div className="flex mt-1 ml-1">
<span className="w-5 mr-2 min-w-5"><EyeIcon className="mt-[.1rem]" /></span>
<span>
<span>{t("seen-by-tenant-label")} at {seenByTenantAt.toLocaleString()}</span>
<CheckCircleIcon className="h-5 w-5 ml-1 mt-[-.2rem] text-success inline-block" />
</span>
</div>
)}
{utilBillsProofOfPaymentUploadedAt && (
<Link
href={`/share/proof-of-payment/${_id}/`}
target="_blank"
className="flex mt-1 ml-1">
<span className="w-5 min-w-5 mr-2"><TicketIcon className="mt-[.1rem]" /></span>
<span>
<span className="underline">{t("download-proof-of-payment-label")}</span>
<CheckCircleIcon className="h-5 w-5 ml-2 mt-[-.2rem] text-success inline-block" />
</span>
</Link>
)}
</div>
)}
{utilBillsProofOfPaymentUploadedAt && (
<Link
href={`/share/proof-of-payment/${_id}/`}
target="_blank"
className="flex items-center gap-2 mt-[-0.2rem] ml-2"
>
<TicketIcon className="h-5 w-5" />
<span className="text-sm">{t("download-proof-of-payment-label")}</span>
<CheckCircleIcon className="h-5 w-5 text-success" />
</Link>
)}
</>: null
</div>
</> : null
}
</div>