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 24b1806a61e7b1c69b51d695126df9128c3fd4ff
parent 5edb80751c3dacdd13acaab6317fee68528026a6
Author: Agastya Chandrakant <acagastya@outlook.com>
Date:   Fri,  9 Oct 2020 15:47:05 +0530

[feature] event-share-link

Diffstat:
Msrc/App/comps/Header.tsx | 5+++++
Msrc/App/comps/TimezoneInput.tsx | 2+-
Msrc/App/index.tsx | 4++++
Asrc/App/pages/CreateEvent.tsx | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/App/pages/Help.tsx | 5+++++
Asrc/App/pages/UNIXTime.tsx | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 189 insertions(+), 1 deletion(-)

diff --git a/src/App/comps/Header.tsx b/src/App/comps/Header.tsx @@ -24,6 +24,11 @@ function Header<never>(): JSX.Element { <div className="collapse navbar-collapse" id="collapsibleNavbar"> <ul className="navbar-nav"> <li className="nav-item"> + <Link className="nav-link" to={`${basePath}/create`}> + Create-events + </Link> + </li> + <li className="nav-item"> <Link className="nav-link" to={`${basePath}/help`}> Help </Link> diff --git a/src/App/comps/TimezoneInput.tsx b/src/App/comps/TimezoneInput.tsx @@ -109,7 +109,7 @@ function TimezoneInput({ }} > <div className="h6 mb-0"> - <ul className="list-group"> + <ul className="list-group text-left"> { // @ts-ignore don't know why ts is complaining about this suggestions.length > 0 ? suggestions.map(showLI) : null diff --git a/src/App/index.tsx b/src/App/index.tsx @@ -1,10 +1,12 @@ import React from 'react'; import { Route, BrowserRouter as Router, Switch } from 'react-router-dom'; +import CreateEvent from './pages/CreateEvent'; import DualConvertor from './pages/DualConvertor'; import FutureConversion from './pages/FutureConversion'; import Help from './pages/Help'; import SimpleConvertor from './pages/SimpleConvertor'; +import UNIXTime from './pages/UNIXTime'; import Footer from './comps/Footer'; import Header from './comps/Header'; @@ -60,6 +62,8 @@ function App<never>(): JSX.Element { /> )} /> + <Route path={`${basePath}/create`} render={() => <CreateEvent />} /> + <Route path={`${basePath}/([0-9]+)`} render={() => <UNIXTime />} /> <Route path={`${basePath}/`} render={() => ( diff --git a/src/App/pages/CreateEvent.tsx b/src/App/pages/CreateEvent.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import moment from 'moment-timezone'; + +import TimezoneInput from '../comps/TimezoneInput'; + +import { HM, localTimezone, MAX_DATE, YMD } from '../../utils'; + +function CreateEvent() { + const { protocol, host } = window.location; + const url = `${protocol}//${host}/`; + const now = moment(Date.now()); + const defaults = { + date: now.format(YMD), + stamp: now.unix(), + time: now.format(HM), + }; + const [fullurl, setFullurl] = React.useState<string>(''); + const [date, setDate] = React.useState<string>(defaults.date); + const [time, setTime] = React.useState<string>(defaults.time); + const [timezone, setTimezone] = React.useState<string>(localTimezone); + let textArea: HTMLInputElement | null; + + function copyToClipboard(): void { + const el = textArea; + el?.select(); + document.execCommand('copy'); + } + + function generateLink(): void { + const instance = moment.tz(`${date} ${time}`, timezone).unix(); + setFullurl(`${url}${instance}`); + } + + function handleDateChange(e: React.ChangeEvent<HTMLInputElement>): void { + setDate(e.target.value); + setFullurl(''); + } + + function handleTimeChange(e: React.ChangeEvent<HTMLInputElement>): void { + setTime(e.target.value); + setFullurl(''); + } + + function handleTimezoneChange(tz: React.SetStateAction<string>): void { + setTimezone(tz); + setFullurl(''); + } + + return ( + <main className="container"> + <h1 className="mb-3 text-center"> + Select the date, time and timezone of your event. + </h1> + <label htmlFor="event-date">Event date</label> + <input + aria-describedby="event-date" + className="form-control mb-4" + id="event-date" + max={MAX_DATE} + name="event-date" + onChange={handleDateChange} + placeholder="Enter date" + type="date" + value={date} + /> + <label htmlFor="event-time">Event time</label> + <input + aria-describedby="event-time" + className="form-control mb-4" + id="event-time" + name="event-time" + onChange={handleTimeChange} + placeholder="Enter time" + type="time" + value={time} + /> + <label htmlFor="event-timezone">Set timezone</label> + <TimezoneInput + autofocus={false} + changeValue={handleTimezoneChange} + id="event-timezone-input" + placeholder="Time zone" + TZ={timezone} + /> + <h1 className="mt-5">Share link!</h1> + <div className="input-group"> + <div className="input-group-prepend" onClick={generateLink}> + <span className="input-group-text">Click to create link!</span> + </div> + <input + className="form-control" + id="event-url" + onClick={copyToClipboard} + readOnly={true} + ref={(text) => (textArea = text)} + style={{ + background: 'white', + }} + type="text" + value={fullurl} + /> + </div> + </main> + ); +} + +export default CreateEvent; diff --git a/src/App/pages/Help.tsx b/src/App/pages/Help.tsx @@ -30,6 +30,11 @@ function Help({ time }: IMoment): JSX.Element { You can <span className="font-weight-bold">save</span> the converted timezones, by clicking the "Save" button. </li> + <li> + Use the <Link to={`${basePath}/create`}>Create event</Link> link to + schedule an event and share the link with participants. They can view + the event's scheduled time in their respective time zones. + </li> </ol> </div> ); diff --git a/src/App/pages/UNIXTime.tsx b/src/App/pages/UNIXTime.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import moment from 'moment-timezone'; +import { Link } from 'react-router-dom'; + +import { basePath, localTimezone } from '../../utils'; +import TimezoneInput from '../comps/TimezoneInput'; + +function UNIXTime(): JSX.Element { + const timestamp = +window.location.pathname.replace('/', '') * 1000; + + const [TZ, setTZ] = React.useState<string>(localTimezone); + + const urlTime = moment.tz(timestamp, TZ); + const rightNow = Date.now(); + const isWas = urlTime.valueOf() >= rightNow ? 'is' : 'was'; + + const [instance, setInstance] = React.useState<moment.Moment>(urlTime); + + const [displayTime, setDisplayTime] = React.useState<string>( + instance.format('HH:mm MMM DD, YYYY Z (z)') + ); + + const [timezone, setTimezone] = React.useState<string>( + instance.format('Z (z)') + ); + + function handleClick() { + setInstance(moment.tz(timestamp, TZ)); + setDisplayTime(instance.format('HH:mm MMM DD, YYYY Z (z)')); + setTimezone(instance.format('Z (z)')); + } + + function handleTimezoneChange(tz: React.SetStateAction<string>) { + setTZ(tz); + setInstance(moment.tz(timestamp, '' + tz)); + } + + return ( + <main className="container"> + <div className="text-center"> + <h3>That {isWas}:</h3> + <h1 className="mb-5 mt-3">{displayTime}</h1> + <h5>Not {timezone}?</h5> + <TimezoneInput + autofocus={false} + changeValue={handleTimezoneChange} + id="event-time-mismatch" + placeholder="Time zone" + TZ={TZ} + /> + <button className="btn btn-primary mb-5 mt-3" onClick={handleClick}> + Change + </button> + <p className="mb-5 mt-5"></p> + <Link + className="btn btn-info mt-5" + role="button" + to={`${basePath}/create`} + > + Schedule a new event + </Link> + </div> + </main> + ); +} + +export default UNIXTime;