From fb7e9b64f773f2dcaaf42caca7779a96a6421413 Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Mon, 20 May 2024 22:18:28 -0700 Subject: [PATCH 1/8] update language option text, remove upper limit on hrs/month, add char limit to availability desc, add comment for legal credential --- src/app/onboarding/legal-credentials/page.tsx | 99 ++++++++++++++++--- src/data/formSchemas.ts | 49 ++++++--- src/data/languages.ts | 2 +- src/types/schema.d.ts | 1 + src/utils/OnboardingProvider.tsx | 1 + 5 files changed, 122 insertions(+), 30 deletions(-) diff --git a/src/app/onboarding/legal-credentials/page.tsx b/src/app/onboarding/legal-credentials/page.tsx index 8f3aaaee..c89dda55 100644 --- a/src/app/onboarding/legal-credentials/page.tsx +++ b/src/app/onboarding/legal-credentials/page.tsx @@ -17,6 +17,7 @@ import { import Icon from '@/components/Icon'; import InputDropdown from '@/components/InputDropdown'; import RadioGroup from '@/components/RadioGroup'; +import TextAreaInput from '@/components/TextAreaInput'; import TextInput from '@/components/TextInput'; import { usStates } from '@/data/citiesAndStates'; import { attorneyCredentialSchema } from '@/data/formSchemas'; @@ -45,6 +46,12 @@ export default function Page() { stateBarred: onboarding.profile.state_barred ?? undefined, barNumber: onboarding.profile.bar_number ?? undefined, eoirRegistered: onboarding.profile.eoir_registered ?? undefined, + legalCredentialComment: + onboarding.profile.legal_credential_comment ?? undefined, + barred: + onboarding.profile.bar_number === undefined + ? undefined + : onboarding.profile.bar_number === 'Not Barred', }, }); @@ -52,7 +59,8 @@ export default function Page() { const isEmpty = useMemo( () => !(formValues.stateBarred && formValues.barNumber) || - formValues.eoirRegistered === undefined, + formValues.eoirRegistered === undefined || + (!formValues.barred && !formValues.legalCredentialComment), [formValues], ); @@ -108,8 +116,8 @@ export default function Page() { /> - If you are barred in multiple states, choose your preferred - state + If you are barred in multiple states, please choose your + preferred state @@ -118,23 +126,29 @@ export default function Page() { ( - - What is your attorney bar number in this state? - + Do you have a bar number in this state? - { + const bool = newValue === 'Yes'; + const barNum = bool ? '' : 'Not Barred'; onboarding.updateProfile({ - bar_number: newValue, + bar_number: barNum, }); - field.onChange(newValue); + form.setValue('barNumber', barNum); + field.onChange(bool); }} /> @@ -142,6 +156,34 @@ export default function Page() { )} /> + {formValues.barred && ( + ( + + + What is your attorney bar number in this state? + + + { + onboarding.updateProfile({ + bar_number: newValue, + }); + field.onChange(newValue); + }} + /> + + + )} + /> + )} + + ( + + + Is there anything about your bar status we should know? + {formValues.barred && ' (optional)'} + + + { + onboarding.updateProfile({ + legal_credential_comment: newValue, + }); + field.onChange(newValue); + }} + /> + + + For example, if you were formerly barred but is not currently. + + + )} + /> + ebbTo(backlinkHref)}> Back diff --git a/src/data/formSchemas.ts b/src/data/formSchemas.ts index bccdc270..fc0f99e6 100644 --- a/src/data/formSchemas.ts +++ b/src/data/formSchemas.ts @@ -73,29 +73,48 @@ export const availabilitySchema = z.object({ required_error: 'Please include your estimated availability in hours per month', }) - .nonnegative({ message: 'This value must be nonnegative' }) - .max(744, { message: 'Please enter a valid hours per month' }), + .nonnegative({ message: 'This value must be nonnegative' }), startDate: z .date({ required_error: 'Please include your estimated starting date of availability', }) .min(getCurrentDate(), { message: 'Must select a current or future date' }), - availability: z.string().optional().nullable(), + availability: z + .string() + .max(400, 'Please keep it within 400 characters') + .optional() + .nullable(), }); -export const attorneyCredentialSchema = z.object({ - stateBarred: z - .string({ - required_error: 'Please include a state', - invalid_type_error: 'Please include a state', - }) - .min(1, { message: 'Please include a state' }), - barNumber: z - .string({ required_error: 'Please include your attorney bar number' }) - .min(1, { message: 'Please include your attorney bar number' }), - eoirRegistered: z.boolean({ required_error: 'Must select one option' }), -}); +export const attorneyCredentialSchema = z + .object({ + stateBarred: z + .string({ + required_error: 'Please include a state', + invalid_type_error: 'Please include a state', + }) + .min(1, { message: 'Please include a state' }), + barred: z.boolean(), + barNumber: z + .string({ required_error: 'Please include your attorney bar number' }) + .min(1, { message: 'Please include your attorney bar number' }), + eoirRegistered: z.boolean({ required_error: 'Must select one option' }), + legalCredentialComment: z + .string() + .max(400, 'Please keep it within 400 characters') + .optional() + .nullable(), + }) + .superRefine((input, ctx) => { + if (!input.barred && !input.legalCredentialComment) + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Please provide some additional information', + path: ['legalCredentialComment'], + }); + return ctx; + }); export const legalFellowCredentialSchema = z.object({ expectedBarDate: z diff --git a/src/data/languages.ts b/src/data/languages.ts index 8a09ddd2..f3f047ed 100644 --- a/src/data/languages.ts +++ b/src/data/languages.ts @@ -11,7 +11,7 @@ export const languages = iso6393 .sort((l1, l2) => l1.localeCompare(l2)); export const optionalLanguages: DropdownOption[] = [ - { label: 'N/A', value: 'N/A' }, + { label: 'Not Applicable', value: 'Not Applicable' }, ...languages.map(l => ({ label: l, value: l })), ]; diff --git a/src/types/schema.d.ts b/src/types/schema.d.ts index a1566c65..40ba276b 100644 --- a/src/types/schema.d.ts +++ b/src/types/schema.d.ts @@ -15,6 +15,7 @@ export interface Profile { city: string; phone_number: string; state_barred?: string; + legal_credential_comment?: string; } export interface ProfileToUpload diff --git a/src/utils/OnboardingProvider.tsx b/src/utils/OnboardingProvider.tsx index 980ec60d..b1e63fc7 100644 --- a/src/utils/OnboardingProvider.tsx +++ b/src/utils/OnboardingProvider.tsx @@ -148,6 +148,7 @@ export default function OnboardingProvider({ eoir_registered: userProfile.eoir_registered, user_id: uid, phone_number: userProfile.phone_number, + legal_credential_comment: userProfile.legal_credential_comment, }; const userLangs = new Set(canReads.concat(canSpeaks)); From 48b65f784890c3120ceef1109a9c3b1a85a018f8 Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Mon, 20 May 2024 22:34:07 -0700 Subject: [PATCH 2/8] add legal credential comment to settings --- src/app/onboarding/legal-credentials/page.tsx | 2 +- .../SettingsSection/RolesSection.tsx | 77 ++++++++++++++++--- src/data/formSchemas.ts | 12 +++ src/types/schema.d.ts | 2 + 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/app/onboarding/legal-credentials/page.tsx b/src/app/onboarding/legal-credentials/page.tsx index c89dda55..f491b1a9 100644 --- a/src/app/onboarding/legal-credentials/page.tsx +++ b/src/app/onboarding/legal-credentials/page.tsx @@ -51,7 +51,7 @@ export default function Page() { barred: onboarding.profile.bar_number === undefined ? undefined - : onboarding.profile.bar_number === 'Not Barred', + : onboarding.profile.bar_number !== 'Not Barred', }, }); diff --git a/src/components/SettingsSection/RolesSection.tsx b/src/components/SettingsSection/RolesSection.tsx index 95b0ab48..67ff4ba0 100644 --- a/src/components/SettingsSection/RolesSection.tsx +++ b/src/components/SettingsSection/RolesSection.tsx @@ -24,6 +24,7 @@ import DateInput from '../DateInput'; import { FormMessage } from '../Form'; import InputDropdown from '../InputDropdown'; import RadioGroup from '../RadioGroup'; +import TextAreaInput from '../TextAreaInput'; import TextInput from '../TextInput'; const getFormDefaults = ( @@ -50,6 +51,11 @@ const getFormDefaults = ( : undefined, stateBarred: profile.state_barred, roles: defaultRole, + barred: + profile.bar_number === undefined + ? undefined + : profile.bar_number !== 'Not Barred', + legalCredentialComment: profile.legal_credential_comment, }; return defaultValue; @@ -104,6 +110,7 @@ export default function RolesSection() { eoir_registered: isAttorney || isLegalFellow ? values.eoirRegistered : null, expected_bar_date: isLegalFellow ? values.expectedBarDate : null, + legal_credential_comment: values.legalCredentialComment || null, }), profile.setRoles(rolesToUpdate), ]); @@ -111,7 +118,7 @@ export default function RolesSection() { setIsEditing(false); }; - const { roles } = form.watch(); + const { roles, barred } = form.watch(); const isAttorney = roles === 'ATTORNEY' || roles === 'ATTORNEY,INTERPRETER'; const isLegalFellow = roles === 'LEGAL_FELLOW' || roles === 'LEGAL_FELLOW,INTERPRETER'; @@ -227,18 +234,46 @@ export default function RolesSection() { formatTruthy(v, 'Yes', 'No', 'N/A')} render={({ field, fieldState }) => ( - { + const bool = newValue === 'Yes'; + const barNum = bool ? '' : 'Not Barred'; + form.setValue('barNumber', barNum); + field.onChange(bool); + }} /> )} /> + + {barred && ( + ( + + )} + /> + )} )} @@ -300,6 +335,30 @@ export default function RolesSection() { )} /> ) : null} + + {isAttorney && ( + v ?? 'N/A'} + render={({ field, fieldState }) => ( + { + field.onChange(newValue); + }} + /> + )} + /> + )} diff --git a/src/data/formSchemas.ts b/src/data/formSchemas.ts index fc0f99e6..e9cde3ca 100644 --- a/src/data/formSchemas.ts +++ b/src/data/formSchemas.ts @@ -154,6 +154,12 @@ export const roleAndLegalSchema = z }) .optional() .nullable(), + barred: z.boolean().optional().nullable(), + legalCredentialComment: z + .string() + .max(400, 'Please keep it under 400 characters') + .optional() + .nullable(), }) .superRefine((input, ctx) => { // attorney or legal fellow must fill out EOIR registered @@ -181,6 +187,12 @@ export const roleAndLegalSchema = z message: 'Please include a state', path: ['stateBarred'], }); + if (!input.barred && !input.legalCredentialComment) + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Please provide some additional information', + path: ['legalCredentialComment'], + }); } // legal fellow fields required diff --git a/src/types/schema.d.ts b/src/types/schema.d.ts index 40ba276b..eedc3e56 100644 --- a/src/types/schema.d.ts +++ b/src/types/schema.d.ts @@ -27,6 +27,7 @@ export interface ProfileToUpload | 'state_barred' | 'eoir_registered' | 'bar_number' + | 'legal_credential_comment' > { start_date: Date; expected_bar_date?: Date | null; @@ -34,6 +35,7 @@ export interface ProfileToUpload state_barred?: string | null; eoir_registered?: boolean | null; bar_number?: string | null; + legal_credential_comment?: string | null; } // only used for ProfileRoles From cfcbee2634782a32310bd04aa79c4df27aee459c Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Mon, 20 May 2024 22:45:38 -0700 Subject: [PATCH 3/8] make discard changes red; fix issue with same value radio input --- src/app/onboarding/legal-credentials/page.tsx | 2 +- src/components/Buttons.tsx | 3 ++- src/components/RadioGroup/index.tsx | 8 ++++---- src/components/SettingsSection/index.tsx | 8 +++++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/app/onboarding/legal-credentials/page.tsx b/src/app/onboarding/legal-credentials/page.tsx index f491b1a9..7e732136 100644 --- a/src/app/onboarding/legal-credentials/page.tsx +++ b/src/app/onboarding/legal-credentials/page.tsx @@ -195,7 +195,7 @@ export default function Page() { ` ${sans.style} appearance: none; - color: ${({ $primaryColor }) => ($primaryColor ? 'white' : COLORS.blueMid)}; + color: ${({ $primaryColor, $secondaryColor }) => + $primaryColor ? 'white' : $secondaryColor || COLORS.blueMid}; background: ${({ $primaryColor }) => $primaryColor || 'white'}; padding: 10px 20px; border-radius: 5px; diff --git a/src/components/RadioGroup/index.tsx b/src/components/RadioGroup/index.tsx index 72fa1ce8..d49079ed 100644 --- a/src/components/RadioGroup/index.tsx +++ b/src/components/RadioGroup/index.tsx @@ -54,13 +54,13 @@ export default function RadioGroup({ )} {options.map(o => ( - + handleChange(o)} /> diff --git a/src/components/SettingsSection/index.tsx b/src/components/SettingsSection/index.tsx index 40f47b94..641c9b9a 100644 --- a/src/components/SettingsSection/index.tsx +++ b/src/components/SettingsSection/index.tsx @@ -1,5 +1,6 @@ import { createContext, useContext, useMemo } from 'react'; import { ControllerProps, FieldPath, FieldValues } from 'react-hook-form'; +import COLORS from '@/styles/colors'; import { Flex } from '@/styles/containers'; import { Spinner } from '@/styles/spinner'; import { H2, P } from '@/styles/text'; @@ -54,7 +55,12 @@ export function SettingSection({ {isEditing ? ( - From 1f45a959c20c4011bfa955522a93f9ac288d6428 Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Thu, 23 May 2024 14:30:25 -0700 Subject: [PATCH 4/8] modify hooks to prevent recursive checking in roles page --- src/utils/hooks.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts index c229ca87..50f50667 100644 --- a/src/utils/hooks.ts +++ b/src/utils/hooks.ts @@ -2,6 +2,7 @@ import { useCallback, useContext, useEffect, useMemo } from 'react'; import { usePathname, useRouter } from 'next/navigation'; +import CONFIG from '@/lib/configs'; import { useAuth } from './AuthProvider'; import { OnboardingContext } from './OnboardingProvider'; import { useProfile } from './ProfileProvider'; @@ -48,6 +49,8 @@ export const useScrollToTop = () => { */ export const useGuardedOnboarding = () => { const onboarding = useContext(OnboardingContext); + const pathname = usePathname(); + if (!onboarding) throw new Error( 'Component should be wrapped inside the onboarding context', @@ -57,8 +60,9 @@ export const useGuardedOnboarding = () => { const { push } = useRouter(); useEffect(() => { - if (flow.length === 0) push('/onboarding/'); - }, [flow, push]); + if (flow.length === 0 && pathname !== CONFIG.onboardingHome) + push('/onboarding/'); + }, [flow, push, pathname]); return { flow, ...rest }; }; From c7832f425f7b0fefc2c843dbe8549ae9d8e1eaeb Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Thu, 23 May 2024 15:07:38 -0700 Subject: [PATCH 5/8] make comment error instant --- src/app/onboarding/legal-credentials/page.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/onboarding/legal-credentials/page.tsx b/src/app/onboarding/legal-credentials/page.tsx index 7e732136..260ccd70 100644 --- a/src/app/onboarding/legal-credentials/page.tsx +++ b/src/app/onboarding/legal-credentials/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { useRouter } from 'next/navigation'; import { FormProvider, useForm } from 'react-hook-form'; @@ -35,6 +35,7 @@ export default function Page() { const onboarding = useGuardedOnboarding(); const { backlinkHref, ebbTo, pageProgress } = useOnboardingNavigation(); const { push } = useRouter(); + const [commentError, setCommentError] = useState(''); // scroll to top useScrollToTop(); @@ -228,8 +229,13 @@ export default function Page() { { + setCommentError( + newValue.length > 400 + ? 'Please keep it within 400 characters' + : '', + ); onboarding.updateProfile({ legal_credential_comment: newValue, }); From 56e98fa599dc450d0d409ac09b21e6dc435a9126 Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Thu, 23 May 2024 15:19:35 -0700 Subject: [PATCH 6/8] make availability error instant --- src/app/onboarding/availability/page.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/onboarding/availability/page.tsx b/src/app/onboarding/availability/page.tsx index 7865a40d..0dbf9fc1 100644 --- a/src/app/onboarding/availability/page.tsx +++ b/src/app/onboarding/availability/page.tsx @@ -31,6 +31,7 @@ export default function Page() { const onboarding = useGuardedOnboarding(); const { backlinkHref, ebbTo, pageProgress } = useOnboardingNavigation(); const { push } = useRouter(); + const [availabilityError, setAvailabilityError] = useState(''); // scroll to top useScrollToTop(); @@ -184,8 +185,13 @@ export default function Page() { { + setAvailabilityError( + newValue.length > 400 + ? 'Please keep it within 400 characters' + : '', + ); onboarding.updateProfile({ availability_description: newValue, }); From 64aea8381e7a62ede539a1485323b67dd1a806a9 Mon Sep 17 00:00:00 2001 From: jinkang-0 Date: Fri, 24 May 2024 00:06:48 -0700 Subject: [PATCH 7/8] address feedback --- src/app/onboarding/availability/page.tsx | 18 +++++++++---- src/app/onboarding/legal-credentials/page.tsx | 17 ++++++------- src/app/onboarding/review/page.tsx | 18 +++++++++++-- src/app/onboarding/styles.ts | 1 + src/components/Buttons.tsx | 6 ++--- .../SettingsSection/AvailabilitySection.tsx | 13 +++++++--- .../SettingsSection/RolesSection.tsx | 25 +++++++++++++------ src/components/SettingsSection/index.tsx | 4 +-- src/data/formSchemas.ts | 12 ++++----- src/styles/containers.ts | 1 + src/types/schema.d.ts | 3 +++ src/utils/OnboardingProvider.tsx | 7 +++++- 12 files changed, 84 insertions(+), 41 deletions(-) diff --git a/src/app/onboarding/availability/page.tsx b/src/app/onboarding/availability/page.tsx index 0dbf9fc1..265dfd03 100644 --- a/src/app/onboarding/availability/page.tsx +++ b/src/app/onboarding/availability/page.tsx @@ -11,7 +11,7 @@ import { FormControl, FormField, FormItem, FormLabel } from '@/components/Form'; import Icon from '@/components/Icon'; import TextAreaInput from '@/components/TextAreaInput'; import TextInput from '@/components/TextInput'; -import { availabilitySchema } from '@/data/formSchemas'; +import { availabilitySchema, CHAR_LIMIT_MSG } from '@/data/formSchemas'; import { CardForm, Flex } from '@/styles/containers'; import { H1Centered } from '@/styles/text'; import { @@ -32,6 +32,7 @@ export default function Page() { const { backlinkHref, ebbTo, pageProgress } = useOnboardingNavigation(); const { push } = useRouter(); const [availabilityError, setAvailabilityError] = useState(''); + const [hoursError, setHoursError] = useState(''); // scroll to top useScrollToTop(); @@ -107,7 +108,7 @@ export default function Page() { { setAvailabilityError( - newValue.length > 400 - ? 'Please keep it within 400 characters' - : '', + newValue.length > 400 ? CHAR_LIMIT_MSG : '', ); onboarding.updateProfile({ availability_description: newValue, diff --git a/src/app/onboarding/legal-credentials/page.tsx b/src/app/onboarding/legal-credentials/page.tsx index 260ccd70..cdc01949 100644 --- a/src/app/onboarding/legal-credentials/page.tsx +++ b/src/app/onboarding/legal-credentials/page.tsx @@ -20,7 +20,7 @@ import RadioGroup from '@/components/RadioGroup'; import TextAreaInput from '@/components/TextAreaInput'; import TextInput from '@/components/TextInput'; import { usStates } from '@/data/citiesAndStates'; -import { attorneyCredentialSchema } from '@/data/formSchemas'; +import { attorneyCredentialSchema, CHAR_LIMIT_MSG } from '@/data/formSchemas'; import { CardForm, Flex } from '@/styles/containers'; import { H1Centered } from '@/styles/text'; import { formatTruthy, identity } from '@/utils/helpers'; @@ -49,10 +49,7 @@ export default function Page() { eoirRegistered: onboarding.profile.eoir_registered ?? undefined, legalCredentialComment: onboarding.profile.legal_credential_comment ?? undefined, - barred: - onboarding.profile.bar_number === undefined - ? undefined - : onboarding.profile.bar_number !== 'Not Barred', + barred: onboarding.profile.has_bar_number ?? undefined, }, }); @@ -144,8 +141,9 @@ export default function Page() { error={fieldState.error?.message} onChange={newValue => { const bool = newValue === 'Yes'; - const barNum = bool ? '' : 'Not Barred'; + const barNum = bool ? '' : 'N/A'; onboarding.updateProfile({ + has_bar_number: bool, bar_number: barNum, }); form.setValue('barNumber', barNum); @@ -232,9 +230,7 @@ export default function Page() { error={fieldState.error?.message ?? commentError} onChange={newValue => { setCommentError( - newValue.length > 400 - ? 'Please keep it within 400 characters' - : '', + newValue.length > 400 ? CHAR_LIMIT_MSG : '', ); onboarding.updateProfile({ legal_credential_comment: newValue, @@ -244,7 +240,8 @@ export default function Page() { /> - For example, if you were formerly barred but is not currently. + For example, if you were formerly barred but are not + currently; or, if your state does not have a bar number. )} diff --git a/src/app/onboarding/review/page.tsx b/src/app/onboarding/review/page.tsx index 427c194a..8b01f1a8 100644 --- a/src/app/onboarding/review/page.tsx +++ b/src/app/onboarding/review/page.tsx @@ -153,10 +153,18 @@ export default function Page() { -

What is your attorney bar number?

-

{onboarding.profile.bar_number || 'N/A'}

+

Do you have a bar number in this state?

+

{onboarding.profile.has_bar_number ? 'Yes' : 'No'}

+ {onboarding.profile.has_bar_number && ( + + +

What is your attorney bar number?

+

{onboarding.profile.bar_number || 'N/A'}

+
+
+ )}

@@ -173,6 +181,12 @@ export default function Page() {

+ + +

Is there anything about your bar status we should know?

+

{onboarding.profile.legal_credential_comment ?? 'N/A'}

+
+
)} diff --git a/src/app/onboarding/styles.ts b/src/app/onboarding/styles.ts index de8e4dde..e6c6fcd0 100644 --- a/src/app/onboarding/styles.ts +++ b/src/app/onboarding/styles.ts @@ -52,6 +52,7 @@ export const SectionField = styled.div<{ $optional?: boolean }>` flex-direction: column; gap: 16px; width: 100%; + overflow-wrap: break-word; & > h4 { ${({ $optional }) => diff --git a/src/components/Buttons.tsx b/src/components/Buttons.tsx index 6ec8b11d..2f880c3b 100644 --- a/src/components/Buttons.tsx +++ b/src/components/Buttons.tsx @@ -86,9 +86,9 @@ const ButtonStyles = css` } &:active { - color: ${COLORS.greyMid}; - border-color: ${COLORS.greyLight}; - background: ${COLORS.greyLight}; + color: ${COLORS.greyMid} !important; + border-color: ${COLORS.greyLight} !important; + background: ${COLORS.greyLight} !important; } ` : null}; diff --git a/src/components/SettingsSection/AvailabilitySection.tsx b/src/components/SettingsSection/AvailabilitySection.tsx index aa018bc8..bf07ba1e 100644 --- a/src/components/SettingsSection/AvailabilitySection.tsx +++ b/src/components/SettingsSection/AvailabilitySection.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { FormProvider, useForm } from 'react-hook-form'; import { z } from 'zod'; -import { availabilitySchema } from '@/data/formSchemas'; +import { availabilitySchema, CHAR_LIMIT_MSG } from '@/data/formSchemas'; import { Box } from '@/styles/containers'; import { Profile } from '@/types/schema'; import { @@ -37,6 +37,7 @@ export default function AvailabilitySection() { const [startDate, setStartDate] = useState( getDateDefault(profile.profileData ?? {}), ); + const [availabilityError, setAvailabilityError] = useState(''); const form = useForm>({ resolver: zodResolver(availabilitySchema), @@ -65,6 +66,7 @@ export default function AvailabilitySection() { setIsEditing(false); form.reset(getFormDefaults(profile.profileData ?? {})); setStartDate(getDateDefault(profile.profileData ?? {})); + setAvailabilityError(''); }} isSubmitting={form.formState.isSubmitting} > @@ -123,8 +125,13 @@ export default function AvailabilitySection() { { + setAvailabilityError( + newValue.length > 400 ? CHAR_LIMIT_MSG : '', + ); + field.onChange(newValue); + }} /> )} /> diff --git a/src/components/SettingsSection/RolesSection.tsx b/src/components/SettingsSection/RolesSection.tsx index 67ff4ba0..39a9f916 100644 --- a/src/components/SettingsSection/RolesSection.tsx +++ b/src/components/SettingsSection/RolesSection.tsx @@ -3,7 +3,11 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { FormProvider, useForm } from 'react-hook-form'; import { z } from 'zod'; import { usStates } from '@/data/citiesAndStates'; -import { FormRoleEnum, roleAndLegalSchema } from '@/data/formSchemas'; +import { + CHAR_LIMIT_MSG, + FormRoleEnum, + roleAndLegalSchema, +} from '@/data/formSchemas'; import { roleOptions } from '@/data/roles'; import { Box } from '@/styles/containers'; import { H3 } from '@/styles/text'; @@ -51,10 +55,7 @@ const getFormDefaults = ( : undefined, stateBarred: profile.state_barred, roles: defaultRole, - barred: - profile.bar_number === undefined - ? undefined - : profile.bar_number !== 'Not Barred', + barred: profile.has_bar_number, legalCredentialComment: profile.legal_credential_comment, }; @@ -69,6 +70,7 @@ const getDateDefault = (profile: Partial): string => export default function RolesSection() { const { profile, auth } = useProfileAuth(); const [isEditing, setIsEditing] = useState(false); + const [commentError, setCommentError] = useState(''); const [expectedBarDate, setExpectedBarDate] = useState( getDateDefault(profile.profileData ?? {}), @@ -110,7 +112,10 @@ export default function RolesSection() { eoir_registered: isAttorney || isLegalFellow ? values.eoirRegistered : null, expected_bar_date: isLegalFellow ? values.expectedBarDate : null, - legal_credential_comment: values.legalCredentialComment || null, + legal_credential_comment: isAttorney + ? values.legalCredentialComment + : null, + has_bar_number: isAttorney ? values.barred : null, }), profile.setRoles(rolesToUpdate), ]); @@ -176,6 +181,7 @@ export default function RolesSection() { getFormDefaults(profile.roles, profile.profileData ?? {}), ); setExpectedBarDate(getDateDefault(profile.profileData ?? {})); + setCommentError(''); }} > { const bool = newValue === 'Yes'; - const barNum = bool ? '' : 'Not Barred'; + const barNum = bool ? '' : 'N/A'; form.setValue('barNumber', barNum); field.onChange(bool); }} @@ -351,8 +357,11 @@ export default function RolesSection() { { + setCommentError( + newValue.length > 400 ? CHAR_LIMIT_MSG : '', + ); field.onChange(newValue); }} /> diff --git a/src/components/SettingsSection/index.tsx b/src/components/SettingsSection/index.tsx index 641c9b9a..97aefb9a 100644 --- a/src/components/SettingsSection/index.tsx +++ b/src/components/SettingsSection/index.tsx @@ -57,8 +57,8 @@ export function SettingSection({