fix revision hide menu and test case
This commit is contained in:
@@ -1,274 +1,274 @@
|
||||
import { useState } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Users,
|
||||
FileText,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
UserCog,
|
||||
Lock,
|
||||
Database,
|
||||
Shield,
|
||||
TrendingUp,
|
||||
LayoutDashboard,
|
||||
Users,
|
||||
FileText,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
// UserCog,
|
||||
// Lock,
|
||||
Database,
|
||||
Shield,
|
||||
TrendingUp,
|
||||
} from "lucide-react";
|
||||
import { clsx } from "clsx";
|
||||
import claimGuardLogo from "../assets/claim-guard.jpeg";
|
||||
|
||||
interface SidebarProps {
|
||||
isCollapsed?: boolean;
|
||||
onToggleCollapse?: () => void;
|
||||
isCollapsed?: boolean;
|
||||
onToggleCollapse?: () => void;
|
||||
}
|
||||
|
||||
export default function Sidebar({
|
||||
isCollapsed = false,
|
||||
onToggleCollapse,
|
||||
isCollapsed = false,
|
||||
onToggleCollapse,
|
||||
}: SidebarProps) {
|
||||
const location = useLocation();
|
||||
const location = useLocation();
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
title: "Dashboard",
|
||||
icon: LayoutDashboard,
|
||||
path: "/dashboard",
|
||||
color: "text-blue-600",
|
||||
},
|
||||
{
|
||||
title: "Integrasi Data",
|
||||
icon: Database,
|
||||
color: "text-blue-600",
|
||||
submenu: [
|
||||
{
|
||||
title: "Sinkronisasi BPJS",
|
||||
icon: Shield,
|
||||
path: "/integration/bpjs-sync",
|
||||
},
|
||||
{
|
||||
title: "Sinkronisasi Rekam Medis",
|
||||
icon: FileText,
|
||||
path: "/integration/medical-record-sync",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Rekam Medis",
|
||||
icon: Users,
|
||||
color: "text-blue-600",
|
||||
submenu: [
|
||||
{
|
||||
title: "Klinis",
|
||||
icon: FileText,
|
||||
path: "/medical-records/clinical",
|
||||
},
|
||||
{
|
||||
title: "Administratif",
|
||||
icon: FileText,
|
||||
path: "/medical-records/administrative",
|
||||
},
|
||||
{
|
||||
title: "Rekomendasi Biaya",
|
||||
icon: TrendingUp,
|
||||
path: "/medical-records/cost-recommendation",
|
||||
},
|
||||
{
|
||||
title: "Kodefikasi BPJS",
|
||||
icon: FileText,
|
||||
path: "/medical-records/bpjs-codification",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Administrasi Sistem",
|
||||
icon: UserCog,
|
||||
color: "text-blue-600",
|
||||
submenu: [
|
||||
{
|
||||
title: "Pengguna",
|
||||
icon: Users,
|
||||
path: "/system-administration/user",
|
||||
},
|
||||
{
|
||||
title: "Peran",
|
||||
icon: Lock,
|
||||
path: "/system-administration/role",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const menuItems = [
|
||||
{
|
||||
title: "Dashboard",
|
||||
icon: LayoutDashboard,
|
||||
path: "/dashboard",
|
||||
color: "text-blue-600",
|
||||
},
|
||||
{
|
||||
title: "Integrasi Data",
|
||||
icon: Database,
|
||||
color: "text-blue-600",
|
||||
submenu: [
|
||||
{
|
||||
title: "Sinkronisasi BPJS",
|
||||
icon: Shield,
|
||||
path: "/integration/bpjs-sync",
|
||||
},
|
||||
{
|
||||
title: "Sinkronisasi Rekam Medis",
|
||||
icon: FileText,
|
||||
path: "/integration/medical-record-sync",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Rekam Medis",
|
||||
icon: Users,
|
||||
color: "text-blue-600",
|
||||
submenu: [
|
||||
{
|
||||
title: "Klinis",
|
||||
icon: FileText,
|
||||
path: "/medical-records/clinical",
|
||||
},
|
||||
{
|
||||
title: "Administratif",
|
||||
icon: FileText,
|
||||
path: "/medical-records/administrative",
|
||||
},
|
||||
{
|
||||
title: "Rekomendasi Biaya",
|
||||
icon: TrendingUp,
|
||||
path: "/medical-records/cost-recommendation",
|
||||
},
|
||||
{
|
||||
title: "Kodefikasi BPJS",
|
||||
icon: FileText,
|
||||
path: "/medical-records/bpjs-codification",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// title: "Administrasi Sistem",
|
||||
// icon: UserCog,
|
||||
// color: "text-blue-600",
|
||||
// submenu: [
|
||||
// {
|
||||
// title: "Pengguna",
|
||||
// icon: Users,
|
||||
// path: "/system-administration/user",
|
||||
// },
|
||||
// {
|
||||
// title: "Peran",
|
||||
// icon: Lock,
|
||||
// path: "/system-administration/role",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
];
|
||||
|
||||
const [expandedMenu, setExpandedMenu] = useState<string | null>(null);
|
||||
const [expandedMenu, setExpandedMenu] = useState<string | null>(null);
|
||||
|
||||
const toggleSubmenu = (title: string) => {
|
||||
setExpandedMenu(expandedMenu === title ? null : title);
|
||||
};
|
||||
const toggleSubmenu = (title: string) => {
|
||||
setExpandedMenu(expandedMenu === title ? null : title);
|
||||
};
|
||||
|
||||
const isActive = (path: string) => location.pathname === path;
|
||||
const isActive = (path: string) => location.pathname === path;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"bg-white border-r border-gray-200 h-screen flex flex-col transition-all duration-300 ease-in-out",
|
||||
isCollapsed ? "w-16" : "w-64"
|
||||
)}
|
||||
>
|
||||
{/* Header */}
|
||||
<div
|
||||
className={clsx(
|
||||
"border-b border-gray-200",
|
||||
isCollapsed ? "p-2" : "p-4"
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
{!isCollapsed ? (
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
<div className="bg-white p-1 rounded-lg mr-3 border border-gray-200">
|
||||
<img
|
||||
src={claimGuardLogo}
|
||||
alt="ClaimGuard Logo"
|
||||
className="h-8 w-8 object-cover rounded-md"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-gray-900">
|
||||
ClaimGuard
|
||||
</h1>
|
||||
<p className="text-xs text-gray-500">Hospital Management</p>
|
||||
</div>
|
||||
</div>
|
||||
{onToggleCollapse && (
|
||||
<button
|
||||
onClick={onToggleCollapse}
|
||||
className="p-1 hover:bg-blue-50 hover:text-blue-600 rounded-md transition-colors"
|
||||
title="Collapse Sidebar"
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4 text-gray-500" />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="w-full flex justify-center">
|
||||
<button
|
||||
onClick={onToggleCollapse}
|
||||
className="bg-white p-2 rounded-lg hover:bg-blue-50 hover:border-blue-300 transition-colors border border-gray-200 shadow-sm"
|
||||
title="ClaimGuard - Expand Sidebar"
|
||||
>
|
||||
<img
|
||||
src={claimGuardLogo}
|
||||
alt="ClaimGuard Logo"
|
||||
className="h-6 w-6 object-cover rounded-sm"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"bg-white border-r border-gray-200 h-screen flex flex-col transition-all duration-300 ease-in-out",
|
||||
isCollapsed ? "w-16" : "w-64"
|
||||
)}
|
||||
>
|
||||
{/* Header */}
|
||||
<div
|
||||
className={clsx(
|
||||
"border-b border-gray-200",
|
||||
isCollapsed ? "p-2" : "p-4"
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
{!isCollapsed ? (
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
<div className="bg-white p-1 rounded-lg mr-3 border border-gray-200">
|
||||
<img
|
||||
src={claimGuardLogo}
|
||||
alt="ClaimGuard Logo"
|
||||
className="h-8 w-8 object-cover rounded-md"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-gray-900">
|
||||
ClaimGuard
|
||||
</h1>
|
||||
<p className="text-xs text-gray-500">Hospital Management</p>
|
||||
</div>
|
||||
</div>
|
||||
{onToggleCollapse && (
|
||||
<button
|
||||
onClick={onToggleCollapse}
|
||||
className="p-1 hover:bg-blue-50 hover:text-blue-600 rounded-md transition-colors"
|
||||
title="Collapse Sidebar"
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4 text-gray-500" />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="w-full flex justify-center">
|
||||
<button
|
||||
onClick={onToggleCollapse}
|
||||
className="bg-white p-2 rounded-lg hover:bg-blue-50 hover:border-blue-300 transition-colors border border-gray-200 shadow-sm"
|
||||
title="ClaimGuard - Expand Sidebar"
|
||||
>
|
||||
<img
|
||||
src={claimGuardLogo}
|
||||
alt="ClaimGuard Logo"
|
||||
className="h-6 w-6 object-cover rounded-sm"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 overflow-y-auto py-4">
|
||||
<div className="px-3 space-y-1">
|
||||
{menuItems.map((item) => (
|
||||
<div key={item.title}>
|
||||
{item.submenu ? (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (isCollapsed && onToggleCollapse) {
|
||||
onToggleCollapse();
|
||||
} else {
|
||||
toggleSubmenu(item.title);
|
||||
}
|
||||
}}
|
||||
title={
|
||||
isCollapsed
|
||||
? `Klik untuk membuka ${item.title}`
|
||||
: item.title
|
||||
}
|
||||
className={clsx(
|
||||
"w-full flex items-center py-2 rounded-lg text-sm font-medium transition-colors",
|
||||
"hover:bg-blue-50 hover:text-blue-700 text-gray-700",
|
||||
isCollapsed ? "px-2 justify-center" : "px-3"
|
||||
)}
|
||||
>
|
||||
<div className="relative">
|
||||
<item.icon
|
||||
className={clsx(
|
||||
"h-5 w-5",
|
||||
item.color,
|
||||
isCollapsed ? "" : "mr-3"
|
||||
)}
|
||||
/>
|
||||
{isCollapsed && (
|
||||
<div className="absolute -bottom-1 -right-1 w-2 h-2 bg-blue-500 rounded-full opacity-60"></div>
|
||||
)}
|
||||
</div>
|
||||
{!isCollapsed && (
|
||||
<>
|
||||
<span className="flex-1 text-left">{item.title}</span>
|
||||
<ChevronRight
|
||||
className={clsx(
|
||||
"h-4 w-4 transition-transform",
|
||||
expandedMenu === item.title && "transform rotate-90"
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 overflow-y-auto py-4">
|
||||
<div className="px-3 space-y-1">
|
||||
{menuItems.map((item) => (
|
||||
<div key={item.title}>
|
||||
{item.submenu ? (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (isCollapsed && onToggleCollapse) {
|
||||
onToggleCollapse();
|
||||
} else {
|
||||
toggleSubmenu(item.title);
|
||||
}
|
||||
}}
|
||||
title={
|
||||
isCollapsed
|
||||
? `Klik untuk membuka ${item.title}`
|
||||
: item.title
|
||||
}
|
||||
className={clsx(
|
||||
"w-full flex items-center py-2 rounded-lg text-sm font-medium transition-colors",
|
||||
"hover:bg-blue-50 hover:text-blue-700 text-gray-700",
|
||||
isCollapsed ? "px-2 justify-center" : "px-3"
|
||||
)}
|
||||
>
|
||||
<div className="relative">
|
||||
<item.icon
|
||||
className={clsx(
|
||||
"h-5 w-5",
|
||||
item.color,
|
||||
isCollapsed ? "" : "mr-3"
|
||||
)}
|
||||
/>
|
||||
{isCollapsed && (
|
||||
<div className="absolute -bottom-1 -right-1 w-2 h-2 bg-blue-500 rounded-full opacity-60"></div>
|
||||
)}
|
||||
</div>
|
||||
{!isCollapsed && (
|
||||
<>
|
||||
<span className="flex-1 text-left">{item.title}</span>
|
||||
<ChevronRight
|
||||
className={clsx(
|
||||
"h-4 w-4 transition-transform",
|
||||
expandedMenu === item.title && "transform rotate-90"
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{!isCollapsed && expandedMenu === item.title && (
|
||||
<div className="ml-6 mt-1 space-y-1">
|
||||
{item.submenu.map((subItem) => (
|
||||
<Link
|
||||
key={subItem.path}
|
||||
to={subItem.path}
|
||||
className={clsx(
|
||||
"flex items-center px-3 py-2 rounded-lg text-sm transition-colors",
|
||||
isActive(subItem.path)
|
||||
? "bg-blue-50 text-blue-700 border-r-2 border-blue-600"
|
||||
: "text-gray-600 hover:bg-blue-50 hover:text-blue-700"
|
||||
)}
|
||||
>
|
||||
<subItem.icon className="h-4 w-4 mr-3" />
|
||||
<span>{subItem.title}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Link
|
||||
to={item.path}
|
||||
title={isCollapsed ? item.title : undefined}
|
||||
className={clsx(
|
||||
"flex items-center py-2 rounded-lg text-sm font-medium transition-colors",
|
||||
isActive(item.path)
|
||||
? "bg-blue-50 text-blue-700 border-r-2 border-blue-600"
|
||||
: "text-gray-700 hover:bg-blue-50 hover:text-blue-700",
|
||||
isCollapsed ? "px-2 justify-center" : "px-3"
|
||||
)}
|
||||
>
|
||||
<item.icon
|
||||
className={clsx(
|
||||
"h-5 w-5",
|
||||
item.color,
|
||||
isCollapsed ? "" : "mr-3"
|
||||
)}
|
||||
/>
|
||||
{!isCollapsed && <span>{item.title}</span>}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{!isCollapsed && expandedMenu === item.title && (
|
||||
<div className="ml-6 mt-1 space-y-1">
|
||||
{item.submenu.map((subItem) => (
|
||||
<Link
|
||||
key={subItem.path}
|
||||
to={subItem.path}
|
||||
className={clsx(
|
||||
"flex items-center px-3 py-2 rounded-lg text-sm transition-colors",
|
||||
isActive(subItem.path)
|
||||
? "bg-blue-50 text-blue-700 border-r-2 border-blue-600"
|
||||
: "text-gray-600 hover:bg-blue-50 hover:text-blue-700"
|
||||
)}
|
||||
>
|
||||
<subItem.icon className="h-4 w-4 mr-3" />
|
||||
<span>{subItem.title}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Link
|
||||
to={item.path}
|
||||
title={isCollapsed ? item.title : undefined}
|
||||
className={clsx(
|
||||
"flex items-center py-2 rounded-lg text-sm font-medium transition-colors",
|
||||
isActive(item.path)
|
||||
? "bg-blue-50 text-blue-700 border-r-2 border-blue-600"
|
||||
: "text-gray-700 hover:bg-blue-50 hover:text-blue-700",
|
||||
isCollapsed ? "px-2 justify-center" : "px-3"
|
||||
)}
|
||||
>
|
||||
<item.icon
|
||||
className={clsx(
|
||||
"h-5 w-5",
|
||||
item.color,
|
||||
isCollapsed ? "" : "mr-3"
|
||||
)}
|
||||
/>
|
||||
{!isCollapsed && <span>{item.title}</span>}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="my-4 px-3">
|
||||
<div className="border-t border-gray-200"></div>
|
||||
</div>
|
||||
</nav>
|
||||
{/* Divider */}
|
||||
<div className="my-4 px-3">
|
||||
<div className="border-t border-gray-200"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Footer space */}
|
||||
<div className="border-t border-gray-200 p-4"></div>
|
||||
</div>
|
||||
);
|
||||
{/* Footer space */}
|
||||
<div className="border-t border-gray-200 p-4"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,472 +1,472 @@
|
||||
import {
|
||||
Users,
|
||||
TrendingUp,
|
||||
AlertTriangle,
|
||||
Shield,
|
||||
Database,
|
||||
RefreshCw,
|
||||
FileText,
|
||||
Search,
|
||||
Bell,
|
||||
CheckCircle,
|
||||
XCircle,
|
||||
Clock,
|
||||
ArrowRight,
|
||||
Code,
|
||||
Stethoscope,
|
||||
Users,
|
||||
TrendingUp,
|
||||
AlertTriangle,
|
||||
Shield,
|
||||
Database,
|
||||
RefreshCw,
|
||||
FileText,
|
||||
Search,
|
||||
Bell,
|
||||
CheckCircle,
|
||||
XCircle,
|
||||
Clock,
|
||||
ArrowRight,
|
||||
Code,
|
||||
Stethoscope,
|
||||
} from "lucide-react";
|
||||
|
||||
export default function Dashboard() {
|
||||
// Stats berdasarkan fitur project yang ada
|
||||
const stats = [
|
||||
{
|
||||
title: "BPJS Sync Status",
|
||||
value: "18/25",
|
||||
change: "72% berhasil",
|
||||
changeColor: "text-green-600",
|
||||
icon: RefreshCw,
|
||||
color: "text-blue-600",
|
||||
subtitle: "Sync hari ini",
|
||||
},
|
||||
{
|
||||
title: "Medical Records",
|
||||
value: "89",
|
||||
change: "+12 hari ini",
|
||||
changeColor: "text-green-600",
|
||||
icon: FileText,
|
||||
color: "text-green-600",
|
||||
subtitle: "Record tersinkron",
|
||||
},
|
||||
{
|
||||
title: "ICD Recommendations",
|
||||
value: "23",
|
||||
change: "87% confidence",
|
||||
changeColor: "text-blue-600",
|
||||
icon: Code,
|
||||
color: "text-purple-600",
|
||||
subtitle: "Generated today",
|
||||
},
|
||||
{
|
||||
title: "Active Users",
|
||||
value: "28/30",
|
||||
change: "24 login hari ini",
|
||||
changeColor: "text-green-600",
|
||||
icon: Users,
|
||||
color: "text-orange-600",
|
||||
subtitle: "System users",
|
||||
},
|
||||
];
|
||||
// Stats berdasarkan fitur project yang ada
|
||||
const stats = [
|
||||
{
|
||||
title: "BPJS Sync Status",
|
||||
value: "18/25",
|
||||
change: "72% berhasil",
|
||||
changeColor: "text-green-600",
|
||||
icon: RefreshCw,
|
||||
color: "text-blue-600",
|
||||
subtitle: "Sync hari ini",
|
||||
},
|
||||
{
|
||||
title: "Medical Records",
|
||||
value: "89",
|
||||
change: "+12 hari ini",
|
||||
changeColor: "text-green-600",
|
||||
icon: FileText,
|
||||
color: "text-green-600",
|
||||
subtitle: "Record tersinkron",
|
||||
},
|
||||
{
|
||||
title: "ICD Recommendations",
|
||||
value: "23",
|
||||
change: "87% confidence",
|
||||
changeColor: "text-blue-600",
|
||||
icon: Code,
|
||||
color: "text-purple-600",
|
||||
subtitle: "Generated today",
|
||||
},
|
||||
{
|
||||
title: "Active Users",
|
||||
value: "28/30",
|
||||
change: "24 login hari ini",
|
||||
changeColor: "text-green-600",
|
||||
icon: Users,
|
||||
color: "text-orange-600",
|
||||
subtitle: "System users",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Welcome Section */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
Dashboard ClaimGuard
|
||||
</h2>
|
||||
<p className="text-gray-600">
|
||||
Monitor BPJS operations, medical records, ICD recommendations, dan
|
||||
sistem management secara real-time.
|
||||
</p>
|
||||
</div>
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Welcome Section */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-2">
|
||||
Dashboard ClaimGuard
|
||||
</h2>
|
||||
<p className="text-gray-600">
|
||||
Monitor BPJS operations, medical records, ICD recommendations, dan
|
||||
sistem management secara real-time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Alert/Warning Section */}
|
||||
<div className="bg-white rounded-lg shadow-sm border mb-6 p-4">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Bell className="h-5 w-5 text-red-500 mr-2" />
|
||||
Peringatan & Notifikasi
|
||||
</h3>
|
||||
<span className="text-sm text-gray-500">Real-time alerts</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<AlertTriangle className="h-4 w-4 text-red-600 mr-2" />
|
||||
<span className="text-sm font-medium text-red-900">
|
||||
Overclaim Detected
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-red-700 mt-1">
|
||||
7 kasus interval < 30 hari
|
||||
</p>
|
||||
<p className="text-xs text-red-600 mt-1">
|
||||
ICD: I10, E11, J18.9
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-red-600 hover:text-red-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/* Alert/Warning Section */}
|
||||
<div className="bg-white rounded-lg shadow-sm border mb-6 p-4 hidden">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Bell className="h-5 w-5 text-red-500 mr-2" />
|
||||
Peringatan & Notifikasi
|
||||
</h3>
|
||||
<span className="text-sm text-gray-500">Real-time alerts</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<AlertTriangle className="h-4 w-4 text-red-600 mr-2" />
|
||||
<span className="text-sm font-medium text-red-900">
|
||||
Overclaim Detected
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-red-700 mt-1">
|
||||
7 kasus interval < 30 hari
|
||||
</p>
|
||||
<p className="text-xs text-red-600 mt-1">
|
||||
ICD: I10, E11, J18.9
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-red-600 hover:text-red-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-orange-50 border border-orange-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<Clock className="h-4 w-4 text-orange-600 mr-2" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
Inconsistent Visits
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700 mt-1">
|
||||
3 kontrol tidak konsisten
|
||||
</p>
|
||||
<p className="text-xs text-orange-600 mt-1">
|
||||
Tipe vs alasan tidak sesuai
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-orange-600 hover:text-orange-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-orange-50 border border-orange-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<Clock className="h-4 w-4 text-orange-600 mr-2" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
Inconsistent Visits
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700 mt-1">
|
||||
3 kontrol tidak konsisten
|
||||
</p>
|
||||
<p className="text-xs text-orange-600 mt-1">
|
||||
Tipe vs alasan tidak sesuai
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-orange-600 hover:text-orange-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<XCircle className="h-4 w-4 text-blue-600 mr-2" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Sync Failures
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700 mt-1">
|
||||
5 BPJS sync gagal
|
||||
</p>
|
||||
<p className="text-xs text-blue-600 mt-1">
|
||||
Perlu retry manual
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-blue-600 hover:text-blue-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<XCircle className="h-4 w-4 text-blue-600 mr-2" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Sync Failures
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700 mt-1">
|
||||
5 BPJS sync gagal
|
||||
</p>
|
||||
<p className="text-xs text-blue-600 mt-1">
|
||||
Perlu retry manual
|
||||
</p>
|
||||
</div>
|
||||
<button className="text-blue-600 hover:text-blue-800">
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
{stats.map((stat, index) => (
|
||||
<div key={index} className="card p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className={`p-2 rounded-lg bg-gray-100 ${stat.color}`}>
|
||||
<stat.icon className="h-5 w-5" />
|
||||
</div>
|
||||
<span className={`text-sm font-medium ${stat.changeColor}`}>
|
||||
{stat.change}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-bold text-gray-900 mb-1">
|
||||
{stat.value}
|
||||
</p>
|
||||
<p className="text-sm font-semibold text-gray-700 mb-1">
|
||||
{stat.title}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">{stat.subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8 hidden">
|
||||
{stats.map((stat, index) => (
|
||||
<div key={index} className="card p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className={`p-2 rounded-lg bg-gray-100 ${stat.color}`}>
|
||||
<stat.icon className="h-5 w-5" />
|
||||
</div>
|
||||
<span className={`text-sm font-medium ${stat.changeColor}`}>
|
||||
{stat.change}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-bold text-gray-900 mb-1">
|
||||
{stat.value}
|
||||
</p>
|
||||
<p className="text-sm font-semibold text-gray-700 mb-1">
|
||||
{stat.title}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">{stat.subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Main Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
||||
{/* BPJS Operations */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Database className="h-5 w-5 text-blue-600 mr-2" />
|
||||
BPJS Operations
|
||||
</h3>
|
||||
<button className="text-sm text-blue-600 hover:text-blue-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
{/* Main Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6 hidden">
|
||||
{/* BPJS Operations */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Database className="h-5 w-5 text-blue-600 mr-2" />
|
||||
BPJS Operations
|
||||
</h3>
|
||||
<button className="text-sm text-blue-600 hover:text-blue-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<RefreshCw className="h-4 w-4 text-blue-600" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Sync Status
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700">Berhasil: 18/25 (72%)</p>
|
||||
<p className="text-xs text-blue-600">
|
||||
Last sync: 15 Jan 2024 14:30
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-blue-600">18</div>
|
||||
<div className="text-xs text-blue-500">Sukses hari ini</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<RefreshCw className="h-4 w-4 text-blue-600" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Sync Status
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700">Berhasil: 18/25 (72%)</p>
|
||||
<p className="text-xs text-blue-600">
|
||||
Last sync: 15 Jan 2024 14:30
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-blue-600">18</div>
|
||||
<div className="text-xs text-blue-500">Sukses hari ini</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Code className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
Active Codes
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">156 kode BPJS aktif</p>
|
||||
<p className="text-xs text-green-600">
|
||||
8 kode baru bulan ini
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">156</div>
|
||||
<div className="text-xs text-green-500">Total kode</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Code className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
Active Codes
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">156 kode BPJS aktif</p>
|
||||
<p className="text-xs text-green-600">
|
||||
8 kode baru bulan ini
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">156</div>
|
||||
<div className="text-xs text-green-500">Total kode</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Shield className="h-4 w-4 text-purple-600" />
|
||||
<span className="text-sm font-medium text-purple-900">
|
||||
Assist Coding
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-purple-700">
|
||||
45 coding assistance
|
||||
</p>
|
||||
<p className="text-xs text-purple-600">12 queries hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-purple-600">45</div>
|
||||
<div className="text-xs text-purple-500">Total assist</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Shield className="h-4 w-4 text-purple-600" />
|
||||
<span className="text-sm font-medium text-purple-900">
|
||||
Assist Coding
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-purple-700">
|
||||
45 coding assistance
|
||||
</p>
|
||||
<p className="text-xs text-purple-600">12 queries hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-purple-600">45</div>
|
||||
<div className="text-xs text-purple-500">Total assist</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Medical Record Operations */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Stethoscope className="h-5 w-5 text-green-600 mr-2" />
|
||||
Medical Records
|
||||
</h3>
|
||||
<button className="text-sm text-green-600 hover:text-green-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
{/* Medical Record Operations */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Stethoscope className="h-5 w-5 text-green-600 mr-2" />
|
||||
Medical Records
|
||||
</h3>
|
||||
<button className="text-sm text-green-600 hover:text-green-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<CheckCircle className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
Sync Records
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">
|
||||
1,250 records tersinkron
|
||||
</p>
|
||||
<p className="text-xs text-green-600">89 records hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">89</div>
|
||||
<div className="text-xs text-green-500">Hari ini</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<CheckCircle className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
Sync Records
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">
|
||||
1,250 records tersinkron
|
||||
</p>
|
||||
<p className="text-xs text-green-600">89 records hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">89</div>
|
||||
<div className="text-xs text-green-500">Hari ini</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Search className="h-4 w-4 text-blue-600" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Patient Search
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700">45 pencarian hari ini</p>
|
||||
<p className="text-xs text-blue-600">84% success rate</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-blue-600">45</div>
|
||||
<div className="text-xs text-blue-500">Searches</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Search className="h-4 w-4 text-blue-600" />
|
||||
<span className="text-sm font-medium text-blue-900">
|
||||
Patient Search
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-blue-700">45 pencarian hari ini</p>
|
||||
<p className="text-xs text-blue-600">84% success rate</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-blue-600">45</div>
|
||||
<div className="text-xs text-blue-500">Searches</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-orange-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<FileText className="h-4 w-4 text-orange-600" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
Latest Records
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700">
|
||||
30 records dalam 30 hari
|
||||
</p>
|
||||
<p className="text-xs text-orange-600">Filter aktif</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-orange-600">30</div>
|
||||
<div className="text-xs text-orange-500">Records</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-orange-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<FileText className="h-4 w-4 text-orange-600" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
Latest Records
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700">
|
||||
30 records dalam 30 hari
|
||||
</p>
|
||||
<p className="text-xs text-orange-600">Filter aktif</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-orange-600">30</div>
|
||||
<div className="text-xs text-orange-500">Records</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Second Row */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* ICD Recommendations & Cost */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<TrendingUp className="h-5 w-5 text-purple-600 mr-2" />
|
||||
ICD & Cost Management
|
||||
</h3>
|
||||
<button className="text-sm text-purple-600 hover:text-purple-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
{/* Second Row */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 hidden">
|
||||
{/* ICD Recommendations & Cost */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<TrendingUp className="h-5 w-5 text-purple-600 mr-2" />
|
||||
ICD & Cost Management
|
||||
</h3>
|
||||
<button className="text-sm text-purple-600 hover:text-purple-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{
|
||||
title: "ICD Recommendations",
|
||||
value: "23",
|
||||
subtitle: "Generated today",
|
||||
detail: "87% avg confidence",
|
||||
color: "text-purple-600",
|
||||
bgColor: "bg-purple-50",
|
||||
icon: Code,
|
||||
},
|
||||
{
|
||||
title: "BPJS Mappings",
|
||||
value: "19/23",
|
||||
subtitle: "Successfully mapped",
|
||||
detail: "83% mapping rate",
|
||||
color: "text-blue-600",
|
||||
bgColor: "bg-blue-50",
|
||||
icon: Shield,
|
||||
},
|
||||
{
|
||||
title: "Cost Analysis",
|
||||
value: "12",
|
||||
subtitle: "Exports today",
|
||||
detail: "JSON format",
|
||||
color: "text-green-600",
|
||||
bgColor: "bg-green-50",
|
||||
icon: TrendingUp,
|
||||
},
|
||||
].map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`flex items-center justify-between p-3 ${item.bgColor} rounded-lg`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<item.icon className={`h-4 w-4 ${item.color}`} />
|
||||
<span
|
||||
className={`text-sm font-medium ${item.color
|
||||
.replace("text-", "text-")
|
||||
.replace("-600", "-900")}`}
|
||||
>
|
||||
{item.title}
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
className={`text-sm ${item.color.replace(
|
||||
"-600",
|
||||
"-700"
|
||||
)}`}
|
||||
>
|
||||
{item.subtitle}
|
||||
</p>
|
||||
<p className={`text-xs ${item.color}`}>{item.detail}</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className={`text-lg font-bold ${item.color}`}>
|
||||
{item.value}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{
|
||||
title: "ICD Recommendations",
|
||||
value: "23",
|
||||
subtitle: "Generated today",
|
||||
detail: "87% avg confidence",
|
||||
color: "text-purple-600",
|
||||
bgColor: "bg-purple-50",
|
||||
icon: Code,
|
||||
},
|
||||
{
|
||||
title: "BPJS Mappings",
|
||||
value: "19/23",
|
||||
subtitle: "Successfully mapped",
|
||||
detail: "83% mapping rate",
|
||||
color: "text-blue-600",
|
||||
bgColor: "bg-blue-50",
|
||||
icon: Shield,
|
||||
},
|
||||
{
|
||||
title: "Cost Analysis",
|
||||
value: "12",
|
||||
subtitle: "Exports today",
|
||||
detail: "JSON format",
|
||||
color: "text-green-600",
|
||||
bgColor: "bg-green-50",
|
||||
icon: TrendingUp,
|
||||
},
|
||||
].map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`flex items-center justify-between p-3 ${item.bgColor} rounded-lg`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<item.icon className={`h-4 w-4 ${item.color}`} />
|
||||
<span
|
||||
className={`text-sm font-medium ${item.color
|
||||
.replace("text-", "text-")
|
||||
.replace("-600", "-900")}`}
|
||||
>
|
||||
{item.title}
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
className={`text-sm ${item.color.replace(
|
||||
"-600",
|
||||
"-700"
|
||||
)}`}
|
||||
>
|
||||
{item.subtitle}
|
||||
</p>
|
||||
<p className={`text-xs ${item.color}`}>{item.detail}</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className={`text-lg font-bold ${item.color}`}>
|
||||
{item.value}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* System Management */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Users className="h-5 w-5 text-orange-600 mr-2" />
|
||||
System Management
|
||||
</h3>
|
||||
<button className="text-sm text-orange-600 hover:text-orange-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
{/* System Management */}
|
||||
<div className="card p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<Users className="h-5 w-5 text-orange-600 mr-2" />
|
||||
System Management
|
||||
</h3>
|
||||
<button className="text-sm text-orange-600 hover:text-orange-800 flex items-center">
|
||||
Lihat Detail <ArrowRight className="h-4 w-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-orange-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Users className="h-4 w-4 text-orange-600" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
User Management
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700">28/30 active users</p>
|
||||
<p className="text-xs text-orange-600">24 login hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-orange-600">28</div>
|
||||
<div className="text-xs text-orange-500">Active</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-orange-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Users className="h-4 w-4 text-orange-600" />
|
||||
<span className="text-sm font-medium text-orange-900">
|
||||
User Management
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-orange-700">28/30 active users</p>
|
||||
<p className="text-xs text-orange-600">24 login hari ini</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-orange-600">28</div>
|
||||
<div className="text-xs text-orange-500">Active</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Shield className="h-4 w-4 text-purple-600" />
|
||||
<span className="text-sm font-medium text-purple-900">
|
||||
Role Management
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-purple-700">25 roles configured</p>
|
||||
<p className="text-xs text-purple-600">
|
||||
2 permissions updated
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-purple-600">25</div>
|
||||
<div className="text-xs text-purple-500">Roles</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between p-3 bg-purple-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Shield className="h-4 w-4 text-purple-600" />
|
||||
<span className="text-sm font-medium text-purple-900">
|
||||
Role Management
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-purple-700">25 roles configured</p>
|
||||
<p className="text-xs text-purple-600">
|
||||
2 permissions updated
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-purple-600">25</div>
|
||||
<div className="text-xs text-purple-500">Roles</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<CheckCircle className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
System Health
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">99.8% uptime</p>
|
||||
<p className="text-xs text-green-600">2.1% error rate</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">99.8%</div>
|
||||
<div className="text-xs text-green-500">Uptime</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<div className="flex items-center justify-between p-3 bg-green-50 rounded-lg">
|
||||
<div>
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<CheckCircle className="h-4 w-4 text-green-600" />
|
||||
<span className="text-sm font-medium text-green-900">
|
||||
System Health
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-green-700">99.8% uptime</p>
|
||||
<p className="text-xs text-green-600">2.1% error rate</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-lg font-bold text-green-600">99.8%</div>
|
||||
<div className="text-xs text-green-500">Uptime</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,520 +1,498 @@
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Code,
|
||||
AlertCircle,
|
||||
Wand2,
|
||||
ShieldCheck,
|
||||
ClipboardList,
|
||||
FileText,
|
||||
Code,
|
||||
AlertCircle,
|
||||
Wand2,
|
||||
ShieldCheck,
|
||||
ClipboardList,
|
||||
FileText,
|
||||
} from "lucide-react";
|
||||
|
||||
interface AssistInput {
|
||||
clinicalNotes: string;
|
||||
labResults: string;
|
||||
procedures: string;
|
||||
clinicalNotes: string;
|
||||
procedures: string;
|
||||
}
|
||||
|
||||
interface ICD10Code {
|
||||
code: string;
|
||||
description: string;
|
||||
reasoning: string;
|
||||
code: string;
|
||||
description: string;
|
||||
reasoning: string;
|
||||
}
|
||||
|
||||
interface ProcedureCode {
|
||||
code: string;
|
||||
description: string;
|
||||
reasoning: string;
|
||||
code: string;
|
||||
description: string;
|
||||
reasoning: string;
|
||||
}
|
||||
|
||||
interface BPJSMapping {
|
||||
ina_cbg_code: string;
|
||||
description: string;
|
||||
tariff: number;
|
||||
ina_cbg_code: string;
|
||||
description: string;
|
||||
tariff: number;
|
||||
}
|
||||
|
||||
interface AssistResult {
|
||||
icd_10_codes: ICD10Code[];
|
||||
procedure_codes: ProcedureCode[];
|
||||
bpjs_mapping: BPJSMapping;
|
||||
icd_10_codes: ICD10Code[];
|
||||
procedure_codes: ProcedureCode[];
|
||||
bpjs_mapping: BPJSMapping;
|
||||
}
|
||||
|
||||
export default function BPJSCodeification() {
|
||||
const [assistInput, setAssistInput] = useState<AssistInput>({
|
||||
clinicalNotes: "",
|
||||
labResults: "",
|
||||
procedures: "",
|
||||
});
|
||||
const [assistLoading, setAssistLoading] = useState(false);
|
||||
const [assistError, setAssistError] = useState<string | null>(null);
|
||||
const [assistResult, setAssistResult] = useState<AssistResult | null>(null);
|
||||
const [assistInput, setAssistInput] = useState<AssistInput>({
|
||||
clinicalNotes: "",
|
||||
procedures: "",
|
||||
});
|
||||
const [assistLoading, setAssistLoading] = useState(false);
|
||||
const [assistError, setAssistError] = useState<string | null>(null);
|
||||
const [assistResult, setAssistResult] = useState<AssistResult | null>(null);
|
||||
|
||||
const formatCurrency = (amount: number) =>
|
||||
new Intl.NumberFormat("id-ID", {
|
||||
style: "currency",
|
||||
currency: "IDR",
|
||||
minimumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
const formatCurrency = (amount: number) =>
|
||||
new Intl.NumberFormat("id-ID", {
|
||||
style: "currency",
|
||||
currency: "IDR",
|
||||
minimumFractionDigits: 0,
|
||||
}).format(amount);
|
||||
|
||||
// Mock pipeline with improved JSON output format
|
||||
const preprocessInput = (input: AssistInput): AssistInput => {
|
||||
const normalize = (s: string) => s.replace(/\s+/g, " ").trim();
|
||||
return {
|
||||
clinicalNotes: normalize(input.clinicalNotes),
|
||||
labResults: normalize(input.labResults),
|
||||
procedures: normalize(input.procedures),
|
||||
};
|
||||
};
|
||||
// Mock pipeline with improved JSON output format
|
||||
const preprocessInput = (input: AssistInput): AssistInput => {
|
||||
const normalize = (s: string) => s.replace(/\s+/g, " ").trim();
|
||||
return {
|
||||
clinicalNotes: normalize(input.clinicalNotes),
|
||||
procedures: normalize(input.procedures),
|
||||
};
|
||||
};
|
||||
|
||||
const mockAssistPipeline = async (
|
||||
input: AssistInput
|
||||
): Promise<AssistResult> => {
|
||||
const text =
|
||||
`${input.clinicalNotes} ${input.labResults} ${input.procedures}`.toLowerCase();
|
||||
const mockAssistPipeline = async (
|
||||
input: AssistInput
|
||||
): Promise<AssistResult> => {
|
||||
const text = `${input.clinicalNotes} ${input.procedures}`.toLowerCase();
|
||||
|
||||
const icd10Codes: ICD10Code[] = [];
|
||||
const procedureCodes: ProcedureCode[] = [];
|
||||
const icd10Codes: ICD10Code[] = [];
|
||||
const procedureCodes: ProcedureCode[] = [];
|
||||
|
||||
// ICD-10 Code Detection
|
||||
if (
|
||||
text.includes("pneumonia") ||
|
||||
text.includes("infiltrat") ||
|
||||
text.includes("demam") ||
|
||||
text.includes("batuk") ||
|
||||
text.includes("sesak")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "J18.9",
|
||||
description: "Pneumonia dengan kuman tidak spesifik",
|
||||
reasoning:
|
||||
"Gejala demam, batuk, sesak napas, dan hasil pemeriksaan rontgen mengarah pada pneumonia.",
|
||||
});
|
||||
}
|
||||
// ICD-10 Code Detection
|
||||
if (
|
||||
text.includes("pneumonia") ||
|
||||
text.includes("infiltrat") ||
|
||||
text.includes("demam") ||
|
||||
text.includes("batuk") ||
|
||||
text.includes("sesak")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "J18.9",
|
||||
description: "Pneumonia dengan kuman tidak spesifik",
|
||||
reasoning:
|
||||
"Gejala demam, batuk, sesak napas, dan hasil pemeriksaan rontgen mengarah pada pneumonia.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("hipertensi") ||
|
||||
text.includes("bp 150/95") ||
|
||||
text.includes("tekanan darah tinggi") ||
|
||||
text.includes("hypertension")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "I10",
|
||||
description: "Hipertensi esensial (primer)",
|
||||
reasoning:
|
||||
"Temuan tekanan darah tinggi pada catatan klinis dan pemeriksaan fisik.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("hipertensi") ||
|
||||
text.includes("bp 150/95") ||
|
||||
text.includes("tekanan darah tinggi") ||
|
||||
text.includes("hypertension")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "I10",
|
||||
description: "Hipertensi esensial (primer)",
|
||||
reasoning:
|
||||
"Temuan tekanan darah tinggi pada catatan klinis dan pemeriksaan fisik.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("diabetes") ||
|
||||
text.includes("hba1c") ||
|
||||
text.includes("glukosa") ||
|
||||
text.includes("gula darah")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "E11.9",
|
||||
description: "Diabetes mellitus tipe 2 tanpa komplikasi",
|
||||
reasoning:
|
||||
"Hasil laboratorium menunjukkan peningkatan HbA1c dan glukosa darah yang mendukung diagnosis diabetes.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("diabetes") ||
|
||||
text.includes("hba1c") ||
|
||||
text.includes("glukosa") ||
|
||||
text.includes("gula darah")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "E11.9",
|
||||
description: "Diabetes mellitus tipe 2 tanpa komplikasi",
|
||||
reasoning:
|
||||
"Hasil laboratorium menunjukkan peningkatan HbA1c dan glukosa darah yang mendukung diagnosis diabetes.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("gastritis") ||
|
||||
text.includes("nyeri perut") ||
|
||||
text.includes("mual") ||
|
||||
text.includes("muntah")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "K29.1",
|
||||
description: "Gastritis akut lainnya",
|
||||
reasoning:
|
||||
"Gejala nyeri perut, mual, muntah mengarah pada gastritis akut.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("gastritis") ||
|
||||
text.includes("nyeri perut") ||
|
||||
text.includes("mual") ||
|
||||
text.includes("muntah")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "K29.1",
|
||||
description: "Gastritis akut lainnya",
|
||||
reasoning:
|
||||
"Gejala nyeri perut, mual, muntah mengarah pada gastritis akut.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("influenza") ||
|
||||
text.includes("flu") ||
|
||||
text.includes("demam") ||
|
||||
text.includes("sakit kepala")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "J11.1",
|
||||
description:
|
||||
"Influenza dengan virus tidak teridentifikasi disertai manifestasi respiratori",
|
||||
reasoning:
|
||||
"Gejala demam, sakit kepala, dan manifestasi respiratori mengarah pada influenza.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("influenza") ||
|
||||
text.includes("flu") ||
|
||||
text.includes("demam") ||
|
||||
text.includes("sakit kepala")
|
||||
) {
|
||||
icd10Codes.push({
|
||||
code: "J11.1",
|
||||
description:
|
||||
"Influenza dengan virus tidak teridentifikasi disertai manifestasi respiratori",
|
||||
reasoning:
|
||||
"Gejala demam, sakit kepala, dan manifestasi respiratori mengarah pada influenza.",
|
||||
});
|
||||
}
|
||||
|
||||
// Procedure Code Detection
|
||||
if (
|
||||
text.includes("rontgen") ||
|
||||
text.includes("x-ray") ||
|
||||
text.includes("chest x-ray") ||
|
||||
text.includes("foto thorax")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "87.44",
|
||||
description: "Foto Rontgen thorax, proyeksi tunggal",
|
||||
reasoning: "Tindakan rontgen dada sesuai gejala respiratori.",
|
||||
});
|
||||
}
|
||||
// Procedure Code Detection
|
||||
if (
|
||||
text.includes("rontgen") ||
|
||||
text.includes("x-ray") ||
|
||||
text.includes("chest x-ray") ||
|
||||
text.includes("foto thorax")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "87.44",
|
||||
description: "Foto Rontgen thorax, proyeksi tunggal",
|
||||
reasoning: "Tindakan rontgen dada sesuai gejala respiratori.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("darah lengkap") ||
|
||||
text.includes("complete blood count") ||
|
||||
text.includes("cbc") ||
|
||||
text.includes("lab darah")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "90.59",
|
||||
description: "Pemeriksaan darah lengkap",
|
||||
reasoning: "Pemeriksaan darah lengkap untuk mendukung diagnosis.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("darah lengkap") ||
|
||||
text.includes("complete blood count") ||
|
||||
text.includes("cbc") ||
|
||||
text.includes("lab darah")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "90.59",
|
||||
description: "Pemeriksaan darah lengkap",
|
||||
reasoning: "Pemeriksaan darah lengkap untuk mendukung diagnosis.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("endoskopi") ||
|
||||
text.includes("endoscopy") ||
|
||||
text.includes("gastroscopy")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "45.13",
|
||||
description: "Esofagogastroduodenoskopi (EGD)",
|
||||
reasoning: "Tindakan endoskopi lambung untuk evaluasi gastritis.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("endoskopi") ||
|
||||
text.includes("endoscopy") ||
|
||||
text.includes("gastroscopy")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "45.13",
|
||||
description: "Esofagogastroduodenoskopi (EGD)",
|
||||
reasoning: "Tindakan endoskopi lambung untuk evaluasi gastritis.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("ekg") ||
|
||||
text.includes("ecg") ||
|
||||
text.includes("elektrokardiogram")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "89.52",
|
||||
description: "Elektrokardiogram (EKG)",
|
||||
reasoning: "Pemeriksaan EKG untuk evaluasi kardiovaskular.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("ekg") ||
|
||||
text.includes("ecg") ||
|
||||
text.includes("elektrokardiogram")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "89.52",
|
||||
description: "Elektrokardiogram (EKG)",
|
||||
reasoning: "Pemeriksaan EKG untuk evaluasi kardiovaskular.",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
text.includes("usg") ||
|
||||
text.includes("ultrasound") ||
|
||||
text.includes("ultrasonografi")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "88.76",
|
||||
description: "USG abdomen dan retroperitoneum diagnostik",
|
||||
reasoning: "Pemeriksaan USG abdomen untuk evaluasi organ dalam.",
|
||||
});
|
||||
}
|
||||
if (
|
||||
text.includes("usg") ||
|
||||
text.includes("ultrasound") ||
|
||||
text.includes("ultrasonografi")
|
||||
) {
|
||||
procedureCodes.push({
|
||||
code: "88.76",
|
||||
description: "USG abdomen dan retroperitoneum diagnostik",
|
||||
reasoning: "Pemeriksaan USG abdomen untuk evaluasi organ dalam.",
|
||||
});
|
||||
}
|
||||
|
||||
// Default codes if nothing specific detected
|
||||
if (icd10Codes.length === 0) {
|
||||
icd10Codes.push({
|
||||
code: "R69",
|
||||
description: "Penyakit tidak spesifik",
|
||||
reasoning:
|
||||
"Tidak ada gejala spesifik yang terdeteksi, memerlukan klarifikasi klinis lebih lanjut.",
|
||||
});
|
||||
}
|
||||
// Default codes if nothing specific detected
|
||||
if (icd10Codes.length === 0) {
|
||||
icd10Codes.push({
|
||||
code: "R69",
|
||||
description: "Penyakit tidak spesifik",
|
||||
reasoning:
|
||||
"Tidak ada gejala spesifik yang terdeteksi, memerlukan klarifikasi klinis lebih lanjut.",
|
||||
});
|
||||
}
|
||||
|
||||
if (procedureCodes.length === 0) {
|
||||
procedureCodes.push({
|
||||
code: "99213",
|
||||
description: "Kunjungan rawat jalan",
|
||||
reasoning: "Kunjungan rawat jalan untuk evaluasi medis.",
|
||||
});
|
||||
}
|
||||
if (procedureCodes.length === 0) {
|
||||
procedureCodes.push({
|
||||
code: "99213",
|
||||
description: "Kunjungan rawat jalan",
|
||||
reasoning: "Kunjungan rawat jalan untuk evaluasi medis.",
|
||||
});
|
||||
}
|
||||
|
||||
// BPJS Mapping based on primary diagnosis
|
||||
let bpjsMapping: BPJSMapping;
|
||||
// BPJS Mapping based on primary diagnosis
|
||||
let bpjsMapping: BPJSMapping;
|
||||
|
||||
const hasPneumonia = icd10Codes.some((code) => code.code.startsWith("J18"));
|
||||
const hasDiabetes = icd10Codes.some((code) => code.code.startsWith("E11"));
|
||||
const hasHypertension = icd10Codes.some((code) =>
|
||||
code.code.startsWith("I10")
|
||||
);
|
||||
const hasGastritis = icd10Codes.some((code) => code.code.startsWith("K29"));
|
||||
const hasInfluenza = icd10Codes.some((code) => code.code.startsWith("J11"));
|
||||
const hasPneumonia = icd10Codes.some((code) => code.code.startsWith("J18"));
|
||||
const hasDiabetes = icd10Codes.some((code) => code.code.startsWith("E11"));
|
||||
const hasHypertension = icd10Codes.some((code) =>
|
||||
code.code.startsWith("I10")
|
||||
);
|
||||
const hasGastritis = icd10Codes.some((code) => code.code.startsWith("K29"));
|
||||
const hasInfluenza = icd10Codes.some((code) => code.code.startsWith("J11"));
|
||||
|
||||
if (hasPneumonia) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "B-4-13-I",
|
||||
description: "Pneumonia tanpa komplikasi",
|
||||
tariff: 3500000,
|
||||
};
|
||||
} else if (hasDiabetes) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "E-4-10-I",
|
||||
description: "Diabetes Mellitus tanpa komplikasi",
|
||||
tariff: 2100000,
|
||||
};
|
||||
} else if (hasHypertension) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "F-4-13-II",
|
||||
description: "Hipertensi dengan komplikasi minor",
|
||||
tariff: 1850000,
|
||||
};
|
||||
} else if (hasGastritis) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "G-4-10-I",
|
||||
description: "Gastritis akut tanpa komplikasi",
|
||||
tariff: 1200000,
|
||||
};
|
||||
} else if (hasInfluenza) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "H-4-11-I",
|
||||
description: "Influenza tanpa komplikasi",
|
||||
tariff: 950000,
|
||||
};
|
||||
} else {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "Z-4-00-I",
|
||||
description: "Kondisi tidak spesifik",
|
||||
tariff: 750000,
|
||||
};
|
||||
}
|
||||
if (hasPneumonia) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "B-4-13-I",
|
||||
description: "Pneumonia tanpa komplikasi",
|
||||
tariff: 3500000,
|
||||
};
|
||||
} else if (hasDiabetes) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "E-4-10-I",
|
||||
description: "Diabetes Mellitus tanpa komplikasi",
|
||||
tariff: 2100000,
|
||||
};
|
||||
} else if (hasHypertension) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "F-4-13-II",
|
||||
description: "Hipertensi dengan komplikasi minor",
|
||||
tariff: 1850000,
|
||||
};
|
||||
} else if (hasGastritis) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "G-4-10-I",
|
||||
description: "Gastritis akut tanpa komplikasi",
|
||||
tariff: 1200000,
|
||||
};
|
||||
} else if (hasInfluenza) {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "H-4-11-I",
|
||||
description: "Influenza tanpa komplikasi",
|
||||
tariff: 950000,
|
||||
};
|
||||
} else {
|
||||
bpjsMapping = {
|
||||
ina_cbg_code: "Z-4-00-I",
|
||||
description: "Kondisi tidak spesifik",
|
||||
tariff: 750000,
|
||||
};
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500)); // Simulate processing time
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500)); // Simulate processing time
|
||||
|
||||
return {
|
||||
icd_10_codes: icd10Codes.slice(0, 3), // Limit to top 3
|
||||
procedure_codes: procedureCodes.slice(0, 3), // Limit to top 3
|
||||
bpjs_mapping: bpjsMapping,
|
||||
};
|
||||
};
|
||||
return {
|
||||
icd_10_codes: icd10Codes.slice(0, 3), // Limit to top 3
|
||||
procedure_codes: procedureCodes.slice(0, 3), // Limit to top 3
|
||||
bpjs_mapping: bpjsMapping,
|
||||
};
|
||||
};
|
||||
|
||||
const runAssistPipeline = async () => {
|
||||
setAssistLoading(true);
|
||||
setAssistError(null);
|
||||
setAssistResult(null);
|
||||
const runAssistPipeline = async () => {
|
||||
setAssistLoading(true);
|
||||
setAssistError(null);
|
||||
setAssistResult(null);
|
||||
|
||||
try {
|
||||
const preprocessed = preprocessInput(assistInput);
|
||||
const result = await mockAssistPipeline(preprocessed);
|
||||
setAssistResult(result);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setAssistError(
|
||||
"Gagal menjalankan BPJS Assist Coding. Silakan coba lagi."
|
||||
);
|
||||
} finally {
|
||||
setAssistLoading(false);
|
||||
}
|
||||
};
|
||||
try {
|
||||
const preprocessed = preprocessInput(assistInput);
|
||||
const result = await mockAssistPipeline(preprocessed);
|
||||
setAssistResult(result);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setAssistError(
|
||||
"Gagal menjalankan BPJS Assist Coding. Silakan coba lagi."
|
||||
);
|
||||
} finally {
|
||||
setAssistLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="p-2 bg-blue-100 rounded-lg">
|
||||
<Code className="h-6 w-6 text-blue-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
Asisten Kodefikasi BPJS
|
||||
</h1>
|
||||
<p className="text-gray-600">
|
||||
Bantuan penentuan kode ICD-10, prosedur, dan mapping INA-CBGs untuk
|
||||
klaim BPJS
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Header */}
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="p-2 bg-blue-100 rounded-lg">
|
||||
<Code className="h-6 w-6 text-blue-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
Asisten Kodefikasi BPJS
|
||||
</h1>
|
||||
<p className="text-gray-600">
|
||||
Bantuan penentuan kode ICD-10, prosedur, dan mapping INA-CBGs untuk
|
||||
klaim BPJS
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Form Bantuan Kodefikasi */}
|
||||
<div className="bg-white rounded-lg shadow-sm border mb-6">
|
||||
<div className="p-6 border-b border-gray-200">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-4 flex items-center">
|
||||
<Wand2 className="h-5 w-5 mr-2 text-blue-600" />
|
||||
Input Data Klinis
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-700 mb-1 flex items-center">
|
||||
<ClipboardList className="h-4 w-4 mr-2 text-blue-600" />
|
||||
Catatan Medis / Anamnesis
|
||||
</label>
|
||||
<textarea
|
||||
rows={4}
|
||||
value={assistInput.clinicalNotes}
|
||||
onChange={(e) =>
|
||||
setAssistInput((s) => ({
|
||||
...s,
|
||||
clinicalNotes: e.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="Pasien mengeluh demam sejak 3 hari, batuk berdahak, sesak napas, nyeri dada..."
|
||||
className="w-full rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent p-3"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Hasil Laboratorium
|
||||
</label>
|
||||
<textarea
|
||||
rows={3}
|
||||
value={assistInput.labResults}
|
||||
onChange={(e) =>
|
||||
setAssistInput((s) => ({
|
||||
...s,
|
||||
labResults: e.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="Leukosit: 15.000/µL, CRP: 25 mg/L, HbA1c: 7.8%, Glukosa Puasa: 180 mg/dL..."
|
||||
className="w-full rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent p-3"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Tindakan / Prosedur yang Dilakukan
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={assistInput.procedures}
|
||||
onChange={(e) =>
|
||||
setAssistInput((s) => ({
|
||||
...s,
|
||||
procedures: e.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="Rontgen thorax, darah lengkap, EKG, endoskopi lambung..."
|
||||
className="w-full rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent p-3"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<button
|
||||
onClick={runAssistPipeline}
|
||||
disabled={
|
||||
assistLoading ||
|
||||
(!assistInput.clinicalNotes &&
|
||||
!assistInput.labResults &&
|
||||
!assistInput.procedures)
|
||||
}
|
||||
className="flex items-center space-x-2 disabled:opacity-60 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg disabled:cursor-not-allowed"
|
||||
>
|
||||
<Wand2 className="h-4 w-4" />
|
||||
<span>
|
||||
{assistLoading ? "Memproses..." : "Generate Kode BPJS"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{assistError && (
|
||||
<div className="text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg p-3">
|
||||
{assistError}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Form Bantuan Kodefikasi */}
|
||||
<div className="bg-white rounded-lg shadow-sm border mb-6">
|
||||
<div className="p-6 border-b border-gray-200">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-4 flex items-center">
|
||||
<Wand2 className="h-5 w-5 mr-2 text-blue-600" />
|
||||
Input Data Klinis
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<div>
|
||||
<label className="text-sm font-medium text-gray-700 mb-1 flex items-center">
|
||||
<ClipboardList className="h-4 w-4 mr-2 text-blue-600" />
|
||||
Catatan Medis / Anamnesis
|
||||
</label>
|
||||
<textarea
|
||||
rows={4}
|
||||
value={assistInput.clinicalNotes}
|
||||
onChange={(e) =>
|
||||
setAssistInput((s) => ({
|
||||
...s,
|
||||
clinicalNotes: e.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="Pasien mengeluh demam sejak 3 hari, batuk berdahak, sesak napas, nyeri dada..."
|
||||
className="w-full rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent p-3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Results Section */}
|
||||
<div className="p-6">
|
||||
{!assistResult ? (
|
||||
<div className="text-center py-12">
|
||||
<AlertCircle className="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 className="mt-2 text-sm font-medium text-gray-900">
|
||||
Belum ada hasil
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-gray-500">
|
||||
Isi input data klinis dan klik "Generate Kode BPJS" untuk
|
||||
memulai.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
{/* ICD-10 Codes */}
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-blue-900 mb-3 flex items-center">
|
||||
<ShieldCheck className="h-5 w-5 mr-2" />
|
||||
Kode ICD-10 Diagnosis
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
{assistResult.icd_10_codes.map((icd, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white border border-blue-200 rounded-md p-3"
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-blue-900">
|
||||
{icd.code} - {icd.description}
|
||||
</div>
|
||||
<div className="text-sm text-blue-700 mt-1">
|
||||
<strong>Alasan:</strong> {icd.reasoning}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Tindakan / Prosedur yang Dilakukan
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
value={assistInput.procedures}
|
||||
onChange={(e) =>
|
||||
setAssistInput((s) => ({
|
||||
...s,
|
||||
procedures: e.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder="Rontgen thorax, darah lengkap, EKG, endoskopi lambung..."
|
||||
className="w-full rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent p-3"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<button
|
||||
onClick={runAssistPipeline}
|
||||
disabled={
|
||||
assistLoading ||
|
||||
(!assistInput.clinicalNotes && !assistInput.procedures)
|
||||
}
|
||||
className="flex items-center space-x-2 disabled:opacity-60 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg disabled:cursor-not-allowed"
|
||||
>
|
||||
<Wand2 className="h-4 w-4" />
|
||||
<span>
|
||||
{assistLoading ? "Memproses..." : "Generate Kode BPJS"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{assistError && (
|
||||
<div className="text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg p-3">
|
||||
{assistError}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Procedure Codes */}
|
||||
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-green-900 mb-3 flex items-center">
|
||||
<FileText className="h-5 w-5 mr-2" />
|
||||
Kode Prosedur
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
{assistResult.procedure_codes.map((proc, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white border border-green-200 rounded-md p-3"
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-green-900">
|
||||
{proc.code} - {proc.description}
|
||||
</div>
|
||||
<div className="text-sm text-green-700 mt-1">
|
||||
<strong>Alasan:</strong> {proc.reasoning}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* Results Section */}
|
||||
<div className="p-6">
|
||||
{!assistResult ? (
|
||||
<div className="text-center py-12">
|
||||
<AlertCircle className="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 className="mt-2 text-sm font-medium text-gray-900">
|
||||
Belum ada hasil
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-gray-500">
|
||||
Isi input data klinis dan klik "Generate Kode BPJS" untuk
|
||||
memulai.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
{/* ICD-10 Codes */}
|
||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-blue-900 mb-3 flex items-center">
|
||||
<ShieldCheck className="h-5 w-5 mr-2" />
|
||||
Kode ICD-10 Diagnosis
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
{assistResult.icd_10_codes.map((icd, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white border border-blue-200 rounded-md p-3"
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-blue-900">
|
||||
{icd.code} - {icd.description}
|
||||
</div>
|
||||
<div className="text-sm text-blue-700 mt-1">
|
||||
<strong>Alasan:</strong> {icd.reasoning}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* BPJS Mapping */}
|
||||
<div className="bg-purple-50 border border-purple-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-purple-900 mb-3">
|
||||
Mapping INA-CBGs BPJS
|
||||
</h4>
|
||||
<div className="bg-white border border-purple-200 rounded-md p-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Kode INA-CBGs:
|
||||
</span>
|
||||
<p className="text-lg font-bold text-purple-900">
|
||||
{assistResult.bpjs_mapping.ina_cbg_code}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Deskripsi:
|
||||
</span>
|
||||
<p className="text-gray-900">
|
||||
{assistResult.bpjs_mapping.description}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Estimasi Tarif:
|
||||
</span>
|
||||
<p className="text-lg font-bold text-green-600">
|
||||
{formatCurrency(assistResult.bpjs_mapping.tariff)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
{/* Procedure Codes */}
|
||||
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-green-900 mb-3 flex items-center">
|
||||
<FileText className="h-5 w-5 mr-2" />
|
||||
Kode Prosedur
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
{assistResult.procedure_codes.map((proc, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white border border-green-200 rounded-md p-3"
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="font-semibold text-green-900">
|
||||
{proc.code} - {proc.description}
|
||||
</div>
|
||||
<div className="text-sm text-green-700 mt-1">
|
||||
<strong>Alasan:</strong> {proc.reasoning}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* BPJS Mapping */}
|
||||
<div className="bg-purple-50 border border-purple-200 rounded-lg p-4">
|
||||
<h4 className="text-lg font-medium text-purple-900 mb-3">
|
||||
Mapping INA-CBGs BPJS
|
||||
</h4>
|
||||
<div className="bg-white border border-purple-200 rounded-md p-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Kode INA-CBGs:
|
||||
</span>
|
||||
<p className="text-lg font-bold text-purple-900">
|
||||
{assistResult.bpjs_mapping.ina_cbg_code}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Deskripsi:
|
||||
</span>
|
||||
<p className="text-gray-900">
|
||||
{assistResult.bpjs_mapping.description}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-600">
|
||||
Estimasi Tarif:
|
||||
</span>
|
||||
<p className="text-lg font-bold text-green-600">
|
||||
{formatCurrency(assistResult.bpjs_mapping.tariff)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,94 +6,201 @@
|
||||
DAFTAR ISI:
|
||||
1. Clinical.tsx - Test Cases (Rekam Medis Klinis)
|
||||
2. Administrative.tsx - Test Cases (Rekam Medis Administratif)
|
||||
3. CostRecommendation.tsx - Test Cases (Rekomendasi Biaya)
|
||||
4. BPJSCodeification.tsx - Test Cases (Kodefikasi BPJS)
|
||||
5. Instruksi Penggunaan Test Cases
|
||||
3. BPJSCodeification.tsx - Test Cases (Asisten Kodefikasi BPJS)
|
||||
4. CostRecommendation.tsx - Test Cases (Rekomendasi Biaya)
|
||||
5. Sample Data untuk Testing
|
||||
6. Instruksi Penggunaan Test Cases
|
||||
|
||||
================================================================================
|
||||
1. CLINICAL.TSX - TEST CASES (REKAM MEDIS KLINIS)
|
||||
================================================================================
|
||||
|
||||
TEST CASE 1: PENCARIAN PASIEN LENGKAP
|
||||
=====================================
|
||||
SCHEMA PENCARIAN:
|
||||
- Input tunggal: Nama Pasien / Nomor Rekam Medis / Nomor BPJS
|
||||
- Tanggal Lahir (Opsional)
|
||||
- Pencarian fleksibel dengan word matching
|
||||
|
||||
TEST CASE 1: PENCARIAN NAMA LENGKAP
|
||||
==================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: Ahmad Budi Santoso
|
||||
- Tanggal Lahir: 15 Januari 1985
|
||||
- Nama/No. RM/No. BPJS: John Doe
|
||||
- Tanggal Lahir: 15 Juni 1985
|
||||
|
||||
Expected Result:
|
||||
Menampilkan rekam medis lengkap dengan identitas pasien, riwayat medis,
|
||||
pemeriksaan fisik, diagnosis, rencana pengobatan, dan dokumen medis.
|
||||
Menampilkan rekam medis lengkap dengan:
|
||||
- Identitas pasien (John Doe, MR2024001, BPJS: 0001234567890)
|
||||
- Riwayat medis (Hipertensi 2020, Diabetes 2021)
|
||||
- Pemeriksaan fisik dengan tanda vital
|
||||
- Diagnosis ICD-10 (Unstable Angina - I20.0)
|
||||
- Rencana pengobatan dan dokumen medis
|
||||
|
||||
TEST CASE 2: PENCARIAN DENGAN NOMOR REKAM MEDIS
|
||||
TEST CASE 2: PENCARIAN NAMA PARSIAL (WORD MATCHING)
|
||||
==================================================
|
||||
Input Form:
|
||||
- Nama/No. RM/No. BPJS: john
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Pasien "John Doe" ditemukan meskipun hanya input "john"
|
||||
|
||||
TEST CASE 3: PENCARIAN DENGAN NOMOR REKAM MEDIS
|
||||
===============================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: MRN2024001
|
||||
- Nama/No. RM/No. BPJS: MR2024001
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Pasien ditemukan berdasarkan nomor rekam medis dengan data klinis lengkap.
|
||||
Pasien John Doe ditemukan berdasarkan nomor rekam medis
|
||||
|
||||
TEST CASE 3: PENCARIAN DENGAN NOMOR BPJS
|
||||
=========================================
|
||||
TEST CASE 4: PENCARIAN DENGAN NOMOR BPJS
|
||||
========================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: 000987654321
|
||||
- Tanggal Lahir: 12 April 1985
|
||||
|
||||
Expected Result:
|
||||
Verifikasi pasien dengan nomor BPJS dan tanggal lahir yang sesuai.
|
||||
|
||||
TEST CASE 4: PENCARIAN NAMA PARSIAL
|
||||
===================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: Sari
|
||||
- Nama/No. RM/No. BPJS: 0001234567890
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Hasil pencarian untuk pasien dengan nama yang mengandung "Sari".
|
||||
Pasien John Doe ditemukan berdasarkan nomor BPJS
|
||||
|
||||
TEST CASE 5: PENCARIAN CASE INSENSITIVE
|
||||
======================================
|
||||
Input Form:
|
||||
- Nama/No. RM/No. BPJS: JOHN DOE
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Pasien ditemukan meskipun menggunakan huruf kapital
|
||||
|
||||
================================================================================
|
||||
2. ADMINISTRATIVE.TSX - TEST CASES (REKAM MEDIS ADMINISTRATIF)
|
||||
================================================================================
|
||||
|
||||
TEST CASE 1: PENCARIAN PASIEN AKTIF
|
||||
===================================
|
||||
SCHEMA PENCARIAN:
|
||||
- Input tunggal: Nama Pasien, No. RM, atau No. BPJS
|
||||
- Tanggal Lahir (Opsional)
|
||||
- Flexible word matching untuk nama
|
||||
|
||||
TEST CASE 1: PENCARIAN PASIEN DENGAN STATUS APPROVED
|
||||
====================================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: Siti Nurhaliza
|
||||
- Tanggal Lahir: 25 Juli 1990
|
||||
- Nama/No. RM/No. BPJS: Ahmad Budi Santoso
|
||||
- Tanggal Lahir: 10 Mei 1985
|
||||
|
||||
Expected Result:
|
||||
Detail administratif menampilkan status klaim aktif, informasi pembayaran,
|
||||
dan riwayat kunjungan.
|
||||
Menampilkan data administratif:
|
||||
- Nama: Ahmad Budi Santoso
|
||||
- MRN: MRN2024001, BPJS: 0001234567890
|
||||
- Status Klaim: Disetujui (hijau)
|
||||
- Status Pembayaran: Lunas (hijau)
|
||||
- Total Biaya: Rp 2.500.000
|
||||
- Rawat Jalan di Poli Penyakit Dalam
|
||||
|
||||
TEST CASE 2: PENCARIAN PASIEN BPJS
|
||||
==================================
|
||||
TEST CASE 2: PENCARIAN DENGAN NAMA PARSIAL
|
||||
==========================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: 000123456789
|
||||
- Nama/No. RM/No. BPJS: ahmad santoso
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Data administratif pasien dengan status klaim BPJS dan detail pembayaran.
|
||||
Menemukan "Ahmad Budi Santoso" dengan flexible matching
|
||||
|
||||
TEST CASE 3: PASIEN KUNJUNGAN TERBARU
|
||||
=====================================
|
||||
TEST CASE 3: PENCARIAN PASIEN UNDER REVIEW
|
||||
==========================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: MRN2024002
|
||||
- Tanggal Lahir: 10 September 1978
|
||||
|
||||
Expected Result:
|
||||
Pasien dengan kunjungan terbaru menampilkan status proses klaim saat ini.
|
||||
|
||||
TEST CASE 4: PASIEN DENGAN MULTIPLE KLAIM
|
||||
=========================================
|
||||
Input Form:
|
||||
- Nama/Nomor RM/BPJS: Bambang Sutrisno
|
||||
- Nama/No. RM/No. BPJS: Siti Aminah
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Pasien dengan beberapa klaim dan riwayat pembayaran.
|
||||
Menampilkan pasien dengan:
|
||||
- Status Klaim: Sedang Ditinjau (biru)
|
||||
- Status Pembayaran: Menunggu (kuning)
|
||||
- Total Biaya: Rp 1.800.000
|
||||
- Sisa Tagihan: Rp 1.800.000
|
||||
|
||||
TEST CASE 4: PENCARIAN PASIEN INPATIENT
|
||||
=======================================
|
||||
Input Form:
|
||||
- Nama/No. RM/No. BPJS: Roberto Silva
|
||||
- Tanggal Lahir: (kosong)
|
||||
|
||||
Expected Result:
|
||||
Menampilkan pasien dengan:
|
||||
- Rawat Inap - Kelas 2
|
||||
- Status Pembayaran: Sebagian (orange)
|
||||
- IGD Emergency case
|
||||
|
||||
================================================================================
|
||||
3. COSTRECOMMENDATION.TSX - TEST CASES (REKOMENDASI BIAYA)
|
||||
3. BPJSCODIFICATION.TSX - TEST CASES (ASISTEN KODEFIKASI BPJS)
|
||||
================================================================================
|
||||
|
||||
SCHEMA INPUT (UPDATED):
|
||||
- Catatan Medis / Anamnesis (textarea)
|
||||
- Tindakan / Prosedur yang Dilakukan (input)
|
||||
- TIDAK ADA input Hasil Laboratorium (sudah dihapus)
|
||||
|
||||
TEST CASE 1: KASUS PNEUMONIA
|
||||
============================
|
||||
Input Form:
|
||||
|
||||
Catatan Medis / Anamnesis:
|
||||
Pasien mengeluh demam sejak 3 hari, batuk berdahak, sesak napas, nyeri dada.
|
||||
Pemeriksaan fisik ditemukan suara napas menurun di basal kanan. Pasien tampak sesak.
|
||||
|
||||
Tindakan / Prosedur:
|
||||
Rontgen thorax, darah lengkap
|
||||
|
||||
Expected Result:
|
||||
- ICD-10: J18.9 - Pneumonia dengan kuman tidak spesifik
|
||||
- Prosedur: 87.44 - Foto Rontgen thorax, 90.59 - Pemeriksaan darah lengkap
|
||||
- INA-CBG: B-4-13-I - Pneumonia tanpa komplikasi (Rp 3.500.000)
|
||||
|
||||
TEST CASE 2: KASUS DIABETES + HIPERTENSI
|
||||
========================================
|
||||
Input Form:
|
||||
|
||||
Catatan Medis / Anamnesis:
|
||||
Pasien dengan riwayat diabetes mellitus dan hipertensi datang untuk kontrol rutin.
|
||||
Keluhan poliuria, polidipsia. Tekanan darah tinggi 150/95 mmHg. Kadar gula darah tinggi.
|
||||
|
||||
Tindakan / Prosedur:
|
||||
EKG, pemeriksaan HbA1c
|
||||
|
||||
Expected Result:
|
||||
- ICD-10: E11.9 - Diabetes mellitus tipe 2, I10 - Hipertensi esensial
|
||||
- Prosedur: 89.52 - Elektrokardiogram
|
||||
- INA-CBG: E-4-10-I - Diabetes Mellitus tanpa komplikasi (Rp 2.100.000)
|
||||
|
||||
TEST CASE 3: KASUS GASTRITIS
|
||||
============================
|
||||
Input Form:
|
||||
|
||||
Catatan Medis / Anamnesis:
|
||||
Pasien mengeluh nyeri perut, mual, muntah sejak kemarin. Nyeri seperti terbakar di ulu hati.
|
||||
|
||||
Tindakan / Prosedur:
|
||||
Endoskopi lambung
|
||||
|
||||
Expected Result:
|
||||
- ICD-10: K29.1 - Gastritis akut lainnya
|
||||
- Prosedur: 45.13 - Esofagogastroduodenoskopi (EGD)
|
||||
- INA-CBG: G-4-10-I - Gastritis akut tanpa komplikasi (Rp 1.200.000)
|
||||
|
||||
TEST CASE 4: KASUS TIDAK SPESIFIK
|
||||
=================================
|
||||
Input Form:
|
||||
|
||||
Catatan Medis / Anamnesis:
|
||||
Pasien datang dengan keluhan umum tidak jelas
|
||||
|
||||
Tindakan / Prosedur:
|
||||
Pemeriksaan rutin
|
||||
|
||||
Expected Result:
|
||||
- ICD-10: R69 - Penyakit tidak spesifik
|
||||
- Prosedur: 99213 - Kunjungan rawat jalan
|
||||
- INA-CBG: Z-4-00-I - Kondisi tidak spesifik (Rp 750.000)
|
||||
|
||||
================================================================================
|
||||
4. COSTRECOMMENDATION.TSX - TEST CASES (REKOMENDASI BIAYA)
|
||||
================================================================================
|
||||
|
||||
TEST CASE 1: KASUS DEMAM BERDARAH DENGUE
|
||||
@@ -118,8 +225,8 @@ Expected Result:
|
||||
Analisis AI menunjukkan peringatan potensi overclaim untuk transfusi
|
||||
dengan Hb > 7 g/dL threshold.
|
||||
|
||||
TEST CASE 2: KASUS PNEUMONIA
|
||||
============================
|
||||
TEST CASE 2: KASUS PNEUMONIA COMMUNITY
|
||||
======================================
|
||||
Input Form:
|
||||
|
||||
Diagnosis Klinis:
|
||||
@@ -138,204 +245,153 @@ Tanggal Kunjungan Terakhir: 15 Agustus 2024
|
||||
Expected Result:
|
||||
Analisis biaya dengan koding ICD-10 yang tepat dan rekomendasi pengobatan.
|
||||
|
||||
TEST CASE 3: KASUS DIABETES FOLLOW-UP
|
||||
=====================================
|
||||
Input Form:
|
||||
|
||||
Diagnosis Klinis:
|
||||
Pasien laki-laki 55 tahun dengan diabetes mellitus tipe 2 kontrol
|
||||
rutin. Keluhan poliuria, polidipsia ringan. GDS 180 mg/dL,
|
||||
HbA1c 8.2%. TD 140/90 mmHg. Kaki: tidak ada ulkus, sensasi normal.
|
||||
|
||||
Prosedur/Tindakan:
|
||||
Pemeriksaan HbA1c, GDS, urinalisis, konsultasi gizi,
|
||||
edukasi diabetes, penyesuaian dosis metformin, kontrol rutin 1 bulan.
|
||||
|
||||
Tanggal Kunjungan Terakhir: 5 September 2024
|
||||
|
||||
Expected Result:
|
||||
Peringatan interval kontrol untuk kunjungan dalam 30 hari,
|
||||
koding manajemen diabetes yang tepat.
|
||||
|
||||
================================================================================
|
||||
4. BPJSCODIFICATION.TSX - TEST CASES (KODEFIKASI BPJS)
|
||||
5. SAMPLE DATA UNTUK TESTING
|
||||
================================================================================
|
||||
|
||||
TEST CASE 1: KASUS EMERGENCY - APPENDICITIS AKUT
|
||||
================================================
|
||||
Input Form:
|
||||
CLINICAL PAGE - MOCK DATA:
|
||||
=========================
|
||||
Patient Identity:
|
||||
- Name: John Doe
|
||||
- Medical Record Number: MR2024001
|
||||
- BPJS Number: 0001234567890
|
||||
- Birth Date: 1985-06-15
|
||||
- Gender: Male
|
||||
- Blood Type: O+
|
||||
- Address: Jl. Sudirman No. 123, Jakarta Pusat
|
||||
|
||||
Keluhan Pasien:
|
||||
Nyeri perut kanan bawah sejak 12 jam yang lalu, mula-mula nyeri
|
||||
di epigastrium kemudian berpindah ke fossa iliaka dextra.
|
||||
Disertai mual, muntah 2x, demam subfebris.
|
||||
Medical History:
|
||||
- Previous Diseases: Hypertension (2020), Diabetes Mellitus Type 2 (2021)
|
||||
- Allergies: Penicillin, Shellfish
|
||||
- Current Medications: Metformin 500mg, Lisinopril 10mg
|
||||
|
||||
Pemeriksaan Fisik:
|
||||
TD 110/70 mmHg, nadi 88x/menit, suhu 37.8°C. Abdomen:
|
||||
McBurney sign (+), Rovsing sign (+), defans muskuler (+)
|
||||
regio iliaka dextra. Bising usus normal.
|
||||
Primary Diagnosis: Unstable Angina (I20.0)
|
||||
Secondary: Essential Hypertension (I10), Type 2 Diabetes (E11.9)
|
||||
|
||||
Pemeriksaan Penunjang:
|
||||
Leukosit 12.500/μL dengan shift to left, USG abdomen:
|
||||
appendix menebal dengan fluid collection, foto polos
|
||||
abdomen dalam batas normal.
|
||||
ADMINISTRATIVE PAGE - MOCK DATA:
|
||||
===============================
|
||||
Patient 1:
|
||||
- Name: Ahmad Budi Santoso
|
||||
- Birth Date: 1985-05-10
|
||||
- MRN: MRN2024001
|
||||
- BPJS: 0001234567890
|
||||
- Claim Status: approved
|
||||
- Payment Status: paid
|
||||
- Total Cost: 2,500,000
|
||||
- Admission Type: outpatient
|
||||
|
||||
Diagnosis: Acute appendicitis
|
||||
Patient 2:
|
||||
- Name: Siti Aminah
|
||||
- Birth Date: 1990-11-22
|
||||
- MRN: MRN2024002
|
||||
- BPJS: 0009876543210
|
||||
- Claim Status: under_review
|
||||
- Payment Status: pending
|
||||
- Total Cost: 1,800,000
|
||||
- Admission Type: outpatient
|
||||
|
||||
Tindakan: Appendectomy laparoscopic
|
||||
Patient 3:
|
||||
- Name: Roberto Silva
|
||||
- Birth Date: 1978-03-15
|
||||
- MRN: MRN2024003
|
||||
- BPJS: 0003456789012
|
||||
- Claim Status: pending
|
||||
- Payment Status: partial
|
||||
- Total Cost: 5,200,000
|
||||
- Admission Type: inpatient
|
||||
- Room Class: Kelas 2
|
||||
|
||||
Expected Result:
|
||||
ICD-10 K35.9, kode prosedur untuk laparoscopic appendectomy,
|
||||
mapping INA-CBG dengan tarif bedah.
|
||||
BPJS CODIFICATION - DETECTION KEYWORDS:
|
||||
======================================
|
||||
Pneumonia Keywords: pneumonia, infiltrat, demam, batuk, sesak
|
||||
→ ICD-10: J18.9, INA-CBG: B-4-13-I (Rp 3.500.000)
|
||||
|
||||
TEST CASE 2: KASUS MEDIS - KRISIS HIPERTENSI
|
||||
============================================
|
||||
Input Form:
|
||||
Hypertension Keywords: hipertensi, bp 150/95, tekanan darah tinggi
|
||||
→ ICD-10: I10, INA-CBG: F-4-13-II (Rp 1.850.000)
|
||||
|
||||
Keluhan Pasien:
|
||||
Nyeri kepala hebat sejak pagi, pandangan kabur, mual muntah.
|
||||
Pasien memiliki riwayat hipertensi tidak terkontrol,
|
||||
tidak rutin minum obat.
|
||||
Diabetes Keywords: diabetes, hba1c, glukosa, gula darah
|
||||
→ ICD-10: E11.9, INA-CBG: E-4-10-I (Rp 2.100.000)
|
||||
|
||||
Pemeriksaan Fisik:
|
||||
Kesadaran compos mentis, TD 220/120 mmHg, nadi 95x/menit
|
||||
reguler, RR 20x/menit. Funduskopi: perdarahan retina (+),
|
||||
papil edema (+). JVP tidak meningkat.
|
||||
Gastritis Keywords: gastritis, nyeri perut, mual, muntah
|
||||
→ ICD-10: K29.1, INA-CBG: G-4-10-I (Rp 1.200.000)
|
||||
|
||||
Pemeriksaan Penunjang:
|
||||
EKG: LVH dengan strain pattern, urinalisis: proteinuria +2,
|
||||
kreatinin 1.8 mg/dL, troponin negatif. Foto thorax:
|
||||
kardiomegali dengan pulmonary edema.
|
||||
|
||||
Diagnosis: Hypertensive emergency with target organ damage
|
||||
|
||||
Tindakan: IV antihypertensive therapy, cardiac monitoring
|
||||
|
||||
Expected Result:
|
||||
ICD-10 I16.1, kode prosedur untuk monitoring intensif,
|
||||
INA-CBG untuk emergency hipertensi.
|
||||
|
||||
TEST CASE 3: KASUS OBSTETRIK - PERSALINAN NORMAL
|
||||
================================================
|
||||
Input Form:
|
||||
|
||||
Keluhan Pasien:
|
||||
G2P1A0 usia kehamilan 39 minggu datang dengan keluhan
|
||||
kontraksi uterus teratur sejak 6 jam yang lalu,
|
||||
keluar lendir bercampur darah.
|
||||
|
||||
Pemeriksaan Fisik:
|
||||
TD 120/80 mmHg, nadi 80x/menit, kontraksi uterus 3x/10 menit
|
||||
lamanya 40 detik. VT: pembukaan 6 cm, ketuban (+),
|
||||
presentasi kepala, hodge II.
|
||||
|
||||
Pemeriksaan Penunjang:
|
||||
CTG: reactive, variabilitas baik, tidak ada deselerasi.
|
||||
Hb 11.5 g/dL, golongan darah O Rh+, HbsAg non-reaktif,
|
||||
VDRL non-reaktif.
|
||||
|
||||
Diagnosis: Term pregnancy in labor, vertex presentation
|
||||
|
||||
Tindakan: Spontaneous vaginal delivery, episiotomy
|
||||
|
||||
Expected Result:
|
||||
ICD-10 O80, kode prosedur untuk persalinan dan episiotomy,
|
||||
paket INA-CBG maternal.
|
||||
|
||||
TEST CASE 4: KASUS PEDIATRIK - BRONKIOLITIS
|
||||
===========================================
|
||||
Input Form:
|
||||
|
||||
Keluhan Pasien:
|
||||
Bayi laki-laki 8 bulan dibawa orangtua dengan keluhan
|
||||
sesak napas sejak 2 hari, batuk, demam ringan.
|
||||
Riwayat pilek pada kakak 1 minggu sebelumnya.
|
||||
|
||||
Pemeriksaan Fisik:
|
||||
BB 8 kg, suhu 37.5°C, RR 50x/menit, retraksi intercostal (+),
|
||||
wheezing ekspirasi (+) bilateral, ronki basah halus (+).
|
||||
SpO2 94% udara bebas.
|
||||
|
||||
Pemeriksaan Penunjang:
|
||||
Foto thorax: hiperinflasi bilateral, peribronchial thickening.
|
||||
Rapid test RSV positif. Leukosit 8.500/μL,
|
||||
analisa gas darah normal.
|
||||
|
||||
Diagnosis: Acute bronchiolitis due to RSV
|
||||
|
||||
Tindakan: Oxygen therapy, bronchodilator nebulization, supportive care
|
||||
|
||||
Expected Result:
|
||||
ICD-10 J21.0, kode prosedur untuk respiratory support,
|
||||
tarif INA-CBG pediatrik.
|
||||
Procedure Keywords:
|
||||
- rontgen, x-ray → 87.44 Foto Rontgen thorax
|
||||
- darah lengkap, cbc → 90.59 Pemeriksaan darah lengkap
|
||||
- endoskopi → 45.13 Esofagogastroduodenoskopi
|
||||
- ekg, ecg → 89.52 Elektrokardiogram
|
||||
- usg, ultrasound → 88.76 USG abdomen
|
||||
|
||||
================================================================================
|
||||
5. INSTRUKSI PENGGUNAAN TEST CASES
|
||||
6. INSTRUKSI PENGGUNAAN TEST CASES
|
||||
================================================================================
|
||||
|
||||
PERUBAHAN SCHEMA TERBARU:
|
||||
========================
|
||||
|
||||
1. ADMINISTRATIVE.TSX:
|
||||
✅ Input tunggal untuk Nama/MRN/BPJS (bukan 3 field terpisah)
|
||||
✅ Flexible word matching untuk nama (ahmad santoso → Ahmad Budi Santoso)
|
||||
✅ Case insensitive search
|
||||
✅ Dapat mencari dengan kata parsial
|
||||
|
||||
2. BPJSCODIFICATION.TSX:
|
||||
✅ DIHAPUS: Input "Hasil Laboratorium"
|
||||
✅ Hanya 2 input: Catatan Medis + Prosedur
|
||||
✅ Interface lebih sederhana
|
||||
|
||||
3. CLINICAL.TSX:
|
||||
✅ Tetap sama dengan pencarian fleksibel
|
||||
|
||||
CARA MELAKUKAN TESTING:
|
||||
=======================
|
||||
|
||||
1. CLINICAL.TSX:
|
||||
- Masukkan data pasien sesuai test case
|
||||
- Klik tombol "Cari Rekam Medis"
|
||||
- Verifikasi tampilan rekam medis lengkap
|
||||
- Input: "john" → Harus menemukan "John Doe"
|
||||
- Input: "MR2024001" → Harus menemukan pasien
|
||||
- Input: "0001234567890" → Harus menemukan via BPJS
|
||||
|
||||
2. ADMINISTRATIVE.TSX:
|
||||
- Input data pasien
|
||||
- Klik tombol "Cari Rekam Medis"
|
||||
- Periksa informasi billing/klaim status
|
||||
- Input: "ahmad santoso" → Harus menemukan "Ahmad Budi Santoso"
|
||||
- Input: "siti" → Harus menemukan "Siti Aminah"
|
||||
- Input: "MRN2024001" → Harus menemukan via MRN
|
||||
- Verifikasi flexible word matching
|
||||
|
||||
3. COSTRECOMMENDATION.TSX:
|
||||
- Masukkan diagnosis klinis (copy paste dari test case)
|
||||
- Masukkan prosedur/tindakan
|
||||
- Pilih tanggal kunjungan terakhir
|
||||
- Klik "Analisis Rekomendasi"
|
||||
- Verifikasi analisis AI dan deteksi overclaim
|
||||
3. BPJSCODIFICATION.TSX:
|
||||
- Hanya isi 2 field (bukan 3)
|
||||
- Test dengan keyword: "pneumonia, batuk, sesak"
|
||||
- Prosedur: "rontgen thorax"
|
||||
- Verifikasi ICD-10 dan tarif yang benar
|
||||
|
||||
4. BPJSCODIFICATION.TSX:
|
||||
- Input data klinis lengkap sesuai test case
|
||||
- Klik tombol untuk generate koding
|
||||
- Periksa hasil ICD-10, prosedur, dan mapping INA-CBG
|
||||
4. COSTRECOMMENDATION.TSX:
|
||||
- Copy paste diagnosis klinis lengkap
|
||||
- Isi prosedur/tindakan
|
||||
- Pilih tanggal kunjungan
|
||||
- Verifikasi analisis AI
|
||||
|
||||
PERILAKU YANG DIHARAPKAN:
|
||||
========================
|
||||
TESTING CHECKLIST:
|
||||
==================
|
||||
✓ Search dengan nama parsial berhasil
|
||||
✓ Search case insensitive berfungsi
|
||||
✓ BPJS Codification hanya 2 input field
|
||||
✓ Word matching fleksibel (ahmad santoso → Ahmad Budi Santoso)
|
||||
✓ Loading spinner tampil
|
||||
✓ Error handling untuk data tidak ditemukan
|
||||
✓ Format mata uang Indonesia (Rp)
|
||||
✓ Responsive di mobile dan desktop
|
||||
✓ Konsistensi warna dan UI
|
||||
|
||||
✓ Loading Spinner: Tampil saat proses pencarian/analisis
|
||||
✓ Hasil Lengkap: Informasi pasien/analisis yang komprehensif
|
||||
✓ Error Handling: Pesan yang tepat jika tidak ada hasil
|
||||
✓ Format Tanggal: Format Indonesia di seluruh aplikasi
|
||||
✓ Status Tombol: Disabled/enabled yang tepat
|
||||
✓ Responsive: Berfungsi di berbagai ukuran layar
|
||||
✓ Bahasa Indonesia: Semua text dalam bahasa Indonesia
|
||||
✓ Tema Biru-Putih: Konsistensi warna tombol
|
||||
|
||||
COVERAGE TESTING:
|
||||
================
|
||||
|
||||
✓ Kasus Emergency (Appendicitis)
|
||||
✓ Kasus Medis (Hipertensi, Pneumonia, Diabetes)
|
||||
✓ Kasus Bedah (Appendectomy)
|
||||
✓ Kasus Obstetrik (Persalinan Normal)
|
||||
✓ Kasus Pediatrik (Bronkiolitis)
|
||||
✓ Pencarian Nama, Nomor RM, BPJS
|
||||
✓ Analisis Biaya dan Overclaim
|
||||
✓ Kodefikasi ICD-10 dan INA-CBG
|
||||
EXPECTED BEHAVIOR:
|
||||
==================
|
||||
✓ Pencarian TIDAK mengembalikan "tidak ada data" jika input valid
|
||||
✓ Flexible matching untuk nama dengan urutan kata berbeda
|
||||
✓ Interface yang sederhana dan user-friendly
|
||||
✓ Performance yang responsif
|
||||
✓ Data yang konsisten dan realistis
|
||||
|
||||
================================================================================
|
||||
CATATAN PENTING:
|
||||
================================================================================
|
||||
|
||||
1. Semua test case menggunakan data medis yang realistis
|
||||
2. Format tanggal menggunakan bahasa Indonesia
|
||||
3. Input diagnosis dan prosedur sudah disesuaikan dengan terminologi medis
|
||||
4. Test case mencakup berbagai spesialisasi medis
|
||||
5. Verifikasi response time dan user experience
|
||||
6. Pastikan tidak ada error di console browser
|
||||
7. Test di berbagai browser (Chrome, Firefox, Edge)
|
||||
|
||||
================================================================================
|
||||
CREATED: Desember 2024
|
||||
VERSION: 1.0
|
||||
UPDATED: Desember 2024
|
||||
VERSION: 2.0
|
||||
CHANGES: Updated schema for unified search input and removed lab results field
|
||||
SYSTEM: Claim Guard Frontend - Medical Records Module
|
||||
================================================================================
|
||||
Reference in New Issue
Block a user