Files
Poll-system/Example_code/admin.go
2025-08-29 16:49:13 -06:00

403 lines
11 KiB
Go

// package handlers
// import (
// "database/sql"
// "errors"
// "log"
// "net/http"
// "strconv"
// "time"
// "github.com/patel-mann/poll-system/app/internal/models"
// "github.com/patel-mann/poll-system/app/internal/utils"
// )
// // View model for listing/assigning schedules
// type AssignmentVM struct {
// ID int
// VolunteerID int
// VolunteerName string
// AddressID int
// Address string
// Date string // YYYY-MM-DD (for input[type=date])
// AppointmentTime string // HH:MM
// VisitedValidated bool
// }
// // GET + POST in one handler:
// // - GET: show assignments + form to assign
// // - POST: create a new assignment
// func AdminAssignmentsHandler(w http.ResponseWriter, r *http.Request) {
// switch r.Method {
// case http.MethodPost:
// if err := createAssignmentFromForm(r); err != nil {
// log.Println("create assignment error:", err)
// volunteers, _ := fetchVolunteers()
// addresses, _ := fetchAddresses()
// assignments, _ := fetchAssignments()
// utils.Render(w, "schedual/assignments.html", map[string]interface{}{
// "Title": "Admin — Assign Addresses",
// "IsAuthenticated": true,
// "ActiveSection": "admin_assignments",
// "Volunteers": volunteers,
// "Addresses": addresses,
// "Assignments": assignments,
// "Error": err.Error(),
// })
// return
// }
// http.Redirect(w, r, "/admin/assignments", http.StatusSeeOther)
// return
// }
// // GET: fetch volunteers, addresses, and existing assignments
// volunteers, err := fetchVolunteers()
// if err != nil {
// log.Println("fetch volunteers error:", err)
// http.Error(w, "Failed to load volunteers", http.StatusInternalServerError)
// return
// }
// addresses, err := fetchAddresses()
// if err != nil {
// log.Println("fetch addresses error:", err)
// http.Error(w, "Failed to load addresses", http.StatusInternalServerError)
// return
// }
// assignments, err := fetchAssignments()
// if err != nil {
// log.Println("fetch assignments error:", err)
// http.Error(w, "Failed to load assignments", http.StatusInternalServerError)
// return
// }
// utils.Render(w, "assignments.html", map[string]interface{}{
// "Title": "Admin — Assign Addresses",
// "IsAuthenticated": true,
// "ActiveSection": "admin_assignments",
// "Volunteers": volunteers,
// "Addresses": addresses,
// "Assignments": assignments,
// })
// }
// // GET (edit form) + POST (update/delete)
// func AdminAssignmentEditHandler(w http.ResponseWriter, r *http.Request) {
// idStr := r.URL.Query().Get("id")
// id, _ := strconv.Atoi(idStr)
// if id <= 0 {
// http.NotFound(w, r)
// return
// }
// if r.Method == http.MethodPost {
// action := r.FormValue("action")
// switch action {
// case "delete":
// if err := deleteAssignment(id); err != nil {
// log.Println("delete assignment error:", err)
// http.Error(w, "Failed to delete assignment", http.StatusInternalServerError)
// return
// }
// http.Redirect(w, r, "/admin/assignments", http.StatusSeeOther)
// return
// case "update":
// if err := updateAssignmentFromForm(id, r); err != nil {
// log.Println("update assignment error:", err)
// vm, _ := fetchAssignmentByID(id)
// volunteers, _ := fetchVolunteers()
// addresses, _ := fetchAddresses()
// utils.Render(w, "assignment_edit.html", map[string]interface{}{
// "Title": "Edit Assignment",
// "Assignment": vm,
// "Volunteers": volunteers,
// "Addresses": addresses,
// "Error": err.Error(),
// })
// return
// }
// http.Redirect(w, r, "/admin/assignments", http.StatusSeeOther)
// return
// default:
// http.Error(w, "Unknown action", http.StatusBadRequest)
// return
// }
// }
// // GET edit
// vm, err := fetchAssignmentByID(id)
// if err != nil {
// if err == sql.ErrNoRows {
// http.NotFound(w, r)
// return
// }
// log.Println("fetch assignment by ID error:", err)
// http.Error(w, "Failed to load assignment", http.StatusInternalServerError)
// return
// }
// volunteers, err := fetchVolunteers()
// if err != nil {
// log.Println("fetch volunteers error:", err)
// http.Error(w, "Failed to load volunteers", http.StatusInternalServerError)
// return
// }
// addresses, err := fetchAddresses()
// if err != nil {
// log.Println("fetch addresses error:", err)
// http.Error(w, "Failed to load addresses", http.StatusInternalServerError)
// return
// }
// utils.Render(w, "assignment_edit.html", map[string]interface{}{
// "Title": "Edit Assignment",
// "Assignment": vm,
// "Volunteers": volunteers,
// "Addresses": addresses,
// })
// }
// // ----- Helpers -----
// func createAssignmentFromForm(r *http.Request) error {
// volID, _ := strconv.Atoi(r.FormValue("volunteer_id"))
// addrID, _ := strconv.Atoi(r.FormValue("address_id"))
// dateStr := r.FormValue("date")
// timeStr := r.FormValue("appointment_time")
// if volID <= 0 || addrID <= 0 || dateStr == "" || timeStr == "" {
// return errors.New("please fill all required fields")
// }
// if _, err := time.Parse("2006-01-02", dateStr); err != nil {
// return errors.New("invalid date format")
// }
// if _, err := time.Parse("15:04", timeStr); err != nil {
// return errors.New("invalid time format")
// }
// _, err := models.DB.Exec(`
// INSERT INTO schedual (user_id, address_id, appointment_date, appointment_time, created_at, updated_at)
// VALUES ($1,$2,$3,$4,NOW(),NOW())
// `, volID, addrID, dateStr, timeStr)
// if err != nil {
// log.Println("database insert error:", err)
// return errors.New("failed to create assignment")
// }
// return nil
// }
// func updateAssignmentFromForm(id int, r *http.Request) error {
// volID, _ := strconv.Atoi(r.FormValue("volunteer_id"))
// addrID, _ := strconv.Atoi(r.FormValue("address_id"))
// dateStr := r.FormValue("date")
// timeStr := r.FormValue("appointment_time")
// if volID <= 0 || addrID <= 0 || dateStr == "" || timeStr == "" {
// return errors.New("please fill all required fields")
// }
// if _, err := time.Parse("2006-01-02", dateStr); err != nil {
// return errors.New("invalid date format")
// }
// if _, err := time.Parse("15:04", timeStr); err != nil {
// return errors.New("invalid time format")
// }
// result, err := models.DB.Exec(`
// UPDATE schedual
// SET user_id=$1, address_id=$2, appointment_date=$3, appointment_time=$4, updated_at=NOW()
// WHERE schedual_id=$5
// `, volID, addrID, dateStr, timeStr, id)
// if err != nil {
// log.Println("database update error:", err)
// return errors.New("failed to update assignment")
// }
// rowsAffected, _ := result.RowsAffected()
// if rowsAffected == 0 {
// return errors.New("assignment not found")
// }
// return nil
// }
// func deleteAssignment(id int) error {
// result, err := models.DB.Exec(`DELETE FROM schedual WHERE schedual_id=$1`, id)
// if err != nil {
// log.Println("database delete error:", err)
// return errors.New("failed to delete assignment")
// }
// rowsAffected, _ := result.RowsAffected()
// if rowsAffected == 0 {
// return errors.New("assignment not found")
// }
// return nil
// }
// // Fetch volunteers
// type VolunteerPick struct {
// ID int
// FirstName string
// LastName string
// Email string
// }
// func fetchVolunteers() ([]VolunteerPick, error) {
// rows, err := models.DB.Query(`
// SELECT users_id, first_name, last_name, email
// FROM "user"
// WHERE role='volunteer'
// ORDER BY first_name, last_name
// `)
// if err != nil {
// return nil, err
// }
// defer rows.Close()
// var out []VolunteerPick
// for rows.Next() {
// var v VolunteerPick
// if err := rows.Scan(&v.ID, &v.FirstName, &v.LastName, &v.Email); err != nil {
// log.Println("fetchVolunteers scan:", err)
// continue
// }
// out = append(out, v)
// }
// return out, rows.Err()
// }
// // Fetch addresses
// type AddressPick struct {
// ID int
// Label string
// VisitedValidated bool
// }
// func fetchAddresses() ([]AddressPick, error) {
// rows, err := models.DB.Query(`
// SELECT
// address_id,
// address,
// street_name,
// street_type,
// street_quadrant,
// house_number,
// house_alpha,
// longitude,
// latitude,
// visited_validated
// FROM address_database
// ORDER BY address_id DESC
// `)
// if err != nil {
// return nil, err
// }
// defer rows.Close()
// var out []AddressPick
// for rows.Next() {
// var addr models.AddressDatabase
// if err := rows.Scan(
// &addr.AddressID,
// &addr.Address,
// &addr.StreetName,
// &addr.StreetType,
// &addr.StreetQuadrant,
// &addr.HouseNumber,
// &addr.HouseAlpha,
// &addr.Longitude,
// &addr.Latitude,
// &addr.VisitedValidated,
// ); err != nil {
// log.Println("fetchAddresses scan:", err)
// continue
// }
// label := addr.Address
// if label == "" {
// label = addr.HouseNumber
// if addr.StreetName != "" {
// if label != "" {
// label += " "
// }
// label += addr.StreetName
// }
// if addr.StreetType != "" {
// label += " " + addr.StreetType
// }
// if addr.StreetQuadrant != "" {
// label += " " + addr.StreetQuadrant
// }
// if addr.HouseAlpha != nil {
// label += " " + *addr.HouseAlpha
// }
// }
// out = append(out, AddressPick{
// ID: addr.AddressID,
// Label: label,
// VisitedValidated: addr.VisitedValidated,
// })
// }
// return out, rows.Err()
// }
// // Add this missing function
// func fetchAssignments() ([]AssignmentVM, error) {
// rows, err := models.DB.Query(`
// SELECT
// s.schedual_id,
// u.users_id,
// COALESCE(u.first_name,'') || ' ' || COALESCE(u.last_name,'') AS volunteer_name,
// a.address_id,
// COALESCE(a.address,'') AS address,
// s.appointment_date,
// s.appointment_time
// FROM schedual s
// JOIN "user" u ON u.users_id = s.user_id
// JOIN address_database a ON a.address_id = s.address_id
// ORDER BY s.appointment_date DESC, s.appointment_time DESC
// `)
// if err != nil {
// return nil, err
// }
// defer rows.Close()
// var assignments []AssignmentVM
// for rows.Next() {
// var vm AssignmentVM
// if err := rows.Scan(&vm.ID, &vm.VolunteerID, &vm.VolunteerName, &vm.AddressID, &vm.Address,
// &vm.Date, &vm.AppointmentTime); err != nil {
// log.Println("fetchAssignments scan:", err)
// continue
// }
// assignments = append(assignments, vm)
// }
// return assignments, rows.Err()
// }
// func fetchAssignmentByID(id int) (AssignmentVM, error) {
// var vm AssignmentVM
// err := models.DB.QueryRow(`
// SELECT
// s.schedual_id,
// u.users_id,
// COALESCE(u.first_name,'') || ' ' || COALESCE(u.last_name,'') AS volunteer_name,
// a.address_id,
// COALESCE(a.address,'') AS address,
// s.appointment_date,
// s.appointment_time
// FROM schedual s
// JOIN "user" u ON u.users_id = s.user_id
// JOIN address_database a ON a.address_id = s.address_id
// WHERE s.schedual_id = $1
// `, id).Scan(&vm.ID, &vm.VolunteerID, &vm.VolunteerName, &vm.AddressID, &vm.Address,
// &vm.Date, &vm.AppointmentTime)
// return vm, err
// }