package main import ( "context" "log" "net/http" "os" "github.com/golang-jwt/jwt/v5" "github.com/joho/godotenv" "github.com/patel-mann/poll-system/app/internal/handlers" "github.com/patel-mann/poll-system/app/internal/models" "github.com/patel-mann/poll-system/app/internal/utils" _ "github.com/lib/pq" // use PostgreSQL ) // Helper function to determine navigation visibility based on role func getNavFlags(role int) (bool, bool, bool) { showAdminNav := role == 1 // Admin role showLeaderNav := role == 2 // Team Leader role showVolunteerNav := role == 3 // Volunteer role return showAdminNav, showVolunteerNav, showLeaderNav } // Helper function to create template data with proper nav flags func createTemplateData(title, activeSection string, role int, isAuthenticated bool, additionalData map[string]interface{}) map[string]interface{} { showAdminNav, showVolunteerNav, _ := getNavFlags(role) data := map[string]interface{}{ "Title": title, "IsAuthenticated": isAuthenticated, "Role": role, "ShowAdminNav": showAdminNav, "ShowVolunteerNav": showVolunteerNav, "ActiveSection": activeSection, } // Add any additional data for key, value := range additionalData { data[key] = value } return data } func authMiddleware(next http.HandlerFunc) http.HandlerFunc { err := godotenv.Load() if err != nil { log.Fatalf("Error loading .env file: %v", err) } jwtSecret := os.Getenv("JWT_SECRET") var jwtKey = []byte(jwtSecret) return func(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("session") if err != nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } claims := &models.Claims{} token, err := jwt.ParseWithClaims(cookie.Value, claims, func(token *jwt.Token) (interface{}, error) { return jwtKey, nil }) if err != nil || !token.Valid { http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Add user info to context ctx := context.WithValue(r.Context(), "user_id", claims.UserID) ctx = context.WithValue(ctx, "user_role", claims.Role) r = r.WithContext(ctx) next.ServeHTTP(w, r) } } // Admin middleware to check if user has admin role func adminMiddleware(next http.HandlerFunc) http.HandlerFunc { return authMiddleware(func(w http.ResponseWriter, r *http.Request) { role, ok := r.Context().Value("user_role").(int) if !ok || role != 1 { http.Redirect(w, r, "/", http.StatusSeeOther) return } next.ServeHTTP(w, r) }) } // Volunteer middleware to check if user has volunteer role func volunteerMiddleware(next http.HandlerFunc) http.HandlerFunc { return authMiddleware(func(w http.ResponseWriter, r *http.Request) { role, ok := r.Context().Value("user_role").(int) if !ok || (role != 3 && role != 2) { http.Redirect(w, r, "/", http.StatusSeeOther) return } next.ServeHTTP(w, r) }) } func schedualHandler(w http.ResponseWriter, r *http.Request) { role := r.Context().Value("user_role").(int) data := createTemplateData("My Schedule", "schedual", role, true, nil) utils.Render(w, "Schedual/schedual.html", data) } func HomeHandler(w http.ResponseWriter, r *http.Request) { utils.Render(w, "dashboard/dashboard.html", map[string]interface{}{ "Title": "Admin Dashboard", "IsAuthenticated": false, "ActiveSection": "dashboard", }) } func main() { models.InitDB() // Static file servers fs := http.FileServer(http.Dir("static")) http.Handle("/static/", http.StripPrefix("/static/", fs)) uploadsFs := http.FileServer(http.Dir("uploads")) http.Handle("/uploads/", http.StripPrefix("/uploads/", uploadsFs)) // Public HTML Routes http.HandleFunc("/", HomeHandler) http.HandleFunc("/login", handlers.LoginHandler) http.HandleFunc("/register", handlers.RegisterHandler) //--- Protected HTML Routes http.HandleFunc("/logout", authMiddleware(handlers.LogoutHandler)) // Common routes (both admin and volunteer can access) http.HandleFunc("/profile", authMiddleware(handlers.ProfileHandler)) http.HandleFunc("/profile/update", authMiddleware(handlers.ProfileUpdateHandler)) //--- Admin-only routes http.HandleFunc("/dashboard", adminMiddleware(handlers.AdminDashboardHandler)) http.HandleFunc("/volunteers", adminMiddleware(handlers.VolunteerHandler)) http.HandleFunc("/volunteer/edit", adminMiddleware(handlers.EditVolunteerHandler)) http.HandleFunc("/team_builder", adminMiddleware(handlers.TeamBuilderHandler)) http.HandleFunc("/team_builder/remove_volunteer", adminMiddleware(handlers.RemoveVolunteerHandler)) http.HandleFunc("/addresses", adminMiddleware(handlers.AddressHandler)) http.HandleFunc("/assign_address", adminMiddleware(handlers.AssignAddressHandler)) http.HandleFunc("/remove_assigned_address", adminMiddleware(handlers.RemoveAssignedAddressHandler)) http.HandleFunc("/addresses/upload-csv", adminMiddleware(handlers.CSVUploadHandler)) http.HandleFunc("/posts", adminMiddleware(handlers.PostsHandler)) //--- Volunteer-only routes http.HandleFunc("/volunteer/dashboard", volunteerMiddleware(handlers.VolunteerPostsHandler)) http.HandleFunc("/volunteer/Addresses", volunteerMiddleware(handlers.VolunteerAppointmentHandler)) http.HandleFunc("/schedual", volunteerMiddleware(schedualHandler)) // Poll routes (volunteer only) http.HandleFunc("/poll", volunteerMiddleware(handlers.PollHandler)) log.Println("Server started on localhost:8080") log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil)) }