added base UI changes
This commit is contained in:
@@ -56,6 +56,15 @@ type ServerSpecs struct {
|
|||||||
GPU string `form:"GPU" binding:"required" bson:GPU`
|
GPU string `form:"GPU" binding:"required" bson:GPU`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BarrierIP Barrier connection information
|
||||||
|
type BarrierIP struct {
|
||||||
|
ID string `bson: ID`
|
||||||
|
BarrierIP string `form:"BarrierIP" binding:"required" bson:hostname`
|
||||||
|
MachineName string `form:"MachineName" binding:"required" bson:hostname`
|
||||||
|
UserID string `json:"UserID"`
|
||||||
|
User Users `gorm:"foreignKey:UserID;references:UserID" json:"ServerInformation"`
|
||||||
|
}
|
||||||
|
|
||||||
// CreateTables CreateDB Add tables to the database
|
// CreateTables CreateDB Add tables to the database
|
||||||
func CreateTables(db *gorm.DB) (*gorm.DB, error) {
|
func CreateTables(db *gorm.DB) (*gorm.DB, error) {
|
||||||
// Creates table to store login sessions
|
// Creates table to store login sessions
|
||||||
@@ -66,6 +75,8 @@ func CreateTables(db *gorm.DB) (*gorm.DB, error) {
|
|||||||
db.AutoMigrate(GameSession{})
|
db.AutoMigrate(GameSession{})
|
||||||
// Creates table of type ServerSpecs
|
// Creates table of type ServerSpecs
|
||||||
db.AutoMigrate(ServerSpecs{})
|
db.AutoMigrate(ServerSpecs{})
|
||||||
|
// Creates table of type BarrierIP
|
||||||
|
db.AutoMigrate(BarrierIP{})
|
||||||
// returns variable DB of type *gorm.DB and error
|
// returns variable DB of type *gorm.DB and error
|
||||||
// which is nil at the current moment
|
// which is nil at the current moment
|
||||||
return db, nil
|
return db, nil
|
||||||
@@ -348,3 +359,60 @@ func GetUserInformation(db *gorm.DB, SessionID string) (*Users, error) {
|
|||||||
|
|
||||||
return nil, errors.New("Session not found. ")
|
return nil, errors.New("Session not found. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddBarrierIP Adds barrierIP information to barrier table
|
||||||
|
func AddBarrierIP(db *gorm.DB, SessionID string, barrierIP string, MachineName string) (*BarrierIP, error) {
|
||||||
|
// Get User Information
|
||||||
|
user, err := GetUserInformation(db, SessionID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the barrier IP exists
|
||||||
|
exists, err := CheckIfBarrierAddressExists(db, barrierIP)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists == false {
|
||||||
|
var NewBarrierIP BarrierIP
|
||||||
|
NewBarrierIP.BarrierIP = barrierIP
|
||||||
|
NewBarrierIP.UserID = user.UserID
|
||||||
|
NewBarrierIP.MachineName = MachineName
|
||||||
|
|
||||||
|
// creates barrier table with info
|
||||||
|
db.Create(NewBarrierIP)
|
||||||
|
|
||||||
|
return &NewBarrierIP, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("BarrierIP already exists. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckIfBarrierAddressExists Check if the barrier ip
|
||||||
|
// address with port exists
|
||||||
|
func CheckIfBarrierAddressExists(db *gorm.DB, barrierIP string) (bool, error) {
|
||||||
|
BarrierRows, err := db.Model(&BarrierIP{}).Where("barrier_ip = ? ", barrierIP).Rows()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer BarrierRows.Close()
|
||||||
|
|
||||||
|
// Checks if there is more than one entry and returns
|
||||||
|
// true if that entry exists.
|
||||||
|
if BarrierRows.Next() {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveBarrierIP Remove barrier row based on the IP address provided
|
||||||
|
func RemoveBarrierIP(db *gorm.DB, barrierIP string) error {
|
||||||
|
// Delete session from the database
|
||||||
|
err := db.Where("barrier_ip = ?", barrierIP).Delete(BarrierIP{})
|
||||||
|
if err != nil {
|
||||||
|
return err.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
404
server/server.go
404
server/server.go
@@ -1,223 +1,261 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server Starts the server for the client side
|
// Server Starts the server for the client side
|
||||||
func Server(port string) error {
|
func Server(port string) error {
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
r.Static("/assets", "./templates/assets")
|
r.Static("/assets", "./templates/assets")
|
||||||
|
|
||||||
r.LoadHTMLGlob("./templates/*.html")
|
r.LoadHTMLGlob("./templates/*.html")
|
||||||
// htmlRender.TemplatesDir = "templates/" // default
|
// htmlRender.TemplatesDir = "templates/" // default
|
||||||
// htmlRender.Ext = ".html" // default
|
// htmlRender.Ext = ".html" // default
|
||||||
|
|
||||||
// Tell gin to use our html render
|
// Tell gin to use our html render
|
||||||
|
|
||||||
// Initialise connection to Sqlite DB
|
// Initialise connection to Sqlite DB
|
||||||
connect, err := Connect()
|
connect, err := Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets default information about the game sessions
|
// Gets default information about the game sessions
|
||||||
r.GET("/", func(c *gin.Context) {
|
r.GET("/", func(c *gin.Context) {
|
||||||
// Get client session ID
|
// Get client session ID
|
||||||
session, err := c.Cookie("SessionID")
|
session, err := c.Cookie("SessionID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Redirect(http.StatusFound, "/login")
|
c.Redirect(http.StatusFound, "/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// User information based on session ID
|
// User information based on session ID
|
||||||
User, err := GetUserInformation(connect, session)
|
User, err := GetUserInformation(connect, session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Redirect(http.StatusFound, "/login")
|
c.Redirect(http.StatusFound, "/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get information of all game sessions available
|
// Get information of all game sessions available
|
||||||
GameSessions, err := DisplayGameSessions(connect)
|
GameSessions, err := DisplayGameSessions(connect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusOK, fmt.Sprint(err))
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "index.html", gin.H{
|
c.HTML(http.StatusOK, "index.html", gin.H{
|
||||||
"title": "Xplane11-WebRTC",
|
"title": "Xplane11-WebRTC",
|
||||||
"GameSessions": GameSessions,
|
"GameSessions": GameSessions,
|
||||||
"User": User,
|
"User": User,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Opens the forgot password page
|
// Opens the forgot password page
|
||||||
r.GET("/forgotpassword", func(c *gin.Context) {
|
r.GET("/forgotpassword", func(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "forgotpassword.html", gin.H{
|
c.HTML(http.StatusOK, "forgotpassword.html", gin.H{
|
||||||
"title": "Xplane11-WebRTC",
|
"title": "Xplane11-WebRTC",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Opens the login page
|
// Opens the login page
|
||||||
r.GET("/login", func(c *gin.Context) {
|
r.GET("/login", func(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "login.html", gin.H{
|
c.HTML(http.StatusOK, "login.html", gin.H{
|
||||||
"title": "Xplane11-WebRTC",
|
"title": "Xplane11-WebRTC",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Validate login information
|
// Validate login information
|
||||||
r.POST("/login", func(c *gin.Context) {
|
r.POST("/login", func(c *gin.Context) {
|
||||||
// you can bind multipart form with explicit binding declaration:
|
// you can bind multipart form with explicit binding declaration:
|
||||||
// c.ShouldBindWith(&form, binding.Form)
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
// or you can simply use autobinding with ShouldBind method:
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
var users Users
|
var users Users
|
||||||
// in this case proper binding will be automatically selected
|
// in this case proper binding will be automatically selected
|
||||||
if err := c.ShouldBind(&users); err != nil {
|
if err := c.ShouldBind(&users); err != nil {
|
||||||
c.String(http.StatusBadRequest, "bad request")
|
c.String(http.StatusBadRequest, "bad request")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := AuthLogin(connect, &users)
|
result, err := AuthLogin(connect, &users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusOK, fmt.Sprint(err))
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
} else {
|
} else {
|
||||||
if result == "success" {
|
if result == "success" {
|
||||||
// Create Login session
|
// Create Login session
|
||||||
session, err := CreateLoginSession(connect, &users)
|
session, err := CreateLoginSession(connect, &users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusExpectationFailed, "error")
|
c.String(http.StatusExpectationFailed, "error")
|
||||||
}
|
}
|
||||||
// TODO redirect to homepage
|
// TODO redirect to homepage
|
||||||
// Set client Cookie as Session ID
|
// Set client Cookie as Session ID
|
||||||
// To be changed when we use HTTPS
|
// To be changed when we use HTTPS
|
||||||
c.SetCookie("SessionID", session.SessionKey, 3600, "/", "*", false, true)
|
c.SetCookie("SessionID", session.SessionKey, 3600, "/", "*", false, true)
|
||||||
// redirects to the home page
|
// redirects to the home page
|
||||||
//c.Redirect(http.StatusFound, "/")
|
//c.Redirect(http.StatusFound, "/")
|
||||||
|
|
||||||
// Sends message success. which then redirects back to the home page
|
// Sends message success. which then redirects back to the home page
|
||||||
c.String(http.StatusOK, "Success!")
|
c.String(http.StatusOK, "Success!")
|
||||||
} else {
|
} else {
|
||||||
c.String(http.StatusOK, "Something is wrong with from our side. Email us: me@akilan.io to find out more. ")
|
c.String(http.StatusOK, "Something is wrong with from our side. Email us: me@akilan.io to find out more. ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Route for logout
|
// Route for logout
|
||||||
r.GET("/logout", func(c *gin.Context) {
|
r.GET("/logout", func(c *gin.Context) {
|
||||||
// Get client session ID
|
// Get client session ID
|
||||||
session, err := c.Cookie("SessionID")
|
session, err := c.Cookie("SessionID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Redirect(http.StatusFound, "/login")
|
c.Redirect(http.StatusFound, "/login")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove Session ID from the database
|
// Remove Session ID from the database
|
||||||
RemoveLoginSession(connect, session)
|
RemoveLoginSession(connect, session)
|
||||||
|
|
||||||
// redirect to the login page
|
// redirect to the login page
|
||||||
c.Redirect(http.StatusFound, "/login")
|
c.Redirect(http.StatusFound, "/login")
|
||||||
})
|
})
|
||||||
|
|
||||||
// Opens the registration page
|
// Opens the registration page
|
||||||
r.GET("/register", func(c *gin.Context) {
|
r.GET("/register", func(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "registration.html", gin.H{
|
c.HTML(http.StatusOK, "registration.html", gin.H{
|
||||||
"title": "Xplane11-WebRTC",
|
"title": "Xplane11-WebRTC",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Register user information required
|
// Register user information required
|
||||||
r.POST("/register", func(c *gin.Context) {
|
r.POST("/register", func(c *gin.Context) {
|
||||||
// you can bind multipart form with explicit binding declaration:
|
// you can bind multipart form with explicit binding declaration:
|
||||||
// c.ShouldBindWith(&form, binding.Form)
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
// or you can simply use autobinding with ShouldBind method:
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
var users Users
|
var users Users
|
||||||
// in this case proper binding will be automatically selected
|
// in this case proper binding will be automatically selected
|
||||||
if err := c.ShouldBind(&users); err != nil {
|
if err := c.ShouldBind(&users); err != nil {
|
||||||
c.String(http.StatusBadRequest, "bad request")
|
c.String(http.StatusBadRequest, "bad request")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = RegisterUser(connect, &users)
|
err = RegisterUser(connect, &users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusOK, fmt.Sprint(err))
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
} else {
|
} else {
|
||||||
c.String(http.StatusOK, "Success! Head back to the login page")
|
c.String(http.StatusOK, "Success! Head back to the login page")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add new server information
|
// Add new server information
|
||||||
r.POST("/AddGameSession", func(c *gin.Context) {
|
r.POST("/AddGameSession", func(c *gin.Context) {
|
||||||
|
|
||||||
// TODO: Binding
|
// TODO: Binding
|
||||||
// you can bind multipart form with explicit binding declaration:
|
// you can bind multipart form with explicit binding declaration:
|
||||||
// c.ShouldBindWith(&form, binding.Form)
|
// c.ShouldBindWith(&form, binding.Form)
|
||||||
// or you can simply use autobinding with ShouldBind method:
|
// or you can simply use autobinding with ShouldBind method:
|
||||||
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
// source: https://github.com/gin-gonic/gin#multiparturlencoded-binding
|
||||||
var gameSession GameSession
|
var gameSession GameSession
|
||||||
|
|
||||||
gameSession.Rate, _ = strconv.ParseFloat(c.PostForm("Rate"), 8)
|
gameSession.Rate, _ = strconv.ParseFloat(c.PostForm("Rate"), 8)
|
||||||
gameSession.Server.GPU = c.PostForm("GPU")
|
gameSession.Server.GPU = c.PostForm("GPU")
|
||||||
gameSession.Link = c.PostForm("Link")
|
gameSession.Link = c.PostForm("Link")
|
||||||
gameSession.Server.CPU = c.PostForm("CPU")
|
gameSession.Server.CPU = c.PostForm("CPU")
|
||||||
gameSession.Server.GPU = c.PostForm("GPU")
|
gameSession.Server.GPU = c.PostForm("GPU")
|
||||||
gameSession.Server.Platform = c.PostForm("Platform")
|
gameSession.Server.Platform = c.PostForm("Platform")
|
||||||
gameSession.Server.Hostname = c.PostForm("HostName")
|
gameSession.Server.Hostname = c.PostForm("HostName")
|
||||||
gameSession.Server.RAM = c.PostForm("RAM")
|
gameSession.Server.RAM = c.PostForm("RAM")
|
||||||
gameSession.Server.Disk = c.PostForm("Disk")
|
gameSession.Server.Disk = c.PostForm("Disk")
|
||||||
|
|
||||||
// in this case proper binding will be automatically selected
|
// in this case proper binding will be automatically selected
|
||||||
//if err := c.ShouldBind(&gameSession); err != nil {
|
//if err := c.ShouldBind(&gameSession); err != nil {
|
||||||
// c.String(http.StatusBadRequest, "bad request")
|
// c.String(http.StatusBadRequest, "bad request")
|
||||||
//}
|
//}
|
||||||
|
|
||||||
err = AddServerSpecs(connect, &gameSession)
|
err = AddServerSpecs(connect, &gameSession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusOK, fmt.Sprint(err))
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
} else {
|
} else {
|
||||||
c.String(http.StatusOK, "Success")
|
c.String(http.StatusOK, "Success")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
go CheckIfGameSessionIsActiveOrRemove(connect)
|
// route to add barrier IP information
|
||||||
|
r.POST("/AddBarrierIP", func(c *gin.Context) {
|
||||||
|
// Get client session ID
|
||||||
|
session, err := c.Cookie("SessionID")
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
}
|
||||||
|
|
||||||
// Run gin server on the specified port
|
barrierIP := c.PostForm("BarrierIP")
|
||||||
err = r.Run(":" + port)
|
MachineName := c.PostForm("MachineName")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
BarrierIP, err := AddBarrierIP(connect, session, barrierIP, MachineName)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, BarrierIP)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Removes barrier ip information from the table
|
||||||
|
// based on the barrier ip address provided.
|
||||||
|
r.POST("RemoveBarrierIP", func(c *gin.Context) {
|
||||||
|
// Get client session ID
|
||||||
|
_, err = c.Cookie("SessionID")
|
||||||
|
if err != nil {
|
||||||
|
c.Redirect(http.StatusFound, "/login")
|
||||||
|
}
|
||||||
|
|
||||||
|
barrierIP := c.PostForm("BarrierIP")
|
||||||
|
// Remove Barrier IP
|
||||||
|
err = RemoveBarrierIP(connect, barrierIP)
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusOK, fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.String(http.StatusOK, "BarrierIP removed successfully")
|
||||||
|
})
|
||||||
|
|
||||||
|
go CheckIfGameSessionIsActiveOrRemove(connect)
|
||||||
|
|
||||||
|
// Run gin server on the specified port
|
||||||
|
err = r.Run(":" + port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckIfGameSessionIsActiveOrRemove(gorm *gorm.DB) {
|
func CheckIfGameSessionIsActiveOrRemove(gorm *gorm.DB) {
|
||||||
for {
|
for {
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
Gamesessions, err := DisplayGameSessions(gorm)
|
Gamesessions, err := DisplayGameSessions(gorm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(Gamesessions) != 0 {
|
if len(Gamesessions) != 0 {
|
||||||
fmt.Println(Gamesessions[0].Link)
|
fmt.Println(Gamesessions[0].Link)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
for i, _ := range Gamesessions {
|
for i, _ := range Gamesessions {
|
||||||
req, err := http.NewRequest("GET", Gamesessions[i].Link, nil)
|
req, err := http.NewRequest("GET", Gamesessions[i].Link, nil)
|
||||||
// Sending request to the backend server
|
// Sending request to the backend server
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
_, err = client.Do(req)
|
_, err = client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// remove from database game session
|
// remove from database game session
|
||||||
_, err = RemoveTableGameSessionID(gorm, Gamesessions[i].GameSessionID)
|
_, err = RemoveTableGameSessionID(gorm, Gamesessions[i].GameSessionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Admin - Free Bulma template</title>
|
<title>Xplane WebRTC</title>
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
|
||||||
<!-- Bulma Version 0.9.0-->
|
<!-- Bulma Version 0.9.0-->
|
||||||
@@ -15,71 +15,140 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- START NAV -->
|
<!-- START NAV -->
|
||||||
<nav class="navbar is-white">
|
<nav class="navbar is-white">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a class="navbar-item brand-text" href="/">
|
<a class="navbar-item brand-text" href="/">
|
||||||
XPlane11-WebRTC
|
XPlane11-WebRTC
|
||||||
</a>
|
|
||||||
<div class="navbar-burger burger" data-target="navMenu">
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="navMenu" class="navbar-menu">
|
|
||||||
<div class="navbar-start">
|
|
||||||
<a class="navbar-item" href="/">
|
|
||||||
Home
|
|
||||||
</a>
|
|
||||||
<a class="navbar-item" href="/logout">
|
|
||||||
Logout
|
|
||||||
</a>
|
</a>
|
||||||
|
<div class="navbar-burger burger" data-target="navMenu">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="navMenu" class="navbar-menu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<a class="navbar-item" href="/">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="/logout">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</nav>
|
<!-- END NAV -->
|
||||||
<!-- END NAV -->
|
<div class="container">
|
||||||
<div class="container">
|
|
||||||
<div class="">
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<section class="hero is-info welcome is-small">
|
<div class="">
|
||||||
<div class="hero-body">
|
<section class="hero is-info welcome is-small">
|
||||||
<div class="container">
|
<div class="hero-body">
|
||||||
<h1 class="title">
|
<div class="container">
|
||||||
Hello, {{ .User.Name }}
|
<h1 class="title">
|
||||||
</h1>
|
Hello, {{ .User.Name }}
|
||||||
<h2 class="subtitle">
|
</h1>
|
||||||
I hope you are having a great day!
|
<h2 class="subtitle">
|
||||||
</h2>
|
I hope you are having a great day!
|
||||||
</article>
|
</h2>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
<section class="info-tiles">
|
||||||
<section class="info-tiles">
|
<div class="column is-6 row is-multiline">
|
||||||
<div class="tile is-ancestor has-text-centered row columns is-multiline">
|
<iframe src="https://www.youtube.com/embed/WVDSVhMW7o4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="width: 100%; height: 100%"></iframe>
|
||||||
{{ range .GameSessions }}
|
|
||||||
<div class="column is-4 tile is-parent">
|
|
||||||
<article class="tile is-child box">
|
|
||||||
<p class="title">{{ .Server.GPU }}</p>
|
|
||||||
<p style="color: #8F99A3; margin-top:-1.25rem; font-weight: 300; font-size: 1.25rem">RAM: {{ .Server.RAM }} MB</p>
|
|
||||||
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Rate: {{ .Rate }}$/hr </p>
|
|
||||||
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">CPU: {{ .Server.CPU }} </p>
|
|
||||||
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Disk: {{ .Server.Disk }} MB</p>
|
|
||||||
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Platform: {{ .Server.Platform }}</p>
|
|
||||||
<br>
|
|
||||||
<a href="{{ .Link }}" class="button is-block is-success is-fullwidth is-medium">Play</a>
|
|
||||||
</article>
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
<div class="column is-6 row is-multiline">
|
||||||
</div>
|
<div class="field is-horizontal">
|
||||||
</section>
|
<div class="field-label is-medium">
|
||||||
|
<label class="label">Barrier IP Address</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="text" placeholder="Barrier IP address">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label is-medium">
|
||||||
|
<label class="label">Machine Name</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-medium" type="text" placeholder="Machine name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<center><button class="button is-black" style="font-weight:700">Add Barrier Information</button>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
|
<div class="column is-6 row is-multiline">
|
||||||
|
<div class="card events-card">
|
||||||
|
<header class="card-header">
|
||||||
|
<p class="card-header-title">
|
||||||
|
Barrier Session information
|
||||||
|
</p>
|
||||||
|
<a href="#" class="card-header-icon" aria-label="more options">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa fa-angle-down" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</header>
|
||||||
|
<div class="card-table">
|
||||||
|
<div class="content">
|
||||||
|
<table class="table is-fullwidth is-striped">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="5%"></td>
|
||||||
|
<td>Barrier IP address and HostName</td>
|
||||||
|
<td class="level-right"><a class="button is-small bg-danger"
|
||||||
|
href="#">Remove</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <footer class="card-footer">
|
||||||
|
<a href="#" class="card-footer-item">Add Barrier session</a>
|
||||||
|
</footer> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tile is-ancestor has-text-centered row columns is-multiline">
|
||||||
|
{{ range .GameSessions }}
|
||||||
|
<div class="column is-4 tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<p class="title">{{ .Server.GPU }}</p>
|
||||||
|
<p style="color: #8F99A3; margin-top:-1.25rem; font-weight: 300; font-size: 1.25rem">
|
||||||
|
RAM: {{ .Server.RAM }} MB</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Rate: {{ .Rate }}$/hr
|
||||||
|
</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">CPU: {{ .Server.CPU }}
|
||||||
|
</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Disk: {{ .Server.Disk }}
|
||||||
|
MB</p>
|
||||||
|
<p style="color: #8F99A3; font-weight: 300; font-size: 1.25rem">Platform: {{
|
||||||
|
.Server.Platform }}</p>
|
||||||
|
<br>
|
||||||
|
<a href="{{ .Link }}" class="button is-block is-success is-fullwidth is-medium">Play</a>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<script async type="text/javascript" src="assets/js/bulma.js"></script>
|
||||||
<script async type="text/javascript" src="assets/js/bulma.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user