feat(07-02): wire agentDownloadUrl to doc detail page, add signedAt to dashboard and client profile
- document detail page: import createAgentDownloadToken, generate agentDownloadUrl server-side for signed docs (signedFilePath present), pass agentDownloadUrl and signedAt props to PreparePanel - DocumentsTable: add signedAt to DocumentRow type, add Date Signed column header and cell - dashboard page: add signedAt to db select so allRows includes signed date for Signed documents - ClientProfileClient: add signedAt to local DocumentRow type (fixes type mismatch with DocumentsTable) - clients/[id]/page: add signedAt to query select to satisfy updated DocumentRow type
This commit is contained in:
@@ -20,6 +20,7 @@ export default async function ClientProfilePage({
|
||||
name: documents.name,
|
||||
status: documents.status,
|
||||
sentAt: documents.sentAt,
|
||||
signedAt: documents.signedAt,
|
||||
clientId: documents.clientId,
|
||||
clientName: sql<string>`${clients.name}`,
|
||||
})
|
||||
|
||||
@@ -22,6 +22,7 @@ export default async function DashboardPage({
|
||||
name: documents.name,
|
||||
status: documents.status,
|
||||
sentAt: documents.sentAt,
|
||||
signedAt: documents.signedAt,
|
||||
clientName: clients.name,
|
||||
clientId: documents.clientId,
|
||||
})
|
||||
@@ -38,16 +39,18 @@ export default async function DashboardPage({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-[var(--navy)] text-2xl font-semibold">
|
||||
<div style={{ marginBottom: "1.5rem" }}>
|
||||
<h1 style={{ color: "#1B2B4B", fontSize: "1.5rem", fontWeight: 700, marginBottom: "0.25rem" }}>
|
||||
Welcome back, {firstName}
|
||||
</h1>
|
||||
<p style={{ color: "#6B7280", fontSize: "0.875rem" }}>All documents across your clients</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<span className="text-sm text-gray-600">Filter by status:</span>
|
||||
<DashboardFilters currentStatus={status} />
|
||||
</div>
|
||||
<div className="bg-white rounded-xl shadow-sm overflow-hidden">
|
||||
|
||||
<div style={{ backgroundColor: "white", borderRadius: "1rem", boxShadow: "0 1px 4px rgba(0,0,0,0.07)", overflow: "hidden" }}>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "0.75rem", padding: "1rem 1.5rem", borderBottom: "1px solid #F3F4F6" }}>
|
||||
<span style={{ fontSize: "0.875rem", color: "#6B7280" }}>Filter by status:</span>
|
||||
<DashboardFilters currentStatus={status} />
|
||||
</div>
|
||||
<DocumentsTable rows={filteredRows} showClientColumn={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { eq } from 'drizzle-orm';
|
||||
import Link from 'next/link';
|
||||
import { PdfViewerWrapper } from './_components/PdfViewerWrapper';
|
||||
import { PreparePanel } from './_components/PreparePanel';
|
||||
import { createAgentDownloadToken } from '@/lib/signing/token';
|
||||
|
||||
export default async function DocumentPage({
|
||||
params,
|
||||
@@ -29,6 +30,12 @@ export default async function DocumentPage({
|
||||
|
||||
if (!doc) redirect('/portal/dashboard');
|
||||
|
||||
// Generate agent download URL server-side for Signed documents
|
||||
// Must be done here (server component) — PreparePanel is 'use client' and cannot call createAgentDownloadToken
|
||||
const agentDownloadUrl = doc.signedFilePath
|
||||
? `/api/documents/${docId}/download?adt=${await createAgentDownloadToken(docId)}`
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className="max-w-5xl mx-auto px-4 py-6">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
@@ -56,6 +63,8 @@ export default async function DocumentPage({
|
||||
defaultEmail={docClient?.email ?? ''}
|
||||
clientName={docClient?.name ?? ''}
|
||||
currentStatus={doc.status}
|
||||
agentDownloadUrl={agentDownloadUrl}
|
||||
signedAt={doc.signedAt ?? null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,7 @@ type DocumentRow = {
|
||||
clientName: string | null;
|
||||
status: "Draft" | "Sent" | "Viewed" | "Signed";
|
||||
sentAt: Date | null;
|
||||
signedAt: Date | null;
|
||||
clientId: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ type DocumentRow = {
|
||||
clientName: string | null;
|
||||
status: "Draft" | "Sent" | "Viewed" | "Signed";
|
||||
sentAt: Date | null;
|
||||
signedAt: Date | null;
|
||||
clientId: string;
|
||||
};
|
||||
|
||||
@@ -39,6 +40,9 @@ export function DocumentsTable({ rows, showClientColumn = true }: Props) {
|
||||
<th style={{ textAlign: "left", fontSize: "0.75rem", fontWeight: 600, color: "#6B7280", textTransform: "uppercase", letterSpacing: "0.05em", padding: "0.75rem 1.5rem" }}>
|
||||
Date Sent
|
||||
</th>
|
||||
<th style={{ textAlign: "left", fontSize: "0.75rem", fontWeight: 600, color: "#6B7280", textTransform: "uppercase", letterSpacing: "0.05em", padding: "0.75rem 1.5rem" }}>
|
||||
Date Signed
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -64,6 +68,16 @@ export function DocumentsTable({ rows, showClientColumn = true }: Props) {
|
||||
? new Date(row.sentAt).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })
|
||||
: "—"}
|
||||
</td>
|
||||
<td style={{ padding: "0.875rem 1.5rem", color: "#6B7280" }}>
|
||||
{row.signedAt
|
||||
? new Date(row.signedAt).toLocaleDateString("en-US", {
|
||||
timeZone: "America/Denver",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})
|
||||
: "—"}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user