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

Questionnaire and valueset list view enhancement #10712

Merged
merged 32 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4ba8831
selected Facility state changed to null
Rishith25 Feb 16, 2025
39fbd97
Merge branch 'develop' of github.com:ohcnetwork/care_fe into develop
Rishith25 Feb 18, 2025
5c7db7e
Merge branch 'develop' of github.com:ohcnetwork/care_fe into develop
Rishith25 Feb 18, 2025
ac1f7ed
Merge branch 'develop' of https://github.com/Rishith25/care_fe into d…
Rishith25 Feb 18, 2025
0333ed8
Merge branch 'develop' of github.com:ohcnetwork/care_fe into develop
Rishith25 Feb 18, 2025
f683f85
Merge branch 'develop' of github.com:ohcnetwork/care_fe into develop
Rishith25 Feb 18, 2025
ca98e14
Merge branch 'develop' of github.com:ohcnetwork/care_fe into develop
Rishith25 Feb 20, 2025
c3271da
Merge branch 'ohcnetwork:develop' into develop
Rishith25 Feb 20, 2025
1444c2c
Merge branch 'develop' of https://github.com/Rishith25/care_fe into d…
Rishith25 Feb 20, 2025
ad8a63b
Refactor: QuestionnaireList and ValueSetList to use cards for mobile …
Rishith25 Feb 20, 2025
c6aa8a8
Fix: Remove inactive status styling from ValueSetList component
Rishith25 Feb 20, 2025
ed93f99
Fix: Update inactive status styling in ValueSetList component
Rishith25 Feb 20, 2025
015f280
Fix: Simplify onClick handler in ValueSetList component
Rishith25 Feb 20, 2025
85cb541
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 20, 2025
0ac67aa
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 21, 2025
ccba09b
refactor: update table components for Questionnaire and ValueSet lists
Rishith25 Feb 21, 2025
ebee568
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 22, 2025
00d614e
feat: enhance QuestionnaireList with responsive card and table views
Rishith25 Feb 22, 2025
e621bd9
add CareIcon to ValueSetList edit buttons
Rishith25 Feb 22, 2025
af82ad1
update button styles and improve description layout
Rishith25 Feb 22, 2025
7c162cd
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 25, 2025
f3bef27
Update badge styles and translations for questionnaire and valueset s…
Rishith25 Feb 25, 2025
b06c84c
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 27, 2025
cee0724
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 27, 2025
982cde5
Add tooltips for long questionnaire and value set titles
Rishith25 Feb 27, 2025
cb2cbd9
Merge branch 'extra-vertical-scrollbar' of https://github.com/Rishith…
Rishith25 Feb 27, 2025
3264b53
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 27, 2025
da7e51c
RenderCard and RenderTable outside the component
Rishith25 Feb 27, 2025
82e7dc3
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 28, 2025
859d16e
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Feb 28, 2025
f71de48
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Mar 4, 2025
e8b9fb1
Merge branch 'develop' into extra-vertical-scrollbar
Rishith25 Mar 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/Routers/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@ import { usePluginRoutes } from "@/hooks/useCareApps";

import ConsultationRoutes from "@/Routers/routes/ConsultationRoutes";
import FacilityRoutes from "@/Routers/routes/FacilityRoutes";
import OrganizationRoutes from "@/Routers/routes/OrganizationRoutes";
import PatientRoutes from "@/Routers/routes/PatientRoutes";
import ResourceRoutes from "@/Routers/routes/ResourceRoutes";
import ScheduleRoutes from "@/Routers/routes/ScheduleRoutes";
import UserRoutes from "@/Routers/routes/UserRoutes";
import AdminRoutes from "@/Routers/routes/adminRoutes";
import { PermissionProvider } from "@/context/PermissionContext";
import { PlugConfigEdit } from "@/pages/Apps/PlugConfigEdit";
import { PlugConfigList } from "@/pages/Apps/PlugConfigList";
import UserDashboard from "@/pages/UserDashboard";

import OrganizationRoutes from "./routes/OrganizationRoutes";
import AdminRoutes from "./routes/adminRoutes";

// List of paths where the sidebar should be hidden
const PATHS_WITHOUT_SIDEBAR = ["/", "/session-expired"];

Expand Down
2 changes: 1 addition & 1 deletion src/components/Medicine/MedicationRequestTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export default function MedicationRequestTable({
) : searchQuery && !displayedMedications.length ? (
<EmptyState searching searchQuery={searchQuery} />
) : (
<ScrollArea className="h-[calc(100vh-16rem)]">
<ScrollArea className="h-fit">
<div className="min-w-[800px]">
<div className="p-2">
<MedicationsTable medications={displayedMedications} />
Expand Down
250 changes: 201 additions & 49 deletions src/components/Questionnaire/QuestionnaireList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,220 @@ import {
} from "lucide-react";
import { useNavigate } from "raviger";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";

import useFilters from "@/hooks/useFilters";

import query from "@/Utils/request/query";
import { QuestionnaireDetail } from "@/types/questionnaire/questionnaire";
import questionnaireApi from "@/types/questionnaire/questionnaireApi";

const RenderCard = ({
questionnaireList,
}: {
questionnaireList: QuestionnaireDetail[];
}) => {
const navigate = useNavigate();
return (
<div className="xl:hidden space-y-4">
{questionnaireList?.length > 0 ? (
questionnaireList.map((questionnaire: QuestionnaireDetail) => (
<Card
key={questionnaire.id}
className="overflow-hidden bg-white rounded-lg cursor-pointer transition-shadow transform hover:shadow-lg"
onClick={() =>
navigate(`/admin/questionnaire/${questionnaire.slug}/edit`)
}
>
<CardContent className="p-6 relative flex flex-col">
<div className="absolute top-4 right-4">
<Badge
className={
{
active: "bg-green-100 text-green-800 hover:bg-green-200",
draft:
"bg-yellow-100 text-yellow-800 hover:bg-yellow-200",
retired: "bg-red-100 text-red-800 hover:bg-red-200",
}[questionnaire.status]
}
>
{t(questionnaire.status)}
</Badge>
</div>

<div className="mb-4 border-b pb-2">
<h3 className="text-left text-xs font-medium uppercase tracking-wider text-gray-500">
{t("title")}
</h3>
{questionnaire.title && questionnaire.title.length > 20 ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="truncate">
<p className="mt-2 text-xl text-left font-bold text-gray-900 truncate">
{questionnaire.title}
</p>
</TooltipTrigger>
<TooltipContent className="bg-black text-white z-40">
{questionnaire.title}
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : (
<p className="mt-2 text-xl text-left font-bold text-gray-900 truncate">
{questionnaire.title}
</p>
)}
</div>

<div className="mb-4">
<h3 className="text-left text-xs font-medium uppercase tracking-wider text-gray-500">
{t("slug")}
</h3>
<p className="text-sm text-gray-900 truncate">
{questionnaire.slug}
</p>
</div>

<div className="mb-4 flex-1">
<h3 className="text-left text-xs font-medium uppercase tracking-wider text-gray-500">
{t("description")}
</h3>
<p className="text-sm text-gray-900 line-clamp-2">
{questionnaire.description}
</p>
</div>

<div className="mt-4 flex justify-end">
<Button
variant="outline"
size="sm"
onClick={(e) => {
e.stopPropagation();
navigate(`/admin/questionnaire/${questionnaire.slug}/edit`);
}}
className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
>
<EyeIcon className="w-4 h-4 mr-1" />
{t("View")}
</Button>
</div>
</CardContent>
</Card>
))
) : (
<div className="py-6 text-center text-gray-500">
{t("no_questionnaires_found")}
</div>
)}
</div>
);
};

const RenderTable = ({
questionnaireList,
}: {
questionnaireList: QuestionnaireDetail[];
}) => {
const navigate = useNavigate();
return (
<div className="hidden xl:block overflow-hidden rounded-lg bg-white shadow overflow-x-auto">
<Table className="min-w-full divide-y divide-gray-200">
<TableHeader className="bg-gray-100 text-gray-700">
<TableRow>
<TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
{t("title")}
</TableHead>
<TableHead className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
{t("description")}
</TableHead>
</TableRow>
</TableHeader>
<TableBody className="divide-y divide-gray-200 bg-white">
{questionnaireList?.length > 0 ? (
questionnaireList.map((questionnaire: QuestionnaireDetail) => (
<TableRow
key={questionnaire.id}
className="cursor-pointer hover:bg-gray-50"
onClick={() =>
navigate(`/admin/questionnaire/${questionnaire.slug}/edit`)
}
>
<TableCell className="px-6 py-2">
{questionnaire.title && questionnaire.title.length > 20 ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<span className="text-sm text-left font-semibold text-gray-950 truncate">
{questionnaire.title}
</span>
</TooltipTrigger>
<TooltipContent className="bg-black text-white z-40">
{questionnaire.title}
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : (
<span className="text-sm text-left font-semibold text-gray-950 truncate">
{questionnaire.title}
</span>
)}
</TableCell>
<TableCell className="px-6 py-2">
<div className="flex items-center justify-between space-x-4">
<div className="truncate text-sm text-gray-900 break-words whitespace-normal">
{questionnaire.description}
</div>
<Button
variant="outline"
size="sm"
className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
>
<EyeIcon className="w-4 h-4 mr-0" />
{t("View")}
</Button>
</div>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={3} className="text-center py-4">
{t("no_questionnaires_found")}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
);
};

export function QuestionnaireList() {
const navigate = useNavigate();

const { qParams, updateQuery, Pagination, resultsPerPage } = useFilters({
limit: 15,
disableCache: true,
});

const navigate = useNavigate();

const { data: response } = useQuery({
queryKey: ["questionnaires", qParams],
queryFn: query(questionnaireApi.list, {
Expand All @@ -44,7 +240,7 @@ export function QuestionnaireList() {

return (
<div className="container mx-auto px-4 py-6">
<div className="mb-4 ">
<div className="mb-4">
<div className="mb-2">
<h1 className="text-2xl font-bold">{t("questionnaire_other")}</h1>
<p className="text-gray-600">{t("manage_and_view_questionnaires")}</p>
Expand Down Expand Up @@ -93,52 +289,8 @@ export function QuestionnaireList() {
</div>
</div>

<div className="overflow-hidden rounded-lg bg-white shadow overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200 ">
<thead className="bg-gray-100 text-gray-700">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium tracking-wider ">
{t("title")}
</th>
<th className="px-6 py-3 text-left text-xs font-medium tracking-wider ">
{t("description")}
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200 bg-white">
{questionnaireList.map((questionnaire: QuestionnaireDetail) => (
<tr
key={questionnaire.id}
onClick={() =>
navigate(`/admin/questionnaire/${questionnaire.slug}/edit`)
}
className="cursor-pointer hover:bg-gray-50"
>
<td className="px-6 py-2">
<div className="text-sm font-semibold text-gray-950">
{questionnaire.title}
</div>
</td>
<td className="px-6 py-2">
<div className="flex items-center justify-between space-x-4">
<div className="w-full text-sm text-gray-950">
{questionnaire.description}
</div>
<Button
variant="outline"
size="sm"
className="font-semibold shadow-gray-300 text-gray-950 border-gray-400"
>
<EyeIcon className="w-4 h-4 mr-0" />
{t("View")}
</Button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<RenderTable questionnaireList={questionnaireList} />
<RenderCard questionnaireList={questionnaireList} />
<Pagination totalCount={response?.count ?? 0} />
</div>
);
Expand Down
Loading
Loading