Merge branch 'master' of github.com:devict/ictgj-voting
This commit is contained in:
commit
d4107d9c16
@ -141,9 +141,15 @@ func handleAdminVotes(w http.ResponseWriter, req *http.Request, page *pageData)
|
||||
Results []Ranking
|
||||
}
|
||||
vpd := new(votePageData)
|
||||
now := time.Now()
|
||||
dayThresh := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
for i := range m.jam.Votes {
|
||||
v := new(vpdVote)
|
||||
v.Timestamp = m.jam.Votes[i].Timestamp.Format(time.RFC3339)
|
||||
if m.jam.Votes[i].Timestamp.Before(dayThresh) {
|
||||
v.Timestamp = m.jam.Votes[i].Timestamp.Format("Jan _2 15:04")
|
||||
} else {
|
||||
v.Timestamp = m.jam.Votes[i].Timestamp.Format(time.Kitchen)
|
||||
}
|
||||
v.ClientId = m.jam.Votes[i].ClientId
|
||||
for _, choice := range m.jam.Votes[i].Choices {
|
||||
for _, fndTm := range m.jam.Teams {
|
||||
|
@ -1,7 +1,3 @@
|
||||
div.content {
|
||||
margin-left: 150px;
|
||||
}
|
||||
|
||||
div.bottom-space {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
@ -122,11 +122,13 @@ div.horizontal-scroll {
|
||||
|
||||
img.thumbnail {
|
||||
height: 100px;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.thumbnail-container {
|
||||
display: block;
|
||||
height: 120px;
|
||||
height: 100%;
|
||||
background-color: #EEE;
|
||||
padding-top: 20px;
|
||||
}
|
||||
@ -228,7 +230,8 @@ table tfoot {
|
||||
}
|
||||
|
||||
#modal-overlay>div {
|
||||
width: 500px;
|
||||
margin: 10% 10%;
|
||||
width: 80%;
|
||||
margin: 100px auto;
|
||||
background-color: #FFF;
|
||||
border: 1px solid #000;
|
||||
@ -242,6 +245,11 @@ div#embiggenedScreenShot {
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
div#embiggenedScreenShot>img{
|
||||
max-width:100%;
|
||||
max-height:100%;
|
||||
}
|
||||
|
||||
div.fullscreen {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@ -304,21 +312,46 @@ input.larger {
|
||||
background-color: #229af9;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small Screens */
|
||||
@media screen and (max-width:35.5em) {
|
||||
div.pure-control-group label.control-label {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width:64em) and (min-width: 48em) {
|
||||
div.pure-control-group label.control-label {
|
||||
text-align: left;
|
||||
.only-large {
|
||||
display: none;
|
||||
}
|
||||
.only-small {
|
||||
display: default;
|
||||
}
|
||||
.team-management-buttons {
|
||||
text-align:left;
|
||||
}
|
||||
.team-management-buttons>.pure-button {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Starting at Small, horizontal */
|
||||
@media screen and (min-width: 35.5em) {
|
||||
div.content {
|
||||
margin-left: 150px;
|
||||
}
|
||||
div.pure-control-group label.control-label {
|
||||
text-align: left;
|
||||
}
|
||||
.only-small {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small Horizontal to Medium */
|
||||
@media screen and (min-width: 35.5em) and (max-width: 48em) { }
|
||||
|
||||
/* Medium Screens */
|
||||
@media screen and (min-width: 48em) and (max-width:64em) { }
|
||||
|
||||
/* Larger Screens */
|
||||
@media (min-width: 64em) { }
|
||||
|
||||
|
@ -1,3 +1,26 @@
|
||||
(function(){
|
||||
document.onkeydown = function(evt) {
|
||||
evt = evt || window.event;
|
||||
var isEscape = false;
|
||||
if("key" in evt) {
|
||||
isEscape = (evt.key == "Escape" || evt.key == "Esc");
|
||||
} else {
|
||||
isEscape = (evt.keyCode == 27);
|
||||
}
|
||||
if(isEscape) {
|
||||
toggleAdminPanel();
|
||||
}
|
||||
}
|
||||
document.querySelector('.menu-button').onclick = function() {
|
||||
var mnu = document.querySelector('#menu .menu-container');
|
||||
if(mnu.style.display == 'inline-block') {
|
||||
mnu.style.display = 'none';
|
||||
} else {
|
||||
mnu.style.display = 'inline-block';
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
function toggleAdminPanel() {
|
||||
var menu = document.querySelector('#menu');
|
||||
if(menu.classList.contains('hidden')) {
|
||||
@ -9,20 +32,6 @@ function toggleAdminPanel() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.onkeydown = function(evt) {
|
||||
evt = evt || window.event;
|
||||
var isEscape = false;
|
||||
if("key" in evt) {
|
||||
isEscape = (evt.key == "Escape" || evt.key == "Esc");
|
||||
} else {
|
||||
isEscape = (evt.keyCode == 27);
|
||||
}
|
||||
if(isEscape) {
|
||||
toggleAdminPanel();
|
||||
}
|
||||
}
|
||||
|
||||
function showModal(options) {
|
||||
var modal = document.getElementById('modal-overlay');
|
||||
document.getElementById('modal-title').innerText = (options.title)?options.title:"";
|
||||
|
9
main.go
9
main.go
@ -136,7 +136,7 @@ func main() {
|
||||
}()
|
||||
|
||||
fmt.Printf("Listening on port %d\n", m.site.Port)
|
||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(m.site.Port), chain))
|
||||
log.Fatal(http.ListenAndServe(m.site.Ip+":"+strconv.Itoa(m.site.Port), chain))
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
@ -154,6 +154,9 @@ func loadConfig() {
|
||||
case "-title":
|
||||
m.site.Title = val
|
||||
fmt.Print("Set site title: ", m.site.Title, "\n")
|
||||
case "-ip":
|
||||
m.site.Ip = val
|
||||
fmt.Print("Set site IP: ", m.site.Ip, "\n")
|
||||
case "-port":
|
||||
var tryPort int
|
||||
var err error
|
||||
@ -246,8 +249,8 @@ func InitPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
||||
var err error
|
||||
var s *sessions.Session
|
||||
if s, err = sessionStore.Get(req, m.site.SessionName); err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return p
|
||||
fmt.Println("Session error... Recreating.")
|
||||
//http.Error(w, err.Error(), 500)
|
||||
}
|
||||
p.session = new(pageSession)
|
||||
p.session.session = s
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
*/
|
||||
type siteData struct {
|
||||
Title string
|
||||
Ip string
|
||||
Port int
|
||||
SessionName string
|
||||
ServerDir string
|
||||
@ -32,6 +33,7 @@ type siteData struct {
|
||||
func NewSiteData(m *model) *siteData {
|
||||
ret := new(siteData)
|
||||
ret.Title = "ICT GameJam"
|
||||
ret.Ip = "127.0.0.1"
|
||||
ret.Port = 8080
|
||||
ret.SessionName = "ict-gamejam"
|
||||
ret.ServerDir = "./"
|
||||
@ -65,6 +67,9 @@ func (s *siteData) LoadFromDB() error {
|
||||
if title, _ := s.m.bolt.GetValue(s.mPath, "title"); strings.TrimSpace(title) != "" {
|
||||
s.Title = title
|
||||
}
|
||||
if ip, err := s.m.bolt.GetValue(s.mPath, "ip"); err == nil {
|
||||
s.Ip = ip
|
||||
}
|
||||
if port, err := s.m.bolt.GetInt(s.mPath, "port"); err == nil {
|
||||
s.Port = port
|
||||
}
|
||||
@ -97,6 +102,9 @@ func (s *siteData) SaveToDB() error {
|
||||
if err = s.m.bolt.SetValue(s.mPath, "title", s.Title); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.m.bolt.SetValue(s.mPath, "ip", s.Ip); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.m.bolt.SetInt(s.mPath, "port", s.Port); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -4,20 +4,16 @@
|
||||
<table id="clients-table" class="sortable pure-table pure-table-bordered center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Friendly Name</th>
|
||||
<th>Client ID</th>
|
||||
<th>Last Known IP</th>
|
||||
<th>Authenticated</th>
|
||||
<th></th>
|
||||
<th>Auth</th>
|
||||
<th>Name</th>
|
||||
<th class="only-large">Client ID</th>
|
||||
<th class="only-large">Last Known IP</th>
|
||||
<th class="only-large">Authenticated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $i, $v := .TemplateData.Clients }}
|
||||
<tr>
|
||||
<td>{{ $v.Name }}</td>
|
||||
<td>{{ $v.UUID }}</td>
|
||||
<td>{{ $v.IP }}</td>
|
||||
<td>{{ if $v.Auth }} Yes {{ else }} No {{ end }}</td>
|
||||
<td>
|
||||
{{ if $v.Auth }}
|
||||
<a href="/admin/clients/{{ $v.UUID }}/deauth" class="primary"><i class="fa fa-2 fa-toggle-on"></i></a>
|
||||
@ -25,6 +21,10 @@
|
||||
<a href="/admin/clients/{{ $v.UUID }}/auth" class="error"><i class="fa fa-2 fa-toggle-off"></i></a>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>{{ $v.Name }}<p class="only-small">({{ $v.UUID }})</p></td>
|
||||
<td class="only-large">{{ $v.UUID }}</td>
|
||||
<td class="only-large">{{ $v.IP }}</td>
|
||||
<td class="only-large">{{ if $v.Auth }} Yes {{ else }} No {{ end }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
|
@ -1,10 +1,10 @@
|
||||
{{ $uuid := .TemplateData.UUID }}
|
||||
<div class="center">
|
||||
<div>
|
||||
<div class="team-management-buttons">
|
||||
<h3>Team Management</h3>
|
||||
<button id="edit-team-button" onclick="javascript:gotoTeamTab();" class="pure-button-toggle-first pure-button pure-button-primary">Team Details</button>
|
||||
<button id="edit-game-button" onclick="javascript:gotoTeamGameTab();" class="pure-button-toggle-middle pure-button">Game Details</button>
|
||||
<button id="edit-team-members-button" onclick="javascript:gotoTeamMemberTab();" class="pure-button-toggle-last pure-button">Team Members</button>
|
||||
<button id="edit-team-button" onclick="javascript:gotoTeamTab();" class="pure-button-toggle-first pure-button pure-button-primary">Team Details</button><br class="only-small" />
|
||||
<button id="edit-game-button" onclick="javascript:gotoTeamGameTab();" class="pure-button-toggle-middle pure-button">Game Details</button><br class="only-small" />
|
||||
<button id="edit-team-members-button" onclick="javascript:gotoTeamMemberTab();" class="pure-button-toggle-last pure-button">Team Members</button><br class="only-small" />
|
||||
</div>
|
||||
<div id="edit-team-tab" class="left">
|
||||
<form class="pure-form pure-form-aligned" action="/admin/teams/{{ $uuid }}/save" method="POST">
|
||||
@ -16,10 +16,10 @@
|
||||
<input id="teamname" name="teamname" value="{{ .TemplateData.Name }}" placeholder="Team Name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-control-group reset-pull">
|
||||
<a href="/admin/teams" class="pull-left space pure-button pure-button-plain">Cancel</a>
|
||||
<button type="submit" class="pull-right space pure-button pure-button-primary">Update Team</button>
|
||||
<button type="button" id="btnDeleteTeam" class="pull-right space pure-button pure-button-error">Delete Team</button>
|
||||
<div class="pure-control-group team-management-buttons">
|
||||
<a href="/admin/teams" class="pure-button pure-button-plain">Cancel</a>
|
||||
<button type="submit" class="pure-button pure-button-primary">Update Team</button>
|
||||
<button type="button" id="btnDeleteTeam" class="pure-button pure-button-error">Delete Team</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
@ -73,9 +73,9 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Slack ID</th>
|
||||
<th>Twitter</th>
|
||||
<th>Email</th>
|
||||
<th class="only-large">Slack ID</th>
|
||||
<th class="only-large">Twitter</th>
|
||||
<th class="only-large">Email</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -83,9 +83,9 @@
|
||||
{{ range $i, $v := .TemplateData.Members }}
|
||||
<tr>
|
||||
<td>{{ $v.Name }}</td>
|
||||
<td>{{ $v.SlackId }}</td>
|
||||
<td>{{ $v.Twitter }}</td>
|
||||
<td>{{ $v.Email }}</td>
|
||||
<td class="only-large">{{ $v.SlackId }}</td>
|
||||
<td class="only-large">{{ $v.Twitter }}</td>
|
||||
<td class="only-large">{{ $v.Email }}</td>
|
||||
<td>
|
||||
<form action="/admin/teams/{{ $uuid }}/deletemember" method="POST">
|
||||
<input type="hidden" name="memberid" value="{{ $v.UUID }}"/>
|
||||
|
@ -5,15 +5,15 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Game Name</th>
|
||||
<th>Team Name</th>
|
||||
<th class="only-large">Team Name</th>
|
||||
<th>Screenshots</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $i, $v := .TemplateData.Teams }}
|
||||
<tr>
|
||||
<td>{{ $v.Game.Name }}</td>
|
||||
<td>{{ $v.Name }}</td>
|
||||
<td>{{ $v.Game.Name }}<p class="only-small">by<br />{{ $v.Name }}</p></td>
|
||||
<td class="only-large">{{ $v.Name }}</td>
|
||||
<td>{{ len $v.Game.Screenshots }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="content">
|
||||
<div class="">
|
||||
<div>
|
||||
<h3>Public Mode</h3>
|
||||
<button onclick="window.location.href='/admin/mode/0'" class="pure-button-toggle-first pure-button {{ if eq .PublicMode 0 }}pure-button-primary{{ end }}">Waiting</button>
|
||||
|
@ -8,19 +8,19 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Management Link</th>
|
||||
<th>Members</th>
|
||||
<th>Game</th>
|
||||
<th class="only-large">Management Link</th>
|
||||
<th class="only-large">Members</th>
|
||||
<th class="only-large">Game</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $i, $v := .TemplateData.Teams }}
|
||||
<tr>
|
||||
<td>{{ $v.Name }}</td>
|
||||
<td><a href="/team/{{ $v.UUID }}">{{ $v.UUID }}</a></td>
|
||||
<td>{{ len $v.Members }}</td>
|
||||
<td>{{ $v.Game.Name }}</td>
|
||||
<td>{{ $v.Name }}<p class="only-small">{{ $v.Game.Name }}</p></td>
|
||||
<td class="only-large"><a href="/team/{{ $v.UUID }}">{{ $v.UUID }}</a></td>
|
||||
<td class="only-large">{{ len $v.Members }}</td>
|
||||
<td class="only-large">{{ $v.Game.Name }}</td>
|
||||
<td>
|
||||
<a href="/admin/teams/{{ $v.UUID }}/edit" class="pure-button pure-button-plain"><i class="fa fa-pencil"></i></a>
|
||||
<a href="/admin/teams/{{ $v.UUID }}/delete" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></a>
|
||||
|
@ -9,16 +9,15 @@
|
||||
<table id="votes-table" class="sortable pure-table pure-table-bordered center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th>Client ID</th>
|
||||
<th>Time</th>
|
||||
<th>Rankings</th>
|
||||
<th class="only-large">Client ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $i, $v := .TemplateData.AllVotes }}
|
||||
<tr>
|
||||
<td>{{ $v.Timestamp }}</td>
|
||||
<td>{{ $v.ClientId }}</td>
|
||||
<td>
|
||||
<ol>
|
||||
{{ range $ci, $cv := $v.Choices }}
|
||||
@ -26,6 +25,7 @@
|
||||
{{ end }}
|
||||
</ol>
|
||||
</td>
|
||||
<td class="only-large">{{ $v.ClientId }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
|
@ -2,26 +2,11 @@
|
||||
<div>No games have been created</div>
|
||||
{{ else }}
|
||||
<div class="content">
|
||||
Rank one or more games from your favorite to least favorite.
|
||||
<p>First choose the games that you want to rank, then put them in order from your most favorite to least favorite.</p>
|
||||
<p>Any games that you don't rank will be considered 'tied for last place'.</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h2>Your Choices</h2>
|
||||
<table id="ranked-table" class="pure-table pure-table-bordered center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rank</th>
|
||||
<th>Game Name</th>
|
||||
<th>Team Name</th>
|
||||
<th>Screenshots</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h2>Unranked Games</h2>
|
||||
<h2>1. Choose the games you want to rank</h2>
|
||||
<table id="unranked-table" class="pure-table pure-table-bordered center">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -49,7 +34,24 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h2>2. Order them from your most favorite to least favorite</h2>
|
||||
<table id="ranked-table" class="pure-table pure-table-bordered center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rank</th>
|
||||
<th>Game Name</th>
|
||||
<th>Team Name</th>
|
||||
<th>Screenshots</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="content half">
|
||||
<h2>3. Submit your vote!</h2>
|
||||
<form action="/vote" onsubmit="return validateVote();">
|
||||
<input id="uservote" type="hidden" name="uservote" value="" />
|
||||
<input id="timestamp" type="hidden" name="timestamp" value="{{.TemplateData.Timestamp}}" />
|
||||
|
Loading…
Reference in New Issue
Block a user