Skip to content

Commit c9e3482

Browse files
committed
Legger til ekstra steg i mellomsteg og forenkler typingen noe
1 parent 17c958b commit c9e3482

File tree

5 files changed

+172
-154
lines changed

5 files changed

+172
-154
lines changed

packages/nextjs/src/components/pages/form-intermediate-step-page/FormIntermediateStepLink.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { LinkPanel } from '@navikt/ds-react';
33
import { InfoBox } from 'components/_common/infoBox/InfoBox';
44
import { LenkeBase } from 'components/_common/lenke/lenkeBase/LenkeBase';
5-
import { FormIntermediateStep_StepLinkData } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPageState';
5+
import { FormIntermediateStep_StepLinkData } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPage';
66
import { EditorHelp } from 'components/_editor-only/editor-help/EditorHelp';
77

88
type Props = FormIntermediateStep_StepLinkData &
@@ -14,6 +14,8 @@ export const FormIntermediateStepLink = ({
1414
languageDisclaimer,
1515
href,
1616
isStepNavigation,
17+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
18+
nextStep,
1719
...rest
1820
}: Props) => {
1921
if (!href) {

packages/nextjs/src/components/pages/form-intermediate-step-page/FormIntermediateStepPage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ThemedPageHeader } from 'components/_common/headers/themedPageHeader/Th
55
import { FormIntermediateStepPageProps } from 'types/content-props/form-intermediate-step';
66
import { ParsedHtml } from 'components/_common/parsedHtml/ParsedHtml';
77
import { LenkeBase } from 'components/_common/lenke/lenkeBase/LenkeBase';
8-
import { useFormIntermediateStepPageState } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPageState';
8+
import { useFormIntermediateStepPage } from 'components/pages/form-intermediate-step-page/useFormIntermediateStepPage';
99
import { FormIntermediateStepLink } from 'components/pages/form-intermediate-step-page/FormIntermediateStepLink';
1010

1111
import style from './FormIntermediateStepPage.module.scss';
@@ -14,7 +14,7 @@ export const FormIntermediateStepPage = (props: FormIntermediateStepPageProps) =
1414
const { language, type, displayName, modifiedTime, data } = props;
1515
const { title, illustration } = data;
1616

17-
const { currentStepData, backUrl } = useFormIntermediateStepPageState(props);
17+
const { currentStepData, backUrl } = useFormIntermediateStepPage(props);
1818

1919
const getTranslations = translator('form', language);
2020

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { useEffect, useState } from 'react';
2+
import { useRouter } from 'next/compat/router';
3+
import {
4+
FormIntermediateStepPageProps,
5+
SelectableStep,
6+
StepBase,
7+
} from 'types/content-props/form-intermediate-step';
8+
import { stripXpPathPrefix } from 'utils/urls';
9+
10+
const STEP_PARAM = 'stegvalg';
11+
12+
export type FormIntermediateStep_StepLinkData = SelectableStep & {
13+
href?: string;
14+
isStepNavigation?: boolean;
15+
};
16+
17+
type StepPath = number[];
18+
export const buildStepUrl = (basePath: string, stepPath: StepPath) =>
19+
`${basePath}?${STEP_PARAM}=${stepPath.join(',')}`;
20+
21+
export const resolveStepUrl = ({
22+
step,
23+
nextStepPath,
24+
basePath,
25+
}: {
26+
step: SelectableStep;
27+
nextStepPath: StepPath;
28+
basePath: string;
29+
}): FormIntermediateStep_StepLinkData => {
30+
switch (step.nextStep?._selected) {
31+
case 'external': {
32+
return {
33+
...step,
34+
href: step.nextStep.external?.externalUrl,
35+
};
36+
}
37+
case 'internal': {
38+
return {
39+
...step,
40+
href: stripXpPathPrefix(step.nextStep.internal?.internalContent._path),
41+
};
42+
}
43+
default: {
44+
return {
45+
...step,
46+
href: buildStepUrl(basePath, nextStepPath),
47+
isStepNavigation: true,
48+
};
49+
}
50+
}
51+
};
52+
53+
export const getStepData = (
54+
data: FormIntermediateStepPageProps['data'],
55+
stepPath: StepPath
56+
): StepBase => {
57+
// No steps selected (meaning the user is on first step)
58+
if (stepPath.length === 0) {
59+
return {
60+
editorial: data.editorial,
61+
stepsHeadline: data.stepsHeadline,
62+
steps: data.steps,
63+
};
64+
}
65+
66+
let tmp: any = data;
67+
68+
stepPath.forEach((index) => {
69+
const foundStep = tmp.steps[index];
70+
if (foundStep) {
71+
tmp = foundStep.nextStep?.next;
72+
}
73+
});
74+
75+
const stepDetails = tmp.nextStep;
76+
if (stepDetails?._selected === 'next') {
77+
return stepDetails.next;
78+
}
79+
80+
return {
81+
editorial: tmp.editorial,
82+
stepsHeadline: tmp.stepsHeadline,
83+
steps: tmp.steps,
84+
};
85+
};
86+
87+
export const buildCurrentStepData = (
88+
allData: FormIntermediateStepPageProps['data'],
89+
basePath: string,
90+
stepPath: StepPath
91+
): StepBase => {
92+
const stepData = getStepData(allData, stepPath);
93+
94+
return {
95+
...stepData,
96+
steps: stepData.steps.map((step, index) =>
97+
resolveStepUrl({ step, nextStepPath: [...stepPath, index], basePath })
98+
),
99+
};
100+
};
101+
102+
export const buildBackUrl = (basePath: string, stepPath: StepPath): string | null => {
103+
if (stepPath.length === 0) {
104+
return null; // No back URL if on the first step
105+
}
106+
107+
if (stepPath.length === 1) {
108+
return basePath; // Back to the first step
109+
}
110+
return buildStepUrl(basePath, stepPath.slice(0, -1));
111+
};
112+
113+
export const getStepPathFromParam = (url: string): StepPath => {
114+
const stepQuery = new URL(url, window.location.origin).searchParams.get(STEP_PARAM);
115+
const stepPath = stepQuery ? stepQuery.split(',').map(Number) : [];
116+
if (stepPath.some(isNaN)) {
117+
return [];
118+
}
119+
return stepPath;
120+
};
121+
122+
export const useFormIntermediateStepPage = (props: FormIntermediateStepPageProps) => {
123+
const [stepPath, setStepPath] = useState<StepPath>([]);
124+
const router = useRouter();
125+
126+
const pagePath = stripXpPathPrefix(props._path);
127+
const currentStepData = buildCurrentStepData(props.data, pagePath, stepPath);
128+
129+
const backUrl = buildBackUrl(pagePath, stepPath);
130+
131+
useEffect(() => {
132+
if (!router) {
133+
return;
134+
}
135+
136+
const handleRouteChange = (url: string) => {
137+
setStepPath(getStepPathFromParam(url));
138+
};
139+
140+
handleRouteChange(router.asPath);
141+
142+
router.events.on('routeChangeComplete', handleRouteChange);
143+
return () => {
144+
router.events.off('routeChangeComplete', handleRouteChange);
145+
};
146+
}, [router]);
147+
148+
return {
149+
currentStepData,
150+
backUrl,
151+
};
152+
};

packages/nextjs/src/components/pages/form-intermediate-step-page/useFormIntermediateStepPageState.tsx

-119
This file was deleted.

packages/nextjs/src/types/content-props/form-intermediate-step.ts

+15-32
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,35 @@ import { OptionSetSingle } from 'types/util-types';
44
import { ContentCommonProps, ContentType } from './_content-common';
55
import { PictogramsProps } from './pictograms';
66

7-
export type FormIntermediateStep_StepData<
8-
NextStep extends FormIntermediateStep_StepBase = FormIntermediateStep_StepBase,
9-
> = {
10-
editorial: ProcessedHtmlProps;
11-
stepsHeadline: string;
12-
steps: NextStep[];
7+
type ExternalOption = any;
8+
type InternalOption = any;
9+
type NextOption = any;
10+
11+
export type StepOptions = {
12+
external?: ExternalOption;
13+
internal?: InternalOption;
14+
next?: NextOption;
1315
};
1416

15-
export type FormIntermediateStep_StepBase = {
17+
export type SelectableStep = {
1618
label: string;
1719
explanation: string;
1820
languageDisclaimer?: string;
21+
nextStep: OptionSetSingle<StepOptions>;
1922
};
2023

21-
type StepBaseOptions = {
22-
external: {
23-
externalUrl: string;
24-
};
25-
internal: {
26-
internalContent: ContentCommonProps;
27-
};
28-
};
29-
30-
type StepLevel1 = FormIntermediateStep_StepBase & {
31-
nextStep: OptionSetSingle<
32-
StepBaseOptions & {
33-
next: FormIntermediateStep_StepData<StepLevel2>;
34-
}
35-
>;
36-
};
37-
38-
type StepLevel2 = FormIntermediateStep_StepBase & {
39-
nextStep: OptionSetSingle<StepBaseOptions>;
24+
export type StepBase = {
25+
editorial: ProcessedHtmlProps;
26+
stepsHeadline: string;
27+
steps: SelectableStep[];
4028
};
4129

42-
export type FormIntermediateStep_StepLevel = StepLevel1 | StepLevel2;
43-
44-
export type FormIntermediateStep_CompoundedStepData =
45-
FormIntermediateStep_StepData<FormIntermediateStep_StepLevel>;
46-
4730
export type FormIntermediateStepPageProps = ContentCommonProps & {
4831
type: ContentType.FormIntermediateStepPage;
4932
data: {
5033
title: string;
5134
illustration: PictogramsProps;
5235
taxonomy?: Taxonomy[];
5336
customCategory: string;
54-
} & FormIntermediateStep_StepData<StepLevel1>;
37+
} & StepBase;
5538
};

0 commit comments

Comments
 (0)