Skip to content

Commit

Permalink
Style Subscribe to Health Packages
Browse files Browse the repository at this point in the history
  • Loading branch information
mathewhany committed Nov 12, 2023
1 parent ed18089 commit bb476d2
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 142 deletions.
129 changes: 84 additions & 45 deletions backend/src/app/controllers/healthPackage.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import {
UpdateHealthPackageResponse,
type UpdateHealthPackageRequest,
type createHealthPackageRequest,
GetAllHealthPackagesResponse,
GetAllHealthPackagesForPatientResponse,
AddHealthPackageResponse,
GetHealthPackageResponse,
GetHealthPackageForPatientResponse,
GetHealthPackageForPatientRequest,
GetSubscribedHealthPackageForPatientResponse,
GetSubscribedHealthPackageForPatientRequest,
SubscribeToHealthPackageRequest,
GetCancelledHealthPackagesForPatientResponse,
GetAllHealthPackagesForPatientRequest,
GetAllHealthPackagesResponse,
} from 'clinic-common/types/healthPackage.types'
import { asyncWrapper } from '../utils/asyncWrapper'
import {
Expand All @@ -26,6 +29,7 @@ import {
} from '../services/healthPackage.service'
import {
CreateHealthPackageRequestValidator,
GetAllHealthPackagesForPatientRequestValidator,
UpdateHealthPackageRequestValidator,
} from 'clinic-common/validators/healthPackage.validator'
import {
Expand All @@ -36,7 +40,6 @@ import {
import { getPatientByUsername } from '../services/patient.service'
import { APIError, NotFoundError } from '../errors'
import { GetWalletMoneyResponse } from 'clinic-common/types/patient.types'
import { Types } from 'mongoose'
import { FamilyMemberModel } from '../models/familyMember.model'
import { PatientModel } from '../models/patient.model'

Expand Down Expand Up @@ -96,17 +99,46 @@ healthPackagesRouter.get(
asyncWrapper(async (req, res) => {
const healthPackages = await getAllHealthPackages()

res.send({
healthPackages: healthPackages.map((healthPackage) => ({
res.send(
healthPackages.map((healthPackage) => ({
id: healthPackage.id,
name: healthPackage.name,
pricePerYear: healthPackage.pricePerYear,
sessionDiscount: healthPackage.sessionDiscount,
medicineDiscount: healthPackage.medicineDiscount,
familyMemberSubscribtionDiscount:
healthPackage.familyMemberSubscribtionDiscount,
})) satisfies GetAllHealthPackagesResponse
)
})
)

healthPackagesRouter.post(
'/for-patient',
validate(GetAllHealthPackagesForPatientRequestValidator),
asyncWrapper<GetAllHealthPackagesForPatientRequest>(async (req, res) => {
const { patientId, isFamilyMember } = req.body

const healthPackages = await getAllHealthPackages()

const discount = await getDiscount({
subscriberId: patientId,
isFamilyMember,
})

res.send(
healthPackages.map((healthPackage) => ({
id: healthPackage.id,
name: healthPackage.name,
pricePerYear: healthPackage.pricePerYear,
discountedPricePerYear:
healthPackage.pricePerYear - discount * healthPackage.pricePerYear,
sessionDiscount: healthPackage.sessionDiscount,
medicineDiscount: healthPackage.medicineDiscount,
familyMemberSubscribtionDiscount:
healthPackage.familyMemberSubscribtionDiscount,
})),
} satisfies GetAllHealthPackagesResponse)
})) satisfies GetAllHealthPackagesForPatientResponse
)
})
)

Expand Down Expand Up @@ -206,41 +238,45 @@ healthPackagesRouter.patch(
)

healthPackagesRouter.post(
'/for-patient',
asyncWrapper<GetHealthPackageForPatientRequest>(async (req, res) => {
const { patientId, isFamilyMember } = req.body
const patient = isFamilyMember
? await FamilyMemberModel.findById(patientId)
: await PatientModel.findById(patientId)

if (!patient?.healthPackage || !patient.healthPackageRenewalDate) {
res.status(204).send({} satisfies GetHealthPackageForPatientResponse)
} else {
const healthPackage = await getHealthPackageById(
patient.healthPackage.toString()
)
const current = new Date()
const renewal = patient.healthPackageRenewalDate
const months =
(renewal.getFullYear() - current.getFullYear()) * 12 +
renewal.getMonth() -
current.getMonth()

res.send({
healthPackage: {
name: healthPackage.name,
id: healthPackage.id,
pricePerYear: healthPackage.pricePerYear,
sessionDiscount: healthPackage.sessionDiscount,
medicineDiscount: healthPackage.medicineDiscount,
familyMemberSubscribtionDiscount:
healthPackage.familyMemberSubscribtionDiscount,
renewalDate: patient.healthPackageRenewalDate.toDateString(),
remainingMonths: months,
},
} satisfies GetHealthPackageForPatientResponse)
'/subscribed',
asyncWrapper<GetSubscribedHealthPackageForPatientRequest>(
async (req, res) => {
const { patientId, isFamilyMember } = req.body
const patient = isFamilyMember
? await FamilyMemberModel.findById(patientId)
: await PatientModel.findById(patientId)

if (!patient?.healthPackage || !patient.healthPackageRenewalDate) {
res
.status(204)
.send({} satisfies GetSubscribedHealthPackageForPatientResponse)
} else {
const healthPackage = await getHealthPackageById(
patient.healthPackage.toString()
)
const current = new Date()
const renewal = patient.healthPackageRenewalDate
const months =
(renewal.getFullYear() - current.getFullYear()) * 12 +
renewal.getMonth() -
current.getMonth()

res.send({
healthPackage: {
name: healthPackage.name,
id: healthPackage.id,
pricePerYear: healthPackage.pricePerYear,
sessionDiscount: healthPackage.sessionDiscount,
medicineDiscount: healthPackage.medicineDiscount,
familyMemberSubscribtionDiscount:
healthPackage.familyMemberSubscribtionDiscount,
renewalDate: patient.healthPackageRenewalDate.toDateString(),
remainingMonths: months,
},
} satisfies GetSubscribedHealthPackageForPatientResponse)
}
}
})
)
)

healthPackagesRouter.post(
Expand All @@ -255,11 +291,14 @@ healthPackagesRouter.post(
throw new NotFoundError()
}

const cancelled: Types.ObjectId[] = []
const cancelled: GetCancelledHealthPackagesForPatientResponse = {}

model.healthPackageHistory.forEach((healthPackage) => {
cancelled.push(healthPackage.healthPackage)
cancelled[healthPackage.healthPackage.toString()] =
healthPackage.date.toDateString()
})
res.send(cancelled)

res.send(cancelled satisfies GetCancelledHealthPackagesForPatientResponse)
})
)

Expand Down
23 changes: 16 additions & 7 deletions clinic-common/types/healthPackage.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type z } from 'zod'
import {
type UpdateHealthPackageRequestValidator,
type CreateHealthPackageRequestValidator,
GetAllHealthPackagesForPatientRequestValidator,
} from '../validators/healthPackage.validator'

export type createHealthPackageRequest = z.infer<
Expand All @@ -26,26 +27,34 @@ export interface UpdateHealthPackageResponse

export interface AddHealthPackageResponse extends HealthPackageResponseBase {}

export interface GetAllHealthPackagesResponse {
healthPackages: HealthPackageResponseBase[]
}
export type GetAllHealthPackagesForPatientRequest = z.infer<
typeof GetAllHealthPackagesForPatientRequestValidator
>

export type GetAllHealthPackagesForPatientResponse = Array<
HealthPackageResponseBase & {
discountedPricePerYear: number
}
>

export type GetAllHealthPackagesResponse = HealthPackageResponseBase[]

export interface GetHealthPackageResponse extends HealthPackageResponseBase {}

export interface GetHealthPackageForPatientRequest {
export interface GetSubscribedHealthPackageForPatientRequest {
patientId: string // patientId or familyMemberId
isFamilyMember: boolean
}

export interface GetHealthPackageForPatientResponse {
export interface GetSubscribedHealthPackageForPatientResponse {
healthPackage?: HealthPackageResponseBase & {
renewalDate: string
remainingMonths: number
}
}

export interface GetCancelledHealthPackagesForPatientResponse {
healthPackageHistory: [string]
export type GetCancelledHealthPackagesForPatientResponse = {
[id: string]: string // Maps ID of cancelled healthPackage to Date of cancellation
}

export interface SubscribeToHealthPackageRequest {
Expand Down
5 changes: 5 additions & 0 deletions clinic-common/validators/healthPackage.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ export const UpdateHealthPackageRequestValidator = zod.object({
medicineDiscount: zod.number().optional(),
familyMemberSubscribtionDiscount: zod.number().optional(),
})

export const GetAllHealthPackagesForPatientRequestValidator = zod.object({
patientId: zod.string(),
isFamilyMember: zod.boolean(),
})
41 changes: 29 additions & 12 deletions frontend/src/api/healthPackages.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import { api } from '.'
import {
AddHealthPackageResponse,
GetAllHealthPackagesResponse,
GetHealthPackageForPatientRequest,
GetHealthPackageForPatientResponse,
GetAllHealthPackagesForPatientResponse,
GetCancelledHealthPackagesForPatientResponse,
GetSubscribedHealthPackageForPatientRequest,
GetSubscribedHealthPackageForPatientResponse,
GetHealthPackageResponse,
SubscribeToHealthPackageRequest,
UnsubscribeToHealthPackageRequest,
UpdateHealthPackageRequest,
UpdateHealthPackageResponse,
createHealthPackageRequest,
GetAllHealthPackagesForPatientRequest,
GetAllHealthPackagesResponse,
} from 'clinic-common/types/healthPackage.types'

export async function getHealthPackages(): Promise<GetAllHealthPackagesResponse> {
export async function getAllHealthPackagesForPatient(
params: GetAllHealthPackagesForPatientRequest
): Promise<GetAllHealthPackagesForPatientResponse> {
return await api
.post<GetAllHealthPackagesForPatientResponse>(
`/health-packages/for-patient`,
params
)
.then((res) => res.data)
}

export async function getAllHealthPackages(): Promise<GetAllHealthPackagesResponse> {
return await api
.get<GetAllHealthPackagesResponse>(`/health-packages/`)
.get<GetAllHealthPackagesResponse>(`/health-packages`)
.then((res) => res.data)
}

Expand Down Expand Up @@ -77,12 +91,12 @@ export async function unsubscribeToHealthPackage(
.then((res) => res.data)
}

export async function getHealthPackageForPatient(
params: GetHealthPackageForPatientRequest
): Promise<GetHealthPackageForPatientResponse> {
export async function getSubscribedHealthPackageForPatient(
params: GetSubscribedHealthPackageForPatientRequest
): Promise<GetSubscribedHealthPackageForPatientResponse> {
return await api
.post<GetHealthPackageForPatientResponse>(
`/health-packages/for-patient`,
.post<GetSubscribedHealthPackageForPatientResponse>(
`/health-packages/subscribed`,
params
)
.then((res) => res.data)
Expand All @@ -91,9 +105,12 @@ export async function getHealthPackageForPatient(
export async function getCancelledHealthPackagesForPatient(params: {
id: string
isFamilyMember: boolean
}): Promise<string[]> {
}): Promise<GetCancelledHealthPackagesForPatientResponse> {
return await api
.post<string[]>(`/health-packages/patient-cancelled`, params)
.post<GetCancelledHealthPackagesForPatientResponse>(
`/health-packages/patient-cancelled`,
params
)
.then((res) => res.data)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deleteHealthPackage, getHealthPackages } from '@/api/healthPackages'
import { deleteHealthPackage, getAllHealthPackages } from '@/api/healthPackages'
import { CardPlaceholder } from '@/components/CardPlaceholder'
import {
Button,
Expand Down Expand Up @@ -32,7 +32,7 @@ export function HealthPackages() {
const navigate = useNavigate()
const query = useQuery({
queryKey: ['health-packages'],
queryFn: () => getHealthPackages(),
queryFn: () => getAllHealthPackages(),
})
// const { addAlert } = useAlerts()
// const alertScope = useMemo(() => uuidv4(), [])
Expand Down Expand Up @@ -108,7 +108,7 @@ export function HealthPackages() {
Add Health Package
</Button>
</Grid>
{query.data.healthPackages.map((healthPackage) => {
{query.data.map((healthPackage) => {
return (
<Grid item xl={4}>
<Card variant="outlined">
Expand Down
Loading

0 comments on commit bb476d2

Please sign in to comment.