improvement: treatments UI/UX updated again to minimize clicking and scrolling.

This commit is contained in:
2026-08-19 23:59:37 +03:30
parent 29c639f5a1
commit d2f07c0ed3
33 changed files with 1651 additions and 744 deletions

View File

@@ -96,6 +96,7 @@ interface CaseCreatePanelProps {
canEdit: boolean;
onSaved: (detail: LabCaseDetail) => void;
onStarted: (detail: LabCaseDetail) => void;
onDeleted: () => void;
onError: (message: string) => void;
}
@@ -104,6 +105,7 @@ export function CaseCreatePanel({
canEdit,
onSaved,
onStarted,
onDeleted,
onError,
}: CaseCreatePanelProps) {
const t = useTranslations('cases');
@@ -136,11 +138,13 @@ export function CaseCreatePanel({
const [applyAllProsthesis, setApplyAllProsthesis] = useState('');
const [saving, setSaving] = useState(false);
const [starting, setStarting] = useState(false);
const [deleting, setDeleting] = useState(false);
const [uploadBusy, setUploadBusy] = useState(false);
const rangeAnchorRef = useRef<FdiToothId | null>(null);
const hydratedIdRef = useRef(labCase.id);
const skipSaveRef = useRef(true);
const startingRef = useRef(false);
const deletingRef = useRef(false);
const allowPersistWhileStartingRef = useRef(false);
const attachmentInputRef = useRef<HTMLInputElement>(null);
@@ -221,6 +225,9 @@ export function CaseCreatePanel({
);
const persist = useCallback(async () => {
if (deletingRef.current) {
return null;
}
if (startingRef.current && !allowPersistWhileStartingRef.current) {
return null;
}
@@ -251,7 +258,7 @@ export function CaseCreatePanel({
skipSaveRef.current = false;
return;
}
if (!canEdit || startingRef.current) return;
if (!canEdit || startingRef.current || deletingRef.current) return;
const timeout = setTimeout(() => {
void persistRef.current();
}, 500);
@@ -264,6 +271,22 @@ export function CaseCreatePanel({
);
}
async function handleDelete() {
if (!canEdit) return;
if (!window.confirm(t('confirmDeleteDraftCase'))) return;
deletingRef.current = true;
skipSaveRef.current = true;
setDeleting(true);
try {
await casesApi.deleteDraft(labCase.id);
onDeleted();
} catch (error: unknown) {
deletingRef.current = false;
setDeleting(false);
onError(getUserFacingError(error, tErrors, t('errorDeleteCase')));
}
}
async function handleStart() {
if (!canEdit) return;
setStarting(true);
@@ -311,7 +334,7 @@ export function CaseCreatePanel({
}
}
const disabled = !canEdit || starting;
const disabled = !canEdit || starting || deleting;
return (
<div className="space-y-4">
@@ -320,14 +343,24 @@ export function CaseCreatePanel({
<h2 className="text-lg font-semibold text-text-primary">{t('addCaseTitle')}</h2>
<p className="text-sm text-text-muted mt-0.5">{t('addCaseSubtitle')}</p>
</div>
<Button
type="button"
variant="primary"
disabled={disabled || saving}
onClick={() => void handleStart()}
>
{starting ? tCommon('loading') : t('startCase')}
</Button>
<div className="flex flex-wrap items-center gap-2">
<Button
type="button"
variant="danger"
disabled={disabled || saving}
onClick={() => handleDelete()}
>
{tCommon('delete')}
</Button>
<Button
type="button"
variant="primary"
disabled={disabled || saving}
onClick={() => void handleStart()}
>
{starting ? tCommon('loading') : t('startCase')}
</Button>
</div>
</div>
<div className="grid gap-3 sm:grid-cols-2">