updated layout and volunteer
change the ui and now able to remove assigned addresses from volunteer
This commit is contained in:
@@ -34,6 +34,7 @@ type PageNumber struct {
|
||||
// AddressWithDetails extends AddressDatabase with appointment and user info
|
||||
type AddressWithDetails struct {
|
||||
models.AddressDatabase
|
||||
UserID *int
|
||||
UserName string
|
||||
UserEmail string
|
||||
AppointmentDate string
|
||||
@@ -97,6 +98,7 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
WHEN ap.sched_id IS NOT NULL THEN true
|
||||
ELSE false
|
||||
END as assigned,
|
||||
ap.user_id,
|
||||
COALESCE(u.first_name || ' ' || u.last_name, '') as user_name,
|
||||
COALESCE(u.email, '') as user_email,
|
||||
COALESCE(ap.appointment_date::text, '') as appointment_date,
|
||||
@@ -133,6 +135,7 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
&a.CreatedAt,
|
||||
&a.UpdatedAt,
|
||||
&a.Assigned,
|
||||
&a.UserID,
|
||||
&a.UserName,
|
||||
&a.UserEmail,
|
||||
&a.AppointmentDate,
|
||||
@@ -324,4 +327,66 @@ func AssignAddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Redirect back to addresses page with success
|
||||
http.Redirect(w, r, "/addresses?success=assigned", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func RemoveAssignedAddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Redirect(w, r, "/addresses", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, "Invalid form", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
userIDStr := r.FormValue("user_id")
|
||||
addressIDStr := r.FormValue("address_id")
|
||||
|
||||
if userIDStr == "" || addressIDStr == "" {
|
||||
http.Error(w, "User ID and Address ID are required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := strconv.Atoi(userIDStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid user ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
addressID, err := strconv.Atoi(addressIDStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid address ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify the user is managed by current admin
|
||||
currentAdminID := r.Context().Value("user_id").(int)
|
||||
var userExists int
|
||||
err = models.DB.QueryRow(`
|
||||
SELECT COUNT(*)
|
||||
FROM admin_volunteers av
|
||||
JOIN appointment ap ON av.volunteer_id = ap.user_id
|
||||
WHERE av.admin_id = $1 AND ap.user_id = $2 AND ap.address_id = $3
|
||||
`, currentAdminID, userID, addressID).Scan(&userExists)
|
||||
if err != nil {
|
||||
log.Println("Verification error:", err)
|
||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if userExists == 0 {
|
||||
http.Error(w, "Unauthorized removal", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove volunteer assignment
|
||||
_, err = models.DB.Exec(`DELETE FROM appointment WHERE user_id = $1 AND address_id = $2`, userID, addressID)
|
||||
if err != nil {
|
||||
log.Println("Remove assignment error:", err)
|
||||
http.Error(w, "Failed to remove assignment", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/addresses?success=removed", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/patel-mann/poll-system/app/internal/models"
|
||||
"github.com/patel-mann/poll-system/app/internal/utils"
|
||||
)
|
||||
|
||||
type AssignedAddress struct {
|
||||
AddressID int
|
||||
Address string
|
||||
StreetName string
|
||||
StreetType string
|
||||
StreetQuadrant string
|
||||
HouseNumber string
|
||||
HouseAlpha *string
|
||||
Longitude float64
|
||||
Latitude float64
|
||||
VisitedValidated bool
|
||||
CreatedAt string
|
||||
UpdatedAt string
|
||||
Assigned bool
|
||||
UserName string
|
||||
UserEmail string
|
||||
UserPhone string
|
||||
AppointmentDate *string
|
||||
AppointmentTime *string
|
||||
}
|
||||
|
||||
func AssignedAddressesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
username,_ := models.GetCurrentUserName(r)
|
||||
|
||||
rows, err := models.DB.Query(`
|
||||
SELECT
|
||||
a.address_id, a.address, a.street_name, a.street_type, a.street_quadrant,
|
||||
a.house_number, a.house_alpha, a.longitude, a.latitude, a.visited_validated,
|
||||
a.created_at, a.updated_at,
|
||||
CASE WHEN ap.user_id IS NOT NULL THEN true ELSE false END as assigned,
|
||||
COALESCE(u.first_name || ' ' || u.last_name, '') as user_name,
|
||||
COALESCE(u.email, '') as user_email,
|
||||
COALESCE(u.phone, '') as user_phone,
|
||||
TO_CHAR(ap.appointment_date, 'YYYY-MM-DD') as appointment_date,
|
||||
TO_CHAR(ap.appointment_time, 'HH24:MI') as appointment_time
|
||||
FROM address_database a
|
||||
LEFT JOIN appointment ap ON a.address_id = ap.address_id
|
||||
LEFT JOIN users u ON ap.user_id = u.user_id
|
||||
ORDER BY a.address_id;
|
||||
`)
|
||||
if err != nil {
|
||||
log.Printf("query error: %v", err)
|
||||
http.Error(w, "query error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var assignedAddresses []AssignedAddress
|
||||
for rows.Next() {
|
||||
var addr AssignedAddress
|
||||
err := rows.Scan(
|
||||
&addr.AddressID, &addr.Address, &addr.StreetName, &addr.StreetType, &addr.StreetQuadrant,
|
||||
&addr.HouseNumber, &addr.HouseAlpha, &addr.Longitude, &addr.Latitude, &addr.VisitedValidated,
|
||||
&addr.CreatedAt, &addr.UpdatedAt, &addr.Assigned, &addr.UserName, &addr.UserEmail,
|
||||
&addr.UserPhone, &addr.AppointmentDate, &addr.AppointmentTime,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("scan error: %v", err)
|
||||
continue
|
||||
}
|
||||
assignedAddresses = append(assignedAddresses, addr)
|
||||
}
|
||||
|
||||
utils.Render(w, "address_assigned.html", map[string]interface{}{
|
||||
"Title": "Assigned Addresses",
|
||||
"IsAuthenticated": true,
|
||||
"AssignedList": assignedAddresses,
|
||||
"ShowAdminNav": true,
|
||||
"Role": "admin",
|
||||
"UserName": username,
|
||||
"ActiveSection": "assigned",
|
||||
})
|
||||
}
|
||||
@@ -51,6 +51,8 @@ func VolunteerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func EditVolunteerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
username,_ := models.GetCurrentUserName(r)
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
volunteerID := r.URL.Query().Get("id")
|
||||
var user models.User
|
||||
@@ -69,6 +71,7 @@ func EditVolunteerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
"Title": "Edit Volunteer",
|
||||
"IsAuthenticated": true,
|
||||
"ShowAdminNav": true,
|
||||
"UserName": username,
|
||||
"Volunteer": user,
|
||||
"ActiveSection": "volunteer",
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user