App

Bundles

Stats
BundleMinifiedGzipBrotli
index.js144 kB46 kB40.1 kB

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 React from "react";
import ReactDOM from "react-dom";
import { today, validateDate } from "../../../../lib/date";
import { TripType, oneWayFlight, returnFlight } from "./TripType";
import { DateEntry } from "./DateEntry";

const initial = today();

class App extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			tripType: oneWayFlight,
			departing: initial,
			departingError: null,
			returning: initial,
			returningError: null
		};
	}

	updateDate(dateType, newDate) {
		let errorMsg = null;
		try {
			validateDate(newDate);
		} catch (error) {
			errorMsg = error.message;
		}

		this.setState({
			[dateType]: newDate,
			[dateType + "Error"]: errorMsg
		});
	}

	bookFlight() {
		const type = this.state.tripType === returnFlight ? "return" : "one-way";

		let message = `You have booked a ${type} flight, departing ${this.state.departing}`;
		if (this.state.tripType == returnFlight) {
			message += ` and returning ${this.state.returning}`;
		}

		alert(message);
	}

	render() {
		let {
			tripType,
			departing,
			departingError,
			returning,
			returningError
		} = this.state;

		if (
			departingError == null &&
			returningError == null &&
			tripType == returnFlight &&
			returning < departing
		) {
			returningError = "Returning date must be on or after departing date.";
		}

		const isBookDisabled = departingError || returningError;

		return (
			<>
				<TripType
					tripType={tripType}
					setTripType={tripType => this.setState({ tripType })}
				/>
				<DateEntry
					label="Departing"
					date={departing}
					setDate={newDate => this.updateDate("departing", newDate)}
					errorMsg={departingError}
				/>
				<DateEntry
					label="Returning"
					date={returning}
					setDate={newDate => this.updateDate("returning", newDate)}
					errorMsg={returningError}
					disabled={tripType !== returnFlight}
				/>
				<div className="form-group">
					<button
						disabled={isBookDisabled}
						onClick={() => this.bookFlight()}
						className="btn btn-primary"
					>
						book
					</button>
				</div>
			</>
		);
	}
}

ReactDOM.render(<App />, document.getElementById("app"));