From 277359636fc2ea0ee518c0cd3528b6b3ee83f118 Mon Sep 17 00:00:00 2001 From: Joonatan Kuosa Date: Tue, 18 Feb 2025 09:48:26 +0200 Subject: [PATCH] refactor: reorganise page functions --- apps/ui/pages/applications/[id]/page1.tsx | 4 +- apps/ui/pages/applications/[id]/page2.tsx | 16 +-- apps/ui/pages/applications/[id]/page3.tsx | 10 +- apps/ui/pages/applications/[id]/preview.tsx | 8 +- .../ui/pages/applications/[id]/view/index.tsx | 54 ++++---- .../pages/recurring/[id]/criteria/index.tsx | 122 +++++++++--------- apps/ui/pages/recurring/[id]/index.tsx | 122 +++++++++--------- 7 files changed, 164 insertions(+), 172 deletions(-) diff --git a/apps/ui/pages/applications/[id]/page1.tsx b/apps/ui/pages/applications/[id]/page1.tsx index f6debdb380..1346ddf256 100644 --- a/apps/ui/pages/applications/[id]/page1.tsx +++ b/apps/ui/pages/applications/[id]/page1.tsx @@ -128,6 +128,8 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { }; } +export default Page1; + export const APPLICATION_PAGE1_QUERY = gql` query ApplicationPage1($id: ID!) { application(id: $id) { @@ -135,5 +137,3 @@ export const APPLICATION_PAGE1_QUERY = gql` } } `; - -export default Page1; diff --git a/apps/ui/pages/applications/[id]/page2.tsx b/apps/ui/pages/applications/[id]/page2.tsx index c6d0a0e71c..fbe6142aa2 100644 --- a/apps/ui/pages/applications/[id]/page2.tsx +++ b/apps/ui/pages/applications/[id]/page2.tsx @@ -25,21 +25,14 @@ import { getApplicationPath } from "@/modules/urls"; import { useDisplayError } from "@/hooks/useDisplayError"; import { gql } from "@apollo/client"; -type Props = Awaited>["props"]; -type PropsNarrowed = Exclude; - function Page2({ application }: PropsNarrowed): JSX.Element { const router = useRouter(); const [update] = useApplicationUpdate(); const dislayError = useDisplayError(); - const handleSave = async (values: ApplicationPage2FormValues) => { - return update(transformApplicationPage2(values)); - }; - const saveAndNavigate = async (values: ApplicationPage2FormValues) => { try { - const pk = await handleSave(values); + const pk = await update(transformApplicationPage2(values)); router.push(getApplicationPath(pk, "page3")); } catch (err) { dislayError(err); @@ -64,6 +57,9 @@ function Page2({ application }: PropsNarrowed): JSX.Element { ); } +type Props = Awaited>["props"]; +type PropsNarrowed = Exclude; + export async function getServerSideProps(ctx: GetServerSidePropsContext) { const { locale, query } = ctx; const pk = toNumber(ignoreMaybeArray(query.id)); @@ -105,6 +101,8 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { }; } +export default Page2; + export const APPLICATION_PAGE2_QUERY = gql` query ApplicationPage2($id: ID!) { application(id: $id) { @@ -112,5 +110,3 @@ export const APPLICATION_PAGE2_QUERY = gql` } } `; - -export default Page2; diff --git a/apps/ui/pages/applications/[id]/page3.tsx b/apps/ui/pages/applications/[id]/page3.tsx index 9d3e552aa8..8c8fea46ed 100644 --- a/apps/ui/pages/applications/[id]/page3.tsx +++ b/apps/ui/pages/applications/[id]/page3.tsx @@ -2,7 +2,8 @@ import React, { useEffect } from "react"; import { ApplicantTypeChoice, ApplicationPage3Document, - ApplicationPage3Query, + type ApplicationPage3Query, + type ApplicationPage3QueryVariables, } from "@gql/gql-types"; import { useTranslation } from "next-i18next"; import { FormProvider, useForm, useFormContext } from "react-hook-form"; @@ -175,11 +176,14 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { return notFound; } const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); - const { data } = await apolloClient.query({ + const { data } = await apolloClient.query< + ApplicationPage3Query, + ApplicationPage3QueryVariables + >({ query: ApplicationPage3Document, variables: { id: base64encode(`ApplicationNode:${pk}`) }, }); - const { application } = data ?? {}; + const { application } = data; if (application == null) { return notFound; } diff --git a/apps/ui/pages/applications/[id]/preview.tsx b/apps/ui/pages/applications/[id]/preview.tsx index f5544754bf..5e38731513 100644 --- a/apps/ui/pages/applications/[id]/preview.tsx +++ b/apps/ui/pages/applications/[id]/preview.tsx @@ -35,9 +35,6 @@ import { ErrorText } from "common/src/components/ErrorText"; import Link from "next/link"; import { validateApplication } from "@/components/application/form"; -type Props = Awaited>["props"]; -type PropsNarrowed = Exclude; - // User has to accept the terms of service then on submit we change the application status // This uses separate Send mutation (not update) so no onNext like the other pages // we could also remove the FormContext here @@ -142,6 +139,9 @@ function Preview({ application, tos }: PropsNarrowed): JSX.Element { ); } +type Props = Awaited>["props"]; +type PropsNarrowed = Exclude; + export async function getServerSideProps(ctx: GetServerSidePropsContext) { const { locale } = ctx; const commonProps = getCommonServerSideProps(); @@ -171,7 +171,7 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { query: ApplicationPage1Document, variables: { id: base64encode(`ApplicationNode:${pk}`) }, }); - const { application } = data ?? {}; + const { application } = data; if (application == null) { return notFound; } diff --git a/apps/ui/pages/applications/[id]/view/index.tsx b/apps/ui/pages/applications/[id]/view/index.tsx index 89b427c833..92d955b19b 100644 --- a/apps/ui/pages/applications/[id]/view/index.tsx +++ b/apps/ui/pages/applications/[id]/view/index.tsx @@ -18,6 +18,7 @@ import { import { ApplicationStatusChoice, ApplicationViewDocument, + type ApplicationViewQueryVariables, type ApplicationViewQuery, } from "@gql/gql-types"; import { Tabs } from "hds-react"; @@ -154,24 +155,6 @@ function View({ application, tos }: PropsNarrowed): JSX.Element { ); } -// TODO refactor this by splitting the query based on tab -// it includes all the application section information that is not required by by the View Application tab -// the reservations tab doesn't need to know what the user applied for but what they got. -// The query is already too complex at 22 complexity (requires backend changes to add more fields). -// Terms of use is only required by the application tab. -// ApplicationCommon fragment needs to be refactored so we have a separate minimal fragments for -// - reservation tab -// - application tab -// They can both be included in the SSR query -// (or alternatively the reservation tab can be fetched on the client side per each applicationSection) -export const APPLICATION_VIEW_QUERY = gql` - query ApplicationView($id: ID!) { - application(id: $id) { - ...ApplicationCommon - } - } -`; - type Props = Awaited>["props"]; type PropsNarrowed = Exclude; @@ -180,15 +163,10 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { const commonProps = getCommonServerSideProps(); const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); - const tos = await getGenericTerms(apolloClient); - const { query } = ctx; - const { id } = query; - - const pkstring = Array.isArray(id) ? id[0] : id; - const pk = Number.isNaN(Number(pkstring)) ? undefined : Number(pkstring); + const pk = toNumber(ignoreMaybeArray(query.id)); - const notFoundRetvalue = { + const notFound = { props: { notFound: true, ...commonProps, @@ -196,23 +174,29 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { notFound: true, }; - if (pk == null) { - return notFoundRetvalue; + if (pk == null || pk <= 0) { + return notFound; } - const { data } = await apolloClient.query({ + const { data } = await apolloClient.query< + ApplicationViewQuery, + ApplicationViewQueryVariables + >({ query: ApplicationViewDocument, variables: { id: base64encode(`ApplicationNode:${pk}`) }, }); - if (!data?.application) { - return notFoundRetvalue; + const { application } = data; + if (application == null) { + return notFound; } + const tos = await getGenericTerms(apolloClient); + return { props: { ...commonProps, - application: data.application, + application, tos, ...(await serverSideTranslations(locale ?? "fi")), }, @@ -220,3 +204,11 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) { } export default View; + +export const APPLICATION_VIEW_QUERY = gql` + query ApplicationView($id: ID!) { + application(id: $id) { + ...ApplicationCommon + } + } +`; diff --git a/apps/ui/pages/recurring/[id]/criteria/index.tsx b/apps/ui/pages/recurring/[id]/criteria/index.tsx index 8e212f06f1..b8ad0e9917 100644 --- a/apps/ui/pages/recurring/[id]/criteria/index.tsx +++ b/apps/ui/pages/recurring/[id]/criteria/index.tsx @@ -5,8 +5,8 @@ import styled from "styled-components"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; import { ApplicationRoundCriteriaDocument, - ApplicationRoundCriteriaQuery, - ApplicationRoundCriteriaQueryVariables, + type ApplicationRoundCriteriaQuery, + type ApplicationRoundCriteriaQueryVariables, } from "@gql/gql-types"; import { breakpoints, H1, H2, H3 } from "common"; import { createApolloClient } from "@/modules/apolloClient"; @@ -26,65 +26,6 @@ import { gql } from "@apollo/client"; type Props = Awaited>["props"]; type PropsNarrowed = Exclude; -export const APPLICATION_ROUND_CRITERIA_QUERY = gql` - query ApplicationRoundCriteria($id: ID!) { - applicationRound(id: $id) { - pk - id - nameFi - nameEn - nameSv - criteriaFi - criteriaEn - criteriaSv - notesWhenApplyingFi - notesWhenApplyingEn - notesWhenApplyingSv - } - } -`; - -export async function getServerSideProps(ctx: GetServerSidePropsContext) { - const { locale, params } = ctx; - const pk = toNumber(ignoreMaybeArray(params?.id)); - const commonProps = getCommonServerSideProps(); - const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); - - const notFound = { - notFound: true, - props: { - ...commonProps, - ...(await serverSideTranslations(locale ?? "fi")), - notFound: true, - }, - }; - - if (pk == null || !(pk > 0)) { - return notFound; - } - const { data } = await apolloClient.query< - ApplicationRoundCriteriaQuery, - ApplicationRoundCriteriaQueryVariables - >({ - query: ApplicationRoundCriteriaDocument, - variables: { - id: base64encode(`ApplicationRoundNode:${pk}`), - }, - }); - const applicationRound = data?.applicationRound; - - if (applicationRound == null) { - return notFound; - } - return { - props: { - ...commonProps, - applicationRound, - ...(await serverSideTranslations(locale ?? "fi")), - }, - }; -} - const ContentWrapper = styled.div` display: flex; gap: var(--spacing-m); @@ -142,4 +83,63 @@ function Criteria({ ); } +export async function getServerSideProps(ctx: GetServerSidePropsContext) { + const { locale, params } = ctx; + const pk = toNumber(ignoreMaybeArray(params?.id)); + const commonProps = getCommonServerSideProps(); + const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); + + const notFound = { + notFound: true, + props: { + ...commonProps, + ...(await serverSideTranslations(locale ?? "fi")), + notFound: true, + }, + }; + + if (pk == null || !(pk > 0)) { + return notFound; + } + const { data } = await apolloClient.query< + ApplicationRoundCriteriaQuery, + ApplicationRoundCriteriaQueryVariables + >({ + query: ApplicationRoundCriteriaDocument, + variables: { + id: base64encode(`ApplicationRoundNode:${pk}`), + }, + }); + + const { applicationRound } = data; + if (applicationRound == null) { + return notFound; + } + return { + props: { + ...commonProps, + applicationRound, + ...(await serverSideTranslations(locale ?? "fi")), + }, + }; +} + export default Criteria; + +export const APPLICATION_ROUND_CRITERIA_QUERY = gql` + query ApplicationRoundCriteria($id: ID!) { + applicationRound(id: $id) { + pk + id + nameFi + nameEn + nameSv + criteriaFi + criteriaEn + criteriaSv + notesWhenApplyingFi + notesWhenApplyingEn + notesWhenApplyingSv + } + } +`; diff --git a/apps/ui/pages/recurring/[id]/index.tsx b/apps/ui/pages/recurring/[id]/index.tsx index 05bfeeaeb2..2421023e88 100644 --- a/apps/ui/pages/recurring/[id]/index.tsx +++ b/apps/ui/pages/recurring/[id]/index.tsx @@ -32,67 +32,6 @@ import { seasonalPrefix } from "@/modules/urls"; import { getApplicationRoundName } from "@/modules/applicationRound"; import { gql } from "@apollo/client"; -type Props = Awaited>["props"]; -type NarrowedProps = Exclude; - -export const APPLICATION_ROUND_QUERY = gql` - query ApplicationRound($id: ID!) { - applicationRound(id: $id) { - id - pk - nameFi - nameEn - nameSv - reservationUnits { - id - pk - } - } - } -`; - -export async function getServerSideProps(ctx: GetServerSidePropsContext) { - const { locale, params } = ctx; - const commonProps = getCommonServerSideProps(); - const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); - const pk = toNumber(ignoreMaybeArray(params?.id)); - - const notFound = { - notFound: true, - props: { - ...commonProps, - ...(await serverSideTranslations(locale ?? "fi")), - notFound: true, - }, - }; - if (pk == null || !(pk > 0)) { - return notFound; - } - const { data } = await apolloClient.query< - ApplicationRoundQuery, - ApplicationRoundQueryVariables - >({ - query: ApplicationRoundDocument, - variables: { - id: base64encode(`ApplicationRoundNode:${pk}`), - }, - }); - const applicationRound = data.applicationRound; - if (applicationRound == null) { - return notFound; - } - - const opts = await getSearchOptions(apolloClient, "seasonal", locale ?? ""); - return { - props: { - ...commonProps, - ...opts, - applicationRound, - ...(await serverSideTranslations(locale ?? "fi")), - }, - }; -} - function SeasonalSearch({ applicationRound, unitOptions, @@ -173,4 +112,65 @@ function SeasonalSearch({ ); } +type Props = Awaited>["props"]; +type NarrowedProps = Exclude; + +export async function getServerSideProps(ctx: GetServerSidePropsContext) { + const { locale, params } = ctx; + const commonProps = getCommonServerSideProps(); + const apolloClient = createApolloClient(commonProps.apiBaseUrl, ctx); + const pk = toNumber(ignoreMaybeArray(params?.id)); + + const notFound = { + notFound: true, + props: { + ...commonProps, + ...(await serverSideTranslations(locale ?? "fi")), + notFound: true, + }, + }; + if (pk == null || !(pk > 0)) { + return notFound; + } + const { data } = await apolloClient.query< + ApplicationRoundQuery, + ApplicationRoundQueryVariables + >({ + query: ApplicationRoundDocument, + variables: { + id: base64encode(`ApplicationRoundNode:${pk}`), + }, + }); + const { applicationRound } = data; + if (applicationRound == null) { + return notFound; + } + + const opts = await getSearchOptions(apolloClient, "seasonal", locale ?? ""); + return { + props: { + ...commonProps, + ...opts, + applicationRound, + ...(await serverSideTranslations(locale ?? "fi")), + }, + }; +} + export default SeasonalSearch; + +export const APPLICATION_ROUND_QUERY = gql` + query ApplicationRound($id: ID!) { + applicationRound(id: $id) { + id + pk + nameFi + nameEn + nameSv + reservationUnits { + id + pk + } + } + } +`;