Finish redesign

This commit is contained in:
Dot-Rar 2019-05-26 14:49:35 +01:00
parent 208bdc03f3
commit e85a607b97
12 changed files with 464 additions and 140 deletions

View File

@ -98,6 +98,7 @@ func LogsHandler(ctx *gin.Context) {
utils.Respond(ctx, template.TemplateLogs.Render(map[string]interface{}{
"name": store.Get("name").(string),
"guildId": guildIdStr,
"avatar": store.Get("avatar").(string),
"baseUrl": config.Conf.Server.BaseUrl,
"isPageOne": page == 1,
"previousPage": page - 1,

View File

@ -3,7 +3,6 @@ package manage
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/TicketsBot/GoPanel/app/http/template"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
@ -54,9 +53,12 @@ func SettingsHandler(ctx *gin.Context) {
return
}
// Get CSRF token
csrfCorrect := ctx.Query("csrf") == store.Get("csrf").(string)
// Get prefix
prefix := ctx.Query("prefix")
if prefix == "" {
if prefix == "" || len(prefix) > 8 || !csrfCorrect {
prefix = table.GetPrefix(guildId)
} else {
table.UpdatePrefix(guildId, prefix)
@ -64,7 +66,7 @@ func SettingsHandler(ctx *gin.Context) {
// Get welcome message
welcomeMessage := ctx.Query("welcomeMessage")
if welcomeMessage == "" {
if welcomeMessage == "" || len(welcomeMessage) > 1000 || !csrfCorrect {
welcomeMessage = table.GetWelcomeMessage(guildId)
} else {
table.UpdateWelcomeMessage(guildId, welcomeMessage)
@ -80,8 +82,13 @@ func SettingsHandler(ctx *gin.Context) {
}
// Update limit, or get current limit if user input is invalid
if limitStr == "" || !utils.IsInt(limitStr) {
invalidTicketLimit := false
if limitStr == "" || !utils.IsInt(limitStr) || limit > 10 || limit < 1 || !csrfCorrect {
limit = table.GetTicketLimit(guildId)
if limitStr != "" { // User wasn't setting anything
invalidTicketLimit = true
}
} else {
table.UpdateTicketLimit(guildId, limit)
}
@ -120,11 +127,13 @@ func SettingsHandler(ctx *gin.Context) {
if err != nil {
log.Error(err.Error())
} else {
if csrfCorrect {
table.UpdateGuilds(userIdStr, base64.StdEncoding.EncodeToString(marshalled))
}
}
}
}
}
// Get a list of actual category IDs
categories := guild.GetCategories()
@ -144,7 +153,7 @@ func SettingsHandler(ctx *gin.Context) {
}
// Update category, or get current category if user input is invalid
if categoryStr == "" || !utils.IsInt(categoryStr) || !utils.Contains(categoryIds, categoryStr) {
if categoryStr == "" || !utils.IsInt(categoryStr) || !utils.Contains(categoryIds, categoryStr) || !csrfCorrect {
category = table.GetChannelCategory(guildId)
} else {
table.UpdateChannelCategory(guildId, category)
@ -175,7 +184,7 @@ func SettingsHandler(ctx *gin.Context) {
archiveChannel, _ = strconv.ParseInt(archiveChannelStr, 10, 64)
}
if archiveChannelStr == "" || !utils.IsInt(archiveChannelStr) || !utils.Contains(channelIds, archiveChannelStr) {
if archiveChannelStr == "" || !utils.IsInt(archiveChannelStr) || !utils.Contains(channelIds, archiveChannelStr) || !csrfCorrect {
archiveChannel = table.GetArchiveChannel(guildId)
} else {
table.UpdateArchiveChannel(guildId, archiveChannel)
@ -184,9 +193,6 @@ func SettingsHandler(ctx *gin.Context) {
// Format channels for templating
var formattedChannels []map[string]interface{}
for _, c := range guild.Channels {
if c.Id == strconv.Itoa(int(archiveChannel)) {
fmt.Println(c.Name)
}
if c.Type == 0 {
formattedChannels = append(formattedChannels, map[string]interface{}{
"channelid": c.Id,
@ -199,11 +205,16 @@ func SettingsHandler(ctx *gin.Context) {
utils.Respond(ctx, template.TemplateSettings.Render(map[string]interface{}{
"name": store.Get("name").(string),
"guildId": guildIdStr,
"avatar": store.Get("avatar").(string),
"prefix": prefix,
"welcomeMessage": welcomeMessage,
"ticketLimit": limit,
"categories": formattedCategories,
"channels": formattedChannels,
"invalidPrefix": len(ctx.Query("prefix")) > 8,
"invalidWelcomeMessage": len(ctx.Query("welcomeMessage")) > 1000,
"invalidTicketLimit": invalidTicketLimit,
"csrf": store.Get("csrf").(string),
}))
} else {
ctx.Redirect(302, "/login")

View File

@ -3,6 +3,7 @@ package root
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
"github.com/TicketsBot/GoPanel/utils"
@ -69,8 +70,11 @@ func CallbackHandler(ctx *gin.Context) {
return
}
store.Set("csrf", utils.RandStringRunes(32))
store.Set("userid", currentUser.Id)
store.Set("name", currentUser.Username)
store.Set("avatar", fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.webp", currentUser.Id, currentUser.Avatar))
if err = store.Save(); err != nil {
log.Error(err.Error())
}

View File

@ -55,6 +55,8 @@ func IndexHandler(ctx *gin.Context) {
"baseurl": config.Conf.Server.BaseUrl,
"servers": servers,
"empty": len(servers) == 0,
"isIndex": true,
"avatar": store.Get("avatar").(string),
}))
} else {
ctx.Redirect(302, "/login")

View File

@ -16,6 +16,7 @@ type Template struct {
var (
LayoutMain Layout
LayoutManage Layout
TemplateIndex Template
TemplateLogs Template
@ -30,6 +31,9 @@ func LoadLayouts() {
LayoutMain = Layout{
compiled: loadLayout("main"),
}
LayoutManage = Layout{
compiled: loadLayout("manage"),
}
}
func LoadTemplates() {
@ -39,11 +43,11 @@ func LoadTemplates() {
}
TemplateLogs = Template{
compiled: loadTemplate("logs"),
Layout: LayoutMain,
Layout: LayoutManage,
}
TemplateSettings = Template{
compiled: loadTemplate("settings"),
Layout: LayoutMain,
Layout: LayoutManage,
}
}

View File

@ -18,7 +18,6 @@ type (
Host string
BaseUrl string
MainSite string
CsrfKey string
Ratelimit Ratelimit
Session Session
}

View File

@ -12,31 +12,80 @@
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">
<style>
body {
font-family: 'Open Sans',sans-serif;
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>
<!-- Materialize -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" 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>
<!-- 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>
<nav>
<div class="nav-wrapper grey darken-4">
<ul id="nav-mobile" class="left hide-on-med-and-down">
<li><a href="{{mainsite}}">Main Site</a></li>
<li><a href="/">Servers</a></li>
</ul>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><a href="/logout">Logout</a></li>
<li><a href="#">Hi, {{name}}</a></li>
<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>
</nav>
</div>
<div class="main-panel">
{{{content}}}
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,117 @@
<!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">
<!-- 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>
<!-- 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>
</ul>
</div>
</nav>
{{{content}}}
</div>
</div>
</body>
</html>

View File

@ -1,6 +1,15 @@
<div class="container">
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col s12">
<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:
@ -9,16 +18,28 @@
</p>
{{/empty}}
{{^empty}}
<p class="center-align" style="padding-top: 50px; font-size: 16px">
Select a server to manage below
</p>
<ul class="collection">
<div class="card-body table-responsive">
<table class="table table-hover table-striped">
<thead>
<th>Server Name</th>
</thead>
<tbody>
{{#servers}}
<li class="collection-item"><a href="{{baseUrl}}/manage/{{serverid}}/settings">{{servername}}</a></li>
<tr>
<td>
<a href="/manage/{{serverid}}/settings">
{{servername}}
</a>
</td>
</tr>
{{/servers}}
</ul>
</tbody>
</table>
</div>
{{/empty}}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,4 +1,89 @@
<div class="container">
<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>
<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-1">
<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>
</div>
</div>
</div>
</div>
</div>
</div>
<!--<div class="container">
<div class="row">
<div class="col s12">
<ul class="pagination center-align" style="padding-top: 50px">
@ -90,4 +175,4 @@
<script>
M.AutoInit();
</script>
</script>-->

View File

@ -1,100 +1,125 @@
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, {});
});
{{#invalidPrefix}}
M.toast({html: 'Prefixes must be between 1 and 8 characters'});
{{/invalidPrefix}}
{{#invalidMessage}}
M.toast({html: 'Welcome messages must be between 1 and 1000 characters'});
{{/invalidMessage}}
</script>
<div class="container">
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col s12">
<ul class="pagination center-align" style="padding-top: 50px">
<li class="disabled"><a href="#!"><i class="material-icons">chevron_left</i></a></li>
<li class="active indigo darken-1"><a href="#!">Settings</a></li>
<li class="waves-effect"><a href="/manage/{{guildId}}/logs/page/1">Logs</a></li>
<li class="waves-effect"><a href="/manage/{{guildId}}/logs/page/1"><i class="material-icons">chevron_right</i></a></li>
</ul>
<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-6 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>
<form class="col s12" action="/manage/{{guildId}}/settings" method="get">
<div class="row">
<div class="input-field col s12">
<p><b>Prefix</b></p>
<input id="prefix" name="prefix" type="text" class="validate" value="{{prefix}}">
<div class="col-md-6 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>
<div class="row">
<div class="input-field col s12">
<p><b>Welcome Message</b></p>
<textarea id="welcomeMessage" name="welcomeMessage" class="materialize-textarea">{{welcomeMessage}}</textarea>
<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="input-field col s12">
<p><b>Ticket Limit</b></p>
<p class="range-field">
<input type="range" id="ticketlimit" name="ticketlimit" min="1" max="10" value="{{ticketLimit}}" />
</p>
<p id="output">Limit: -1</p>
<div class="col-md-6 pr-1">
<label>Archive Channel</label>
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">#</div>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<p><b>Channel Category</b></p>
<select name="category">
{{#categories}}
{{#active}}
<option value="{{categoryid}}" selected>{{categoryname}}</option>
{{/active}}
{{^active}}
<option value="{{categoryid}}">{{categoryname}}</option>
{{/active}}
{{/categories}}
</select>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<p><b>Archive Channel</b></p>
<select name="archivechannel">
<select class="form-control" name="archivechannel">
{{#channels}}
{{#active}}
<option value="{{channelid}}" selected>#{{channelname}}</option>
{{/active}}
{{^active}}
<option value="{{channelid}}">#{{channelname}}</option>
{{/active}}
<option {{#active}}selected{{/active}} value="{{channelname}}">{{channelname}}</option>
{{/channels}}
</select>
</div>
</div>
<div class="col-md-6 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>
<input name="csrf" type="hidden" value="{{csrf}}">
<div class="row">
<div class="col s12 center-align">
<button class="btn waves-effect waves-light indigo darken-1" type="submit" name="action">Save
<i class="material-icons right">send</i>
</button>
<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>
<script>
var slider = document.getElementById("ticketlimit");
var output = document.getElementById("output");
output.innerHTML = "Limit: " + slider.value;
slider.oninput = () => {
output.innerHTML = "Limit: " + slider.value;
}
</script>
<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">&times;</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">&times;</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">&times;</span>
</button>
</div>
<div class="toast-body">
The ticketLimit you specified was invalid
</div>
</div>
{{/invalidTicketLimit}}
</div>
</div>
<script>
$('.toast').toast('show')
</script>
</div>

View File

@ -6,7 +6,13 @@ import (
)
func IsLoggedIn(store sessions.Session) bool {
return store.Get("access_token") != nil && store.Get("expiry") != nil && store.Get("refresh_token") != nil && store.Get("userid") != nil && store.Get("name") != nil
return store.Get("access_token") != nil &&
store.Get("expiry") != nil &&
store.Get("refresh_token") != nil &&
store.Get("userid") != nil &&
store.Get("name") != nil &&
store.Get("avatar") != nil &&
store.Get("csrf") != nil
}
func GetUserId(store sessions.Session) (int64, error) {