mirror of
https://github.com/quantum5/qcal.git
synced 2025-04-24 17:51:57 -04:00
Add ability to navigate to date
This commit is contained in:
parent
143a411107
commit
c4b2f56772
69
src/App.tsx
69
src/App.tsx
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React, {FormEvent} from 'react';
|
||||
import {Calendar} from './Calendar';
|
||||
import {frSupportedYear, gregorianJDN, jdnFrench, Month} from './dates';
|
||||
import {endGregorian, frSupportedYear, gregorianJDN, jdnFrench, Month, startGregorian} from './dates';
|
||||
|
||||
type YearMonth = {
|
||||
year: number;
|
||||
|
@ -21,6 +21,9 @@ function parseURL(): YearMonth | null {
|
|||
|
||||
type AppState = YearMonth & {
|
||||
todayJDN: number,
|
||||
goYear: string,
|
||||
goMonth: string,
|
||||
goDay: string,
|
||||
};
|
||||
|
||||
class App extends React.Component<{}, AppState> {
|
||||
|
@ -35,6 +38,9 @@ class App extends React.Component<{}, AppState> {
|
|||
this.state = {
|
||||
...(parseURL() || {year, month}),
|
||||
todayJDN,
|
||||
goYear: today.getFullYear().toString(),
|
||||
goMonth: (today.getMonth() + 1).toString(),
|
||||
goDay: today.getDate().toString(),
|
||||
};
|
||||
this.updateURL();
|
||||
this.updateStateFromURL = this.updateStateFromURL.bind(this);
|
||||
|
@ -60,6 +66,36 @@ class App extends React.Component<{}, AppState> {
|
|||
}
|
||||
}
|
||||
|
||||
changeField(field: keyof AppState, event: any) {
|
||||
const change: Partial<AppState> = {};
|
||||
change[field] = event.target.value;
|
||||
this.setState(change);
|
||||
}
|
||||
|
||||
validYear() {
|
||||
return /^-?\d+$/.test(this.state.goYear) && startGregorian.getFullYear() <= +this.state.goYear &&
|
||||
+this.state.goYear <= endGregorian.getFullYear();
|
||||
}
|
||||
|
||||
validMonth() {
|
||||
return /^\d+$/.test(this.state.goMonth) && 1 <= +this.state.goMonth && +this.state.goMonth <= 12;
|
||||
}
|
||||
|
||||
validDay() {
|
||||
return /^\d+$/.test(this.state.goDay) && 1 <= +this.state.goDay && +this.state.goDay <= 31;
|
||||
}
|
||||
|
||||
goToGregorian(event: FormEvent) {
|
||||
event.preventDefault();
|
||||
|
||||
if (!this.validYear() || !this.validMonth() || !this.validDay())
|
||||
return;
|
||||
|
||||
const jdn = gregorianJDN(+this.state.goYear, +this.state.goMonth, +this.state.goDay);
|
||||
const {year, month} = jdnFrench(jdn);
|
||||
this.setState({year, month});
|
||||
}
|
||||
|
||||
setState(state: any, callback?: () => void) {
|
||||
super.setState(state, () => {
|
||||
this.updateURL();
|
||||
|
@ -68,11 +104,30 @@ class App extends React.Component<{}, AppState> {
|
|||
}
|
||||
|
||||
render() {
|
||||
return <Calendar
|
||||
year={this.state.year} month={this.state.month} todayJDN={this.state.todayJDN}
|
||||
onSwitch={(year, month) => {
|
||||
this.setState({year, month})
|
||||
}}/>;
|
||||
return <>
|
||||
<Calendar
|
||||
year={this.state.year} month={this.state.month} todayJDN={this.state.todayJDN}
|
||||
onSwitch={(year, month) => {
|
||||
this.setState({year, month});
|
||||
}}/>
|
||||
|
||||
<div className="navigate">
|
||||
<h4>Go to a date</h4>
|
||||
<form className="input-group" onSubmit={this.goToGregorian.bind(this)}>
|
||||
<span className="input-group-text">Gregorian<span className="hide-small"> Date</span></span>
|
||||
<input type="number" className={`form-control go-year ${this.validYear() ? '' : 'is-invalid'}`}
|
||||
onChange={this.changeField.bind(this, 'goYear')} value={this.state.goYear}
|
||||
min={startGregorian.getFullYear()} max={endGregorian.getFullYear()}/>
|
||||
<input type="number" className={`form-control go-month ${this.validMonth() ? '' : 'is-invalid'}`}
|
||||
onChange={this.changeField.bind(this, 'goMonth')} value={this.state.goMonth}
|
||||
min={1} max={12}/>
|
||||
<input type="number" className={`form-control go-day ${this.validDay() ? '' : 'is-invalid'}`}
|
||||
onChange={this.changeField.bind(this, 'goDay')} value={this.state.goDay}
|
||||
min={1} max={31}/>
|
||||
<button type="submit" className="form-control btn btn-primary go-button">Go</button>
|
||||
</form>
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,9 @@ export function jdnGregorian(jdn: number): Date {
|
|||
return new Date(year, month - 1, day);
|
||||
}
|
||||
|
||||
export const startGregorian = jdnGregorian(startJD);
|
||||
export const endGregorian = jdnGregorian(frJDN(endYear, 13, frIsLeap(endYear) ? 6: 5));
|
||||
|
||||
export function jdnFrench(jdn: number): FrenchDate {
|
||||
let lo = 0;
|
||||
let hi = leaps.length;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
@import 'bootstrap/scss/transitions';
|
||||
@import 'bootstrap/scss/type';
|
||||
@import 'bootstrap/scss/card';
|
||||
@import 'bootstrap/scss/forms';
|
||||
@import './consts';
|
||||
|
||||
body {
|
||||
|
@ -34,6 +35,30 @@ nav.navbar {
|
|||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.hide-small {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.navigate {
|
||||
max-width: $calendar-width;
|
||||
margin-top: $spacer;
|
||||
@include make-container();
|
||||
|
||||
.go-year {
|
||||
max-width: 7em;
|
||||
}
|
||||
|
||||
.go-month, .go-day {
|
||||
max-width: 5em;
|
||||
}
|
||||
|
||||
.go-button {
|
||||
max-width: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
max-width: $calendar-width;
|
||||
margin-top: $spacer;
|
||||
|
|
Loading…
Reference in a new issue