use Go templating
This commit is contained in:
parent
5472f20964
commit
7aba0cc253
@ -1,7 +1,6 @@
|
||||
package manage
|
||||
|
||||
import (
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"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),
|
||||
"guildId": guildIdStr,
|
||||
"csrf": store.Get("csrf").(string),
|
||||
@ -104,6 +103,6 @@ func BlacklistHandler(ctx *gin.Context) {
|
||||
"blacklisted": blacklisted,
|
||||
"userNotFound": userNotFound,
|
||||
"isStaff": isStaff,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package manage
|
||||
|
||||
import (
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"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),
|
||||
"guildId": guildIdStr,
|
||||
"avatar": store.Get("avatar").(string),
|
||||
@ -105,7 +104,7 @@ func LogsHandler(ctx *gin.Context) {
|
||||
"nextPage": page + 1,
|
||||
"logs": formattedLogs,
|
||||
"page": page,
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
ctx.Redirect(302, "/login")
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package manage
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"github.com/TicketsBot/GoPanel/utils"
|
||||
@ -254,7 +253,7 @@ func SettingsHandler(ctx *gin.Context) {
|
||||
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),
|
||||
"guildId": guildIdStr,
|
||||
"avatar": store.Get("avatar").(string),
|
||||
@ -272,7 +271,7 @@ func SettingsHandler(ctx *gin.Context) {
|
||||
"panelcontent": panelContent,
|
||||
"panelcolour": strconv.FormatInt(int64(panelColour), 16),
|
||||
"usersCanClose": usersCanClose,
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
ctx.Redirect(302, "/login")
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package manage
|
||||
|
||||
import (
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"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),
|
||||
"guildId": guildIdStr,
|
||||
"csrf": store.Get("csrf").(string),
|
||||
"avatar": store.Get("avatar").(string),
|
||||
"baseUrl": config.Conf.Server.BaseUrl,
|
||||
"tickets": ticketsFormatted,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package manage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"github.com/TicketsBot/GoPanel/utils"
|
||||
@ -108,7 +107,7 @@ func TicketViewHandler(ctx *gin.Context) {
|
||||
premium := make(chan bool)
|
||||
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),
|
||||
"guildId": guildIdStr,
|
||||
"csrf": store.Get("csrf").(string),
|
||||
@ -120,6 +119,6 @@ func TicketViewHandler(ctx *gin.Context) {
|
||||
"ticketId": ticket.TicketId,
|
||||
"include_mock": true,
|
||||
"premium": <-premium,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package root
|
||||
|
||||
import (
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/TicketsBot/GoPanel/database/table"
|
||||
"github.com/TicketsBot/GoPanel/utils"
|
||||
@ -40,24 +39,14 @@ func IndexHandler(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
var servers []map[string]string
|
||||
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{}{
|
||||
ctx.HTML(200, "main/index", gin.H{
|
||||
"name": store.Get("name").(string),
|
||||
"baseurl": config.Conf.Server.BaseUrl,
|
||||
"servers": servers,
|
||||
"empty": len(servers) == 0,
|
||||
"servers": adminGuilds,
|
||||
"empty": len(adminGuilds) == 0,
|
||||
"isIndex": true,
|
||||
"avatar": store.Get("avatar").(string),
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
ctx.Redirect(302, "/login")
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"github.com/TicketsBot/GoPanel/app/http/endpoints/manage"
|
||||
"github.com/TicketsBot/GoPanel/app/http/endpoints/root"
|
||||
"github.com/TicketsBot/GoPanel/app/http/template"
|
||||
"github.com/TicketsBot/GoPanel/config"
|
||||
"github.com/gin-contrib/multitemplate"
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -15,10 +15,6 @@ import (
|
||||
func StartServer() {
|
||||
log.Println("Starting HTTP server")
|
||||
|
||||
// Compile templates
|
||||
template.LoadLayouts()
|
||||
template.LoadTemplates()
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
// Sessions
|
||||
@ -35,45 +31,65 @@ func StartServer() {
|
||||
// Handle static asset requests
|
||||
router.Use(static.Serve("/assets/", static.LocalFile("./public/static", false)))
|
||||
|
||||
// Root
|
||||
// Register templates
|
||||
router.HTMLRender = createRenderer()
|
||||
|
||||
router.GET("/", root.IndexHandler)
|
||||
|
||||
// /login
|
||||
router.GET("/login", root.LoginHandler)
|
||||
|
||||
// /callback
|
||||
router.GET("/callback", root.CallbackHandler)
|
||||
|
||||
// /logout
|
||||
router.GET("/logout", root.LogoutHandler)
|
||||
|
||||
// /manage/:id/settings
|
||||
router.GET("/manage/:id/settings", manage.SettingsHandler)
|
||||
|
||||
// /manage/:id/logs/page/:page
|
||||
router.GET("/manage/:id/logs/page/:page", manage.LogsHandler)
|
||||
|
||||
// /manage/:id/logs/view/:uuid
|
||||
router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler)
|
||||
|
||||
// /manage/:id/blacklist
|
||||
router.GET("/manage/:id/blacklist", manage.BlacklistHandler)
|
||||
|
||||
// /manage/:id/blacklist/remove/:user
|
||||
router.GET("/manage/:id/blacklist/remove/:user", manage.BlacklistRemoveHandler)
|
||||
|
||||
// /manage/:id/tickets
|
||||
router.GET("/manage/:id/tickets", manage.TicketListHandler)
|
||||
|
||||
// /manage/:id/tickets/view/:uuid
|
||||
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.GET("/webchat", manage.WebChatWs)
|
||||
|
||||
if err := router.Run(config.Conf.Server.Host); err != nil {
|
||||
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="container-fluid">
|
||||
<div class="row">
|
||||
@ -18,14 +19,14 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#tickets}}
|
||||
{{range .tickets}}
|
||||
<tr>
|
||||
<td>{{ticketId}}</td>
|
||||
<td>{{username}}#{{discrim}}</td>
|
||||
<td>{{#members}}{{username}}#{{discrim}}{{sep}}{{/members}}</td>
|
||||
<td><a class="btn btn-primary btn-sm" role="button" href="/manage/{{guildId}}/tickets/view/{{uuid}}">View</a></td>
|
||||
<td>{{.ticketId}}</td>
|
||||
<td>{{.username}}#{{.discrim}}</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>
|
||||
</tr>
|
||||
{{/tickets}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -39,3 +40,4 @@
|
||||
$('.toast').toast('show');
|
||||
</script>
|
||||
</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