Files
Poll-system/app/main.go

169 lines
5.4 KiB
Go
Raw Normal View History

2025-08-26 14:13:09 -06:00
package main
import (
"context"
"log"
"net/http"
"os"
"github.com/golang-jwt/jwt/v5"
2025-08-27 17:54:45 -06:00
"github.com/joho/godotenv"
2025-08-26 14:13:09 -06:00
"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
2025-08-28 17:09:23 -06:00
showLeaderNav := role == 2 // Team Leader role
2025-08-26 14:13:09 -06:00
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 {
2025-08-28 17:09:23 -06:00
err := godotenv.Load()
2025-08-27 17:54:45 -06:00
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
jwtSecret := os.Getenv("JWT_SECRET")
var jwtKey = []byte(jwtSecret)
2025-08-26 14:13:09 -06:00
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) {
2025-08-27 17:54:45 -06:00
return jwtKey, nil
2025-08-26 14:13:09 -06:00
})
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{}{
2025-08-28 17:09:23 -06:00
"Title": "Admin Dashboard",
"IsAuthenticated": false,
"ActiveSection": "dashboard",
})
2025-08-26 14:13:09 -06:00
}
func main() {
models.InitDB()
2025-08-28 17:09:23 -06:00
// Static file servers
2025-08-26 14:13:09 -06:00
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
2025-08-28 17:09:23 -06:00
uploadsFs := http.FileServer(http.Dir("uploads"))
http.Handle("/uploads/", http.StripPrefix("/uploads/", uploadsFs))
2025-08-26 14:13:09 -06:00
// 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))
2025-08-27 13:21:11 -06:00
http.HandleFunc("/team_builder/remove_volunteer", adminMiddleware(handlers.RemoveVolunteerHandler))
2025-08-26 14:13:09 -06:00
http.HandleFunc("/addresses", adminMiddleware(handlers.AddressHandler))
2025-08-27 13:21:11 -06:00
http.HandleFunc("/assign_address", adminMiddleware(handlers.AssignAddressHandler))
http.HandleFunc("/remove_assigned_address", adminMiddleware(handlers.RemoveAssignedAddressHandler))
2025-08-28 23:27:24 -06:00
http.HandleFunc("/addresses/upload-csv", adminMiddleware(handlers.CSVUploadHandler))
2025-08-26 14:13:09 -06:00
http.HandleFunc("/posts", adminMiddleware(handlers.PostsHandler))
//--- Volunteer-only routes
http.HandleFunc("/volunteer/dashboard", volunteerMiddleware(handlers.VolunteerPostsHandler))
2025-08-27 13:21:11 -06:00
http.HandleFunc("/volunteer/Addresses", volunteerMiddleware(handlers.VolunteerAppointmentHandler))
2025-08-26 14:13:09 -06:00
http.HandleFunc("/schedual", volunteerMiddleware(schedualHandler))
2025-08-28 17:09:23 -06:00
// Poll routes (volunteer only)
http.HandleFunc("/poll", volunteerMiddleware(handlers.PollHandler))
2025-08-27 13:21:11 -06:00
2025-08-26 14:13:09 -06:00
log.Println("Server started on localhost:8080")
2025-08-27 13:21:11 -06:00
log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
2025-08-28 17:09:23 -06:00
}