diff options
| author | Felix Hanley <felix@userspace.com.au> | 2020-03-31 04:53:01 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2020-03-31 04:53:01 +0000 |
| commit | 7a5dc7b8b58d869fe7f0fb57c1c7b8462afb4e81 (patch) | |
| tree | 07d015f4791acd91cb876828a72bbd186d431c4d | |
| parent | 74b027ce3b2c66ced134ca364cfbc249f02373ff (diff) | |
| download | sws-7a5dc7b8b58d869fe7f0fb57c1c7b8462afb4e81.tar.gz sws-7a5dc7b8b58d869fe7f0fb57c1c7b8462afb4e81.tar.bz2 | |
Filter updates and styling
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | charts.go | 2 | ||||
| -rw-r--r-- | cmd/server/routes.go | 47 | ||||
| -rw-r--r-- | sass/main.scss | 39 | ||||
| -rw-r--r-- | tmpl/filter.tmpl | 153 | ||||
| -rw-r--r-- | tmpl/hitView.tmpl | 10 | ||||
| -rw-r--r-- | tmpl/layout.tmpl | 2 | ||||
| -rw-r--r-- | tmpl/navbar.tmpl | 2 | ||||
| -rw-r--r-- | tmpl/site.tmpl | 25 | ||||
| -rw-r--r-- | tmpl/sites.tmpl | 25 |
10 files changed, 183 insertions, 123 deletions
@@ -7,4 +7,5 @@ counter/sws.min.js cmd/server/migrations.go cmd/server/counter.go cmd/server/templates.go +static/default.css *.db @@ -95,7 +95,7 @@ func SparklineSVG(w io.Writer, data *HitSet, d time.Duration) error { hits.XValues, hits.YValues = xVals, yVals graph := gochart.Chart{ - Width: 300, + Width: 600, Height: 50, Series: []gochart.Series{hits}, // Background: gochart.Style{ diff --git a/cmd/server/routes.go b/cmd/server/routes.go index ae018b6..cd89739 100644 --- a/cmd/server/routes.go +++ b/cmd/server/routes.go @@ -87,27 +87,6 @@ func createRouter(db sws.Store, mmdbPath string) (chi.Router, error) { r.Post(loginURL, handleLogin(db, rndr)) - // Static files - r.Get("/*", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - p := strings.TrimPrefix(r.URL.Path, "/") - debug("loading", p) - if b, err := loadTemplate(p); err == nil { - name := filepath.Base(p) - etag := fmt.Sprintf(`"%x"`, sha1.Sum(b)) - - if match := r.Header.Get("If-None-Match"); match != "" { - if strings.Contains(match, etag) { - w.WriteHeader(http.StatusNotModified) - return - } - } - - w.Header().Set("Etag", etag) - w.Header().Set("Cache-Control", "no-cache") - http.ServeContent(w, r, name, time.Now(), bytes.NewReader(b)) - } - })) - // Authed routes r.Group(func(r chi.Router) { // Ensure we have a user in context @@ -155,6 +134,32 @@ func createRouter(db sws.Store, mmdbPath string) (chi.Router, error) { }) }) }) + + // Static files + r.Get("/*", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := strings.TrimPrefix(r.URL.Path, "/") + debug("loading static", p) + b, err := loadTemplate(p) + if err == nil { + name := filepath.Base(p) + etag := fmt.Sprintf(`"%x"`, sha1.Sum(b)) + + if match := r.Header.Get("If-None-Match"); match != "" { + if strings.Contains(match, etag) { + w.WriteHeader(http.StatusNotModified) + return + } + } + + w.Header().Set("Etag", etag) + w.Header().Set("Cache-Control", "no-cache") + http.ServeContent(w, r, name, time.Now(), bytes.NewReader(b)) + } + debug("no template found, trying files") + fs := http.FileServer(http.Dir("public")) + fs.ServeHTTP(w, r) + //log("file not found:", p, err) + })) }) r.NotFound(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/sass/main.scss b/sass/main.scss index 78f3064..bbcf415 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -22,31 +22,54 @@ $card-header-shadow: 0; @import "../node_modules/bulma/sass/components/menu"; @import "../node_modules/bulma/sass/components/card"; +$gutter: 1rem; +$header-height: 3.25rem; + .navbar { position: fixed; width: 100%; } .page { display: flex; - flex-direction: row; flex-wrap: wrap; justify-content: space-between; - margin-left: 24px; - margin-right: 24px; + margin-left: $gutter; + margin-right: $gutter; } -.header { - width: 100%; +.page--sites { + flex-direction: column; } -.level { +.page--site { + flex-direction: row; + padding-top: $navbar-height + $header-height + $gutter; +} +.header--site { + display: flex; + position: fixed; + top: $header-height; + left: $gutter; + right: $gutter; + z-index: 100; + background-color: white; + padding: .5em; +} +.header__title { + flex: 1; +} +.filter { + flex: 1; +} +.site__summary { width: 100%; } .card { - // background-color: #fff; border: 1px solid #e6e9ed; - flex: 1 1 400px; margin: .5em; padding: .5em; } +.card--narrow { + flex: 1 1 400px; +} .card--wide { flex: 1 1 100%; } diff --git a/tmpl/filter.tmpl b/tmpl/filter.tmpl index ce9ff95..e039281 100644 --- a/tmpl/filter.tmpl +++ b/tmpl/filter.tmpl @@ -1,73 +1,96 @@ {{ define "filter" }} - <div class="timerange"> - <!-- - <form> - <input type="date" name="bdate" value="{{ .Begin|dateRFC }}" /> - <input type="time" name="btime" value="{{ .Begin|timeRFC }}" /> - <input type="date" name="edate" value="{{ .End|dateRFC }}" /> - <input type="time" name="etime" value="{{ .End|timeRFC }}" /> - <select name="timezone"> - <option value="-39600">-1100</option> - <option value="-36000">-1000</option> - <option value="-32400">-0900</option> - <option value="-28800">-0800</option> - <option value="-25200">-0700</option> - <option value="-21600">-0600</option> - <option value="-18000">-0500</option> - <option value="-14400">-0400</option> - <option value="-10800">-0300</option> - <option value="-7200">-0200</option> - <option value="-3600">-0100</option> - <option value="0">UTC</option> - <option value="3600">+0100</option> - <option value="7200">+0200</option> - <option value="10800">+0300</option> - <option value="14400">+0400</option> - <option value="18000">+0500</option> - <option value="21600">+0600</option> - <option value="25200">+0700</option> - <option value="28800">+0800</option> - <option value="32400">+0900</option> - <option value="36000">+1000</option> - <option value="39600">+1100</option> - </select> - </form> - --> - <a href="?{{ datetimeRelative "-24h" | .QuerySetEncode "begin" }}">last day</a> - <a href="?{{ datetimeRelative "-168h" | .QuerySetEncode "begin" }}">last 7 days</a> - <a href="?{{ datetimeRelative "-720h" | .QuerySetEncode "begin" }}">last 30 days</a> - <a href="?{{ .QuerySetEncode "bots" "0" }}">without bots</a> - <a href="?{{ .QuerySetEncode "bots" "1" }}">only bots</a> - </div> - <div class="field is-grouped is-grouped-multiline"> - <div class="control"> - {{ if .QuerySetContains "bots" }} - {{ $bots := .Query.Get "bots" }} - {{ if eq $bots "0" }} - <div class="tags has-addons"> - <a class="tag is-link">No bots</a> - <a class="tag is-delete" href="?{{ .QuerySetEncode "bots" "" }}"></a> - </div> - {{ end }} - {{ if eq $bots "1" }} - <div class="tags has-addons"> - <a class="tag is-link">Only bots</a> + <div class="filter tags field is-grouped"> + <span>Filters:</span> + {{ if .QuerySetContains "bots" }} + {{ $bots := .Query.Get "bots" }} + {{ if eq $bots "0" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "bots" "" }}">no bots</a> <a class="tag is-delete" href="?{{ .QuerySetEncode "bots" "" }}"></a> - </div> - {{ end }} - {{ end }} - {{ if .QuerySetContains "country" }} - <div class="tags has-addons"> - <a class="tag is-link">Country {{ .Query.Get "country" }}</a> - <a class="tag is-delete" href="?{{ .QuerySetEncode "country" "" }}"></a> + </span> </div> {{ end }} - {{ if .QuerySetContains "begin" }} - <div class="tags has-addons"> - <a class="tag is-link">Time filter</a> - <a class="tag is-delete" href="?{{ .QuerySetEncode "begin" "" }}"></a> + {{ if eq $bots "1" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "bots" "" }}">only bots</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "bots" "" }}"></a> + </span> </div> {{ end }} - </div> + {{ else }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-info" href="?{{ .QuerySetEncode "bots" "0" }}">bots</a> + <a class="tag is-light" href="?{{ .QuerySetEncode "bots" "0" }}">without</a> + </span> + </div> + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-info" href="?{{ .QuerySetEncode "bots" "1" }}">bots</a> + <a class="tag is-light" href="?{{ .QuerySetEncode "bots" "1" }}">only</a> + </span> + </div> + {{ end }} + {{ if .QuerySetContains "country" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "country" "" }}">country {{ .Query.Get "country" }}</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "country" "" }}"></a> + </span> + </div> + {{ end }} + {{ if .QuerySetContains "path" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "path" "" }}">path</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "path" "" }}"></a> + </span> + </div> + {{ end }} + {{ if .QuerySetContains "browser" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "browser" "" }}">browser</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "browser" "" }}"></a> + </span> + </div> + {{ end }} + {{ if .QuerySetContains "referrer" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "referrer" "" }}">referrer</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "referrer" "" }}"></a> + </span> + </div> + {{ end }} + {{ if .QuerySetContains "begin" }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-danger" href="?{{ .QuerySetEncode "begin" "" }}">time</a> + <a class="tag is-delete" href="?{{ .QuerySetEncode "begin" "" }}"></a> + </span> + </div> + {{ else }} + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-info" href="?{{ datetimeRelative "-24h" | .QuerySetEncode "begin" }}">days</a> + <a class="tag is-light" href="?{{ datetimeRelative "-24h" | .QuerySetEncode "begin" }}">1</a> + </span> + </div> + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-info" href="?{{ datetimeRelative "-168h" | .QuerySetEncode "begin" }}">days</a> + <a class="tag is-light" href="?{{ datetimeRelative "-168h" | .QuerySetEncode "begin" }}">7</a> + </span> + </div> + <div class="control"> + <span class="tags has-addons"> + <a class="tag is-info" href="?{{ datetimeRelative "-720h" | .QuerySetEncode "begin" }}">days</a> + <a class="tag is-light" href="?{{ datetimeRelative "-720h" | .QuerySetEncode "begin" }}">30</a> + </span> + </div> + {{ end }} </div> {{ end }} diff --git a/tmpl/hitView.tmpl b/tmpl/hitView.tmpl index 3deb96b..f7d4dcb 100644 --- a/tmpl/hitView.tmpl +++ b/tmpl/hitView.tmpl @@ -17,7 +17,7 @@ </section> {{ if .PageSet }} - <section id="pages" class="card"> + <section id="pages" class="card card--narrow"> <header class="card-header"> <h3 class="card-header-title">Top 10 pages</h3> </header> @@ -47,7 +47,7 @@ </section> {{ end }} - <section id="countries" class="card"> + <section id="countries" class="card card--narrow"> <header class="card-header"> <h3 class="card-header-title">Countries</h3> </header> @@ -73,7 +73,7 @@ </div> </section> - <section id="referrers" class="card"> + <section id="referrers" class="card card--narrow"> <header class="card-header"> <h3 class="card-header-title">Referrers</h3> </header> @@ -97,7 +97,7 @@ </div> </section> - <section id="useragents" class="card"> + <section id="useragents" class="card card--narrow"> <header class="card-header"> <h3 class="card-header-title">User agents</h3> </header> @@ -125,7 +125,7 @@ {{ end }} {{ define "siteSummary" }} - <section class="level"> + <section class="site__summary level"> {{ with .Hits }} <div class="level-item has-text-centered"> <div> diff --git a/tmpl/layout.tmpl b/tmpl/layout.tmpl index 4ab0db0..056ce60 100644 --- a/tmpl/layout.tmpl +++ b/tmpl/layout.tmpl @@ -7,7 +7,7 @@ </head> <body class="has-navbar-fixed-top"> {{ template "navbar" . }} - <main class="page"> + <main class="page{{ if .Sites }} page--sites{{ end }}{{ if .Site }} page--site{{ end }}"> {{ template "flash" . }} {{ template "content" . }} </main> diff --git a/tmpl/navbar.tmpl b/tmpl/navbar.tmpl index f49ae6f..b7a1cd7 100644 --- a/tmpl/navbar.tmpl +++ b/tmpl/navbar.tmpl @@ -2,7 +2,7 @@ <nav class="navbar is-black is-fixed-top" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <a class="navbar-item" href="//{{ .Domain }}"> - <img src="//{{ .Domain }}/logo.png" width="112" height="28"> + <img src="//{{ .Domain }}/favicon64.png" height="28"> </a> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarMain"> diff --git a/tmpl/site.tmpl b/tmpl/site.tmpl index 4f4ffc3..c44f8f0 100644 --- a/tmpl/site.tmpl +++ b/tmpl/site.tmpl @@ -1,20 +1,23 @@ {{ define "content" }} - <header class="header header--site"> - {{ if .Site.ID }} - {{ with .Site }} - <h1 class="title title--site">Hits for {{ .Name }}</h1> - <span class="subtitle">{{ .Description }}</span> + {{ if .Site.ID }} + <header class="header header--site"> + <div class="header__title"> + {{ with .Site }} + <h1 class="title title--site">{{ .Name }}</h1> + {{ end }} + </div> + {{ if .Site.ID }} + {{ template "filter" . }} {{ end }} - {{ else }} + </header> + {{ else }} + <header class="header header--site"> <h1 class="title--site">New Site</h1> - {{ end }} - </header> + </header> + {{ end }} {{ template "siteSummary" . }} - {{ if .Site.ID }} - {{ template "filter" . }} - {{ end }} {{ if .Hits }} {{ template "hitView" . }} {{ else }} diff --git a/tmpl/sites.tmpl b/tmpl/sites.tmpl index 044e595..9d449f6 100644 --- a/tmpl/sites.tmpl +++ b/tmpl/sites.tmpl @@ -2,17 +2,22 @@ <header> <h1 class="title">Sites</h1> </header> - <ul class="sites"> - {{ range .Sites }} - {{ template "siteForList" . }} - {{ end }} - </ul> + {{ range .Sites }} + {{ template "siteForList" . }} + {{ end }} {{ end }} {{ define "siteForList" }} - <li> - <a href="/sites/{{ .ID }}/">{{ .Name }}</a> - <span>{{ .Description }}</span> - <img src="{{ sparkline .ID }}" /> - </li> + <a class="site card" href="/sites/{{ .ID }}/"> + <div class="card-header"> + <object data="/favicon64.png" type="image/png"> + <img class="card-header-icon" src="//{{ .Name }}/favicon.ico" alt="{{ .Name }} favicon" /> + </object> + <span class="card-header-title">{{ .Name }}</span> + <img src="{{ sparkline .ID }}" /> + </div> + <div class="card-content"> + {{ .Description }} + </div> + </a> {{ end }} |
