package main import ( "encoding/json" "io/ioutil" "log" "net/http" "os" "strconv" "github.com/gorilla/mux" "go-sjles-pta-vote/server/models" "go-sjles-pta-vote/server/services" ) func voteHandler(w http.ResponseWriter, r *http.Request) { var vote models.Vote if err := json.NewDecoder(r.Body).Decode(&vote); err != nil { http.Error(w, "Invalid request payload", http.StatusBadRequest) return } err := services.SetVote(&vote) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } func voteIDHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) idStr := vars["id"] id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { http.Error(w, "Invalid poll ID", http.StatusBadRequest) return } vote := models.Vote{ PollId: id, Email: "example@example.com", // Replace with actual email retrieval logic Vote: true, // Replace with actual vote retrieval logic } err = services.SetVote(&vote) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } func statsHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { filePath := "./server/templates/stats.html" log.Printf("Serving stats.html from %s", filePath) http.ServeFile(w, r, filePath) } else if r.Method == "POST" { vars := mux.Vars(r) id := vars["id"] poll, err := services.GetPollByQuestion(id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } json.NewEncoder(w).Encode(poll) } else { w.WriteHeader(http.StatusMethodNotAllowed) } } func statsIDHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] poll, err := services.GetPollByQuestion(id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } json.NewEncoder(w).Encode(poll) } func adminHandler(w http.ResponseWriter, r *http.Request) { // Add admin functionality here w.WriteHeader(http.StatusOK) } func adminIDHandler(w http.ResponseWriter, r *http.Request) { //vars := mux.Vars(r) //id := vars["id"] // Add admin functionality here w.WriteHeader(http.StatusOK) } func adminMembersHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { // Redirect to client's AdminMembersPage instead of serving members.html w.Header().Set("Location", "/admin-members") w.WriteHeader(http.StatusFound) return } else if r.Method == "POST" { var year int var err error if err = r.ParseMultipartForm(10 << 20); err != nil { http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) return } if y := r.FormValue("year"); y != "" { year, err = strconv.Atoi(y) log.Printf("Parsed year: %d", year) if err != nil { http.Error(w, "Invalid year", http.StatusBadRequest) return } } file, _, err := r.FormFile("members.csv") if err != nil { http.Error(w, "Failed to upload file", http.StatusBadRequest) return } defer file.Close() fileBytes, err := ioutil.ReadAll(file) if err != nil { http.Error(w, "Failed to read file", http.StatusInternalServerError) return } if err = services.ParseMembersFromBytes(year, fileBytes); err != nil { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) return } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]bool{"success": true}) } else { w.WriteHeader(http.StatusMethodNotAllowed) } } // Add a new handler for the client's AdminMembersPage func adminMembersClientHandler(w http.ResponseWriter, r *http.Request) { filePath := "./client/build/admin-members.html" if _, err := os.Stat(filePath); err == nil { http.ServeFile(w, r, filePath) } else { w.WriteHeader(http.StatusNotFound) } } func main() { log.SetOutput(os.Stdout) log.SetFlags(log.LstdFlags | log.Lshortfile) log.Printf("Starting server on :8080") http.HandleFunc("/vote", voteHandler) http.HandleFunc("/vote/{id}", voteIDHandler) http.HandleFunc("/stats", statsHandler) http.HandleFunc("/stats/{id}", statsIDHandler) http.HandleFunc("/admin", adminHandler) http.HandleFunc("/admin/{id}", adminIDHandler) http.HandleFunc("/admin/members", adminMembersHandler) http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) { filePath := "./server/icons/favicon.ico" http.ServeFile(w, r, filePath) }) http.Handle("/", http.FileServer(http.Dir("./client/build"))) // Add this function to handle static files during development http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { http.ServeFile(w, r, "./client/build/index.html") } else { file := "./client/build" + r.URL.Path if _, err := os.Stat(file); err == nil { http.ServeFile(w, r, file) } else { w.WriteHeader(http.StatusNotFound) } } }) // Add this line to handle client's AdminMembersPage http.HandleFunc("/admin-members", adminMembersClientHandler) log.Fatal(http.ListenAndServe(":8080", nil)) }