Skip to content

Commit 542e810

Browse files
committed
feat: add login help page
1 parent 3db2c68 commit 542e810

File tree

21 files changed

+361
-8
lines changed

21 files changed

+361
-8
lines changed

api/src/cms-integrity-tests/contextualInfoLinks.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const composeErrorMessage = (numberOfExpectedCollections: number): string => {
2020
return `We expected ${numberOfExpectedCollections} number of collections in our CMS. You have likely added a new collection to the CMS and now must add to the Contextual Info Search tool to make sure any contextual info links that may ever be used in that new collection can be caught. Look at contextualInfoLinks.ts and the files in shared/lib/search for more details`;
2121
};
2222

23-
const expectedNumberofCollections = 11;
23+
const expectedNumberofCollections = 12;
2424

2525
describe("ContextualInfoLinks", () => {
2626
describe("findMatchingContextualInfo", () => {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"loginSupportPage": {
3+
"pageTitle": "Having trouble logging in to Business.NJ.gov?",
4+
"lastUpdated": "Nov 5, 2025",
5+
"multipleAccountsCallout": ":::miniCallout{ calloutType=\"informational\" }\n**If you have multiple myNewJersey accounts, use the email linked to your business.**\n:::",
6+
"myNewJerseyIntroContent": "You need a myNewJersey account to log in to [account.Business.NJ.gov](/). myNewJersey is a platform used by different government agencies in New Jersey.\n\nTo link your myNewJersey account to account.business.nj.gov:\n\n",
7+
"steps": [
8+
{
9+
"content": "Make sure you're logged out of all other MyNJ accounts across your browser."
10+
},
11+
{
12+
"content": "Open an incognito browser."
13+
},
14+
{
15+
"content": "Go to [https://account.business.nj.gov/](/) and click on the \"Get Started\" button.",
16+
"imagePath": "/img/login-support-home-login.png",
17+
"imageAlt": "Screenshot showing the Get Started button on the Business.NJ.gov homepage"
18+
},
19+
{
20+
"content": "Answer the \"Tell us about your business\" question and click \"Next.\""
21+
},
22+
{
23+
"content": "Once you're on the dashboard, click on the link in the purple card on the right side of your screen.",
24+
"imagePath": "/img/login-support-dashboard-login.png",
25+
"imageAlt": "Screenshot showing the purple card with the link to create and link myNewJersey account on the dashboard"
26+
},
27+
{
28+
"content": "Fill out the email information on the next screen, then click \"Create and Link myNewJersey Account.\" Clicking this link will take you to our partner site, https://my.nj.gov.",
29+
"imagePath": "/img/login-support-link-login.png",
30+
"imageAlt": "Screenshot showing the Create and Link myNewJersey Account form with email fields"
31+
},
32+
{
33+
"content": "Follow the prompts to link your existing myNewJersey account. If you have not created an account through myNewJersey yet, create one now.",
34+
"imagePath": "/img/login-support-mynj-login.png",
35+
"imageAlt": "Screenshot of the myNewJersey login page with options to create an account or link an existing one"
36+
}
37+
],
38+
"logoutIfStillHavingTrouble": "If you're still having trouble, ~~logoutButton~~ to reset your session on [account.business.nj.gov](https://account.business.nj.gov), and repeat the steps above.",
39+
"logoutButtonText": "log out",
40+
"supportCallout": {
41+
"header": "Dedicated Business Experts ready to help",
42+
"body": "Still having issues? Chat with a business advocate based in New Jersey.",
43+
"buttonText": "Start a Live Chat"
44+
}
45+
}
46+
}

shared/src/contexts/configContext.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import * as DashboardTabs from "../../../content/src/fieldConfig/dashboard-tabs.
2828
import * as DeferredLocation from "../../../content/src/fieldConfig/deferred-location.json";
2929
import * as Ein from "../../../content/src/fieldConfig/ein.json";
3030
import * as ElevatorRegistration from "../../../content/src/fieldConfig/elevator-registration.json";
31+
import * as EmployerRates from "../../../content/src/fieldConfig/employer-rates.json";
3132
import * as EnvironmentQuestionnaire from "../../../content/src/fieldConfig/env-questionnaire.json";
3233
import * as FilingDefaults from "../../../content/src/fieldConfig/filing-defaults.json";
3334
import * as Footer from "../../../content/src/fieldConfig/footer.json";
@@ -44,6 +45,7 @@ import * as LandingPageExperienceB from "../../../content/src/fieldConfig/landin
4445
import * as LandingPage from "../../../content/src/fieldConfig/landing-page.json";
4546
import * as LegalMessageDefaults from "../../../content/src/fieldConfig/legal-message-defaults.json";
4647
import * as LicenseSearchTask from "../../../content/src/fieldConfig/license-search-task.json";
48+
import * as LoginSupportPage from "../../../content/src/fieldConfig/login-support-page.json";
4749
import * as ManageBusinessVehicles from "../../../content/src/fieldConfig/manage-business-vehicles.json";
4850
import * as NaicsCode from "../../../content/src/fieldConfig/naics-code.json";
4951
import * as NavigationDefaults from "../../../content/src/fieldConfig/navigation-defaults.json";
@@ -78,7 +80,6 @@ import * as XrayRegistration from "../../../content/src/fieldConfig/xray-registr
7880
import * as XrayRenewal from "../../../content/src/fieldConfig/xray-renewal.json";
7981
import * as CalloutAlerts from "../../../content/src/mappings/callout-alerts.json";
8082
import * as PageMetadata from "../../../content/src/page-metadata/page-metadata.json";
81-
import * as EmployerRates from "../../../content/src/fieldConfig/employer-rates.json";
8283

8384
import { merge } from "lodash";
8485
import { createContext } from "react";
@@ -170,6 +171,7 @@ const merged = JSON.parse(
170171
FormationDataDeletionModal,
171172
EmployerRates,
172173
RemoveBusinessModal,
174+
LoginSupportPage,
173175
),
174176
),
175177
);
@@ -254,7 +256,8 @@ export type ConfigType = typeof LegalMessageDefaults &
254256
typeof FilingDefaults &
255257
typeof FormationDataDeletionModal &
256258
typeof EmployerRates &
257-
typeof RemoveBusinessModal;
259+
typeof RemoveBusinessModal &
260+
typeof LoginSupportPage;
258261

259262
export const getMergedConfig = (): ConfigType => {
260263
return merge(
@@ -338,6 +341,7 @@ export const getMergedConfig = (): ConfigType => {
338341
FilingDefaults,
339342
FormationDataDeletionModal,
340343
RemoveBusinessModal,
344+
LoginSupportPage,
341345
);
342346
};
343347

shared/src/lib/search/cmsCollections.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,8 @@ export const cmsCollections = [
109109
"Formation Date Deletion Modal",
110110
],
111111
},
112+
{
113+
label: "ℹ️ SUPPORT",
114+
children: ["Login Support Page"],
115+
},
112116
];
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
collections:
2+
- name: "support-label"
3+
label: "ℹ️ SUPPORT"
4+
folder: "content/src"
5+
fields:
6+
- { name: "" }
7+
8+
- name: "login-support-page"
9+
label: "Login Support Page"
10+
delete: false
11+
create: false
12+
files:
13+
- label: "Login Support Page"
14+
name: "login-support-page"
15+
file: "content/src/fieldConfig/login-support-page.json"
16+
editor:
17+
preview: true
18+
fields:
19+
- label: "Login Support Page"
20+
name: loginSupportPage
21+
collapsed: false
22+
widget: object
23+
fields:
24+
- { label: "Page Title", name: "pageTitle", widget: "string" }
25+
- { label: "Last Updated Date", name: "lastUpdated", widget: "string" }
26+
- {
27+
label: "Multiple Accounts Callout",
28+
name: "multipleAccountsCallout",
29+
widget: markdown,
30+
}
31+
- {
32+
label: "myNewJersey Intro Content",
33+
name: "myNewJerseyIntroContent",
34+
widget: "string",
35+
}
36+
- label: "Steps"
37+
name: "steps"
38+
widget: list
39+
fields:
40+
- { label: "Step Content (Markdown)", name: "content", widget: "markdown" }
41+
- {
42+
label: "Image Path (e.g., /img/login-support-home-login.png)",
43+
name: "imagePath",
44+
widget: "string",
45+
required: false,
46+
}
47+
- { label: "Image Alt Text", name: "imageAlt", widget: "string", required: false }
48+
- {
49+
label: "Logout If Still Having Trouble",
50+
name: "logoutIfStillHavingTrouble",
51+
widget: "string",
52+
hint:
53+
"This field is conditionally rendered. It will only display when a user is
54+
detected to be logged in.",
55+
}
56+
- { label: "Logout Button Text", name: "logoutButtonText", widget: "string" }
57+
- label: "Support Callout"
58+
name: "supportCallout"
59+
widget: object
60+
fields:
61+
- { label: "Header", name: "header", widget: "string" }
62+
- { label: "Body Text", name: "body", widget: "string" }
63+
- { label: "Button Text", name: "buttonText", widget: "string" }
687 KB
Loading
578 KB
Loading
336 KB
Loading
207 KB
Loading

web/src/components/Content.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface ContentProps {
2424
overrides?: { [key: string]: { ({ children }: { children: string[] }): ReactElement } };
2525
onClick?: (url?: string) => void;
2626
customComponents?: Record<string, ReactElement>;
27+
showLaunchIcon?: boolean;
2728
}
2829

2930
export const Content = (props: ContentProps): ReactNode => {
@@ -38,7 +39,7 @@ export const Content = (props: ContentProps): ReactNode => {
3839
return <>{`\`${props.children}\``}</>;
3940
}
4041
: ContextualInfoLink,
41-
a: Link(props.onClick),
42+
a: Link(props.onClick, props.showLaunchIcon ?? true),
4243
h2: (props: any): ReactElement => {
4344
return (
4445
<Heading level={2} style={{ marginTop: "1rem" }}>
@@ -104,7 +105,7 @@ export const Content = (props: ContentProps): ReactNode => {
104105
);
105106
};
106107

107-
const Link = (onClick?: (url?: string) => void): any => {
108+
const Link = (onClick?: (url?: string) => void, showLaunchIcon?: boolean): any => {
108109
return Object.assign(
109110
(props: any): ReactElement => {
110111
const childrenContent =
@@ -122,6 +123,7 @@ const Link = (onClick?: (url?: string) => void): any => {
122123
href={props.href}
123124
id={props.title}
124125
onClick={(): void => onClick && onClick(props.href)}
126+
showLaunchIcon={showLaunchIcon}
125127
>
126128
{linkText}
127129
</ExternalLink>
@@ -146,11 +148,13 @@ export const ExternalLink = ({
146148
href,
147149
onClick,
148150
id,
151+
showLaunchIcon = true,
149152
}: {
150153
children: string;
151154
href: string;
152155
onClick?: (url?: string) => void;
153156
id?: string;
157+
showLaunchIcon?: boolean;
154158
}): ReactElement => {
155159
return (
156160
<a
@@ -166,7 +170,7 @@ export const ExternalLink = ({
166170
}}
167171
>
168172
{children}
169-
<Icon iconName="launch" />
173+
{showLaunchIcon && <Icon iconName="launch" />}
170174
</a>
171175
);
172176
};

0 commit comments

Comments
 (0)