Working on editing team games
This commit is contained in:
parent
597623d71b
commit
1faf4b9aa1
@ -55,3 +55,31 @@ func handleAdminClients(w http.ResponseWriter, req *http.Request, page *pageData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clientIsAuthenticated(cid string, req *http.Request) bool {
|
||||||
|
return clientIsServer(req) || dbClientIsAuth(cid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func clientIsServer(req *http.Request) bool {
|
||||||
|
clientIp, _, _ := net.SplitHostPort(req.RemoteAddr)
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err == nil {
|
||||||
|
for _, i := range ifaces {
|
||||||
|
if addrs, err := i.Addrs(); err == nil {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
if clientIp == ip.String() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
@ -10,23 +14,63 @@ import (
|
|||||||
func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData) {
|
func handleAdminGames(w http.ResponseWriter, req *http.Request, page *pageData) {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
page.SubTitle = "Games"
|
page.SubTitle = "Games"
|
||||||
gameId := vars["id"]
|
teamId := vars["id"]
|
||||||
teamId := req.FormValue("teamid")
|
if teamId == "" {
|
||||||
if strings.TrimSpace(teamId) != "" {
|
// Games List
|
||||||
page.session.setStringValue("teamid", teamId)
|
type gamesPageData struct {
|
||||||
page.TeamID = teamId
|
Games []Game
|
||||||
}
|
}
|
||||||
if gameId == "new" {
|
page.TemplateData = gamesPageData{Games: dbGetAllGames()}
|
||||||
|
page.SubTitle = "Games"
|
||||||
|
page.show("admin-games.html", w)
|
||||||
|
} else {
|
||||||
switch vars["function"] {
|
switch vars["function"] {
|
||||||
case "save":
|
case "save":
|
||||||
name := req.FormValue("gamename")
|
name := req.FormValue("gamename")
|
||||||
|
desc := req.FormValue("gamedesc")
|
||||||
if dbIsValidTeam(teamId) {
|
if dbIsValidTeam(teamId) {
|
||||||
if dbEditTeamGame(teamId, name) != nil {
|
if err := dbUpdateTeamGame(teamId, name, desc); err != nil {
|
||||||
|
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Team game updated", "success")
|
||||||
}
|
}
|
||||||
|
redirect("/admin/teams/"+teamId, w, req)
|
||||||
}
|
}
|
||||||
default:
|
case "screenshotupload":
|
||||||
page.SubTitle = "Add New Game"
|
if err := saveScreenshots(teamId, req); err != nil {
|
||||||
page.show("admin-addgame.html", w)
|
page.session.setFlashMessage("Error updating game: "+err.Error(), "error")
|
||||||
|
}
|
||||||
|
redirect("/admin/teams/"+teamId, w, req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func saveScreenshots(teamId string, req *http.Request) error {
|
||||||
|
err := req.ParseMultipartForm((1 << 10) * 24)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fheaders := range req.MultipartForm.File {
|
||||||
|
for _, hdr := range fheaders {
|
||||||
|
// open uploaded
|
||||||
|
var infile multipart.File
|
||||||
|
if infile, err = hdr.Open(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// open destination
|
||||||
|
var outfile *os.File
|
||||||
|
if outfile, err = os.Create("./uploaded/" + hdr.Filename); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 32K buffer copy
|
||||||
|
var written int64
|
||||||
|
if written, err = io.Copy(outfile, infile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
page.SubTitle = "Teams"
|
page.SubTitle = "Teams"
|
||||||
teamId := vars["id"]
|
teamId := vars["id"]
|
||||||
if teamId == "new" {
|
if teamId == "new" {
|
||||||
|
// Add a new team
|
||||||
switch vars["function"] {
|
switch vars["function"] {
|
||||||
case "save":
|
case "save":
|
||||||
name := req.FormValue("teamname")
|
name := req.FormValue("teamname")
|
||||||
@ -30,6 +31,7 @@ func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
page.show("admin-addteam.html", w)
|
page.show("admin-addteam.html", w)
|
||||||
}
|
}
|
||||||
} else if teamId != "" {
|
} else if teamId != "" {
|
||||||
|
// Functions for existing team
|
||||||
if dbIsValidTeam(teamId) {
|
if dbIsValidTeam(teamId) {
|
||||||
switch vars["function"] {
|
switch vars["function"] {
|
||||||
case "save":
|
case "save":
|
||||||
@ -44,8 +46,11 @@ func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
redirect("/admin/teams", w, req)
|
redirect("/admin/teams", w, req)
|
||||||
case "delete":
|
case "delete":
|
||||||
var err error
|
var err error
|
||||||
|
t := dbGetTeam(teamId)
|
||||||
if err = dbDeleteTeam(teamId); err != nil {
|
if err = dbDeleteTeam(teamId); err != nil {
|
||||||
page.session.setFlashMessage("Error deleting team: "+err.Error(), "error")
|
page.session.setFlashMessage("Error deleting team: "+err.Error(), "error")
|
||||||
|
} else {
|
||||||
|
page.session.setFlashMessage("Team "+t.Name+" Deleted", "success")
|
||||||
}
|
}
|
||||||
redirect("/admin/teams", w, req)
|
redirect("/admin/teams", w, req)
|
||||||
case "savemember":
|
case "savemember":
|
||||||
@ -61,10 +66,11 @@ func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
redirect("/admin/teams/"+teamId, w, req)
|
redirect("/admin/teams/"+teamId, w, req)
|
||||||
case "deletemember":
|
case "deletemember":
|
||||||
mbrId := req.FormValue("memberid")
|
mbrId := req.FormValue("memberid")
|
||||||
|
m, _ := dbGetTeamMember(teamId, mbrId)
|
||||||
if err := dbDeleteTeamMember(teamId, mbrId); err != nil {
|
if err := dbDeleteTeamMember(teamId, mbrId); err != nil {
|
||||||
page.session.setFlashMessage("Error deleting team member: "+err.Error(), "error")
|
page.session.setFlashMessage("Error deleting team member: "+err.Error(), "error")
|
||||||
} else {
|
} else {
|
||||||
page.session.setFlashMessage("Member deleted from team", "success")
|
page.session.setFlashMessage(m.Name+" deleted from team", "success")
|
||||||
}
|
}
|
||||||
redirect("/admin/teams/"+teamId, w, req)
|
redirect("/admin/teams/"+teamId, w, req)
|
||||||
default:
|
default:
|
||||||
@ -78,10 +84,10 @@ func handleAdminTeams(w http.ResponseWriter, req *http.Request, page *pageData)
|
|||||||
redirect("/admin/teams", w, req)
|
redirect("/admin/teams", w, req)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Team List
|
||||||
type teamsPageData struct {
|
type teamsPageData struct {
|
||||||
Teams []Team
|
Teams []Team
|
||||||
}
|
}
|
||||||
|
|
||||||
page.TemplateData = teamsPageData{Teams: dbGetAllTeams()}
|
page.TemplateData = teamsPageData{Teams: dbGetAllTeams()}
|
||||||
page.SubTitle = "Teams"
|
page.SubTitle = "Teams"
|
||||||
page.show("admin-teams.html", w)
|
page.show("admin-teams.html", w)
|
||||||
|
@ -17,6 +17,14 @@ div.content {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.file {
|
||||||
|
padding: .5em .6em;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: inset 0 1px 3px #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
#menu {
|
#menu {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
@ -29,6 +37,14 @@ div.content {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#menu .pure-menu-nonlink {
|
||||||
|
color: #777;
|
||||||
|
padding: .5em 1em;
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
#menu .menu-button {
|
#menu .menu-button {
|
||||||
display: inline;
|
display: inline;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -57,8 +73,87 @@ div.content {
|
|||||||
background-color: #191818;
|
background-color: #191818;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.uuid-field {
|
div.horizontal-scroll {
|
||||||
width: 360px;
|
overflow-x: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.thumbnail {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail-container {
|
||||||
|
display: block;
|
||||||
|
height: 120px;
|
||||||
|
background-color: #EEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-sides {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big-space {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-all {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: center;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.center td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.padding td {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pure-button-error {
|
||||||
|
background-color: #DD0000;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-overlay {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-overlay>div {
|
||||||
|
width: 500px;
|
||||||
|
margin: 100px auto;
|
||||||
|
background-color: #FFF;
|
||||||
|
border: 1px solid #000;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 40em) {
|
@media (min-width: 40em) {
|
||||||
@ -92,6 +187,11 @@ input.uuid-field {
|
|||||||
margin-left: 150px;
|
margin-left: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aside.flash.success {
|
||||||
|
background-color: #229af9;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
margin-left: 150px;
|
margin-left: 150px;
|
||||||
}
|
}
|
||||||
|
@ -15,3 +15,51 @@ document.onkeydown = function(evt) {
|
|||||||
toggleAdminPanel();
|
toggleAdminPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showModal(options) {
|
||||||
|
var modal = document.getElementById('modal-overlay');
|
||||||
|
document.getElementById('modal-title').innerText = (options.title)?options.title:"";
|
||||||
|
document.getElementById('modal-subtitle').innerText = (options.subtitle)?options.subtitle:"";
|
||||||
|
if(options.body) {
|
||||||
|
document.getElementById('modal-body').innerText = options.body;
|
||||||
|
} else if(options.bodyNode) {
|
||||||
|
document.getElementById('modal-body').appendChild(options.bodyNode);
|
||||||
|
}
|
||||||
|
if(options.buttons) {
|
||||||
|
for(var i = 0; i < options.buttons.length; i++) {
|
||||||
|
var btn;
|
||||||
|
if(options.buttons[i].isSubmit) {
|
||||||
|
btn = document.createElement('submit');
|
||||||
|
} else {
|
||||||
|
btn = document.createElement('a');
|
||||||
|
}
|
||||||
|
options.buttons[i].title = (options.buttons[i].title==undefined)?'':options.buttons[i].title;
|
||||||
|
options.buttons[i].href = (options.buttons[i].href==undefined)?'#':options.buttons[i].href;
|
||||||
|
options.buttons[i].click = (options.buttons[i].click==undefined)?function(){}:options.buttons[i].click;
|
||||||
|
options.buttons[i].class = (options.buttons[i].class==undefined)?'':options.buttons[i].class;
|
||||||
|
options.buttons[i].position = (options.buttons[i].position==undefined)?'right':options.buttons[i].position;
|
||||||
|
|
||||||
|
btn.innerHTML = options.buttons[i].title;
|
||||||
|
btn.title = options.buttons[i].title;
|
||||||
|
btn.href = options.buttons[i].href;
|
||||||
|
btn.className = 'space pure-button '+options.buttons[i].class+' '+options.buttons[i].position;
|
||||||
|
snack.listener(
|
||||||
|
{node:btn, event:'click'},
|
||||||
|
options.buttons[i].click
|
||||||
|
);
|
||||||
|
document.getElementById('modal-buttons').appendChild(btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modal.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideModal() {
|
||||||
|
var modal = document.getElementById('modal-overlay');
|
||||||
|
modal.style.visibility = 'hidden';
|
||||||
|
document.getElementById('modal-title').innerHTML = '';
|
||||||
|
document.getElementById('modal-body').innerHTML = '';
|
||||||
|
var buttonsDiv = document.getElementById('modal-buttons')
|
||||||
|
while(buttonsDiv.firstChild) {
|
||||||
|
buttonsDiv.removeChild(buttonsDiv.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4
main.go
4
main.go
@ -53,6 +53,7 @@ type pageData struct {
|
|||||||
CurrentJam string
|
CurrentJam string
|
||||||
ClientID string
|
ClientID string
|
||||||
ClientIsAuth bool
|
ClientIsAuth bool
|
||||||
|
ClientIsServer bool
|
||||||
TeamID string
|
TeamID string
|
||||||
|
|
||||||
TemplateData interface{}
|
TemplateData interface{}
|
||||||
@ -237,7 +238,8 @@ func InitPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.ClientID = p.session.getClientID()
|
p.ClientID = p.session.getClientID()
|
||||||
p.ClientIsAuth = dbClientIsAuth(p.ClientID)
|
p.ClientIsAuth = clientIsAuthenticated(p.ClientID, req)
|
||||||
|
p.ClientIsServer = clientIsServer(req)
|
||||||
p.TeamID, _ = p.session.getStringValue("teamid")
|
p.TeamID, _ = p.session.getStringValue("teamid")
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
143
model_games.go
143
model_games.go
@ -1,12 +1,145 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/pborman/uuid"
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/pborman/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
UUID *uuid.UUID
|
Name string
|
||||||
Name string
|
TeamId string
|
||||||
|
Description string
|
||||||
|
Screenshots []Screenshot
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbIsValidGame(id string) bool {
|
type Screenshot struct {
|
||||||
return true
|
Description string
|
||||||
|
Image string
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbUpdateTeamGame(teamId, name, desc string) error {
|
||||||
|
var err error
|
||||||
|
if err = openDatabase(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closeDatabase()
|
||||||
|
|
||||||
|
// Make sure the team is valid
|
||||||
|
tm := dbGetTeam(teamId)
|
||||||
|
if tm == nil {
|
||||||
|
return errors.New("Invalid team")
|
||||||
|
}
|
||||||
|
gamePath := []string{"teams", teamId, "game"}
|
||||||
|
|
||||||
|
if err := db.MkBucketPath(gamePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if name == "" {
|
||||||
|
name = tm.Name + "'s Game"
|
||||||
|
}
|
||||||
|
if err := db.SetValue(gamePath, "name", name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := db.SetValue(gamePath, "description", desc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := db.MkBucketPath(append(gamePath, "screenshots")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetAllGames() []Game {
|
||||||
|
var ret []Game
|
||||||
|
tms := dbGetAllTeams()
|
||||||
|
for i := range tms {
|
||||||
|
ret = append(ret, *dbGetTeamGame(tms[i].UUID))
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetTeamGame(teamId string) *Game {
|
||||||
|
var err error
|
||||||
|
if err = openDatabase(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer closeDatabase()
|
||||||
|
|
||||||
|
gamePath := []string{"teams", teamId, "game"}
|
||||||
|
gm := new(Game)
|
||||||
|
if gm.Name, err = db.GetValue(gamePath, "name"); err != nil {
|
||||||
|
gm.Name = ""
|
||||||
|
}
|
||||||
|
gm.TeamId = teamId
|
||||||
|
if gm.Description, err = db.GetValue(gamePath, "description"); err != nil {
|
||||||
|
gm.Description = ""
|
||||||
|
}
|
||||||
|
gm.Screenshots = dbGetTeamGameScreenshots(teamId)
|
||||||
|
return gm
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screenshots are saved as base64 encoded pngs
|
||||||
|
func dbGetTeamGameScreenshots(teamId string) []Screenshot {
|
||||||
|
var ret []Screenshot
|
||||||
|
var err error
|
||||||
|
ssPath := []string{"teams", teamId, "game", "screenshots"}
|
||||||
|
var ssIds []string
|
||||||
|
if ssIds, err = db.GetBucketList(ssPath); err != nil {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
for _, v := range ssIds {
|
||||||
|
if ss := dbGetTeamGameScreenshot(teamId, v); ss != nil {
|
||||||
|
ret = append(ret, *ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbGetTeamGameScreenshot(teamId, ssId string) *Screenshot {
|
||||||
|
var err error
|
||||||
|
ssPath := []string{"teams", teamId, "game", "screenshots", ssId}
|
||||||
|
ret := new(Screenshot)
|
||||||
|
if ret.Description, err = db.GetValue(ssPath, "description"); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if ret.Image, err = db.GetValue(ssPath, "image"); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbSaveTeamGameScreenshot(teamId string, ss *Screenshot) error {
|
||||||
|
var err error
|
||||||
|
if err = openDatabase(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer closeDatabase()
|
||||||
|
|
||||||
|
ssPath := []string{"teams", teamId, "game", "screenshots"}
|
||||||
|
// Generate a UUID for this screenshot
|
||||||
|
uuid := uuid.New()
|
||||||
|
ssPath = append(ssPath, uuid)
|
||||||
|
if err := db.MkBucketPath(ssPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := db.SetValue(ssPath, "description", ss.Description); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := db.SetValue(ssPath, "image", ss.Image); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbDeleteTeamGameScreenshot(teamId, ssId string) error {
|
||||||
|
var err error
|
||||||
|
if err = openDatabase(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer closeDatabase()
|
||||||
|
|
||||||
|
ssPath := []string{"teams", teamId, "game", "screenshots"}
|
||||||
|
return db.DeleteBucket(ssPath, ssId)
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ func dbGetTeam(id string) *Team {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
tm.Members, _ = dbGetTeamMembers(id)
|
tm.Members, _ = dbGetTeamMembers(id)
|
||||||
|
tm.Game = dbGetTeamGame(id)
|
||||||
return tm
|
return tm
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +214,6 @@ func dbGetTeamMembers(teamid string) ([]TeamMember, error) {
|
|||||||
for _, v := range memberUuids {
|
for _, v := range memberUuids {
|
||||||
var mbr *TeamMember
|
var mbr *TeamMember
|
||||||
if mbr, err = dbGetTeamMember(teamid, v); err == nil {
|
if mbr, err = dbGetTeamMember(teamid, v); err == nil {
|
||||||
fmt.Println("Finding Team Members", teamid, mbr.Name)
|
|
||||||
ret = append(ret, *mbr)
|
ret = append(ret, *mbr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,70 +1,126 @@
|
|||||||
{{ $uuid := .TemplateData.UUID }}
|
{{ $uuid := .TemplateData.UUID }}
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<form class="pure-form pure-form-aligned" action="/admin/teams/{{ .TemplateData.UUID }}/save" method="POST">
|
<div class="left">
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/teams/{{ $uuid }}/save" method="POST">
|
||||||
|
<h3>Team Details</h3>
|
||||||
|
<fieldset>
|
||||||
|
<div class="left big-space">
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label class="control-label" for="teamname">Team Name</label>
|
||||||
|
<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>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/games/{{ $uuid }}/save" method="POST">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="left big-space">
|
||||||
<span>{{ .TemplateData.Name }}</span>
|
<h3>Team Game</h3>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label class="control-label" for="gamename">Game Name</label>
|
||||||
|
<input id="gamename" name="gamename" value="{{ .TemplateData.Game.Name }}" placeholder="Game Name">
|
||||||
|
</div>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label class="control-label" for="gamedesc">Description</label>
|
||||||
|
<textarea id="gamedesc" name="gamedesc" placeholder="Description...">{{ .TemplateData.Game.Description }}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<label class="control-label">Screenshots</label>
|
||||||
|
<div class="center-all horizontal-scroll thumbnail-container">
|
||||||
|
{{ if not .TemplateData.Game.Screenshots }}
|
||||||
|
<a style="margin-top:40px;" class="center-all pure-button pure-button-primary" href="javascript:toggleUploadSSForm();">Upload Screenshot</a>
|
||||||
|
{{ else }}
|
||||||
|
{{ range $i, $v := .TemplateData.Game.Screenshots }}
|
||||||
|
<img class="thumbnail" alt="{{ $v.Description }}" src="{{ $v.Image }}" />
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ if .TemplateData.Game.Screenshots }}
|
||||||
|
<div class="right">
|
||||||
|
<a id="toggleUploadSSFormBtn" class="pure-button pure-button-primary" href="javascript:toggleUploadSSForm();">Upload Screenshot</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pure-control-group">
|
|
||||||
<label class="control-label" for="teamname">Team Name</label>
|
|
||||||
<input id="teamname" name="teamname" value="{{ .TemplateData.Name }}" placeholder="Team Name">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pure-control-group reset-pull">
|
<div class="pure-control-group reset-pull">
|
||||||
<a href="/admin/teams" class="pull-left space pure-button pure-button-plain">Cancel</a>
|
<a href="/admin/teams/{{ $uuid }}" class="pull-left space pure-button pure-button-plain">Cancel</a>
|
||||||
<button type="submit" class="pull-right space pure-button pure-button-primary">Update</button>
|
<button type="submit" class="pull-right space pure-button pure-button-primary">Update Game</button>
|
||||||
<button type="button" id="btnDeleteUser" class="pull-right space pure-button pure-button-error">Delete</button>
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2>Members</h2>
|
<hr />
|
||||||
<table>
|
<div class="left">
|
||||||
<thead>
|
<h3>Team Members</h3>
|
||||||
<tr>
|
<table class="center padding hide">
|
||||||
<th>Name</th>
|
<thead>
|
||||||
<th>Slack ID</th>
|
<tr>
|
||||||
<th>Twitter</th>
|
<th>Name</th>
|
||||||
<th>Email</th>
|
<th>Slack ID</th>
|
||||||
<th>Edit</th>
|
<th>Twitter</th>
|
||||||
<th>Remove</th>
|
<th>Email</th>
|
||||||
</tr>
|
<th>Edit</th>
|
||||||
</thead>
|
<th>Remove</th>
|
||||||
<tbody>
|
</tr>
|
||||||
{{ range $i, $v := .TemplateData.Members }}
|
</thead>
|
||||||
<tr>
|
<tbody>
|
||||||
<td>{{ $v.Name }}</td>
|
{{ range $i, $v := .TemplateData.Members }}
|
||||||
<td>{{ $v.SlackId }}</td>
|
<tr>
|
||||||
<td>{{ $v.Twitter }}</td>
|
<td>{{ $v.Name }}</td>
|
||||||
<td>{{ $v.Email }}</td>
|
<td>{{ $v.SlackId }}</td>
|
||||||
<td>
|
<td>{{ $v.Twitter }}</td>
|
||||||
<a href="/admin/teams/{{ $v.UUID }}/edit" class="pure-button pure-button-plain"><i class="fa fa-pencil"></i></a>
|
<td>{{ $v.Email }}</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
<a href="/admin/teams/{{ $v.UUID }}/edit" class="pure-button pure-button-plain"><i class="fa fa-pencil"></i></a>
|
||||||
<form action="/admin/teams/{{ $uuid }}/deletemember" method="POST">
|
</td>
|
||||||
<input type="hidden" name="memberid" value="{{ $v.UUID }}"/>
|
<td>
|
||||||
<button type="submit" class="pure-button pure-button-plain"><i class="fa fa-trash"></i></button>
|
<form action="/admin/teams/{{ $uuid }}/deletemember" method="POST">
|
||||||
</form>
|
<input type="hidden" name="memberid" value="{{ $v.UUID }}"/>
|
||||||
</td>
|
<button type="submit" class="pure-button pure-button-error"><i class="fa fa-trash"></i></button>
|
||||||
</tr>
|
</form>
|
||||||
{{ end }}
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td colspan="6" class="center">Add a new member</td>
|
{{ end }}
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td colspan="6">Add a new member</td>
|
||||||
<td colspan="6">
|
</tr>
|
||||||
<form action="/admin/teams/{{ $uuid }}/savemember" method="POST">
|
<tr>
|
||||||
<input id="newmembername" name="newmembername" value="" placeholder="Member Name" />
|
<td colspan="6" class="padding">
|
||||||
|
<form class="pure-form" action="/admin/teams/{{ $uuid }}/savemember" method="POST">
|
||||||
|
<div class="pure-control-group">
|
||||||
|
<input id="newmembername" name="newmembername" value="" placeholder="Member Name" autofocus />
|
||||||
<input id="newmemberslackid" name="newmemberslackid" value="" placeholder="@SlackID" />
|
<input id="newmemberslackid" name="newmemberslackid" value="" placeholder="@SlackID" />
|
||||||
<input id="newmembertwitter" name="newmembertwitter" value="" placeholder="@Twitter" />
|
<input id="newmembertwitter" name="newmembertwitter" value="" placeholder="@Twitter" />
|
||||||
<input id="newmemberemail" name="newmemberemail" value="" placeholder="user@email.com" />
|
<input id="newmemberemail" name="newmemberemail" value="" placeholder="user@email.com" />
|
||||||
<button type="submit" class="pull-right space pure-button pure-button-primary">Add</button>
|
<button type="submit" class="pull-right space-sides pure-button pure-button-primary">Add</button>
|
||||||
</form>
|
</div>
|
||||||
</td>
|
</form>
|
||||||
</tr>
|
</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="pure-control-group reset-pull">
|
||||||
|
<a href="/admin/teams" class="pull-left space pure-button pure-button-plain">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="uploadscreenshotform" style="display:none;">
|
||||||
|
<h3>Upload Screenshot</h3>
|
||||||
|
<form class="pure-form pure-form-aligned" action="/admin/games/{{ $uuid }}/screenshotupload" method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="pure-control-group" style="margin-bottom:50px;">
|
||||||
|
<input class="file" type="file" name="newssfile" multiple>
|
||||||
|
</div>
|
||||||
|
<a href="javascript:hideModal();" class="pull-left space-sides pure-button">Cancel</a>
|
||||||
|
<button type="submit" class="pull-right space-sides pure-button pure-button-primary">Add</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
snack.listener(
|
snack.listener(
|
||||||
@ -72,7 +128,7 @@
|
|||||||
function() {
|
function() {
|
||||||
showModal({
|
showModal({
|
||||||
title: 'Delete Team',
|
title: 'Delete Team',
|
||||||
subtitle: '({{ .TemplateData.Name }} - {{ $uuid}})',
|
subtitle: '({{ .TemplateData.Name }})',
|
||||||
body: 'Are you sure? This cannot be undone.',
|
body: 'Are you sure? This cannot be undone.',
|
||||||
buttons: [{
|
buttons: [{
|
||||||
title:'Cancel',
|
title:'Cancel',
|
||||||
@ -87,4 +143,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
function toggleUploadSSForm() {
|
||||||
|
var uploadForm = document.getElementById('uploadscreenshotform');
|
||||||
|
showModal({
|
||||||
|
title: 'Upload Screenshot',
|
||||||
|
subtitle: '({{ .TemplateData.Name }})',
|
||||||
|
bodyNode: uploadForm
|
||||||
|
});
|
||||||
|
uploadForm.style.display="block";
|
||||||
|
document.getElementById('modal-body').style.height='165px';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,11 +12,15 @@
|
|||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
{{if .ClientIsAuth}}
|
{{ if .ClientIsAuth }}
|
||||||
<a href="/admin/clients/{{.ClientID}}/remove" class="pure-menu-link"><i class="fa fa-key"></i> DeAuth Client</a>
|
{{ if .ClientIsServer }}
|
||||||
{{else}}
|
<span class="pure-menu-nonlink"><i class="fa fa-server"></i> Server Mode</span>
|
||||||
|
{{ else }}
|
||||||
|
<a href="/admin/clients/{{.ClientID}}/remove" class="pure-menu-link"><i class="fa fa-key"></i> DeAuth Client</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
<a href="/admin/clients/{{.ClientID}}/add" class="pure-menu-link"><i class="fa fa-key"></i> Auth Client</a>
|
<a href="/admin/clients/{{.ClientID}}/add" class="pure-menu-link"><i class="fa fa-key"></i> Auth Client</a>
|
||||||
{{end}}
|
{{ end }}
|
||||||
<ul class="pure-menu-list menu-bottom">
|
<ul class="pure-menu-list menu-bottom">
|
||||||
{{ range $k, $v := .BottomMenu }}
|
{{ range $k, $v := .BottomMenu }}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<script>
|
<script>
|
||||||
var clientID = "{{.ClientID}}";
|
var clientID = "{{.ClientID}}";
|
||||||
</script>
|
</script>
|
||||||
|
<aside class="flash center {{.FlashClass}}">
|
||||||
|
{{.FlashMessage}}
|
||||||
|
</aside>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<aside class="flash center {{.FlashClass}}">
|
|
||||||
{{.FlashMessage}}
|
|
||||||
</aside>
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
devICT Game Jam - {{.CurrentJam}}
|
devICT Game Jam - {{.CurrentJam}}
|
||||||
</div>
|
</div>
|
||||||
<div class="header-menu">
|
<div class="header-menu">
|
||||||
<h1>{{.SubTitle}}</h1>
|
<h2>{{.SubTitle}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user