improvement: treatments UI/UX updated again to minimize clicking and scrolling.
This commit is contained in:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user