package models import ( "sort" "strings" "time" "code.nonshy.com/nonshy/website/pkg/log" ) // Feedback table for Contact Us & Reporting to admins. type Feedback struct { ID uint64 `gorm:"primaryKey"` UserID uint64 `gorm:"index"` // if logged-in user posted this Acknowledged bool `gorm:"index"` // admin dashboard "read" status Intent string Subject string Message string TableName string TableID uint64 ReplyTo string // logged-out user may leave their email for reply CreatedAt time.Time UpdatedAt time.Time } // GetFeedback by ID. func GetFeedback(id uint64) (*Feedback, error) { m := &Feedback{} result := DB.First(&m, id) return m, result.Error } // CountUnreadFeedback gets the count of unacknowledged feedback for admins. func CountUnreadFeedback() int64 { query := DB.Where( "acknowledged = ?", false, ) var count int64 result := query.Model(&Feedback{}).Count(&count) if result.Error != nil { log.Error("models.CountUnreadFeedback: %s", result.Error) } return count } // PaginateFeedback func PaginateFeedback(acknowledged bool, intent, subject string, search *Search, pager *Pagination) ([]*Feedback, error) { var ( fb = []*Feedback{} wheres = []string{} placeholders = []interface{}{} ) wheres = append(wheres, "acknowledged = ?") placeholders = append(placeholders, acknowledged) if intent != "" { wheres = append(wheres, "intent = ?") placeholders = append(placeholders, intent) } if subject != "" { wheres = append(wheres, "subject = ?") placeholders = append(placeholders, subject) } // Search terms. for _, term := range search.Includes { var ilike = "%" + strings.ToLower(term) + "%" wheres = append(wheres, "message ILIKE ?") placeholders = append(placeholders, ilike) } for _, term := range search.Excludes { var ilike = "%" + strings.ToLower(term) + "%" wheres = append(wheres, "message NOT ILIKE ?") placeholders = append(placeholders, ilike) } query := DB.Where( strings.Join(wheres, " AND "), placeholders..., ).Order( pager.Sort, ) query.Model(&Feedback{}).Count(&pager.Total) result := query.Offset( pager.GetOffset(), ).Limit(pager.PerPage).Find(&fb) return fb, result.Error } // PaginateFeedbackAboutUser digs through feedback about a specific user ID or one of their Photos. // // It returns reports where table_name=users and their user ID, or where table_name=photos and about any // of their current photo IDs. Additionally, it will look for chat room reports which were about their // username. func PaginateFeedbackAboutUser(user *User, pager *Pagination) ([]*Feedback, error) { var ( fb = []*Feedback{} photoIDs, _ = user.AllPhotoIDs() wheres = []string{} placeholders = []interface{}{} ) wheres = append(wheres, ` (table_name = 'users' AND table_id = ?) OR (table_name = 'photos' AND table_id IN ?) OR message LIKE ? `) placeholders = append(placeholders, user.ID, photoIDs, user.Username) query := DB.Where( strings.Join(wheres, " AND "), placeholders..., ).Order( pager.Sort, ) query.Model(&Feedback{}).Count(&pager.Total) result := query.Offset( pager.GetOffset(), ).Limit(pager.PerPage).Find(&fb) return fb, result.Error } // DistinctFeedbackSubjects returns the distinct subjects on feedback & reports. func DistinctFeedbackSubjects() []string { var results = []string{} query := DB.Model(&Feedback{}). Select("DISTINCT feedbacks.subject"). Group("feedbacks.subject"). Find(&results) if query.Error != nil { log.Error("DistinctFeedbackSubjects: %s", query.Error) return nil } sort.Strings(results) return results } // CreateFeedback saves a new Feedback row to the DB. func CreateFeedback(fb *Feedback) error { result := DB.Create(fb) return result.Error } // Save Feedback. func (fb *Feedback) Save() error { result := DB.Save(fb) return result.Error }