feat: add stats page

This commit is contained in:
Krispire Admin
2026-05-31 14:54:15 +05:30
parent d3ad443fde
commit 72f4e6527c
14 changed files with 750 additions and 36 deletions
+27 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strconv"
"strings"
"time"
"github.com/joho/godotenv"
@@ -36,13 +37,19 @@ type Config struct {
R2Bucket string
R2PublicURL string // Public base URL for objects, e.g. https://cdn.example.com or the R2 public bucket URL
// SMTP — used for password-reset and email-verification mails.
// SMTP — used for password-reset, email-verification, and
// /feedback admin-notification mails.
SMTPHost string
SMTPPort int
SMTPUsername string
SMTPPassword string
SMTPFrom string // "Prabhupāda Says <noreply@prabhupadasays.org>"
// Comma-separated FEEDBACK_ADMIN_EMAILS — recipients for the
// /feedback notification fan-out. Empty disables the email send
// (the DB row is still written and visible via /stats).
FeedbackAdminEmails []string
// Push Notifications (existing — unchanged).
FCMCredentialsFile string
APNsKeyFile string
@@ -95,6 +102,8 @@ func Load() (*Config, error) {
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
SMTPFrom: getEnv("SMTP_FROM", "noreply@localhost"),
FeedbackAdminEmails: parseList(getEnv("FEEDBACK_ADMIN_EMAILS", "")),
FCMCredentialsFile: getEnv("FCM_CREDENTIALS_FILE", ""),
APNsKeyFile: getEnv("APNS_KEY_FILE", ""),
APNsKeyID: getEnv("APNS_KEY_ID", ""),
@@ -147,3 +156,20 @@ func getEnvBool(key string, fallback bool) bool {
}
return fallback
}
// parseList splits a comma-separated env value, trimming whitespace
// and discarding empty entries. Returns nil for empty input so
// callers can range over it safely without a length check.
func parseList(s string) []string {
if s == "" {
return nil
}
parts := strings.Split(s, ",")
out := make([]string, 0, len(parts))
for _, p := range parts {
if p = strings.TrimSpace(p); p != "" {
out = append(out, p)
}
}
return out
}