use pikaday for the date component, closes #32

This commit is contained in:
Danny 2018-05-16 17:02:46 +02:00
parent f082231b12
commit 0ecd4ec251
8 changed files with 313 additions and 55 deletions

View File

@ -2,6 +2,7 @@
import { h, Component } from 'preact';
import { bind } from 'decko';
import Pikadayer from './Pikadayer.js';
const availablePeriods = [
{
@ -103,29 +104,17 @@ class DatePicker extends Component {
return date.getFullYear() + '-' + addZero(date.getMonth() + 1) + '-' + addZero(date.getDate());
}
@bind
startPicking(e) {
this.setState({ picking: e.target.dataset.value })
}
@bind
stopPicking(e) {
this.setState({ picking: '' })
}
@bind
setStartDate(e) {
let newStartDate = e.target.valueAsDate;
if(newStartDate) {
this.setDateRange(newStartDate, this.state.endDate, '')
setStartDate(date) {
if(date) {
this.setDateRange(date, this.state.endDate, '')
}
}
@bind
setEndDate(e) {
let newEndDate = e.target.valueAsDate;
if(newEndDate) {
this.setDateRange(this.state.startDate, newEndDate, '')
setEndDate(date) {
if(date) {
this.setDateRange(this.state.startDate, date, '')
}
}
@ -138,23 +127,11 @@ class DatePicker extends Component {
return (
<ul>
{links}
<li>
<li class="custom">
<span style="padding: 0 8px 0 0;">&mdash;</span>
<span class="datepicker-wrap">
<strong onclick={this.startPicking} data-value="start">{state.startDate.toLocaleDateString()}</strong>
<span class="datepicker" style={state.picking === 'start' ? '' : 'display: none'}>
<label>Choose start date</label>
<input type="date" value={this.dateValue(state.startDate)} onblur={this.stopPicking} onchange={this.setStartDate} />
</span>
</span>
<span> to </span>
<span class="datepicker-wrap">
<strong onclick={this.startPicking} data-value="end">{state.endDate.toLocaleDateString()}</strong>
<span class="datepicker" style={state.picking === 'end' ? '' : 'display: none'}>
<label>Choose end date</label>
<input type="date" value={this.dateValue(state.endDate)} onblur={this.stopPicking} onchange={this.setStartDate} />
</span>
</span>
<Pikadayer value={this.dateValue(state.startDate)} onSelect={this.setStartDate} />
<span style="margin: 0 8px"> to </span>
<Pikadayer value={this.dateValue(state.endDate)} onSelect={this.setEndDate} />
</li>
</ul>
)

View File

@ -0,0 +1,18 @@
'use strict';
import Pikaday from 'pikaday';
import { h, Component } from 'preact';
class Pikadayer extends Component {
componentDidMount() {
new Pikaday({
field: this.base,
onSelect: this.props.onSelect,
})
}
render(props) {
return <input {...props} />
}
}
export default Pikadayer

View File

@ -26,7 +26,10 @@ class Realtime extends Component {
@bind
fetchData() {
Client.request(`stats/site/realtime`)
.then((d) => { this.setState({ count: d })})
.then((d) => {
this.setState({ count: d })
document.title = ( d > 0 ? d + ' current visitors &mdot; Fathom' : 'Fathom' );
})
.catch((e) => {
if(e.message == 401) {
this.props.onError();

View File

@ -69,10 +69,9 @@ class Table extends Component {
ahref.href = (p.Hostname + p.Pathname) || p.URL;
let classes = "table-row";
if(state.total > 0) {
classes += " w" + Math.round(p.Pageviews / state.total * 100);
classes += " w" + Math.min(98, Math.round(p.Pageviews / state.total * 100 * 2.5));
}
// TODO: Add percentage of total back in
let label = ahref.pathname + ahref.search;
if( props.showHostname ) {
label = ahref.hostname.replace('www.', '') + (ahref.pathname.length > 1 ? ahref.pathname : '');

255
assets/sass/pikaday.scss Normal file
View File

@ -0,0 +1,255 @@
/*!
* Pikaday
* Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/
*/
// Variables
// Declare any of these variables before importing this SCSS file to easily override defaults
// Variables are namespaced with the pd (pikaday) prefix
// Colours
$pd-text-color: #333 !default;
$pd-title-color: #333 !default;
$pd-title-bg: #fff !default;
$pd-picker-bg: #fff !default;
$pd-picker-border: #ccc !default;
$pd-picker-border-bottom: #bbb !default;
$pd-picker-shadow: rgba(0,0,0,.5) !default;
$pd-th-color: #999 !default;
$pd-day-color: #666 !default;
$pd-day-bg: #f5f5f5 !default;
$pd-day-hover-color: #fff !default;
$pd-day-hover-bg: #ff8000 !default;
$pd-day-today-color: #33aaff !default;
$pd-day-selected-color: #fff !default;
$pd-day-selected-bg: #33aaff !default;
$pd-day-selected-shadow: #178fe5 !default;
$pd-day-disabled-color: #999 !default;
$pd-week-color: #999 !default;
// Font
$pd-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !default;
.pika-single {
z-index: 9999;
display: block;
position: relative;
color: $pd-text-color;
background: $pd-picker-bg;
border: 1px solid $pd-picker-border;
border-bottom-color: $pd-picker-border-bottom;
font-family: $pd-font-family;
&.is-hidden {
display: none;
}
&.is-bound {
position: absolute;
box-shadow: 0 5px 15px -5px $pd-picker-shadow;
}
}
// clear child float (pika-lendar), using the famous micro clearfix hack
// http://nicolasgallagher.com/micro-clearfix-hack/
.pika-single {
*zoom: 1;
&:before,
&:after {
content: " ";
display: table;
}
&:after { clear: both }
}
.pika-lendar {
float: left;
width: 240px;
margin: 8px;
}
.pika-title {
position: relative;
text-align: center;
select {
cursor: pointer;
position: absolute;
z-index: 9998;
margin: 0;
left: 0;
top: 5px;
filter: alpha(opacity=0);
opacity: 0;
}
}
.pika-label {
display: inline-block;
*display: inline;
position: relative;
z-index: 9999;
overflow: hidden;
margin: 0;
padding: 5px 3px;
font-size: 14px;
line-height: 20px;
font-weight: bold;
color: $pd-title-color;
background-color: $pd-title-bg;
}
.pika-prev,
.pika-next {
display: block;
cursor: pointer;
position: relative;
outline: none;
border: 0;
padding: 0;
width: 20px;
height: 30px;
text-indent: 20px; // hide text using text-indent trick, using width value (it's enough)
white-space: nowrap;
overflow: hidden;
background-color: transparent;
background-position: center center;
background-repeat: no-repeat;
background-size: 75% 75%;
opacity: .5;
*position: absolute;
*top: 0;
&:hover {
opacity: 1;
}
&.is-disabled {
cursor: default;
opacity: .2;
}
}
.pika-prev,
.is-rtl .pika-next {
float: left;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
*left: 0;
}
.pika-next,
.is-rtl .pika-prev {
float: right;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
*right: 0;
}
.pika-select {
display: inline-block;
*display: inline;
}
.pika-table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: 0;
th,
td {
width: 14.285714285714286%;
padding: 0;
}
th {
color: $pd-th-color;
font-size: 12px;
line-height: 25px;
font-weight: bold;
text-align: center;
}
abbr {
border-bottom: none;
cursor: help;
}
}
.pika-button {
cursor: pointer;
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
outline: none;
border: 0;
margin: 0;
width: 100%;
padding: 5px;
color: $pd-day-color;
font-size: 12px;
line-height: 15px;
text-align: right;
background: $pd-day-bg;
.is-today & {
color: $pd-day-today-color;
font-weight: bold;
}
.is-selected & {
color: $pd-day-selected-color;
font-weight: bold;
background: $pd-day-selected-bg;
box-shadow: inset 0 1px 3px $pd-day-selected-shadow;
border-radius: 3px;
}
.is-disabled &,
.is-outside-current-month & {
color: $pd-day-disabled-color;
opacity: .3;
}
.is-disabled & {
pointer-events: none;
cursor: default;
}
&:hover {
color: $pd-day-hover-color;
background: $pd-day-hover-bg;
box-shadow: none;
border-radius: 3px;
}
.is-selection-disabled {
pointer-events: none;
cursor: default;
}
}
.pika-week {
font-size: 11px;
color: $pd-week-color;
}
.is-inrange .pika-button {
background: #D5E9F7;
}
.is-startrange .pika-button {
color: #fff;
background: #6CB31D;
box-shadow: none;
border-radius: 3px;
}
.is-endrange .pika-button {
color: #fff;
background: #33aaff;
box-shadow: none;
border-radius: 3px;
}

View File

@ -76,6 +76,14 @@ body {
nav.date-nav li a:hover { color: #98a0a6; }
nav.date-nav li.active a:hover { color: #46494d; }
nav.date-nav li.active a:after { content:""; background: #88ffc6; display: block; width: 100%; height: 3px; position: absolute; top: 4px; z-index: -1; margin: 0 0 0 -4px; transition: all .4s ease; }
.date-nav .custom input {
background: transparent;
border: 0;
width: 65px;
outline: 0;
font-weight: bold;
cursor: pointer;
}
nav li.visitors { color: #533feb; }
nav li.signout a { padding-right: 0; }
@ -125,20 +133,6 @@ body {
a { color: #46494d; text-decoration: none; transition: all .4s ease; }
.cell a:hover { color: #533feb; }
.datepicker-wrap{ position: relative; }
.datepicker{
position: absolute;
left: 0;
top: 20px;
padding: 6px;
display: block;
z-index: 10;
background: #f5f7fa;
box-shadow: 0 2px 8px 0 rgba(70, 73, 77, 0.16);
border-radius: 4px;
}
@media ( min-width: 1220px ) {
nav.main-nav ul { margin-top: 24px; }
@ -170,8 +164,5 @@ body {
}
@import "util";
@import "pikaday";

14
package-lock.json generated
View File

@ -4083,6 +4083,12 @@
"xtend": "^4.0.0"
}
},
"moment": {
"version": "2.22.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
"integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ==",
"optional": true
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@ -4607,6 +4613,14 @@
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
"pikaday": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/pikaday/-/pikaday-1.7.0.tgz",
"integrity": "sha512-b1z65oFulNTKOdcg9+wTnZWBzfekf1AqPMCmmK9qH6aT7stqDyh76G6nLeuYr3WqchjW/7QLOBFmok14sCecsA==",
"requires": {
"moment": "2.x"
}
},
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",

View File

@ -25,6 +25,7 @@
"d3-tip": "^0.7.1",
"decko": "^1.2.0",
"gulp-uglify": "^3.0.0",
"pikaday": "^1.7.0",
"preact": "^8.2.7",
"pump": "^3.0.0"
}