package handlers import ( "encoding/json" "fmt" "log" "net/http" "os" "strings" "strconv" ) // Struct for incoming JSON request type SignupRequest struct { Email string `json:"email"` } // Struct for JSON response type SignupResponse struct { Message string `json:"message"` } type User struct { Email string `json:"email"` } func HandleSignup(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Only POST allowed", http.StatusMethodNotAllowed) return } if err := r.ParseForm(); err != nil { http.Error(w, "Failed to parse form", http.StatusBadRequest) return } email := strings.TrimSpace(r.FormValue("email")) if email == "" { http.Error(w, "Missing email", http.StatusBadRequest) return } // Optional: basic email format check if !strings.Contains(email, "@") { http.Error(w, "Invalid email format", http.StatusBadRequest) return } log.Printf("Received signup from email: %s", email) err := AddUserToFile(email, "db/users.json") if err != nil { log.Printf("Error saving user: %v", err) http.Error(w, "Failed to save user", http.StatusInternalServerError) return } // Respond with success w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(SignupResponse{ Message: fmt.Sprintf("Signup received. In the coming days, you will receive an email telling you how to join."), }) } func AddUserToFile(email string, filepath string) error { // Read the current users (if file exists) users := make(map[string]User) if existingData, err := os.ReadFile(filepath); err == nil && len(existingData) > 0 { if err := json.Unmarshal(existingData, &users); err != nil { return fmt.Errorf("invalid users.json format: %v", err) } } // Find the next numeric key maxID := 0 for key := range users { id, err := strconv.Atoi(key) if err == nil && id > maxID { maxID = id } } newID := strconv.Itoa(maxID + 1) // Add new user users[newID] = User{Email: email} // Marshal updated data updated, err := json.MarshalIndent(users, "", " ") if err != nil { return fmt.Errorf("could not marshal updated users: %v", err) } // Write updated data back to file if err := os.WriteFile(filepath, updated, 0644); err != nil { return fmt.Errorf("could not write to users file: %v", err) } return nil }