FutureConversion.tsx (5037B)
1 import React from "react"; 2 import moment from "moment-timezone"; 3 4 import ErrorAlert from "../comps/ErrorAlert"; 5 import FutureConverted from "../comps/FutureConverted"; 6 import SavedFuture from "../comps/SavedFuture"; 7 import TimezoneInput from "../comps/TimezoneInput"; 8 9 import { displayTime, getYesterday, timezoneList } from "../../utils"; 10 import { MAX_DATE, YMD, localTimezone } from "../../utils"; 11 12 import { IFutureConversion } from "../../utils/interfaces"; 13 14 function FutureConversion({ 15 date, 16 setDate, 17 setTime, 18 setTZ1, 19 setTZ2, 20 time, 21 // now, // aliased because [time, setTime] hook 22 TZ1, 23 TZ2, 24 }: IFutureConversion): JSX.Element { 25 const [selectedTime, setSelectedTime] = React.useState< 26 moment.Moment | undefined 27 >(undefined); 28 const [err, setErr] = React.useState<string>(""); 29 30 function handleDateChange(e: React.ChangeEvent<HTMLInputElement>): void { 31 setDate(e.target.value); 32 setSelectedTime(undefined); 33 } 34 35 function handleFormSubmit(e: React.FormEvent<HTMLFormElement>): void { 36 e.preventDefault(); 37 38 // 0. Reset Error and selected time 39 setErr(""); 40 setSelectedTime(undefined); 41 // 1. Validate selected date 42 const selectedDate = moment(date); 43 if (!selectedDate.isValid()) { 44 setErr("Chosen date is not valid."); 45 console.warn(err); 46 return; 47 } 48 // 2. Check limit of selected date 49 // 2.1 MAX allowed 50 const epoch = moment(MAX_DATE, YMD); 51 if (epoch.unix() - selectedDate.unix() < 0) { 52 setErr("Chosen date is outside the maximum permissible limit."); 53 console.warn(err); 54 return; 55 } 56 // 2.2 MIN allowed -- yesterday 57 const yDayMoment = moment(yesterday.format(YMD), YMD); 58 const selectedMoment = moment(selectedDate.format(YMD), YMD); 59 if (selectedMoment.unix() - yDayMoment.unix() < 0) { 60 setErr("Chosen date is in the past."); 61 console.warn(err); 62 return; 63 } 64 // 3. Validate chosen time 65 const dateStr = selectedDate.format(YMD); 66 const timeStr = time; 67 const dateTimeStr = `${dateStr} ${timeStr}`; 68 const dateTime = moment.tz(dateTimeStr, TZ1); 69 if (!dateTime.isValid()) { 70 setErr("Error occurred while parsing time."); 71 console.warn(err); 72 return; 73 } 74 // 4. validate chosen timezone 75 if (timezoneList.indexOf(TZ1) < 0) { 76 setErr("Selected timezone is invalid."); 77 console.warn(err); 78 return; 79 } 80 // 5. validate set timezone 81 if (timezoneList.indexOf(TZ2) < 0) { 82 setErr("Selected timezone to convert is invalid."); 83 console.warn(err); 84 return; 85 } 86 // 6. convert time 87 setSelectedTime(dateTime); 88 } 89 90 function handleTimeChange(e: React.ChangeEvent<HTMLInputElement>): void { 91 setTime(e.target.value); 92 setSelectedTime(undefined); 93 } 94 95 const yesterday = getYesterday(); 96 97 return ( 98 <div className="container"> 99 <form autoComplete="false" onSubmit={handleFormSubmit}> 100 <div className="form-group"> 101 <label htmlFor="choose-date">Choose date</label> 102 <input 103 aria-describedby="choose-date" 104 className="form-control" 105 id="chosen-date" 106 max={MAX_DATE} 107 min={displayTime({ 108 fmtStr: YMD, 109 time: yesterday, 110 timezone: localTimezone, 111 })} 112 name="choose-date" 113 onChange={handleDateChange} 114 placeholder="Enter date" 115 type="date" 116 value={date} 117 /> 118 </div> 119 <div className="form-group"> 120 <label htmlFor="choose-time">Choose time</label> 121 <input 122 aria-describedby="choose-time" 123 className="form-control" 124 id="choose-time" 125 name="choose-time" 126 onChange={handleTimeChange} 127 placeholder="Enter time" 128 type="time" 129 value={time} 130 /> 131 </div> 132 <div className="form-group"> 133 <label htmlFor="choose-from-timezone">Set timezone</label> 134 <TimezoneInput 135 autofocus={false} 136 changeValue={setTZ1} 137 clearInput={setSelectedTime} 138 id="choose-from-timezone" 139 placeholder="Set timezone" 140 TZ={TZ1} 141 /> 142 </div> 143 <div className="form-group"> 144 <label htmlFor="convert-to-timezone">Convert to timezone</label> 145 <TimezoneInput 146 autofocus={false} 147 changeValue={setTZ2} 148 clearInput={setSelectedTime} 149 id="convert-to-timezone" 150 placeholder="Convert to timezone" 151 TZ={TZ2} 152 /> 153 </div> 154 <button className="btn btn-success" type="submit"> 155 Convert 156 </button> 157 {err ? <ErrorAlert msg={err} /> : null} 158 {selectedTime !== undefined ? ( 159 <FutureConverted selectedTime={selectedTime} TZ1={TZ1} TZ2={TZ2} /> 160 ) : null} 161 </form> 162 <SavedFuture selectedTime={selectedTime} /> 163 </div> 164 ); 165 } 166 167 export default FutureConversion;