Skip to content

Commit

Permalink
feat: Activate detour flow (#2793)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshlarson authored Sep 24, 2024
1 parent 444a29f commit c3c4052
Show file tree
Hide file tree
Showing 6 changed files with 685 additions and 40 deletions.
156 changes: 156 additions & 0 deletions assets/src/components/detours/activateDetourModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { PropsWithChildren } from "react"
import { Button, Form, Modal } from "react-bootstrap"

const possibleDurations = [
"1 hour",
"2 hours",
"3 hours",
"4 hours",
"5 hours",
"6 hours",
"7 hours",
"8 hours",
"Until end of service",
"Until further notice",
]

const possibleReasons = [
"Accident",
"Construction",
"Demonstration",
"Disabled bus",
"Drawbridge being raised",
"Electrical work",
"Fire",
"Hazmat condition",
"Holiday",
"Hurricane",
"Maintenance",
"Medical emergency",
"Parade",
"Police activity",
"Snow",
"Special event",
"Tie replacement",
"Traffic",
"Weather",
]

interface SurroundingModalProps extends PropsWithChildren {
onCancel: () => void
onNext?: () => void
onBack?: () => void
onActivate?: () => void
}

const SurroundingModal = ({
onCancel,
onNext,
onBack,
onActivate,
children,
}: SurroundingModalProps) => (
<Modal show animation={false}>
<Modal.Header>Start detour</Modal.Header>
<Modal.Body>{children}</Modal.Body>
<Modal.Footer>
{onBack && (
<Button variant="outline-primary" className="me-auto" onClick={onBack}>
Back
</Button>
)}
<Button variant="outline-primary" onClick={onCancel}>
Cancel
</Button>
{onActivate ? (
<Button variant="primary" onClick={onActivate}>
Activate detour
</Button>
) : (
<Button
variant="primary"
disabled={onNext === undefined}
onClick={onNext}
>
Next
</Button>
)}
</Modal.Footer>
</Modal>
)

const SelectingDuration = ({
onSelectDuration,
selectedDuration,
}: {
onSelectDuration: (duration: string) => void
selectedDuration?: string
}) => (
<Modal.Body>
<h5>Step 1 of 3 - Select detour duration</h5>
<p>
<span>Time length</span> <span>(estimate)</span>
</p>
<Form>
{possibleDurations.map((duration) => (
<Form.Check
onChange={() => {
onSelectDuration(duration)
}}
id={`duration-${duration}`}
key={`duration-${duration}`}
type="radio"
label={duration}
checked={selectedDuration === duration}
/>
))}
</Form>
</Modal.Body>
)

const SelectingReason = ({
onSelectReason,
selectedReason,
}: {
onSelectReason: (reason: string) => void
selectedReason?: string
}) => (
<Modal.Body>
<h5>Step 2 of 3 - Select reason for detour</h5>
<Form>
{possibleReasons.map((reason) => (
<Form.Check
onChange={() => {
onSelectReason(reason)
}}
id={`reason-${reason}`}
key={`reason-${reason}`}
type="radio"
label={reason}
checked={selectedReason === reason}
/>
))}
</Form>
</Modal.Body>
)

const Confirming = () => (
<Modal.Body>
<h5>Step 3 of 3 - Activate detour</h5>
<p>Are you sure that you want to activate this detour?</p>
<p>
Once activated, other Skate users, OIOs, and MBTA ridership will see this
detour information.
</p>
<p className="fst-italic">
You will still need to radio people / whatever is accurate.
</p>
</Modal.Body>
)

export const ActivateDetour = {
Modal: SurroundingModal,
SelectingDuration,
SelectingReason,
Confirming,
}
18 changes: 11 additions & 7 deletions assets/src/components/detours/detourFinishedPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import React from "react"
import React, { PropsWithChildren } from "react"
import { Button, Form, OverlayTrigger, Popover } from "react-bootstrap"
import * as BsIcons from "../../helpers/bsIcons"
import { Panel } from "./diversionPage"

interface DetourFinishedPanelProps extends PropsWithChildren {
onNavigateBack: () => void
detourText: string
onChangeDetourText: (value: string) => void
onActivateDetour?: () => void
}

export const DetourFinishedPanel = ({
onNavigateBack,
detourText,
onChangeDetourText,
onActivateDetour,
}: {
onNavigateBack: () => void
detourText: string
onChangeDetourText: (value: string) => void
onActivateDetour?: () => void
}) => (
children,
}: DetourFinishedPanelProps) => (
<Panel as="article">
<Panel.Header className="">
<h1 className="c-diversion-panel__h1 my-3">Share Detour Details</h1>
Expand Down Expand Up @@ -71,5 +74,6 @@ export const DetourFinishedPanel = ({
)}
</Panel.Body.Footer>
</Panel.Body>
{children}
</Panel>
)
79 changes: 77 additions & 2 deletions assets/src/components/detours/diversionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import inTestGroup, { TestGroups } from "../../userInTestGroup"
import { ActiveDetourPanel } from "./activeDetourPanel"
import { PastDetourPanel } from "./pastDetourPanel"
import userInTestGroup from "../../userInTestGroup"
import { ActivateDetour } from "./activateDetourModal"

const displayFieldsFromRouteAndPattern = (
route: Route,
Expand Down Expand Up @@ -100,6 +101,9 @@ export const DiversionPage = ({
clear,
reviewDetour,
editDetour,

selectedDuration,
selectedReason,
} = useDetour(
"snapshot" in useDetourProps
? { snapshot: useDetourProps.snapshot }
Expand Down Expand Up @@ -256,11 +260,82 @@ export const DiversionPage = ({
onActivateDetour={
inTestGroup(TestGroups.DetoursList)
? () => {
send({ type: "detour.share.activate" })
send({ type: "detour.share.open-activate-modal" })
}
: undefined
}
/>
>
{snapshot.matches({
"Detour Drawing": {
"Share Detour": "Activating",
},
}) ? (
<ActivateDetour.Modal
onCancel={() => {
send({ type: "detour.share.activate-modal.cancel" })
}}
onBack={
snapshot.can({ type: "detour.share.activate-modal.back" })
? () => {
send({ type: "detour.share.activate-modal.back" })
}
: undefined
}
onNext={
snapshot.can({ type: "detour.share.activate-modal.next" })
? () => {
send({ type: "detour.share.activate-modal.next" })
}
: undefined
}
onActivate={
snapshot.can({
type: "detour.share.activate-modal.activate",
})
? () => {
send({ type: "detour.share.activate-modal.activate" })
}
: undefined
}
>
{snapshot.matches({
"Detour Drawing": {
"Share Detour": { Activating: "Selecting Duration" },
},
}) ? (
<ActivateDetour.SelectingDuration
onSelectDuration={(selectedDuration: string) => {
send({
type: "detour.share.activate-modal.select-duration",
duration: selectedDuration,
})
}}
selectedDuration={selectedDuration}
/>
) : snapshot.matches({
"Detour Drawing": {
"Share Detour": { Activating: "Selecting Reason" },
},
}) ? (
<ActivateDetour.SelectingReason
onSelectReason={(selectedReason: string) => {
send({
type: "detour.share.activate-modal.select-reason",
reason: selectedReason,
})
}}
selectedReason={selectedReason}
/>
) : snapshot.matches({
"Detour Drawing": {
"Share Detour": { Activating: "Confirming" },
},
}) ? (
<ActivateDetour.Confirming />
) : null}
</ActivateDetour.Modal>
) : null}
</DetourFinishedPanel>
) : snapshot.matches({ "Detour Drawing": "Active" }) ? (
<ActiveDetourPanel
directions={extendedDirections}
Expand Down
11 changes: 11 additions & 0 deletions assets/src/hooks/useDetour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export const useDetour = (input: UseDetourInput) => {
finishedDetour,
detourShape,
nearestIntersection,
selectedDuration,
selectedReason,
} = snapshot.context

const { result: unfinishedDetour } = useApiCall({
Expand Down Expand Up @@ -213,5 +215,14 @@ export const useDetour = (input: UseDetourInput) => {
: undefined,
/** When present, puts this detour in "edit mode" */
editDetour,

/**
* Detour duration as selected in the activate-detour flow
*/
selectedDuration,
/**
* Detour reason as selected in the activate-detour flow
*/
selectedReason,
}
}
Loading

0 comments on commit c3c4052

Please sign in to comment.