diff --git a/src/app/onboarding/availability/page.tsx b/src/app/onboarding/availability/page.tsx
index 7865a40d..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 {
@@ -31,6 +31,8 @@ export default function Page() {
const onboarding = useGuardedOnboarding();
const { backlinkHref, ebbTo, pageProgress } = useOnboardingNavigation();
const { push } = useRouter();
+ const [availabilityError, setAvailabilityError] = useState('');
+ const [hoursError, setHoursError] = useState('');
// scroll to top
useScrollToTop();
@@ -106,7 +108,7 @@ export default function Page() {
{
+ setAvailabilityError(
+ 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 8f3aaaee..cdc01949 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';
@@ -17,9 +17,10 @@ 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';
+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';
@@ -34,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();
@@ -45,6 +47,9 @@ 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.has_bar_number ?? undefined,
},
});
@@ -52,7 +57,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 +114,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 +124,30 @@ 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 ? '' : 'N/A';
onboarding.updateProfile({
- bar_number: newValue,
+ has_bar_number: bool,
+ bar_number: barNum,
});
- field.onChange(newValue);
+ form.setValue('barNumber', barNum);
+ field.onChange(bool);
}}
/>
@@ -142,6 +155,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)'}
+
+
+ {
+ setCommentError(
+ newValue.length > 400 ? CHAR_LIMIT_MSG : '',
+ );
+ onboarding.updateProfile({
+ legal_credential_comment: newValue,
+ });
+ field.onChange(newValue);
+ }}
+ />
+
+
+ For example, if you were formerly barred but are not
+ currently; or, if your state does not have a bar number.
+
+
+ )}
+ />
+
ebbTo(backlinkHref)}>
Back
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 24567392..2f880c3b 100644
--- a/src/components/Buttons.tsx
+++ b/src/components/Buttons.tsx
@@ -45,7 +45,8 @@ interface ButtonProps {
const ButtonStyles = css`
${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;
@@ -85,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/NavBar/index.tsx b/src/components/NavBar/index.tsx
index e23261cc..f3fb0eab 100644
--- a/src/components/NavBar/index.tsx
+++ b/src/components/NavBar/index.tsx
@@ -32,12 +32,12 @@ const navlinks: NavLink[] = [
export default function NavBar() {
const profile = useProfile();
- if (!profile) throw new Error('Profile must be defined.');
+ if (!profile) throw new Error('Profile must be defined');
const currentPath = usePathname();
const auth = useAuth();
- if (!auth) throw new Error('Auth must be defined.');
+ if (!auth) throw new Error('Auth must be defined');
const authButtonView = useMemo(() => {
if (profile.profileReady && auth.userId)
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/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 95b0ab48..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';
@@ -24,6 +28,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 +55,8 @@ const getFormDefaults = (
: undefined,
stateBarred: profile.state_barred,
roles: defaultRole,
+ barred: profile.has_bar_number,
+ legalCredentialComment: profile.legal_credential_comment,
};
return defaultValue;
@@ -63,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 ?? {}),
@@ -104,6 +112,10 @@ export default function RolesSection() {
eoir_registered:
isAttorney || isLegalFellow ? values.eoirRegistered : null,
expected_bar_date: isLegalFellow ? values.expectedBarDate : null,
+ legal_credential_comment: isAttorney
+ ? values.legalCredentialComment
+ : null,
+ has_bar_number: isAttorney ? values.barred : null,
}),
profile.setRoles(rolesToUpdate),
]);
@@ -111,7 +123,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';
@@ -169,6 +181,7 @@ export default function RolesSection() {
getFormDefaults(profile.roles, profile.profileData ?? {}),
);
setExpectedBarDate(getDateDefault(profile.profileData ?? {}));
+ setCommentError('');
}}
>
formatTruthy(v, 'Yes', 'No', 'N/A')}
render={({ field, fieldState }) => (
- {
+ const bool = newValue === 'Yes';
+ const barNum = bool ? '' : 'N/A';
+ form.setValue('barNumber', barNum);
+ field.onChange(bool);
+ }}
/>
)}
/>
+
+ {barred && (
+ (
+
+ )}
+ />
+ )}
>
)}
@@ -300,6 +341,33 @@ export default function RolesSection() {
)}
/>
) : null}
+
+ {isAttorney && (
+ v ?? 'N/A'}
+ render={({ field, fieldState }) => (
+ {
+ 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 40f47b94..97aefb9a 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 ? (
-