diff --git a/src/components/ActivitySelector.module.css b/src/components/ActivitySelector.module.css index 9be60ca..47b034b 100644 --- a/src/components/ActivitySelector.module.css +++ b/src/components/ActivitySelector.module.css @@ -12,7 +12,7 @@ } .summary { - width: 20rem; + width: 25rem; margin: auto; } diff --git a/src/components/ActivitySelector.tsx b/src/components/ActivitySelector.tsx index 9cff5e0..4a77b01 100644 --- a/src/components/ActivitySelector.tsx +++ b/src/components/ActivitySelector.tsx @@ -1,5 +1,11 @@ import styles from "./ActivitySelector.module.css"; -import { ChangeEvent, Dispatch, SetStateAction, useEffect, useState } from "react"; +import { + ChangeEvent, + Dispatch, + SetStateAction, + useEffect, + useState, +} from "react"; import { Button, Heading, Modal, Panel, TextField } from "@navikt/ds-react"; import { addDays, format } from "date-fns"; import Spacer from "./Spacer"; @@ -10,10 +16,9 @@ export type ActivitySelectorProps = { endDate: Date; savedDates: SavedDates; setSavedDates: Dispatch>; -} +}; export default function ActivitySelector(props: ActivitySelectorProps) { - const [open, setOpen] = useState(false); const [selectedDate, setSelectedDate] = useState(null); const [selectedType, setSelectedType] = useState(null); @@ -29,16 +34,16 @@ export default function ActivitySelector(props: ActivitySelectorProps) { setSelectedHours(savedDates[date.getTime()]?.hours); setSelectedDate(date); setOpen(true); - } + }; const dateTypeSelected = (type: ActivityType | null) => { setSelectedType(type); setSelectedHours(0); - } + }; const updateHours = (event: ChangeEvent) => { setSelectedHours(Number.parseFloat(event.target.value)); - } + }; const saveDate = () => { if (selectedDate == null) { @@ -50,7 +55,6 @@ export default function ActivitySelector(props: ActivitySelectorProps) { return; } - const key = selectedDate.getTime(); // Delete object if its type is empty @@ -64,13 +68,12 @@ export default function ActivitySelector(props: ActivitySelectorProps) { ...savedDates, [key]: { type: selectedType, - hours: hoursNumber - } + hours: hoursNumber, + }, }); } - setOpen(false); - } + }; // Building day grid const days = []; @@ -81,9 +84,12 @@ export default function ActivitySelector(props: ActivitySelectorProps) { let addClass = styles.none; if (currentData?.type == ActivityType.WORK) addClass = styles.work; - else if (currentData?.type == ActivityType.ILLNESS) addClass = styles.illness; - else if (currentData?.type == ActivityType.MEASURES) addClass = styles.measures; - else if (currentData?.type == ActivityType.VACATION) addClass = styles.vacation; + else if (currentData?.type == ActivityType.ILLNESS) + addClass = styles.illness; + else if (currentData?.type == ActivityType.MEASURES) + addClass = styles.measures; + else if (currentData?.type == ActivityType.VACATION) + addClass = styles.vacation; let hours = <>; if (currentData?.type == ActivityType.WORK) { @@ -94,8 +100,9 @@ export default function ActivitySelector(props: ActivitySelectorProps) {
{hours} @@ -103,57 +110,15 @@ export default function ActivitySelector(props: ActivitySelectorProps) { ); } - const hoursInput = - - // Summary - let workHours = 0; - let illnessDays = 0; - let measuresDays = 0; - let vacationDays = 0; - for (const key in savedDates) { - const currentData = savedDates[key]; - - if (currentData.type == ActivityType.WORK) workHours += (currentData.hours || 0); - else if (currentData.type == ActivityType.ILLNESS) illnessDays += 1; - else if (currentData.type == ActivityType.MEASURES) measuresDays += 1; - else if (currentData.type == ActivityType.VACATION) vacationDays += 1; - } - - let summaryWork = <> - if (workHours > 0) { - summaryWork =
-
Arbeid
-
{workHours} {(workHours == 1) ? 'time' : 'timer'}
-
- } - - let summaryIllness = <> - if (illnessDays > 0) { - summaryIllness =
-
Syk
-
{illnessDays} {(illnessDays == 1) ? 'dag' : 'dager'}
-
- } - - let summaryMeasures = <> - if (measuresDays > 0) { - summaryMeasures =
-
Tiltak
-
{measuresDays} {(measuresDays == 1) ? 'dag' : 'dager'}
-
- } - - let summaryVacation = <> - if (vacationDays > 0) { - summaryVacation =
-
Fravær/ferie
-
{vacationDays} {(vacationDays == 1) ? 'dag' : 'dager'}
-
- } + const hoursInput = ( + + ); return (
@@ -165,31 +130,19 @@ export default function ActivitySelector(props: ActivitySelectorProps) {
fre
lør
søn
- { - days - } + {days}
- { - Object.keys(savedDates).length !== 0 && -
-
Sammenlagt for meldeperioden:
- {summaryWork} - {summaryIllness} - {summaryMeasures} - {summaryVacation} -
- } - - setOpen((x) => !x)} + onClose={() => { + setOpen((x) => !x); + }} aria-labelledby="modal-heading" > @@ -200,42 +153,75 @@ export default function ActivitySelector(props: ActivitySelectorProps) {
- { - (selectedType == ActivityType.WORK) ? hoursInput : '' - } + {selectedType == ActivityType.WORK ? hoursInput : ""}
@@ -244,13 +230,17 @@ export default function ActivitySelector(props: ActivitySelectorProps) { -
-
); } diff --git a/src/components/ActivitySummary.tsx b/src/components/ActivitySummary.tsx new file mode 100644 index 0000000..935fd83 --- /dev/null +++ b/src/components/ActivitySummary.tsx @@ -0,0 +1,92 @@ +import styles from "./ActivitySelector.module.css"; +import { ActivityType, SavedDates } from "../models/Data"; + +export type ActivitySummaryProps = { + savedDates: SavedDates; +}; + +export default function ActivitySummary(props: ActivitySummaryProps) { + const { savedDates } = props; + // Summary + let workHours = 0; + let illnessDays = 0; + let measuresDays = 0; + let vacationDays = 0; + const hasActivity = () => { + if (workHours + illnessDays + measuresDays + vacationDays > 0) return true; + return false; + }; + for (const key in savedDates) { + const currentData = savedDates[key]; + + if (currentData.type == ActivityType.WORK) + workHours += currentData.hours || 0; + else if (currentData.type == ActivityType.ILLNESS) illnessDays += 1; + else if (currentData.type == ActivityType.MEASURES) measuresDays += 1; + else if (currentData.type == ActivityType.VACATION) vacationDays += 1; + } + + let summaryWork = <>; + if (workHours > 0) { + summaryWork = ( +
+
Arbeid
+
+ {workHours} {workHours == 1 ? "time" : "timer"} +
+
+ ); + } + + let summaryIllness = <>; + if (illnessDays > 0) { + summaryIllness = ( +
+
Syk
+
+ {illnessDays} {illnessDays == 1 ? "dag" : "dager"} +
+
+ ); + } + + let summaryMeasures = <>; + if (measuresDays > 0) { + summaryMeasures = ( +
+
Tiltak
+
+ {measuresDays} {measuresDays == 1 ? "dag" : "dager"} +
+
+ ); + } + + let summaryVacation = <>; + if (vacationDays > 0) { + summaryVacation = ( +
+
Fravær/ferie
+
+ {vacationDays} {vacationDays == 1 ? "dag" : "dager"} +
+
+ ); + } + const summaryNothing = ( +
+ Ingen aktivitet utenom å være arbeidssøker +
+ ); + + return ( +
+
Sammenlagt for meldeperioden:
+ {hasActivity() && summaryWork} + {hasActivity() && summaryIllness} + {hasActivity() && summaryMeasures} + {hasActivity() && summaryVacation} + {!hasActivity() && summaryNothing} +
+ ); +} diff --git a/src/components/Guidance.tsx b/src/components/Guidance.tsx new file mode 100644 index 0000000..f08bed4 --- /dev/null +++ b/src/components/Guidance.tsx @@ -0,0 +1,297 @@ +import { Accordion, Heading } from "@navikt/ds-react"; + +export default function Guidance() { + return ( + <> + + Hva må man rapportere? + +

NAV trenger å vite en del informasjon, blablabla

+ + + Hva må jeg rapportere som arbeid? + +

+ Spørsmål 1 - Arbeid +

{" "} +

+ Hvis du har vært i arbeid i perioden meldekortet gjelder for, må + du oppgi alle timene du har arbeidet hver dag. Dette gjelder alle + dager i uken, også lørdag og søndag, uansett når på døgnet du + jobber. +

{" "} +

+ En time i arbeid skal føres som en time på meldekortet. Hvis du + ikke jobber nøyaktig hele eller halve timer, runder du av til + nærmeste halve time. Er det like langt til begge alternativer + runder du av nedover, ikke oppover. +

{" "} +

+ Som hovedregel skal du alltid oppgi det antall timer du faktisk + arbeider. Hvis du mottar dagpenger oppgir du både lønnet og + ulønnet arbeid. Inntektsgivende arbeid skal føres i den perioden + arbeidet har blitt utført, selv om inntekten først kommer senere. +

{" "} +

+ Hvis du får lønn for flere timer enn du faktisk har jobbet, skal + du føre alle timene du får lønn for. Dette gjelder også om + arbeidsgiveren din velger å betale kompensasjon for tapt lønn når + du er permittert. +

{" "} +

+ Ubetalt lunsj +

{" "} +

+ Ubetalt lunsjpause regnes ikke som arbeid, og du skal ikke føre + dette på meldekortet. Du skal føre betalt lunsjpause som arbeid på + meldekortet. +

{" "} +

+ Avspasering +

{" "} +

+ Avspasering føres som om du var på jobb. +

{" "} +

+ Hva regnes som arbeid? +

{" "} +

+ Med «arbeid» mener vi aktivitet som kan gi eller som normalt ville + ha vært betalt, som for eksempel: +

+
    +
  • + arbeid i vanlige arbeidsforhold (som lønnstaker) +
  • +
  • + arbeid i eget foretak (det har ikke noe å si om du har + registrert foretaket som ENK, ANS, AS, NUF eller noe annet) +
  • +
  • + gratisarbeid (for andre) når arbeidet vanligvis er betalt +
  • +
  • + timer du får betalt for, også når du ikke jobber alle timene + (for eksempel ved akkordarbeid) +
  • +
  • + provisjonssalg, telefonsalg og liknende +
  • +
  • frilansarbeid
  • +
  • lønnede verv
  • +
  • + hobbypreget arbeid, «homeparties» og liknende +
  • +
  • omsorgsstønad
  • +
+

+ Lønnspliktperiode +

{" "} +

+ Hvis du er 100 prosent permittert skal du ikke føre timer på + meldekortet de dagene du får lønn fra arbeidsgiveren din i + arbeidsgivers lønnspliktperiode. Er du delvis permittert, skal du + føre de timene du faktisk jobber. +

{" "} +

+ Mottar du allerede dagpenger når du blir permittert skal du føre + timer for de dagene du får lønn av arbeidsgiveren din. Dette + kalles arbeidsgivers lønnspliktperiode.{" "} +

{" "} +

+ Fosterforeldre +

{" "} +

+ Du skal ikke føre opp timer som fosterforeldre på meldekortet. +

{" "} +

+ Etablere egen virksomhet +

{" "} +

+ Har du fått vedtak fra NAV om at du kan beholde{" "} + + dagpenger mens du etablerer egen virksomhet + + , skal du ikke føre på de timene du jobber i virksomheten på + meldekortet. Har du ikke fått vedtak fra NAV om at du kan beholde + dagpenger mens du etablerer egen virksomhet, skal du føre på alle + timer du jobber på meldekortet. Dette gjelder selv om du ikke tar + ut lønn eller om virksomheten går med underskudd. +

{" "} +

+ Formue og skattefri inntekt +

{" "} +

+ Du skal ikke føre opp rene inntekter fra formue, det samme gjelder + enkelte skattefrie inntekter på meldekortet. Eksempler er: +

+
    +
  • + utleie av fast eiendom utenfor virksomhet +
  • +
  • + renter, aksjeutbytte og annen avkastning av penger og + verdipapirer utenfor virksomhet +
  • +
  • + skattefri oppussing av egen bolig/fritidsbolig +
  • +
+

+ Ulønnet arbeid +

{" "} +

+ Du skal ikke føre opp enkelte former for ulønnet arbeid på + meldekortet. Eksempler er +

+
    +
  • + ulønnet arbeid, sosiale tjenester og besøkstjenester for + funksjonshemmede og eldre +
  • +
  • + arbeid for humanitære organisasjoner, religiøse organisasjoner, + idrettslag og liknende, for arbeid som normalt utføres av + medlemmer og frivillige uten godtgjørelse +
  • +
+

+ Naturalytelser +

{" "} +

+ Naturalytelser er goder som du mottar fra arbeidsgiveren din, som + for eksempel telefon eller bil. +

{" "} +

+ For permitterte: Hvis du har hatt goder i mindre + enn tre måneder før du ble permittert, regnes summen av disse + godene som timelønn. Antall timer som godene utgjør skal føres som + timer med arbeid på meldekortene. +

+
+
+ + + Hva må jeg rapportere av tiltak, kurs og utdanning? + + +

+ Spørsmål 2 - Aktivitet/kurs/utdanning +

{" "} +

+ Hvis du har avtalt med NAV å delta på tiltak, kurs, utdanning + eller annen aktivitet, skal du svare «ja» og krysse av for de + dagene du har utført avtalt aktivitet. Les mer om{" "} + + dagpenger i kombinasjon med utdanning og opplæring. + +

{" "} +

+ Hvis du deltar på kurs eller utdanning som ikke er avtalt, skal du + svare «ja», og krysse av for de dagene du har deltatt. Dette + gjelder også hvis du «leser» et fag på egenhånd. +

{" "} +

+ Du skal bare melde fra om tiltak, kurs eller utdanning på + meldekortet. Du skal ikke føre opp andre aktiviteter du har avtalt + med NAV, slik som informasjonsmøter i regi av NAV og tid til å + føre aktivitetsplan. +

{" "} +

+ Hvis du ikke har utført en avtalt aktivitet, svarer du «nei». Hvis + du ikke har avtalt aktivitet med NAV, og heller ikke har deltatt + på kurs/utdanning, svarer du «nei». +

+
+
+ + Hva gjelder for sykdom? + +

+ Spørsmål 3 - Sykdomsfravær +

{" "} +

+ Hvis du på grunn av egen sykdom ikke har vært i stand til å jobbe + eller delta på tiltak, kurs, utdanning eller jobbintervju, skal du + svare «ja». Du skal da krysse av for de dagene du ikke har jobbet + eller utført avtalt aktivitet. +

{" "} +

+ Hvis du ikke har hatt fravær på grunn av sykdom, svarer du «nei». +

{" "} +

+ Hvis du deltar på tiltak må du i tillegg melde fra til den som er + ansvarlig for tiltaket. +

{" "} +

+ Du har ikke rett til dagpenger når du er syk, men du kan ha rett + til sykepenger. Du har ikke egenmeldingsdager når du mottar + dagpenger, og må derfor be om sykmelding fra første dag du er syk. +

{" "} +

+ + Jeg er arbeidsledig eller permittert og blir sykmeldt + +

+
+
+ + + Hvis jeg tar ferie eller har annet fravær? + + +

+ Spørsmål 4 - Ferie og annet fravær +

{" "} +

+ Du kan som hovedregel oppholde deg hvor du vil i Norge når du + mottar dagpenger, uten å føre fravær på meldekortet. Er du ikke + tilgjengelig for jobb eller tiltak på grunn av ferie eller annet + fravær, må du føre disse dagene som fravær på meldekortet. Gjelder + fraværet sykdom skal du svare på dette i spørsmål 3. +

{" "} +

+ Deltar du på tiltak må du melde fra til tiltaksarrangør. +

{" "} +

+ Hvis du har fravær vil du få trekk i utbetalingen din. Har du + opparbeidet deg rett til{" "} + + dagpenger under ferie + + , vil du ikke få trekk i utbetalingen din. +

{" "} +

+ Skal du reise bort over lengre tid, må du kontakte NAV. NAV vil da + vurdere om du fortsatt har rett til dagpenger i fraværsperioden. +

+
+
+
+ + ); +} diff --git a/src/components/Step1.tsx b/src/components/Step1.tsx deleted file mode 100644 index f7488c5..0000000 --- a/src/components/Step1.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { Heading, Radio, RadioGroup } from "@navikt/ds-react"; -import Spacer from "./Spacer"; -import NavPanelWithButtons from "./NavPanelWithButtons"; -import { CommonFormProps } from "../pages/form"; -import { FormEvent, useState } from "react"; - -export default function Step1(props: CommonFormProps) { - - const { - questionWork, - setQuestionWork, - questionMeasures, - setQuestionMeasures, - questionIllness, - setQuestionIllness, - questionVacation, - setQuestionVacation, - nextStep, - showLoader - } = props; - - const [isChecked, setIsChecked] = useState(false); - - // Validators - const questionWorkValidated = () => { - return questionWork != null; - } - const questionMeasuresValidated = () => { - return questionMeasures != null; - } - const questionIllnessValidated = () => { - return questionIllness != null; - } - const questionVacationValidated = () => { - return questionVacation != null; - } - - // Check form - const checkForm = (event: FormEvent) => { - setIsChecked(true); - - if (questionWorkValidated() && - questionMeasuresValidated() && - questionIllnessValidated() && - questionVacationValidated()) { - nextStep(event); - } - } - - // Render - return ( - <> - Aktivitet siste 14 dager - - - - setQuestionWork(val)} - value={questionWork} - error={isChecked && !questionWorkValidated() && "Du må svare på dette spørsmålet"} - > - Ja - Nei - - - - - setQuestionMeasures(val)} - value={questionMeasures} - error={isChecked && !questionMeasuresValidated() && "Du må svare på dette spørsmålet"} - > - Ja - Nei - - - - - setQuestionIllness(val)} - value={questionIllness} - error={isChecked && !questionIllnessValidated() && "Du må svare på dette spørsmålet"} - > - Ja - Nei - - - - - setQuestionVacation(val)} - value={questionVacation} - error={isChecked && !questionVacationValidated() && "Du må svare på dette spørsmålet"} - > - Ja - Nei - - - - - - - ); -} diff --git a/src/components/Step2.tsx b/src/components/Step2.tsx deleted file mode 100644 index 8a1ab84..0000000 --- a/src/components/Step2.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import styles from "./ActivitySelector.module.css"; -import { Heading } from "@navikt/ds-react"; -import Spacer from "./Spacer"; -import ActivitySelector from "./ActivitySelector"; -import Error from "./Error"; -import NavPanelWithButtons from "./NavPanelWithButtons"; -import { CommonFormProps } from "../pages/form"; -import { FormEvent, useState } from "react"; - -export default function Step2(props: CommonFormProps) { - - const { startDate, endDate, savedDates, setSavedDates, prevStep, nextStep, showLoader } = props; - - const [isChecked, setIsChecked] = useState(false); - - // Validators - const savedDatesValidated = () => { - return Object.keys(savedDates).length > 0; - } - - // Check form - const checkForm = (event: FormEvent) => { - setIsChecked(true); - - if (savedDatesValidated()) { - nextStep(event); - } - } - - // Render - return ( - <> - Utfylling - - - - - -
- -
- - - - - - ); -} diff --git a/src/components/Step4.tsx b/src/components/Step4.tsx deleted file mode 100644 index c87b7a1..0000000 --- a/src/components/Step4.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { BodyShort, ConfirmationPanel, Heading, Panel } from "@navikt/ds-react"; -import Spacer from "./Spacer"; -import Error from "./Error"; -import NavPanelWithButtons from "./NavPanelWithButtons"; -import { CommonFormProps } from "../pages/form"; -import { FormEvent, useState } from "react"; -import { format } from "date-fns"; -import { ActivityType } from "../models/Data"; - -export default function Step4(props: CommonFormProps) { - - const { - questionWork, - questionMeasures, - questionIllness, - questionVacation, - savedDates, - questionProceed, - questionConsent, - setQuestionConsent, - prevStep, - send, - showLoader, - error - } = props; - - const [isChecked, setIsChecked] = useState(false); - - // Validators - const questionConsentValidated = () => { - return questionConsent; - } - - // Check form - const checkForm = (event: FormEvent) => { - setIsChecked(true); - - if (questionConsentValidated()) { - send(event); - } - } - - const days = []; - for (const key in savedDates) { - const date = format(new Date(+key), "dd.MM.yy"); - const type = savedDates[key].type; - const hours = type == ActivityType.WORK ? '(' + savedDates[key].hours + ' t)' : ''; - const str = date + ' ' + type + ' ' + hours; - - days.push( -
- {str} -
- ); - } - - // Render - return ( - <> - Arbeidssøker - - - - - - Har du vært i arbeid de siste 14 dager? - - - {questionWork ? 'Ja' : 'Nei'} - - - - - Har du deltatt på tiltak, kurs eller utdanning? - - - {questionMeasures ? 'Ja' : 'Nei'} - - - - - Har du vært syk? - - - {questionIllness ? 'Ja' : 'Nei'} - - - - - Har du hatt ferie eller annet fravær? - - - {questionVacation ? 'Ja' : 'Nei'} - - - - - Registrerte dager - - {days} - - - - Ønsker du fortsatt å være registrert hos NAV som arbeidssøker de neste 14 dager? - - - {questionProceed ? 'Ja' : 'Nei'} - - - - - - setQuestionConsent((x) => !x)} - error={isChecked && !questionConsentValidated() && "Du må samtykke før du kan fortsette."} - > - For å komme videre må du gi oss lov til å hente inn og bruke opplysninger - om deg. - - - - - - - - - ); -} diff --git a/src/components/StepActivity.tsx b/src/components/StepActivity.tsx new file mode 100644 index 0000000..7cd1e52 --- /dev/null +++ b/src/components/StepActivity.tsx @@ -0,0 +1,62 @@ +import { Heading, Radio, RadioGroup } from "@navikt/ds-react"; +import Spacer from "./Spacer"; +import NavPanelWithButtons from "./NavPanelWithButtons"; +import { CommonFormProps } from "../pages/form"; +import { FormEvent, useState } from "react"; + +export default function StepActivity(props: CommonFormProps) { + const { questionWork, setQuestionWork, prevStep, nextStep, showLoader } = + props; + + const [isChecked, setIsChecked] = useState(false); + + // Validators + const questionWorkValidated = () => { + return questionWork != null; + }; + + // Check form + const checkForm = (event: FormEvent) => { + setIsChecked(true); + + if (questionWorkValidated()) { + nextStep(event); + } + }; + + // Render + return ( + <> + + Aktivitet siste 14 dager + + + + + setQuestionWork(val)} + value={questionWork} + error={ + isChecked && + !questionWorkValidated() && + "Du må svare på dette spørsmålet" + } + > + Ja + Nei + + + + + + + ); +} diff --git a/src/components/StepFillDays.tsx b/src/components/StepFillDays.tsx new file mode 100644 index 0000000..58f97dc --- /dev/null +++ b/src/components/StepFillDays.tsx @@ -0,0 +1,72 @@ +import styles from "./ActivitySelector.module.css"; +import { Heading, Panel } from "@navikt/ds-react"; +import Spacer from "./Spacer"; +import ActivitySelector from "./ActivitySelector"; +import Error from "./Error"; +import NavPanelWithButtons from "./NavPanelWithButtons"; +import { CommonFormProps } from "../pages/form"; +import { FormEvent, useState } from "react"; +import ActivitySummary from "./ActivitySummary"; + +export default function StepFillDays(props: CommonFormProps) { + const { + startDate, + endDate, + savedDates, + setSavedDates, + prevStep, + nextStep, + showLoader, + } = props; + + const [isChecked, setIsChecked] = useState(false); + + // Validators + const savedDatesValidated = () => { + return Object.keys(savedDates).length > 0; + }; + + // Check form + const checkForm = (event: FormEvent) => { + setIsChecked(true); + nextStep(event); + }; + + // Render + return ( + <> + + Fyll ut aktivitet + + + + + + + + + +
+ +
+ + + + + + ); +} diff --git a/src/components/StepIntroduction.tsx b/src/components/StepIntroduction.tsx new file mode 100644 index 0000000..6f35227 --- /dev/null +++ b/src/components/StepIntroduction.tsx @@ -0,0 +1,48 @@ +import { ConfirmationPanel, Heading } from "@navikt/ds-react"; +import Spacer from "./Spacer"; +import NavPanelWithButtons from "./NavPanelWithButtons"; +import { CommonFormProps } from "../pages/form"; +import { FormEvent, useState } from "react"; + +export default function StepIntroduction(props: CommonFormProps) { + const { nextStep, showLoader, questionIllness, setQuestionIllness } = props; + + // Check form + const checkForm = (event: FormEvent) => { + nextStep(event); + }; + const isChecked = () => { + if (questionIllness !== null) { + return questionIllness; + } + return undefined; + }; + // Render + return ( + <> + + Introduksjon + +

Slik fyller du ut dagpenger!

+ + + + setQuestionIllness((questionIllness) => !questionIllness) + } + > + Her kan du velge å ikke se denne introduksjonen mer + + + + + + + ); +} diff --git a/src/components/StepSummary.module.css b/src/components/StepSummary.module.css new file mode 100644 index 0000000..6926a46 --- /dev/null +++ b/src/components/StepSummary.module.css @@ -0,0 +1,3 @@ +.summary { + display: flex; +} \ No newline at end of file diff --git a/src/components/StepSummary.tsx b/src/components/StepSummary.tsx new file mode 100644 index 0000000..b5a632d --- /dev/null +++ b/src/components/StepSummary.tsx @@ -0,0 +1,108 @@ +import { BodyShort, ConfirmationPanel, Heading, Panel } from "@navikt/ds-react"; +import Spacer from "./Spacer"; +import Error from "./Error"; +import NavPanelWithButtons from "./NavPanelWithButtons"; +import { CommonFormProps } from "../pages/form"; +import { FormEvent, useState } from "react"; +import { format } from "date-fns"; +import { ActivityType } from "../models/Data"; +import ActivitySummary from "./ActivitySummary"; +import styles from "./StepSummary.module.css"; + +export default function StepSummary(props: CommonFormProps) { + const { + questionWork, + savedDates, + questionProceed, + questionConsent, + setQuestionConsent, + prevStep, + send, + showLoader, + error, + } = props; + + const [isChecked, setIsChecked] = useState(false); + + // Validators + const questionConsentValidated = () => { + return questionConsent; + }; + + // Check form + const checkForm = (event: FormEvent) => { + setIsChecked(true); + + if (questionConsentValidated()) { + send(event); + } + }; + + //todo, oversette activityType til work + const days = []; + for (const key in savedDates) { + const date = format(new Date(+key), "dd.MM.yy"); + const type = savedDates[key].type; + const hours = + type == ActivityType.WORK ? "(" + savedDates[key].hours + " t)" : ""; + const str = date + " " + type + " " + hours; + + days.push(
{str}
); + } + + // Render + return ( + <> + + Oppsummering + + + + + + + Har du vært i aktivitet de siste 14 dager? + + {questionWork ? "Ja" : "Nei"} + + + + + + + Ønsker du fortsatt å være registrert hos NAV som arbeidssøker de neste + 14 dager? + + {questionProceed ? "Ja" : "Nei"} + + + + + setQuestionConsent((x) => !x)} + error={ + isChecked && + !questionConsentValidated() && + "Du må samtykke før du kan fortsette." + } + > + For å komme videre må du gi oss lov til å hente inn og bruke + opplysninger om deg. + + + + + + + + + ); +} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index d91cbb3..dd3f844 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,9 +1,15 @@ -import Document, { DocumentContext, Head, Html, Main, NextScript, } from "next/document"; +import Document, { + DocumentContext, + Head, + Html, + Main, + NextScript, +} from "next/document"; import { Components as DecoratorComponents, Env, fetchDecoratorReact, - Props as DecoratorProps + Props as DecoratorProps, } from "@navikt/nav-dekoratoren-moduler/ssr"; export default class MyDocument extends Document { @@ -16,16 +22,16 @@ export default class MyDocument extends Document { availableLanguages: [ { locale: "nb", - handleInApp: true + handleInApp: true, }, { locale: "en", - handleInApp: true - } + handleInApp: true, + }, ], - language: "nb" + language: "nb", }; - + //t const Dekorator: DecoratorComponents = await fetchDecoratorReact({ ...dekoratorProps, }).catch((err) => { diff --git a/src/pages/form.tsx b/src/pages/form.tsx index 073df83..1a9bf38 100644 --- a/src/pages/form.tsx +++ b/src/pages/form.tsx @@ -1,18 +1,24 @@ import { Heading } from "@navikt/ds-react"; import Divider from "../components/Divider"; -import CustomStepper from "../components/CustomStepper"; -import Step1 from "../components/Step1"; -import Step2 from "../components/Step2"; -import Step3 from "../components/Step3"; -import Step4 from "../components/Step4"; +import StepActivity from "../components/StepActivity"; +import StepFillDays from "../components/StepFillDays"; +import StepSummary from "../components/StepSummary"; import Receipt from "../components/Receipt"; import CancelButton from "../components/CancelButton"; import { format, getISOWeek } from "date-fns"; -import { Dispatch, FormEventHandler, SetStateAction, useEffect, useState } from "react"; +import { + Dispatch, + FormEventHandler, + SetStateAction, + useEffect, + useState, +} from "react"; import { ActivityType, Data, Day, SavedDates } from "../models/Data"; import { LoadedData } from "../models/LoadedData"; import { fromStringToDate } from "../utils/date.utils"; import CenteredLoader from "../components/CenteredLoader"; +import StepIntroduction from "../components/StepIntroduction"; +import Guidance from "../components/Guidance"; export type CommonFormProps = { startDate: Date; @@ -36,7 +42,7 @@ export type CommonFormProps = { send: FormEventHandler; showLoader: boolean; error: string; -} +}; export default function Page() { // TODO: Get ID from the earliest meldekort and set it as currentId @@ -50,54 +56,128 @@ export default function Page() { // Service variables const maxStep = 4; - const [currentStep, setCurrentStep] = useState(1); + const [currentStep, setCurrentStep] = useState(0); const [showLoader, setShowLoader] = useState(false); const [showReceipt, setShowReceipt] = useState(false); - const [error, setError] = useState(''); - const [isLoading, setLoading] = useState(false) + const [error, setError] = useState(""); + const [isLoading, setLoading] = useState(false); + const [isFetched, setIsFetched] = useState(false); // Data variables const [questionWork, setQuestionWork] = useState(null); - const [questionMeasures, setQuestionMeasures] = useState(null); + const [questionMeasures, setQuestionMeasures] = useState( + null + ); const [questionIllness, setQuestionIllness] = useState(null); - const [questionVacation, setQuestionVacation] = useState(null); + const [questionVacation, setQuestionVacation] = useState( + null + ); const [savedDates, setSavedDates] = useState([]); const [questionProceed, setQuestionProceed] = useState(null); const [questionConsent, setQuestionConsent] = useState(); useEffect(() => { - setLoading(true) - fetch('/api/periods/' + currentId) + setLoading(true); + fetch("/api/periods/" + currentId) .then((res) => res.json()) .then((loadedData: LoadedData) => { // Convert loaded days to SavedDates - const loadedSavedDates: SavedDates = {} + const loadedSavedDates: SavedDates = {}; loadedData?.days?.forEach((day) => { - // @ts-ignore - loadedSavedDates[fromStringToDate(day.date).getTime()] = { type: ActivityType[day.type], hours: day.hours } + loadedSavedDates[fromStringToDate(day.date).getTime()] = { + // @ts-ignore + type: ActivityType[day.type], + hours: day.hours, + }; }); // If we didn't get data and fields are undefined > use null // We can't leave undefined in these fields, because it makes these components uncontrolled - setQuestionWork(loadedData.questionWork == undefined ? null : loadedData.questionWork); - setQuestionMeasures(loadedData.questionMeasures == undefined ? null : loadedData.questionMeasures); - setQuestionIllness(loadedData.questionIllness == undefined ? null : loadedData.questionIllness); - setQuestionVacation(loadedData.questionVacation == undefined ? null : loadedData.questionVacation); + setQuestionWork( + loadedData.questionWork == undefined ? null : loadedData.questionWork + ); + setQuestionMeasures( + loadedData.questionMeasures == undefined + ? null + : loadedData.questionMeasures + ); + setQuestionIllness( + loadedData.questionIllness == undefined + ? null + : loadedData.questionIllness + ); + setQuestionVacation( + loadedData.questionVacation == undefined + ? null + : loadedData.questionVacation + ); setSavedDates(loadedSavedDates); - setQuestionProceed(loadedData.questionProceed == undefined ? null : loadedData.questionProceed); + setQuestionProceed( + loadedData.questionProceed == undefined + ? null + : loadedData.questionProceed + ); setQuestionConsent(false); // User must check it every time - setLoading(false) - }).catch((error) => { - console.log(error) - }); - }, []) + setLoading(false); + }) + .then(() => { + setIsFetched(true); + }) + .catch((error) => { + console.log(error); + }); + }, []); + useEffect(() => { + if (!isLoading && isFetched) { + setCurrentStep(calculateStep()); + } + }, [isFetched]); const startDateStr = format(startDate, "dd.MM.yy"); const endDateStr = format(endDate, "dd.MM.yy"); + const hasActivity = () => { + if (savedDates) { + for (const key in savedDates) { + const currentData = savedDates[key]; + if ( + currentData.type == ActivityType.WORK || + currentData.type == ActivityType.ILLNESS || + currentData.type == ActivityType.MEASURES || + currentData.type == ActivityType.VACATION + ) { + return true; + } + } + } + return false; + }; - const prevStep = () => { + const calculateStep = () => { + let shouldGoToStep = currentStep + 1; + if (currentStep == 0) { + if (hasActivity()) { + shouldGoToStep = 3; + } else shouldGoToStep = 2; + if (!questionIllness) { + shouldGoToStep = 1; + } + } + if (currentStep == 2 && !questionWork) { + shouldGoToStep = 4; + } + if (currentStep == 3 && !hasActivity()) { + shouldGoToStep = 2; + } + if (isLoading) { + shouldGoToStep = 0; + } + return shouldGoToStep; + }; + + const prevStep = async () => { if (currentStep > 1) { + await save(); setCurrentStep(currentStep - 1); } }; @@ -105,38 +185,38 @@ export default function Page() { const nextStep = async () => { if (currentStep < maxStep) { await save(); - setCurrentStep(currentStep + 1); + setCurrentStep(calculateStep()); } }; const save = async () => { - const response = await postData('/api/periods/save'); + const response = await postData("/api/periods/save"); if (!response.ok) { - setError('Feil i vårt baksystem. Kunne ikke lagre data'); + setError("Feil i vårt baksystem. Kunne ikke lagre data"); } // Hide loader setShowLoader(false); - } + }; const send = async () => { - const response = await postData('/api/periods/send'); + const response = await postData("/api/periods/send"); if (response.ok) { setCurrentStep(currentStep + 1); setShowReceipt(true); } else { - setError('Feil i vårt baksystem. Prøv senere'); + setError("Feil i vårt baksystem. Prøv senere"); } // Hide loader setShowLoader(false); - } + }; const postData = async (endpoint: string) => { // Reset error - setError(''); + setError(""); // Show loader setShowLoader(true); @@ -159,8 +239,8 @@ export default function Page() { questionIllness, questionVacation, days, - questionProceed - } + questionProceed, + }; // Send the data to the server in JSON format. const JSONdata = JSON.stringify(data); @@ -168,10 +248,10 @@ export default function Page() { // Form the request for sending data to the server. const options = { // The method is POST because we are sending data. - method: 'POST', + method: "POST", // Tell the server we're sending JSON. headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, // Body of the request is the JSON data we created above. body: JSONdata, @@ -179,7 +259,7 @@ export default function Page() { // Send the form data to our forms API on Vercel and get a response. return await fetch(endpoint, options); - } + }; const commonFormProps: CommonFormProps = { startDate, @@ -202,8 +282,8 @@ export default function Page() { nextStep, send, showLoader, - error - } + error, + }; if (isLoading) { return ( @@ -215,21 +295,22 @@ export default function Page() { return (
- Dagpenger rapportering - Uke {getISOWeek(startDate)} - {getISOWeek(endDate)} ({startDateStr} - {endDateStr}) - + + Dagpenger rapportering + + + Uke {getISOWeek(startDate)} - {getISOWeek(endDate)} ({startDateStr} -{" "} + {endDateStr}) + - - {!showReceipt && } - - {currentStep == 1 && } - {currentStep == 2 && } - {currentStep == 3 && } - {currentStep == 4 && } + {currentStep == 1 && } + {currentStep == 2 && } + {currentStep == 3 && } + {currentStep == 4 && } + {currentStep == 0 &&

Laster

} {showReceipt && } - {!showReceipt && } + {currentStep != 0 && }
); } diff --git a/src/styles/globals.css b/src/styles/globals.css index b0ca98a..6bbf7e9 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -18,7 +18,7 @@ a { box-sizing: border-box; } -@media (prefers-color-scheme: dark) { +@media (prefers-color-scheme: light) { html { color-scheme: dark; }