dev day #100 - WE ARE FUCKING DONE, hotfixes incoming but we did it in 100 days, lets fucking go guys, anyone reading this...i love you

This commit is contained in:
Tomas Dvorak
2025-11-22 21:30:10 +01:00
parent f5b6f83974
commit aa036b6550
47 changed files with 3607 additions and 2177 deletions
+125 -14
View File
@@ -180,6 +180,28 @@ func (cc *ContactController) recalcNewsletterAutomationEnabled() {
s.NewsletterWeeklyHour = 9
changed = true
}
// Auto-activate match reminders with sane defaults if not configured
if !s.EnableMatchReminders {
s.EnableMatchReminders = true
changed = true
}
if s.NewsletterReminderLeadHours <= 0 {
s.NewsletterReminderLeadHours = 48 // 48h before kickoff
changed = true
}
// Auto-activate match results notifications and default quiet hours if missing
if !s.EnableResults {
s.EnableResults = true
changed = true
}
// Only set quiet hours if both are unset (0,0) to avoid overriding admin-configured values
if s.NewsletterQuietStart == 0 && s.NewsletterQuietEnd == 0 {
s.NewsletterQuietStart = 22 // 22:00
s.NewsletterQuietEnd = 8 // 08:00
changed = true
}
}
if s.ID == 0 {
_ = cc.DB.Create(&s).Error
@@ -511,12 +533,6 @@ func (cc *ContactController) SubscribeToNewsletter(c *gin.Context) {
}
}
}
// Additionally, send a minimal confirmation using newsletter template with manage link (best-effort)
_ = cc.emailService.SendNewsletter(&email.NewsletterData{
Subject: "Vítejte v odběru",
Content: fmt.Sprintf("<p>Děkujeme za přihlášení. Spravujte své preference <a href=\"%s\">zde</a>.</p>", manageURL),
Recipients: []string{emailStr},
})
// Recalculate automation after (re)subscription
cc.recalcNewsletterAutomationEnabled()
c.JSON(http.StatusOK, gin.H{"message": "Subscribed"})
@@ -700,21 +716,89 @@ func (cc *ContactController) SubmitContactForm(c *gin.Context) {
return
}
go func(nm, em, subj, msgBody, ipAddr, agent string) {
go func(m models.ContactMessage) {
// 1) Notify primary contact(s) (club contact email / env fallbacks)
_ = cc.emailService.SendContactForm(&email.ContactFormData{
Name: nm,
Email: em,
Subject: subj,
Message: msgBody,
IPAddress: ipAddr,
UserAgent: agent,
Name: m.Name,
Email: m.Email,
Subject: m.Subject,
Message: m.Message,
IPAddress: m.IPAddress,
UserAgent: m.UserAgent,
})
}(name, emailStr, subject, message, ip, ua)
// 2) Auto-forward to configured list when enabled
var set models.Settings
if err := cc.DB.First(&set).Error; err == nil && set.ContactForwardEnabled && strings.TrimSpace(set.ContactForwardList) != "" {
// Build recipient list from ContactForwardList (comma/semicolon/space separated)
parts := strings.FieldsFunc(set.ContactForwardList, func(r rune) bool { return r == ',' || r == ';' || r == ' ' || r == '\n' || r == '\t' })
uniq := make(map[string]struct{})
dest := make([]string, 0, len(parts))
// Exclude addresses that already received the primary notification (contact/admin emails)
exclude := map[string]struct{}{}
if v := strings.ToLower(strings.TrimSpace(set.ContactEmail)); v != "" {
exclude[v] = struct{}{}
}
if config.AppConfig != nil {
if v := strings.ToLower(strings.TrimSpace(config.AppConfig.ContactEmail)); v != "" {
exclude[v] = struct{}{}
}
if v := strings.ToLower(strings.TrimSpace(config.AppConfig.AdminEmail)); v != "" {
exclude[v] = struct{}{}
}
}
for _, p := range parts {
v := strings.TrimSpace(p)
if v == "" {
continue
}
lv := strings.ToLower(v)
if _, ok := uniq[lv]; ok {
continue
}
if _, skip := exclude[lv]; skip {
continue
}
uniq[lv] = struct{}{}
dest = append(dest, v)
}
if len(dest) > 0 {
fwd := &email.EmailData{
Subject: fmt.Sprintf("Přeposláno: Kontaktní formulář - %s", strings.TrimSpace(m.Subject)),
To: dest,
Template: "contact_form",
Data: struct {
Name string
Email string
Subject string
Message string
Time string
IP string
Agent string
}{
Name: m.Name,
Email: m.Email,
Subject: m.Subject,
Message: m.Message,
Time: m.CreatedAt.Format(time.RFC1123Z),
IP: m.IPAddress,
Agent: m.UserAgent,
},
}
if err := cc.emailService.SendEmail(fwd); err != nil {
logger.Error("Auto-forward of contact message %d failed: %v", m.ID, err)
} else {
logger.Info("Auto-forwarded contact message %d to %v", m.ID, dest)
}
}
}
}(msg)
c.JSON(http.StatusOK, gin.H{"message": "Message received", "id": msg.ID})
}
func (cc *ContactController) AdminSmtpTest(c *gin.Context) {
// ... rest of the code remains the same ...
if c.GetString("userRole") != "admin" {
c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
return
@@ -904,6 +988,33 @@ func (cc *ContactController) UpdateNewsletterAutomation(c *gin.Context) {
s = models.Settings{}
}
s.NewsletterEnabled = input.Enabled
// If enabling, ensure defaults for weekly/matches/results are set like auto-recalc does
if input.Enabled {
if !s.EnableWeekly {
s.EnableWeekly = true
}
if strings.TrimSpace(s.NewsletterWeeklyDay) == "" {
s.NewsletterWeeklyDay = "sun"
}
if s.NewsletterWeeklyHour < 0 || s.NewsletterWeeklyHour > 23 {
s.NewsletterWeeklyHour = 9
}
if !s.EnableMatchReminders {
s.EnableMatchReminders = true
}
if s.NewsletterReminderLeadHours <= 0 {
s.NewsletterReminderLeadHours = 48
}
if !s.EnableResults {
s.EnableResults = true
}
if s.NewsletterQuietStart == 0 && s.NewsletterQuietEnd == 0 {
s.NewsletterQuietStart = 22
s.NewsletterQuietEnd = 8
}
}
if s.ID == 0 {
if err := cc.DB.Create(&s).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to persist setting"})