package templates import ( "fmt" "veola/internal/models" ) type SettingsData struct { Page Values map[string]string // CredentialStatus maps each secret settings key to a human-readable // status ("Saved in settings", "Set in config.toml", "Not set"). Secret // values are never rendered into the form itself. CredentialStatus map[string]string IsAdmin bool Users []models.User TestNtfyOK string TestApifyOK string TestEbayOK string TestResendOK string EbayUsedToday int EbayDailyLimit int ApifyToday int ApifyMonth int ApifyCostPerCall float64 MonthlyBudget float64 PasswordMsg string PasswordError string UserMsg string UserError string EmailMsg string EmailError string // ForwardAuthMode is true when the deployment delegates identity to // Authentik (forward-auth). Email is then managed centrally in Authentik // and read-only in Veola for every user. ForwardAuthMode bool } // ApifyMonthCost is the estimated month-to-date Apify spend. func (d SettingsData) ApifyMonthCost() float64 { return float64(d.ApifyMonth) * d.ApifyCostPerCall } // EbayLimitReached reports whether eBay polling is currently halted because // the daily call limit has been hit. func (d SettingsData) EbayLimitReached() bool { return d.EbayDailyLimit > 0 && d.EbayUsedToday >= d.EbayDailyLimit } // credStatus renders the "Saved in settings / Set in config.toml / Not set" // indicator for a secret field without ever printing the secret itself. templ credStatus(d SettingsData, key string) { if s := d.CredentialStatus[key]; s != "" {
Status: { s }
} } templ settingsBody(d SettingsData) {

Settings

Credentials, budget, notifications, and users

Apify, eBay and Ntfy

API credentials (Apify, eBay, ntfy, Resend) are managed in config.toml on the server, not here. Use the Test buttons to verify them.
@CSRFInput(d.CSRFToken)
@credStatus(d, "apify_api_key")
@credStatus(d, "ebay_client_id")
@credStatus(d, "ebay_client_secret")
eBay API calls today: if d.EbayDailyLimit > 0 { { fmt.Sprintf("%d / %d", d.EbayUsedToday, d.EbayDailyLimit) } } else { { fmt.Sprintf("%d (uncapped)", d.EbayUsedToday) } } if d.EbayLimitReached() { Limit reached. eBay polling halted until the next reset (midnight US Pacific). }
@credStatus(d, "ntfy_auth")
@credStatus(d, "resend_api_key")
Used for deal-alert and weekly-digest email. Domain must be verified in Resend.
Apify does not report exact spend; this estimate drives the budget figures shown to everyone.
0 hides the budget bar. When set, the dashboard shows month-to-date spend against it.
if !d.IsAdmin {
Read-only for non-admin users.
} else {
}
if d.TestNtfyOK != "" {
{ d.TestNtfyOK }
} if d.TestApifyOK != "" {
{ d.TestApifyOK }
} if d.TestEbayOK != "" {
{ d.TestEbayOK }
} if d.TestResendOK != "" {
{ d.TestResendOK }
}
Apify calls this month: { fmt.Sprintf("%d", d.ApifyMonth) } if d.ApifyCostPerCall > 0 { { fmt.Sprintf("(~$%.2f est.)", d.ApifyMonthCost()) } } today: { fmt.Sprintf("%d", d.ApifyToday) }

Change Password

if d.PasswordError != "" {
{ d.PasswordError }
} if d.PasswordMsg != "" {
{ d.PasswordMsg }
}
@CSRFInput(d.CSRFToken)

Email Notifications

if d.EmailError != "" {
{ d.EmailError }
} if d.EmailMsg != "" {
{ d.EmailMsg }
}
@CSRFInput(d.CSRFToken)
if emailManagedExternally(d) {
Managed by Authentik. Change your email in your Authentik profile; it syncs here on next sign-in.
} else {
Where deal alerts and the weekly digest are sent. Requires Resend to be configured by an admin.
}
if d.IsAdmin {

Users

if d.UserError != "" {
{ d.UserError }
} if d.UserMsg != "" {
{ d.UserMsg }
} for _, u := range d.Users { }
UsernameRoleCreated
{ u.Username } { string(u.Role) } { u.CreatedAt.Format("2006-01-02") }
}
} // currentEmail and the two opt-in accessors read the signed-in user's saved // email preferences off Page.CurrentUser, guarding the nil case. func currentEmail(d SettingsData) string { if d.CurrentUser == nil { return "" } return d.CurrentUser.Email } func currentDealAlerts(d SettingsData) bool { return d.CurrentUser != nil && d.CurrentUser.EmailDealAlerts } func currentWeeklyDigest(d SettingsData) bool { return d.CurrentUser != nil && d.CurrentUser.EmailWeeklyDigest } // emailManagedExternally reports whether email is owned by Authentik and so is // read-only in Veola. True for any user when the deployment runs in forward-auth // mode (email is centralized in Authentik), and for an individual forward row // regardless of mode (the address is its IdP match key). func emailManagedExternally(d SettingsData) bool { return d.ForwardAuthMode || (d.CurrentUser != nil && d.CurrentUser.AuthSource == "forward") } templ Settings(d SettingsData) { @Layout(d.Page, settingsBody(d)) }