mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
dev day #79
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"fotbal-club/internal/models"
|
||||
"fotbal-club/internal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -421,11 +422,30 @@ func (pc *PollController) Vote(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// If not authenticated, don't persist personal info even if provided
|
||||
if !hasUser {
|
||||
input.VoterName = ""
|
||||
input.VoterEmail = ""
|
||||
}
|
||||
// Normalize voter info. Allow guests to optionally provide name/email.
|
||||
// If authenticated and no voter_name/email provided, fallback to user's profile.
|
||||
var derivedName string
|
||||
var derivedEmail string
|
||||
if hasUser {
|
||||
if uID, ok := userID.(uint); ok {
|
||||
var u models.User
|
||||
if err := pc.DB.First(&u, uID).Error; err == nil {
|
||||
if u.FirstName != "" || u.LastName != "" {
|
||||
derivedName = fmt.Sprintf("%s %s", u.FirstName, u.LastName)
|
||||
}
|
||||
derivedEmail = u.Email
|
||||
}
|
||||
}
|
||||
}
|
||||
// Final values to persist
|
||||
voterName := input.VoterName
|
||||
voterEmail := input.VoterEmail
|
||||
if voterName == "" && derivedName != "" {
|
||||
voterName = derivedName
|
||||
}
|
||||
if voterEmail == "" && derivedEmail != "" {
|
||||
voterEmail = derivedEmail
|
||||
}
|
||||
|
||||
// Check if already voted
|
||||
ipHash := pc.hashIP(c.ClientIP())
|
||||
@@ -477,8 +497,8 @@ func (pc *PollController) Vote(c *gin.Context) {
|
||||
IPHash: ipHash,
|
||||
UserAgent: userAgent,
|
||||
SessionToken: sessionToken,
|
||||
VoterName: input.VoterName,
|
||||
VoterEmail: input.VoterEmail,
|
||||
VoterName: voterName,
|
||||
VoterEmail: voterEmail,
|
||||
}
|
||||
|
||||
if hasUser {
|
||||
@@ -513,7 +533,15 @@ func (pc *PollController) Vote(c *gin.Context) {
|
||||
pc.DB.Preload("Options", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("display_order ASC, id ASC")
|
||||
}).First(&poll, poll.ID)
|
||||
|
||||
|
||||
// Engagement: award points to authenticated user
|
||||
if hasUser {
|
||||
uid := userID.(uint)
|
||||
svc := services.NewEngagementService(pc.DB)
|
||||
_, _ = svc.AwardPointsCapped(uid, 3, "poll_vote", map[string]interface{}{"poll_id": poll.ID})
|
||||
_ = svc.CheckAndAwardAchievements(uid)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Vote recorded successfully",
|
||||
"poll": poll,
|
||||
@@ -637,3 +665,59 @@ func (pc *PollController) GetPollStats(c *gin.Context) {
|
||||
"guest_votes": guestVotes,
|
||||
})
|
||||
}
|
||||
|
||||
// AdminListVotes returns detailed list of votes for a poll (admin only)
|
||||
func (pc *PollController) AdminListVotes(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var votes []models.PollVote
|
||||
if err := pc.DB.Preload("Option").Preload("User").Where("poll_id = ?", id).Order("created_at DESC").Find(&votes).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch votes"})
|
||||
return
|
||||
}
|
||||
|
||||
type VoteDTO struct {
|
||||
ID uint `json:"id"`
|
||||
PollID uint `json:"poll_id"`
|
||||
OptionID uint `json:"option_id"`
|
||||
OptionText string `json:"option_text"`
|
||||
UserID *uint `json:"user_id"`
|
||||
UserEmail string `json:"user_email"`
|
||||
UserFirstName string `json:"user_first_name"`
|
||||
UserLastName string `json:"user_last_name"`
|
||||
VoterName string `json:"voter_name"`
|
||||
VoterEmail string `json:"voter_email"`
|
||||
SessionToken string `json:"session_token"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
result := make([]VoteDTO, 0, len(votes))
|
||||
for _, v := range votes {
|
||||
optionText := ""
|
||||
if v.Option != nil {
|
||||
optionText = v.Option.Text
|
||||
}
|
||||
var userEmail, firstName, lastName string
|
||||
if v.User != nil {
|
||||
userEmail = v.User.Email
|
||||
firstName = v.User.FirstName
|
||||
lastName = v.User.LastName
|
||||
}
|
||||
result = append(result, VoteDTO{
|
||||
ID: v.ID,
|
||||
PollID: v.PollID,
|
||||
OptionID: v.OptionID,
|
||||
OptionText: optionText,
|
||||
UserID: v.UserID,
|
||||
UserEmail: userEmail,
|
||||
UserFirstName: firstName,
|
||||
UserLastName: lastName,
|
||||
VoterName: v.VoterName,
|
||||
VoterEmail: v.VoterEmail,
|
||||
SessionToken: v.SessionToken,
|
||||
CreatedAt: v.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"votes": result})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user