Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Franklinjaradev/ttp 24 patient can message care team #8

Merged
merged 11 commits into from
Dec 5, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import * as z from "zod";

import { Button } from "@acme/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@acme/ui/form";
import { Input } from "@acme/ui/input";
import { toast } from "@acme/ui/use-toast";

const CreateMessage = () => {
const FormSchema = z.object({
status: z.string().min(2, {
message: "Status must be at least 2 characters.",
}),
recipient: z.string().min(2, {
message: "Recipient must be at least 2 characters.",
}),
sender: z.string().min(2, {
message: "Sender must be at least 2 characters.",
}),
payload: z.string().min(2, {
message: "Payload must be at least 2 characters.",
}),
});

const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
status: "unknown",
recipient: "",
},
});

function onSubmit(data: z.infer<typeof FormSchema>) {
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
</pre>
),
});
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
);
};

export default CreateMessage;
24 changes: 24 additions & 0 deletions apps/nextjs/src/app/(authenticated)/messages/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react";
import Link from "next/link";

export default function MessagesLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<header className="mx-auto flex w-full max-w-3xl items-center justify-between border-b border-gray-200 bg-white px-4 py-6 sm:px-6">
<div className="flex items-center">
<Link href="/">
<h1>Logo</h1>
</Link>
</div>
<div className="ml-10 flex items-baseline space-x-4">Get Help</div>
</header>
<main className="container col-span-1 mx-auto flex items-center justify-center px-4 md:col-span-1 xl:col-span-2">
{children}
</main>
</>
);
}
5 changes: 5 additions & 0 deletions apps/nextjs/src/app/(authenticated)/messages/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { api } from "~/trpc/react";

export default async function MessagesPage() {
return <div></div>;
}
112 changes: 112 additions & 0 deletions apps/nextjs/src/app/(authenticated)/patient/[patientId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@acme/ui/card";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@acme/ui/table";

import CreateMessage from "~/components/communication/create-message";
import { api } from "~/trpc/server";

export const runtime = "edge";

const PatientIdPage = async ({ params }: { params: { patientId: string } }) => {
const patient = await api.canvas.getPatient.query({
path: {
patient_id: params.patientId,
},
});

const listReceivedMsgs = await api.communication.searchRecipientMsgs.query({
query: {
recipient: params.patientId,
},
});

const listSendMsgs = await api.communication.searchSenderMsgs.query({
query: {
sender: params.patientId,
},
});

return (
<Card className="w-full">
<CardHeader>
<CardTitle>{patient?.name![0]?.given![0]}</CardTitle>
<CardDescription>Id: {patient.id}</CardDescription>
</CardHeader>
<CardContent>
<CreateMessage type="Patient" sender={patient.id!} />
</CardContent>
<CardContent>
<CardHeader>
<CardTitle>Messages Received</CardTitle>
</CardHeader>
<Table>
<TableCaption>A list of your recent messages received.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Created At</TableHead>
<TableHead>Received At</TableHead>
<TableHead>Recipient</TableHead>
<TableHead>Payload</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{listReceivedMsgs.entry.map((msg, i) => (
<TableRow key={i}>
<TableCell>{msg.resource.sent}</TableCell>
<TableCell>
{msg.resource.received ?? "No received yet"}
</TableCell>
<TableCell>{msg.resource.recipient[0]?.reference}</TableCell>
<TableCell>{msg.resource.payload[0]?.contentString}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
<CardContent>
<CardHeader>
<CardTitle>Messages Sent</CardTitle>
</CardHeader>
<Table>
<TableCaption>A list of your recent messages sent.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Created At</TableHead>
<TableHead>Received At</TableHead>
<TableHead>Recipient</TableHead>
<TableHead>Payload</TableHead>
<TableHead>Read</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{listSendMsgs.entry.map((msg, i) => (
<TableRow key={i}>
<TableCell>{msg.resource.sent}</TableCell>
<TableCell>
{msg.resource.received ?? "No received yet"}
</TableCell>
<TableCell>{msg.resource.recipient[0]?.reference}</TableCell>
<TableCell>{msg.resource.payload[0]?.contentString}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
);
};

export default PatientIdPage;
16 changes: 16 additions & 0 deletions apps/nextjs/src/app/(authenticated)/patient/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Header from "~/components/header";

export default function PatientLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex flex-col gap-4">
<Header />
<main className="container col-span-1 mx-auto flex items-center justify-center px-4 md:col-span-1 xl:col-span-2">
{children}
</main>
</div>
);
}
5 changes: 5 additions & 0 deletions apps/nextjs/src/app/(authenticated)/patient/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const PatientPage = () => {
return <div>PatientPage</div>;
};

export default PatientPage;
18 changes: 15 additions & 3 deletions apps/nextjs/src/app/(landing)/_components/patient.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
"use client";

import Link from "next/link";

import { Button } from "@acme/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@acme/ui/card";

import { api } from "~/trpc/react";

export function Patient() {
Expand All @@ -18,8 +23,15 @@ export function Patient() {
}

return (
<div>
<p>{data?.name?.[0]?.family ?? ""}</p>
</div>
<Card>
<CardHeader>
<CardTitle>{data?.name?.[0]?.family ?? ""}</CardTitle>
</CardHeader>
<CardContent>
<Link href={`patient/${data.id}`}>
<Button>View Patient</Button>
</Link>
</CardContent>
</Card>
);
}
Loading
Loading