func (br *BeuboRouter) AdminUserRoleDelete(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_user_roles", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	params := mux.Vars(r)
	id := params["id"]
	i, err := strconv.Atoi(id)
	utility.ErrorHandler(err, false)
	role := structs.FetchRole(br.DB, i)
	if role.ID != 0 && !role.IsDefault() {
		structs.DeleteRole(br.DB, i)
	} else {
		utility.SetFlash(w, "error", []byte("Can not delete a default role"))
		http.Redirect(w, r, "/admin/users/roles", 302)
		return
	}
	utility.SetFlash(w, "message", []byte("Role deleted"))
	http.Redirect(w, r, "/admin/users/roles", 302)
}
AdminUserRoleDelete handles the deletion of a user role
package routes
import (
	"fmt"
	"github.com/gorilla/mux"
	"github.com/uberswe/beubo/pkg/middleware"
	"github.com/uberswe/beubo/pkg/structs"
	"github.com/uberswe/beubo/pkg/structs/page"
	"github.com/uberswe/beubo/pkg/structs/page/component"
	"github.com/uberswe/beubo/pkg/utility"
	"html"
	"html/template"
	"net/http"
	"strconv"
)
type userAddData struct {
	Roles []structs.Role
	Sites []structs.Site
}
func (br *BeuboRouter) AdminUserAdd(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	roles := []structs.Role{}
	sites := []structs.Site{}
	br.DB.Find(&roles)
	br.DB.Find(&sites)
	pageData := structs.PageData{
		Template: "admin.user.add",
		Title:    "Admin - Add User",
		Themes:   br.Renderer.GetThemes(),
		Extra: userAddData{
			Roles: roles,
			Sites: sites,
		},
	}
	br.Renderer.RenderHTMLPage(w, r, pageData)
}
func (br *BeuboRouter) AdminUserAddPost(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	path := "/admin/users/add"
	successMessage := "User created"
	invalidError := "an error occurred and the user could not be created."
	email := r.FormValue("emailField")
	password := r.FormValue("passwordField")
	rs := []int{}
	ss := []int{}
	for key, values := range r.PostForm {
		if key == fmt.Sprintf("%s[]", "roleField") {
			for _, value := range values {
				valueInt, err := strconv.Atoi(value)
				utility.ErrorHandler(err, false)
				rs = append(rs, valueInt)
			}
		} else if key == fmt.Sprintf("%s[]", "siteField") {
			for _, value := range values {
				valueInt, err := strconv.Atoi(value)
				utility.ErrorHandler(err, false)
				ss = append(ss, valueInt)
			}
		}
	}
	roles := []*structs.Role{}
	if len(rs) > 0 {
		br.DB.Find(&roles, rs)
	}
	sites := []*structs.Site{}
	if len(ss) > 0 {
		br.DB.Find(&sites, ss)
	}
	if !utility.IsEmailValid(email) {
		invalidError = "The email is invalid"
		utility.SetFlash(w, "error", []byte(invalidError))
		http.Redirect(w, r, path, 302)
		return
	}
	if len(password) < 8 {
		invalidError = "The password is too short"
		utility.SetFlash(w, "error", []byte(invalidError))
		http.Redirect(w, r, path, 302)
		return
	}
	if structs.CreateUser(br.DB, email, password, roles, sites) {
		utility.SetFlash(w, "message", []byte(successMessage))
		http.Redirect(w, r, "/admin/users", 302)
		return
	}
	utility.SetFlash(w, "error", []byte(invalidError))
	http.Redirect(w, r, "/admin/users/add", 302)
}
func (br *BeuboRouter) AdminUserDelete(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	params := mux.Vars(r)
	id := params["id"]
	i, err := strconv.Atoi(id)
	utility.ErrorHandler(err, false)
	structs.DeleteUser(br.DB, i)
	utility.SetFlash(w, "message", []byte("User deleted"))
	http.Redirect(w, r, "/admin/users", 302)
}
type userEdit struct {
	User     structs.User
	Role     structs.Role
	Roles    []userEditRole
	Features []userEditFeature
	Sites    []userEditSite
}
type userEditRole struct {
	Role    structs.Role
	Checked bool
}
type userEditSite struct {
	Site    structs.Site
	Checked bool
}
func (br *BeuboRouter) AdminUserEdit(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	params := mux.Vars(r)
	id := params["id"]
	i, err := strconv.Atoi(id)
	utility.ErrorHandler(err, false)
	user := structs.FetchUser(br.DB, i)
	if user.ID == 0 {
		br.NotFoundHandler(w, r)
		return
	}
	ueRoles := []userEditRole{}
	roles := []structs.Role{}
	br.DB.Find(&roles)
	for _, role := range roles {
		ueRoles = append(ueRoles, userEditRole{Role: role, Checked: user.HasRole(br.DB, role)})
	}
	ueSites := []userEditSite{}
	sites := []structs.Site{}
	br.DB.Find(&sites)
	for _, site := range sites {
		ueSites = append(ueSites, userEditSite{Site: site, Checked: user.CanAccessSite(br.DB, site)})
	}
	pageData := structs.PageData{
		Template: "admin.user.edit",
		Title:    "Admin - Edit Site",
		Extra: userEdit{
			User:  user,
			Roles: ueRoles,
			Sites: ueSites,
		},
		Themes: br.Renderer.GetThemes(),
	}
	br.Renderer.RenderHTMLPage(w, r, pageData)
}
func (br *BeuboRouter) AdminUserEditPost(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	params := mux.Vars(r)
	id := params["id"]
	path := fmt.Sprintf("/admin/users/edit/%s", id)
	i, err := strconv.Atoi(id)
	utility.ErrorHandler(err, false)
	successMessage := "User updated"
	invalidError := "an error occurred and the user could not be updated."
	email := r.FormValue("emailField")
	password := r.FormValue("passwordField")
	rs := []int{}
	ss := []int{}
	for key, values := range r.PostForm {
		if key == fmt.Sprintf("%s[]", "roleField") {
			for _, value := range values {
				valueInt, err := strconv.Atoi(value)
				utility.ErrorHandler(err, false)
				rs = append(rs, valueInt)
			}
		} else if key == fmt.Sprintf("%s[]", "siteField") {
			for _, value := range values {
				valueInt, err := strconv.Atoi(value)
				utility.ErrorHandler(err, false)
				ss = append(ss, valueInt)
			}
		}
	}
	roles := []*structs.Role{}
	if len(rs) > 0 {
		br.DB.Find(&roles, rs)
	}
	sites := []*structs.Site{}
	if len(ss) > 0 {
		br.DB.Find(&sites, ss)
	}
	if !utility.IsEmailValid(email) {
		invalidError = "The email is invalid"
		utility.SetFlash(w, "error", []byte(invalidError))
		http.Redirect(w, r, path, 302)
		return
	}
	if len(password) > 0 && len(password) < 8 {
		invalidError = "The password is too short"
		utility.SetFlash(w, "error", []byte(invalidError))
		http.Redirect(w, r, path, 302)
		return
	}
	if structs.UpdateUser(br.DB, i, email, password, roles, sites) {
		utility.SetFlash(w, "message", []byte(successMessage))
		http.Redirect(w, r, "/admin/users", 302)
		return
	}
	utility.SetFlash(w, "error", []byte(invalidError))
	http.Redirect(w, r, path, 302)
}
func (br *BeuboRouter) AdminUserRoles(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_users", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	var roles []structs.Role
	if err := br.DB.Find(&roles).Error; err != nil {
		utility.ErrorHandler(err, false)
	}
	var rows []component.Row
	for _, role := range roles {
		sid := fmt.Sprintf("%d", role.ID)
		if role.Name == "Administrator" || role.Name == "Member" {
			rows = append(rows, component.Row{
				Columns: []component.Column{
					{Name: "ID", Value: sid},
					{Name: "Name", Value: html.EscapeString(role.Name)},
					{},
					{},
				},
			})
		} else {
			rows = append(rows, component.Row{
				Columns: []component.Column{
					{Name: "ID", Value: sid},
					{Name: "Name", Value: html.EscapeString(role.Name)},
					{Name: "", Field: component.Button{
						Link:    template.URL(fmt.Sprintf("/admin/users/roles/edit/%s", sid)),
						Class:   "btn btn-primary",
						Content: "Edit",
						T:       br.Renderer.T,
					}},
					{Name: "", Field: component.Button{
						Link:    template.URL(fmt.Sprintf("/admin/users/roles/delete/%s", sid)),
						Class:   "btn btn-primary",
						Content: "Delete",
						T:       br.Renderer.T,
					}},
				},
			})
		}
	}
	table := component.Table{
		Section: "main",
		Header: []component.Column{
			{Name: "ID"},
			{Name: "Name"},
			{Name: ""},
			{Name: ""},
		},
		Rows:             rows,
		PageNumber:       1,
		PageDisplayCount: 10,
		T:                br.Renderer.T,
	}
	pageData := structs.PageData{
		Template: "admin.page",
		Title:    "Admin - User Roles",
		Components: []page.Component{
			component.Button{
				Section: "main",
				Link:    template.URL("/admin/users/roles/add"),
				Class:   "btn btn-primary",
				Content: "Add Role",
				T:       br.Renderer.T,
			},
			table,
		},
	}
	br.Renderer.RenderHTMLPage(w, r, pageData)
}
func (br *BeuboRouter) AdminUserRoleAdd(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_user_roles", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	features := []structs.Feature{}
	br.DB.Find(&features)
	pageData := structs.PageData{
		Template: "admin.user.role.add",
		Title:    "Admin - Add Role",
		Themes:   br.Renderer.GetThemes(),
		Extra:    features,
	}
	br.Renderer.RenderHTMLPage(w, r, pageData)
}
func (br *BeuboRouter) AdminUserRoleAddPost(w http.ResponseWriter, r *http.Request) {
	if !middleware.CanAccess(br.DB, "manage_user_roles", r) {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	path := "/admin/users/roles/add"
	successMessage := "Role created"
	invalidError := "an error occurred and the user could not be created."
	name := r.FormValue("nameField")
	if len(name) < 2 {
		invalidError = "The name is too short"
		utility.SetFlash(w, "error", []byte(invalidError))
		http.Redirect(w, r, path, 302)
		return
	}
	if structs.CreateRole(br.DB, name) {
		utility.SetFlash(w, "message", []byte(successMessage))
		http.Redirect(w, r, "/admin/users/roles", 302)
		return
	}
	utility.SetFlash(w, "error", []byte(invalidError))
	http.Redirect(w, r, "/admin/users/roles/add", 302)
}