package handlers import ( "database/sql" "log" "net/http" "time" "github.com/patel-mann/poll-system/app/internal/models" "github.com/patel-mann/poll-system/app/internal/utils" ) ///////////////////// // Core Validation // ///////////////////// // ValidateAvailability checks if a user is available at a specific time func ValidateAvailability(checkDate time.Time, checkTime time.Time, userID int) bool { var startTime, endTime time.Time day := checkDate.Format("2006-01-02") err := models.DB.QueryRow(` SELECT start_time, end_time FROM availability WHERE user_id = $1 AND day_of_week = $2`, userID, day).Scan(&startTime, &endTime) if err != nil { if err != sql.ErrNoRows { log.Printf("DB error in ValidateAvailability: %v", err) } return false } return checkTime.After(startTime) && checkTime.Before(endTime) } //////////////////// // Volunteer CRUD // //////////////////// // View volunteer availability func VolunteerGetAvailabilityHandler(w http.ResponseWriter, r *http.Request) { userID := models.GetCurrentUserID(w, r) username, _ := models.GetCurrentUserName(r) role, _ := r.Context().Value("user_role").(int) rows, err := models.DB.Query(` SELECT availability_id, day_of_week, start_time, end_time, created_at FROM availability WHERE user_id = $1 ORDER BY day_of_week DESC`, userID) if err != nil { log.Println("Error fetching availability:", err) http.Error(w, "Database error", http.StatusInternalServerError) return } defer rows.Close() var availability []models.Availability for rows.Next() { var a models.Availability if err := rows.Scan(&a.AvailabilityID, &a.DayOfWeek, &a.StartTime, &a.EndTime, &a.CreatedAt); err != nil { log.Println("Row scan error:", err) continue } availability = append(availability, a) } utils.Render(w, "volunteer_schedule.html", map[string]interface{}{ "Title": "My Schedule", "ShowVolunteerNav": true, "IsVolunteer": true, "IsAuthenticated": true, "Availability": availability, "UserName": username, "Role": role, "ActiveSection": "schedule", }) } // Add or update schedule func VolunteerPostScheduleHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Redirect(w, r, "/volunteer/schedule", http.StatusSeeOther) return } userID := models.GetCurrentUserID(w, r) day := r.FormValue("day") start := r.FormValue("start_time") end := r.FormValue("end_time") if day == "" || start == "" || end == "" { http.Error(w, "All fields required", http.StatusBadRequest) return } _, err := models.DB.Exec(` INSERT INTO availability (user_id, day_of_week, start_time, end_time, created_at) VALUES ($1, $2, $3, $4, NOW()) ON CONFLICT (user_id, day_of_week) DO UPDATE SET start_time = $3, end_time = $4`, userID, day, start, end) if err != nil { log.Println("Insert availability error:", err) http.Error(w, "Could not save schedule", http.StatusInternalServerError) return } http.Redirect(w, r, "/volunteer/schedule", http.StatusSeeOther) } // Delete schedule func VolunteerDeleteScheduleHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } userID := models.GetCurrentUserID(w, r) idStr := r.FormValue("id") _, err := models.DB.Exec(`DELETE FROM availability WHERE availability_id = $1 AND user_id = $2`, idStr, userID) if err != nil { log.Println("Delete availability error:", err) http.Error(w, "Could not delete schedule", http.StatusInternalServerError) return } http.Redirect(w, r, "/volunteer/schedule", http.StatusSeeOther) }