admin core func done
This commit is contained in:
@@ -31,33 +31,37 @@ type PageNumber struct {
|
||||
IsCurrent bool
|
||||
}
|
||||
|
||||
// AddressWithDetails extends AddressDatabase with appointment and user info
|
||||
type AddressWithDetails struct {
|
||||
models.AddressDatabase
|
||||
UserName string
|
||||
UserEmail string
|
||||
AppointmentDate string
|
||||
AppointmentTime string
|
||||
}
|
||||
|
||||
func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Get pagination parameters from query string
|
||||
pageStr := r.URL.Query().Get("page")
|
||||
pageSizeStr := r.URL.Query().Get("pageSize")
|
||||
username,_ := models.GetCurrentUserName(r)
|
||||
|
||||
|
||||
// Default values
|
||||
page := 1
|
||||
pageSize := 20 // Default page size
|
||||
|
||||
// Parse page number
|
||||
pageSize := 20
|
||||
if pageStr != "" {
|
||||
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
|
||||
page = p
|
||||
}
|
||||
}
|
||||
|
||||
// Parse page size
|
||||
if pageSizeStr != "" {
|
||||
if ps, err := strconv.Atoi(pageSizeStr); err == nil && ps > 0 && ps <= 100 {
|
||||
pageSize = ps
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate offset
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
// Get total count first
|
||||
// Get total count
|
||||
var totalRecords int
|
||||
err := models.DB.QueryRow(`SELECT COUNT(*) FROM "address_database"`).Scan(&totalRecords)
|
||||
if err != nil {
|
||||
@@ -65,27 +69,43 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate pagination info
|
||||
totalPages := (totalRecords + pageSize - 1) / pageSize
|
||||
if totalPages == 0 {
|
||||
totalPages = 1
|
||||
}
|
||||
|
||||
// Ensure current page is within bounds
|
||||
if page > totalPages {
|
||||
page = totalPages
|
||||
offset = (page - 1) * pageSize
|
||||
}
|
||||
|
||||
// Get paginated results
|
||||
// Query addresses with appointment + user info
|
||||
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"
|
||||
WHERE street_quadrant = 'ne'
|
||||
ORDER BY address_id
|
||||
SELECT
|
||||
a.address_id,
|
||||
a.address,
|
||||
a.street_name,
|
||||
a.street_type,
|
||||
a.street_quadrant,
|
||||
a.house_number,
|
||||
COALESCE(a.house_alpha, '') as house_alpha,
|
||||
a.longitude,
|
||||
a.latitude,
|
||||
a.visited_validated,
|
||||
a.created_at,
|
||||
a.updated_at,
|
||||
CASE
|
||||
WHEN ap.sched_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(ap.appointment_date::text, '') as appointment_date,
|
||||
COALESCE(ap.appointment_time::text, '') 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
|
||||
WHERE a.street_quadrant = 'ne'
|
||||
ORDER BY a.address_id
|
||||
LIMIT $1 OFFSET $2
|
||||
`, pageSize, offset)
|
||||
if err != nil {
|
||||
@@ -95,9 +115,10 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var addresses []models.AddressDatabase
|
||||
var addresses []AddressWithDetails
|
||||
for rows.Next() {
|
||||
var a models.AddressDatabase
|
||||
var a AddressWithDetails
|
||||
var houseAlpha string
|
||||
err := rows.Scan(
|
||||
&a.AddressID,
|
||||
&a.Address,
|
||||
@@ -105,28 +126,68 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
&a.StreetType,
|
||||
&a.StreetQuadrant,
|
||||
&a.HouseNumber,
|
||||
&a.HouseAlpha,
|
||||
&houseAlpha,
|
||||
&a.Longitude,
|
||||
&a.Latitude,
|
||||
&a.VisitedValidated,
|
||||
&a.CreatedAt,
|
||||
&a.UpdatedAt,
|
||||
&a.Assigned,
|
||||
&a.UserName,
|
||||
&a.UserEmail,
|
||||
&a.AppointmentDate,
|
||||
&a.AppointmentTime,
|
||||
)
|
||||
if err != nil {
|
||||
log.Println("Scan error:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle nullable house_alpha
|
||||
if houseAlpha != "" {
|
||||
a.HouseAlpha = &houseAlpha
|
||||
}
|
||||
|
||||
addresses = append(addresses, a)
|
||||
}
|
||||
|
||||
// Calculate start and end record numbers for display
|
||||
// Get users associated with this admin
|
||||
currentAdminID := r.Context().Value("user_id").(int)
|
||||
userRows, err := models.DB.Query(`
|
||||
SELECT u.user_id, u.first_name || ' ' || u.last_name AS name
|
||||
FROM users u
|
||||
JOIN admin_volunteers av ON u.user_id = av.volunteer_id
|
||||
WHERE av.admin_id = $1 AND av.is_active = true
|
||||
`, currentAdminID)
|
||||
if err != nil {
|
||||
log.Println("Failed to fetch users:", err)
|
||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer userRows.Close()
|
||||
|
||||
type UserOption struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
var users []UserOption
|
||||
for userRows.Next() {
|
||||
var u UserOption
|
||||
if err := userRows.Scan(&u.ID, &u.Name); err != nil {
|
||||
log.Println("User scan error:", err)
|
||||
continue
|
||||
}
|
||||
users = append(users, u)
|
||||
}
|
||||
|
||||
// Pagination info
|
||||
startRecord := offset + 1
|
||||
endRecord := offset + len(addresses)
|
||||
if totalRecords == 0 {
|
||||
startRecord = 0
|
||||
}
|
||||
|
||||
// Generate page numbers for pagination controls
|
||||
pageNumbers := generatePageNumbers(page, totalPages)
|
||||
|
||||
pagination := PaginationInfo{
|
||||
CurrentPage: page,
|
||||
TotalPages: totalPages,
|
||||
@@ -147,9 +208,11 @@ func AddressHandler(w http.ResponseWriter, r *http.Request) {
|
||||
"Title": "Addresses",
|
||||
"IsAuthenticated": true,
|
||||
"ShowAdminNav": true,
|
||||
"ActiveSection": "address", // Add this line
|
||||
"ActiveSection": "address",
|
||||
"Addresses": addresses,
|
||||
"Role": "admin",
|
||||
"Users": users,
|
||||
"UserName": username,
|
||||
"Role": "admin",
|
||||
"Pagination": pagination,
|
||||
})
|
||||
}
|
||||
@@ -182,3 +245,83 @@ func generatePageNumbers(currentPage, totalPages int) []PageNumber {
|
||||
|
||||
return pageNumbers
|
||||
}
|
||||
|
||||
func AssignAddressHandler(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 exists and is associated with the current admin
|
||||
currentAdminID := r.Context().Value("user_id").(int)
|
||||
var userExists int
|
||||
err = models.DB.QueryRow(`
|
||||
SELECT COUNT(*) FROM admin_volunteers av
|
||||
JOIN users u ON av.volunteer_id = u.user_id
|
||||
WHERE av.admin_id = $1 AND u.user_id = $2 AND av.is_active = true
|
||||
`, currentAdminID, userID).Scan(&userExists)
|
||||
if err != nil {
|
||||
log.Println("User verification error:", err)
|
||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if userExists == 0 {
|
||||
http.Error(w, "Invalid user selection", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if this address is already assigned to any user
|
||||
var exists int
|
||||
err = models.DB.QueryRow(`
|
||||
SELECT COUNT(*) FROM appointment
|
||||
WHERE address_id = $1
|
||||
`, addressID).Scan(&exists)
|
||||
if err != nil {
|
||||
log.Println("Assignment check error:", err)
|
||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if exists > 0 {
|
||||
http.Error(w, "This address is already assigned to another user", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Assign the address - create appointment
|
||||
_, err = models.DB.Exec(`
|
||||
INSERT INTO appointment (user_id, address_id, appointment_date, appointment_time, created_at, updated_at)
|
||||
VALUES ($1, $2, CURRENT_DATE, CURRENT_TIME, NOW(), NOW())
|
||||
`, userID, addressID)
|
||||
if err != nil {
|
||||
log.Println("Assignment error:", err)
|
||||
http.Error(w, "Failed to assign address", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Redirect back to addresses page with success
|
||||
http.Redirect(w, r, "/addresses?success=assigned", http.StatusSeeOther)
|
||||
}
|
||||
Reference in New Issue
Block a user