From 30db05945f0d70a20d9bb1c29f6830c50de1d129 Mon Sep 17 00:00:00 2001 From: Dustin Pianalto Date: Thu, 6 Mar 2025 19:55:54 -0900 Subject: [PATCH] mc --- db/operations.go | 10 ++++++++++ web/server.go | 27 +++++++++++++++++++++++++ web/templates/register.templ | 38 ++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/db/operations.go b/db/operations.go index 59cd50b..842372d 100644 --- a/db/operations.go +++ b/db/operations.go @@ -149,6 +149,16 @@ func (db *DB) GetRacers() ([]models.Racer, error) { return racers, nil } +// IsCarNumberUnique checks if a car number is already in use +func (db *DB) IsCarNumberUnique(carNumber string) (bool, error) { + var count int + err := db.QueryRow("SELECT COUNT(*) FROM racers WHERE car_number = ?", carNumber).Scan(&count) + if err != nil { + return false, err + } + return count == 0, nil +} + // GetRacersByGroup returns racers in a specific group func (db *DB) GetRacersByGroup(groupID int64) ([]models.Racer, error) { rows, err := db.Query(` diff --git a/web/server.go b/web/server.go index a10bc50..9a151e6 100644 --- a/web/server.go +++ b/web/server.go @@ -150,6 +150,9 @@ func (s *Server) routes() { // Add admin events route s.router.Get("/api/admin-events", s.handleAdminEvents()) + + // Add validate car number route + s.router.Get("/api/validate/car-number", s.handleValidateCarNumber()) } // Start starts the web server @@ -908,3 +911,27 @@ func (s *Server) handleAdminEvents() http.HandlerFunc { } } } + +// handleValidateCarNumber handles the validate car number API endpoint +func (s *Server) handleValidateCarNumber() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + carNumber := r.URL.Query().Get("value") + if carNumber == "" { + http.Error(w, "Car number is required", http.StatusBadRequest) + return + } + + isUnique, err := s.db.IsCarNumberUnique(carNumber) + if err != nil { + s.logger.Error("Failed to check car number uniqueness", "error", err) + http.Error(w, "Failed to validate car number", http.StatusInternalServerError) + return + } + + if !isUnique { + w.Write([]byte("Car number is already in use")) + } else { + w.WriteHeader(http.StatusOK) + } + } +} diff --git a/web/templates/register.templ b/web/templates/register.templ index c3f6194..dace0c9 100644 --- a/web/templates/register.templ +++ b/web/templates/register.templ @@ -33,6 +33,7 @@ templ RegisterForm(groups []models.Group, isAdmin bool) { hx-post="/api/racers" hx-target="#racer-form-message" hx-swap="innerHTML" + hx-on::before-request="return validateForm()" hx-on::after-request="if(event.detail.successful) { document.getElementById('racer-form').reset(); setTimeout(function() { @@ -55,7 +56,24 @@ templ RegisterForm(groups []models.Group, isAdmin bool) {
- + +
+
+
+ Loading... +
+ Checking availability... +
@@ -81,4 +99,20 @@ templ RegisterForm(groups []models.Group, isAdmin bool) {
-} \ No newline at end of file +} + + \ No newline at end of file