use Go templating
This commit is contained in:
parent
5472f20964
commit
7aba0cc253
@ -1,7 +1,6 @@
|
|||||||
package manage
|
package manage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -95,7 +94,7 @@ func BlacklistHandler(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateBlacklist.Render(map[string]interface{}{
|
ctx.HTML(200, "manage/blacklist", gin.H{
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"guildId": guildIdStr,
|
"guildId": guildIdStr,
|
||||||
"csrf": store.Get("csrf").(string),
|
"csrf": store.Get("csrf").(string),
|
||||||
@ -104,6 +103,6 @@ func BlacklistHandler(ctx *gin.Context) {
|
|||||||
"blacklisted": blacklisted,
|
"blacklisted": blacklisted,
|
||||||
"userNotFound": userNotFound,
|
"userNotFound": userNotFound,
|
||||||
"isStaff": isStaff,
|
"isStaff": isStaff,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package manage
|
package manage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -95,7 +94,7 @@ func LogsHandler(ctx *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateLogs.Render(map[string]interface{}{
|
ctx.HTML(200, "manage/logs",gin.H{
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"guildId": guildIdStr,
|
"guildId": guildIdStr,
|
||||||
"avatar": store.Get("avatar").(string),
|
"avatar": store.Get("avatar").(string),
|
||||||
@ -105,7 +104,7 @@ func LogsHandler(ctx *gin.Context) {
|
|||||||
"nextPage": page + 1,
|
"nextPage": page + 1,
|
||||||
"logs": formattedLogs,
|
"logs": formattedLogs,
|
||||||
"page": page,
|
"page": page,
|
||||||
}))
|
})
|
||||||
} else {
|
} else {
|
||||||
ctx.Redirect(302, "/login")
|
ctx.Redirect(302, "/login")
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package manage
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -254,7 +253,7 @@ func SettingsHandler(ctx *gin.Context) {
|
|||||||
table.SetUserCanClose(guildId, usersCanClose)
|
table.SetUserCanClose(guildId, usersCanClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateSettings.Render(map[string]interface{}{
|
ctx.HTML(200, "manage/settings", gin.H{
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"guildId": guildIdStr,
|
"guildId": guildIdStr,
|
||||||
"avatar": store.Get("avatar").(string),
|
"avatar": store.Get("avatar").(string),
|
||||||
@ -272,7 +271,7 @@ func SettingsHandler(ctx *gin.Context) {
|
|||||||
"panelcontent": panelContent,
|
"panelcontent": panelContent,
|
||||||
"panelcolour": strconv.FormatInt(int64(panelColour), 16),
|
"panelcolour": strconv.FormatInt(int64(panelColour), 16),
|
||||||
"usersCanClose": usersCanClose,
|
"usersCanClose": usersCanClose,
|
||||||
}))
|
})
|
||||||
} else {
|
} else {
|
||||||
ctx.Redirect(302, "/login")
|
ctx.Redirect(302, "/login")
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package manage
|
package manage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -98,13 +97,13 @@ func TicketListHandler(ctx *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateTicketList.Render(map[string]interface{}{
|
ctx.HTML(200, "manage/ticketlist", gin.H{
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"guildId": guildIdStr,
|
"guildId": guildIdStr,
|
||||||
"csrf": store.Get("csrf").(string),
|
"csrf": store.Get("csrf").(string),
|
||||||
"avatar": store.Get("avatar").(string),
|
"avatar": store.Get("avatar").(string),
|
||||||
"baseUrl": config.Conf.Server.BaseUrl,
|
"baseUrl": config.Conf.Server.BaseUrl,
|
||||||
"tickets": ticketsFormatted,
|
"tickets": ticketsFormatted,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package manage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -108,7 +107,7 @@ func TicketViewHandler(ctx *gin.Context) {
|
|||||||
premium := make(chan bool)
|
premium := make(chan bool)
|
||||||
go utils.IsPremiumGuild(store, guildIdStr, premium)
|
go utils.IsPremiumGuild(store, guildIdStr, premium)
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateTicketView.Render(map[string]interface{}{
|
ctx.HTML(200, "manage/ticketview", gin.H{
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"guildId": guildIdStr,
|
"guildId": guildIdStr,
|
||||||
"csrf": store.Get("csrf").(string),
|
"csrf": store.Get("csrf").(string),
|
||||||
@ -120,6 +119,6 @@ func TicketViewHandler(ctx *gin.Context) {
|
|||||||
"ticketId": ticket.TicketId,
|
"ticketId": ticket.TicketId,
|
||||||
"include_mock": true,
|
"include_mock": true,
|
||||||
"premium": <-premium,
|
"premium": <-premium,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package root
|
package root
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
"github.com/TicketsBot/GoPanel/database/table"
|
"github.com/TicketsBot/GoPanel/database/table"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
@ -40,24 +39,14 @@ func IndexHandler(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var servers []map[string]string
|
ctx.HTML(200, "main/index", gin.H{
|
||||||
for _, server := range adminGuilds {
|
|
||||||
element := map[string]string{
|
|
||||||
"serverid": server.Id,
|
|
||||||
"servername": server.Name,
|
|
||||||
}
|
|
||||||
|
|
||||||
servers = append(servers, element)
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.Respond(ctx, template.TemplateIndex.Render(map[string]interface{}{
|
|
||||||
"name": store.Get("name").(string),
|
"name": store.Get("name").(string),
|
||||||
"baseurl": config.Conf.Server.BaseUrl,
|
"baseurl": config.Conf.Server.BaseUrl,
|
||||||
"servers": servers,
|
"servers": adminGuilds,
|
||||||
"empty": len(servers) == 0,
|
"empty": len(adminGuilds) == 0,
|
||||||
"isIndex": true,
|
"isIndex": true,
|
||||||
"avatar": store.Get("avatar").(string),
|
"avatar": store.Get("avatar").(string),
|
||||||
}))
|
})
|
||||||
} else {
|
} else {
|
||||||
ctx.Redirect(302, "/login")
|
ctx.Redirect(302, "/login")
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TicketsBot/GoPanel/app/http/endpoints/manage"
|
"github.com/TicketsBot/GoPanel/app/http/endpoints/manage"
|
||||||
"github.com/TicketsBot/GoPanel/app/http/endpoints/root"
|
"github.com/TicketsBot/GoPanel/app/http/endpoints/root"
|
||||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
|
||||||
"github.com/TicketsBot/GoPanel/config"
|
"github.com/TicketsBot/GoPanel/config"
|
||||||
|
"github.com/gin-contrib/multitemplate"
|
||||||
"github.com/gin-contrib/static"
|
"github.com/gin-contrib/static"
|
||||||
"github.com/gin-gonic/contrib/sessions"
|
"github.com/gin-gonic/contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -15,10 +15,6 @@ import (
|
|||||||
func StartServer() {
|
func StartServer() {
|
||||||
log.Println("Starting HTTP server")
|
log.Println("Starting HTTP server")
|
||||||
|
|
||||||
// Compile templates
|
|
||||||
template.LoadLayouts()
|
|
||||||
template.LoadTemplates()
|
|
||||||
|
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
|
|
||||||
// Sessions
|
// Sessions
|
||||||
@ -35,45 +31,65 @@ func StartServer() {
|
|||||||
// Handle static asset requests
|
// Handle static asset requests
|
||||||
router.Use(static.Serve("/assets/", static.LocalFile("./public/static", false)))
|
router.Use(static.Serve("/assets/", static.LocalFile("./public/static", false)))
|
||||||
|
|
||||||
// Root
|
// Register templates
|
||||||
|
router.HTMLRender = createRenderer()
|
||||||
|
|
||||||
router.GET("/", root.IndexHandler)
|
router.GET("/", root.IndexHandler)
|
||||||
|
|
||||||
// /login
|
|
||||||
router.GET("/login", root.LoginHandler)
|
router.GET("/login", root.LoginHandler)
|
||||||
|
|
||||||
// /callback
|
|
||||||
router.GET("/callback", root.CallbackHandler)
|
router.GET("/callback", root.CallbackHandler)
|
||||||
|
|
||||||
// /logout
|
|
||||||
router.GET("/logout", root.LogoutHandler)
|
router.GET("/logout", root.LogoutHandler)
|
||||||
|
|
||||||
// /manage/:id/settings
|
|
||||||
router.GET("/manage/:id/settings", manage.SettingsHandler)
|
router.GET("/manage/:id/settings", manage.SettingsHandler)
|
||||||
|
|
||||||
// /manage/:id/logs/page/:page
|
|
||||||
router.GET("/manage/:id/logs/page/:page", manage.LogsHandler)
|
router.GET("/manage/:id/logs/page/:page", manage.LogsHandler)
|
||||||
|
|
||||||
// /manage/:id/logs/view/:uuid
|
|
||||||
router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler)
|
router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler)
|
||||||
|
|
||||||
// /manage/:id/blacklist
|
|
||||||
router.GET("/manage/:id/blacklist", manage.BlacklistHandler)
|
router.GET("/manage/:id/blacklist", manage.BlacklistHandler)
|
||||||
|
|
||||||
// /manage/:id/blacklist/remove/:user
|
|
||||||
router.GET("/manage/:id/blacklist/remove/:user", manage.BlacklistRemoveHandler)
|
router.GET("/manage/:id/blacklist/remove/:user", manage.BlacklistRemoveHandler)
|
||||||
|
|
||||||
// /manage/:id/tickets
|
|
||||||
router.GET("/manage/:id/tickets", manage.TicketListHandler)
|
router.GET("/manage/:id/tickets", manage.TicketListHandler)
|
||||||
|
|
||||||
// /manage/:id/tickets/view/:uuid
|
|
||||||
router.GET("/manage/:id/tickets/view/:uuid", manage.TicketViewHandler)
|
router.GET("/manage/:id/tickets/view/:uuid", manage.TicketViewHandler)
|
||||||
|
|
||||||
// POST /manage/:id/tickets/view/:uuid
|
|
||||||
router.POST("/manage/:id/tickets/view/:uuid", manage.SendMessage)
|
router.POST("/manage/:id/tickets/view/:uuid", manage.SendMessage)
|
||||||
|
|
||||||
router.GET("/webchat", manage.WebChatWs)
|
router.GET("/webchat", manage.WebChatWs)
|
||||||
|
|
||||||
if err := router.Run(config.Conf.Server.Host); err != nil {
|
if err := router.Run(config.Conf.Server.Host); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createRenderer() multitemplate.Renderer {
|
||||||
|
r := multitemplate.NewRenderer()
|
||||||
|
|
||||||
|
r = addMainTemplate(r, "index")
|
||||||
|
|
||||||
|
r = addManageTemplate(r, "blacklist")
|
||||||
|
r = addManageTemplate(r, "logs")
|
||||||
|
r = addManageTemplate(r, "settings")
|
||||||
|
r = addManageTemplate(r, "ticketlist")
|
||||||
|
r = addManageTemplate(r, "ticketview")
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMainTemplate(renderer multitemplate.Renderer, name string) multitemplate.Renderer {
|
||||||
|
renderer.AddFromFiles(fmt.Sprintf("main/%s", name),
|
||||||
|
"./public/templates/layouts/main.tmpl",
|
||||||
|
"./public/templates/includes/head.tmpl",
|
||||||
|
"./public/templates/includes/sidebar.tmpl",
|
||||||
|
fmt.Sprintf("./public/templates/views/%s.tmpl", name),
|
||||||
|
)
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
func addManageTemplate(renderer multitemplate.Renderer, name string) multitemplate.Renderer {
|
||||||
|
renderer.AddFromFiles(fmt.Sprintf("manage/%s", name),
|
||||||
|
"./public/templates/layouts/manage.tmpl",
|
||||||
|
"./public/templates/includes/head.tmpl",
|
||||||
|
"./public/templates/includes/sidebar.tmpl",
|
||||||
|
"./public/templates/includes/navbar.tmpl",
|
||||||
|
fmt.Sprintf("./public/templates/views/%s.tmpl", name),
|
||||||
|
)
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
package template
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/hoisie/mustache"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Layout struct {
|
|
||||||
compiled *mustache.Template
|
|
||||||
}
|
|
||||||
|
|
||||||
type Template struct {
|
|
||||||
compiled *mustache.Template
|
|
||||||
Layout Layout
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
LayoutMain Layout
|
|
||||||
LayoutManage Layout
|
|
||||||
|
|
||||||
TemplateIndex Template
|
|
||||||
TemplateLogs Template
|
|
||||||
TemplateSettings Template
|
|
||||||
TemplateBlacklist Template
|
|
||||||
TemplateTicketList Template
|
|
||||||
TemplateTicketView Template
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t *Template) Render(context ...interface{}) string {
|
|
||||||
return t.compiled.RenderInLayout(t.Layout.compiled, context[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadLayouts() {
|
|
||||||
LayoutMain = Layout{
|
|
||||||
compiled: loadLayout("main"),
|
|
||||||
}
|
|
||||||
LayoutManage = Layout{
|
|
||||||
compiled: loadLayout("manage"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadTemplates() {
|
|
||||||
TemplateIndex = Template{
|
|
||||||
compiled: loadTemplate("index"),
|
|
||||||
Layout: LayoutMain,
|
|
||||||
}
|
|
||||||
TemplateLogs = Template{
|
|
||||||
compiled: loadTemplate("logs"),
|
|
||||||
Layout: LayoutManage,
|
|
||||||
}
|
|
||||||
TemplateSettings = Template{
|
|
||||||
compiled: loadTemplate("settings"),
|
|
||||||
Layout: LayoutManage,
|
|
||||||
}
|
|
||||||
TemplateBlacklist = Template{
|
|
||||||
compiled: loadTemplate("blacklist"),
|
|
||||||
Layout: LayoutManage,
|
|
||||||
}
|
|
||||||
TemplateTicketList = Template{
|
|
||||||
compiled: loadTemplate("ticketlist"),
|
|
||||||
Layout: LayoutManage,
|
|
||||||
}
|
|
||||||
TemplateTicketView = Template{
|
|
||||||
compiled: loadTemplate("ticketview"),
|
|
||||||
Layout: LayoutManage,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadLayout(name string) *mustache.Template {
|
|
||||||
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/layouts/%s.mustache", name))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpl
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadTemplate(name string) *mustache.Template {
|
|
||||||
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/views/%s.mustache", name))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpl
|
|
||||||
}
|
|
38
public/static/css/style.css
Normal file
38
public/static/css/style.css
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
body {
|
||||||
|
font-family: 'Open Sans',sans-serif !important;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
background: url("/assets/img/sidebar-2.jpg");
|
||||||
|
background-size: cover;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-bottom {
|
||||||
|
position: absolute !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
background: url("{{.avatar}}?size=32");
|
||||||
|
width: 28px;
|
||||||
|
height: 29px;
|
||||||
|
display: block;
|
||||||
|
background-size: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterCard {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td, .table th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
29
public/templates/includes/head.tmpl
Normal file
29
public/templates/includes/head.tmpl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{{define "head"}}
|
||||||
|
<title>Tickets | A Discord Support Manager Bot</title>
|
||||||
|
|
||||||
|
<!-- Meta -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="Management panel for the Discord Tickets bot">
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
||||||
|
<link rel="icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
||||||
|
|
||||||
|
<!-- Custom CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
|
||||||
|
<link href="/assets/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Bootstrap -->
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
|
<link href="/assets/css/light-bootstrap-dashboard.css?v=1.4.0" rel="stylesheet"/>
|
||||||
|
<link href="/assets/css/animate.min.css" rel="stylesheet"/>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<!-- Discord theme -->
|
||||||
|
<link href="/assets/css/discordmock.css" rel="stylesheet"/>
|
||||||
|
|
||||||
|
<!-- Icons -->
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
|
||||||
|
{{end}}
|
20
public/templates/includes/navbar.tmpl
Normal file
20
public/templates/includes/navbar.tmpl
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{{define "navbar"}}
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav mr-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/manage/{{.guildId}}/settings">Settings</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/manage/{{.guildId}}/logs/page/1">Logs</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/manage/{{.guildId}}/blacklist">Blacklist</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/manage/{{.guildId}}/tickets">Ticket List</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
{{end}}
|
33
public/templates/includes/sidebar.tmpl
Normal file
33
public/templates/includes/sidebar.tmpl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{{define "sidebar"}}
|
||||||
|
<div class="sidebar" data-color="orange" data-image="/assets/img/sidebar-2.jpg">
|
||||||
|
<div class="sidebar-wrapper">
|
||||||
|
<div class="logo">
|
||||||
|
<a href="https://ticketsbot.net" class="simple-text">
|
||||||
|
TicketsBot
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="nav-item sidebar-bottom">
|
||||||
|
<a href="/">
|
||||||
|
<i class="fas fa-server"></i>
|
||||||
|
<p>Servers</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item sidebar-bottom" style="bottom: 60px">
|
||||||
|
<a href="/logout">
|
||||||
|
<i class="fas fa-sign-out-alt"></i>
|
||||||
|
<p>Logout</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item sidebar-bottom" style="bottom: 10px">
|
||||||
|
<a href="#">
|
||||||
|
<i class="avatar"></i>
|
||||||
|
<p>{{.name}}</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,94 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Tickets | A Discord Support Manager Bot</title>
|
|
||||||
|
|
||||||
<!-- Meta -->
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
||||||
<meta name="description" content="Management panel for the Discord Tickets bot">
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
|
||||||
<link rel="icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
|
||||||
|
|
||||||
<!-- Custom CSS -->
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Open Sans',sans-serif !important;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background: url("/assets/img/sidebar-2.jpg");
|
|
||||||
background-size: cover;
|
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-bottom {
|
|
||||||
position: absolute !important;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
background: url("{{avatar}}?size=32");
|
|
||||||
width: 28px;
|
|
||||||
height: 29px;
|
|
||||||
display: block;
|
|
||||||
background-size: cover;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
|
||||||
<link href="/assets/css/light-bootstrap-dashboard.css?v=1.4.0" rel="stylesheet"/>
|
|
||||||
<link href="/assets/css/animate.min.css" rel="stylesheet"/>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<!-- Icons -->
|
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="sidebar" data-color="orange" data-image="/assets/img/sidebar-2.jpg">
|
|
||||||
<div class="sidebar-wrapper">
|
|
||||||
<div class="logo">
|
|
||||||
<a href="https://ticketsbot.net" class="simple-text">
|
|
||||||
TicketsBot
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="nav">
|
|
||||||
<li class="nav-item sidebar-bottom">
|
|
||||||
<a href="/">
|
|
||||||
<i class="fas fa-server"></i>
|
|
||||||
<p>Servers</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="nav-item sidebar-bottom" style="bottom: 60px">
|
|
||||||
<a href="/logout">
|
|
||||||
<i class="fas fa-sign-out-alt"></i>
|
|
||||||
<p>Logout</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item sidebar-bottom" style="bottom: 10px">
|
|
||||||
<a href="#">
|
|
||||||
<i class="avatar"></i>
|
|
||||||
<p>{{name}}</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="main-panel">
|
|
||||||
{{{content}}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
14
public/templates/layouts/main.tmpl
Normal file
14
public/templates/layouts/main.tmpl
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
{{template "head" .}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
{{template "sidebar" .}}
|
||||||
|
<div class="main-panel">
|
||||||
|
{{template "content" .}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,131 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Tickets | A Discord Support Manager Bot</title>
|
|
||||||
|
|
||||||
<!-- Meta -->
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
||||||
<meta name="description" content="Management panel for the Discord Tickets bot">
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
|
||||||
<link rel="icon" href="/assets/img/favicon.ico" type="image/x-icon">
|
|
||||||
|
|
||||||
<!-- Custom CSS -->
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Open Sans',sans-serif !important;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background: url("/assets/img/sidebar-2.jpg");
|
|
||||||
background-size: cover;
|
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-bottom {
|
|
||||||
position: absolute !important;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
background: url("{{avatar}}?size=32");
|
|
||||||
width: 28px;
|
|
||||||
height: 29px;
|
|
||||||
display: block;
|
|
||||||
background-size: cover;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filterCard {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table td, .table th {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
|
||||||
<link href="/assets/css/light-bootstrap-dashboard.css?v=1.4.0" rel="stylesheet"/>
|
|
||||||
<link href="/assets/css/animate.min.css" rel="stylesheet"/>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
{{#include_mock}}
|
|
||||||
<!-- Discord theme -->
|
|
||||||
<link href="/assets/css/discordmock.css" rel="stylesheet"/>
|
|
||||||
{{/include_mock}}
|
|
||||||
|
|
||||||
<!-- Icons -->
|
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="sidebar" data-color="orange" data-image="/assets/img/sidebar-2.jpg">
|
|
||||||
<div class="sidebar-wrapper">
|
|
||||||
<div class="logo">
|
|
||||||
<a href="https://ticketsbot.net" class="simple-text">
|
|
||||||
TicketsBot
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="nav">
|
|
||||||
<li class="nav-item sidebar-bottom">
|
|
||||||
<a href="/">
|
|
||||||
<i class="fas fa-server"></i>
|
|
||||||
<p>Servers</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="nav-item sidebar-bottom" style="bottom: 60px">
|
|
||||||
<a href="/logout">
|
|
||||||
<i class="fas fa-sign-out-alt"></i>
|
|
||||||
<p>Logout</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item sidebar-bottom" style="bottom: 10px">
|
|
||||||
<a href="#">
|
|
||||||
<i class="avatar"></i>
|
|
||||||
<p>{{name}}</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="main-panel">
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/manage/{{guildId}}/settings">Settings</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/manage/{{guildId}}/logs/page/1">Logs</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/manage/{{guildId}}/blacklist">Blacklist</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/manage/{{guildId}}/tickets">Ticket List</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
{{{content}}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
16
public/templates/layouts/manage.tmpl
Normal file
16
public/templates/layouts/manage.tmpl
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
{{template "head" .}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
{{template "sidebar" .}}
|
||||||
|
|
||||||
|
<div class="main-panel">
|
||||||
|
{{template "navbar" .}}
|
||||||
|
{{template "content" .}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,113 +0,0 @@
|
|||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">Blacklisted Users</h4>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="card-body table-responsive">
|
|
||||||
<div id="accordion">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header collapsed filterCard" id="addBlacklistHeader" data-toggle="collapse" data-target="#addBlacklist" aria-expanded="false" aria-controls="addBlacklist">
|
|
||||||
<span class="align-middle" data-toggle="collapse" data-target="#addBlacklist" aria-expanded="false" aria-controls="addBlacklist">
|
|
||||||
<i class="fas fa-plus"></i> Add New User
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="addBlacklist" class="collapse" aria-labelledby="addBlacklistHeader" data-parent="#accordion">
|
|
||||||
<div class="card-body">
|
|
||||||
<form>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 pr-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Username</label>
|
|
||||||
<input name="username" type="text" class="form-control" placeholder="Username">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-1 px-1">
|
|
||||||
<label>Discriminator</label>
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<div class="input-group-text">#</div>
|
|
||||||
</div>
|
|
||||||
<input name="discrim" type="text" class="form-control" placeholder="0000">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input name="csrf" type="hidden" value="{{csrf}}">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary mx-auto"><i class="fas fa-paper-plane"></i> Submit</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="table table-hover table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>User ID</th>
|
|
||||||
<th>Username#Discrim</th>
|
|
||||||
<th>Remove</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#blacklisted}}
|
|
||||||
<tr>
|
|
||||||
<td>{{userId}}</td>
|
|
||||||
<td>{{username}}#{{discrim}}</td>
|
|
||||||
<td><a href="{{baseUrl}}/manage/{{guildId}}/blacklist/remove/{{userId}}?c={{csrf}}">Remove</a></td>
|
|
||||||
</tr>
|
|
||||||
{{/blacklisted}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
|
||||||
<div style="position: absolute; right: 10px; min-width: 300px">
|
|
||||||
{{#userNotFound}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Warning</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
The user you specified couldn't be found
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/userNotFound}}
|
|
||||||
{{#isStaff}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Warning</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
You cannot blacklist a staff member
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/isStaff}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
</script>
|
|
||||||
</div>
|
|
115
public/templates/views/blacklist.tmpl
Normal file
115
public/templates/views/blacklist.tmpl
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
{{define "content"}}
|
||||||
|
<div class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="card-title">Blacklisted Users</h4>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-body table-responsive">
|
||||||
|
<div id="accordion">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header collapsed filterCard" id="addBlacklistHeader" data-toggle="collapse" data-target="#addBlacklist" aria-expanded="false" aria-controls="addBlacklist">
|
||||||
|
<span class="align-middle" data-toggle="collapse" data-target="#addBlacklist" aria-expanded="false" aria-controls="addBlacklist">
|
||||||
|
<i class="fas fa-plus"></i> Add New User
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div id="addBlacklist" class="collapse" aria-labelledby="addBlacklistHeader" data-parent="#accordion">
|
||||||
|
<div class="card-body">
|
||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Username</label>
|
||||||
|
<input name="username" type="text" class="form-control" placeholder="Username">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1 px-1">
|
||||||
|
<label>Discriminator</label>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text">#</div>
|
||||||
|
</div>
|
||||||
|
<input name="discrim" type="text" class="form-control" placeholder="0000">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input name="csrf" type="hidden" value="{{.csrf}}">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary mx-auto"><i class="fas fa-paper-plane"></i> Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>User ID</th>
|
||||||
|
<th>Username#Discrim</th>
|
||||||
|
<th>Remove</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .blacklisted}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.userId}}</td>
|
||||||
|
<td>{{.username}}#{{.discrim}}</td>
|
||||||
|
<td><a href="/manage/{{$.guildId}}/blacklist/remove/{{.userId}}?c={{$.csrf}}">Remove</a></td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
||||||
|
<div style="position: absolute; right: 10px; min-width: 300px">
|
||||||
|
{{if .userNotFound}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Warning</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
The user you specified couldn't be found
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{if .isStaff}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Warning</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
You cannot blacklist a staff member
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('.toast').toast('show');
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,45 +0,0 @@
|
|||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">Servers</h4>
|
|
||||||
{{^empty}}
|
|
||||||
<p class="card-category">Select a server to manage below</p>
|
|
||||||
{{/empty}}
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
{{#empty}}
|
|
||||||
<p class="center-align" style="padding-top: 50px; font-size: 16px">
|
|
||||||
You are not the admin of any guilds that the bot is in. Click below to invite the bot:
|
|
||||||
<br />
|
|
||||||
<a href="https://invite.ticketsbot.net">Invite</a>
|
|
||||||
</p>
|
|
||||||
{{/empty}}
|
|
||||||
{{^empty}}
|
|
||||||
<div class="card-body table-responsive">
|
|
||||||
<table class="table table-hover table-striped">
|
|
||||||
<thead>
|
|
||||||
<th>Server Name</th>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#servers}}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="/manage/{{serverid}}/settings">
|
|
||||||
{{servername}}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{/servers}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{{/empty}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
46
public/templates/views/index.tmpl
Normal file
46
public/templates/views/index.tmpl
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{{define "content"}}
|
||||||
|
<div class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="card-title">Servers</h4>
|
||||||
|
{{if .empty}}
|
||||||
|
<p class="card-category">Select a server to manage below</p>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{{if .empty}}
|
||||||
|
<p class="center-align" style="padding-top: 50px; font-size: 16px">
|
||||||
|
You are not the admin of any guilds that the bot is in. Click below to invite the bot:
|
||||||
|
<br/>
|
||||||
|
<a href="https://invite.ticketsbot.net">Invite</a>
|
||||||
|
</p>
|
||||||
|
{{else}}
|
||||||
|
<div class="card-body table-responsive">
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<th>Server Name</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .servers}}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="/manage/{{.Id}}/settings">
|
||||||
|
{{.Name}}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,100 +0,0 @@
|
|||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div id="accordion">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header collapsed filterCard" id="filterHeader" data-toggle="collapse" data-target="#filterLogs" aria-expanded="false" aria-controls="filterLogs">
|
|
||||||
<span class="align-middle" data-toggle="collapse" data-target="#filterLogs" aria-expanded="false" aria-controls="filterLogs">
|
|
||||||
<i class="fas fa-search"></i> Filter Logs
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="filterLogs" class="collapse" aria-labelledby="filterHeader" data-parent="#accordion">
|
|
||||||
<div class="card-body">
|
|
||||||
<form action="/manage/{[guildId}}/logs/page/1">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 pr-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Ticket ID</label>
|
|
||||||
<input name="ticketid" type="text" class="form-control" placeholder="Ticket ID">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Username</label>
|
|
||||||
<input name="username" type="text" class="form-control" placeholder="Username">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>User ID</label>
|
|
||||||
<input name="userid" type="text" class="form-control" placeholder="User ID">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary mx-auto"><i class="fas fa-paper-plane"></i> Filter</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">Logs</h4>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="card-body table-responsive">
|
|
||||||
<table class="table table-hover table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Ticket ID</th>
|
|
||||||
<th>Username</th>
|
|
||||||
<th>User ID</th>
|
|
||||||
<th>Log URL</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#logs}}
|
|
||||||
<tr>
|
|
||||||
<td>{{ticketid}}</td>
|
|
||||||
<td>{{username}}</td>
|
|
||||||
<td>{{userid}}</td>
|
|
||||||
<td><a href="{{baseUrl}}/manage/{{guildId}}/logs/view/{{uuid}}">{{uuid}}</a></td>
|
|
||||||
</tr>
|
|
||||||
{{/logs}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<ul class="pagination justify-content-center">
|
|
||||||
{{#isPageOne}}
|
|
||||||
<li class="disabled"><a href="#"><i class="fas fa-chevron-left"></i></a></li>
|
|
||||||
{{/isPageOne}}
|
|
||||||
{{^isPageOne}}
|
|
||||||
<li class="waves-effect"><a href="/manage/{{guildId}}/logs/page/{{previousPage}}"><i class="fas fa-chevron-left"></i></a></li>
|
|
||||||
{{/isPageOne}}
|
|
||||||
|
|
||||||
<p class="center-align" style="padding-left: 10px; padding-right: 10px;">Page {{page}}</p>
|
|
||||||
|
|
||||||
<li class="waves-effect"><a href="/manage/{{guildId}}/logs/page/{{nextPage}}"><i class="fas fa-chevron-right"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
100
public/templates/views/logs.tmpl
Normal file
100
public/templates/views/logs.tmpl
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
{{define "content"}}
|
||||||
|
<div class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div id="accordion">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header collapsed filterCard" id="filterHeader" data-toggle="collapse" data-target="#filterLogs" aria-expanded="false" aria-controls="filterLogs">
|
||||||
|
<span class="align-middle" data-toggle="collapse" data-target="#filterLogs" aria-expanded="false" aria-controls="filterLogs">
|
||||||
|
<i class="fas fa-search"></i> Filter Logs
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div id="filterLogs" class="collapse" aria-labelledby="filterHeader" data-parent="#accordion">
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="/manage/{{.guildId}}/logs/page/1">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Ticket ID</label>
|
||||||
|
<input name="ticketid" type="text" class="form-control" placeholder="Ticket ID">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Username</label>
|
||||||
|
<input name="username" type="text" class="form-control" placeholder="Username">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>User ID</label>
|
||||||
|
<input name="userid" type="text" class="form-control" placeholder="User ID">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary mx-auto"><i class="fas fa-paper-plane"></i> Filter</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="card-title">Logs</h4>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-body table-responsive">
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Ticket ID</th>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>User ID</th>
|
||||||
|
<th>Log URL</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .logs}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.ticketid}}</td>
|
||||||
|
<td>{{.username}}</td>
|
||||||
|
<td>{{.userid}}</td>
|
||||||
|
<td><a href="/manage/{{$.guildId}}/logs/view/{{.uuid}}">{{.uuid}}</a></td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<ul class="pagination justify-content-center">
|
||||||
|
{{if .isPageOne}}
|
||||||
|
<li class="disabled"><a href="#"><i class="fas fa-chevron-left"></i></a></li>
|
||||||
|
{{else}}
|
||||||
|
<li class="waves-effect"><a href="/manage/{{.guildId}}/logs/page/{{.previousPage}}"><i class="fas fa-chevron-left"></i></a></li>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<p class="center-align" style="padding-left: 10px; padding-right: 10px;">Page {{.page}}</p>
|
||||||
|
<li class="waves-effect"><a href="/manage/{{.guildId}}/logs/page/{{.nextPage}}"><i class="fas fa-chevron-right"></i></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,165 +0,0 @@
|
|||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">
|
|
||||||
<h4 class="card-title">Settings</h4>
|
|
||||||
{{^empty}}
|
|
||||||
<p class="card-category">Select a server to manage below</p>
|
|
||||||
{{/empty}}
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-5 pr-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Prefix (Max len. 8)</label>
|
|
||||||
<input name="prefix" type="text" class="form-control" placeholder="t!" value="{{prefix}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Ticket Limit (1-10)</label>
|
|
||||||
<input name="ticketlimit" type="text" class="form-control" placeholder="5" value="{{ticketLimit}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Ping @everyone on ticket open</label>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" name="pingeveryone" value="on" {{#pingEveryone}}checked{{/pingEveryone}} style="width:30px;height:30px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<label>Welcome Message (Max len. 1000)</label>
|
|
||||||
<textarea name="welcomeMessage" class="form-control" rows="3" style="resize: none">{{welcomeMessage}}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-5 pr-1">
|
|
||||||
<label>Archive Channel</label>
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<div class="input-group-text">#</div>
|
|
||||||
</div>
|
|
||||||
<select class="form-control" name="archivechannel">
|
|
||||||
{{#channels}}
|
|
||||||
<option {{#active}}selected{{/active}} value="{{channelid}}">{{channelname}}</option>
|
|
||||||
{{/channels}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-5 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Channel Category</label>
|
|
||||||
<select class="form-control" name="category">
|
|
||||||
{{#categories}}
|
|
||||||
<option {{#active}}selected{{/active}} value="{{categoryid}}">{{categoryname}}</option>
|
|
||||||
{{/categories}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-2 px-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Allow users to close tickets</label>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" name="userscanclose" value="on" {{#usersCanClose}}checked{{/usersCanClose}} style="width:30px;height:30px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 pr-1">
|
|
||||||
<label>Panel Title</label>
|
|
||||||
<input name="paneltitle" type="text" class="form-control" placeholder="Open A Ticket" value="{{paneltitle}}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6 pr-1">
|
|
||||||
<label>Panel Content</label>
|
|
||||||
<input name="panelcontent" type="text" class="form-control" placeholder="React with :envelope_with_arrow: to open a ticket" value="{{panelcontent}}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3 pr-1">
|
|
||||||
<label>Panel Colour (Hex)</label>
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<div class="input-group-text">#</div>
|
|
||||||
</div>
|
|
||||||
<input name="panelcolour" type="text" class="form-control" placeholder="23A31A" value="{{panelcolour}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input name="csrf" type="hidden" value="{{csrf}}">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-1 pr-1">
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i> Submit</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
|
||||||
<div style="position: absolute; right: 10px; min-width: 300px">
|
|
||||||
{{#invalidPrefix}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Warning</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
The prefix you specified was invalid
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/invalidPrefix}}
|
|
||||||
{{#invalidWelcomeMessage}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Warning</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
The welcome message you specified was invalid
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/invalidWelcomeMessage}}
|
|
||||||
{{#invalidTicketLimit}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Warning</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
The ticketLimit you specified was invalid
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/invalidTicketLimit}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
$('#pingeveryone').prop('indeterminate', {{pingEveryone}});
|
|
||||||
</script>
|
|
||||||
</div>
|
|
167
public/templates/views/settings.tmpl
Normal file
167
public/templates/views/settings.tmpl
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
{{define "content"}}
|
||||||
|
<div class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="card-title">Settings</h4>
|
||||||
|
{{if .empty}}
|
||||||
|
<p class="card-category">Select a server to manage below</p>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Prefix (Max len. 8)</label>
|
||||||
|
<input name="prefix" type="text" class="form-control" placeholder="t!" value="{{.prefix}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Ticket Limit (1-10)</label>
|
||||||
|
<input name="ticketlimit" type="text" class="form-control" placeholder="5" value="{{.ticketLimit}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Ping @everyone on ticket open</label>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" name="pingeveryone" value="on" {{if .pingEveryone}}checked{{end}} style="width:30px;height:30px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label>Welcome Message (Max len. 1000)</label>
|
||||||
|
<textarea name="welcomeMessage" class="form-control" rows="3" style="resize: none">{{.welcomeMessage}}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5 pr-1">
|
||||||
|
<label>Archive Channel</label>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text">#</div>
|
||||||
|
</div>
|
||||||
|
<select class="form-control" name="archivechannel">
|
||||||
|
{{range .channels}}
|
||||||
|
<option {{if .active}}selected{{end}} value="{{.channelid}}">{{.channelname}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-5 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Channel Category</label>
|
||||||
|
<select class="form-control" name="category">
|
||||||
|
{{range .categories}}
|
||||||
|
<option {{if .active}}selected{{end}} value="{{.categoryid}}">{{.categoryname}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2 px-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Allow users to close tickets</label>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" name="userscanclose" value="on" {{if .usersCanClose}}checked{{end}} style="width:30px;height:30px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 pr-1">
|
||||||
|
<label>Panel Title</label>
|
||||||
|
<input name="paneltitle" type="text" class="form-control" placeholder="Open A Ticket" value="{{.paneltitle}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 pr-1">
|
||||||
|
<label>Panel Content</label>
|
||||||
|
<input name="panelcontent" type="text" class="form-control" placeholder="React with :envelope_with_arrow: to open a ticket" value="{{.panelcontent}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3 pr-1">
|
||||||
|
<label>Panel Colour (Hex)</label>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text">#</div>
|
||||||
|
</div>
|
||||||
|
<input name="panelcolour" type="text" class="form-control" placeholder="23A31A" value="{{.panelcolour}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input name="csrf" type="hidden" value="{{.csrf}}">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-1 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i> Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
||||||
|
<div style="position: absolute; right: 10px; min-width: 300px">
|
||||||
|
{{if .invalidPrefix}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Warning</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
The prefix you specified was invalid
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{if .invalidWelcomeMessage}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Warning</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
The welcome message you specified was invalid
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{if .invalidTicketLimit}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Warning</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
The ticketLimit you specified was invalid
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('.toast').toast('show');
|
||||||
|
$('#pingeveryone').prop('indeterminate', {{.pingEveryone}});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -1,3 +1,4 @@
|
|||||||
|
{{define "content"}}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -18,14 +19,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#tickets}}
|
{{range .tickets}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ticketId}}</td>
|
<td>{{.ticketId}}</td>
|
||||||
<td>{{username}}#{{discrim}}</td>
|
<td>{{.username}}#{{.discrim}}</td>
|
||||||
<td>{{#members}}{{username}}#{{discrim}}{{sep}}{{/members}}</td>
|
<td>{{range .members}}{{.username}}#{{.discrim}}{{.sep}}{{end}}</td>
|
||||||
<td><a class="btn btn-primary btn-sm" role="button" href="/manage/{{guildId}}/tickets/view/{{uuid}}">View</a></td>
|
<td><a class="btn btn-primary btn-sm" role="button" href="/manage/{{$.guildId}}/tickets/view/{{.uuid}}">View</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/tickets}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -39,3 +40,4 @@
|
|||||||
$('.toast').toast('show');
|
$('.toast').toast('show');
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
@ -1,109 +0,0 @@
|
|||||||
<div class="content">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="discord-container">
|
|
||||||
<div class="channel-header">
|
|
||||||
<span class="channel-name">#ticket-{{ticketId}}</span>
|
|
||||||
</div>
|
|
||||||
<div id="message-container">
|
|
||||||
{{#messages}}
|
|
||||||
<div class="message">
|
|
||||||
<b>{{username}}</b>
|
|
||||||
{{content}}
|
|
||||||
</div>
|
|
||||||
{{/messages}}
|
|
||||||
</div>
|
|
||||||
<div class="input-container">
|
|
||||||
<form action="javascript:sendMessage()">
|
|
||||||
{{#premium}}
|
|
||||||
<input type="text" class="form-control message-input" id="message" name="message"
|
|
||||||
placeholder="Message #ticket-{{ticketId}}">
|
|
||||||
{{/premium}}
|
|
||||||
{{^premium}}
|
|
||||||
<input type="text" class="form-control message-input" id="message" name="message"
|
|
||||||
placeholder="Premium users get live messages and can respond through webchat" disabled>
|
|
||||||
{{/premium}}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
|
||||||
<div style="position: absolute; right: 10px; min-width: 300px">
|
|
||||||
{{#isError}}
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
<strong class="mr-auto">Error</strong>
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
{{error}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/isError}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
</script>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Scroll to bottom
|
|
||||||
let container = document.getElementById("message-container");
|
|
||||||
container.scrollTop = container.scrollHeight;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{{#premium}}
|
|
||||||
<script>
|
|
||||||
ws = new WebSocket("wss://panel.ticketsbot.net/webchat");
|
|
||||||
|
|
||||||
ws.onopen = (evt) => {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
"type": "auth",
|
|
||||||
"data": {
|
|
||||||
"guild": "{{guildId}}",
|
|
||||||
"ticket": "{{ticketId}}"
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = (evt) => {
|
|
||||||
let data = JSON.parse(evt.data);
|
|
||||||
|
|
||||||
let container = document.getElementById("message-container");
|
|
||||||
|
|
||||||
let element = document.createElement("div");
|
|
||||||
element.className = "message";
|
|
||||||
element.innerHTML = `
|
|
||||||
<b>${data.username}</b>
|
|
||||||
${data.content}
|
|
||||||
`;
|
|
||||||
|
|
||||||
container.appendChild(element);
|
|
||||||
|
|
||||||
// Scroll to bottom
|
|
||||||
container.scrollTop = container.scrollHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
function sendMessage() {
|
|
||||||
let msg = document.getElementById("message").value;
|
|
||||||
document.getElementById("message").value = "";
|
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
"type": "send",
|
|
||||||
"data": msg
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{{/premium}}
|
|
110
public/templates/views/ticketview.tmpl
Normal file
110
public/templates/views/ticketview.tmpl
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
{{define "content"}}
|
||||||
|
<div class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="discord-container">
|
||||||
|
<div class="channel-header">
|
||||||
|
<span class="channel-name">#ticket-{{.ticketId}}</span>
|
||||||
|
</div>
|
||||||
|
<div id="message-container">
|
||||||
|
{{range .messages}}
|
||||||
|
<div class="message">
|
||||||
|
<b>{{.username}}</b>
|
||||||
|
{{.content}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
<div class="input-container">
|
||||||
|
<form action="javascript:sendMessage()">
|
||||||
|
{{if .premium}}
|
||||||
|
<input type="text" class="form-control message-input" id="message" name="message"
|
||||||
|
placeholder="Message #ticket-{{.ticketId}}">
|
||||||
|
{{else}}
|
||||||
|
<input type="text" class="form-control message-input" id="message" name="message"
|
||||||
|
placeholder="Premium users get live messages and can respond through webchat" disabled>
|
||||||
|
{{end}}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-live="polite" aria-atomic="true" style="position: relative; min-height: 200px;">
|
||||||
|
<div style="position: absolute; right: 10px; min-width: 300px">
|
||||||
|
{{if .isError}}
|
||||||
|
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false">
|
||||||
|
<div class="toast-header">
|
||||||
|
<strong class="mr-auto">Error</strong>
|
||||||
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
{{.error}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('.toast').toast('show');
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Scroll to bottom
|
||||||
|
let container = document.getElementById("message-container");
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{if .premium}}
|
||||||
|
<script>
|
||||||
|
ws = new WebSocket("wss://panel.ticketsbot.net/webchat");
|
||||||
|
|
||||||
|
ws.onopen = (evt) => {
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
"type": "auth",
|
||||||
|
"data": {
|
||||||
|
"guild": "{{.guildId}}",
|
||||||
|
"ticket": "{{.ticketId}}"
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (evt) => {
|
||||||
|
let data = JSON.parse(evt.data);
|
||||||
|
|
||||||
|
let container = document.getElementById("message-container");
|
||||||
|
|
||||||
|
let element = document.createElement("div");
|
||||||
|
element.className = "message";
|
||||||
|
element.innerHTML = `
|
||||||
|
<b>${data.username}</b>
|
||||||
|
${data.content}
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(element);
|
||||||
|
|
||||||
|
// Scroll to bottom
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
function sendMessage() {
|
||||||
|
let msg = document.getElementById("message").value;
|
||||||
|
document.getElementById("message").value = "";
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
"type": "send",
|
||||||
|
"data": msg
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
@ -1,7 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
func Respond(ctx *gin.Context, s string) {
|
|
||||||
ctx.Data(200, "text/html; charset=utf-8", []byte(s))
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user