feat(admin/ui): enterprise inquiries pipeline

Add /enterprise page wired to /admin/enterprise/inquiries. Sales-style
pipeline: pending → contacted → converted | declined, with an inline
<select> on each row so triage is one click per inquiry rather than a
detail-page round-trip.

Each row shows company, contact, estimated volume, team size, and the
free-form notes from the marketing-site form. Pending is the default
filter so the queue surfaces first; "All" reveals historical decisions.

Added a sidebar entry under Accounts (Briefcase icon) so the inquiry
queue is one click away from the rest of the customer-facing admin.
This commit is contained in:
Matt
2026-05-28 09:52:42 +02:00
parent 3c5fb83e2b
commit 0c206dbfbb
5 changed files with 257 additions and 0 deletions
@@ -0,0 +1,41 @@
// /admin/enterprise/inquiries — sales-pipeline triage.
import { Request } from "@/lib/api/client";
import type {
EnterpriseInquiry,
UpdateEnterpriseInquiryRequest,
} from "@/lib/api/models/admin";
export function listEnterpriseInquiries(
status?: string,
limit = 50,
): Promise<{ data: EnterpriseInquiry[] }> {
const usp = new URLSearchParams();
if (status) usp.set("status", status);
usp.set("limit", String(limit));
return Request({
method: "GET",
url: `/admin/enterprise/inquiries?${usp.toString()}`,
authorization: true,
});
}
export function getEnterpriseInquiry(id: string): Promise<EnterpriseInquiry> {
return Request({
method: "GET",
url: `/admin/enterprise/inquiries/${id}`,
authorization: true,
});
}
export function updateEnterpriseInquiry(
id: string,
body: UpdateEnterpriseInquiryRequest,
): Promise<EnterpriseInquiry> {
return Request({
method: "PATCH",
url: `/admin/enterprise/inquiries/${id}`,
authorization: true,
data: body,
});
}
+29
View File
@@ -323,6 +323,35 @@ export interface ProvisioningJobCreate {
};
}
// /admin/enterprise/inquiries — sales pipeline for "talk to us"
// requests submitted from the marketing site.
export type EnterpriseInquiryStatus =
| "pending"
| "contacted"
| "converted"
| "declined";
export interface EnterpriseInquiry {
id: string;
company_name: string;
contact_name: string;
contact_email: string;
estimated_volume?: number | null;
team_size?: number | null;
notes: string;
status: EnterpriseInquiryStatus;
created_at: string;
processed_at?: string | null;
processed_by?: string | null;
}
export interface UpdateEnterpriseInquiryRequest {
status?: EnterpriseInquiryStatus;
assigned_to?: string;
notes?: string;
}
// /admin/campaigns/* — platform-wide campaign admin (force-stop runaway
// campaigns, inspect engagement counters per campaign).