@@ -2,6 +2,7 @@ import { data, useFetcher } from 'react-router';
2
2
import type { RouteHandle } from 'react-router' ;
3
3
4
4
import { faXmark , faExclamationCircle } from '@fortawesome/free-solid-svg-icons' ;
5
+ import type { SessionData } from 'express-session' ;
5
6
import { useTranslation } from 'react-i18next' ;
6
7
import * as v from 'valibot' ;
7
8
@@ -14,10 +15,13 @@ import { ErrorSummary } from '~/components/error-summary';
14
15
import { InputCheckbox } from '~/components/input-checkbox' ;
15
16
import { PageTitle } from '~/components/page-title' ;
16
17
import { Progress } from '~/components/progress' ;
18
+ import { AppError } from '~/errors/app-error' ;
17
19
import { getFixedT } from '~/i18n-config.server' ;
18
20
import { handle as parentHandle } from '~/routes/protected/layout' ;
19
21
import { getLanguage } from '~/utils/i18n-utils' ;
20
22
23
+ type PrivacyStatmentSessionData = NonNullable < SessionData [ 'inPersonSINCase' ] [ 'privacyStatement' ] > ;
24
+
21
25
export const handle = {
22
26
i18nNamespace : [ ...parentHandle . i18nNamespace , 'protected' ] ,
23
27
} as const satisfies RouteHandle ;
@@ -28,9 +32,7 @@ export async function loader({ context, request }: Route.LoaderArgs) {
28
32
29
33
return {
30
34
documentTitle : t ( 'protected:privacy-statement.page-title' ) ,
31
- defaultFormValues : {
32
- confirmPrivacyNotice : context . session . inPersonSINCase ?. confirmPrivacyNotice ,
33
- } ,
35
+ defaultFormValues : context . session . inPersonSINCase ?. privacyStatement ,
34
36
} ;
35
37
}
36
38
@@ -42,34 +44,40 @@ export async function action({ context, request }: Route.ActionArgs) {
42
44
requireAuth ( context . session , new URL ( request . url ) , [ 'user' ] ) ;
43
45
const lang = getLanguage ( request ) ;
44
46
const t = await getFixedT ( request , handle . i18nNamespace ) ;
47
+
45
48
const formData = await request . formData ( ) ;
49
+ const action = formData . get ( 'action' ) ;
46
50
47
- if ( formData . get ( 'action' ) === 'back' ) {
48
- throw i18nRedirect ( 'routes/protected/index.tsx' , request ) ;
49
- }
51
+ switch ( action ) {
52
+ case 'back' : {
53
+ throw i18nRedirect ( 'routes/protected/index.tsx' , request ) ;
54
+ }
50
55
51
- // submit action
52
- const schema = v . object ( {
53
- confirmPrivacyNotice : v . pipe (
54
- v . string ( t ( 'protected:privacy-statement.confirm-privacy-notice-checkbox.required' ) ) ,
55
- v . trim ( ) ,
56
- v . nonEmpty ( t ( 'protected:privacy-statement.confirm-privacy-notice-checkbox.required' ) ) ,
57
- ) ,
58
- } ) ;
56
+ case 'next' : {
57
+ const schema = v . object ( {
58
+ agreedToTerms : v . literal ( true , t ( 'protected:privacy-statement.confirm-privacy-notice-checkbox.required' ) ) ,
59
+ } ) satisfies v . GenericSchema < PrivacyStatmentSessionData > ;
59
60
60
- const input = { confirmPrivacyNotice : formData . get ( 'confirmPrivacyNotice' ) as string } ;
61
- const parsedDataResult = v . safeParse ( schema , input , { lang } ) ;
61
+ const input = {
62
+ agreedToTerms : formData . get ( 'agreedToTerms' ) ? true : undefined ,
63
+ } satisfies Partial < PrivacyStatmentSessionData > ;
62
64
63
- if ( ! parsedDataResult . success ) {
64
- return data ( { errors : v . flatten < typeof schema > ( parsedDataResult . issues ) . nested } , { status : 400 } ) ;
65
- }
65
+ const parseResult = v . safeParse ( schema , input , { lang } ) ;
66
66
67
- context . session . inPersonSINCase = {
68
- ...( context . session . inPersonSINCase ?? { } ) ,
69
- ...input ,
70
- } ;
67
+ if ( ! parseResult . success ) {
68
+ return data ( { errors : v . flatten < typeof schema > ( parseResult . issues ) . nested } , { status : 400 } ) ;
69
+ }
70
+
71
+ context . session . inPersonSINCase ??= { } ;
72
+ context . session . inPersonSINCase . privacyStatement = parseResult . output ;
71
73
72
- throw i18nRedirect ( 'routes/protected/person-case/first-name.tsx' , request ) ; //TODO: change it to redirect to file="routes/protected/person-case/request-details.tsx"
74
+ throw i18nRedirect ( 'routes/protected/person-case/first-name.tsx' , request ) ; //TODO: change it to redirect to file="routes/protected/person-case/request-details.tsx"
75
+ }
76
+
77
+ default : {
78
+ throw new AppError ( `Unrecognized action: ${ action } ` ) ;
79
+ }
80
+ }
73
81
}
74
82
75
83
export default function PrivacyStatement ( { loaderData, actionData, params } : Route . ComponentProps ) {
@@ -120,10 +128,10 @@ export default function PrivacyStatement({ loaderData, actionData, params }: Rou
120
128
</ p >
121
129
122
130
< InputCheckbox
123
- id = "confirmPrivacyNotice "
124
- name = "confirmPrivacyNotice "
125
- errorMessage = { errors ?. confirmPrivacyNotice ?. [ 0 ] }
126
- defaultChecked = { loaderData . defaultFormValues . confirmPrivacyNotice === 'on' }
131
+ id = "agreed-to-terms "
132
+ name = "agreedToTerms "
133
+ errorMessage = { errors ?. agreedToTerms ?. [ 0 ] }
134
+ defaultChecked = { loaderData . defaultFormValues ?. agreedToTerms }
127
135
required
128
136
>
129
137
{ t ( 'protected:privacy-statement.confirm-privacy-notice-checkbox.title' ) }
0 commit comments