PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | resources/js/pages/RecurringRulesPage.tsx +29 -11 3.0.4 → 3.0.16 View file →
@@ -17,8 +17,9 @@
17 17 CheckCircle,
18 18 XCircle,
19 19 } from "lucide-react";
20 20 import { __ } from "../lib/i18n";
21 +import { toDateValue } from "../lib/dateFormat";
21 22 import { Button } from "../components/ui/button";
22 23 import { Input } from "../components/ui/input";
23 24 import { Select } from "../components/ui/select";
24 25 import { PageHeader } from "../components/common/PageHeader";
@@ -64,8 +65,10 @@
64 65 ? parseInt(urlParams.get("trip_id")!)
65 66 : null;
66 67
67 68 // Filters and search
69 + const [bulkDeleteConfirm, setBulkDeleteConfirm] = useState(false);
70 +
68 71 const [searchTerm, setSearchTerm] = useState("");
69 72 const [statusFilter, setStatusFilter] = useState("all");
70 73 const [page, setPage] = useState(1);
71 74
@@ -197,18 +200,11 @@
197 200 if (!bulkAction || selectedIds.length === 0) return;
198 201
199 202 switch (bulkAction) {
200 203 case "delete":
201 - if (
202 - confirm(
203 - __(
204 - "Are you sure you want to delete {count} rule(s)?",
205 - "yatra",
206 - ).replace("{count}", selectedIds.length.toString()),
207 - )
208 - ) {
209 - bulkDeleteMutation.mutate(selectedIds);
210 - }
204 + // Confirmed through the shared dialog, matching the single-rule delete
205 + // already used on this page.
206 + setBulkDeleteConfirm(true);
211 207 break;
212 208 }
213 209
214 210 setBulkAction("");
@@ -226,12 +222,13 @@
226 222 setPage(1);
227 223 };
228 224
229 225 // Format helpers
226 + // eslint-disable-next-line react-hooks/exhaustive-deps
230 227 const formatDate = (dateString: string | null | undefined): string => {
231 228 if (!dateString) return "--";
232 229 try {
233 - const date = new Date(dateString);
230 + const date = toDateValue(dateString);
234 231 return date.toLocaleDateString("en-US", {
235 232 year: "numeric",
236 233 month: "short",
237 234 day: "numeric",
@@ -240,8 +237,9 @@
240 237 return dateString;
241 238 }
242 239 };
243 240
241 + // eslint-disable-next-line react-hooks/exhaustive-deps
244 242 const getRuleTypeLabel = (type: string): string => {
245 243 const labels: Record<string, string> = {
246 244 weekly: __("Weekly", "yatra"),
247 245 monthly: __("Monthly", "yatra"),
@@ -249,8 +247,9 @@
249 247 };
250 248 return labels[type] || type;
251 249 };
252 250
251 + // eslint-disable-next-line react-hooks/exhaustive-deps
253 252 const getWeekdaysLabel = (rule: RecurringRule): string => {
254 253 const weekdays =
255 254 rule.days_of_week_array ||
256 255 (rule.days_of_week ? rule.days_of_week.split(",").map(Number) : []);
@@ -266,8 +265,9 @@
266 265 ];
267 266 return weekdays.map((d) => dayNames[d]).join(", ");
268 267 };
269 268
269 + // eslint-disable-next-line react-hooks/exhaustive-deps
270 270 const getStatusBadge = (status: string) => {
271 271 const statusConfig: Record<
272 272 string,
273 273 { label: string; className: string; icon: React.ReactNode }
@@ -638,8 +638,26 @@
638 638 </CardContent>
639 639 </Card>
640 640 </>
641 641 )}
642 +
643 + <ConfirmationDialog
644 + isOpen={bulkDeleteConfirm}
645 + onClose={() => setBulkDeleteConfirm(false)}
646 + onConfirm={() => {
647 + bulkDeleteMutation.mutate(selectedIds);
648 + setBulkDeleteConfirm(false);
649 + }}
650 + title={__("Delete Rules", "yatra")}
651 + message={__(
652 + "Are you sure you want to delete {count} rule(s)? This action cannot be undone.",
653 + "yatra",
654 + ).replace("{count}", selectedIds.length.toString())}
655 + confirmText={__("Delete", "yatra")}
656 + cancelText={__("Cancel", "yatra")}
657 + variant="danger"
658 + isLoading={bulkDeleteMutation.isPending}
659 + />
642 660 </div>
643 661 );
644 662 };
645 663