package models import ( "time" "gorm.io/datatypes" "gorm.io/gorm" ) // ContactMessage represents a message sent through the contact form type ContactMessage struct { BaseModel Name string `json:"name" gorm:"not null"` Email string `json:"email" gorm:"not null"` Subject string `json:"subject" gorm:"not null"` Message string `json:"message" gorm:"type:text;not null"` Source string `json:"source" gorm:"size:50;default:contact"` // e.g., "contact", "sponsor" IPAddress string `json:"ip_address" gorm:"size:45"` UserAgent string `json:"user_agent" gorm:"type:text"` IsRead bool `json:"is_read" gorm:"default:false"` ReadAt time.Time `json:"read_at,omitempty"` } // TableName specifies the table name for the ContactMessage model func (ContactMessage) TableName() string { return "contact_messages" } // NewsletterSubscription represents a user subscription to the newsletter type NewsletterSubscription struct { BaseModel Email string `json:"email" gorm:"uniqueIndex;not null"` IsActive bool `json:"is_active" gorm:"default:true"` // Preferences stores subscriber choices (e.g. matches, scores, events, blog) as JSON // Use datatypes.JSONMap so GORM/driver can marshal/unmarshal JSONB correctly Preferences datatypes.JSONMap `json:"preferences" gorm:"type:jsonb;default:'{}'::jsonb"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // TableName specifies the table name for the NewsletterSubscription model func (NewsletterSubscription) TableName() string { return "newsletter_subscriptions" } // CreateContactMessage creates a new contact message in the database func CreateContactMessage(db *gorm.DB, message *ContactMessage) error { return db.Create(message).Error } // GetContactMessages retrieves a paginated list of contact messages func GetContactMessages(db *gorm.DB, page, limit int) ([]ContactMessage, int64, error) { var messages []ContactMessage var count int64 offset := (page - 1) * limit // Get total count if err := db.Model(&ContactMessage{}).Count(&count).Error; err != nil { return nil, 0, err } // Get paginated results err := db.Offset(offset). Limit(limit). Order("created_at DESC"). Find(&messages).Error return messages, count, err } // MarkMessageAsRead marks a contact message as read func MarkMessageAsRead(db *gorm.DB, id uint) error { return db.Model(&ContactMessage{}). Where("id = ?", id). Updates(map[string]interface{}{ "is_read": true, "read_at": time.Now(), }).Error } // SubscribeToNewsletter subscribes an email to the newsletter func SubscribeToNewsletter(db *gorm.DB, email string) error { subscription := NewsletterSubscription{ Email: email, IsActive: true, CreatedAt: time.Now(), UpdatedAt: time.Now(), } return db.Where(NewsletterSubscription{Email: email}). Attrs(subscription). FirstOrCreate(&subscription). Update("is_active", true). Error } // UnsubscribeFromNewsletter unsubscribes an email from the newsletter func UnsubscribeFromNewsletter(db *gorm.DB, email string) error { return db.Model(&NewsletterSubscription{}). Where("email = ?", email). Update("is_active", false). Error } // GetActiveSubscribers returns a list of all active newsletter subscribers func GetActiveSubscribers(db *gorm.DB) ([]string, error) { var subscribers []string err := db.Model(&NewsletterSubscription{}). Where("is_active = ?", true). Pluck("email", &subscribers). Error return subscribers, err }