improvement: users can now comment on a case and it's details and have an option to make it visible for clinics too.
This commit is contained in:
@@ -2,17 +2,19 @@
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { MessageSquare } from 'lucide-react';
|
||||
import { formatApiErrorMessage } from '@/components/shared/formatApiError';
|
||||
import { useAuth } from '@/lib/hooks/useAuth';
|
||||
import { useToast } from '@/lib/hooks/useToast';
|
||||
import { organizationApi } from '@/lib/api/organization';
|
||||
import { treatmentCatalogApi } from '@/lib/api/treatment-catalog';
|
||||
import { treatmentTypeLabelFromCatalog } from '@/components/ui/treatment/treatmentTypeDisplay';
|
||||
import { Badge, type BadgeVariant } from '@/components/ui/shared/Badge';
|
||||
import { Badge } from '@/components/ui/shared/Badge';
|
||||
import { Button } from '@/components/ui/shared/Button';
|
||||
import { SearchBar } from '@/components/ui/shared/SearchBar';
|
||||
import { ToastStack } from '@/components/ui/shared/Toast';
|
||||
import { LabCaseCommentsPanel } from '@/components/ui/lab/LabCaseCommentsPanel';
|
||||
import { labTaskStatusVariant } from '@/components/ui/lab/labTaskStatusDisplay';
|
||||
import {
|
||||
formatToothList,
|
||||
prosthesisTypeBadgeStyle,
|
||||
@@ -23,17 +25,6 @@ import type { TreatmentCatalogEntry } from '@/types/treatment-catalog';
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
function taskStatusVariant(status: LabTaskStatus): BadgeVariant {
|
||||
switch (status) {
|
||||
case 'COMPLETED':
|
||||
return 'success';
|
||||
case 'IN_PROGRESS':
|
||||
return 'default';
|
||||
default:
|
||||
return 'warning';
|
||||
}
|
||||
}
|
||||
|
||||
function formatPatientName(patient: { firstName: string; lastName: string }) {
|
||||
return `${patient.firstName} ${patient.lastName}`.trim();
|
||||
}
|
||||
@@ -96,6 +87,7 @@ export function ConnectionCaseHistoryContent({
|
||||
const [treatmentCatalog, setTreatmentCatalog] = useState<TreatmentCatalogEntry[]>([]);
|
||||
const [loadingList, setLoadingList] = useState(false);
|
||||
const [loadingDetail, setLoadingDetail] = useState(false);
|
||||
const [commentCount, setCommentCount] = useState(0);
|
||||
|
||||
const locale = user?.language ?? 'en';
|
||||
const isClinic = currentOrganization?.type === 'CLINIC';
|
||||
@@ -154,11 +146,21 @@ export function ConnectionCaseHistoryContent({
|
||||
useEffect(() => {
|
||||
if (!selectedCaseId) {
|
||||
setSelectedCase(null);
|
||||
setCommentCount(0);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
void organizationApi
|
||||
.listConnectionCaseComments(connection.id, selectedCaseId)
|
||||
.then((r) => {
|
||||
if (!cancelled) setCommentCount(r.data.length);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) setCommentCount(0);
|
||||
});
|
||||
|
||||
void (async () => {
|
||||
setLoadingDetail(true);
|
||||
setError('');
|
||||
@@ -180,6 +182,10 @@ export function ConnectionCaseHistoryContent({
|
||||
};
|
||||
}, [selectedCaseId, connection.id, showError, setError]);
|
||||
|
||||
function scrollToComments() {
|
||||
document.getElementById('case-comments')?.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
@@ -300,9 +306,19 @@ export function ConnectionCaseHistoryContent({
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<header className="space-y-1 border-b border-border pb-3">
|
||||
<h2 className="text-lg font-semibold text-text-primary">
|
||||
{formatPatientName(selectedCase.patient)}
|
||||
</h2>
|
||||
<div className="flex flex-wrap items-start justify-between gap-2">
|
||||
<h2 className="text-lg font-semibold text-text-primary">
|
||||
{formatPatientName(selectedCase.patient)}
|
||||
</h2>
|
||||
{isClinic ? (
|
||||
<Button type="button" variant="outline" size="sm" onClick={scrollToComments}>
|
||||
<MessageSquare className="h-4 w-4 me-1.5" />
|
||||
{commentCount > 0
|
||||
? tCases('commentsCount', { count: commentCount })
|
||||
: tCases('showComments')}
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
<p className="text-sm text-text-muted">
|
||||
{tCases('patientMobile')}: {selectedCase.patient.mobile}
|
||||
</p>
|
||||
@@ -330,12 +346,6 @@ export function ConnectionCaseHistoryContent({
|
||||
total={selectedCase.taskProgress.total}
|
||||
/>
|
||||
</div>
|
||||
{selectedCase.labComment ? (
|
||||
<p className="text-sm text-text-muted pt-1">
|
||||
<span className="font-medium text-text-primary">{tCases('labComment')}:</span>{' '}
|
||||
{selectedCase.labComment}
|
||||
</p>
|
||||
) : null}
|
||||
</header>
|
||||
|
||||
{selectedCase.details.length > 0 && (
|
||||
@@ -395,7 +405,7 @@ export function ConnectionCaseHistoryContent({
|
||||
<span className="min-w-0 flex-1">
|
||||
{task.stepOrder}. {task.stepLabel}
|
||||
</span>
|
||||
<Badge variant={taskStatusVariant(task.status)} fixedWidth={false}>
|
||||
<Badge variant={labTaskStatusVariant(task.status)} fixedWidth={false}>
|
||||
{statusOptions.find((opt) => opt.value === task.status)?.label ??
|
||||
task.status}
|
||||
</Badge>
|
||||
@@ -413,27 +423,31 @@ export function ConnectionCaseHistoryContent({
|
||||
</div>
|
||||
|
||||
{isClinic && selectedCaseId ? (
|
||||
<LabCaseCommentsPanel
|
||||
caseId={selectedCaseId}
|
||||
canPost
|
||||
canToggleVisibility={false}
|
||||
loadComments={async () => {
|
||||
const r = await organizationApi.listConnectionCaseComments(
|
||||
connection.id,
|
||||
selectedCaseId,
|
||||
);
|
||||
return r.data;
|
||||
}}
|
||||
onPost={async (body) => {
|
||||
const r = await organizationApi.addConnectionCaseComment(
|
||||
connection.id,
|
||||
selectedCaseId,
|
||||
body,
|
||||
);
|
||||
return r.data;
|
||||
}}
|
||||
onError={showError}
|
||||
/>
|
||||
<section id="case-comments" className="scroll-mt-4 border-t border-border pt-4">
|
||||
<LabCaseCommentsPanel
|
||||
caseId={selectedCaseId}
|
||||
canPost
|
||||
canToggleVisibility={false}
|
||||
loadComments={async () => {
|
||||
const r = await organizationApi.listConnectionCaseComments(
|
||||
connection.id,
|
||||
selectedCaseId,
|
||||
);
|
||||
setCommentCount(r.data.length);
|
||||
return r.data;
|
||||
}}
|
||||
onPost={async (body) => {
|
||||
const r = await organizationApi.addConnectionCaseComment(
|
||||
connection.id,
|
||||
selectedCaseId,
|
||||
body,
|
||||
);
|
||||
setCommentCount((n) => n + 1);
|
||||
return r.data;
|
||||
}}
|
||||
onError={showError}
|
||||
/>
|
||||
</section>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user