package templates import "dealroom/internal/model" import "fmt" import "strings" func capitalizeFirst(s string) string { if len(s) == 0 { return s } return strings.ToUpper(s[:1]) + s[1:] } type AdminStats struct { ContactCount int DealCount int UserCount int OrgCount int } // --- Admin Dashboard --- templ AdminDashboard(profile *model.Profile, stats AdminStats) { @Layout(profile, "admin") {

Admin

Manage your organization's data.

@adminCard("/admin/contacts", "Contacts", fmt.Sprintf("%d", stats.ContactCount), "Buyers, sellers, and advisors", "teal") @adminCard("/admin/deals", "Deals", fmt.Sprintf("%d", stats.DealCount), "Active and archived deals", "amber") @adminCard("/admin/users", "Users", fmt.Sprintf("%d", stats.UserCount), "Team members and access", "green") @adminCard("/admin/organizations", "Organizations", fmt.Sprintf("%d", stats.OrgCount), "Organization management", "purple")
} } templ adminCard(href string, title string, count string, desc string, color string) {

{ title }

{ count }

{ desc }

} // --- Contacts List --- templ AdminContacts(profile *model.Profile, contacts []*model.Contact, filter string) { @Layout(profile, "admin") {
@adminBreadcrumb("Contacts")

Contacts

{ fmt.Sprintf("%d total", len(contacts)) }
@filterPill("/admin/contacts", "All", filter == "") @filterPill("/admin/contacts?type=buyer", "Buyers", filter == "buyer") @filterPill("/admin/contacts?type=internal", "Internal", filter == "internal") @filterPill("/admin/contacts?type=advisor", "Advisors", filter == "advisor")
New Contact
if len(contacts) == 0 { } for _, c := range contacts { }
Name Company Email Type Tags Actions
No contacts found.
{ contactInitials(c.FullName) }
{ c.FullName }

{ c.Title }

{ c.Company } { c.Email } @ContactTypeBadge(c.ContactType)
for _, tag := range splitTags(c.Tags) { if tag != "" { { tag } } }
@editDeleteActions("/admin/contacts", c.ID)
} } // --- Contact Form --- templ AdminContactForm(profile *model.Profile, contact *model.Contact, deals []*model.Deal, linkedDealIDs []string) { @Layout(profile, "admin") {
@adminBreadcrumbSub("Contacts", "/admin/contacts", formTitle("Contact", contact.ID))
@formField("full_name", "Full Name", "text", contact.FullName, true) @formField("email", "Email", "email", contact.Email, false) @formField("phone", "Phone", "tel", contact.Phone, false) @formField("company", "Company", "text", contact.Company, false) @formField("title", "Title", "text", contact.Title, false) @formSelect("contact_type", "Contact Type", contact.ContactType, []SelectOption{ {Value: "buyer", Label: "Buyer"}, {Value: "internal", Label: "Internal"}, {Value: "advisor", Label: "Advisor"}, }) @formField("tags", "Tags", "text", contact.Tags, false) @formTextarea("notes", "Notes", contact.Notes)
for _, d := range deals { }
@formActions("/admin/contacts")
} } // --- Deals List --- templ AdminDeals(profile *model.Profile, deals []*model.Deal) { @Layout(profile, "admin") {
@adminBreadcrumb("Deals")

Deals

{ fmt.Sprintf("%d total", len(deals)) }
New Deal
if len(deals) == 0 { } for _, d := range deals { }
Name Target Company Stage Size Status Actions
No deals found.
{ d.Name } { d.TargetCompany } @StageBadge(d.Stage) { formatDealSizeCurrency(d.DealSize, d.Currency) } if d.IsArchived { Archived } else { Active } @editDeleteActions("/admin/deals", d.ID)
} } func formatDealSizeCurrency(size float64, currency string) string { if size >= 1000000 { return fmt.Sprintf("%s%.1fM", currency+" ", size/1000000) } if size > 0 { return fmt.Sprintf("%s%.0f", currency+" ", size) } return "—" } // --- Deal Form --- templ AdminDealForm(profile *model.Profile, deal *model.Deal) { @Layout(profile, "admin") {
@adminBreadcrumbSub("Deals", "/admin/deals", formTitle("Deal", deal.ID))
@formField("name", "Deal Name", "text", deal.Name, true) @formTextarea("description", "Description", deal.Description) @formField("target_company", "Target Company", "text", deal.TargetCompany, false) @formField("industry", "Industry", "text", deal.Industry, false) @formSelect("stage", "Stage", deal.Stage, []SelectOption{ {Value: "prospect", Label: "Prospect"}, {Value: "internal", Label: "Internal"}, {Value: "initial_marketing", Label: "Initial Marketing"}, {Value: "ioi", Label: "IOI"}, {Value: "loi", Label: "LOI"}, {Value: "closed", Label: "Closed"}, })
@formField("deal_size", "Deal Size", "number", fmt.Sprintf("%.0f", deal.DealSize), false) @formSelect("currency", "Currency", deal.Currency, []SelectOption{ {Value: "USD", Label: "USD"}, {Value: "EUR", Label: "EUR"}, {Value: "GBP", Label: "GBP"}, })
@formField("ioi_date", "IOI Date", "date", deal.IOIDate, false) @formField("loi_date", "LOI Date", "date", deal.LOIDate, false)
@formField("exclusivity_end", "Exclusivity End", "date", deal.ExclusivityEnd, false) @formField("expected_close_date", "Expected Close", "date", deal.ExpectedCloseDate, false)
@formCheckbox("buyer_can_comment", "Allow buyer comments", deal.BuyerCanComment) @formCheckbox("seller_can_comment", "Allow seller comments", deal.SellerCanComment) @formCheckbox("is_archived", "Archived", deal.IsArchived) @formActions("/admin/deals")
} } // --- Users List --- templ AdminUsers(profile *model.Profile, users []*model.Profile) { @Layout(profile, "admin") {
@adminBreadcrumb("Users")

Users

{ fmt.Sprintf("%d total", len(users)) }
New User
if len(users) == 0 { } for _, u := range users { }
Name Email Role Actions
No users found.
{ initials(u.FullName) }
{ u.FullName }
{ u.Email } @roleBadge(u.Role) if u.ID != profile.ID { @editDeleteActions("/admin/users", u.ID) } else { Edit }
} } templ roleBadge(role string) { { capitalizeFirst(role) } } // --- User Form --- templ AdminUserForm(profile *model.Profile, user *model.Profile) { @Layout(profile, "admin") {
@adminBreadcrumbSub("Users", "/admin/users", formTitle("User", user.ID))
@formField("full_name", "Full Name", "text", user.FullName, true) @formField("email", "Email", "email", user.Email, true) @formSelect("role", "Role", user.Role, []SelectOption{ {Value: "owner", Label: "Owner"}, {Value: "admin", Label: "Admin"}, {Value: "member", Label: "Member"}, {Value: "viewer", Label: "Viewer"}, }) @formField("buyer_group", "Buyer Group", "text", user.BuyerGroup, false) @formActions("/admin/users")
} } // --- Organizations List --- templ AdminOrgs(profile *model.Profile, orgs []*model.Organization) { @Layout(profile, "admin") {
@adminBreadcrumb("Organizations")

Organizations

{ fmt.Sprintf("%d total", len(orgs)) }
New Organization
if len(orgs) == 0 { } for _, o := range orgs { }
Name Slug Actions
No organizations found.
{ o.Name } { o.Slug } @editDeleteActions("/admin/organizations", o.ID)
} } // --- Organization Form --- templ AdminOrgForm(profile *model.Profile, org *model.Organization) { @Layout(profile, "admin") {
@adminBreadcrumbSub("Organizations", "/admin/organizations", formTitle("Organization", org.ID))
@formField("name", "Name", "text", org.Name, true) @formField("slug", "Slug", "text", org.Slug, true) @formSelect("org_type", "Organization Type", org.OrgType, []SelectOption{ {Value: "company", Label: "Company"}, {Value: "bank", Label: "Investment Bank"}, {Value: "pe_vc", Label: "PE / VC Firm"}, }) @formActions("/admin/organizations")
} } // --- Shared Components --- type SelectOption struct { Value string Label string } func dealLinked(dealID string, linked []string) bool { for _, id := range linked { if id == dealID { return true } } return false } func formTitle(entity string, id string) string { if id == "" { return "New " + entity } return "Edit " + entity } templ adminBreadcrumb(section string) { } templ adminBreadcrumbSub(section string, sectionHref string, sub string) { } templ filterPill(href string, label string, active bool) { { label } } templ editDeleteActions(basePath string, id string) {
Edit Delete
} templ formField(name string, label string, fieldType string, value string, required bool) {
if required { } else { }
} templ formTextarea(name string, label string, value string) {
} templ formSelect(name string, label string, current string, options []SelectOption) {
} templ formCheckbox(name string, label string, checked bool) {
if checked { } else { }
} templ formActions(cancelHref string) {
Cancel
}