Skip to content

Commit

Permalink
feat: group travel contact page
Browse files Browse the repository at this point in the history
  • Loading branch information
mortennordseth committed Oct 3, 2024
1 parent f2cce65 commit 354dece
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 0 deletions.
132 changes: 132 additions & 0 deletions src/page-modules/contact/group-travel/group-travel-state-machine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { assign, setup } from 'xstate';

export type ContextType = {
travelType: 'bus' | 'boat' | null;
formData: {
dateOfTravel: string;
line: string;
fromStop: string;
toStop: string;
departure: string;
returnInfo: string;
groupSize: string;
responsiblePerson: string;
phoneNumber: string;
};
};

type GroupTravelEvents =
| { type: 'CHOOSE_BOAT' }
| { type: 'CHOOSE_BUS' }
| { type: 'SUBMIT'; formData: ContextType['formData'] };

export const groupTravelStateMachine = setup({
types: {
context: {} as ContextType,
events: {} as GroupTravelEvents,
},
guards: {
isFormValid: ({ context }) => {
const {
dateOfTravel,
line,
fromStop,
toStop,
groupSize,
responsiblePerson,
phoneNumber,
} = context.formData;
return (
!!dateOfTravel &&
!!line &&
!!fromStop &&
!!toStop &&
!!groupSize &&
!!responsiblePerson &&
!!phoneNumber
);
},
},
actions: {
navigateToErrorPage: () => {
window.location.href = '/contact/error';
},
navigateToSuccessPage: () => {
window.location.href = '/contact/success';
},
updatedFormData: assign(({ context, event }) => {
if (event.type !== 'SUBMIT') return context;
return {
formData: {
...context.formData,
...event.formData,
},
};
}),
showValidationErrors: (context) => {
console.log('Need to handle validation');
},
},
}).createMachine({
id: 'ticketControlForm',
initial: 'selectTravelType',
context: {
travelType: null, // 'bus' or 'boat'
formData: {
dateOfTravel: '',
line: '',
fromStop: '',
toStop: '',
departure: '',
returnInfo: '',
groupSize: '',
responsiblePerson: '',
phoneNumber: '',
},
} as ContextType,
states: {
selectTravelType: {
on: {
CHOOSE_BOAT: {
target: 'boatInfo',
actions: assign({ travelType: 'boat' }),
},
CHOOSE_BUS: {
target: 'busForm',
actions: assign({ travelType: 'bus' }),
},
},
},
boatInfo: {
type: 'final',
},
busForm: {
initial: 'editing',
states: {
editing: {
on: {
SUBMIT: [
{
target: 'success',
guard: 'isFormValid',
actions: 'updatedFormData',
},
{
target: 'editing',
actions: 'showValidationErrors',
},
],
},
},
success: {
entry: 'navigateToSuccessPage',
type: 'final',
},
error: {
entry: 'navigateToErrorPage',
type: 'final',
},
},
},
},
});
7 changes: 7 additions & 0 deletions src/page-modules/contact/group-travel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function GroupTravelContent() {
return (
<div>
<h1>Group travel content</h1>
</div>
);
}
24 changes: 24 additions & 0 deletions src/pages/contact/group-travel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import DefaultLayout from '@atb/layouts/default';
import { withGlobalData, WithGlobalData } from '@atb/layouts/global-data';
import { NextPage } from 'next';
import {
ContactPageLayout,
ContactPageLayoutProps,
} from '@atb/page-modules/contact';
import GroupTravelContent from '@atb/page-modules/contact/group-travel';

export type GroupTravelPageProps = WithGlobalData<ContactPageLayoutProps>;

const GroupTravelPage: NextPage<GroupTravelPageProps> = (props) => {
return (
<DefaultLayout {...props}>
<ContactPageLayout {...props}>
<GroupTravelContent />
</ContactPageLayout>
</DefaultLayout>
);
};

export default GroupTravelPage;

export const getServerSideProps = withGlobalData();

0 comments on commit 354dece

Please sign in to comment.