Files
Poll-system/app/internal/handlers/volunteer_posts.go

176 lines
4.7 KiB
Go
Raw Normal View History

2025-08-26 14:13:09 -06:00
// Add this to your handlers package (create volunteer_posts.go or add to existing file)
package handlers
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/patel-mann/poll-system/app/internal/models"
"github.com/patel-mann/poll-system/app/internal/utils"
)
2025-08-28 17:09:23 -06:00
type VolunteerStatistics struct {
AppointmentsToday int
AppointmentsThisWeek int
TotalAppointments int
PollsCompleted int
PollsRemaining int
LawnSignsRequested int
BannerSignsRequested int
PollCompletionPercent int
}
// VolunteerPostsHandler - Dashboard view for volunteers with posts and statistics
2025-08-26 14:13:09 -06:00
func VolunteerPostsHandler(w http.ResponseWriter, r *http.Request) {
// Only allow GET requests for volunteers
if r.Method != http.MethodGet {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Get user info from context
role := r.Context().Value("user_role").(int)
2025-08-27 13:21:11 -06:00
CurrentUserID := models.GetCurrentUserID(w, r)
2025-08-28 17:09:23 -06:00
username, _ := models.GetCurrentUserName(r)
2025-08-26 14:13:09 -06:00
// Fetch posts from database
rows, err := models.DB.Query(`
SELECT p.post_id, p.author_id, u.first_name || ' ' || u.last_name AS author_name,
p.content, COALESCE(p.image_url, '') as image_url, p.created_at
FROM post p
JOIN users u ON p.author_id = u.user_id
2025-08-27 13:21:11 -06:00
JOIN admin_volunteers x ON u.user_id = x.admin_id
WHERE x.volunteer_id = $1
2025-08-26 14:13:09 -06:00
ORDER BY p.created_at DESC
2025-08-28 17:09:23 -06:00
`, CurrentUserID)
2025-08-26 14:13:09 -06:00
if err != nil {
fmt.Printf("Database query error: %v\n", err)
http.Error(w, "Failed to fetch posts", http.StatusInternalServerError)
return
}
defer rows.Close()
var posts []models.Post
for rows.Next() {
var p models.Post
err := rows.Scan(&p.PostID, &p.AuthorID, &p.AuthorName, &p.Content, &p.ImageURL, &p.CreatedAt)
if err != nil {
fmt.Printf("Row scan error: %v\n", err)
continue
}
posts = append(posts, p)
}
// Add cache busting parameter to image URLs
for i := range posts {
if posts[i].ImageURL != "" {
posts[i].ImageURL += "?t=" + strconv.FormatInt(time.Now().UnixNano(), 10)
}
}
2025-08-28 17:09:23 -06:00
// Get volunteer statistics
stats, err := getVolunteerStatistics(CurrentUserID)
if err != nil {
fmt.Printf("Failed to fetch statistics: %v\n", err)
// Continue with empty stats rather than failing
stats = &VolunteerStatistics{}
}
2025-08-26 14:13:09 -06:00
// Get navigation flags
showAdminNav, showVolunteerNav := getNavFlags(role)
fmt.Printf("Volunteer viewing %d posts\n", len(posts))
2025-08-28 17:09:23 -06:00
2025-08-26 14:13:09 -06:00
utils.Render(w, "dashboard/volunteer_dashboard.html", map[string]interface{}{
2025-08-28 17:09:23 -06:00
"Title": "Volunteer Dashboard",
2025-08-26 14:13:09 -06:00
"IsAuthenticated": true,
"ShowAdminNav": showAdminNav,
"ShowVolunteerNav": showVolunteerNav,
2025-08-28 17:09:23 -06:00
"UserName": username,
2025-08-26 14:13:09 -06:00
"Posts": posts,
2025-08-28 17:09:23 -06:00
"Statistics": stats,
"ActiveSection": "dashboard",
"IsVolunteer": true,
2025-08-26 14:13:09 -06:00
})
}
2025-08-28 17:09:23 -06:00
func getVolunteerStatistics(userID int) (*VolunteerStatistics, error) {
stats := &VolunteerStatistics{}
today := time.Now().Format("2006-01-02")
// Get start of current week (Monday)
now := time.Now()
weekday := now.Weekday()
if weekday == time.Sunday {
weekday = 7
}
weekStart := now.AddDate(0, 0, -int(weekday)+1).Format("2006-01-02")
// Appointments today
err := models.DB.QueryRow(`
SELECT COUNT(*)
FROM appointment
WHERE user_id = $1 AND DATE(appointment_date) = $2
`, userID, today).Scan(&stats.AppointmentsToday)
if err != nil {
return nil, err
}
// Appointments this week
err = models.DB.QueryRow(`
SELECT COUNT(*)
FROM appointment
WHERE user_id = $1 AND DATE(appointment_date) >= $2 AND DATE(appointment_date) <= $3
`, userID, weekStart, today).Scan(&stats.AppointmentsThisWeek)
if err != nil {
return nil, err
}
// Total appointments
err = models.DB.QueryRow(`
SELECT COUNT(*)
FROM appointment
WHERE user_id = $1
`, userID).Scan(&stats.TotalAppointments)
if err != nil {
return nil, err
}
// Polls completed
err = models.DB.QueryRow(`
SELECT COUNT(DISTINCT pr.poll_response_id)
FROM poll p
JOIN poll_response pr ON p.poll_id = pr.poll_id
WHERE p.user_id = $1
`, userID).Scan(&stats.PollsCompleted)
if err != nil {
return nil, err
}
// Polls remaining (appointments without poll responses)
stats.PollsRemaining = stats.TotalAppointments - stats.PollsCompleted
// Calculate completion percentage
if stats.TotalAppointments > 0 {
stats.PollCompletionPercent = (stats.PollsCompleted * 100) / stats.TotalAppointments
} else {
stats.PollCompletionPercent = 0
}
// Signs requested
err = models.DB.QueryRow(`
SELECT
COALESCE(SUM(pr.question3_lawn_signs), 0),
COALESCE(SUM(pr.question4_banner_signs), 0)
FROM poll p
JOIN poll_response pr ON p.poll_id = pr.poll_id
WHERE p.user_id = $1
`, userID).Scan(&stats.LawnSignsRequested, &stats.BannerSignsRequested)
if err != nil {
return nil, err
}
return stats, nil
}