Skip to content

Commit f424fd4

Browse files
committed
updates
1 parent 741e876 commit f424fd4

File tree

9 files changed

+215
-29
lines changed

9 files changed

+215
-29
lines changed

pnpm-lock.yaml

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/(dashboard)/patients/[id]/actions.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"use server";
22

33
import { BinaryPatchData, pushResourceBundle } from "@/lib/fhir/bundle";
4-
import { fetchCarePlan } from "./fetch";
4+
import { createDetails, fetchCarePlan } from "./fetch";
55
import {
66
CarePlanData,
77
CarePlanDataActivity,
88
} from "../../../../lib/models/types";
99
import { fhirR4 } from "@smile-cdr/fhirts";
1010
import { mapCarePlanToTask } from "@/lib/fhir/tasks";
1111
import { createJsonPatchUpdate } from "@/lib/utils";
12+
import { fhirServer } from "@/lib/api/axios";
1213

1314
export const fixTasks = async (formData: FormData) => {
1415
const resourcesToUpdate: (fhirR4.Resource | BinaryPatchData)[] = [];
@@ -30,7 +31,6 @@ export const fixTasks = async (formData: FormData) => {
3031
const task = creatNewTask(data.careplan, activity);
3132
resourcesToUpdate.push(task);
3233
} else {
33-
3434
if (!activity.isTaskAndCarePlanSameStatus && activity.taskReference) {
3535
activity.taskStatus = mapCarePlanToTask(
3636
activity.carePlanActivityStatus
@@ -80,6 +80,33 @@ export const fixTasks = async (formData: FormData) => {
8080
return refetchedCarePlan?.carePlanData;
8181
};
8282

83+
export const fetchCarePlanVersion = async (
84+
id: string,
85+
version: number
86+
): Promise<CarePlanData | null> => {
87+
try {
88+
const res = await fhirServer.get(`/CarePlan/${id}/_history/${version}`);
89+
return await createDetails(id, res.data);
90+
} catch (error) {
91+
console.log(error);
92+
return null;
93+
}
94+
};
95+
96+
export const setCurrentVersion = async (
97+
id: string,
98+
version: number
99+
): Promise<CarePlanData | null> => {
100+
try {
101+
const res = await fhirServer.get(`/CarePlan/${id}/_history/${version}`);
102+
await fhirServer.put(`/CarePlan/${id}`, res.data);
103+
return await createDetails(id, res.data);
104+
} catch (error) {
105+
console.log(error);
106+
return null;
107+
}
108+
};
109+
83110
const creatNewTask = (
84111
carePlan: CarePlanData,
85112
activity: CarePlanDataActivity

src/app/(dashboard)/patients/[id]/fetch.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ export const fetchCarePlan = async (
3636
}
3737
};
3838

39-
const createDetails = async (
39+
40+
export const createDetails = async (
4041
patienyId: string,
4142
carePlan: fhirR4.CarePlan
4243
): Promise<CarePlanData> => {
4344
const tasks = await getTasksFromCarePlan(carePlan);
44-
return {
45+
const plan: CarePlanData = {
4546
id: carePlan.id ?? "",
47+
version: Number.parseInt(carePlan.meta?.versionId ?? "1"),
4648
author: carePlan.author?.display,
4749
tags: carePlan?.meta?.tag ?? [],
4850
title: carePlan.title,
@@ -56,6 +58,7 @@ const createDetails = async (
5658
"https://d-tree.org/fhir/care-plan-visit-number"
5759
)?.coding?.[0].code ?? "NA",
5860
};
61+
return plan;
5962
};
6063

6164
const getTasksFromCarePlan = async (

src/app/(dashboard)/patients/[id]/page.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { CarePlanContainer } from "./components/careplanContainer";
2-
import { fixTasks } from "./actions";
1+
import { fetchCarePlanVersion, fixTasks, setCurrentVersion } from "./actions";
32
import { fetchCarePlan } from "./fetch";
43
import { CarePlanData } from "../../../../lib/models/types";
54
import { fhirServer } from "@/lib/api/axios";
@@ -12,6 +11,7 @@ import { fhirR4 } from "@smile-cdr/fhirts";
1211
import Duplicates from "./components/duplicates";
1312
import PatientInfo from "./components/patientInfo";
1413
import Link from "next/link";
14+
import CareplanViewer from "@/components/careplan/careplan-viewer";
1515

1616
export const maxDuration = 60;
1717

@@ -64,7 +64,12 @@ export default async function Page({ params }: { params: { id: string } }) {
6464
<TabPanels className="mt-3">
6565
<TabPanel key="general" className="rounded-xl bg-white/5 p-3">
6666
{carePlan && (
67-
<CarePlanContainer data={carePlan} action={fixTasks} />
67+
<CareplanViewer
68+
data={carePlan}
69+
fixCarePlan={fixTasks}
70+
toVersion={fetchCarePlanVersion}
71+
setCurrentVersion={setCurrentVersion}
72+
/>
6873
)}
6974
{!carePlan && (
7075
<div className="flex flex-col gap-4 w-full p-8">

src/app/layout.tsx

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
1-
import './globals.css'
2-
import type { Metadata } from 'next'
3-
import { Inter } from 'next/font/google'
1+
import ReactQueryProvider from "@/providers/reatc-query";
2+
import "./globals.css";
3+
import type { Metadata } from "next";
4+
import { Inter } from "next/font/google";
45

5-
const inter = Inter({ subsets: ['latin'] })
6+
const inter = Inter({ subsets: ["latin"] });
67

78
export const metadata: Metadata = {
8-
title: 'Create Next App',
9-
description: 'Generated by create next app',
10-
}
9+
title: "Create Next App",
10+
description: "Generated by create next app",
11+
};
1112

1213
export default function RootLayout({
1314
children,
1415
}: {
15-
children: React.ReactNode
16+
children: React.ReactNode;
1617
}) {
1718
return (
1819
<html lang="en" data-theme="cupcake">
19-
<body className={inter.className + ""}>{children}</body>
20+
<body className={inter.className + ""}>
21+
<ReactQueryProvider>{children}</ReactQueryProvider>
22+
</body>
2023
</html>
21-
)
24+
);
2225
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"use client";
2+
3+
import { CarePlanData } from "@/lib/models/types";
4+
import React from "react";
5+
import { CarePlanContainer } from "./careplanContainer";
6+
7+
type Props = {
8+
data: CarePlanData;
9+
fixCarePlan: (data: FormData) => Promise<any>;
10+
toVersion: (id: string, version: number) => Promise<CarePlanData | null>;
11+
setCurrentVersion: (
12+
id: string,
13+
version: number
14+
) => Promise<CarePlanData | null>;
15+
};
16+
17+
const CareplanViewer = ({
18+
toVersion,
19+
setCurrentVersion,
20+
data,
21+
fixCarePlan,
22+
}: Props) => {
23+
const [carePlan, setCarePlan] = React.useState(data);
24+
const [loading, setLoading] = React.useState(false);
25+
const [error, setError] = React.useState(false);
26+
27+
const changeVersion = async (
28+
action: () => Promise<CarePlanData | null>,
29+
reload: boolean = false
30+
) => {
31+
try {
32+
setError(false);
33+
setLoading(true);
34+
const newCarePlan = await action();
35+
if (newCarePlan == null) {
36+
throw new Error("Could not fetch care plan");
37+
}
38+
setCarePlan(newCarePlan);
39+
setLoading(false);
40+
setError(false);
41+
if (reload) {
42+
window.location.reload();
43+
}
44+
} catch (error) {
45+
console.error(error);
46+
setError(true);
47+
}
48+
};
49+
50+
if (error) {
51+
return <div>Something went wrong</div>;
52+
}
53+
54+
if (loading) {
55+
return <div>Loading...</div>;
56+
}
57+
58+
return (
59+
<CarePlanContainer
60+
data={carePlan}
61+
action={fixCarePlan}
62+
latestVersion={data.version}
63+
toVersion={(version) => {
64+
changeVersion(async () => {
65+
return await toVersion(data.id, version);
66+
});
67+
}}
68+
setCurrentVersion={(version) => {
69+
changeVersion(async () => {
70+
return await setCurrentVersion(data.id, version);
71+
}, true);
72+
}}
73+
/>
74+
);
75+
};
76+
77+
export default CareplanViewer;

src/app/(dashboard)/patients/[id]/components/careplanContainer.tsx src/components/careplan/careplanContainer.tsx

+59-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,23 @@
22

33
import { CarePlanData, CarePlanDataActivity } from "@/lib/models/types";
44
import { useEffect, useState } from "react";
5+
import { Button } from "../ui/button";
56

67
type Props = {
78
action: (data: FormData) => Promise<any>;
9+
toVersion: (version: number) => void;
810
data: CarePlanData;
11+
latestVersion: number;
12+
setCurrentVersion: (version: number) => void;
913
};
1014

11-
export const CarePlanContainer = ({ data, action }: Props) => {
15+
export const CarePlanContainer = ({
16+
data,
17+
action,
18+
toVersion,
19+
latestVersion,
20+
setCurrentVersion,
21+
}: Props) => {
1222
const [careplan, setCarePlan] = useState<CarePlanData>(data);
1323
const [items, setItems] = useState<CarePlanDataActivity[]>();
1424
const [selectFix, setSelectFix] = useState<boolean>(false);
@@ -95,7 +105,17 @@ export const CarePlanContainer = ({ data, action }: Props) => {
95105
</div>
96106
)}
97107
<div className="flex flex-col gap-4">
98-
<div>{careplan && <CarePlanSummary careplan={careplan} />}</div>
108+
<div>
109+
{careplan && (
110+
<CarePlanSummary
111+
careplan={careplan}
112+
lastestVersion={latestVersion}
113+
setCurrentVersion={setCurrentVersion}
114+
previous={() => toVersion(careplan.version - 1)}
115+
next={() => toVersion(careplan.version + 1)}
116+
/>
117+
)}
118+
</div>
99119
<h5 className="scroll-m-20 text-4xl font-bold tracking-tight">Tasks</h5>
100120
{careplan.activities?.map((activity: CarePlanDataActivity) => {
101121
return (
@@ -170,12 +190,47 @@ export const CarePlanContainer = ({ data, action }: Props) => {
170190
);
171191
};
172192

173-
const CarePlanSummary = ({ careplan }: { careplan: CarePlanData }) => {
193+
const CarePlanSummary = ({
194+
careplan,
195+
lastestVersion,
196+
previous,
197+
next,
198+
setCurrentVersion,
199+
}: {
200+
careplan: CarePlanData;
201+
lastestVersion: number;
202+
previous: () => void;
203+
next: () => void;
204+
setCurrentVersion: (version: number) => void;
205+
}) => {
174206
return (
175207
<div>
176208
<details className="collapse bg-base-200">
177209
<summary className="collapse-title text-xl font-medium">
178-
View Care Plan Details
210+
<div className="flex flex-row justify-between w-full items-center">
211+
<span>View Care Plan Details</span>
212+
<div className="flex flex-row gap-2 items-center">
213+
{careplan.version != lastestVersion && (
214+
<Button onClick={() => setCurrentVersion(careplan.version)}>
215+
Set as Current version
216+
</Button>
217+
)}
218+
{careplan.version > 1 && (
219+
<Button variant="link" onClick={previous}>
220+
{" "}
221+
{"< "} Previous
222+
</Button>
223+
)}
224+
<span className="badge badge-primary">
225+
Version: {careplan.version}
226+
</span>
227+
{careplan.version < lastestVersion && (
228+
<Button variant="link" onClick={next}>
229+
Next {" >"}
230+
</Button>
231+
)}
232+
</div>
233+
</div>
179234
</summary>
180235
<div className="collapse-content">
181236
<h6>{careplan.title}</h6>

src/lib/models/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { fhirR4 } from "@smile-cdr/fhirts";
22

33
export type CarePlanData = {
44
id: string;
5+
version: number;
56
title?: string;
67
patientId: string;
78
requester?: string;

src/providers/reatc-query.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use client";
2+
3+
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
4+
import { useState } from "react";
5+
6+
const ReactQueryProvider = ({ children }: { children: React.ReactNode }) => {
7+
const [queryClient] = useState(() => new QueryClient());
8+
9+
return (
10+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
11+
);
12+
};
13+
14+
export default ReactQueryProvider;

0 commit comments

Comments
 (0)