commit 24b1806a61e7b1c69b51d695126df9128c3fd4ff
parent 5edb80751c3dacdd13acaab6317fee68528026a6
Author: Agastya Chandrakant <acagastya@outlook.com>
Date: Fri, 9 Oct 2020 15:47:05 +0530
[feature] event-share-link
Diffstat:
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;