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

220 lines
5.6 KiB
Go
Raw Normal View History

2025-08-26 14:13:09 -06:00
package handlers
import (
"fmt"
"log"
"net/http"
"strconv"
"github.com/patel-mann/poll-system/app/internal/models"
"github.com/patel-mann/poll-system/app/internal/utils"
)
func VolunteerHandler(w http.ResponseWriter, r *http.Request) {
// TODO: Replace this with actual session/jwt extraction
currentAdminID := r.Context().Value("user_id").(int)
rows, err := models.DB.Query(`
SELECT u.user_id, u.email, u.role_id, u.first_name, u.last_name, u.phone
FROM "users" u
JOIN admin_volunteers av ON u.user_id = av.volunteer_id
WHERE av.admin_id = $1 AND ( u.role_id = 3 OR u.role_id = 2 )
`, currentAdminID)
if err != nil {
http.Error(w, "Query error", http.StatusInternalServerError)
return
}
defer rows.Close()
var user []models.User
for rows.Next() {
var b models.User
err := rows.Scan(&b.UserID, &b.Email, &b.RoleID, &b.FirstName, &b.LastName, &b.Phone)
if err != nil {
log.Println("Scan error:", err)
continue
}
user = append(user, b)
}
utils.Render(w, "volunteer/volunteer.html", map[string]interface{}{
"Title": "Assigned Volunteers",
"IsAuthenticated": true,
"ShowAdminNav": true,
"Users": user,
"ActiveSection": "volunteer",
})
}
func EditVolunteerHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
volunteerID := r.URL.Query().Get("id")
var user models.User
err := models.DB.QueryRow(`
SELECT user_id, email, role_id, first_name, last_name, phone
FROM "users"
WHERE user_id = $1 AND (role_id = 3 OR role_id = 2)
`, volunteerID).Scan(&user.UserID, &user.Email, &user.RoleID, &user.FirstName, &user.LastName, &user.Phone)
if err != nil {
http.Error(w, "Volunteer not found", http.StatusNotFound)
return
}
utils.Render(w, "volunteer/edit_volunteer.html", map[string]interface{}{
"Title": "Edit Volunteer",
"IsAuthenticated": true,
"ShowAdminNav": true,
"Volunteer": user,
"ActiveSection": "volunteer",
})
return
}
if r.Method == http.MethodPost {
err := r.ParseForm()
if err != nil {
http.Error(w, "Invalid form", http.StatusBadRequest)
return
}
volunteerID := r.FormValue("user_id")
firstName := r.FormValue("first_name")
lastName := r.FormValue("last_name")
email := r.FormValue("email")
phone := r.FormValue("phone")
roleID := r.FormValue("role_id")
rid, err := strconv.Atoi(roleID)
if err != nil || (rid != 2 && rid != 3) {
http.Error(w, "Invalid role selection", http.StatusBadRequest)
return
}
_, err = models.DB.Exec(`
UPDATE "users"
SET first_name = $1, last_name = $2, email = $3, phone = $4, role_id = $5
WHERE user_id = $6
`, firstName, lastName, email, phone, rid, volunteerID)
if err != nil {
fmt.Print(err)
http.Error(w, "Update failed", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/volunteers", http.StatusSeeOther)
}
}
type User struct {
ID int
Name string
}
type TeamLead struct {
ID int
Name string
Volunteers []User
}
type TeamBuilderData struct {
TeamLeads []TeamLead
UnassignedVolunteers []User
}
func TeamBuilderHandler(w http.ResponseWriter, r *http.Request) {
// GET request: show team leads and unassigned volunteers
if r.Method == http.MethodGet {
var teamLeads []TeamLead
var unassignedVolunteers []User
// Get all team leads (role_id = 2)
tlRows, err := models.DB.Query(`SELECT user_id, first_name || ' ' || last_name AS name FROM users WHERE role_id = 2`)
if err != nil {
http.Error(w, "Error fetching team leads", http.StatusInternalServerError)
return
}
defer tlRows.Close()
for tlRows.Next() {
var tl TeamLead
tlRows.Scan(&tl.ID, &tl.Name)
// Get assigned volunteers for this team lead
vRows, _ := models.DB.Query(`SELECT u.user_id, u.first_name || ' ' || u.last_name AS name
FROM users u
JOIN team t ON u.user_id = t.volunteer_id
WHERE t.team_lead_id = $1`, tl.ID)
for vRows.Next() {
var vol User
vRows.Scan(&vol.ID, &vol.Name)
tl.Volunteers = append(tl.Volunteers, vol)
}
teamLeads = append(teamLeads, tl)
}
// Get unassigned volunteers (role_id = 3)
vRows, _ := models.DB.Query(`SELECT user_id, first_name || ' ' || last_name AS name
FROM users
WHERE role_id = 3
AND user_id NOT IN (SELECT volunteer_id FROM team)`)
for vRows.Next() {
var vol User
vRows.Scan(&vol.ID, &vol.Name)
unassignedVolunteers = append(unassignedVolunteers, vol)
}
utils.Render(w, "volunteer/team_builder.html", map[string]interface{}{
"Title": "Team Builder",
"IsAuthenticated": true,
"ShowAdminNav": true,
"TeamLeads": teamLeads,
"UnassignedVolunteers": unassignedVolunteers,
"ActiveSection": "team_builder",
})
return
}
// POST request: assign volunteer to a team lead
if r.Method == http.MethodPost {
if err := r.ParseForm(); err != nil {
http.Error(w, "Invalid form", http.StatusBadRequest)
return
}
volunteerID, err := strconv.Atoi(r.FormValue("volunteer_id"))
if err != nil {
http.Error(w, "Invalid volunteer ID", http.StatusBadRequest)
return
}
teamLeadID, err := strconv.Atoi(r.FormValue("team_lead_id"))
if err != nil {
http.Error(w, "Invalid team lead ID", http.StatusBadRequest)
return
}
_, err = models.DB.Exec(`INSERT INTO team (volunteer_id, team_lead_id) VALUES ($1, $2)`, volunteerID, teamLeadID)
if err != nil {
fmt.Println(err)
http.Error(w, "Failed to assign volunteer", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/team_builder", http.StatusSeeOther)
}
}
//assign volunterr the title of team_leader
//Team View
//edit volnteer data
//