improvement: treatment UX fully overhauled.

This commit is contained in:
2026-07-13 01:03:26 +03:30
parent abf0371a5b
commit f28cd06615
27 changed files with 1370 additions and 212 deletions

View File

@@ -12,6 +12,14 @@ import {
import type { TreatmentDetailDraft } from '@/types/treatment';
import type { TreatmentCatalogEntry } from '@/types/treatment-catalog';
import { treatmentTypeColor } from '@/components/shared/treatmentTypeDisplay';
import {
canCommentOnDetailLabCase,
isDetailReadyForLabDispatch,
isDetailTypeSelected,
isLabDependentDetailMissingTeeth,
} from '@/components/treatment/treatmentDetailRules';
import { DetailLabCaseCommentsSection } from '@/components/ui/treatment/DetailLabCaseCommentsSection';
import { labBlockedBannerClass } from '@/components/treatment/treatmentStatusStyles';
interface TreatmentDetailsEditorProps {
details: TreatmentDetailDraft[];
@@ -27,6 +35,7 @@ interface TreatmentDetailsEditorProps {
uploadBusy: boolean;
onAddDetail: () => void;
onUploadFiles: (files: FileList | null) => void;
onCommentError?: (message: string) => void;
}
export function TreatmentDetailsEditor({
@@ -43,6 +52,7 @@ export function TreatmentDetailsEditor({
uploadBusy,
onAddDetail,
onUploadFiles,
onCommentError,
}: TreatmentDetailsEditorProps) {
const t = useTranslations('treatment');
const attachmentInputRef = useRef<HTMLInputElement>(null);
@@ -52,12 +62,19 @@ export function TreatmentDetailsEditor({
const locked = isDetailLocked(activeDetail);
const readOnly = disabled || locked;
const treatmentTypeTextColor = treatmentTypeColor(
activeDetail.treatmentType,
treatmentCatalog.findIndex((e) => e.code === activeDetail.treatmentType),
const treatmentTypeTextColor = isDetailTypeSelected(activeDetail)
? treatmentTypeColor(
activeDetail.treatmentType,
treatmentCatalog.findIndex((e) => e.code === activeDetail.treatmentType),
)
: undefined;
const showPendingLabHint =
isDetailReadyForLabDispatch(activeDetail, labDependentCodes) && !locked && !readOnly;
const showMissingTeethLabBlock = isLabDependentDetailMissingTeeth(
activeDetail,
labDependentCodes,
);
const isLabDependent = labDependentCodes.has(activeDetail.treatmentType);
const showPendingLabHint = isLabDependent && !locked && !readOnly;
const showLabCaseComments = canCommentOnDetailLabCase(activeDetail);
return (
<div className="surface-card p-3 sm:p-4 space-y-4">
@@ -107,6 +124,9 @@ export function TreatmentDetailsEditor({
{showPendingLabHint && (
<p className={labPendingBannerClass}>{t('detailPendingLabSend')}</p>
)}
{showMissingTeethLabBlock && (
<p className={labBlockedBannerClass}>{t('labShipmentBlockedBody')}</p>
)}
<label className="block text-xs font-medium text-text-secondary">
{t('comments')}
@@ -140,6 +160,7 @@ export function TreatmentDetailsEditor({
disabled={readOnly}
style={{ color: treatmentTypeTextColor }}
>
<option value="">{t('treatmentTypePlaceholder')}</option>
{treatmentCatalog.map((entry, index) => (
<option
key={entry.code}
@@ -192,6 +213,14 @@ export function TreatmentDetailsEditor({
</div>
</div>
{showLabCaseComments ? (
<DetailLabCaseCommentsSection
detail={activeDetail}
canPost={canEdit && !disabled}
onError={onCommentError}
/>
) : null}
{canEdit && saveStatus !== 'idle' && (
<p
className={`text-xs pt-2 border-t border-border/60 ${autosaveStatusClass(saveStatus)}`}