import React from 'react'; import {Calendar} from './Calendar'; import {dateJDN, gregorianJDN, JulianMonth} from '@common/gregorian'; import {DayChanger} from '@common/ui/DayChanger'; import {jdnJulian} from '@common/julian'; import {GregorianJumper} from '@common/dateJump'; // Not real limitations other than JS number precision. const START_JDN = gregorianJDN(-10_000_000_000_000, 1, 1); const END_JDN = gregorianJDN(10_000_000_000_000, 12, 31); type YearMonth = { year: number; month: JulianMonth; } function parseURL(): YearMonth | null { const match = /\/(-?\d+)\/(\d+)/.exec(window.location.pathname); if (!match) return null; const month = +match[2]; const year = +match[1]; if (month < 1 || month > 23) return null; return {year: year, month: month as JulianMonth}; } type AppState = YearMonth & { todayJDN: number, }; class App extends React.Component<{}, AppState> { state: AppState; constructor(props: {}) { super(props); const todayJDN = dateJDN(new Date()); const [year, month] = jdnJulian(todayJDN); this.state = { ...(parseURL() || {year, month}), todayJDN, }; this.updateStateFromURL = this.updateStateFromURL.bind(this); } componentDidMount() { window.addEventListener('popstate', this.updateStateFromURL); } componentWillUnmount() { window.removeEventListener('popstate', this.updateStateFromURL); } private updateStateFromURL(event: PopStateEvent) { this.setState(event.state); } private updateURL() { const {year, month} = this.state; const path = `/${year}/${month}`; if (path !== window.location.pathname) { window.history.pushState({year, month}, '', path); } } setState(state: any, callback?: () => void) { super.setState(state, () => { this.updateURL(); callback?.(); }); } onDateChange = (todayJDN: number) => { this.setState({todayJDN}); }; goToJDN = (jdn: number) => { const [year, month] = jdnJulian(jdn); this.setState({year, month}); }; render() { return <> { this.setState({year, month}); }}/>

Go to a date

; } } export default App;