package handlers import ( "log" "net/http" ssstripe "git.nixc.us/a250/ss-atlas/internal/stripe" "git.nixc.us/a250/ss-atlas/internal/version" ) func (a *App) handleDashboard(w http.ResponseWriter, r *http.Request) { acct, identity, err := a.currentAccount(r) remoteUser := accountDisplay(acct, identity) remoteEmail := firstNonEmpty(identity.Email, "") isSubscribed := isSubscribedAccount(acct) var customerID string stackDeployed := false stackRunning := false var subStatus *ssstripe.SubscriptionStatus paidNotActivated := false if err != nil { log.Printf("dashboard: account lookup failed: %v", err) } if acct != nil && acct.StripeCustomerID != "" && !isSubscribed { paidNotActivated = true } var instSlug string var customerDomain string if isSubscribed && acct != nil { customerID = acct.StripeCustomerID if customerID != "" { subStatus = a.stripe.GetCustomerSubscriptionStatus(customerID) } if subStatus == nil { subStatus = &ssstripe.SubscriptionStatus{Label: "Active", Badge: "badge-active"} } inst, err := a.accounts.InstanceByAccountID(r.Context(), acct.ID) if err == nil { instSlug = inst.Slug customerDomain = inst.CustomerDomain exists, err := a.swarm.StackExists(inst.StackName) if err != nil { log.Printf("dashboard: stack check failed for %s: %v", inst.StackName, err) } stackDeployed = exists if exists { replicas, _ := a.swarm.GetWebReplicas(inst.StackName) stackRunning = replicas > 0 } } else { log.Printf("dashboard: instance lookup failed for account %d: %v", acct.ID, err) } } data := map[string]any{ "AppURL": a.cfg.AppURL, "IdentityURL": a.cfg.IdentityURL, "User": remoteUser, "Email": remoteEmail, "Groups": identity.Groups, "Domain": a.cfg.TraefikDomain, "InstanceSlug": instSlug, "IsSubscribed": isSubscribed, "PaidNotActivated": paidNotActivated, "CustomerID": customerID, "SubStatus": subStatus, "StackDeployed": stackDeployed, "StackRunning": stackRunning, "CustomerDomain": customerDomain, "StackError": r.URL.Query().Get("stack_error"), "PortalError": r.URL.Query().Get("portal_error"), "Linked": r.URL.Query().Get("linked") == "1", "Commit": version.Commit, "BuildTime": version.BuildTime, } if err := a.tmpl.ExecuteTemplate(w, "dashboard.html", data); err != nil { log.Printf("template error: %v", err) http.Error(w, "internal error", http.StatusInternalServerError) } } func contains(s, substr string) bool { return len(s) >= len(substr) && searchString(s, substr) } func searchString(s, sub string) bool { for i := 0; i <= len(s)-len(sub); i++ { if s[i:i+len(sub)] == sub { return true } } return false }