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
| Name |
Company |
Email |
Type |
Tags |
Actions |
if len(contacts) == 0 {
| No contacts found. |
}
for _, c := range contacts {
{ 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) {
@Layout(profile, "admin") {
@adminBreadcrumbSub("Contacts", "/admin/contacts", formTitle("Contact", contact.ID))
}
}
// --- Deals List ---
templ AdminDeals(profile *model.Profile, deals []*model.Deal) {
@Layout(profile, "admin") {
@adminBreadcrumb("Deals")
Deals
{ fmt.Sprintf("%d total", len(deals)) }
New Deal
| Name |
Target Company |
Stage |
Size |
Status |
Actions |
if len(deals) == 0 {
| No deals found. |
}
for _, d := range deals {
| { 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))
}
}
// --- Users List ---
templ AdminUsers(profile *model.Profile, users []*model.Profile) {
@Layout(profile, "admin") {
@adminBreadcrumb("Users")
Users
{ fmt.Sprintf("%d total", len(users)) }
New User
| Name |
Email |
Role |
Actions |
if len(users) == 0 {
| No users found. |
}
for _, u := range users {
{ 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))
}
}
// --- Organizations List ---
templ AdminOrgs(profile *model.Profile, orgs []*model.Organization) {
@Layout(profile, "admin") {
@adminBreadcrumb("Organizations")
| Name |
Slug |
Actions |
if len(orgs) == 0 {
| No organizations found. |
}
for _, o := range orgs {
| { 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))
}
}
// --- Shared Components ---
type SelectOption struct {
Value string
Label string
}
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) {
}
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) {
}