From 0e8045d9a2f4a5bfc472fecb802c912516fed02e Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 16:50:09 +0530 Subject: [PATCH 1/8] add navigation to the footer links --- src/AppRouter.tsx | 2 +- src/components/FooterBottom.tsx | 6 +- src/components/FooterNavigation.tsx | 98 ++++++++--------------------- src/components/MelbourneFAQ.tsx | 12 ++-- src/utils/footerConstants.ts | 16 +++-- 5 files changed, 46 insertions(+), 88 deletions(-) diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index ed1dd57..5671705 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -293,7 +293,7 @@ export function AppRouter({ - + } /> diff --git a/src/components/FooterBottom.tsx b/src/components/FooterBottom.tsx index f11d8ca..c32da0b 100644 --- a/src/components/FooterBottom.tsx +++ b/src/components/FooterBottom.tsx @@ -17,13 +17,13 @@ export function FooterBottom({ onPrivacyPolicyClick }: FooterBottomProps) {
{/* Copyright */}

- © 2024 CityCards. All rights reserved. + © 2026 CityCards. All rights reserved.

{/* Right Section - Legal Links and Social Icons */}
{/* Legal Links */} -
+ {/*
Cookie Policy -
+
*/} {/* Social Icons - Horizontal Layout */}
diff --git a/src/components/FooterNavigation.tsx b/src/components/FooterNavigation.tsx index f05d37d..a6dad8f 100644 --- a/src/components/FooterNavigation.tsx +++ b/src/components/FooterNavigation.tsx @@ -1,37 +1,21 @@ import { motion } from 'motion/react'; import { footerSections } from '../utils/footerConstants'; +import { Link } from 'react-router-dom'; -interface FooterNavigationProps { - onHomeClick?: () => void; - onMelbourneClick?: () => void; - onPassesClick?: () => void; - onSignInClick?: () => void; - onAttractionsClick?: () => void; - onBlogsClick?: () => void; - onHowItWorksClick?: () => void; - onFAQClick?: () => void; - onPrivacyPolicyClick?: () => void; - onAboutUsClick?: () => void; - onContactUsClick?: () => void; - currentPage?: string; -} +const linkRoutes: Record = { + 'Home': '/', + // 'Cancellation policy': '/cancellation-policy', + 'How It Works': '/how-it-works', + 'FAQ': '/faq', + 'Blog': '/blogs', + 'Contact Us': '/contact-us', + 'Privacy Policy': '/privacy-policy', + // 'Terms of Service': '/terms', +}; -export function FooterNavigation({ - onHomeClick, - onMelbourneClick, - onPassesClick, - onSignInClick, - onAttractionsClick, - onBlogsClick, - onHowItWorksClick, - onFAQClick, - onPrivacyPolicyClick, - onAboutUsClick, - onContactUsClick, - currentPage -}: FooterNavigationProps) { +export function FooterNavigation() { return ( -
+
{Object.entries(footerSections).map(([key, section]) => (

{section.title}

+
    - {section.links.map((link, index) => { - const getClickHandler = () => { - switch (link) { - case 'Home': return onHomeClick; - case 'Melbourne': return onMelbourneClick; - case 'Passes': return onPassesClick; - case 'Sign In': return onSignInClick; - case 'Attractions': return onAttractionsClick; - case 'Blog': return onBlogsClick; - case 'How It Works': return onHowItWorksClick; - case 'FAQ': return onFAQClick; - case 'Privacy Policy': return onPrivacyPolicyClick; - case 'Contact Us': return onContactUsClick; - default: return undefined; - } - }; - - const clickHandler = getClickHandler(); - - return ( -
  • - {clickHandler ? ( - { - e.preventDefault(); - clickHandler(); - }} - className="text-white/80 hover:text-white transition-colors duration-200 text-sm text-left" - whileHover={{ x: 4 }} - transition={{ duration: 0.2 }} - > - {link} - - ) : ( - - {link} - - )} -
  • - ); - })} + {section.links.map((link) => ( +
  • + + + {link} + + +
  • + ))}
))} diff --git a/src/components/MelbourneFAQ.tsx b/src/components/MelbourneFAQ.tsx index b9c4e83..bf7d1f4 100644 --- a/src/components/MelbourneFAQ.tsx +++ b/src/components/MelbourneFAQ.tsx @@ -19,12 +19,12 @@ import { } from "./ui/accordion"; const faqData = [ - { - id: "refund", - question: "Can I get a refund on my Melbourne CityCard?", - answer: "Yes, you can cancel your Melbourne CityCard and receive a full refund if you cancel at least 24 hours in advance of your selected start date. For cancellations within 24 hours, refunds are subject to our cancellation policy. Digital cards can be refunded instantly through your account.", - icon: CreditCard - }, + // { + // id: "refund", + // question: "Can I get a refund on my Melbourne CityCard?", + // answer: "Yes, you can cancel your Melbourne CityCard and receive a full refund if you cancel at least 24 hours in advance of your selected start date. For cancellations within 24 hours, refunds are subject to our cancellation policy. Digital cards can be refunded instantly through your account.", + // icon: CreditCard + // }, { id: "duration", question: "How long is my Melbourne CityCard valid?", diff --git a/src/utils/footerConstants.ts b/src/utils/footerConstants.ts index 86afdeb..ef31a2b 100644 --- a/src/utils/footerConstants.ts +++ b/src/utils/footerConstants.ts @@ -1,16 +1,20 @@ export const footerSections = { explore: { title: 'Explore', - links: ['Home', 'My Adventures', 'Cancellation policy'] + links: ['Home', + 'Cancellation policy' + ] }, learn: { title: 'Learn', - links: ['How It Works', 'Safety Tips', 'FAQ', 'Blog'] - }, - community: { - title: 'Community', - links: ['Testimonials', 'Partner Stories', 'Events & Meetups', 'Newsletter'] + links: ['How It Works', + // 'Safety Tips', + 'FAQ', 'Blog'] }, + // community: { + // title: 'Community', + // links: ['Testimonials', 'Partner Stories', 'Events & Meetups', 'Newsletter'] + // }, support: { title: 'Support', links: ['Contact Us', 'Privacy Policy', 'Terms of Service'] From 27382c45e389eac4bb36202fe112bce125b61099 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 17:00:41 +0530 Subject: [PATCH 2/8] round off the tax amount before adding to cart --- src/pages/CheckoutPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/CheckoutPage.tsx b/src/pages/CheckoutPage.tsx index 3464eca..a9465fe 100644 --- a/src/pages/CheckoutPage.tsx +++ b/src/pages/CheckoutPage.tsx @@ -151,7 +151,7 @@ function CheckoutConfigCard({ const adultPrice = item?.adultPrice * noOfAdults const childPrice = item?.childPrice * noOfChildren const basePrice = adultPrice + childPrice - const taxAmount = basePrice * 0.1 + const taxAmount = Math.round(basePrice * 0.1) const strikedPrice = basePrice + 20 const [addCardToCart] = useAddCardToCartMutation() From 420d2038f2070707c834d38c0fb71cc6fbc800ef Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 17:48:48 +0530 Subject: [PATCH 3/8] add validations in register page --- src/components/RegisterPage.tsx | 405 +++++++++++++++++--------------- 1 file changed, 221 insertions(+), 184 deletions(-) diff --git a/src/components/RegisterPage.tsx b/src/components/RegisterPage.tsx index f6ea833..32f9e07 100644 --- a/src/components/RegisterPage.tsx +++ b/src/components/RegisterPage.tsx @@ -37,19 +37,56 @@ export default function RegisterPage() { setFormData(prev => ({ ...prev, [field]: value })); }; - const validateForm = () => { - if (!formData.firstName.trim()) return toast.error('First name is required'), false; - if (!formData.lastName.trim()) return toast.error('Last name is required'), false; - if (!formData.emailAddress.includes('@')) return toast.error('Invalid email address'), false; - if (!formData.isdCode.startsWith("+")) toast.error("ISD code must start with '+'"), false; - if (!/^\+\d+$/.test(formData.isdCode)) toast.error("ISD code must contain only numbers after '+'"), false; - if (!/^\d+$/.test(formData.mobileNumber)) return toast.error('Invalid mobile number'), false; - if (!formData.address1.trim()) return toast.error('Address required'), false; - if (!formData.city.trim()) return toast.error('City required'), false; - if (!formData.state.trim()) return toast.error('State required'), false; - if (!/^\d+$/.test(formData.postalCode)) return toast.error('Postal code should only contain numbers'), false; - return true; - }; + const validateForm = () => { + // First Name + if (!formData.firstName.trim()) return toast.error('First name is required'), false; + if (!/^[A-Za-z]+$/.test(formData.firstName)) return toast.error('First name must contain only alphabets'), false; + if (formData.firstName.length < 2 || formData.firstName.length > 50) return toast.error('First name must be between 2 and 50 characters'), false; + + // Last Name + if (!formData.lastName.trim()) return toast.error('Last name is required'), false; + if (!/^[A-Za-z]+$/.test(formData.lastName)) return toast.error('Last name must contain only alphabets'), false; + if (formData.lastName.length < 2 || formData.lastName.length > 50) return toast.error('Last name must be between 2 and 50 characters'), false; + + // Email + if (!formData.emailAddress.includes('@')) return toast.error('Invalid email address'), false; + + // ISD Code + if (!formData.isdCode.startsWith("+")) return toast.error("ISD code must start with '+'"), false; + if (!/^\+\d+$/.test(formData.isdCode)) return toast.error("ISD code must contain only numbers after '+'"), false; + + // Mobile Number + if (!/^\d+$/.test(formData.mobileNumber)) return toast.error('Invalid mobile number'), false; + if (formData.mobileNumber.length < 7 || formData.mobileNumber.length > 15) return toast.error('Mobile number must be between 7 and 15 digits'), false; + + // Address Line 1 + if (!formData.address1.trim()) return toast.error('Address required'), false; + if (!/^[A-Za-z0-9\s]+$/.test(formData.address1)) return toast.error('Address must be alphanumeric'), false; + if (formData.address1.length < 5 || formData.address1.length > 100) return toast.error('Address must be between 5 and 100 characters'), false; + + // City + if (!formData.city.trim()) return toast.error('City required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.city)) return toast.error('City must contain only alphabets'), false; + if (formData.city.length < 2 || formData.city.length > 50) return toast.error('City must be between 2 and 50 characters'), false; + + // State + if (!formData.state.trim()) return toast.error('State required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.state)) return toast.error('State must contain only alphabets'), false; + if (formData.state.length < 2 || formData.state.length > 50) return toast.error('State must be between 2 and 50 characters'), false; + + // Country + if (!formData.country.trim()) return toast.error('Country required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.country)) return toast.error('Country must contain only alphabets'), false; + if (formData.country.length < 2 || formData.country.length > 50) return toast.error('Country must be between 2 and 50 characters'), false; + + // Postal Code + if (!/^\d+$/.test(formData.postalCode)) return toast.error('Postal code should only contain numbers'), false; + if (formData.postalCode.length < 4 || formData.postalCode.length > 10) return toast.error('Postal code must be between 4 and 10 digits'), false; + + return true; +}; + + const handleRegister = async () => { if (!validateForm()) return; @@ -79,182 +116,182 @@ export default function RegisterPage() { }; return ( -
- {/* Navbar */} - +
+ {/* Navbar */} + - {/* Main Content */} -
-
+ {/* Main Content */} +
+
- {/* Header */} -
-

- Create Account -

-

- Register to get started with City Cards -

+ {/* Header */} +
+

+ Create Account +

+

+ Register to get started with City Cards +

+
+ + {/* Form Container */} +
+ + {/* Personal Info */} +
+

+ Personal Information +

+ +
+
+ + handleInputChange('firstName', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+ + handleInputChange('lastName', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+
+ +
+ + handleInputChange('emailAddress', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+
+ + handleInputChange('isdCode', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+ + handleInputChange('mobileNumber', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+
+
+ + {/* Address */} +
+

+ Address Information +

+ +
+ + handleInputChange('address1', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+ + handleInputChange('address2', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+
+ + handleInputChange('city', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+ + handleInputChange('state', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+
+ +
+
+ + handleInputChange('country', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+ +
+ + handleInputChange('postalCode', e.target.value)} + className="h-12 bg-gray-50 border-0 rounded-xl mt-1" + /> +
+
+
+ + {helperText && ( +

{helperText}

+ )} + + + +
+
- {/* Form Container */} -
- - {/* Personal Info */} -
-

- Personal Information -

- -
-
- - handleInputChange('firstName', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
- - handleInputChange('lastName', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
-
- -
- - handleInputChange('emailAddress', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
-
- - handleInputChange('isdCode', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
- - handleInputChange('mobileNumber', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
-
-
- - {/* Address */} -
-

- Address Information -

- -
- - handleInputChange('address1', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
- - handleInputChange('address2', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
-
- - handleInputChange('city', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
- - handleInputChange('state', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
-
- -
-
- - handleInputChange('country', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
- -
- - handleInputChange('postalCode', e.target.value)} - className="h-12 bg-gray-50 border-0 rounded-xl mt-1" - /> -
-
-
- - {helperText && ( -

{helperText}

- )} - - - + {/* Footer */} +
+
-
- - {/* Footer */} -
-
-
-
); } \ No newline at end of file From 977eecd4d8a83fa8ea7bd3f1fa7287e4da8b6643 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 17:51:12 +0530 Subject: [PATCH 4/8] add indentation in register page --- src/components/RegisterPage.tsx | 76 ++++++++++++++++----------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/components/RegisterPage.tsx b/src/components/RegisterPage.tsx index 32f9e07..89adc60 100644 --- a/src/components/RegisterPage.tsx +++ b/src/components/RegisterPage.tsx @@ -37,54 +37,54 @@ export default function RegisterPage() { setFormData(prev => ({ ...prev, [field]: value })); }; - const validateForm = () => { - // First Name - if (!formData.firstName.trim()) return toast.error('First name is required'), false; - if (!/^[A-Za-z]+$/.test(formData.firstName)) return toast.error('First name must contain only alphabets'), false; - if (formData.firstName.length < 2 || formData.firstName.length > 50) return toast.error('First name must be between 2 and 50 characters'), false; + const validateForm = () => { + // First Name + if (!formData.firstName.trim()) return toast.error('First name is required'), false; + if (!/^[A-Za-z]+$/.test(formData.firstName)) return toast.error('First name must contain only alphabets'), false; + if (formData.firstName.length < 2 || formData.firstName.length > 50) return toast.error('First name must be between 2 and 50 characters'), false; - // Last Name - if (!formData.lastName.trim()) return toast.error('Last name is required'), false; - if (!/^[A-Za-z]+$/.test(formData.lastName)) return toast.error('Last name must contain only alphabets'), false; - if (formData.lastName.length < 2 || formData.lastName.length > 50) return toast.error('Last name must be between 2 and 50 characters'), false; + // Last Name + if (!formData.lastName.trim()) return toast.error('Last name is required'), false; + if (!/^[A-Za-z]+$/.test(formData.lastName)) return toast.error('Last name must contain only alphabets'), false; + if (formData.lastName.length < 2 || formData.lastName.length > 50) return toast.error('Last name must be between 2 and 50 characters'), false; - // Email - if (!formData.emailAddress.includes('@')) return toast.error('Invalid email address'), false; + // Email + if (!formData.emailAddress.includes('@')) return toast.error('Invalid email address'), false; - // ISD Code - if (!formData.isdCode.startsWith("+")) return toast.error("ISD code must start with '+'"), false; - if (!/^\+\d+$/.test(formData.isdCode)) return toast.error("ISD code must contain only numbers after '+'"), false; + // ISD Code + if (!formData.isdCode.startsWith("+")) return toast.error("ISD code must start with '+'"), false; + if (!/^\+\d+$/.test(formData.isdCode)) return toast.error("ISD code must contain only numbers after '+'"), false; - // Mobile Number - if (!/^\d+$/.test(formData.mobileNumber)) return toast.error('Invalid mobile number'), false; - if (formData.mobileNumber.length < 7 || formData.mobileNumber.length > 15) return toast.error('Mobile number must be between 7 and 15 digits'), false; + // Mobile Number + if (!/^\d+$/.test(formData.mobileNumber)) return toast.error('Invalid mobile number'), false; + if (formData.mobileNumber.length < 7 || formData.mobileNumber.length > 15) return toast.error('Mobile number must be between 7 and 15 digits'), false; - // Address Line 1 - if (!formData.address1.trim()) return toast.error('Address required'), false; - if (!/^[A-Za-z0-9\s]+$/.test(formData.address1)) return toast.error('Address must be alphanumeric'), false; - if (formData.address1.length < 5 || formData.address1.length > 100) return toast.error('Address must be between 5 and 100 characters'), false; + // Address Line 1 + if (!formData.address1.trim()) return toast.error('Address required'), false; + if (!/^[A-Za-z0-9\s]+$/.test(formData.address1)) return toast.error('Address must be alphanumeric'), false; + if (formData.address1.length < 5 || formData.address1.length > 100) return toast.error('Address must be between 5 and 100 characters'), false; - // City - if (!formData.city.trim()) return toast.error('City required'), false; - if (!/^[A-Za-z\s]+$/.test(formData.city)) return toast.error('City must contain only alphabets'), false; - if (formData.city.length < 2 || formData.city.length > 50) return toast.error('City must be between 2 and 50 characters'), false; + // City + if (!formData.city.trim()) return toast.error('City required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.city)) return toast.error('City must contain only alphabets'), false; + if (formData.city.length < 2 || formData.city.length > 50) return toast.error('City must be between 2 and 50 characters'), false; - // State - if (!formData.state.trim()) return toast.error('State required'), false; - if (!/^[A-Za-z\s]+$/.test(formData.state)) return toast.error('State must contain only alphabets'), false; - if (formData.state.length < 2 || formData.state.length > 50) return toast.error('State must be between 2 and 50 characters'), false; + // State + if (!formData.state.trim()) return toast.error('State required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.state)) return toast.error('State must contain only alphabets'), false; + if (formData.state.length < 2 || formData.state.length > 50) return toast.error('State must be between 2 and 50 characters'), false; - // Country - if (!formData.country.trim()) return toast.error('Country required'), false; - if (!/^[A-Za-z\s]+$/.test(formData.country)) return toast.error('Country must contain only alphabets'), false; - if (formData.country.length < 2 || formData.country.length > 50) return toast.error('Country must be between 2 and 50 characters'), false; + // Country + if (!formData.country.trim()) return toast.error('Country required'), false; + if (!/^[A-Za-z\s]+$/.test(formData.country)) return toast.error('Country must contain only alphabets'), false; + if (formData.country.length < 2 || formData.country.length > 50) return toast.error('Country must be between 2 and 50 characters'), false; - // Postal Code - if (!/^\d+$/.test(formData.postalCode)) return toast.error('Postal code should only contain numbers'), false; - if (formData.postalCode.length < 4 || formData.postalCode.length > 10) return toast.error('Postal code must be between 4 and 10 digits'), false; + // Postal Code + if (!/^\d+$/.test(formData.postalCode)) return toast.error('Postal code should only contain numbers'), false; + if (formData.postalCode.length < 4 || formData.postalCode.length > 10) return toast.error('Postal code must be between 4 and 10 digits'), false; - return true; -}; + return true; + }; From cdfcc70e455df5afca0b312cfea6021ab3a3110f Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 18:24:34 +0530 Subject: [PATCH 5/8] integrate api to show itineraries in profile acc to the city selected --- src/Redux/services/itinerary.service.ts | 9 ++++++--- src/pages/ProfilePage.tsx | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Redux/services/itinerary.service.ts b/src/Redux/services/itinerary.service.ts index ece4428..d4b9b60 100644 --- a/src/Redux/services/itinerary.service.ts +++ b/src/Redux/services/itinerary.service.ts @@ -8,8 +8,6 @@ export const itineraryApi = createApi({ endpoints: (builder) => ({ - - createMagicItinerary: builder.mutation({ query: (itineraryDetails) => ({ // keep the name of the variables being passed here same as when calling the mutation hook url: `/website/itinerary`, @@ -24,7 +22,12 @@ export const itineraryApi = createApi({ }), getUserItineraries: builder.query({ - query: () => `/website/itinerary/all-initineraries`, + query: (cityId) => { + const params = new URLSearchParams() + + params.append('cityXid', cityId); + return `/website/itinerary/all-initineraries/?${params.toString()}` + } }), }) diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index ceacdd4..22cf974 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -107,7 +107,7 @@ export function ProfilePage({ const { data: userDetails, isLoading } = useGetUserProfileDetailsQuery(userId) const [updateUserProfileDetails, { isLoading: savingChanges }] = useUpdateUserProfileDetailsMutation(); const { data, isLoading: loadingCards } = useGetUserCardsQuery({sort,cityId}) - const { data: userItineraries, isLoading: loadingItineraries } = useGetUserItinerariesQuery({}) + const { data: userItineraries, isLoading: loadingItineraries } = useGetUserItinerariesQuery(cityId) const cards = data ?? [] const itineraries = userItineraries?.itineraries ?? [] From 16fe56913d9eb94a41874b1292cd2bdda74c5953 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 19:29:18 +0530 Subject: [PATCH 6/8] debug the cityId issue in getting user itineraries --- src/Redux/services/itinerary.service.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Redux/services/itinerary.service.ts b/src/Redux/services/itinerary.service.ts index d4b9b60..899a0b9 100644 --- a/src/Redux/services/itinerary.service.ts +++ b/src/Redux/services/itinerary.service.ts @@ -24,9 +24,8 @@ export const itineraryApi = createApi({ getUserItineraries: builder.query({ query: (cityId) => { const params = new URLSearchParams() - - params.append('cityXid', cityId); - return `/website/itinerary/all-initineraries/?${params.toString()}` + params.append('cityId', cityId); + return `/website/itinerary/all-initineraries?${params.toString()}` } }), From 37601dd51d3320a23bd5737358e5074af41aa055 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 19:31:26 +0530 Subject: [PATCH 7/8] round off the basePrice and strikedPrice --- src/pages/CheckoutPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/CheckoutPage.tsx b/src/pages/CheckoutPage.tsx index a9465fe..b6b8a79 100644 --- a/src/pages/CheckoutPage.tsx +++ b/src/pages/CheckoutPage.tsx @@ -150,9 +150,9 @@ function CheckoutConfigCard({ const cardMode = item?.cardType?.name === "selective_pass" ? "flexi" : "unlimited" const adultPrice = item?.adultPrice * noOfAdults const childPrice = item?.childPrice * noOfChildren - const basePrice = adultPrice + childPrice + const basePrice = Math.round(adultPrice + childPrice) const taxAmount = Math.round(basePrice * 0.1) - const strikedPrice = basePrice + 20 + const strikedPrice = Math.round(basePrice + 20) const [addCardToCart] = useAddCardToCartMutation() From 2c9bf7da8335407d836593cd036f9a1a7995d87e Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 23 Apr 2026 19:50:48 +0530 Subject: [PATCH 8/8] show toast error when not able to create itinerary with the error msg from backend --- src/pages/CreateMagicIternaryPage.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pages/CreateMagicIternaryPage.tsx b/src/pages/CreateMagicIternaryPage.tsx index d99377e..9353b8f 100644 --- a/src/pages/CreateMagicIternaryPage.tsx +++ b/src/pages/CreateMagicIternaryPage.tsx @@ -149,7 +149,7 @@ export function CreateMagicItineraryPage({ const [selectedActivity, setSelectedActivity] = useState(null); const [createMagicItinerary] = useCreateMagicItineraryMutation(); - const navigate= useNavigate() + const navigate = useNavigate() const toggleFavorite = (activityKey: string) => { setFavorites(prev => { @@ -213,17 +213,17 @@ export function CreateMagicItineraryPage({ const generateItinerary = async () => { try { - console.log("creating itinerary...", itineraryDetails); setIsGenerating(true); const response = await createMagicItinerary(itineraryDetails); - console.log(response) setGeneratedItinerary(response); - setShowResults(true); - toast.success("Itinerary created successfully!"); - navigate(`/itinerary-summary/${response?.data?.id}`) - } catch (error) { - console.error("Error creating itinerary:", error); - toast.error("Failed to create itinerary. Please try again."); + if (response?.data?.id) { + navigate(`/itinerary-summary/${response?.data?.id}`) + toast.success("Itinerary created successfully!"); + } else { + throw new Error(response?.error?.data?.message) + } + } catch (error: any) { + toast.error(error.message); } finally { setIsGenerating(false); }