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:
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">×</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;