package handlers import ( "html/template" "log" "net/http" "shop/internal/auth" "shop/internal/repository" ) type AdminHandler struct { repo *repository.AdminRepository products *repository.ProductRepository session *auth.Session templates *template.Template } type adminLoginData struct { Title string Error string Email string } type adminDashboardData struct { Title string Email string ProductCount int Categories interface{} } func NewAdminHandler( adminRepo *repository.AdminRepository, productRepo *repository.ProductRepository, session *auth.Session, templates *template.Template, ) *AdminHandler { return &AdminHandler{ repo: adminRepo, products: productRepo, session: session, templates: templates, } } func (h *AdminHandler) LoginPage(w http.ResponseWriter, r *http.Request) { if email, ok := h.session.FromRequest(r); ok && email != "" { http.Redirect(w, r, "/admin/", http.StatusSeeOther) return } data := adminLoginData{Title: "Вход в админку"} w.Header().Set("Content-Type", "text/html; charset=utf-8") _ = h.templates.ExecuteTemplate(w, "admin_login.html", data) } func (h *AdminHandler) Login(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } email := r.FormValue("email") password := r.FormValue("password") ok, err := h.repo.Authenticate(r.Context(), email, password) if err != nil { log.Printf("admin auth: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if !ok { h.renderLoginError(w, email, "Неверный email или пароль") return } token, err := h.session.Create(email) if err != nil { log.Printf("session: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } h.session.SetCookie(w, token) http.Redirect(w, r, "/admin/", http.StatusSeeOther) } func (h *AdminHandler) Logout(w http.ResponseWriter, r *http.Request) { h.session.ClearCookie(w) http.Redirect(w, r, "/admin/login", http.StatusSeeOther) } func (h *AdminHandler) Dashboard(w http.ResponseWriter, r *http.Request) { email, ok := h.session.FromRequest(r) if !ok { http.Redirect(w, r, "/admin/login", http.StatusSeeOther) return } ctx := r.Context() products, err := h.products.Featured(ctx, 100) if err != nil { log.Printf("admin products: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } categories, err := h.products.Categories(ctx) if err != nil { log.Printf("admin categories: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } data := adminDashboardData{ Title: "Админ-панель", Email: email, ProductCount: len(products), Categories: categories, } w.Header().Set("Content-Type", "text/html; charset=utf-8") _ = h.templates.ExecuteTemplate(w, "admin_dashboard.html", data) } func (h *AdminHandler) renderLoginError(w http.ResponseWriter, email, msg string) { data := adminLoginData{ Title: "Вход в админку", Error: msg, Email: email, } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusUnauthorized) _ = h.templates.ExecuteTemplate(w, "admin_login.html", data) }