diff options
Diffstat (limited to 'layouts')
-rw-r--r-- | layouts/_default/single.html (renamed from layouts/incident/single.html) | 7 | ||||
-rw-r--r-- | layouts/incident/post.html | 8 | ||||
-rw-r--r-- | layouts/index.html | 275 | ||||
-rw-r--r-- | layouts/issues/issue.html | 29 | ||||
-rw-r--r-- | layouts/issues/single.html | 17 | ||||
-rw-r--r-- | layouts/partials/footer.html | 20 | ||||
-rw-r--r-- | layouts/partials/header-mini.html | 7 | ||||
-rw-r--r-- | layouts/partials/js.html | 62 | ||||
-rw-r--r-- | layouts/partials/meta.html | 194 | ||||
-rw-r--r-- | layouts/shortcodes/track.html | 1 |
10 files changed, 288 insertions, 332 deletions
diff --git a/layouts/incident/single.html b/layouts/_default/single.html index 92ead19..c0a9070 100644 --- a/layouts/incident/single.html +++ b/layouts/_default/single.html @@ -1,13 +1,10 @@ {{ partial "meta" . }} <body> - <div class="contain"> <a href="{{ .Site.BaseURL }}">← Go back</a> - - <br><br><hr> - - {{ .Render "post"}} + <hr> + {{ .Render "post" }} </div> {{ partial "footer" . }} diff --git a/layouts/incident/post.html b/layouts/incident/post.html deleted file mode 100644 index 593481a..0000000 --- a/layouts/incident/post.html +++ /dev/null @@ -1,8 +0,0 @@ -<div class="article"> - <h3> - <a href="{{ .Permalink }}">{{ .Title }} {{ if .Draft }}[DRAFT]{{ end }}</a> - </h3> - <h4>Began on {{ .Date }} ({{ .ReadingTime }} min read)</h4> - - {{ .Content }} -</div> diff --git a/layouts/index.html b/layouts/index.html index 85b800a..68a1265 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -1,244 +1,83 @@ {{ partial "meta" . }} - - <body> - <div class="header notice"> - <div class="contain"> - <a href="{{ .Site.BaseURL }}" class="logo"> - <img src="{{ .Site.Params.logo }}" alt="{{ .Site.Title }}"> +{{ $incidents := where .Site.RegularPages "Params.section" "issue" }} +{{ $active := where $incidents "Params.resolved" "=" false }} + +{{ $isNotice := where $active "Params.severity" "=" "notice" }} +{{ $isDisrupted := where $active "Params.severity" "=" "disrupted" }} +{{ $isDown := where $active "Params.severity" "=" "down" }} + + <body class="status-{{ if $isDown }}down{{ else }}{{ if $isDisrupted}}disrupted{{ else }}{{ if $isNotice }}notice{{ else }}ok{{ end }}{{ end }}{{ end }}"> + <div class="header"> + <div class="contain contain--more center"> + <a href="/" class="logo"> + {{ if .Site.Params.useLogo }} + <h1><img src="{{ .Site.Params.logo }}" alt="{{ .Site.Title }}"></h1> + {{ else }} + <h1>{{ .Site.Title }}</h1> + {{ end }} </a> - - <button class="subscribe">Subscribe</button> </div> </div> <!-- Main --> <div class="contain"> <noscript> - <p class="error">Uh oh! It looks like you have disabled JavaScript or your browser is a piece of garbage. This means we cannot fetch the neccesary data to show you information about our services. Please <a href="//enable-javascript.com">enable scripting</a> and try again.</p> + <p class="error">Uh oh! It looks like you have disabled JavaScript. Please <a href="//enable-javascript.com">enable scripting</a> to enhance your experience on this website.</p> + <div class="padding"></div> </noscript> - <div class="subscriber-box"> - <div class="subscriber-box--header"> - <div class="contain"> - <strong>Notifications</strong> - <span class="close"> - <img alt="Close" src="https://cdn4.iconfinder.com/data/icons/geomicons/32/672366-x-128.png"> - </span> - </div> - </div> - - <div class="contain"> - <p>Users of modern browsers such as Chrome and Firefox get access to web notifications, a feature that shows alerts for things such as Facebook mentions, new emails, or in our case, status updates. These updates can be seen even if the user is not actively looking at this status page, however, the tab has to stay open.</p> - - <p class="error">Only some users may be able to use this feature. This feature does not work on mobile devices and is not fully tested.</p> - - <div id="alert-init"> - <input type="checkbox" id="alerts"> - <label for="alerts">Ping me when the status changes</label> - </div> - - <p class="alert-status faded">You have not enabled notifications.</p> - </div> + <!-- Main info --> + <div class="summary"> + <strong> + {{ if $isDown }} + Experiencing major issues + {{ else }} + {{ if $isDisrupted}} + Experiencing disruptions + {{ else }} + {{ if $isNotice }} + Please read announcement + {{ else }} + All systems operational + {{ end }}{{ end }}{{ end }} + </strong> + + <span class="status summary__date" onclick="location.reload()"></span> </div> - <!-- Main info --> - <div class="summary notice"> - <div class="tldr notice"> - <strong>Checking status…</strong> + {{ range $active }} + <div class="padding"></div> + <small class="date">{{ .Date.Format "January 02, 2006 at 3:04 PM" }}</small><br> + <strong class="faded">{{ .Title }}</strong> + {{ .Content }} + <div class="padding"></div> + {{ else }}{{ end }} - <span class="status"></span> - </div> - <div class="details contain"> - <p>{{ .Site.Params.announcement }}</p> - </div> - </div><br> + <div class="padding"></div> <!-- Individual info --> <div class="components"> - <div class="component" data-status="" data-id="forums"> - API <small class="ping testing">Pinging…</small> - </div> - <div class="component" data-status="" data-id="website"> - Website <small class="ping testing">Pinging…</small> - </div> + {{ $systems := .Site.Params.systems }} + {{ range $index, $systems }} + <div class="component" data-status="ok"> + {{ . }} + <span class="component-status">Operational</span> + </div> + {{ end }} </div> - <br> - <small><a href="#disclaimer">Disclaimer</a></small> - <!-- End main --> - </div> + </div><div class="padding"></div><hr> <div class="contain"> - <h2>Incident history</h2><hr><br> + <h2 class="center">Incident history</h2> {{ range first 10 .Data.Pages }} - {{ .Render "post" }} + {{ .Render "issue" }} {{ end }} - - <aside id="meta"> </aside> </div> - <script async> - /** - * Dev toolset - */ - - console.log('Welcome to cState! https://github.com/mistermantas/cstate'); - - /** - * Notifications - */ - - // Notification toggle - document.querySelector('#alerts').addEventListener('click', enableNotifications) - - // Toggling logic - function enableNotifications() { - if(window.Notification && Notification.permission !== "denied") { - Notification.requestPermission(function(status) { - // status is "granted", if accepted by user - var n = new Notification('Great, you just enabled alerts!', { - body: 'You are now going to receive notifications (like this one) whenever the status changes so long as this tab is open. This feature is still being tested.', - icon: '/favicon.ico' - }) - - // Looks like we DO have permission now - // So let's mark that checkbox - document.querySelector('#alert-init').setAttribute('hidden', 'hidden') - document.querySelector('.alert-status').innerHTML = '<strong>Notifications are enabled. </strong>' - document.querySelector('.alert-status').className = 'alert-status' - }) - } - } - - if (Notification.permission === 'granted') { - // Looks like we DO have permission - // So let's mark that checkbox - document.querySelector('#alert-init').setAttribute('hidden', 'hidden') - document.querySelector('.alert-status').innerHTML = '<strong>Notifications are enabled. </strong>' - document.querySelector('.alert-status').className = 'alert-status' - } - - /** - * Subscribe button - */ - - function hasClass(element, cls) { - return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; - } - - document.querySelector('.subscribe').addEventListener('click', pressSubscribeButton); - document.querySelector('.close').addEventListener('click', pressSubscribeButton); - - function pressSubscribeButton() { - if (document.querySelector('.subscriber-box').className === 'subscriber-box active') { - document.querySelector('.subscriber-box').className = 'subscriber-box'; - } else { - document.querySelector('.subscriber-box').className = 'subscriber-box active'; - } - } - - /** - * Apply data - */ - - document.querySelector('.component[data-id=forums]').setAttribute('data-status', 'ok'); - document.querySelector('.component[data-id=website]').setAttribute('data-status', 'ok'); - - /** - * Get elements - */ - - const header = document.querySelector('.header'); - const summary = document.querySelector('.summary'); - const summaryDetails = document.querySelector('.details'); - const tldr = document.querySelector('.tldr'); - - var summaryText = document.querySelector('.summary strong'); - var lastUpdated = document.querySelector('.summary span'); - - /** - * Prelimenary logic - */ - - var online = navigator.onLine; - - function updateStatus() { - var lastUpdate = new Date; - } - - /** - * Check for internet - */ - - var lastUpdate = new Date(); - - function timeSince(date) { - var seconds = Math.floor((new Date() - date) / 1000); - - var interval = Math.floor(seconds / 31536000); - - if (interval > 1) { - return interval + ' years'; - } - interval = Math.floor(seconds / 2592000); - if (interval > 1) { - return interval + ' months'; - } - interval = Math.floor(seconds / 86400); - if (interval > 1) { - return interval + 'd'; - } - interval = Math.floor(seconds / 3600); - if (interval > 1) { - return interval + 'h'; - } - interval = Math.floor(seconds / 60); - if (interval > 1) { - return interval + 'min'; - } - return Math.floor(seconds) + 's'; - } - var aDay = 24*60*60*1000; - - // Show second by second updates - window.setInterval(function() { - lastUpdated.innerHTML = 'Last updated ' + timeSince(lastUpdate) + ' ago'; - }, 1000); - - - /** - * Adaptive TLDR - */ - - const status = document.querySelector('.component[data-id=forums]').getAttribute('data-status') === 'ok' && - document.querySelector('.component[data-id=website]').getAttribute('data-status') === 'ok' - - if (status) { - // Change text - summaryText.innerHTML = 'All systems operational'; - // Change design - summary.className = 'summary ok'; - tldr.className = 'tldr ok'; - summaryDetails.className = 'details contain ok'; - header.className = 'header ok'; - } else if (!status) { - // Change text - summaryText.innerHTML = 'Experiencing downtime'; - // Change design - summary.className = 'summary down'; - tldr.className = 'tldr down'; - summaryDetails.className = 'details contain down'; - header.className = 'header down'; - - new Notification ( - 'We are experiencing downtime!', { - body : 'Please view the status page for more information. This alert was automatically triggered to let you know of this change.', - icon : '/favicon.ico' - } - ) - } - </script> - -{{ partial "footer" . }} + {{ partial "js" . }} + {{ partial "footer" . }} + </body> +</html> diff --git a/layouts/issues/issue.html b/layouts/issues/issue.html new file mode 100644 index 0000000..9b63b78 --- /dev/null +++ b/layouts/issues/issue.html @@ -0,0 +1,29 @@ +{{ $incidents := where .Site.RegularPages "Params.section" "issue" }} +{{ $active := where $incidents "Params.resolved" "=" false }} + +{{ $isNotice := where $active "Params.severity" "=" "notice" }} +{{ $isDisrupted := where $active "Params.severity" "=" "disrupted" }} +{{ $isDown := where $active "Params.severity" "=" "down" }} + +<div class="article"> + <span class="marker"> + {{ .Params.severity }} + </span> + + <small class="date"> + {{ .Date.Format "January 02, 2006 at 3:04 PM" }} + </small> + + {{ if .Params.Resolved }} + <span class="ok">✓</span> + {{ end }} + + + <h3> + <a href="{{ .Permalink }}">{{ .Title }}</a> + </h3> + + <hr> + + {{ .Content }} +</div> diff --git a/layouts/issues/single.html b/layouts/issues/single.html new file mode 100644 index 0000000..52c4145 --- /dev/null +++ b/layouts/issues/single.html @@ -0,0 +1,17 @@ +{{ partial "meta" . }} + +{{ $incidents := where .Site.RegularPages "Params.section" "issue" }} +{{ $active := where $incidents "Params.resolved" "=" false }} + +{{ $isNotice := where $active "Params.severity" "=" "notice" }} +{{ $isDisrupted := where $active "Params.severity" "=" "disrupted" }} +{{ $isDown := where $active "Params.severity" "=" "down" }} + + <body class="status-{{ if $isDown }}down{{ else }}{{ if $isDisrupted}}disrupted{{ else }}{{ if $isNotice }}notice{{ else }}ok{{ end }}{{ end }}{{ end }}"> + {{ partial "header-mini" . }} + + <div class="contain"> + {{ .Render "issue" }} + </div> + +{{ partial "footer" . }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 1773af9..e1314ce 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -1,14 +1,10 @@ - <div class="footer"> - <div class="contain"> +<div class="footer"> + <div class="contain"> + <p><strong>{{ now.Year }} © {{ .Site.Title }}</strong></p> - <p id="disclaimer">{{ .Site.Params.description }}</p> + <p>{{ .Site.Params.description }}</p> - <small class="copyright">Powered by <a href="https://github.com/mistermantas/cstate">cState</a></small> - - </div> - </div> - - - <script defer>window.$crisp=[];window.CRISP_WEBSITE_ID="1456a9bd-7292-4dee-b61d-5d9946f925b5";(function(){d=document;s=d.createElement("script");s.src="https://client.crisp.chat/l.js";s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})();</script> - </body> -</html> + <!-- Please keep this one around to help cState grow <3 --> + <small class="copyright faded">Powered by <a href="https://github.com/mistermantas/cstate">cState</a></small> + </div> +</div> diff --git a/layouts/partials/header-mini.html b/layouts/partials/header-mini.html new file mode 100644 index 0000000..93a26c2 --- /dev/null +++ b/layouts/partials/header-mini.html @@ -0,0 +1,7 @@ +<div class="header"> + <div class="contain"> + <a href="/" class="no-underline">← + <strong>{{ .Site.Title }}</strong> + </a> + </div> +</div> diff --git a/layouts/partials/js.html b/layouts/partials/js.html new file mode 100644 index 0000000..9ef2a23 --- /dev/null +++ b/layouts/partials/js.html @@ -0,0 +1,62 @@ +<script type="javascript"> + /** + * Dev toolset + */ + + console.log('Welcome to cState! https://github.com/mistermantas/cstate'); + document.querySelector('html').className = 'js'; + + + /** + * Make theme color pretty + */ + + if (document.body.className === 'status-down') { + document.querySelector('meta[name=theme-color]').setAttribute('content', themeDownColor); + } else if (document.body.className === 'status-disrupted') { + document.querySelector('meta[name=theme-color]').setAttribute('content', themeDisruptedColor); + } else { + document.querySelector('meta[name=theme-color]').setAttribute('content', themeNoticeColor); + } + + + /** + * Check for internet + */ + + var lastUpdated = document.querySelector('.summary__date'); + var lastUpdate = new Date(); + + function timeSince(date) { + var seconds = Math.floor((new Date() - date) / 1000); + + var interval = Math.floor(seconds / 31536000); + + if (interval > 1) { + return interval + ' years'; + } + interval = Math.floor(seconds / 2592000); + if (interval > 1) { + return interval + ' months'; + } + interval = Math.floor(seconds / 86400); + if (interval > 1) { + return interval + 'd'; + } + interval = Math.floor(seconds / 3600); + if (interval > 1) { + return interval + 'h'; + } + interval = Math.floor(seconds / 60); + if (interval > 1) { + return interval + 'min'; + } + return Math.floor(seconds) + 's'; + } + var aDay = 24*60*60*1000; + + // Show second by second updates + window.setInterval(function() { + lastUpdated.innerHTML = 'Last checked ' + timeSince(lastUpdate) + ' ago'; + }, 1000); +</script> diff --git a/layouts/partials/meta.html b/layouts/partials/meta.html index cea1571..e3ebbf1 100644 --- a/layouts/partials/meta.html +++ b/layouts/partials/meta.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html lang="{{ .Site.LanguageCode }}" class="nojs"> +<html lang="{{ .Site.LanguageCode }}" class="no-js"> <head> <!-- Basics --> <meta charset="utf-8"> @@ -9,13 +9,22 @@ <meta name="description" content="{{ if .Description }}{{ else }}{{ .Site.Params.description }}{{ end }}"> <title>{{ .Site.Title }}</title> <link rel="canonical" href="{{ .Permalink }}"> - <meta name="theme-color" content="#000000"> + {{ .Hugo.Generator }} + <meta name="theme-color" content="#{{ .Site.Params.ok }}"> + <script> + var themeOkColor = '#{{ .Site.Params.ok }}'; + var themeNoticeColor = '#{{ .Site.Params.notice }}'; + var themeDisruptedColor = '#{{ .Site.Params.disrupted }}'; + var themeDownColor = '#{{ .Site.Params.down }}'; + </script> <!-- Sources --> <style> /** * Color palette * + * Default: * white: #fff; + * whitesmoke: #f5f5f5; * forestgreen: #228B22; * crimson: #DC143C; * darkorange: #FF8C00; @@ -27,29 +36,49 @@ margin: 0; background: #fff; color: #444; - font: 16px sans-serif; + font: 100%/1.5 BlinkMacSystemFont, -apple-system, 'San Francisco Text', Helvetica, Arial, sans-serif; + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + hr { + border: 0; + border-bottom: 1px solid #dedede; + margin: 24px 0; } a { text-decoration: none; - border-bottom: 0.2px dotted currentColor; + color: #000; + border-bottom: 1px dotted currentColor; } + a.no-underline { border-bottom: 0; } + a:hover { border-bottom-style: solid; } + a:active { position: relative; top: 2px; } + + h2 { font-size: 26px; } + h3 { font-size: 20px; } + h4 { font-size: 18px; } - h1, h2, h4 { + h2, h4 { font-weight: normal; color: #000; } h3 { - margin-bottom: 0; + margin: 0; color: #000; } - h4 { - margin-top: 0; - color: #999; + .date { + margin-bottom: 0; + color: #666; + font-variant: small-caps; } .faded { @@ -58,12 +87,17 @@ .header { padding: 16px; + } + + .header a { color: #fff; + font-size: 24px; + font-variant: small-caps; } img { - height: 16px; - padding: 4px; + width: 100%; + height: auto; } .contain { @@ -72,96 +106,79 @@ padding: 16px; } - .summary { - border: 2px solid #fff; + .contain--more { + max-width: 480px; } - .summary .tldr { + .center { text-align: center; } + .padding { padding: 12px; } + + .summary { padding: 16px; color: #fff; } - .components { - border: 2px solid #ccc; - border-bottom: 0; + .summary__date { + display: block; + cursor: pointer; } - .component { - color: #000; - padding: 16px; - border-bottom: 2px solid #ccc; + .summary__date:hover { + color: #{{ .Site.Params.faded }}; } - .ping.testing { - color: #dcdcdc; - font-style: italic; + .summary__date:hover:after { + content: ' ⟳ '; + color: #fff; } - .ping.done { - color: #aaa; + .components { + border: 2px solid #{{ .Site.Params.border }}; + border-bottom: 0; } - .error { - color: #DC143C; + .component { + color: #000; + padding: 16px; + border-bottom: 2px solid #{{ .Site.Params.border }}; } - /* .component:before { - content: '[+]'; - opacity: 0.4; - cursor: pointer; - } */ + .ok { color: #{{ .Site.Params.ok }}; } + .error { color: #{{ .Site.Params.down }}; } - .close { - float: right; + .footer { + margin-top: 64px; + padding: 20px 0; + background: #f5f5f5; } - .subscribe, .status { + .copyright { display: block; + font-variant: small-caps; } - .subscribe { - margin: 8px 0; - } - - button, .close { - cursor: pointer; - } - - .subscriber-box.active { - display: block; + .copyright a, a.logo { + border-bottom: 0; } - .subscriber-box { - display: none; - background: #fff; - position: fixed; + .logo img { + height: auto; width: 100%; - height: 100%; - top: 0; - left: 0; - z-index: 1; - overflow-y: scroll; } - .subscriber-box--header { - color: #000; - border-bottom: 1px solid #aaa; - } - - .footer { - padding: 64px; - background: #F0F0F0; - text-align: center; + .logo--small img { + height: 32px; + width: auto; } - .copyright { - display: block; - font-variant: small-caps; - text-align: center; - } + .article h3 a { border: 0; } - .copyright a, a.logo { - border-bottom: 0; + .marker { + text-transform: uppercase; + font-size: smaller; + padding: 2px 8px; + padding-right: 4px; + border: 2px solid #{{ .Site.Params.border }}; } @@ -169,36 +186,35 @@ * Specific to the status */ - .header.ok, .tldr.ok { background: #228B22; } - .header.disrupted, .tldr.disrupted { background: #FF8C00; } - .header.down, .tldr.down { background: #DC143C; } - .header.notice, .tldr.notice { background: #708090; } - - .summary.ok { border-color: #228B22; } - .summary.disrupted { border-color: #FF8C00; } - .summary.down { border-color: #DC143C; } - .summary.notice { border-color: #708090; } + .status-ok .summary, .status-ok .header { background: #{{ .Site.Params.ok }}; } + .status-disrupted .summary, .status-disrupted .header { background: #{{ .Site.Params.disrupted }}; } + .status-down .summary, .status-down .header { background: #{{ .Site.Params.down }}; } + .status-notice .summary, .status-notice .header { background: #{{ .Site.Params.notice }}; } + .marker-ok { background: #{{ .Site.Params.ok }}; } + .marker-disrupted { background: #{{ .Site.Params.disrupted }}; } + .marker-down { background: #{{ .Site.Params.down }}; } + .marker-notice { background: #{{ .Site.Params.notice }}; } /** * Dynamically show individual component statuses */ - .component:after { float: right; } - .component[data-status="ok"]:after { content: "Operational"; color: #228B22; } - .component[data-status="disrupted"]:after { content: "Disrupted"; color: #FF8C00; } - .component[data-status="down"]:after { content: "Down"; color: #DC143C; } - .component[data-status="notice"]:after { content: "Maintenance"; color: #708090; } + .component-status { float: right; } + .component[data-status="ok"] .component-status { color: #{{ .Site.Params.ok }};; } + .component[data-status="disrupted"] .component-status { color: #{{ .Site.Params.disrupted }};; } + .component[data-status="down"] .component-status { color: #{{ .Site.Params.down }};; } + .component[data-status="notice"] .component-status { color: #{{ .Site.Params.notice }};; } /** - * Extend to desktops + * Responsiveness */ - @media (min-width: 560px) { - .status, .subscribe { + @media (min-width: 640px) { + .summary__date { float: right; - display: inline-block; + display: inline; } } </style> diff --git a/layouts/shortcodes/track.html b/layouts/shortcodes/track.html new file mode 100644 index 0000000..0c0c67f --- /dev/null +++ b/layouts/shortcodes/track.html @@ -0,0 +1 @@ +<p class="faded">{{ dateFormat "02 Jan 2006 15:04" (.Get 0) }}</p> |