Skip to content

Commit

Permalink
Add public library
Browse files Browse the repository at this point in the history
  • Loading branch information
olimsaidov committed Nov 22, 2024
1 parent e17125b commit b6bf03f
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { PageHeader } from "@/components/page-header";
import { PageSizeSelect } from "@/components/page-size-select";
import Link from "next/link";
import { Search } from "lucide-react";
import { Pager } from "@/components/pager";
import { Bundle, Questionnaire } from "fhir/r4";
import { isDefined } from "@/lib/utils";
import { decidePageSize } from "@/lib/server/utils";
import ky from "ky";

interface PageProps {
searchParams: Promise<{
page?: string;
title?: string;
pageSize?: string;
}>;
}

export default async function PublicLibraryPage({ searchParams }: PageProps) {
const publicLibrary = ky.extend({
prefixUrl: "https://form-builder.aidbox.app",
});
const params = await searchParams;

const pageSize = await decidePageSize(params.pageSize);
const page = Number(params.page) || 1;
const title = params.title || "";

const response = await publicLibrary
.get("fhir/Questionnaire", {
searchParams: {
_count: pageSize,
_page: page,
...(title && { "title:contains": title }),
},
})
.json<Bundle<Questionnaire>>();

const resources =
response.entry?.map((entry) => entry.resource)?.filter(isDefined) || [];

const total = response.total || 0;
const totalPages = Math.ceil(total / pageSize);

return (
<>
<PageHeader
items={[{ href: "/", label: "Home" }, { label: "Questionnaires" }]}
/>
<div className="flex-1 p-6">
<div className="flex gap-2 mb-6">
<form className="flex-1 flex gap-2" action="/questionnaires">
<div className="relative flex-1">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
type="search"
name="title"
placeholder="Search questionnaires by title..."
defaultValue={title}
className="pl-8"
/>
</div>
<Button type="submit">Search</Button>
{title && (
<Button variant="ghost" asChild>
<Link href="/questionnaires">Clear</Link>
</Button>
)}
</form>
</div>

<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>Title</TableHead>
<TableHead>Status</TableHead>
<TableHead>Date</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{resources.map((resource) => (
<TableRow key={resource.id}>
<TableCell>{resource.title}</TableCell>
<TableCell>{resource.status}</TableCell>
<TableCell>{resource.date}</TableCell>
<TableCell>
<Button variant="outline" size="sm" asChild>
<Link href={`/questionnaires/${resource.id}`}>View</Link>
</Button>
</TableCell>
</TableRow>
))}
{!resources.length && (
<TableRow>
<TableCell colSpan={4} className="text-center py-4">
No questionnaires found
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>

<div className="flex items-center justify-between space-x-2 py-4">
<div className="flex items-center gap-4">
{total ? (
<div className="text-sm text-muted-foreground">{`Showing ${
(page - 1) * pageSize + 1
}-${Math.min(
page * pageSize,
total,
)} of ${total} practitioners`}</div>
) : null}
<PageSizeSelect currentSize={pageSize} />
</div>
<Pager currentPage={page} totalPages={totalPages} />
</div>
</div>
</>
);
}
138 changes: 98 additions & 40 deletions aidbox-forms-smart-launch-2/src/components/app-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,122 @@ import * as React from "react";
import {
FileQuestion,
LayoutDashboard,
Library,
LucideIcon,
SquareMenu,
UserCog,
Users,
} from "lucide-react";
import { usePathname } from "next/navigation";

import {
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
} from "@/components/ui/sidebar";
import Link from "next/link";

const data = {
navMain: [
{
title: "Dashboard",
href: "/dashboard",
icon: LayoutDashboard,
},
{
title: "Patients",
href: "/patients",
icon: Users,
},
{
title: "Practitioners",
href: "/practitioners",
icon: UserCog,
},
{
title: "Questionnaires",
href: "/questionnaires",
icon: FileQuestion,
},
{
title: "Questionnaire Responses",
href: "/questionnaire-responses",
icon: SquareMenu,
},
],
};
const data: {
label?: string;
children: {
icon: LucideIcon;
href: string;
title: string;
children?: {
icon: LucideIcon;
href: string;
title: string;
}[];
}[];
}[] = [
{
children: [
{
title: "Dashboard",
href: "/dashboard",
icon: LayoutDashboard,
},
{
title: "Patients",
href: "/patients",
icon: Users,
},
{
title: "Practitioners",
href: "/practitioners",
icon: UserCog,
},
{
title: "Questionnaires",
href: "/questionnaires",
icon: FileQuestion,
},
{
title: "Questionnaire Responses",
href: "/questionnaire-responses",
icon: SquareMenu,
},
],
},
{
label: "Public Library",
children: [
{
title: "Questionnaires",
href: "/public-library/questionnaires",
icon: Library,
},
],
},
];

export function AppMenu() {
const pathname = usePathname();

return (
<SidebarMenu>
{data.navMain.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild isActive={pathname === item.href}>
<Link href={item.href}>
<item.icon className="mr-2 h-4 w-4" />
{item.title}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<>
{data.map((group, index) => (
<SidebarGroup key={index}>
{group.label && <SidebarGroupLabel>{group.label}</SidebarGroupLabel>}
<SidebarGroupContent>
<SidebarMenu>
{group.children.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild isActive={pathname === item.href}>
<Link href={item.href}>
<item.icon className="mr-2 h-4 w-4" />
{item.title}
</Link>
</SidebarMenuButton>
{item.children && (
<SidebarMenuSub>
{item.children.map((child) => (
<SidebarMenuSubItem key={child.title}>
<SidebarMenuSubButton
asChild
isActive={pathname === child.href}
>
<Link href={child.href}>
<child.icon className="mr-2 h-4 w-4" />
{child.title}
</Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
)}
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
))}
</SidebarMenu>
</>
);
}
5 changes: 1 addition & 4 deletions aidbox-forms-smart-launch-2/src/components/app-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
Expand Down Expand Up @@ -43,9 +42,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<AppMenu />
</SidebarGroup>
<AppMenu />
</SidebarContent>
<SidebarFooter>
<PatientCard />
Expand Down
9 changes: 0 additions & 9 deletions aidbox-forms-smart-launch/src/hooks/use-client.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,10 @@ export const defaultScope = [
"patient/QuestionnaireResponse.crus", // Request create, read, update access to QuestionnaireResponse resource
];

const brokenUrl = "https://form-builder.aidbox.app";
const correctUrl = "https://form-builder.aidbox.app/fhir";

export const publicBuilderClient = client(correctUrl);

export const fixPotentialBrokenUrl = (url) => {
if (url.startsWith(brokenUrl) && !url.startsWith(correctUrl)) {
return url.replace(brokenUrl, correctUrl);
}

return url;
};

const clientContext = createContext(null);

export const authorize = (options) => {
Expand Down
7 changes: 2 additions & 5 deletions aidbox-forms-smart-launch/src/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import {
fixPotentialBrokenUrl,
publicBuilderClient,
} from "@/hooks/use-client.jsx";
import { publicBuilderClient } from "@/hooks/use-client.jsx";

export function cn(...inputs) {
return twMerge(clsx(inputs));
Expand Down Expand Up @@ -271,7 +268,7 @@ export async function findQuestionnaireWithClient(client, ref) {
.then((result) => [publicBuilderClient, unbundle(result)]),
client.request(query).then((result) => [client, unbundle(result)]),
publicBuilderClient
.request(fixPotentialBrokenUrl(ref))
.request(ref)
.then((result) => [publicBuilderClient, unbundle(result)]),
]);
}
Expand Down

0 comments on commit b6bf03f

Please sign in to comment.