From 465a1132a47fb9b3d7395c7f4b1139f92c36aad4 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bachorski <60391032+arkadiuszbachorski@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:31:22 +0200 Subject: [PATCH] Add birth date to patients and users (#26) # Add birth date to patients and users ## :recycle: Current situation & Problem Patients and users need to have their date of birth set. https://github.com/user-attachments/assets/a5cabc6b-73da-4f2b-92d6-999fab6fcc26 ### Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordBDHG/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordBDHG/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordBDHG/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordBDHG/.github/blob/main/CONTRIBUTING.md). --- app/(dashboard)/patients/PatientForm.tsx | 26 +++++++++-- app/(dashboard)/patients/[id]/page.tsx | 1 + app/(dashboard)/patients/invite/page.tsx | 3 +- app/(dashboard)/users/UserForm.tsx | 21 ++++++++- app/(dashboard)/users/[id]/page.tsx | 5 +- app/(dashboard)/users/invite/page.tsx | 3 +- app/globals.css | 4 ++ modules/firebase/models/baseTypes.ts | 4 +- modules/firebase/utils.ts | 7 +-- .../src/components/Calendar/Calendar.tsx | 5 ++ .../src/components/DatePicker/DatePicker.tsx | 46 ++++++++++--------- 11 files changed, 90 insertions(+), 35 deletions(-) diff --git a/app/(dashboard)/patients/PatientForm.tsx b/app/(dashboard)/patients/PatientForm.tsx index 93c05499..c7aa89b8 100644 --- a/app/(dashboard)/patients/PatientForm.tsx +++ b/app/(dashboard)/patients/PatientForm.tsx @@ -9,6 +9,7 @@ import { z } from 'zod' import { type User } from '@/modules/firebase/utils' import { Button } from '@/packages/design-system/src/components/Button' +import { DatePicker } from '@/packages/design-system/src/components/DatePicker' import { Input } from '@/packages/design-system/src/components/Input' import { Select, @@ -25,10 +26,11 @@ import { } from '@/packages/design-system/src/modules/auth/user' export const patientFormSchema = z.object({ - email: z.string().min(1, 'Email is required'), + email: z.string().email().min(1, 'Email is required'), displayName: z.string(), invitationCode: z.string(), - clinician: z.string(), + clinician: z.string().min(1, 'Clinician is required'), + dateOfBirth: z.date().optional(), }) export type PatientFormSchema = z.infer @@ -40,7 +42,10 @@ interface PatientFormProps { email: string | null }> userInfo?: Pick - user?: Pick + user?: Pick< + User, + 'organization' | 'invitationCode' | 'clinician' | 'dateOfBirth' + > onSubmit: (data: PatientFormSchema) => Promise clinicianPreselectId?: string } @@ -60,6 +65,7 @@ export const PatientForm = ({ displayName: userInfo?.displayName ?? '', invitationCode: user?.invitationCode ?? '', clinician: user?.clinician ?? clinicianPreselectId ?? '', + dateOfBirth: user?.dateOfBirth ? new Date(user.dateOfBirth) : undefined, }, }) @@ -81,6 +87,20 @@ export const PatientForm = ({ label="Display name" render={({ field }) => } /> + ( + field.onChange(date)} + defaultMonth={field.value} + toYear={new Date().getFullYear()} + /> + )} + /> {isEdit && ( { invitationCode: form.invitationCode, clinician: form.clinician, organization: clinician.organization, + dateOfBirth: form.dateOfBirth?.toISOString(), } if (resourceType === 'user') { await callables.updateUserInformation({ diff --git a/app/(dashboard)/patients/invite/page.tsx b/app/(dashboard)/patients/invite/page.tsx index 4ffeb737..e4489a8f 100644 --- a/app/(dashboard)/patients/invite/page.tsx +++ b/app/(dashboard)/patients/invite/page.tsx @@ -31,9 +31,10 @@ const InvitePatientPage = async () => { type: UserType.patient, clinician: form.clinician, organization: clinician.organization, + dateOfBirth: form.dateOfBirth?.toISOString(), }, }) - redirect(routes.patients.patient(result.data.code)) + redirect(routes.patients.patient(result.data.id)) } return ( diff --git a/app/(dashboard)/users/UserForm.tsx b/app/(dashboard)/users/UserForm.tsx index 6f6ffc3d..e93d041b 100644 --- a/app/(dashboard)/users/UserForm.tsx +++ b/app/(dashboard)/users/UserForm.tsx @@ -14,6 +14,7 @@ import { UserType, } from '@/modules/firebase/utils' import { Button } from '@/packages/design-system/src/components/Button' +import { DatePicker } from '@/packages/design-system/src/components/DatePicker' import { Input } from '@/packages/design-system/src/components/Input' import { Select, @@ -28,9 +29,10 @@ import { type UserInfo } from '@/packages/design-system/src/modules/auth/user' export const userFormSchema = z .object({ - email: z.string().min(1, 'Email is required'), + email: z.string().email().min(1, 'Email is required'), displayName: z.string(), invitationCode: z.string(), + dateOfBirth: z.date().optional(), organizationId: z.string().optional(), type: z.nativeEnum(UserType), }) @@ -49,7 +51,7 @@ export type UserFormSchema = z.infer interface UserFormProps { organizations: Array> userInfo?: Pick - user?: Pick + user?: Pick type?: UserType onSubmit: (data: UserFormSchema) => Promise } @@ -74,6 +76,7 @@ export const UserForm = ({ authUser.user.organization : user?.organization, invitationCode: user?.invitationCode ?? '', + dateOfBirth: user?.dateOfBirth ? new Date(user.dateOfBirth) : undefined, }, }) @@ -95,6 +98,20 @@ export const UserForm = ({ label="Display name" render={({ field }) => } /> + ( + field.onChange(date)} + defaultMonth={field.value} + toYear={new Date().getFullYear()} + /> + )} + /> {isEdit && ( { } const userData = { invitationCode: form.invitationCode, - organization: form.organizationId ?? deleteField(), + organization: form.organizationId, type: form.type, + dateOfBirth: form.dateOfBirth?.toISOString(), } if (resourceType === 'user') { await callables.updateUserInformation({ diff --git a/app/(dashboard)/users/invite/page.tsx b/app/(dashboard)/users/invite/page.tsx index e343bdc1..82576d5f 100644 --- a/app/(dashboard)/users/invite/page.tsx +++ b/app/(dashboard)/users/invite/page.tsx @@ -30,9 +30,10 @@ const InviteUserPage = async () => { user: { ...(form.organizationId ? { organization: form.organizationId } : {}), type: form.type, + dateOfBirth: form.dateOfBirth?.toISOString(), }, }) - redirect(routes.users.user(result.data.code)) + redirect(routes.users.user(result.data.id)) } return ( diff --git a/app/globals.css b/app/globals.css index 97043c41..8abf7c23 100644 --- a/app/globals.css +++ b/app/globals.css @@ -41,4 +41,8 @@ SPDX-License-Identifier: MIT .interactive-opacity { @apply focus-ring transition-opacity hover:opacity-60; } + + .hide-all-hidden [aria-hidden="true"] { + display: none; + } } diff --git a/modules/firebase/models/baseTypes.ts b/modules/firebase/models/baseTypes.ts index d4cdca90..85dc6cad 100644 --- a/modules/firebase/models/baseTypes.ts +++ b/modules/firebase/models/baseTypes.ts @@ -34,8 +34,8 @@ export interface FHIRExtension { } export interface FHIRPeriod { - start?: Date - end?: Date + start?: string + end?: string } export interface FHIRRatio { diff --git a/modules/firebase/utils.ts b/modules/firebase/utils.ts index 8936ba6f..27eda0c5 100644 --- a/modules/firebase/utils.ts +++ b/modules/firebase/utils.ts @@ -52,9 +52,9 @@ export enum UserType { export interface User { type: UserType - dateOfBirth?: Date + dateOfBirth?: string | null clinician?: string - dateOfEnrollment?: Date + dateOfEnrollment?: string invitationCode?: string messagesSettings?: UserMessagesSettings organization?: string @@ -199,9 +199,10 @@ export const getCallables = (functions: Functions) => ({ clinician?: string language?: string timeZone?: string + dateOfBirth?: string | null } }, - { code: string } + { id: string } >(functions, 'createInvitation'), getUsersInformation: httpsCallable< GetUsersInformationInput, diff --git a/packages/design-system/src/components/Calendar/Calendar.tsx b/packages/design-system/src/components/Calendar/Calendar.tsx index f0f20383..30df9b49 100644 --- a/packages/design-system/src/components/Calendar/Calendar.tsx +++ b/packages/design-system/src/components/Calendar/Calendar.tsx @@ -23,11 +23,16 @@ export const Calendar = ({ +export type DatePickerProps = ComponentProps -export const DatePicker = ({ selected, ...props }: DatePickerProps) => ( - - - - - - - - -) +export const DatePicker = (props: DatePickerProps) => { + const { selected } = props + return ( + + + + + + + + + ) +}