Skip to content

Commit 39bc651

Browse files
feat(user/request-form): add required profile fields
1 parent 9adfefd commit 39bc651

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

components/user/request-form.module.scss

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,29 @@
33
@include common.card-styles;
44

55
.card {
6+
position: relative;
67
margin-top: 24px;
7-
padding: 16px;
8-
}
98

10-
.field {
11-
@include common.field;
12-
}
9+
.inputs {
10+
margin: 16px auto;
11+
padding: 0 16px;
1312

14-
.button {
15-
width: 100%;
16-
margin: 8px 0 0;
17-
}
13+
.field {
14+
@include common.field;
15+
}
16+
17+
.btn {
18+
margin-top: 8px;
19+
width: 100%;
20+
}
21+
22+
.error {
23+
@include common.error;
24+
}
25+
}
1826

19-
.error {
20-
@include common.error;
27+
.divider {
28+
@include common.divider;
29+
margin: 8px 0;
30+
}
2131
}

components/user/request-form.tsx

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@ export default function RequestForm({
6060
]);
6161
const [subjects, setSubjects] = useState<SubjectOption[]>([]);
6262
const [message, setMessage] = useState<string>('');
63-
const [phone, setPhone] = useState<string>('');
6463
const [time, setTime] = useState<Timeslot>();
6564

65+
// TODO: Sync this somehow with the global user state. When we log out, these
66+
// should become empty once again.
67+
const [reference, setReference] = useState<string>(currentUser.reference);
68+
const [phone, setPhone] = useState<string>(currentUser.phone);
69+
6670
useEffect(() => {
6771
setStudents((prev) => {
6872
const idx = prev.findIndex((s) => s.label === 'Me');
@@ -164,21 +168,24 @@ export default function RequestForm({
164168
const onPhoneChange = useCallback((event: FormEvent<HTMLInputElement>) => {
165169
setPhone(event.currentTarget.value);
166170
}, []);
167-
168-
const phoneRequired = useMemo(() => {
169-
return org ? org.profiles.includes('phone') : false;
170-
}, [org]);
171+
const onReferenceChange = useCallback((evt: FormEvent<HTMLInputElement>) => {
172+
setReference(evt.currentTarget.value);
173+
}, []);
171174

172175
const track = useTrack();
173176

174177
// Signup the user via a Google Popup window if they aren't current logged in
175178
// **before** sending the request (this will trigger an update app-wide).
176179
const onSubmit = useCallback(
177180
async (event: FormEvent<HTMLFormElement>) => {
181+
const userMissingRequiredProfileProps =
182+
(!currentUser.phone && org?.profiles.includes('phone')) ||
183+
(!currentUser.reference && org?.profiles.includes('reference'));
184+
const userWithProps = new User({ ...currentUser, phone, reference });
178185
event.preventDefault();
179186
setLoading(true);
180187
if (!currentUser.id) {
181-
const [err] = await to(signupWithGoogle(currentUser));
188+
const [err] = await to(signupWithGoogle(userWithProps));
182189
if (err) {
183190
setLoading(false);
184191
setError(
@@ -188,14 +195,14 @@ export default function RequestForm({
188195
);
189196
return;
190197
}
191-
} else if (!currentUser.phone && phoneRequired) {
198+
} else if (userMissingRequiredProfileProps) {
192199
const [err, res] = await to<
193200
AxiosResponse<UserJSON>,
194201
AxiosError<APIErrorJSON>
195-
>(axios.put('/api/account', { ...currentUser.toJSON(), phone }));
202+
>(axios.put('/api/account', userWithProps.toJSON()));
196203
if (err) {
197204
setLoading(false);
198-
setError(getErrorMessage(err, 'adding your phone number', t));
205+
setError(getErrorMessage(err, 'updating your profile', t));
199206
return;
200207
}
201208
await updateUser(User.fromJSON((res as AxiosResponse<UserJSON>).data));
@@ -216,12 +223,14 @@ export default function RequestForm({
216223
setChecked(true);
217224
}
218225
},
219-
[user, track, currentUser, phoneRequired, phone, updateUser, t]
226+
[user, track, currentUser, org, phone, reference, updateUser, t]
220227
);
221228

222-
const forOthers = useMemo(() => {
223-
return students.findIndex((s) => s.label === 'Me') < 0 ? 'for-others-' : '';
224-
}, [students]);
229+
const forOthers = useMemo(
230+
() =>
231+
students.findIndex((s) => s.label === 'Me') < 0 ? 'for-others-' : '',
232+
[students]
233+
);
225234
const person = useMemo(() => {
226235
// TODO: This logic only works for English; when we add i18n we'll probably
227236
// have to scrap all of this "custom placeholder" logic.
@@ -237,17 +246,6 @@ export default function RequestForm({
237246
<form className={styles.card} onSubmit={onSubmit}>
238247
<Loader active={loading} checked={checked} />
239248
<div className={styles.inputs}>
240-
{!currentUser.phone && phoneRequired && (
241-
<TextField
242-
label={t('match3rd:phone')}
243-
value={phone}
244-
onChange={onPhoneChange}
245-
className={styles.field}
246-
type='tel'
247-
outlined
248-
required
249-
/>
250-
)}
251249
{admin && (
252250
<UserSelect
253251
required
@@ -292,8 +290,39 @@ export default function RequestForm({
292290
onChange={onMessageChange}
293291
value={message}
294292
/>
293+
</div>
294+
<div className={styles.divider} />
295+
<div className={styles.inputs}>
296+
{!currentUser.phone && org?.profiles.includes('phone') && (
297+
<TextField
298+
label={t('user3rd:phone')}
299+
value={phone}
300+
onChange={onPhoneChange}
301+
className={styles.field}
302+
type='tel'
303+
outlined
304+
required
305+
/>
306+
)}
307+
{!currentUser.reference && org?.profiles.includes('reference') && (
308+
<TextField
309+
className={styles.field}
310+
label={t('user3rd:reference', {
311+
org: org.name || 'Tutorbook',
312+
})}
313+
placeholder={t('common:reference-placeholder', {
314+
org: org.name || 'Tutorbook',
315+
})}
316+
onChange={onReferenceChange}
317+
value={reference}
318+
rows={3}
319+
textarea
320+
outlined
321+
required
322+
/>
323+
)}
295324
<Button
296-
className={styles.button}
325+
className={styles.btn}
297326
label={
298327
!currentUser.id ? t('match3rd:signup-btn') : t('match3rd:send-btn')
299328
}

0 commit comments

Comments
 (0)