PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 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 All 85 releases
← All changes | resources/js/pages/AccountPage.tsx +38 -1 3.0.8 → 3.0.17 View file →
@@ -2,8 +2,9 @@
2 2 import { useQuery } from "@tanstack/react-query";
3 3 import { apiClient } from "../lib/api-client";
4 4 import { API_ENDPOINTS } from "../lib/api-endpoints";
5 5 import { __ } from "../lib/i18n";
6 +import { toDateValue } from "../lib/dateFormat";
6 7 import {
7 8 LayoutDashboard,
8 9 Calendar,
9 10 CreditCard,
@@ -33,8 +34,9 @@
33 34 import Payments from "./account/Payments";
34 35 import Documents from "./account/Documents";
35 36 import Profile from "./account/Profile";
36 37 import SavedTrips from "./account/SavedTrips";
38 +import { useToast } from "../components/ui/toast";
37 39
38 40 const navigation: Array<{
39 41 id: Section;
40 42 label: string;
@@ -49,8 +51,9 @@
49 51 ];
50 52
51 53 const AccountPage: React.FC = () => {
52 54 const accountShell = useMemo(() => getYatraAccountPageGlobals(), []);
55 + const { showToast } = useToast();
53 56
54 57 const accountNavigation = React.useMemo(() => {
55 58 const wl =
56 59 typeof window !== "undefined" &&
@@ -155,8 +158,42 @@
155 158 const newSection = getSectionFromUrl();
156 159 setSection(newSection);
157 160 }, [urlKey]);
158 161
162 + // Surface the result of an email-change confirmation. The confirmation link
163 + // (from WordPress-style verification email) redirects here with
164 + // ?email_change=success|error; show feedback, open the Profile tab, then
165 + // strip the param so a refresh doesn't repeat the toast.
166 + React.useEffect(() => {
167 + if (typeof window === "undefined") {
168 + return;
169 + }
170 + const params = new URLSearchParams(window.location.search);
171 + const outcome = params.get("email_change");
172 + if (outcome !== "success" && outcome !== "error") {
173 + return;
174 + }
175 + if (outcome === "success") {
176 + showToast(__("Your email address has been updated.", "yatra"), "success");
177 + setSection("profile");
178 + } else {
179 + showToast(
180 + __(
181 + "This email confirmation link is invalid or has expired.",
182 + "yatra",
183 + ),
184 + "error",
185 + );
186 + }
187 + params.delete("email_change");
188 + const query = params.toString();
189 + const cleanUrl = `${window.location.pathname}${query ? `?${query}` : ""}`;
190 + window.history.replaceState({}, "", cleanUrl);
191 + (window as any).__lastAccountSearch = window.location.search;
192 + // Run once on mount.
193 + // eslint-disable-next-line react-hooks/exhaustive-deps
194 + }, []);
195 +
159 196 // Update URL and localStorage when section changes
160 197 const handleSectionChange = (newSection: Section) => {
161 198 setSection(newSection);
162 199
@@ -403,9 +440,9 @@
403 440 const outstanding = payments
404 441 .filter((p: Payment) => p.status === "pending")
405 442 .reduce((sum: number, payment: Payment) => sum + payment.amount, 0);
406 443 const upcoming = bookings.filter(
407 - (b: Booking) => new Date(b.travel_date) > new Date(),
444 + (b: Booking) => toDateValue(b.travel_date) > new Date(),
408 445 ).length;
409 446
410 447 // Calculate from real data
411 448 const totalSpent = displayProfile?.total_spent ?? 0;