package handlers import ( "database/sql" "encoding/json" "fmt" "net/http" "strconv" "code.springupsoftware.com/cmc/cmc-sales/internal/cmc/db" "github.com/gorilla/mux" ) type AddressHandler struct { queries *db.Queries } func NewAddressHandler(queries *db.Queries) *AddressHandler { return &AddressHandler{queries: queries} } func (h *AddressHandler) List(w http.ResponseWriter, r *http.Request) { limit := 50 offset := 0 if l := r.URL.Query().Get("limit"); l != "" { if val, err := strconv.Atoi(l); err == nil { limit = val } } if o := r.URL.Query().Get("offset"); o != "" { if val, err := strconv.Atoi(o); err == nil { offset = val } } addresses, err := h.queries.ListAddresses(r.Context(), db.ListAddressesParams{ Limit: int32(limit), Offset: int32(offset), }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(addresses) } func (h *AddressHandler) Get(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.Atoi(vars["id"]) if err != nil { http.Error(w, "Invalid address ID", http.StatusBadRequest) return } address, err := h.queries.GetAddress(r.Context(), int32(id)) if err != nil { if err == sql.ErrNoRows { http.Error(w, "Address not found", http.StatusNotFound) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(address) } func (h *AddressHandler) Create(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) // Parse form data for HTMX requests if err := r.ParseForm(); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Get customer ID from URL or form var customerID int32 if cid := vars["customerid"]; cid != "" { if id, err := strconv.Atoi(cid); err == nil { customerID = int32(id) } } else if cid := r.FormValue("customer_id"); cid != "" { if id, err := strconv.Atoi(cid); err == nil { customerID = int32(id) } } params := db.CreateAddressParams{ Name: r.FormValue("name"), Address: r.FormValue("address"), City: r.FormValue("city"), StateID: 1, // Default state CountryID: 1, // Default country CustomerID: customerID, Type: r.FormValue("type"), Postcode: r.FormValue("postcode"), } // Parse state_id and country_id if provided if sid := r.FormValue("state_id"); sid != "" { if id, err := strconv.Atoi(sid); err == nil { params.StateID = int32(id) } } if cid := r.FormValue("country_id"); cid != "" { if id, err := strconv.Atoi(cid); err == nil { params.CountryID = int32(id) } } // Check if this is a JSON request if r.Header.Get("Content-Type") == "application/json" { if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } result, err := h.queries.CreateAddress(r.Context(), params) if err != nil { if r.Header.Get("HX-Request") == "true" { w.Header().Set("Content-Type", "text/html") w.Write([]byte(`
Error creating address
`)) return } http.Error(w, err.Error(), http.StatusInternalServerError) return } id, err := result.LastInsertId() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // If HTMX request, return the new address row if r.Header.Get("HX-Request") == "true" { w.Header().Set("Content-Type", "text/html") // Return a simple HTML response for now w.Write([]byte(`
Address created successfully
`)) return } // JSON response for API w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]interface{}{ "id": id, }) } func (h *AddressHandler) Update(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.Atoi(vars["id"]) if err != nil { http.Error(w, "Invalid address ID", http.StatusBadRequest) return } var params db.UpdateAddressParams if r.Header.Get("Content-Type") == "application/json" { if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } } else { // Handle form data if err := r.ParseForm(); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } params = db.UpdateAddressParams{ Name: r.FormValue("name"), Address: r.FormValue("address"), City: r.FormValue("city"), Type: r.FormValue("type"), Postcode: r.FormValue("postcode"), } // Parse IDs if sid := r.FormValue("state_id"); sid != "" { if stateID, err := strconv.Atoi(sid); err == nil { params.StateID = int32(stateID) } } if cid := r.FormValue("country_id"); cid != "" { if countryID, err := strconv.Atoi(cid); err == nil { params.CountryID = int32(countryID) } } if cid := r.FormValue("customer_id"); cid != "" { if customerID, err := strconv.Atoi(cid); err == nil { params.CustomerID = int32(customerID) } } } params.ID = int32(id) if err := h.queries.UpdateAddress(r.Context(), params); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) } func (h *AddressHandler) Delete(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.Atoi(vars["id"]) if err != nil { http.Error(w, "Invalid address ID", http.StatusBadRequest) return } if err := h.queries.DeleteAddress(r.Context(), int32(id)); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) } func (h *AddressHandler) CustomerAddresses(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) customerID, err := strconv.Atoi(vars["customerID"]) if err != nil { http.Error(w, "Invalid customer ID", http.StatusBadRequest) return } addresses, err := h.queries.GetCustomerAddresses(r.Context(), int32(customerID)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // If AJAX request, return HTML if r.Header.Get("X-Requested-With") == "XMLHttpRequest" { w.Header().Set("Content-Type", "text/html") // For now, return a simple HTML list w.Write([]byte("")) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(addresses) } func (h *AddressHandler) AddAnother(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) increment := vars["increment"] // Return an HTML form for adding another address w.Header().Set("Content-Type", "text/html") html := fmt.Sprintf(`

Address %s

`, increment, increment, increment, increment, increment, increment, increment, increment) w.Write([]byte(html)) } func (h *AddressHandler) RemoveAnother(w http.ResponseWriter, r *http.Request) { // This typically returns empty content or a success message // The actual removal is handled by JavaScript on the frontend w.WriteHeader(http.StatusOK) }