expertise from his3 API and add default.js example

This commit is contained in:
AlfandiMario
2025-10-30 15:36:33 +07:00
parent 25ed4ebfaa
commit 9ab6fb405d
2 changed files with 446 additions and 77 deletions

View File

@@ -341,7 +341,8 @@ const SidePanel = ({
fetchAccessionNumber();
}, [studyInstanceUID]); // Run when studyInstanceUID changes
// Ubah fungsi fetchExpertiseData menjadi dengan parameter accessionNumber
const [expertiseError, setExpertiseError] = useState(null);
const fetchExpertiseData = async accessionNumber => {
try {
// Check if window.config.expertise_host exists
@@ -355,46 +356,45 @@ const SidePanel = ({
return;
}
setIsExpertiseLoading(true);
const url = `${window.config.expertise_host}/nv/query.php?method=view&AccessionNumber=${encodeURIComponent(accessionNumber)}`;
accessionNumber = 'MR.251027.001';
// Debuggging
// const url = 'http://152.42.173.210/nv/testQueryBase64.php';
setIsExpertiseLoading(true);
const url = `${window.config.expertise_host}/${encodeURIComponent(accessionNumber)}`;
const response = await fetch(url);
const data = await response.json();
console.log('Study data:', data);
const resp = await response.json();
console.log('Expertise Resp:', resp);
if (data?.study?.expertise && data.study.expertise.length > 0) {
const expertiseItem = { ...data.study.expertise[0] };
if (resp?.error) {
setExpertiseError(resp.message || resp.error);
return;
}
if (resp?.status_code === 200 && resp?.data) {
const expertiseItem = { ...resp.data };
// Decode base64 encoded fields
// UTF-8 safe base64 decoding
const decodeBase64 = str => {
try {
// Step 1: decode base64 to binary
const binary = atob(str);
// Step 2: create a Uint8Array from the binary string
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
// Step 3: decode the Uint8Array as UTF-8
return new TextDecoder('utf-8').decode(bytes);
} catch (e) {
console.error('Error decoding base64 string:', e);
return str; // Return original if decoding fails
return str;
}
};
// Decode known base64 fields
if (expertiseItem.expertise) {
expertiseItem.expertise = decodeBase64(expertiseItem.expertise);
if (expertiseItem.ekspertiseResult) {
expertiseItem.ekspertiseResult = decodeBase64(expertiseItem.ekspertiseResult);
}
if (expertiseItem.radiologist) {
expertiseItem.radiologist = decodeBase64(expertiseItem.radiologist);
}
// Add any other fields that might be base64 encoded
setExpertiseData(expertiseItem);
}
@@ -416,83 +416,45 @@ const SidePanel = ({
);
}
if (expertiseError) {
return (
<ScrollArea className="border-input bg-background h-[500px] w-full rounded-md border py-2 px-3 text-base text-white">
<h3 className="mb-4 text-lg font-bold">Expertise</h3>
<p className="text-red-500">{expertiseError}</p>
</ScrollArea>
);
}
if (!expertiseData) {
return null;
}
const parseExpertise = text => {
if (!text) return {};
const result = {};
let currentSection = 'Keterangan';
// Split expertise text by lines and process each line
const lines = text.split('\r\n').filter(line => line.trim() !== '');
lines.forEach(line => {
// Check if this is a section header
if (line.includes(':') && !line.trim().startsWith('-')) {
const parts = line.split(':');
currentSection = parts[0].trim();
const value = parts[1]?.trim() || '';
if (value) {
if (!result[currentSection]) {
result[currentSection] = [];
}
result[currentSection].push(value);
}
} else if (line.toLowerCase().includes('kesan')) {
currentSection = 'Kesan';
} else {
// Add line to current section
if (!result[currentSection]) {
result[currentSection] = [];
}
result[currentSection].push(line.trim());
}
});
return result;
};
const parsedSections = parseExpertise(expertiseData.expertise);
// Create formatted data structure
const formattedData = [
{ label: 'Dokter Pengirim', value: expertiseData.ordering_physician || '' },
{ label: 'Dokter Pengirim', value: expertiseData.orderingPhysician || '' },
{ label: 'Dokter Radiologis', value: expertiseData.radiologist || '' },
{ label: 'Waktu Expertise', value: expertiseData.expertise_dttm || '' },
{ label: 'Waktu Expertise', value: expertiseData.expertiseDttm || '' },
];
// Add additional sections from parsed text
Object.entries(parsedSections).forEach(([key, value]) => {
formattedData.push({
label: key,
value: Array.isArray(value) ? value : [value],
});
});
return (
<ScrollArea className="border-input bg-background h-[500px] w-full rounded-md border p-2 text-sm text-white">
<h3 className="mb-4 text-lg font-bold">Expertise</h3>
<ScrollArea className="border-input bg-background h-[800px] w-full rounded-md border py-2 px-3 text-base text-white">
<h3 className="mb-4 text-xl font-bold">Expertise</h3>
{formattedData.map((section, index) => (
<div
key={index}
className="mb-4"
>
<h5 className="text-base font-bold">{section.label}:</h5>
{Array.isArray(section.value) ? (
<ul className="list-disc pl-6">
{section.value.map((item, idx) => (
<li key={idx}>{item}</li>
))}
</ul>
) : (
<p className="break-words">{section.value}</p>
)}
<h5 className="text-lg font-bold">{section.label}:</h5>
<p className="break-words">{section.value}</p>
</div>
))}
<div className="mb-4">
<h5 className="text-lg font-bold">Hasil Expertise:</h5>
<div
className="leading-6"
dangerouslySetInnerHTML={{ __html: expertiseData.ekspertiseResult || '' }}
/>
</div>
</ScrollArea>
);
};