From 94176f1c4ebb641ae70ed68a02a4efa25b7920d4 Mon Sep 17 00:00:00 2001 From: Daniel Haarhoff Date: Thu, 7 Nov 2024 22:08:32 +0000 Subject: [PATCH] Update all forms to only call page template in single place #76 --- src/commands/area/add-owner-form.ts | 19 ++++---- src/commands/area/create-form.ts | 20 +++----- src/commands/area/remove-area-form.ts | 15 ++---- src/commands/area/remove-owner-form.ts | 11 ++--- src/commands/equipment/add-form.ts | 13 ++---- .../equipment/register-training-sheet-form.ts | 12 ++--- .../link-number-to-email-form.ts | 20 ++------ src/commands/members/edit-name-form.ts | 5 +- src/commands/members/edit-pronouns-form.ts | 5 +- .../members/sign-owner-agreement-form.ts | 5 +- src/commands/super-user/declare-form.ts | 11 +---- src/commands/super-user/revoke-form.ts | 44 ++++++++---------- src/commands/trainers/add-trainer-form.ts | 46 ++++++++++--------- .../trainers/mark-member-trained-form.ts | 12 ++--- .../trainers/revoke-member-trained-form.ts | 12 ++--- src/http/form-get.ts | 10 +++- src/queries/me/index.ts | 5 +- src/types/form.ts | 4 +- src/types/html.ts | 8 ++-- 19 files changed, 117 insertions(+), 160 deletions(-) diff --git a/src/commands/area/add-owner-form.ts b/src/commands/area/add-owner-form.ts index 54cb46f5..809835bc 100644 --- a/src/commands/area/add-owner-form.ts +++ b/src/commands/area/add-owner-form.ts @@ -2,7 +2,7 @@ import {flow, pipe} from 'fp-ts/lib/function'; import * as RA from 'fp-ts/ReadonlyArray'; import * as E from 'fp-ts/Either'; import * as O from 'fp-ts/Option'; -import {EmailAddress, User} from '../../types'; +import {EmailAddress} from '../../types'; import * as t from 'io-ts'; import {StatusCodes} from 'http-status-codes'; import {formatValidationErrors} from 'io-ts-reporters'; @@ -11,8 +11,13 @@ import { failureWithStatus, } from '../../types/failure-with-status'; import {Form} from '../../types/form'; -import {html, joinHtml, safe, sanitizeString} from '../../types/html'; -import {pageTemplate} from '../../templates'; +import { + html, + joinHtml, + safe, + sanitizeString, + toLoggedInContent, +} from '../../types/html'; import {renderMemberNumber} from '../../templates/member-number'; import {SharedReadModel} from '../../read-models/shared-state'; import { @@ -31,7 +36,6 @@ type Member = { }; type ViewModel = { - user: User; areaId: string; areaOwners: { existing: ReadonlyArray; @@ -112,7 +116,7 @@ const renderBody = (viewModel: ViewModel) => html` `; const renderForm = (viewModel: ViewModel) => - pipe(viewModel, renderBody, pageTemplate(safe('Add Owner'), viewModel.user)); + pipe(viewModel, renderBody, toLoggedInContent(safe('Add Owner'))); const paramsCodec = t.strict({ area: t.string, @@ -199,10 +203,9 @@ const getAreaName = (db: SharedReadModel['db'], areaId: string) => const constructForm: Form['constructForm'] = input => - ({user, readModel}): E.Either => + ({readModel}): E.Either => pipe( - {user}, - E.right, + E.Do, E.bind('areaId', () => getAreaId(input)), E.bind('areaName', ({areaId}) => getAreaName(readModel.db, areaId)), E.bind('areaOwners', ({areaId}) => diff --git a/src/commands/area/create-form.ts b/src/commands/area/create-form.ts index 1ffa549a..e9e5de57 100644 --- a/src/commands/area/create-form.ts +++ b/src/commands/area/create-form.ts @@ -1,20 +1,15 @@ import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {User} from '../../types'; import {Form} from '../../types/form'; import {pipe} from 'fp-ts/lib/function'; -import {html, safe} from '../../types/html'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {v4} from 'uuid'; import {UUID} from 'io-ts-types'; -type ViewModel = { - user: User; -}; +type ViewModel = unknown; -const renderForm = (viewModel: ViewModel) => +const renderForm = () => pipe( - viewModel, - () => html` + html`

Create an area

@@ -23,13 +18,10 @@ const renderForm = (viewModel: ViewModel) =>
`, - pageTemplate(safe('Create Area'), viewModel.user) + toLoggedInContent(safe('Create Area')) ); export const createForm: Form = { renderForm, - constructForm: - () => - ({user}) => - E.right({user}), + constructForm: () => () => E.right({}), }; diff --git a/src/commands/area/remove-area-form.ts b/src/commands/area/remove-area-form.ts index 522655ef..d814df7f 100644 --- a/src/commands/area/remove-area-form.ts +++ b/src/commands/area/remove-area-form.ts @@ -1,25 +1,21 @@ import * as E from 'fp-ts/Either'; import * as t from 'io-ts'; -import {pageTemplate} from '../../templates'; -import {User} from '../../types'; import {Form} from '../../types/form'; import {flow, pipe} from 'fp-ts/lib/function'; -import {html, safe, sanitizeString} from '../../types/html'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; import {StatusCodes} from 'http-status-codes'; import {failureWithStatus} from '../../types/failure-with-status'; import {formatValidationErrors} from 'io-ts-reporters'; import {getAreaName} from './get-area-name'; type ViewModel = { - user: User; areaId: string; areaName: string; }; const renderForm = (viewModel: ViewModel) => pipe( - viewModel, - () => html` + html`

Remove '${sanitizeString(viewModel.areaName)}'?

@@ -28,7 +24,7 @@ const renderForm = (viewModel: ViewModel) =>
`, - pageTemplate(safe('Remove Area'), viewModel.user) + toLoggedInContent(safe('Remove Area')) ); const paramsCodec = t.strict({ @@ -55,10 +51,9 @@ export const removeAreaForm: Form = { renderForm, constructForm: input => - ({user, readModel}) => + ({readModel}) => pipe( - {user}, - E.right, + E.Do, E.bind('areaId', () => getAreaId(input)), E.bind('areaName', ({areaId}) => getAreaName(readModel.db, areaId)) ), diff --git a/src/commands/area/remove-owner-form.ts b/src/commands/area/remove-owner-form.ts index ff590d45..a2114f1a 100644 --- a/src/commands/area/remove-owner-form.ts +++ b/src/commands/area/remove-owner-form.ts @@ -2,11 +2,10 @@ import * as tt from 'io-ts-types'; import * as t from 'io-ts'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {EmailAddress, User} from '../../types'; +import {EmailAddress} from '../../types'; import {Form} from '../../types/form'; import {flow, pipe} from 'fp-ts/lib/function'; -import {html, safe, sanitizeString} from '../../types/html'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; import {StatusCodes} from 'http-status-codes'; import {failureWithStatus} from '../../types/failure-with-status'; import {formatValidationErrors} from 'io-ts-reporters'; @@ -17,7 +16,6 @@ import {SharedReadModel} from '../../read-models/shared-state'; import * as O from 'fp-ts/Option'; type ViewModel = { - user: User; areaId: string; areaName: string; owner: { @@ -73,7 +71,7 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Remove Owner'), viewModel.user) + toLoggedInContent(safe('Remove Owner')) ); const getOwner = (db: SharedReadModel['db'], memberNumber: number) => @@ -119,11 +117,10 @@ export const removeOwnerForm: Form = { renderForm, constructForm: input => - ({user, readModel}) => + ({readModel}) => pipe( input, decodeParams, - E.bind('user', () => E.right(user)), E.bind('areaName', ({areaId}) => getAreaName(readModel.db, areaId)), E.bind('owner', ({memberNumber}) => getOwner(readModel.db, memberNumber) diff --git a/src/commands/equipment/add-form.ts b/src/commands/equipment/add-form.ts index 478149dc..346ad4ec 100644 --- a/src/commands/equipment/add-form.ts +++ b/src/commands/equipment/add-form.ts @@ -1,9 +1,8 @@ import {pipe} from 'fp-ts/lib/function'; import * as t from 'io-ts'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe, sanitizeString} from '../../types/html'; -import {DomainEvent, User} from '../../types'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; +import {DomainEvent} from '../../types'; import {v4} from 'uuid'; import {Form} from '../../types/form'; import {formatValidationErrors} from 'io-ts-reporters'; @@ -13,7 +12,6 @@ import {readModels} from '../../read-models'; import {UUID} from 'io-ts-types'; type ViewModel = { - user: User; areaId: UUID; areaName: string; }; @@ -30,7 +28,7 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Create Equipment'), viewModel.user) + toLoggedInContent(safe('Create Equipment')) ); const getAreaId = (input: unknown) => @@ -54,12 +52,11 @@ const getAreaName = (events: ReadonlyArray, areaId: UUID) => const constructForm: Form['constructForm'] = input => - ({user, events}) => + ({events}) => pipe( E.Do, E.bind('areaId', () => getAreaId(input)), - E.bind('areaName', ({areaId}) => getAreaName(events, areaId)), - E.bind('user', () => E.right(user)) + E.bind('areaName', ({areaId}) => getAreaName(events, areaId)) ); export const addForm: Form = { diff --git a/src/commands/equipment/register-training-sheet-form.ts b/src/commands/equipment/register-training-sheet-form.ts index 263c5688..51e3b777 100644 --- a/src/commands/equipment/register-training-sheet-form.ts +++ b/src/commands/equipment/register-training-sheet-form.ts @@ -1,15 +1,12 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {html, safe, sanitizeString} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; -import {pageTemplate} from '../../templates'; import {getEquipmentName} from './get-equipment-name'; import {getEquipmentIdFromForm} from './get-equipment-id-from-form'; import {UUID} from 'io-ts-types'; type ViewModel = { - user: User; equipmentId: UUID; equipmentName: string; }; @@ -31,15 +28,14 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Register training sheet'), viewModel.user) + toLoggedInContent(safe('Register training sheet')) ); const constructForm: Form['constructForm'] = input => - ({events, user}) => + ({events}) => pipe( - {user}, - E.right, + E.Do, E.bind('equipmentId', () => getEquipmentIdFromForm(input)), E.bind('equipmentName', ({equipmentId}) => getEquipmentName(events, equipmentId) diff --git a/src/commands/member-numbers/link-number-to-email-form.ts b/src/commands/member-numbers/link-number-to-email-form.ts index a0afa740..b3fb66d1 100644 --- a/src/commands/member-numbers/link-number-to-email-form.ts +++ b/src/commands/member-numbers/link-number-to-email-form.ts @@ -1,15 +1,11 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; -type ViewModel = { - user: User; -}; +type ViewModel = unknown; -const renderForm = (viewModel: ViewModel) => +const renderForm = () => pipe( html`

Link a member number to an e-mail address

@@ -24,16 +20,10 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate( - safe('Link a member number to an e-mail address'), - viewModel.user - ) + toLoggedInContent(safe('Link a member number to an e-mail address')) ); -const constructForm: Form['constructForm'] = - () => - ({user}) => - E.right({user}); +const constructForm: Form['constructForm'] = () => () => E.right({}); export const linkNumberToEmailForm: Form = { renderForm, diff --git a/src/commands/members/edit-name-form.ts b/src/commands/members/edit-name-form.ts index 5c9c729a..db0c2a02 100644 --- a/src/commands/members/edit-name-form.ts +++ b/src/commands/members/edit-name-form.ts @@ -1,7 +1,6 @@ import {flow, pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {User} from '../../types'; import {Form} from '../../types/form'; import * as t from 'io-ts'; @@ -30,7 +29,7 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Edit name'), viewModel.user) + toLoggedInContent(safe('Edit name')) ); const paramsCodec = t.strict({ diff --git a/src/commands/members/edit-pronouns-form.ts b/src/commands/members/edit-pronouns-form.ts index 850f6e3b..93669a17 100644 --- a/src/commands/members/edit-pronouns-form.ts +++ b/src/commands/members/edit-pronouns-form.ts @@ -1,7 +1,6 @@ import {flow, pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {User} from '../../types'; import {Form} from '../../types/form'; import * as t from 'io-ts'; @@ -30,7 +29,7 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Edit pronouns'), viewModel.user) + toLoggedInContent(safe('Edit pronouns')) ); const paramsCodec = t.strict({ diff --git a/src/commands/members/sign-owner-agreement-form.ts b/src/commands/members/sign-owner-agreement-form.ts index 62180dac..aa75c13e 100644 --- a/src/commands/members/sign-owner-agreement-form.ts +++ b/src/commands/members/sign-owner-agreement-form.ts @@ -1,7 +1,6 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; import {User} from '../../types'; import {ownerAgreement} from './owner-agreement'; @@ -27,7 +26,7 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Sign Owner Agreement'), viewModel.user) + toLoggedInContent(safe('Sign Owner Agreement')) ); const constructForm: Form['constructForm'] = diff --git a/src/commands/super-user/declare-form.ts b/src/commands/super-user/declare-form.ts index 370ce286..eff4dc1e 100644 --- a/src/commands/super-user/declare-form.ts +++ b/src/commands/super-user/declare-form.ts @@ -1,15 +1,12 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; import {memberInput} from '../../templates/member-input'; import {readModels} from '../../read-models'; import {Member} from '../../read-models/members'; type ViewModel = { - user: User; members: ReadonlyArray; }; @@ -25,11 +22,7 @@ const render = (viewModel: ViewModel) => html` `; const renderForm = (viewModel: ViewModel) => - pipe( - viewModel, - render, - pageTemplate(safe('Declare super user'), viewModel.user) - ); + pipe(viewModel, render, toLoggedInContent(safe('Declare super user'))); const constructForm: Form['constructForm'] = () => diff --git a/src/commands/super-user/revoke-form.ts b/src/commands/super-user/revoke-form.ts index 96cd0bab..87708315 100644 --- a/src/commands/super-user/revoke-form.ts +++ b/src/commands/super-user/revoke-form.ts @@ -2,9 +2,7 @@ import {flow, pipe} from 'fp-ts/lib/function'; import * as tt from 'io-ts-types'; import * as t from 'io-ts'; import * as E from 'fp-ts/Either'; -import {pageTemplate} from '../../templates'; -import {html, safe} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, toLoggedInContent} from '../../types/html'; import {failureWithStatus} from '../../types/failure-with-status'; import {StatusCodes} from 'http-status-codes'; import {formatValidationErrors} from 'io-ts-reporters'; @@ -12,7 +10,6 @@ import {Form} from '../../types/form'; import {renderMemberNumber} from '../../templates/member-number'; type ViewModel = { - user: User; toBeRevoked: number; }; @@ -37,35 +34,32 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Revoke super user'), viewModel.user) + toLoggedInContent(safe('Revoke super user')) ); const paramsCodec = t.strict({ memberNumber: tt.IntFromString, }); -const constructForm: Form['constructForm'] = - input => - ({user}) => - pipe( - input, - paramsCodec.decode, - E.mapLeft( - flow( - formatValidationErrors, - failureWithStatus( - 'Parameters submitted to the form were invalid', - StatusCodes.BAD_REQUEST - ) +const constructForm: Form['constructForm'] = input => () => + pipe( + input, + paramsCodec.decode, + E.mapLeft( + flow( + formatValidationErrors, + failureWithStatus( + 'Parameters submitted to the form were invalid', + StatusCodes.BAD_REQUEST ) - ), - E.map(params => ({ - user, - toBeRevoked: params.memberNumber, - })) - ); + ) + ), + E.map(params => ({ + toBeRevoked: params.memberNumber, + })) + ); export const revokeForm: Form = { - renderForm: renderForm, + renderForm, constructForm, }; diff --git a/src/commands/trainers/add-trainer-form.ts b/src/commands/trainers/add-trainer-form.ts index 9997b048..c1ca5960 100644 --- a/src/commands/trainers/add-trainer-form.ts +++ b/src/commands/trainers/add-trainer-form.ts @@ -2,8 +2,13 @@ import {pipe} from 'fp-ts/lib/function'; import * as t from 'io-ts'; import * as E from 'fp-ts/Either'; import * as O from 'fp-ts/Option'; -import {pageTemplate} from '../../templates'; -import {html, joinHtml, safe, sanitizeString} from '../../types/html'; +import { + html, + joinHtml, + safe, + sanitizeString, + toLoggedInContent, +} from '../../types/html'; import {User} from '../../types'; import {Form} from '../../types/form'; import {formatValidationErrors} from 'io-ts-reporters'; @@ -23,29 +28,27 @@ import { import {eq} from 'drizzle-orm'; type ViewModel = { - user: User; areaOwnersThatAreNotTrainers: ReadonlyArray; equipment: Equipment; }; -const nobodyToAddAsTrainer = (user: ViewModel['user']) => - pipe( - html` -
-

Add a trainer

-

You can't add any trainers right now.

-

- Either all owners are already trainers or there are no owners for this - area. -

-
- `, - pageTemplate(safe('Add Trainer'), user) - ); +const nobodyToAddAsTrainer = pipe( + html` +
+

Add a trainer

+

You can't add any trainers right now.

+

+ Either all owners are already trainers or there are no owners for this + area. +

+
+ `, + toLoggedInContent(safe('Add Trainer')) +); const renderForm = (viewModel: ViewModel) => { if (viewModel.areaOwnersThatAreNotTrainers.length === 0) { - return nobodyToAddAsTrainer(viewModel.user); + return nobodyToAddAsTrainer; } return pipe( @@ -89,7 +92,7 @@ const renderForm = (viewModel: ViewModel) => { `, - pageTemplate(safe('Add Trainer'), viewModel.user) + toLoggedInContent(safe('Add Trainer')) ); }; @@ -142,7 +145,7 @@ const getPotentialTrainers = (db: SharedReadModel['db'], equipmentId: UUID) => { const constructForm: Form['constructForm'] = input => - ({user, readModel}) => + ({readModel}) => pipe( E.Do, E.bind('equipmentId', () => getEquipmentId(input)), @@ -157,8 +160,7 @@ const constructForm: Form['constructForm'] = }), E.bind('areaOwnersThatAreNotTrainers', ({equipmentId}) => getPotentialTrainers(readModel.db, equipmentId) - ), - E.bind('user', () => E.right(user)) + ) ); export const addTrainerForm: Form = { diff --git a/src/commands/trainers/mark-member-trained-form.ts b/src/commands/trainers/mark-member-trained-form.ts index 217300cc..3446209f 100644 --- a/src/commands/trainers/mark-member-trained-form.ts +++ b/src/commands/trainers/mark-member-trained-form.ts @@ -1,10 +1,8 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; import * as O from 'fp-ts/Option'; -import {html, safe, sanitizeString} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; -import {pageTemplate} from '../../templates'; import {getEquipmentIdFromForm} from '../equipment/get-equipment-id-from-form'; import {memberInput} from '../../templates/member-input'; import {Member} from '../../read-models/members'; @@ -13,7 +11,6 @@ import {failureWithStatus} from '../../types/failure-with-status'; import {StatusCodes} from 'http-status-codes'; type ViewModel = { - user: User; equipment: Equipment; members: ReadonlyArray; }; @@ -37,15 +34,14 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Member Training Complete'), viewModel.user) + toLoggedInContent(safe('Member Training Complete')) ); const constructForm: Form['constructForm'] = input => - ({user, readModel}) => + ({readModel}) => pipe( - {user}, - E.right, + E.Do, E.bind('equipment_id', () => getEquipmentIdFromForm(input)), E.bind('equipment', ({equipment_id}) => { const equipment = readModel.equipment.get(equipment_id); diff --git a/src/commands/trainers/revoke-member-trained-form.ts b/src/commands/trainers/revoke-member-trained-form.ts index a94cb55c..b8c21786 100644 --- a/src/commands/trainers/revoke-member-trained-form.ts +++ b/src/commands/trainers/revoke-member-trained-form.ts @@ -1,10 +1,8 @@ import {pipe} from 'fp-ts/lib/function'; import * as E from 'fp-ts/Either'; import * as O from 'fp-ts/Option'; -import {html, safe, sanitizeString} from '../../types/html'; -import {User} from '../../types'; +import {html, safe, sanitizeString, toLoggedInContent} from '../../types/html'; import {Form} from '../../types/form'; -import {pageTemplate} from '../../templates'; import {getEquipmentIdFromForm} from '../equipment/get-equipment-id-from-form'; import {memberInput} from '../../templates/member-input'; import {Member} from '../../read-models/members'; @@ -13,7 +11,6 @@ import {failureWithStatus} from '../../types/failure-with-status'; import {StatusCodes} from 'http-status-codes'; type ViewModel = { - user: User; equipment: Equipment; members: ReadonlyArray; }; @@ -34,15 +31,14 @@ const renderForm = (viewModel: ViewModel) => `, - pageTemplate(safe('Revoked Training'), viewModel.user) + toLoggedInContent(safe('Revoke Training')) ); const constructForm: Form['constructForm'] = input => - ({user, readModel}) => + ({readModel}) => pipe( - {user}, - E.right, + E.Do, E.bind('equipment_id', () => getEquipmentIdFromForm(input)), E.bind('equipment', ({equipment_id}) => { const equipment = readModel.equipment.get(equipment_id); diff --git a/src/http/form-get.ts b/src/http/form-get.ts index 7619c889..1aafb167 100644 --- a/src/http/form-get.ts +++ b/src/http/form-get.ts @@ -1,14 +1,16 @@ import {Request, Response} from 'express'; +import * as O from 'fp-ts/Option'; import * as TE from 'fp-ts/TaskEither'; import {pipe} from 'fp-ts/lib/function'; import {StatusCodes} from 'http-status-codes'; import {getUserFromSession} from '../authentication'; import {Dependencies} from '../dependencies'; -import {oopsPage} from '../templates'; +import {oopsPage, pageTemplate} from '../templates'; import {sequenceS} from 'fp-ts/lib/Apply'; import {Form} from '../types/form'; import {failureWithStatus} from '../types/failure-with-status'; import {CompleteHtmlDocument, sanitizeString} from '../types/html'; +import {logInPath} from '../authentication/auth-routes'; const getUser = (req: Request, deps: Dependencies) => pipe( @@ -26,6 +28,11 @@ const getUser = (req: Request, deps: Dependencies) => export const formGet = (deps: Dependencies, form: Form) => async (req: Request, res: Response) => { + const user = getUserFromSession(deps)(req.session); + if (O.isNone(user)) { + res.redirect(logInPath); + return; + } await pipe( { user: getUser(req, deps), @@ -35,6 +42,7 @@ export const formGet = TE.let('readModel', () => deps.sharedReadModel), TE.chainEitherK(form.constructForm({...req.query, ...req.params})), TE.map(form.renderForm), + TE.map(({title, body}) => pageTemplate(title, user.value)(body)), TE.matchW( failure => { deps.logger.error(failure, 'Failed to show form to a user'); diff --git a/src/queries/me/index.ts b/src/queries/me/index.ts index 90afa4fc..98f66e85 100644 --- a/src/queries/me/index.ts +++ b/src/queries/me/index.ts @@ -3,12 +3,13 @@ import * as TE from 'fp-ts/TaskEither'; import {render} from './render'; import {constructViewModel} from './construct-view-model'; import {Query} from '../query'; -import {toLoggedInContent, safe} from '../../types/html'; +import {toLoggedInContent, safe, HttpResponse} from '../../types/html'; export const me: Query = deps => user => pipe( user.memberNumber, constructViewModel(deps, user), TE.map(viewModel => render(viewModel)), - TE.map(toLoggedInContent(safe('My Details'))) + TE.map(toLoggedInContent(safe('My Details'))), + TE.map(HttpResponse.mk.LoggedInContent) ); diff --git a/src/types/form.ts b/src/types/form.ts index 5f1008ec..d094e6e2 100644 --- a/src/types/form.ts +++ b/src/types/form.ts @@ -1,11 +1,11 @@ import {DomainEvent, User} from '.'; import {FailureWithStatus} from './failure-with-status'; import * as E from 'fp-ts/Either'; -import {CompleteHtmlDocument} from './html'; +import {LoggedInContent} from './html'; import {SharedReadModel} from '../read-models/shared-state'; export type Form = { - renderForm: (viewModel: T) => CompleteHtmlDocument; + renderForm: (viewModel: T) => LoggedInContent; constructForm: ( input: unknown ) => (context: { diff --git a/src/types/html.ts b/src/types/html.ts index 66739f67..5236dfaa 100644 --- a/src/types/html.ts +++ b/src/types/html.ts @@ -69,7 +69,7 @@ interface CompleteHtmlPage { rendered: CompleteHtmlDocument; } -interface LoggedInPage { +export interface LoggedInContent { title: HtmlSubstitution; body: Html; } @@ -87,12 +87,12 @@ export type HttpResponse = | Sum.Member<'Redirect', Redirect> | Sum.Member<'Raw', Raw> | Sum.Member<'CompleteHtmlPage', CompleteHtmlPage> - | Sum.Member<'LoggedInContent', LoggedInPage>; + | Sum.Member<'LoggedInContent', LoggedInContent>; export const HttpResponse = Sum.create(); export const toLoggedInContent = (title: HtmlSubstitution) => (body: Html) => - HttpResponse.mk.LoggedInContent({ + ({ title: title, body: body, - }); + }) satisfies LoggedInContent;