#566 clean up My Orders page (3 removals)

Per user request on the طلباتي page:

1. Removed the "Clear finished orders" bulk button entirely. The button
   was showing as a raw i18n key (myOrder c...) for the user and they
   asked for it gone. Dropped the related AlertDialog, confirmClearOpen
   state, handleClearFinished handler, and the locale keys
   clearFinished_*, clearConfirmTitle/Body_*, clearConfirm,
   clearedCount_*, and clearedPartial in both ar.json and en.json.

2. Removed the "تراجع / Undo" ToastAction shown after deleting an
   order. The toast now displays only the "Order deleted" title; the
   7-second timer + pendingDeleteIds soft-delete window is preserved
   so the actual DELETE still fires after the grace period. The undo
   closure was deleted since nothing references it anymore. Single-id
   call site stays untouched (scheduleDelete still receives [id]).

3. Removed the "ستتاح لك ثوانٍ قليلة للتراجع" description from the
   cancel-order confirmation dialog. The cancelConfirmBody key was
   dropped from both locales. The AlertDialog now shows only the
   title + the two action buttons.

Out of scope (kept as-is):
- The undo ToastAction after CANCEL (user only asked about delete).
- Incoming-orders page.

Notes:
- ToastAction import is still used by the cancel-undo path.
- Trash2 import still used by the per-card delete button.
- Pre-existing TS error in use-push-subscription.ts is unrelated.
This commit is contained in:
riyadhafraa
2026-05-17 14:07:23 +00:00
parent c3e42fd73e
commit 4c57c58f8c
3 changed files with 10 additions and 123 deletions
+1 -11
View File
@@ -127,7 +127,6 @@
"notesLabel": "ملاحظات:",
"cancel": "إلغاء الطلب",
"cancelConfirmTitle": "إلغاء هذا الطلب؟",
"cancelConfirmBody": "ستتاح لك ثوانٍ قليلة للتراجع.",
"cancelConfirm": "نعم، إلغاء",
"keep": "احتفظ به",
"cancelled": "تم إلغاء الطلب",
@@ -141,16 +140,7 @@
"deleted": "تم حذف الطلب",
"deleteFailed": "تعذّر حذف الطلب",
"undo": "تراجع",
"undone": "تمت الاستعادة",
"clearFinished_one": "مسح طلب منتهٍ",
"clearFinished_other": "مسح {{count}} طلبات منتهية",
"clearConfirmTitle": "مسح الطلبات المنتهية؟",
"clearConfirmBody_one": "سيتم حذف طلب واحد منتهٍ نهائياً من سجلّك.",
"clearConfirmBody_other": "سيتم حذف {{count}} طلبات منتهية نهائياً من سجلّك.",
"clearConfirm": "نعم، امسح",
"clearedCount_one": "تم حذف طلب واحد",
"clearedCount_other": "تم حذف {{count}} طلبات",
"clearedPartial": "تم حذف {{ok}} وفشل {{fail}}"
"undone": "تمت الاستعادة"
},
"orderStatus": {
"pending": "بانتظار المستلِم",
+1 -11
View File
@@ -127,7 +127,6 @@
"notesLabel": "Notes:",
"cancel": "Cancel order",
"cancelConfirmTitle": "Cancel this order?",
"cancelConfirmBody": "You'll have a few seconds to undo this.",
"cancelConfirm": "Yes, cancel",
"keep": "Keep it",
"cancelled": "Order cancelled",
@@ -141,16 +140,7 @@
"deleted": "Order deleted",
"deleteFailed": "Could not delete the order",
"undo": "Undo",
"undone": "Restored",
"clearFinished_one": "Clear 1 finished",
"clearFinished_other": "Clear {{count}} finished",
"clearConfirmTitle": "Clear finished orders?",
"clearConfirmBody_one": "1 finished order will be permanently removed from your history.",
"clearConfirmBody_other": "{{count}} finished orders will be permanently removed from your history.",
"clearConfirm": "Yes, clear",
"clearedCount_one": "1 order deleted",
"clearedCount_other": "{{count}} orders deleted",
"clearedPartial": "{{ok}} deleted, {{fail}} failed"
"undone": "Restored"
},
"orderStatus": {
"pending": "Awaiting receiver",
+8 -101
View File
@@ -309,9 +309,6 @@ function OrderCard({
<AlertDialogTitle>
{t("myOrders.cancelConfirmTitle")}
</AlertDialogTitle>
<AlertDialogDescription>
{t("myOrders.cancelConfirmBody")}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={updateStatus.isPending}>
@@ -369,7 +366,6 @@ export default function MyOrdersPage() {
const lang = i18n.language;
const isRtl = lang === "ar";
const BackIcon = isRtl ? ArrowRight : ArrowLeft;
const [confirmClearOpen, setConfirmClearOpen] = useState(false);
const deleteOrder = useDeleteServiceOrder();
const [pendingDeleteIds, setPendingDeleteIds] = useState<Set<number>>(
() => new Set(),
@@ -438,65 +434,24 @@ export default function MyOrdersPage() {
const timer = setTimeout(() => {
ids.forEach((id) => timersRef.current.delete(id));
void performDelete(ids).then(({ okCount, failCount }) => {
void performDelete(ids).then(({ failCount }) => {
setPendingDeleteIds((prev) => {
const next = new Set(prev);
ids.forEach((id) => next.delete(id));
return next;
});
if (failCount > 0) {
// Restore failed deletions on error so the user sees them again.
setPendingDeleteIds((prev) => {
const next = new Set(prev);
ids.forEach((id) => next.delete(id));
return next;
});
// #224: surface ONE summary toast instead of N error toasts. Total
// failure keeps the existing single-line copy; partial failure
// uses the existing `clearedPartial` key with both counts.
toast({
title:
okCount === 0
? t("myOrders.deleteFailed")
: t("myOrders.clearedPartial", { ok: okCount, fail: failCount }),
title: t("myOrders.deleteFailed"),
variant: "destructive",
});
} else {
setPendingDeleteIds((prev) => {
const next = new Set(prev);
ids.forEach((id) => next.delete(id));
return next;
});
}
});
}, UNDO_WINDOW_MS);
ids.forEach((id) => timersRef.current.set(id, timer));
const undo = () => {
ids.forEach((id) => {
const existing = timersRef.current.get(id);
if (existing) clearTimeout(existing);
timersRef.current.delete(id);
});
setPendingDeleteIds((prev) => {
const next = new Set(prev);
ids.forEach((id) => next.delete(id));
return next;
});
handle.dismiss();
toast({ title: t("myOrders.undone") });
};
// #223: lean on i18next pluralization (clearedCount_one / _other are
// already in both locales) so N=1 reads as "1 order deleted" instead
// of the generic "Order deleted" copy.
const title = t("myOrders.clearedCount", { count: ids.length });
const handle = toast({
title,
duration: UNDO_WINDOW_MS,
action: (
<ToastAction altText={t("myOrders.undo")} onClick={undo}>
{t("myOrders.undo")}
</ToastAction>
),
});
toast({ title: t("myOrders.deleted") });
};
const sortedOrders = orders
@@ -508,14 +463,6 @@ export default function MyOrdersPage() {
)
: [];
const finishedOrders = sortedOrders.filter((o) => isFinished(o.status));
const finishedCount = finishedOrders.length;
const handleClearFinished = () => {
setConfirmClearOpen(false);
scheduleDelete(finishedOrders.map((o) => o.id));
};
return (
<div className="min-h-screen os-bg flex flex-col">
<div className="glass-panel border-b border-slate-200/70 px-4 py-4 flex items-center gap-3 sticky top-0 z-10">
@@ -567,19 +514,6 @@ export default function MyOrdersPage() {
</div>
) : (
<div className="flex flex-col gap-3">
{finishedCount > 0 && (
<div className="flex justify-end">
<Button
variant="ghost"
size="sm"
className="text-slate-600 hover:text-rose-700 hover:bg-rose-50 gap-1.5"
onClick={() => setConfirmClearOpen(true)}
>
<Trash2 size={14} />
{t("myOrders.clearFinished", { count: finishedCount })}
</Button>
</div>
)}
{sortedOrders.map((o) => (
<OrderCard
key={o.id}
@@ -602,33 +536,6 @@ export default function MyOrdersPage() {
)}
</div>
<AlertDialog open={confirmClearOpen} onOpenChange={setConfirmClearOpen}>
<AlertDialogContent dir={lang === "ar" ? "rtl" : "ltr"}>
<AlertDialogHeader>
<AlertDialogTitle>
{t("myOrders.clearConfirmTitle")}
</AlertDialogTitle>
<AlertDialogDescription>
{t("myOrders.clearConfirmBody", { count: finishedCount })}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
{t("myOrders.keep")}
</AlertDialogCancel>
<AlertDialogAction
onClick={(e) => {
e.preventDefault();
handleClearFinished();
}}
className="bg-rose-600 hover:bg-rose-700 text-white"
>
{t("myOrders.clearConfirm")}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<OrderServiceModal
open={reorderTarget !== null}
onOpenChange={(o) => {