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:
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user