Skip to content

Commit

Permalink
feat: add page with forms for means of transport (#348)
Browse files Browse the repository at this point in the history
* Save progress

* Update translations.

* Update machineEvents

* Update mode of transport form selector.

* Update form view an state machine.

* Add rule to avoid having to provide email if the user dont want to e contacted.

* Update to use correct validation and add validation roule to routeArea.

* Spliting the form into multiple forms. One for each option.

* Add prop types to pass state and send as params.

* Add formtype as API param.

* Remove console.log()

* Update translations and make personal info opional.

* rename from mods-of-transport to means-of-transport.

* rename from routeArea to area

* Update src/translations/pages/contact.ts

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>

* Update src/translations/pages/contact.ts

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>

* Update src/translations/pages/contact.ts

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>

* Update src/translations/pages/contact.ts

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>

* Update src/translations/pages/contact.ts

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>

* Move button to index.ts

* Set initial date and plannedDepartureTime with global functions from utils.ts.

* Move form and onSumbit functions to /means-of-transport/index.ts

* Fix copy-paste error.

* Remove console.log

* Change from using hasTags to chech to using context.formType in radio buttons.

* remove unused import.

* Simplify validation logic and update when to clean up error messages.

* Fix typo and translation errors

* Ensure that inly string values are submitet to the api.

---------

Co-authored-by: Morten Nordseth <43166974+mortennordseth@users.noreply.github.com>
  • Loading branch information
jonasbrunvoll and mortennordseth committed Sep 24, 2024
1 parent b2a5788 commit 136d8c9
Show file tree
Hide file tree
Showing 19 changed files with 2,195 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/page-modules/contact/contact.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@value typo-body__secondary from "@atb/theme/typography.module.css";

.form_options__list {
list-style-type: none;
}

.rules__list {
padding: var(--spacings-medium);
padding-left: var(--spacings-xLarge);
Expand Down
1 change: 1 addition & 0 deletions src/page-modules/contact/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { FeeComplaintForm } from './ticket-control/complaint';
export { type Line } from './server/journey-planner/validators';
export { shouldShowContactPage } from './utils';
export { FeedbackForm } from './ticket-control/feedback';
export { MeansOfTransportContent } from './means-of-transport';
2 changes: 1 addition & 1 deletion src/page-modules/contact/layouts/contact-page-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const contactPages: ContactPage[] = [
},
{
title: PageText.Contact.modeOfTransport.title,
href: '/contact/mode-of-transport',
href: '/contact/means-of-transport',
icon: 'transportation/Bus',
},
{
Expand Down
19 changes: 16 additions & 3 deletions src/page-modules/contact/machineEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Line } from './server/journey-planner/validators';
import { TranslatedString } from '@atb/translations';

export type ReasonForTransportFailure = { id: string; name: TranslatedString };
export type Area = { id: string; name: TranslatedString };

export const machineEvents = {} as
| { type: 'VALIDATE' }
Expand All @@ -13,7 +14,8 @@ export const machineEvents = {} as
| 'isAppTicketStorageMode'
| 'agreesFirstAgreement'
| 'agreesSecondAgreement'
| 'hasInternationalBankAccount';
| 'hasInternationalBankAccount'
| 'wantsToBeContacted';
}
| {
type: 'UPDATE_FIELD';
Expand Down Expand Up @@ -43,19 +45,30 @@ export const machineEvents = {} as
| 'appPhoneNumber'
| 'customerNumber'
| 'travelCardNumber'
| 'isAppTicketStorageMode';
| 'isAppTicketStorageMode'
| 'formType'
| 'area';
value:
| string
| number
| Line
| Line['quays'][0]
| TransportModeType
| ReasonForTransportFailure
| Area
| File[];
}

// travel-guarantee
| { type: 'TAXI' }
| { type: 'CAR' }
| { type: 'OTHER' }
| { type: 'SET_STATE_SUBMITTED'; stateSubmitted: string | undefined };
| { type: 'SET_STATE_SUBMITTED'; stateSubmitted: string | undefined }

// mode-of-transport
| { type: 'DRIVER_FORM' }
| { type: 'TRANSPORTATION_FORM' }
| { type: 'DELAY_FORM' }
| { type: 'STOP_FORM' }
| { type: 'SERVICE_OFFERING_FORM' }
| { type: 'INJURY_FORM' };
247 changes: 247 additions & 0 deletions src/page-modules/contact/means-of-transport/forms/delayForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
import { PageText, useTranslation } from '@atb/translations';
import { useLines } from '../../lines/use-lines';
import { SectionCard } from '../../components/section-card';
import { Typo } from '@atb/components/typography';
import Select from '../../components/input/select';
import { ComponentText } from '@atb/translations';
import { Input } from '../../components/input';
import { TransportModeType } from '@atb-as/config-specs';
import { Line } from '../..';
import { FileInput } from '../../components/input/file';
import { Textarea } from '../../components/input/textarea';
import { ContextProps } from '../means-of-transport-form-machine';
import { machineEvents } from '../../machineEvents';

type DelayFormProps = {
state: {
hasTag(arg0: string): boolean | undefined;
context: ContextProps;
};
send: (event: typeof machineEvents) => void;
};

export const DelayForm = ({ state, send }: DelayFormProps) => {
const { t } = useTranslation();
const { getLinesByMode, getQuaysByLine } = useLines();

return (
<div>
<SectionCard title={PageText.Contact.modeOfTransport.delay.description}>
<Typo.p textType="body__primary">
{t(PageText.Contact.modeOfTransport.delay.info)}
</Typo.p>
</SectionCard>

<SectionCard title={PageText.Contact.modeOfTransport.delay.about.title}>
<Typo.p textType="body__primary">
{t(PageText.Contact.modeOfTransport.delay.about.description)}
</Typo.p>

<Select
label={t(PageText.Contact.inputFields.transportMode.label).toString()}
value={state.context.transportMode}
onChange={(value) =>
send({
type: 'UPDATE_FIELD',
field: 'transportMode',
value: value as TransportModeType,
})
}
error={
state.context?.errorMessages['transportMode']?.[0]
? t(state.context?.errorMessages['transportMode']?.[0])
: undefined
}
valueToText={(val: TransportModeType) =>
t(ComponentText.TransportMode.modes[val])
}
valueToId={(val: TransportModeType) => val}
options={['bus', 'water'] as TransportModeType[]}
placeholder={t(
PageText.Contact.inputFields.transportMode.optionLabel,
)}
/>

<Select
label={t(PageText.Contact.inputFields.line.label)}
value={state.context.line}
disabled={!state.context.transportMode}
onChange={(value: Line | undefined) => {
if (!value) return;
send({
type: 'UPDATE_FIELD',
field: 'line',
value: value,
});
}}
options={getLinesByMode(
state.context.transportMode as TransportModeType,
)}
valueToId={(line: Line) => line.id}
valueToText={(line: Line) => line.name}
placeholder={t(PageText.Contact.inputFields.line.optionLabel)}
error={
state.context?.errorMessages['line']?.[0]
? t(state.context?.errorMessages['line']?.[0])
: undefined
}
/>

<Select
label={t(PageText.Contact.inputFields.fromStop.label)}
value={state.context.fromStop}
disabled={!state.context.line}
onChange={(value) => {
if (!value) return;
send({
type: 'UPDATE_FIELD',
field: 'fromStop',
value: value,
});
}}
options={
state.context.line?.id ? getQuaysByLine(state.context.line.id) : []
}
placeholder={t(PageText.Contact.inputFields.fromStop.optionLabel)}
error={
state.context?.errorMessages['fromStop']?.[0]
? t(state.context?.errorMessages['fromStop']?.[0])
: undefined
}
valueToId={(quay: Line['quays'][0]) => quay.id}
valueToText={(quay: Line['quays'][0]) => quay.name}
/>

<Select
label={t(PageText.Contact.inputFields.toStop.label)}
value={state.context.toStop}
disabled={!state.context.line}
onChange={(value) => {
if (!value) return;
send({
type: 'UPDATE_FIELD',
field: 'toStop',
value: value,
});
}}
placeholder={t(PageText.Contact.inputFields.toStop.optionLabel)}
options={
state.context.line?.id ? getQuaysByLine(state.context.line.id) : []
}
error={
state.context?.errorMessages['toStop']?.[0]
? t(state.context?.errorMessages['toStop']?.[0])
: undefined
}
valueToId={(quay: Line['quays'][0]) => quay.id}
valueToText={(quay: Line['quays'][0]) => quay.name}
/>

<Input
label={PageText.Contact.inputFields.date}
type="date"
name="date"
value={state.context.date}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'date',
value: e.target.value,
})
}
/>

<Input
label={PageText.Contact.inputFields.plannedDepartureTime}
type="time"
name="time"
value={state.context.plannedDepartureTime}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'plannedDepartureTime',
value: e.target.value,
})
}
/>
</SectionCard>

<SectionCard title={PageText.Contact.inputFields.feedback.title}>
<Typo.p textType="body__primary">
{t(PageText.Contact.inputFields.feedback.description)}
</Typo.p>
<Textarea
value={state.context.feedback}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'feedback',
value: e.target.value,
})
}
error={
state.context.errorMessages['feedback']?.[0]
? t(state.context.errorMessages['feedback']?.[0]).toString()
: undefined
}
/>
<FileInput
name="attachments"
label={t(PageText.Contact.inputFields.feedback.attachment)}
onChange={(files) => {
send({
type: 'UPDATE_FIELD',
field: 'attachments',
value: files,
});
}}
/>
</SectionCard>
<SectionCard title={PageText.Contact.aboutYouInfo.optionalTitle}>
<Input
label={PageText.Contact.inputFields.firstName.label}
type="text"
name="firstName"
value={state.context.firstName}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'firstName',
value: e.target.value,
})
}
/>

<Input
label={PageText.Contact.inputFields.lastName.label}
type="text"
name="lastName"
value={state.context.lastName}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'lastName',
value: e.target.value,
})
}
/>

<Input
label={PageText.Contact.inputFields.email.label}
type="email"
name="email"
value={state.context.email}
onChange={(e) =>
send({
type: 'UPDATE_FIELD',
field: 'email',
value: e.target.value,
})
}
/>
</SectionCard>
</div>
);
};

export default DelayForm;
Loading

0 comments on commit 136d8c9

Please sign in to comment.