Skip to content

Commit

Permalink
Change Trip Planner Form Inputs (#2091)
Browse files Browse the repository at this point in the history
Co-authored-by: Cristen Jones <cjones3@mbta.com>
  • Loading branch information
anthonyshull and thecristen authored Jun 24, 2024
1 parent 46ebf9e commit aad62bb
Show file tree
Hide file tree
Showing 22 changed files with 412 additions and 182 deletions.
179 changes: 178 additions & 1 deletion assets/css/_trip-plan-form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
.m-trip-plan__optimize-for {
@include icon-size-inline(1em);

margin-bottom: 0;
margin-bottom: .75rem;
margin-top: $base-spacing;

.c-svg__icon-accessible-default {
Expand Down Expand Up @@ -173,3 +173,180 @@
.m-trip-plan__hidden {
display: none;
}

.c-trip-plan-widget__inputs {
label {
margin-bottom: .75rem;
}
}

#trip-planner-form {
.c-accordion-ui {
border-radius: $border-radius;
margin-top: .75rem;
}

.c-accordion-ui__content {
background: white;
border-bottom: solid 1px $brand-primary;
border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
}

.c-accordion-ui__target {
border-bottom: none;
}

.c-accordion-ui__trigger {
border-top-left-radius: $border-radius;
border-top-right-radius: $border-radius;

&.collapsed {
border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
}
}
}

.trip-planner-form {
padding-top: 1rem;

h2 {
font-size: 16px;
font-weight: bold;
line-height: 1.5;
margin-bottom: .5rem;
margin-top: .5rem;
}
}

#trip-planner-inputs {
margin: .75rem 0;
width: 100%;

#trip-plan-datepicker {
margin-bottom: 1rem;
margin-top: .75rem;
}

.btn-group {
width: 100%;

.btn+.btn {
margin-left: 0;
}

label:has(:checked) {
@extend .active;
}
}

input {
padding: calc(#{$base-spacing} / 2);
}

label {
border-color: $brand-primary;
border-width: 1px 0;
font-weight: 400;
padding: calc(#{$base-spacing} / 2);
text-transform: capitalize;
width: 33.33%;
}

label.active {
background-color: $brand-primary-lightest;
color: $brand-primary;
font-weight: 700;
}

label:first-child,
label:last-child {
border-left-width: 1px;
border-right-width: 1px;
}

input[type='text'] {
border: 1px solid $brand-primary;
border-radius: $border-radius;
width: 100%;
}

i.fa-calendar {
color: $brand-primary;
}

.flatpickr {
position: relative;

.form-control[readonly] {
background-color: $body-bg;
}

a[data-toggle] {
position: absolute;
right: .75rem;
top: .5rem;
}
}

.flatpickr-mobile {
border: 1px solid $brand-primary;
border-radius: $border-radius;
width: calc(100% - 2.5rem);

& ~ a[data-toggle] {
position: unset;
}
}
}

.flatpickr-months {
font-family: $headings-font-family;
font-weight: $headings-font-weight;
line-height: $headings-line-height;

.flatpickr-month {
color: inherit;
}
}

.flatpickr-current-month {
font-size: $font-size-base-xxl;
font-weight: inherit;

.flatpickr-monthDropdown-months {
font-weight: inherit;
}

input.cur-year[disabled],
input.cur-year[disabled]:hover {
color: inherit;
}
}

.flatpickr-time input {
font-size: inherit;
}

.flatpickr-day {
font-weight: $font-weight-medium;
}

.flatpickr-calendar {
font-family: $font-family-base;
font-size: inherit;
line-height: inherit;
}

.flatpickr-day.selected {
background-color: $brand-primary;
border-color: $white;
color: $white;

&:hover {
background-color: $brand-primary-lightest;
border-color: $white;
color: $brand-primary;
}
}
11 changes: 11 additions & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import tabbedNav from "./tabbed-nav.js";
import { accordionInit } from "../ts/ui/accordion";
import initializeSentry from "../ts/sentry";
import setupAlgoliaAutocomplete from "../ts/ui/autocomplete/index";
import setupTripPlannerForm from "./trip-planner-form.js";

// Establish Phoenix Socket and LiveView configuration.
import { Socket } from "phoenix";
Expand All @@ -52,17 +53,27 @@ import { LiveSocket } from "phoenix_live_view";
let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");

let Hooks = {};

Hooks.AlgoliaAutocomplete = {
mounted() {
setupAlgoliaAutocomplete(this.el);
}
};

Hooks.ScrollIntoView = {
mounted() {
this.el.scrollIntoView({ behavior: "smooth" });
}
};

Hooks.TripPlannerForm = {
mounted() {
setupTripPlannerForm(this.el);
}
};

let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: Hooks
Expand Down
46 changes: 0 additions & 46 deletions assets/js/test/time-controls-test.js

This file was deleted.

97 changes: 97 additions & 0 deletions assets/js/trip-planner-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* eslint no-unused-vars: ["error", { "args": "none" }] */

import flatpickr from "flatpickr";
import { format } from "date-fns";

/**
* Formats a date into a string in the user's locale.
*/
function i18nDate(date, locale = navigator.language) {
const formatter = new Intl.DateTimeFormat(locale, {
month: "long",
weekday: "long",
day: "numeric",
hour: "numeric",
minute: "numeric"
});

return formatter.format(date);
}

/**
* Updates the title of the accordion based on the mode selections.
*/
function updateAccordionTitle(elem, modeCheckboxes) {
const checkedModes = Array.prototype.slice
.call(modeCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.labels[0].textContent);

const title = elem.querySelector(".c-accordion-ui__title");

if (checkedModes.length === 0) {
title.textContent = "Walking Only";
} else if (checkedModes.length === modeCheckboxes.length) {
title.textContent = "All Modes";
} else {
title.textContent = checkedModes.join(", ");
}
}

const SERVER_FORMAT = "Y-m-d G:i K";

/**
* Initializes the trip planner inputs and sets all listeners.
*/
export default function setupTripPlannerForm(elem) {
// Gets data that is injected into the template.
// This is how we get the user selections from the query params to set controls.
let data = elem.querySelector("#data").innerHTML;
data = JSON.parse(data);

const maxDate = new Date(data.maxDate);
const minDate = new Date(data.minDate);

// Sets the initial value of the date input display.
// Default to 'now' and uses the server date if 'now.'
// Otherwise, we use the chosen time.
const time = data.chosenTime || "now";
const dateTime = new Date(
time === "now" ? data.dateTime : data.chosenDateTime
);

// Initializes the date picker.
flatpickr(elem.querySelector("#trip-plan-datepicker .flatpickr"), {
allowInvalidPreload: true, // needed on mobile to prevent the input from becoming blank when selecting a date outside the min/max
altInput: true, // allow different format to be sent to server
dateFormat: "Y-m-d G:i K", // this gets sent to the server
defaultDate: dateTime,
enableTime: true,
maxDate,
minDate,
formatDate: (date, formatString, locale) => {
if (formatString === SERVER_FORMAT) {
// Formats a date into a string in the format util.ex parse/1 expects.
return format(date, "yyyy-MM-dd HH:mm aa");
}

// if not being sent to the server, use localized format
return i18nDate(date, locale);
},
wrap: true // works with adjacent icon
});

// When someone makes mode selections, we update the title of the accordion.
const modeCheckboxes = elem.querySelectorAll(
".c-accordion-ui input[type='checkbox']"
);

modeCheckboxes.forEach(checkbox => {
checkbox.addEventListener("click", _event => {
updateAccordionTitle(elem, modeCheckboxes);
});
});

// Setup the correct title when the page is loaded.
updateAccordionTitle(elem, modeCheckboxes);
}
6 changes: 6 additions & 0 deletions assets/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"dot-prop-immutable": "^1.5.0",
"fast-deep-equal": "^3.1.3",
"filesize": "^3.3.0",
"flatpickr": "^4.6.13",
"focus-trap": "^7.5.2",
"form-data": "^1.0.1",
"formdata-polyfill": "^3.0.20",
Expand Down
Loading

0 comments on commit aad62bb

Please sign in to comment.