diff --git a/src/page-modules/contact/index.ts b/src/page-modules/contact/index.ts index 2c6d3871..a044bf55 100644 --- a/src/page-modules/contact/index.ts +++ b/src/page-modules/contact/index.ts @@ -7,5 +7,6 @@ export { export { PostponePaymentForm } from './ticket-control'; export { RefundForm } from './travel-guarantee'; +export { FeeComplaintForm } from './ticket-control/complaint'; export { type Line } from './server/journey-planner/validators'; export { shouldShowContactPage } from './utils'; diff --git a/src/page-modules/contact/machineEvents.ts b/src/page-modules/contact/machineEvents.ts index 18458b13..0ee3085d 100644 --- a/src/page-modules/contact/machineEvents.ts +++ b/src/page-modules/contact/machineEvents.ts @@ -5,13 +5,16 @@ import { TranslatedString } from '@atb/translations'; export type ReasonForTransportFailure = { id: string; name: TranslatedString }; export const machineEvents = {} as - | { type: 'TOGGLE' } - | { type: 'TAXI' } - | { type: 'CAR' } - | { type: 'OTHER' } | { type: 'VALIDATE' } | { type: 'SET_BANK_ACCOUNT_FOREIGN' } - | { type: 'SET_STATE_SUBMITTED'; stateSubmitted: string | undefined } + | { + type: 'TOGGLE'; + field: + | 'isAppTicketStorageMode' + | 'agreesFirstAgreement' + | 'agreesSecondAgreement' + | 'hasInternationalBankAccount'; + } | { type: 'UPDATE_FIELD'; field: @@ -34,7 +37,12 @@ export const machineEvents = {} as | 'city' | 'bankAccountNumber' | 'IBAN' - | 'SWIFT'; + | 'SWIFT' + | 'feeNumber' + | 'appPhoneNumber' + | 'customerNumber' + | 'travelCardNumber' + | 'isAppTicketStorageMode'; value: | string | number @@ -42,4 +50,10 @@ export const machineEvents = {} as | Line['quays'][0] | TransportModeType | ReasonForTransportFailure; - }; + } + + // travel-guarantee + | { type: 'TAXI' } + | { type: 'CAR' } + | { type: 'OTHER' } + | { type: 'SET_STATE_SUBMITTED'; stateSubmitted: string | undefined }; diff --git a/src/page-modules/contact/ticket-control/complaint/complaintFormMachine.ts b/src/page-modules/contact/ticket-control/complaint/complaintFormMachine.ts index 103769f5..d5899f5b 100644 --- a/src/page-modules/contact/ticket-control/complaint/complaintFormMachine.ts +++ b/src/page-modules/contact/ticket-control/complaint/complaintFormMachine.ts @@ -1,391 +1,193 @@ -import { assign, setup } from 'xstate'; +import { assign, fromPromise, setup } from 'xstate'; +import { machineEvents } from '../../machineEvents'; +import { commonFieldValidator, InputErrorMessages } from '../../validation'; + +type APIParams = { + feeNumber: string; + appPhoneNumber: string | undefined; + customerNumber: string | undefined; + travelCardNumber: string | undefined; + feedback: string; + firstName: string; + lastName: string; + address: string; + postalCode: string; + city: string; + email: string; + phoneNumber: string; + bankAccountNumber: string; + IBAN: string; + SWIFT: string; +}; + +type ContextProps = { + agreesFirstAgreement: boolean; + agreesSecondAgreement: boolean; + isAppTicketStorageMode: boolean; + hasInternationalBankAccount: boolean; + errorMessages: InputErrorMessages; +} & APIParams; export const formMachine = setup({ types: { - context: {} as { - feeNumber: string; - registeredMobile: string | undefined; - customerNumber: string | undefined; - travelcard: string | undefined; - feedback: string; - firstname: string; - lastname: string; - address: string; - postalCode: string; - city: string; - email: string; - phonenumber: string; - bankAccount: string; - iban: string; - swift: string; - ticketStorageMode: string | undefined; - }, + context: {} as ContextProps, + events: machineEvents, }, - guards: { - isFeedNumberEmpty: ({ context }) => context.feeNumber.length === 0, - isTicketStorageModeUndefined: ({ context }) => !context.ticketStorageMode, - isRegisteredMobileUndefined: ({ context }) => { - return !context.registeredMobile && context.ticketStorageMode === 'App'; - }, - isCustomerNumberUndefined: ({ context }) => { - return !context.customerNumber && context.ticketStorageMode === 'App'; - }, - isTravelcardUndefined: ({ context }) => { - return !context.travelcard && context.ticketStorageMode === 'Travelcard'; - }, - isFeedbackEmpty: ({ context }) => context.feedback.length === 0, - isFirstnameEmpty: ({ context }) => context.firstname.length === 0, - isLastnameEmpty: ({ context }) => context.lastname.length === 0, - isEmailEmpty: ({ context }) => context.email.length === 0, - isAddressEmpty: ({ context }) => context.address.length === 0, - isPostalCodeEmpty: ({ context }) => context.postalCode.length === 0, - isCityEmpty: ({ context }) => context.city.length === 0, - isPhonenumberEmpty: ({ context }) => context.phonenumber.length === 0, - isBankAccountEmpty: ({ context }) => context.bankAccount.length === 0, + validateInputs: ({ context }) => commonFieldValidator(context), + }, + actions: { + cleanErrorMessages: assign({ + errorMessages: () => ({}), + }), + + toggleField: assign(({ context, event }: any) => { + if (event.type === 'TOGGLE') { + const { field } = event; + return { + [field]: !context[field], + }; + } + return context; + }), + + updateField: assign(({ context, event }) => { + if (event.type === 'UPDATE_FIELD') { + const { field, value } = event; + // Remove errorMessages if any + context.errorMessages[field] = []; + return { + ...context, + [field]: value, + }; + } + return context; + }), + }, + actors: { + callAPI: fromPromise( + async ({ + input: { + feeNumber, + appPhoneNumber, + customerNumber, + travelCardNumber, + feedback, + firstName, + lastName, + address, + postalCode, + city, + email, + phoneNumber, + bankAccountNumber, + IBAN, + SWIFT, + }, + }: { + input: APIParams; + }) => { + return await fetch('/contact/ticket-control', { + method: 'POST', + body: JSON.stringify({ + feeNumber: feeNumber, + appPhoneNumber: appPhoneNumber, + customerNumber: customerNumber, + travelCardNumber: travelCardNumber, + additionalInfo: feedback, + firstName: firstName, + lastName: lastName, + address: address, + postalCode: postalCode, + city: city, + email: email, + phoneNumber: phoneNumber, + bankAccountNumber: bankAccountNumber, + IBAN: IBAN, + SWIFT: SWIFT, + }), + }).then((response) => { + // throw an error to force onError + if (!response.ok) throw new Error('Failed to call API'); + return response.ok; + }); + }, + ), }, - actions: {}, }).createMachine({ - /** @xstate-layout N4IgpgJg5mDOIC5QDMxgMIHsC2AHANgIYCWAdgC4BimATtgHTLE2zkCCUNa2YFAxIU5pKzVhy5geFANoAGALqJQuTLGLlimUkpAAPRAEYAnAHYANCACeiAKxGDAJnoBmACzP7JgBwA2L668vAF8gi1QMHAISCmo6elgwAGMtCHFuXnI+CGJYQQkRFnYhSQy5RSQQFTUNLR19BC8HHxcHLwNGhxNnNqNXC2sEOx8nf27hmxM-G1cQsLQsPCIyKloGBOTSVOKpTLy0AGUklLSSmQUdKvVNbQr6g1dZWXofB59TB5s7bv7bZxf6L6mBxGBwOZwGEyzEDhBZRZaxBiQK6kKB8fYAUQAKgB9Sjo9HYgByAFUALIAIXRACUyhdVFdardfk9jCC3CYTA5ZHYvD8EH5XPR7rIfLI-gYPEZplCYZEljFVvQkRoUWisdjMQBJdAAaXV+0xAHkqWwAOIE0mGgAi6NpFUuNRuoHqARM9FMPmG90mjxsfJsXjdNmGrhMRiMoucYpmoWh8zl0RWcWVZFRGJxVPRps1Bup6Kt2Mt5M1ABlbed7fTHXVbLIDADPa5jG8TKG6+YrIhXEYnkZRsGo56DAYfM4ZfHFomEUrsiq0+r0MSDYbSdSiWTKTSK8oq9ca4M688XrJek0A64fAY+R5Ba8wWfgcZIbHZZP4YqU6r0xqTQA1dElugbBUlado7tUe5MoM4IuH2F6mHWLx2HywJuo0bSyF44Ygp0HLjhEb4Ksms6pmqOJ4vm5JsLqYGVLujLOrYDzupMorGAYsgOI4HYDFy9YON2fY2G4nzOAG+GwvKSaIiRX7qpQmpUgahJsKutEOpBjHQW6I5eI8UpNC8RjOP6rL0JMAZccMrQnhJCbvsRyLzjiJZsMpqnluU4EMk6ei-EY9CYUJXQjq4rjAqZYpCoGLYRvYI52YR0kzk5ZHYmwVpWpm+z7Op9G+fU0yCl4zhcgETRgnW-qPM0opSq24LTA4NiJXCREyal34AAqGgabAlti6DWp5dIQQxfmDM19BtM1rQCUFfx8t2HGBeCrg2CKl4hS1L4Tm1yWfs5g2apiACaeVjQVtijoFHrhsGI5cj4S1tM49Drc4pUmI8ekxnMBH7dOh1peipJsKWF0+funxus4JgbRK302PcDhLSYI7TfDXKfdMbhGK1UlA7JR1dQAEoahLoiSpIUtSkPVlByM2IF8HDoGNgCfcS3DE8qGyGG30isGO3-ZJU4fsTaVUYSOrpegQ3EoSmL05pE3I7DvQPRK63DDxXYc296NYcGsjwS8BPi45c5ZDkexgAUYjbKU250Zd+7DhzAKPCKoI+MjgR8hKnTun4rZdCeow+BbDkddb2S5MUhwbFsEg7Cr413N6Xs1b7-u8p2CCOPz5ntOjwn8yK+O7QDhMS51xLkqSJ3p1dCCgnrCBuG4Je9GFmGinYf1xjXlux6R+wN03ysGF5rtQ1B7eB10bro-Y4V2O0AZR9XYsxyl1sT43zcOLPGkZ4gi8FxCEb0FxIJC+8-PPqL9ntfv4+T83zin-l+6XwMI4wy32MPzLwW9wTRzfsDQ+U9pCuB-m7BenRA5gMFKvAwyMowTFbA4SBB1JYwObjYBB88tL-0QOCdoPcHjGSwu4KUeCib1yPsrHwJCGZkOQQXASvge4cWFO0UqjC64H0-srEw7DVb1HIYXP4b0uJYQEnYZqQthFWw-iw6QXhJHnzblw3ieknCr0Qnpbiaix5fjEdIIwOjW4yLhhtah3hvBNGCDvV++DmGwI4rYv++iuzdCMSA76fZ0HmPfpYzRw5fFII7q8Zoxi-jAm5N9Mc7ikpMNEVEk+o1SETRkRxUMwDAxI1CZxNxL8MkiI0d47+uSOH5P8W3CETwja9FbJhcpz9h67ygQQqx9wYlaQ9k4DaOczztHzgAjBboFEcm5GU1o4TYAAFcABG2B1DW2yoaEs-4W7u1MP6Hw31pr0JCmxLiyz1mbPINbSg-VNTEkzAcqCjg2guEcJ8J+EYTx9ALh8sZdZgT2DEk0KusZSCYAgHAHQr5AarHqVIww4I+QAFpmjeyxdilG4SmCFBODsJFuj7jrXep0Ec-NgSjjcIHUqXh3p+FDkOWayyjibEJRkYlrcRnZx9hMgOBcN5vWMB4UU3IejdPhbXdRKJuXuzDHyVsaD2iigFtyU229KkItlVARgaBCQrOwGssANB5WMylO6PmrFKWgmvHfahiMLxiq1T0jxmTUz6rAIa41pr6AADdCD4GIBAc1WkuiCk+KGME31Ojdj9AXT6xc77hROXDVsDD0k6osXq8IPqTU0CVDQGgtAw0TReG9EECEbWijtYm9kPc4aksvBgkWbqqm6q9fmv1pqS2FskLgcglhKAGqNQWst9Q3j1ird9GtnFUaJvcMzO+3QwpwwvCVcJh16AaESAAazAOQfY5BaCCDAKSaFYAJ22EtTO-mQ5a0LoAReQUCiQR0N6ObLNMqc07uIPuw9x7T0wAvTCgNQaQ3XoQN4J4gZjZRkDPGkyV9Pj1jaU2XomERyuulaPCJerd0HqPSemgZ7QNgCLX2qDFarXVoffOwOyjgE9gWc6v2bbcN723YRwDJGyOXso7QegKzNhgCYKQSAmJ-1EaA1wfjMLqP2Fo7O+jdaAFdAZXfTCwJ3BNHhlu4mf6APEeA+egTvahMiZheJyAVIwBQByOQU1kAL1rOIPgK9lZEFaSncp+9l5H1Lxvug+CAQ2hfu1T+-DRmZN8ZA+Z4tlnRM2YgOgFZrAcCmu7WarzeTJ1KbvXOtThgTkBWMe0YyHJ2hD0430pyMXeOmfI4J-teAh2YlI-6sA+BEiEBoKG3LDT8vTutapp9hgwHLuMFxE8uM-ZpMi3h7d4QIBrMIPuqDdhmaFbGyhHshsQFcQwR0Cp7bs3RZW2t-d4Hg0De8kNxAnI0L9zNh8dGe2lNabcPcKUekpV7Si8ttAq31t7pa9R9wfmivjc7mKNDoq-gZu7KGAz9XLug5a0qNrw7gdXb3YpkbdGAsMcTcOAKK7uwdP8Pp79S3DP4tYKQQgPBNu3tG8T4rej0Yl2NhCIyvgFtncB-T0Q5Amc8Bu5BwbyLoOtABFhXwOsOY9ivNwsS5OKsvHhjSqui2uMi8KOLijFmcv3ZlzRnbHOYdgnDD3Lpl5Aindq54ucjBRdG8xwOodDsxfM882b3RvnLe2ut66ZjpsITCXmjhgHdP6tEEZ371n232ch8DvcTTpcM2fE9CKVHruE++4l4G27UGnvumvuhUqmrnpXzBMzI2zj2l1jcPnz1hePcm4h5W1PgW6+TGKWA4wHNgzNTbyiegHe-ee+xyWQgieWfS8DwV3vJOAFyJ54r3oHgME1dj-r+rhAIAQC4LAeAS-W5bah7t7hAYV7sRSXfrC-2R4H9d0fk-cBYCS7u3PB7svCdWxm1Jh-AUITkptHc6wYY8Jac39PUP9T9v8u8L99wLdV9OcKUG8KswoRwg4Y9X86t39j9ECZ9B1LA2BiCv8Cdr8rcUI9J5EKsJgME9NAxx89UqhyAg0sAFMUCLUU8ic09E1hIsDe5-B3B2w98CCXdPUOCuCBMS8pcA9W4uhK1r4M0FdmoO4kkGCEJHhWguhgw2D6BZD8BuDjdEtTc-9zdIdg8+8Bg-gbpV5JgHg3BWgUdYDCCZDVBODTCEs+0scyCupvC5CeClDUCV8BC7CKF4Z+Jh9V1wQKUnd99PCJ9Eh1ABgwi+CaDBCBgmwTk7dXhQwOYX9elpDUj0if8y9k0LwOIDDPR4YjAlpmopsexhJRxHcDAjC0ih1wdeCfMbD0CYdwpLV0E+cwphiuiKiTcAih10B0jqDbC18AkSpmMJQRQxIXEjDJASB8Bk9siojO4h9G12jwp1oONkiyi9Vtj3NKi+iJp0YnB2J1pcIxRRQpkKFjINdKs-BPo9IkipCPUJ9rj8BejMj+ie9IiljO5TAytpt50wpwwIQtjsAdjSCh10QUT3MFjBiloRRZkKtWIMNvB-jSjAT2CAALLQXgMdU1PYxYznEqJwBRHmCMTeLoIw3ASkiTUgGkwtBQ3-M+ZQyHIOanToN4LiGHewWEwITkaYeGeGSQ0k6pCfTkqknk31ftCw7vfYqE35YpWKO-AMXXIXOPV3VU7k3ktEywLqLk6kjU7EyEznQpe-QMDiKUOsD2IwtbUgPdNgRIZIETcgOknEq+KUEQ14v4KNXwL0wgH0v0gMigW4sE+45ibsS8GhdwMMQMFCU2BgwIWo8YDYmMuM-0zAQM0EqwwPAYx063TCA7GU0MPwTCc4gE5UvVb0300s8s6Yr3SwckWMzshMoMu44bHUjAiEWIx3DkQeOGa5DZLZVMKDe4MSaaZGF4PI9Y-5AYHsQKRk0wLuJlTojw5KVZf0qgkcwwZgvlayP2SZY5U5E8HfSYQcfwEIEIIAA */ id: 'feeComplaintForm', - initial: 'firstAgreement', + initial: 'editing', context: { feeNumber: '', - registeredMobile: undefined, + appPhoneNumber: undefined, customerNumber: undefined, - travelcard: undefined, + travelCardNumber: undefined, feedback: '', - firstname: '', - lastname: '', + firstName: '', + lastName: '', address: '', postalCode: '', city: '', email: '', - phonenumber: '', - bankAccount: '', - iban: '', - swift: '', - ticketStorageMode: undefined, + phoneNumber: '', + bankAccountNumber: '', + IBAN: '', + SWIFT: '', + agreesFirstAgreement: false, + agreesSecondAgreement: false, + hasInternationalBankAccount: false, + isAppTicketStorageMode: true, + errorMessages: {}, }, states: { - firstAgreement: { - on: { - agreeFirstAgreement: 'secondAgreement', - }, - tags: ['firstAgreement'], - }, - - secondAgreement: { - on: { - disagreeFirstAgreement: 'firstAgreement', - agreeSecondAgreement: 'editing', - }, - tags: ['firstAgreement', 'secondAgreement'], - }, - editing: { + entry: 'cleanErrorMessages', on: { - SET_FEE_NUMBER: { - actions: assign({ - feeNumber: ({ event }) => event.feeNumber, - }), - }, - SET_TICKET_STORAGE_MODE: { - actions: assign({ - ticketStorageMode: ({ event }) => event.ticketStorageMode, - }), - }, - SET_REGISTERED_MOBILE: { - actions: assign({ - registeredMobile: ({ event }) => event.registeredMobile, - }), - }, - SET_CUSTOMER_NUMBER: { - actions: assign({ - customerNumber: ({ event }) => event.customerNumber, - }), - }, - SET_TRAVELCARD: { - actions: assign({ - travelcard: ({ event }) => event.travelcard, - }), - }, - SET_FEEDBACK: { - actions: assign({ - feedback: ({ event }) => event.feedback, - }), - }, - SET_FIRSTNAME: { - actions: assign({ - firstname: ({ event }) => event.firstname, - }), - }, - SET_LASTNAME: { - actions: assign({ - lastname: ({ event }) => event.lastname, - }), - }, - SET_ADDRESS: { - actions: assign({ - address: ({ event }) => event.address, - }), - }, - SET_POSTAL_CODE: { - actions: assign({ - postalCode: ({ event }) => event.postalCode, - }), - }, - SET_CITY: { - actions: assign({ - city: ({ event }) => event.city, - }), - }, - SET_EMAIL: { - actions: assign({ - email: ({ event }) => event.email, - }), - }, - SET_PHONENUMMBER: { - actions: assign({ - phonenumber: ({ event }) => event.phonenumber, - }), - }, - SET_BANK_ACCOUNT: { - actions: assign({ - bankAccount: ({ event }) => event.bankAccount, - }), - }, - SET_IBAN: { - actions: assign({ - iban: ({ event }) => event.iban, - }), - }, - SET_SWIFT: { - actions: assign({ - swift: ({ event }) => event.swift, - }), + TOGGLE: { + actions: 'toggleField', }, - disagreeFirstAgreement: { - target: 'firstAgreement', + UPDATE_FIELD: { + actions: 'updateField', }, - disagreeSecondAgreement: { - target: 'secondAgreement', + VALIDATE: { + guard: 'validateInputs', + target: 'submitting', }, - SUBMIT: [ - { - guard: 'isFeedNumberEmpty', - target: 'editing.feeNumber.error.emptyFeeNumber', - }, - { - guard: 'isTicketStorageModeUndefined', - target: - 'editing.ticketStorageMode.error.undefinedTicketStoreageMode', - }, - { - guard: 'isRegisteredMobileUndefined', - target: 'editing.ticketStorageMode.error.undefinedRegisteredMobile', - }, - { - guard: 'isCustomerNumberUndefined', - target: 'editing.ticketStorageMode.error.undefinedCustomerNumber', - }, - { - guard: 'isTravelcardUndefined', - target: 'editing.ticketStorageMode.error.undefinedTravelcard', - }, - { - guard: 'isFeedbackEmpty', - target: 'editing.feedback.error.emptyFeedback', - }, - { - guard: 'isFirstnameEmpty', - target: 'editing.firstname.error.emptyFirstname', - }, - { - guard: 'isLastnameEmpty', - target: 'editing.lastname.error.emptyLastname', - }, - { - guard: 'isAddressEmpty', - target: 'editing.address.error.emptyAddress', - }, - { - guard: 'isPostalCodeEmpty', - target: 'editing.postalCode.error.emptyPostalCode', - }, - { - guard: 'isCityEmpty', - target: 'editing.city.error.emptyCity', - }, - { - guard: 'isEmailEmpty', - target: 'editing.email.error.emptyEmail', - }, - { - guard: 'isPhonenumberEmpty', - target: 'editing.phonenumber.error.emptyPhonenumber', - }, - { - guard: 'isBankAccountEmpty', - target: 'editing.bankAccount.error.emptyBankAccount', - }, - { - target: 'submitting', - }, - ], }, - type: 'parallel', + }, - states: { - feeNumber: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyFeeNumber', - states: { - emptyFeeNumber: {}, - }, - }, - }, - }, - ticketStorageMode: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'undefinedTicketStorageMode', - states: { - undefinedTicketStoreageMode: {}, - undefinedRegisteredMobile: {}, - undefinedCustomerNumber: {}, - undefinedTravelcard: {}, - }, - }, - }, - }, - feedback: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyFeedback', - states: { - emptyFeedback: {}, - }, - }, - }, - }, - firstname: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyFirstname', - states: { - emptyFirstname: {}, - }, - }, - }, - }, - lastname: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyLastname', - states: { - emptyLastname: {}, - }, - }, - }, - }, - address: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyAddress', - states: { - emptyAddress: {}, - }, - }, - }, - }, - postalCode: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyPostalCode', - states: { - emptyPostalCode: {}, - }, - }, - }, - }, - city: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyCity', - states: { - emptyCity: {}, - }, - }, - }, - }, - email: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyEmail', - states: { - emptyEmail: {}, - }, - }, - }, - }, - phonenumber: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyPhonenumber', - states: { - emptyPhonenumber: {}, - }, - }, - }, - }, - bankAccount: { - initial: 'valid', - states: { - valid: {}, - error: { - initial: 'emptyBankAccount', - states: { - emptyBankAccount: {}, - }, - }, - }, + submitting: { + invoke: { + src: 'callAPI', + input: ({ context }) => ({ + feeNumber: context.feeNumber, + appPhoneNumber: context.appPhoneNumber, + customerNumber: context.customerNumber, + travelCardNumber: context.travelCardNumber, + feedback: context.feedback, + firstName: context.firstName, + lastName: context.lastName, + address: context.address, + postalCode: context.postalCode, + city: context.city, + email: context.email, + phoneNumber: context.phoneNumber, + bankAccountNumber: context.bankAccountNumber, + IBAN: context.IBAN, + SWIFT: context.SWIFT, + }), + + onDone: { + target: 'success', }, - }, - tags: ['firstAgreement', 'secondAgreement', 'editing'], - }, - submitting: { - on: { - RESOLVE: 'success', - FALIURE: { + onError: { target: 'editing', }, }, - tags: ['firstAgreement', 'secondAgreement', 'editing'], }, + success: { type: 'final', }, diff --git a/src/page-modules/contact/ticket-control/complaint/feeComplaintForm.tsx b/src/page-modules/contact/ticket-control/complaint/feeComplaintForm.tsx deleted file mode 100644 index 9d47c950..00000000 --- a/src/page-modules/contact/ticket-control/complaint/feeComplaintForm.tsx +++ /dev/null @@ -1,562 +0,0 @@ -import { FormEventHandler, useState } from 'react'; -import style from '../../contact.module.css'; -import { Button } from '@atb/components/button'; -import { Input } from '../../components/input'; -import { SectionCard } from '../../components/section-card'; -import { PageText, TranslatedString, useTranslation } from '@atb/translations'; -import { useMachine } from '@xstate/react'; -import { formMachine } from './complaintFormMachine'; -import { Checkbox } from '../../components/input/checkbox'; -import { Typo } from '@atb/components/typography'; -import { RadioInput } from '../../components/input/radio'; -import { Textarea } from '../../components/input/textarea'; - -export const FeeComplaintForm = () => { - const { t } = useTranslation(); - const [state, send] = useMachine(formMachine); - - const onSubmit: FormEventHandler = async (e) => { - e.preventDefault(); - - if (!state.matches('submitting')) return; - - const response = await fetch('/api/contact/ticket-control', { - method: 'POST', - body: JSON.stringify({ - feeNumber: state.context.feeNumber, - appPhoneNumber: state.context.registeredMobile, - customerNumber: state.context.customerNumber, - travelCardNumber: state.context.travelcard, - additionalInfo: state.context.feedback, - firstName: state.context.firstname, - lastName: state.context.lastname, - address: state.context.address, - postalCode: state.context.postalCode, - city: state.context.city, - email: state.context.email, - phoneNumber: state.context.phonenumber, - bankAccountNumber: state.context.bankAccount, - IBAN: state.context.iban, - SWIFT: state.context.swift, - }), - }); - - if (response.ok) { - const res = await response.json(); - send({ type: 'RESOLVE' }); - } else { - send({ type: 'FALIURE' }); - } - }; - - const agreesFirstAgreement = state.hasTag('secondAgreement'); - const agreesSecondAgreement = state.hasTag('editing'); - const isAppSelected = state.context.ticketStorageMode === 'App'; - const isTravelcardSelected = state.context.ticketStorageMode === 'Travelcard'; - const [isBankAccountForeign, setBankAccountForeign] = useState(false); - - const FirstAgreement = () => { - return ( - - - {t( - PageText.Contact.ticketControl.feeComplaint.firstAgreement.question, - )} - -
- - {t( - PageText.Contact.ticketControl.feeComplaint.firstAgreement - .labelRules, - )} - -
    - {PageText.Contact.ticketControl.feeComplaint.firstAgreement.rules.map( - (rule: TranslatedString, index: number) => ( -
  • - {t(rule)} -
  • - ), - )} -
-
- - - send({ - type: !agreesFirstAgreement - ? 'agreeFirstAgreement' - : 'disagreeFirstAgreement', - }) - } - /> -
- ); - }; - - const SecondAgreement = () => { - return ( - - - - {t(PageText.Contact.ticketControl.feeComplaint.secondAgreement.info)} - - - - send({ - type: !agreesSecondAgreement - ? 'agreeSecondAgreement' - : 'disagreeSecondAgreement', - }) - } - /> - - ); - }; - - const isFeeNumberEmpty = state.matches({ - editing: { feeNumber: { error: 'emptyFeeNumber' } }, - }); - - const undefinedTicketStoreageMode = state.matches({ - editing: { - ticketStorageMode: { error: 'undefinedTicketStoreageMode' }, - }, - }); - const isRegisteredMobileUndefined = state.matches({ - editing: { - ticketStorageMode: { error: 'undefinedRegisteredMobile' }, - }, - }); - const isCustomerNumberUndefined = state.matches({ - editing: { - ticketStorageMode: { error: 'undefinedCustomerNumber' }, - }, - }); - const isTravelcardUndefined = state.matches({ - editing: { - ticketStorageMode: { error: 'undefinedTravelcard' }, - }, - }); - - const isFeedbackEmpty = state.matches({ - editing: { feedback: { error: 'emptyFeedback' } }, - }); - - const isFirstnameEmpty = state.matches({ - editing: { firstname: { error: 'emptyFirstname' } }, - }); - - const isLastnameEmpty = state.matches({ - editing: { lastname: { error: 'emptyLastname' } }, - }); - - const isAddressEmpty = state.matches({ - editing: { address: { error: 'emptyAddress' } }, - }); - - const isPostalCodeEmpty = state.matches({ - editing: { postalCode: { error: 'emptyPostalCode' } }, - }); - - const isCityEmpty = state.matches({ - editing: { city: { error: 'emptyCity' } }, - }); - - const isPhonenumberEmpty = state.matches({ - editing: { phonenumber: { error: 'emptyPhonenumber' } }, - }); - - const isEmailEmpty = state.matches({ - editing: { email: { error: 'emptyEmail' } }, - }); - const isBankAccountEmpty = state.matches({ - editing: { bankAccount: { error: 'emptyBankAccount' } }, - }); - - return ( -
- {state.hasTag('firstAgreement') && } - {state.hasTag('secondAgreement') && } - {state.hasTag('editing') && ( -
- - - send({ - type: 'SET_FEE_NUMBER', - feeNumber: e.target.value, - }) - } - /> - - - {t( - PageText.Contact.ticketControl.feeComplaint.ticketStorage - .question, - )} - - -
- - send({ - type: 'SET_TICKET_STORAGE_MODE', - ticketStorageMode: 'App', - }) - } - /> - - send({ - type: 'SET_TICKET_STORAGE_MODE', - ticketStorageMode: 'Travelcard', - }) - } - /> - {undefinedTicketStoreageMode && ( - - )} -
- - {isAppSelected && ( -
- - send({ - type: 'SET_REGISTERED_MOBILE', - registeredMobile: e.target.value, - }) - } - /> - - - send({ - type: 'SET_CUSTOMER_NUMBER', - customerNumber: e.target.value, - }) - } - /> -
- )} - {isTravelcardSelected && ( - - send({ - type: 'SET_TRAVELCARD', - travelcard: e.target.value, - }) - } - /> - )} -
- -