[FEAT] 實作公共事業費逾期提醒、租戶自訂通知設定及發送測試信功能
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 56s

This commit is contained in:
2026-03-05 16:01:00 +08:00
parent 016366407c
commit 07b7d9b327
15 changed files with 519 additions and 44 deletions

View File

@@ -41,7 +41,8 @@ import {
AlertDialogTitle,
} from "@/Components/ui/alert-dialog";
import { Can } from "@/Components/Permission/Can";
import { formatDateWithDayOfWeek, formatInvoiceNumber, getDateRange } from "@/utils/format";
import { formatDateWithDayOfWeek, getDateRange } from "@/utils/format";
import { StatusBadge } from "@/Components/shared/StatusBadge";
interface PageProps {
fees: {
@@ -361,12 +362,20 @@ export default function UtilityFeeIndex({ fees, availableCategories, filters }:
<TableHeader className="bg-gray-50">
<TableRow>
<TableHead className="w-[50px] text-center">#</TableHead>
<TableHead className="w-[120px]">
<button
onClick={() => handleSort('due_date')}
className="flex items-center hover:text-gray-900"
>
<SortIcon field="due_date" />
</button>
</TableHead>
<TableHead className="w-[120px]">
<button
onClick={() => handleSort('transaction_date')}
className="flex items-center hover:text-gray-900"
>
<SortIcon field="transaction_date" />
<SortIcon field="transaction_date" />
</button>
</TableHead>
<TableHead>
@@ -377,14 +386,7 @@ export default function UtilityFeeIndex({ fees, availableCategories, filters }:
<SortIcon field="category" />
</button>
</TableHead>
<TableHead>
<button
onClick={() => handleSort('invoice_number')}
className="flex items-center hover:text-gray-900"
>
<SortIcon field="invoice_number" />
</button>
</TableHead>
<TableHead className="w-[100px] text-center"></TableHead>
<TableHead className="text-right">
<div className="flex justify-end">
<button
@@ -402,7 +404,7 @@ export default function UtilityFeeIndex({ fees, availableCategories, filters }:
<TableBody>
{fees.data.length === 0 ? (
<TableRow>
<TableCell colSpan={7}>
<TableCell colSpan={8}>
<div className="flex flex-col items-center justify-center space-y-2 py-8">
<FileText className="h-8 w-8 text-gray-300" />
<p className="text-gray-500"></p>
@@ -415,16 +417,27 @@ export default function UtilityFeeIndex({ fees, availableCategories, filters }:
<TableCell className="text-gray-500 font-medium text-center">
{fees.from + index}
</TableCell>
<TableCell className="font-medium text-gray-700">
{formatDateWithDayOfWeek(fee.transaction_date)}
<TableCell className="text-gray-700">
{formatDateWithDayOfWeek(fee.due_date)}
</TableCell>
<TableCell className={`font-medium ${fee.transaction_date ? "text-gray-700" : "text-gray-400 italic"}`}>
{fee.transaction_date ? formatDateWithDayOfWeek(fee.transaction_date) : "未填寫"}
</TableCell>
<TableCell>
<Badge variant="outline">
{fee.category}
</Badge>
</TableCell>
<TableCell className="font-mono text-sm text-gray-600">
{formatInvoiceNumber(fee.invoice_number)}
<TableCell className="text-center">
{fee.payment_status === "paid" && (
<StatusBadge variant="success"></StatusBadge>
)}
{fee.payment_status === "pending" && (
<StatusBadge variant="warning"></StatusBadge>
)}
{fee.payment_status === "overdue" && (
<StatusBadge variant="destructive"></StatusBadge>
)}
</TableCell>
<TableCell className="text-right font-bold text-gray-900">
$ {Number(fee.amount).toLocaleString()}