diff --git a/web/dashboard-contact.html b/web/dashboard-contact.html new file mode 100644 index 00000000..c66f754a --- /dev/null +++ b/web/dashboard-contact.html @@ -0,0 +1,49 @@ +{{template "header" .}} + + +
+ +
+| Exchange | +LAST - BTC/USD | +LAST - LTC/USD | +LAST - BTC/LTC | ++ |
|---|---|---|---|---|
| SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +
+
| DATE/TIME | +EXCHANGE | +CURRENCIES USED | +PROFIT LOSS | ++ |
|---|---|---|---|---|
| SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +
| Trade Execution date | +Trade Exchange | +Trade Type | +Initial Investment | +PROFIT/LOSS | +
|---|---|---|---|---|
| SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +SOMETHING HERE | +
The error {{.Error}} has occured.
++ +
+Index
++ This is the login page.... +
+goto dashboard +{{template "footer" .}} diff --git a/web/static/css/cover.css b/web/static/css/cover.css new file mode 100644 index 00000000..f4d789e9 --- /dev/null +++ b/web/static/css/cover.css @@ -0,0 +1,163 @@ +/* + * Globals + */ + +/* Links */ +a, +a:focus, +a:hover { + color: #fff; +} + +/* Custom default button */ +.btn-default, +.btn-default:hover, +.btn-default:focus { + color: #333; + text-shadow: none; /* Prevent inheritence from `body` */ + background-color: #fff; + border: 1px solid #fff; +} + + +/* + * Base structure + */ + +html, +body { + height: 100%; + background-color: #333; +} +body { + color: #fff; + text-align: center; + text-shadow: 0 1px 3px rgba(0,0,0,.5); +} + +/* Extra markup and styles for table-esque vertical and horizontal centering */ +.site-wrapper { + display: table; + width: 100%; + height: 100%; /* For at least Firefox */ + min-height: 100%; + -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5); + box-shadow: inset 0 0 100px rgba(0,0,0,.5); +} +.site-wrapper-inner { + display: table-cell; + vertical-align: top; +} +.cover-container { + margin-right: auto; + margin-left: auto; +} + +/* Padding for spacing */ +.inner { + padding: 30px; +} + + +/* + * Header + */ +.masthead-brand { + margin-top: 10px; + margin-bottom: 10px; +} + +.masthead-nav > li { + display: inline-block; +} +.masthead-nav > li + li { + margin-left: 20px; +} +.masthead-nav > li > a { + padding-right: 0; + padding-left: 0; + font-size: 16px; + font-weight: bold; + color: #fff; /* IE8 proofing */ + color: rgba(255,255,255,.75); + border-bottom: 2px solid transparent; +} +.masthead-nav > li > a:hover, +.masthead-nav > li > a:focus { + background-color: transparent; + border-bottom-color: #a9a9a9; + border-bottom-color: rgba(255,255,255,.25); +} +.masthead-nav > .active > a, +.masthead-nav > .active > a:hover, +.masthead-nav > .active > a:focus { + color: #fff; + border-bottom-color: #fff; +} + +@media (min-width: 768px) { + .masthead-brand { + float: left; + } + .masthead-nav { + float: right; + } +} + + +/* + * Cover + */ + +.cover { + padding: 0 20px; +} +.cover .btn-lg { + padding: 10px 20px; + font-weight: bold; +} + + +/* + * Footer + */ + +.mastfoot { + color: #999; /* IE8 proofing */ + color: rgba(255,255,255,.5); +} + + +/* + * Affix and center + */ + +@media (min-width: 768px) { + /* Pull out the header and footer */ + .masthead { + position: fixed; + top: 0; + } + .mastfoot { + position: fixed; + bottom: 0; + } + /* Start the vertical centering */ + .site-wrapper-inner { + vertical-align: middle; + } + /* Handle the widths */ + .masthead, + .mastfoot, + .cover-container { + width: 100%; /* Must be percentage or pixels for horizontal alignment */ + } +} + +@media (min-width: 992px) { + .masthead, + .mastfoot, + .cover-container { + width: 700px; + } +} \ No newline at end of file diff --git a/web/static/css/dashboard.css b/web/static/css/dashboard.css new file mode 100644 index 00000000..de315748 --- /dev/null +++ b/web/static/css/dashboard.css @@ -0,0 +1,105 @@ +/* + * Base structure + */ + +/* Move down content because we have a fixed navbar that is 50px tall */ +body { + padding-top: 50px; +} + + +/* + * Global add-ons + */ + +.sub-header { + padding-bottom: 10px; + border-bottom: 1px solid #eee; +} + +/* + * Top navigation + * Hide default border to remove 1px line. + */ +.navbar-fixed-top { + border: 0; +} + +/* + * Sidebar + */ + +/* Hide for mobile, show later */ +.sidebar { + display: none; +} +@media (min-width: 768px) { + .sidebar { + position: fixed; + top: 51px; + bottom: 0; + left: 0; + z-index: 1000; + display: block; + padding: 20px; + overflow-x: hidden; + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + background-color: #f5f5f5; + border-right: 1px solid #eee; + } +} + +/* Sidebar navigation */ +.nav-sidebar { + margin-right: -21px; /* 20px padding + 1px border */ + margin-bottom: 20px; + margin-left: -20px; +} +.nav-sidebar > li > a { + padding-right: 20px; + padding-left: 20px; +} +.nav-sidebar > .active > a, +.nav-sidebar > .active > a:hover, +.nav-sidebar > .active > a:focus { + color: #fff; + background-color: #428bca; +} + + +/* + * Main content + */ + +.main { + padding: 20px; +} +@media (min-width: 768px) { + .main { + padding-right: 40px; + padding-left: 40px; + } +} +.main .page-header { + margin-top: 0; +} + + +/* + * Placeholder dashboard ideas + */ + +.placeholders { + margin-bottom: 30px; + text-align: center; +} +.placeholders h4 { + margin-bottom: 0; +} +.placeholder { + margin-bottom: 20px; +} +.placeholder img { + display: inline-block; + border-radius: 50%; +} \ No newline at end of file diff --git a/webserver.go b/webserver.go index df7daf66..fe54fdcb 100644 --- a/webserver.go +++ b/webserver.go @@ -2,11 +2,24 @@ package main import ( "html/template" + "io/ioutil" "log" "net/http" "strconv" ) +type Page struct { + Title string + StaticStylesheet template.HTML + Body []byte + Error string +} + +const ( + coverCSS = `` + dashboardCSS = `` +) + func GetWebserverHost() string { host := SplitStrings(bot.config.Webserver.ListenAddress, ":")[0] if host == "" { @@ -22,6 +35,8 @@ func GetWebserverPort() int { } func StartWebserver() error { + fs := http.FileServer(http.Dir("web")) + http.Handle("/web/", http.StripPrefix("/web/", fs)) http.HandleFunc("/", index) var err error go func() { @@ -39,16 +54,62 @@ func ServerHTTPError(w http.ResponseWriter, err error) { func index(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") - tmpl, err := template.ParseFiles("web/index.html", "web/header.html", "web/footer.html") - if err != nil { - ServerHTTPError(w, err) - return - } - - tmplValues := map[string]interface{}{"title": "Home"} - tmpl.Execute(w, tmplValues) - if err != nil { - ServerHTTPError(w, err) - return + switch r.URL.Path { + case "/": + renderTemplate(w, "index.html", readPage("/index")) + case "/login": + renderTemplate(w, "login.html", readPage(r.URL.Path)) + case "/logout": + renderTemplate(w, "index.html", readPage("/index")) + case "/dashboard-marketdepth": + renderTemplate(w, "dashboard-marketdepth.html", readPage(r.URL.Path)) + case "/dashboard-ordermanagement": + renderTemplate(w, "dashboard-ordermanagement.html", readPage(r.URL.Path)) + case "/dashboard-contact": + renderTemplate(w, "dashboard-contact.html", readPage(r.URL.Path)) + case "/dashboard-settings": + renderTemplate(w, "dashboard-settings.html", readPage(r.URL.Path)) + case "/dashboard-reports": + renderTemplate(w, "dashboard-reports.html", readPage(r.URL.Path)) + default: + w.WriteHeader(http.StatusNotFound) + renderTemplate(w, "error.html", readPage("/error")) + } +} + +func readPage(client string) *Page { + filename := "web/" + client[1:] + ".html" + body, err := ioutil.ReadFile(filename) + if err != nil { + log.Println("Webserver: Failed to open file -- ", err, "client string is: ", client) + return nil + } + stylesheet := setStylesheet(client) + return &Page{Title: client[1:], StaticStylesheet: stylesheet, Body: body} +} + +func setStylesheet(client string) template.HTML { + if len(client) >= 10 { + if client[:10] == "/dashboard" { + return template.HTML(dashboardCSS) + } + } + return template.HTML(coverCSS) +} + +func renderTemplate(w http.ResponseWriter, pageName string, p *Page) { + tmpl, err := template.ParseFiles("web/index.html", "web/header.html", + "web/footer.html", "web/dashboard-marketdepth.html", "web/login.html", + "web/dashboard-ordermanagement.html", "web/dashboard-reports.html", + "web/dashboard-settings.html", "web/dashboard-contact.html", "web/error.html") + + if err != nil { + log.Println("Webserver: Could not parsefile -- ", err) + ServerHTTPError(w, err) + return + } + err = tmpl.ExecuteTemplate(w, pageName, p) + if err != nil { + log.Println("Webserver: Could not execute template -- ", err) } }