#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:
@@ -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": "بانتظار المستلِم",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user