-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathAddAttendeeModal.tsx
More file actions
113 lines (99 loc) · 3.9 KB
/
AddAttendeeModal.tsx
File metadata and controls
113 lines (99 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { useContext, useState } from 'react';
import { Modal } from 'react-bootstrap4-modal';
import { ActionFunction, RouterContextProvider, redirect, useFetcher, useNavigate } from 'react-router';
import { useTranslation } from 'react-i18next';
import { LoadingIndicator, ErrorDisplay } from '@neinteractiveliterature/litform';
import UserSelect from '../BuiltInFormControls/UserSelect';
import { AddAttendeeUsersQueryData, AddAttendeeUsersQueryDocument } from './queries.generated';
import { FormResponse } from '../FormPresenter/useFormResponse';
import AppRootContext from 'AppRootContext';
import { CreateUserConProfileDocument, CreateUserConProfileMutationVariables } from './mutations.generated';
import { apolloClientContext } from '../AppContexts';
export const action: ActionFunction<RouterContextProvider> = async ({ context, request }) => {
const client = context.get(apolloClientContext);
try {
const variables = (await request.json()) as CreateUserConProfileMutationVariables;
await client.mutate({ mutation: CreateUserConProfileDocument, variables });
await client.resetStore();
return redirect('..');
} catch (error) {
return error;
}
};
type UserType = AddAttendeeUsersQueryData['users_paginated']['entries'][0];
function AddAttendeeModal(): React.JSX.Element {
const { t } = useTranslation();
const navigate = useNavigate();
const { convention } = useContext(AppRootContext);
const [user, setUser] = useState<UserType>();
const [userConProfile, setUserConProfile] = useState<FormResponse>();
const fetcher = useFetcher();
const error = fetcher.data instanceof Error ? fetcher.data : undefined;
const inProgress = fetcher.state !== 'idle';
const close = () => {
setUser(undefined);
setUserConProfile(undefined);
navigate('/user_con_profiles', { replace: true });
};
const userSelected = (newUser: UserType | null) => {
if (!newUser) return;
setUser(newUser);
setUserConProfile({
__typename: 'UserConProfile',
id: 'not-created-yet',
form_response_attrs: {
first_name: newUser.first_name ?? null,
last_name: newUser.last_name ?? null,
},
});
};
const createClicked = () => {
if (!user || !userConProfile) {
return;
}
fetcher.submit(
{
user_id: user.id,
user_con_profile: {
form_response_attrs_json: JSON.stringify(userConProfile.form_response_attrs),
},
} satisfies CreateUserConProfileMutationVariables,
{ method: 'POST', encType: 'application/json' },
);
};
return (
<Modal visible dialogClassName="modal-lg">
<div className="modal-header">{t('admin.userConProfiles.addAttendee.header')}</div>
<div className="modal-body">
<p>
{t(
'admin.userConProfiles.addAttendee.text',
`Choose a user to add as an attendee for {{ conventionName }}.
This person must already be a user in the site database in order to be added.`,
{ conventionName: convention?.name },
)}
</p>
<UserSelect value={user} onChange={userSelected} usersQuery={AddAttendeeUsersQueryDocument} />
{user && (
<div className="mt-4">
<p>{t('admin.userConProfiles.addAttendee.dataCopyingNote')}</p>
</div>
)}
<ErrorDisplay graphQLError={error} />
</div>
<div className="modal-footer">
<button className="btn btn-secondary" type="button" onClick={close} disabled={inProgress}>
{t('buttons.cancel')}
</button>
<button className="btn btn-primary" type="button" onClick={createClicked} disabled={user == null || inProgress}>
{inProgress ? (
<LoadingIndicator iconSet="bootstrap-icons" />
) : (
t('admin.userConProfiles.addAttendee.addButtonText')
)}
</button>
</div>
</Modal>
);
}
export const Component = AddAttendeeModal;