time-convertor-ts

Convert time across timezones (typescript)
git clone http://git.hanabi.in/repos/time-convertor-ts.git
Log | Files | Refs | README | LICENSE

commit 995d08ec60d08bacd99cd26f5465f8d680300656
parent 5f9d5ec6aae5646a42308ef0290bc57107bbb41a
Author: Agastya Chandrakant <acagastya@outlook.com>
Date:   Tue, 26 May 2020 13:34:19 +0530

housekeeping; min date for future is Yday

Diffstat:
Msrc/App/comps/ErrorAlert.tsx | 6+++---
Msrc/App/comps/FutureConverted.tsx | 2++
Msrc/App/comps/Header.tsx | 6+++---
Msrc/App/comps/SavedTimezones.tsx | 5++---
Msrc/App/comps/ShowSavedZones.tsx | 1+
Msrc/App/comps/TimezoneInput.tsx | 4++--
Msrc/App/pages/DualConvertor.tsx | 8+++++---
Msrc/App/pages/FutureConversion.tsx | 25++++++++++++++-----------
Msrc/App/pages/Help.tsx | 18+++---------------
Msrc/App/pages/SimpleConvertor.tsx | 16+++++++++-------
Msrc/utils/index.ts | 26++++++++++++++++++++------
Msrc/utils/interfaces.tsx | 25++++++++++---------------
12 files changed, 74 insertions(+), 68 deletions(-)

diff --git a/src/App/comps/ErrorAlert.tsx b/src/App/comps/ErrorAlert.tsx @@ -3,15 +3,15 @@ import React from 'react'; function ErrorAlert({ msg }: { msg: string }) { return ( <div - className="alert alert-warning alert-dismissible fade show mt-5" + className="alert alert-dismissible alert-warning fade mt-5 show" role="alert" > {msg} <button - type="button" + aria-label="Close" className="close" data-dismiss="alert" - aria-label="Close" + type="button" > <span aria-hidden="true">&times;</span> </button> diff --git a/src/App/comps/FutureConverted.tsx b/src/App/comps/FutureConverted.tsx @@ -2,7 +2,9 @@ import React from 'react'; import moment from 'moment-timezone'; import { displayTime, friendlyStr, getAbbr } from '../../utils'; + import { HMMDY, HMSDMY } from '../../utils'; + import { IFutureConverted } from '../../utils/interfaces'; function FutureConverted({ diff --git a/src/App/comps/Header.tsx b/src/App/comps/Header.tsx @@ -7,16 +7,16 @@ function Header<never>(): JSX.Element { return ( <nav className="bg-danger mb-5 navbar navbar-dark navbar-expand-lg"> <Link className="navbar-brand" to={`${basePath}/`}> - <span aria-label="time convertor" role="img"> - {new Date().getMinutes() % 2 ? '⏳' : '⌛️'} + <span aria-label="time-convertor" role="img"> + ⌛️ </span>{' '} time convertor </Link> <button aria-label="Toggle navigation" className="navbar-toggler" - data-toggle="collapse" data-target="#collapsibleNavbar" + data-toggle="collapse" type="button" > <span className="navbar-toggler-icon"></span> diff --git a/src/App/comps/SavedTimezones.tsx b/src/App/comps/SavedTimezones.tsx @@ -4,14 +4,13 @@ import ShowSavedZones from './ShowSavedZones'; import { getSavedZones } from '../../utils'; -import { ISavedTimezones } from '../../utils/interfaces'; +import { IMoment } from '../../utils/interfaces'; -function SavedTimezones({ time }: ISavedTimezones): JSX.Element { +function SavedTimezones({ time }: IMoment): JSX.Element { const savedZones = getSavedZones(); return ( <div className="saved"> {savedZones.length > 0 ? ( - // @ts-ignore <ShowSavedZones savedZones={savedZones} time={time} /> ) : ( <h5 diff --git a/src/App/comps/ShowSavedZones.tsx b/src/App/comps/ShowSavedZones.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { displayTime, friendlyStr, removeTimeZone } from '../../utils'; + import { HMSDMY } from '../../utils'; import { IShowSavedTimezones } from '../../utils/interfaces'; diff --git a/src/App/comps/TimezoneInput.tsx b/src/App/comps/TimezoneInput.tsx @@ -78,6 +78,7 @@ function TimezoneInput({ autoFocus={autofocus} className="w-75" id={id} + maxLength={100} name={id} onBlur={handleBlur} onChange={handleChange} @@ -87,7 +88,6 @@ function TimezoneInput({ style={style} type="text" value={inputValue} - maxLength={100} /> <div className="suggestion-list" @@ -108,7 +108,7 @@ function TimezoneInput({ <div className="h6 mb-0"> <ul className="list-group"> { - // @ts-ignore + // @ts-ignore don't know why ts is complaining about this suggestions.length > 0 ? suggestions.map(showLI) : null } </ul> diff --git a/src/App/pages/DualConvertor.tsx b/src/App/pages/DualConvertor.tsx @@ -1,15 +1,17 @@ import React from 'react'; -import TimezoneInput from '../comps/TimezoneInput'; import SavedTimezones from '../comps/SavedTimezones'; +import TimezoneInput from '../comps/TimezoneInput'; import { clearTimezones, displayTime, - saveTimezones, getSavedZones, + saveTimezones, } from '../../utils'; + import { HMSDMY } from '../../utils'; + import { IDualConvertor } from '../../utils/interfaces'; function DualConvertor({ @@ -24,7 +26,7 @@ function DualConvertor({ <h3 className="mb-5 text-center"> Convert <em>current</em> time across time zones. </h3> - <div className="row mb-3" id="labels"> + <div className="mb-3 row" id="labels"> <div className="col text-right" id="first-time-lbl-box"> <TimezoneInput autofocus={true} diff --git a/src/App/pages/FutureConversion.tsx b/src/App/pages/FutureConversion.tsx @@ -1,18 +1,19 @@ import React from 'react'; import moment from 'moment-timezone'; +import ErrorAlert from '../comps/ErrorAlert'; import FutureConverted from '../comps/FutureConverted'; import TimezoneInput from '../comps/TimezoneInput'; -import { displayTime, timezoneList } from '../../utils'; +import { displayTime, getYesterday, timezoneList } from '../../utils'; import { HM, MAX_DATE, YMD, localTimezone } from '../../utils'; + import { IFutureConversion } from '../../utils/interfaces'; -import ErrorAlert from '../comps/ErrorAlert'; function FutureConversion({ - time: now, setTZ1, setTZ2, + time: now, // aliased because [time, setTime] hook TZ1, TZ2, }: IFutureConversion): JSX.Element { @@ -25,7 +26,7 @@ function FutureConversion({ const [selectedTime, setSelectedTime] = React.useState< moment.Moment | undefined - >(); + >(undefined); const [err, setErr] = React.useState<string>(''); function handleDateChange(e: React.ChangeEvent<HTMLInputElement>): void { @@ -54,10 +55,10 @@ function FutureConversion({ console.warn(err); return; } - // 2.2 MIN allowed - const todayMoment = moment(now.format(YMD), YMD); + // 2.2 MIN allowed -- yesterday + const yDayMoment = moment(yesterday.format(YMD), YMD); const selectedMoment = moment(selectedDate.format(YMD), YMD); - if (selectedMoment.unix() - todayMoment.unix() < 0) { + if (selectedMoment.unix() - yDayMoment.unix() < 0) { setErr('Chosen date is in the past.'); console.warn(err); return; @@ -93,6 +94,8 @@ function FutureConversion({ setSelectedTime(undefined); } + const yesterday = getYesterday(); + return ( <div className="container"> <form autoComplete="false" onSubmit={handleFormSubmit}> @@ -105,7 +108,7 @@ function FutureConversion({ max={MAX_DATE} min={displayTime({ fmtStr: YMD, - time: now, + time: yesterday, timezone: localTimezone, })} name="choose-date" @@ -134,9 +137,9 @@ function FutureConversion({ autofocus={false} changeValue={setTZ1} clearInput={setSelectedTime} - TZ={TZ1} id="choose-from-timezone" placeholder="Set timezone" + TZ={TZ1} /> </div> <div className="form-group"> @@ -145,12 +148,12 @@ function FutureConversion({ autofocus={false} changeValue={setTZ2} clearInput={setSelectedTime} - TZ={TZ2} id="convert-to-timezone" placeholder="Convert to timezone" + TZ={TZ2} /> </div> - <button type="submit" className="btn btn-success"> + <button className="btn btn-success" type="submit"> Convert </button> {err ? <ErrorAlert msg={err} /> : null} diff --git a/src/App/pages/Help.tsx b/src/App/pages/Help.tsx @@ -1,11 +1,12 @@ import React from 'react'; import { Link } from 'react-router-dom'; -import { IMoment } from '../../utils/interfaces'; - import { getAbbr } from '../../utils'; + import { basePath, localTimezone } from '../../utils'; +import { IMoment } from '../../utils/interfaces'; + function Help({ time }: IMoment): JSX.Element { return ( <div className="container"> @@ -28,19 +29,6 @@ function Help({ time }: IMoment): JSX.Element { <li> You can <span className="font-weight-bold">save</span> the converted timezones, by clicking the "Save" button. - <ul className="list"> - <li> - An ascending order list of converted time zones appear at the - bottom. - </li> - <li> - If you wish to clear all the saved time zones, press "Clear All". - </li> - <li> - If you wish to delete an individual timezone, you can delete from - the list by. - </li> - </ul> </li> </ol> </div> diff --git a/src/App/pages/SimpleConvertor.tsx b/src/App/pages/SimpleConvertor.tsx @@ -1,26 +1,28 @@ import React from 'react'; -import TimezoneInput from '../comps/TimezoneInput'; import SavedTimezones from '../comps/SavedTimezones'; +import TimezoneInput from '../comps/TimezoneInput'; import { clearTimezones, displayTime, - saveTimezones, friendlyStr, - localTimezone, getSavedZones, + localTimezone, + saveTimezones, } from '../../utils'; + import { HMSDMY } from '../../utils'; + import { ISimpleConvertor } from '../../utils/interfaces'; -function SimpleConvertor({ time, TZ1, setTZ1 }: ISimpleConvertor): JSX.Element { +function SimpleConvertor({ setTZ1, time, TZ1 }: ISimpleConvertor): JSX.Element { return ( <main className="container"> <h1 className="mb-5 text-center"> Convert <em>current</em> time to other time zone. </h1> - <div className="row mb-3" id="labels"> + <div className="mb-3 row" id="labels"> <div className="col text-right" id="first-time-lbl-box" @@ -53,16 +55,16 @@ function SimpleConvertor({ time, TZ1, setTZ1 }: ISimpleConvertor): JSX.Element { <div className="text-right mt-5"> <button className="btn btn-success mr-3" - type="button" onClick={() => saveTimezones([TZ1])} + type="button" > Save timezone </button> <button className="btn btn-danger" disabled={getSavedZones().length === 0} - type="button" onClick={clearTimezones} + type="button" > Clear All </button> diff --git a/src/utils/index.ts b/src/utils/index.ts @@ -30,19 +30,19 @@ function friendlyStr(str: string): string { /** * + * @description Obtain the abbreviation of a timezone * @param timezone {string} Time zone string * @param time {moment.Moment} moment object * @returns {string} - * @description Obtain the abbreviation of a timezone */ function getAbbr({ timezone, time }: { timezone: string, time: moment.Moment }): string { - // @ts-ignore + // @ts-ignore -- they most certainly won't be undefined return moment.tz.zone(timezone).abbr(time); } /** * @description Fetch list of saved time zones from the localStorage - * @returns {string[]} Array of saved time zones + * @returns {string[] | []} Array of saved time zones */ function getSavedZones<never>(): string[] | [] { // query localStorage to get JSON as string @@ -53,8 +53,21 @@ function getSavedZones<never>(): string[] | [] { } /** - * @param {string} zone zone to be removed from the localStorage + * @description get yesterday's date as a moment object + * @ref { https://flaviocopes.com/how-to-get-yesterday-date-javascript/ } + * @returns {moment.Moment} + */ +function getYesterday<never>(): moment.Moment { + const today = new Date() + const yesterday = new Date() + + yesterday.setDate(today.getDate() - 1) + return moment(yesterday); +} + +/** * @description Removes one zone from localStorage + * @param {string} zone zone to be removed from the localStorage */ function removeTimeZone(zone: string = ''): void { // get saved zones @@ -69,11 +82,11 @@ function removeTimeZone(zone: string = ''): void { /** * - * @param timezone {string[]} An array of timezones * @description takes in an array of timezones and updates the localStorage + * @param timezone {string[]} An array of timezones */ function saveTimezones(timezone: string[] | [] = []) { - + // get saved zones const savedZones = getSavedZones(); // new array of sorted time zones const newZones = Array.from(new Set([...savedZones, ...timezone])).sort(); @@ -97,6 +110,7 @@ export { friendlyStr, getAbbr, getSavedZones, + getYesterday, removeTimeZone, saveTimezones, unfriendlyStr diff --git a/src/utils/interfaces.tsx b/src/utils/interfaces.tsx @@ -1,23 +1,22 @@ import React from 'react'; -export interface IDualConvertor { - time: moment.Moment; - TZ1: string; - TZ2: string; - setTZ1: React.Dispatch<React.SetStateAction<string>>; - setTZ2: React.Dispatch<React.SetStateAction<string>>; -} - export interface IDisplayTime { fmtStr: string; time: moment.Moment; timezone: string; } +export interface IDualConvertor { + setTZ1: React.Dispatch<React.SetStateAction<string>>; + setTZ2: React.Dispatch<React.SetStateAction<string>>; + time: moment.Moment; + TZ1: string; + TZ2: string; +} export interface IFutureConversion { - time: moment.Moment; setTZ1: React.Dispatch<React.SetStateAction<string>>; setTZ2: React.Dispatch<React.SetStateAction<string>>; + time: moment.Moment; TZ1: string; TZ2: string; } @@ -31,25 +30,21 @@ export interface IMoment { time: moment.Moment; } -export interface ISavedTimezones { - time: moment.Moment; -} - export interface IShowSavedTimezones { savedZones: string[]; time: moment.Moment; } export interface ISimpleConvertor { + setTZ1: React.Dispatch<React.SetStateAction<string>>; time: moment.Moment; TZ1: string; - setTZ1: React.Dispatch<React.SetStateAction<string>>; } export interface ITimezoneInput { autofocus: boolean; changeValue: React.Dispatch<React.SetStateAction<string>>; - clearInput?: Function; + clearInput?: React.Dispatch<React.SetStateAction<moment.Moment | undefined>>; id: string; placeholder: string; TZ: string;