Skip to content

Commit a816ac8

Browse files
authored
Merge pull request #6 from wavezync/feat/dod-and-doa
feat: add Date of Admission and Date of Discharge fields to surgeries
2 parents 4c96977 + e2c2f97 commit a816ac8

10 files changed

Lines changed: 144 additions & 26 deletions

File tree

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@
1010
},
1111
"tailwindCSS.experimental.classRegex": [
1212
"class:\\s*?[\"'`]([^\"'`]*).*?,"
13-
]
13+
],
14+
"css.lint.unknownAtRules": "ignore",
15+
"css.validate": false,
16+
"scss.validate": false
1417
}

resources/templates/surgery-opnote.hbs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@
3232
<td class='label'>Ward:</td>
3333
<td>{{surgery.ward}}</td>
3434
</tr>
35+
{{#if surgery.doa}}{{#if surgery.dod}}
36+
<tr>
37+
<td class='label'>DoA:</td>
38+
<td>{{surgery.doa}}</td>
39+
<td class='label'>DoD:</td>
40+
<td>{{surgery.dod}}</td>
41+
</tr>
42+
{{/if}}{{/if}}
43+
{{#if surgery.doa}}{{#unless surgery.dod}}
44+
<tr>
45+
<td class='label'>DoA:</td>
46+
<td colspan='3'>{{surgery.doa}}</td>
47+
</tr>
48+
{{/unless}}{{/if}}
49+
{{#unless surgery.doa}}{{#if surgery.dod}}
50+
<tr>
51+
<td class='label'>DoD:</td>
52+
<td colspan='3'>{{surgery.dod}}</td>
53+
</tr>
54+
{{/if}}{{/unless}}
3555
</table>
3656

3757
<!-- Surgery Title -->

src/main/db/migrations.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import * as m_000_init from './migrations/000_init'
22
import * as m_001_app_settings from './migrations/001_app_settings'
33
import * as m_002_telephone_setting from './migrations/002_telephone_setting'
4+
import * as m_003_doa_dod from './migrations/003_doa_dod'
45

56
export default {
67
'000_init': m_000_init,
78
'001_app_settings': m_001_app_settings,
8-
'002_telephone_setting': m_002_telephone_setting
9+
'002_telephone_setting': m_002_telephone_setting,
10+
'003_doa_dod': m_003_doa_dod
911
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { Kysely } from 'kysely'
3+
4+
export async function up(db: Kysely<any>): Promise<void> {
5+
await db.schema
6+
.alterTable('surgeries')
7+
.addColumn('doa', 'integer') // Date of Admission
8+
.execute()
9+
10+
await db.schema
11+
.alterTable('surgeries')
12+
.addColumn('dod', 'integer') // Date of Discharge
13+
.execute()
14+
}
15+
16+
export async function down(db: Kysely<any>): Promise<void> {
17+
await db.schema.alterTable('surgeries').dropColumn('doa').execute()
18+
19+
await db.schema.alterTable('surgeries').dropColumn('dod').execute()
20+
}

src/renderer/src/components/surgery/AddOrEditSurgery.tsx

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ import { DoctorAutoComplete } from '../doctor/DoctorAutoComplete'
1919
import toast from 'react-hot-toast'
2020
import { SurgeryModel } from '../../../../shared/models/SurgeryModel'
2121
import { unwrapResult } from '@renderer/lib/utils'
22+
23+
const toValidDate = (date?: Date | null): Date | null => {
24+
if (!date) return null
25+
return !isNaN(date.getTime()) ? date : null
26+
}
2227
const KBD = ({ children }: { children: React.ReactNode }) => (
2328
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
2429
{children}
@@ -30,6 +35,8 @@ const surgerySchema = z.object({
3035
bht: z.string().min(1, { message: 'BHT is required' }),
3136
ward: z.string().min(1, { message: 'Ward is required' }),
3237
date: z.date().nullable(),
38+
doa: z.date().nullable(),
39+
dod: z.date().nullable(),
3340
doneBy: z.array(z.number()),
3441
assistedBy: z.array(z.number()),
3542
notes: z.string().optional(),
@@ -56,7 +63,9 @@ export const AddOrEditSurgery = forwardRef<AddOrEditSurgeryRef, AddOrEditSurgery
5663
bht: surgery?.bht || '',
5764
title: surgery?.title || '',
5865
ward: surgery?.ward || '',
59-
date: surgery?.date || null,
66+
date: toValidDate(surgery?.date),
67+
doa: toValidDate(surgery?.doa),
68+
dod: toValidDate(surgery?.dod),
6069
assistedBy: surgery?.assistedBy?.map((ab) => ab.id) || [],
6170
doneBy: surgery?.doneBy?.map((db) => db.id) || [],
6271
notes: surgery?.notes || '',
@@ -70,12 +79,14 @@ export const AddOrEditSurgery = forwardRef<AddOrEditSurgeryRef, AddOrEditSurgery
7079
try {
7180
console.log(data)
7281
if (!patientId) throw new Error('Patient ID is required')
73-
const { doneBy, assistedBy, date, ...rest } = data
82+
const { doneBy, assistedBy, date, doa, dod, ...rest } = data
7483

7584
const { result, error } = await window.api.invoke('createNewSurgery', {
7685
...rest,
7786
patient_id: patientId,
78-
date: date ? +date : null
87+
date: date ? +date : null,
88+
doa: doa ? +doa : null,
89+
dod: dod ? +dod : null
7990
})
8091

8192
if (error) throw error
@@ -104,11 +115,13 @@ export const AddOrEditSurgery = forwardRef<AddOrEditSurgeryRef, AddOrEditSurgery
104115
try {
105116
if (!surgery) throw new Error('Surgery is required')
106117

107-
const { doneBy, assistedBy, date, ...rest } = data
118+
const { doneBy, assistedBy, date, doa, dod, ...rest } = data
108119

109120
const { result, error } = await window.api.invoke('updateSurgery', surgery.id, {
110121
...rest,
111-
date: date ? +date : null
122+
date: date ? +date : null,
123+
doa: doa ? +doa : null,
124+
dod: dod ? +dod : null
112125
})
113126

114127
if (error) throw error
@@ -202,7 +215,7 @@ export const AddOrEditSurgery = forwardRef<AddOrEditSurgeryRef, AddOrEditSurgery
202215
)}
203216
/>
204217

205-
<div className="flex flex-col md:flex-row md:items-end md:space-x-2 w-full mt-1">
218+
<div className="flex flex-col md:flex-row md:items-end gap-2 w-full mt-1">
206219
<div className="flex flex-col w-full md:w-1/2">
207220
<FormField
208221
name="bht"
@@ -234,22 +247,48 @@ export const AddOrEditSurgery = forwardRef<AddOrEditSurgeryRef, AddOrEditSurgery
234247
)}
235248
/>
236249
</div>
250+
</div>
237251

238-
<div className="flex flex-col">
239-
<FormField
240-
name="date"
241-
control={form.control}
242-
render={({ field }) => (
243-
<FormItem>
244-
<FormLabel>Surgery Date</FormLabel>
245-
<FormControl>
246-
<DatePicker onSelect={field.onChange} selected={field.value || undefined} />
247-
</FormControl>
248-
<FormMessage />
249-
</FormItem>
250-
)}
251-
/>
252-
</div>
252+
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 w-full mt-2">
253+
<FormField
254+
name="date"
255+
control={form.control}
256+
render={({ field }) => (
257+
<FormItem className="flex flex-col">
258+
<FormLabel>Surgery Date</FormLabel>
259+
<FormControl>
260+
<DatePicker onSelect={field.onChange} selected={field.value || undefined} />
261+
</FormControl>
262+
<FormMessage />
263+
</FormItem>
264+
)}
265+
/>
266+
<FormField
267+
name="doa"
268+
control={form.control}
269+
render={({ field }) => (
270+
<FormItem className="flex flex-col">
271+
<FormLabel>Date of Admission</FormLabel>
272+
<FormControl>
273+
<DatePicker onSelect={field.onChange} selected={field.value || undefined} />
274+
</FormControl>
275+
<FormMessage />
276+
</FormItem>
277+
)}
278+
/>
279+
<FormField
280+
name="dod"
281+
control={form.control}
282+
render={({ field }) => (
283+
<FormItem className="flex flex-col">
284+
<FormLabel>Date of Discharge</FormLabel>
285+
<FormControl>
286+
<DatePicker onSelect={field.onChange} selected={field.value || undefined} />
287+
</FormControl>
288+
<FormMessage />
289+
</FormItem>
290+
)}
291+
/>
253292
</div>
254293

255294
<div className="flex flex-col mt-4">

src/renderer/src/lib/print.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const surgeryPrintData = (
2626
?.map((doctor) => `Dr. ${doctor.name} (${doctor.designation})`)
2727
.join(', '),
2828
date: surgery?.date ? formatDate(surgery?.date) : null,
29+
doa: surgery?.doa ? formatDate(surgery?.doa) : null,
30+
dod: surgery?.dod ? formatDate(surgery?.dod) : null,
2931
notes: isEmptyHtml(surgery?.notes) ? null : surgery?.notes,
3032
post_op_notes: isEmptyHtml(surgery?.post_op_notes) ? null : surgery?.post_op_notes
3133
},

src/renderer/src/lib/utils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ export async function unwrapResult<T>(promise: Promise<{ result: T; error: any }
2121

2222
export const trim = (str: string, len = 20) => (str.length > len ? str.slice(0, len) + '...' : str)
2323

24-
export const formatDate = (date?: Date) => dayjs(date).format('DD/MM/YYYY')
24+
export const formatDate = (date?: Date) => {
25+
const d = dayjs(date)
26+
return d.isValid() ? d.format('DD/MM/YYYY') : ''
27+
}
2528

26-
export const formatDateTime = (date?: Date) => dayjs(date).format('DD/MM/YYYY HH:mm')
29+
export const formatDateTime = (date?: Date) => {
30+
const d = dayjs(date)
31+
return d.isValid() ? d.format('DD/MM/YYYY HH:mm') : ''
32+
}
2733

2834
export const formatTime = (date?: Date) => dayjs(date).format('HH:mm')
2935

src/renderer/src/routes/surgeries/view-surgery.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ export const SurgeryCard = ({ surgery, patient }: SurgeryCardProps) => {
174174
<span className="font-semibold">Date:</span>{' '}
175175
<Badge variant={'secondary'}>{surgery.date ? formatDate(surgery.date) : 'N/A'}</Badge>
176176
</div>
177+
178+
{surgery.doa && (
179+
<div className="md:ml-4">
180+
<span className="font-semibold">DoA:</span>{' '}
181+
<Badge variant={'secondary'}>{formatDate(surgery.doa)}</Badge>
182+
</div>
183+
)}
184+
185+
{surgery.dod && (
186+
<div className="md:ml-4">
187+
<span className="font-semibold">DoD:</span>{' '}
188+
<Badge variant={'secondary'}>{formatDate(surgery.dod)}</Badge>
189+
</div>
190+
)}
177191
</div>
178192

179193
<div className="flex md:flex-row flex-col">

src/shared/models/SurgeryModel.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import { Surgery } from '../types/db'
22
import { DoctorModel } from './DoctorModel'
33
import { PatientModel } from './PatientModel'
44

5+
const toValidDate = (value: unknown): Date | null => {
6+
if (!value) return null
7+
const date = new Date(value as number)
8+
return isNaN(date.getTime()) ? null : date
9+
}
10+
511
export class SurgeryModel implements Surgery {
612
id: number
713
created_at: Date
@@ -10,6 +16,8 @@ export class SurgeryModel implements Surgery {
1016
bht: string
1117
ward: string
1218
date: Date | null
19+
doa: Date | null
20+
dod: Date | null
1321
notes: string | null
1422
post_op_notes: string | null
1523
patient_id: number
@@ -25,7 +33,9 @@ export class SurgeryModel implements Surgery {
2533
this.title = data.title
2634
this.bht = data.bht
2735
this.ward = data.ward
28-
this.date = data.date !== null ? new Date(data.date) : null
36+
this.date = toValidDate(data.date)
37+
this.doa = toValidDate(data.doa)
38+
this.dod = toValidDate(data.dod)
2939
this.notes = data.notes
3040
this.post_op_notes = data.post_op_notes
3141
this.patient_id = data.patient_id

src/shared/types/db.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface SurgeryTable {
2222
bht: string
2323
ward: string
2424
date: ColumnType<Date, number, number> | null
25+
doa: ColumnType<Date, number, number> | null
26+
dod: ColumnType<Date, number, number> | null
2527
notes: string | null
2628
post_op_notes: string | null
2729

0 commit comments

Comments
 (0)