From 2c43674dcc093d0818c7e18f3cc120d1be469817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Rivi=C3=A8re?= Date: Wed, 4 Jan 2023 10:59:50 +0100 Subject: [PATCH] feat(form): Display form status and last modification time --- .../administration/Games/Game/Game.tsx | 2 +- .../Personalization/PersonalizationForm.tsx | 57 ++++++++++++++++++- .../play/Personalization/models/form.tsx | 2 + .../client/src/modules/translations/fr.json | 11 +++- .../migration.sql | 2 + packages/server/prisma/schema.prisma | 1 + .../src/modules/players/services/index.ts | 2 + .../src/modules/profiles/types/index.ts | 1 + .../eventHandlers/updateProfileHandler.ts | 2 + 9 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 packages/server/prisma/migrations/20230104093231_add_last_status_form_update/migration.sql diff --git a/packages/client/src/modules/administration/Games/Game/Game.tsx b/packages/client/src/modules/administration/Games/Game/Game.tsx index 27efe9b3..4082b3d1 100644 --- a/packages/client/src/modules/administration/Games/Game/Game.tsx +++ b/packages/client/src/modules/administration/Games/Game/Game.tsx @@ -35,7 +35,7 @@ function Game() { <> - Atelier {game?.id} + Atelier {game?.code} diff --git a/packages/client/src/modules/play/Personalization/PersonalizationForm.tsx b/packages/client/src/modules/play/Personalization/PersonalizationForm.tsx index e465aa33..1ab97441 100644 --- a/packages/client/src/modules/play/Personalization/PersonalizationForm.tsx +++ b/packages/client/src/modules/play/Personalization/PersonalizationForm.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useState } from "react"; -import { Button, Grid, Tooltip, Typography } from "@mui/material"; +import { Button, Grid, Tooltip, Typography, useTheme } from "@mui/material"; import { CustomContainer } from "./styles/personalization"; import { BackArrow, BackArrowWithValidation } from "./common/BackArrow"; import { QuestionLine, QuestionText } from "./styles/form"; @@ -7,6 +7,7 @@ import { useForm } from "react-hook-form"; import { PersoFormInputList, PersoFormNumberInput } from "./common/FormInputs"; import { formSections, + FormStatus, formValues, PersoForm, persoFormInputs, @@ -30,11 +31,13 @@ import { useQuery } from "react-query"; import { IGame } from "../../../utils/types"; import { ErrorAlert } from "../../alert"; import { Accordion } from "../../common/components/Accordion"; +import { t } from "../../translations"; export { PersonalizationForm }; function PersonalizationForm() { const gameId = useGameId(); + const theme = useTheme(); const { profile, updateProfile } = usePlay(); const query = useQuery(`/api/games/${gameId}`, () => { @@ -96,6 +99,22 @@ function PersonalizationForm() { throw new Error("Unsupported question type"); }; + const formatLastUpdateDate = (date: Date) => { + if (!date) { + return "Aucune action enregistrée"; + } + + const dateObj = new Date(date); + const day = dateObj.toLocaleDateString([], { + dateStyle: "short", + }); + const time = new Date(date).toLocaleTimeString([], { + timeStyle: "short", + }); + + return `le ${day} à ${time}`; + }; + const buildFormLine = (question: Question, display: boolean) => { return ( )}
+ {profile && profile.status && ( + + + + État du formulaire: + {" "} + {t(`form.status.${profile.status as FormStatus}`)} + + + + {t(`form.last-action.${profile.status as FormStatus}`)}: + {" "} + {formatLastUpdateDate(profile.lastStatusUpdate)} + + + )} {!isDirty && ( diff --git a/packages/client/src/modules/play/Personalization/models/form.tsx b/packages/client/src/modules/play/Personalization/models/form.tsx index f98206bf..ddc895b1 100644 --- a/packages/client/src/modules/play/Personalization/models/form.tsx +++ b/packages/client/src/modules/play/Personalization/models/form.tsx @@ -1,6 +1,8 @@ import { range } from "lodash"; import { buildChoices } from "../utils/choices"; +export type FormStatus = "draft" | "pendingValidation" | "validated"; + export const persoFormInputs = [ "numberAdults", "numberKids", diff --git a/packages/client/src/modules/translations/fr.json b/packages/client/src/modules/translations/fr.json index 8d3d686a..25bdeac8 100644 --- a/packages/client/src/modules/translations/fr.json +++ b/packages/client/src/modules/translations/fr.json @@ -96,5 +96,14 @@ "step.production-2.name": "Étape 4", "step.production-2.title": "Choix de production 2", "step.production-3.name": "Étape 5", - "step.production-3.title": "Choix de production 3" + "step.production-3.title": "Choix de production 3", + + "form.status.draft": "Brouillon", + "form.status.pendingValidation": "Transmis à l'animateur - En attente de validation", + "form.status.validated": "Validé", + + "form.last-action.draft": "Dernière sauvegarde", + "form.last-action.pendingValidation": "Dernier envoi à l'animateur", + "form.last-action.validated": "Validation" + } diff --git a/packages/server/prisma/migrations/20230104093231_add_last_status_form_update/migration.sql b/packages/server/prisma/migrations/20230104093231_add_last_status_form_update/migration.sql new file mode 100644 index 00000000..9ad78c5b --- /dev/null +++ b/packages/server/prisma/migrations/20230104093231_add_last_status_form_update/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Profile" ADD COLUMN "lastStatusUpdate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; diff --git a/packages/server/prisma/schema.prisma b/packages/server/prisma/schema.prisma index 10987ca0..e8769fbe 100644 --- a/packages/server/prisma/schema.prisma +++ b/packages/server/prisma/schema.prisma @@ -74,6 +74,7 @@ model Profile { personalization Personalization @relation(fields: [personalizationId], references: [id]) personalizationId Int status ProfileStatus @default(draft) + lastStatusUpdate DateTime @default(now()) } enum ProfileStatus { diff --git a/packages/server/src/modules/players/services/index.ts b/packages/server/src/modules/players/services/index.ts index 011a5079..b9e11ac4 100644 --- a/packages/server/src/modules/players/services/index.ts +++ b/packages/server/src/modules/players/services/index.ts @@ -98,6 +98,7 @@ async function setDefaultProfiles( data: { personalizationId: defaultPersonalization.id, status: "validated", + lastStatusUpdate: new Date(), }, }); await model.update({ @@ -134,6 +135,7 @@ async function validateProfiles(gameId: number): Promise { }, data: { status: "validated", + lastStatusUpdate: new Date(), }, }); } diff --git a/packages/server/src/modules/profiles/types/index.ts b/packages/server/src/modules/profiles/types/index.ts index c0489de4..de21de4b 100644 --- a/packages/server/src/modules/profiles/types/index.ts +++ b/packages/server/src/modules/profiles/types/index.ts @@ -7,4 +7,5 @@ interface Profile { personalization: Personalization; personalizationId: number; status: ProfileStatus; + lastStatusUpdate: Date; } diff --git a/packages/server/src/modules/websocket/eventHandlers/updateProfileHandler.ts b/packages/server/src/modules/websocket/eventHandlers/updateProfileHandler.ts index ee490762..2981ea4a 100644 --- a/packages/server/src/modules/websocket/eventHandlers/updateProfileHandler.ts +++ b/packages/server/src/modules/websocket/eventHandlers/updateProfileHandler.ts @@ -80,12 +80,14 @@ function handleUpdateProfile(io: Server, socket: Socket) { await update(personalizationId, personalizationData); await profileServices.update(player?.profileId, { status: profileStatus as ProfileStatus, + lastStatusUpdate: new Date(), }); } else { const personalization = await create(personalizationData); const profile = await profileServices.create({ personalizationId: personalization.id, status: profileStatus as ProfileStatus, + lastStatusUpdate: new Date(), }); await playersServices.update(gameId, userId, { profileId: profile?.id,