App
Source
export function DateEntry({
label,
date,
errorMsg,
setDate,
disabled = false
}) {
const inputId = `${label}-date`;
return (
<div className={"form-group" + (errorMsg ? " has-error" : "")}>
<label className="form-label" htmlFor={inputId}>
{label}
</label>
<input
id={inputId}
className="form-input"
type="text"
value={date}
onChange={e => setDate(e.target.value)}
disabled={disabled}
/>
{errorMsg && <p className="form-input-hint">{errorMsg}</p>}
</div>
);
}
export const oneWayFlight = "one-way";
export const returnFlight = "return";
export function TripType({ tripType, setTripType }) {
return (
<div className="form-group">
<label className="form-label" htmlFor="trip-type">
Trip type
</label>
<select
id="trip-type"
className="form-select"
value={tripType}
onChange={e => setTripType(e.target.value)}
>
<option value={oneWayFlight}>one-way flight</option>
<option value={returnFlight}>return flight</option>
</select>
</div>
);
}
import { useState } from "react";
import ReactDOM from "react-dom";
import { today, validateDate } from "../../../../lib/date";
import { TripType, oneWayFlight, returnFlight } from "./TripType";
import { DateEntry } from "./DateEntry";
const initialDate = today();
function useDate(initialDate) {
const [date, setDate] = useState(initialDate);
const [error, setError] = useState(null);
function updateDate(newDate) {
setDate(newDate);
try {
validateDate(newDate);
setError(null);
} catch (error) {
setError(error.message);
}
}
return [date, error, updateDate];
}
function App() {
const [tripType, setTripType] = useState(oneWayFlight);
const [departing, departingError, setDeparting] = useDate(initialDate);
let [returning, returningError, setReturning] = useDate(initialDate);
if (
departingError == null &&
returningError == null &&
tripType == returnFlight &&
returning < departing
) {
returningError = "Returning date must be on or after departing date.";
}
const isBookDisabled =
departingError ||
returningError ||
(tripType == returnFlight && returning < departing);
function bookFlight() {
const type = tripType === returnFlight ? "return" : "one-way";
let message = `You have booked a ${type} flight, departing ${departing}`;
if (tripType == returnFlight) {
message += ` and returning ${returning}`;
}
alert(message);
}
return (
<>
<TripType tripType={tripType} setTripType={value => setTripType(value)} />
<DateEntry
label="Departing"
date={departing}
setDate={newDate => setDeparting(newDate)}
errorMsg={departingError}
/>
<DateEntry
label="Returning"
date={returning}
setDate={newDate => setReturning(newDate)}
errorMsg={returningError}
disabled={tripType !== returnFlight}
/>
<div className="form-group">
<button
disabled={isBookDisabled}
onClick={bookFlight}
className="btn btn-primary"
>
book
</button>
</div>
</>
);
}
ReactDOM.render(<App />, document.getElementById("app"));