From 99c0dc5a411d2eccbdf49b9e050686a0f2558619 Mon Sep 17 00:00:00 2001 From: talksik Date: Tue, 28 Oct 2025 16:50:24 -0700 Subject: [PATCH] add total revenue in header --- go-cli/cmd/main.go | 108 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/go-cli/cmd/main.go b/go-cli/cmd/main.go index f095769..55360b0 100644 --- a/go-cli/cmd/main.go +++ b/go-cli/cmd/main.go @@ -3,7 +3,9 @@ package main import ( "context" "crypto/tls" + "encoding/json" "fmt" + "io" "os" "strings" "time" @@ -18,8 +20,106 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" + "net/http" ) +type MetricResponse struct { + Metrics []struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Value float64 `json:"value"` + Unit string `json:"unit"` + Period string `json:"period"` + } `json:"metrics"` +} + +func getRevenue() string { + client := &http.Client{} + + req, err := http.NewRequest("GET", "https://api.revenuecat.com/v2/projects/proj5b2f7356/metrics/overview", nil) + if err != nil { + return fmt.Sprintf("Error creating request: %v", err) + } + + // Add authorization header + req.Header.Add("Authorization", "Bearer sk_wxmjNCLtnDSUPmSXlbEWyuqkpTVTi") + + response, err := client.Do(req) + if err != nil { + return fmt.Sprintf("Error fetching revenue: %v", err) + } + defer response.Body.Close() + + body, err := io.ReadAll(response.Body) + if err != nil { + return fmt.Sprintf("Error reading response: %v", err) + } + + var metricResp MetricResponse + err = json.Unmarshal(body, &metricResp) + if err != nil { + return fmt.Sprintf("Error parsing JSON: %v", err) + } + + // Create a map for easy lookup + metrics := make(map[string]struct { + name string + value float64 + unit string + }) + + for _, m := range metricResp.Metrics { + metrics[m.ID] = struct { + name string + value float64 + unit string + }{ + name: m.Name, + value: m.Value, + unit: m.Unit, + } + } + if m, ok := metrics["revenue"]; ok { + return fmt.Sprintf("%s%.0f", m.unit, m.value) + } + return "" + + // Format the output + // var result strings.Builder + // result.WriteString("\n") + // result.WriteString("šŸ’° Revenue Metrics\n") + // result.WriteString("═══════════════════════════════════════\n\n") + + // Key metrics + // if m, ok := metrics["mrr"]; ok { + // result.WriteString(fmt.Sprintf("MRR: %s%.0f\n", m.unit, m.value)) + // } + // if m, ok := metrics["revenue"]; ok { + // result.WriteString(fmt.Sprintf("Revenue (28d): %s%.0f\n", m.unit, m.value)) + // } + // result.WriteString("\n") + // + // if m, ok := metrics["active_subscriptions"]; ok { + // result.WriteString(fmt.Sprintf("Active Subscriptions: %s%.0f\n", m.unit, m.value)) + // } + // if m, ok := metrics["active_trials"]; ok { + // result.WriteString(fmt.Sprintf("Active Trials: %s%.0f\n", m.unit, m.value)) + // } + // result.WriteString("\n") + // + // if m, ok := metrics["new_customers"]; ok { + // result.WriteString(fmt.Sprintf("New Customers (28d): %s%.0f\n", m.unit, m.value)) + // } + // if m, ok := metrics["active_users"]; ok { + // result.WriteString(fmt.Sprintf("Active Users (28d): %s%.0f\n", m.unit, m.value)) + // } + // + // result.WriteString("\n═══════════════════════════════════════\n") + // + // return result.String() +} + var ( titleStyle = lipgloss.NewStyle(). Bold(true). @@ -105,12 +205,14 @@ type model struct { terminalWidth int terminalHeight int focusOnDetail bool // true = detail panel has focus, false = list has focus + revenue string } func initialModel(humans []*HumanData) model { return model{ - humans: humans, - cursor: 0, + humans: humans, + cursor: 0, + revenue: getRevenue(), } } @@ -281,7 +383,7 @@ func (m model) View() string { pastSevenDaysSignupsCount++ } } - header := titleStyle.Render(fmt.Sprintf("šŸ‘„ Humans | %d total | %d in the past 7 days", len(m.humans), pastSevenDaysSignupsCount)) + header := titleStyle.Render(fmt.Sprintf("šŸ‘„ Humans | %d total | %d in the past 7 days | Revenue: %s", len(m.humans), pastSevenDaysSignupsCount, m.revenue)) // Status bar showing current position statusBar := statusStyle.Render(fmt.Sprintf(" %d/%d", m.cursor+1, len(m.humans)))