feat(03-02): add StatusBadge and DocumentsTable shared portal components

- StatusBadge: color-coded pill for Draft=gray, Sent=blue, Viewed=amber, Signed=green
- DocumentsTable: reusable table with optional Client column, StatusBadge integration
- Date format: toLocaleDateString en-US short month; null sentAt renders as em-dash
This commit is contained in:
Chandler Copeland
2026-03-19 16:37:30 -06:00
parent 9c4caeedba
commit 28d42f5d9b
2 changed files with 79 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
import { StatusBadge } from "./StatusBadge";
type DocumentRow = {
id: string;
name: string;
clientName: string | null;
status: "Draft" | "Sent" | "Viewed" | "Signed";
sentAt: Date | null;
clientId: string;
};
type Props = { rows: DocumentRow[]; showClientColumn?: boolean };
export function DocumentsTable({ rows, showClientColumn = true }: Props) {
return (
<table className="w-full text-sm">
<thead>
<tr>
<th className="text-left text-xs font-medium text-gray-500 uppercase px-4 py-3">
Document Name
</th>
{showClientColumn && (
<th className="text-left text-xs font-medium text-gray-500 uppercase px-4 py-3">
Client
</th>
)}
<th className="text-left text-xs font-medium text-gray-500 uppercase px-4 py-3">
Status
</th>
<th className="text-left text-xs font-medium text-gray-500 uppercase px-4 py-3">
Date Sent
</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id}>
<td className="px-4 py-3 border-t border-gray-100">{row.name}</td>
{showClientColumn && (
<td className="px-4 py-3 border-t border-gray-100">
{row.clientName ?? "—"}
</td>
)}
<td className="px-4 py-3 border-t border-gray-100">
<StatusBadge status={row.status} />
</td>
<td className="px-4 py-3 border-t border-gray-100">
{row.sentAt
? row.sentAt.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})
: "—"}
</td>
</tr>
))}
</tbody>
</table>
);
}

View File

@@ -0,0 +1,18 @@
type DocumentStatus = "Draft" | "Sent" | "Viewed" | "Signed";
const STATUS_STYLES: Record<DocumentStatus, string> = {
Draft: "bg-gray-100 text-gray-600",
Sent: "bg-blue-100 text-blue-700",
Viewed: "bg-amber-100 text-amber-700",
Signed: "bg-green-100 text-green-700",
};
export function StatusBadge({ status }: { status: DocumentStatus }) {
return (
<span
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${STATUS_STYLES[status]}`}
>
{status}
</span>
);
}