From e98a54635bdaa111184821f9449f5057bbe4f87d Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 2 Apr 2026 12:18:06 +0530 Subject: [PATCH 01/14] change PostCard to Postcard --- src/components/Navbar.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 0dcef92..b5eee1c 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -143,11 +143,11 @@ export default function Navbar({ isShared: false }, { - label: 'Your PostCard', + label: 'Your Postcard', path: '/postcards', isShared: true, - landingLabel: 'Your PostCard', - melbourneLabel: 'Your PostCard' + landingLabel: 'Your Postcard', + melbourneLabel: 'Your Postcard' } ], melbourne: [ From e1fb13d4c043e3f66e132f59fccf9bcffe5048b4 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 2 Apr 2026 12:47:07 +0530 Subject: [PATCH 02/14] remove the image from postcard hero section --- src/components/Navbar.tsx | 6 +++--- src/components/PostCardsPage.tsx | 6 +++--- src/components/ProfilePage.tsx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index b5eee1c..dad69bf 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -186,11 +186,11 @@ export default function Navbar({ melbourneLabel: 'Your Card' }, { - label: 'Your PostCard', + label: 'Your Postcard', path: '/postcards', isShared: true, - landingLabel: 'Your PostCard', - melbourneLabel: 'Your PostCard' + landingLabel: 'Your Postcard', + melbourneLabel: 'Your Postcard' } ] }; diff --git a/src/components/PostCardsPage.tsx b/src/components/PostCardsPage.tsx index 3eb05f6..8892510 100644 --- a/src/components/PostCardsPage.tsx +++ b/src/components/PostCardsPage.tsx @@ -13,7 +13,7 @@ import { CustomPostcards } from './CustomPostcards'; import { HowItWorks } from './HowItWorks'; import { ImageWithFallback } from './figma/ImageWithFallback'; import { Layout } from '../Layout'; -import front from '../assets/front.jpg' +// import front from '../assets/front.jpg' interface User { @@ -89,7 +89,7 @@ export function PostCardsPage({
*/} - < img src={front} alt='Postcard image' /> + {/* < img src={front} alt='Postcard image' /> */}
{/* Decorative elements */} diff --git a/src/components/ProfilePage.tsx b/src/components/ProfilePage.tsx index 02842d6..0cb4dea 100644 --- a/src/components/ProfilePage.tsx +++ b/src/components/ProfilePage.tsx @@ -225,7 +225,7 @@ export function ProfilePage({ >

My{' '} - Profile + Profile

Manage your account, passes, and travel itineraries From 993ccf2c4748211ed3441179a8e37f080e57a1be Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 2 Apr 2026 13:11:18 +0530 Subject: [PATCH 03/14] add a gradient white shadow effect when showing attractions --- src/components/LandingVarietyOfAdventures.tsx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/components/LandingVarietyOfAdventures.tsx b/src/components/LandingVarietyOfAdventures.tsx index 3e7ab94..4af0519 100644 --- a/src/components/LandingVarietyOfAdventures.tsx +++ b/src/components/LandingVarietyOfAdventures.tsx @@ -154,7 +154,7 @@ export function LandingVarietyOfAdventures() {

{/* Header */}
- Experience{' '} for Every Traveller - - From iconic laneways and world-class coffee to stunning gardens and vibrant markets, + From iconic laneways and world-class coffee to stunning gardens and vibrant markets, discover Melbourne's unique character through curated experiences that showcase the city's soul.
@@ -180,7 +180,7 @@ export function LandingVarietyOfAdventures() { {/* Carousel Container - Full Width */}
{/* Scrolling Track */} -
- + {/* Bottom Content Card */}
-
- + {/* Icon */} -
- + {/* Attraction Info */}
@@ -332,19 +332,19 @@ export function LandingVarietyOfAdventures() { {/* Gradient Fade Edges */} -
-
+
+
{/* CTA Button */} - -
- {/* Content */}
{step === 'email' ? ( + // ... Email step (unchanged)
- {/* Email Input */}
setEmail(e.target.value)} - className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" onKeyDown={(e) => e.key === 'Enter' && handleSendOTP()} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" /> - {helperText && ( -

- {helperText} -

- )} + {error &&

{error}

} + {helperText &&

{helperText}

}
- {/* Send OTP Button */}
) : (
{/* Email Display */}
- -
- {email} + +
+ {email}
- {helperText && ( -

- {helperText} -

- )}
- {/* OTP Input */} + {/* OTP Inputs with Paste Support */}
- {/* Countdown */} {countdown > 0 && ( -

- {formatCountdown(countdown)} +

+ Resend OTP in {formatCountdown(countdown)}

)}
- {/* Verify Button */} + {error &&

{error}

} + - {/* Resend OTP */} {countdown === 0 && ( diff --git a/src/main.tsx b/src/main.tsx index 241b0b3..9cf6d51 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,13 +1,14 @@ import { createRoot } from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; import App from "./App"; -import "./index.css"; import { Provider } from "react-redux"; import { store } from "./Redux/Store"; +import { Toaster } from "sonner"; createRoot(document.getElementById("root")!).render( + From cdb9c7e734e1ea52a2a4c500e40bdef4db81dca1 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 9 Apr 2026 13:04:08 +0530 Subject: [PATCH 06/14] integrate the register user api --- src/components/LoginModal.tsx | 268 +++++++++++---------- src/components/RegisterModal.tsx | 391 +++++++++++++++++++++++++++++++ src/global.d.ts | 2 + src/main.tsx | 2 + 4 files changed, 540 insertions(+), 123 deletions(-) create mode 100644 src/components/RegisterModal.tsx diff --git a/src/components/LoginModal.tsx b/src/components/LoginModal.tsx index 5eca180..bff54d3 100644 --- a/src/components/LoginModal.tsx +++ b/src/components/LoginModal.tsx @@ -7,6 +7,7 @@ import { Label } from './ui/label'; import { useAuth } from '../context/AuthContext'; import { useLoginMutation, useVerifyOtpMutation } from '../Redux/services/auth.service'; import { toast } from 'sonner'; +import { RegisterModal } from './RegisterModal'; interface LoginModalProps { isOpen: boolean; @@ -20,6 +21,7 @@ export function LoginModal({ isOpen, onClose }: LoginModalProps) { const [countdown, setCountdown] = useState(0); const [helperText, setHelperText] = useState(''); const [error, setError] = useState(''); + const [showRegisterModal, setShowRegisterModal] = useState(false); const { login } = useAuth(); @@ -158,136 +160,156 @@ export function LoginModal({ isOpen, onClose }: LoginModalProps) { }; return ( - - {isOpen && ( - <> - + <> + + {isOpen && ( + <> + - -
-
- + +
+
+ -

- Login -

-

- Enter your email and verify with OTP -

-
+

+ Login +

+

+ Enter your email and verify with OTP +

+
-
- {step === 'email' ? ( - // ... Email step (unchanged) -
-
- - setEmail(e.target.value)} - onKeyDown={(e) => e.key === 'Enter' && handleSendOTP()} - className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" - /> - {error &&

{error}

} - {helperText &&

{helperText}

} -
- - -
- ) : ( -
- {/* Email Display */} -
- -
- {email} -
-
- - {/* OTP Inputs with Paste Support */} -
- -
- {otp.map((digit, index) => ( - handleOTPChange(index, e.target.value.replace(/\D/g, ''))} - onKeyDown={(e) => handleOTPKeyDown(index, e)} - onPaste={handlePaste} // ← Paste support added here - data-otp-index={index} - className="w-12 h-12 text-center font-poppins font-semibold text-lg bg-gray-100 border-0 rounded-xl focus:bg-white focus:ring-2 focus:ring-gray-800 focus:outline-none transition-all" - /> - ))} +
+ {step === 'email' ? ( + // ... Email step (unchanged) +
+
+ + setEmail(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleSendOTP()} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> + {error &&

{error}

} + {helperText &&

{helperText}

}
- {countdown > 0 && ( -

- Resend OTP in {formatCountdown(countdown)} -

+ +
+ +
+
+ ) : ( +
+ {/* Email Display */} +
+ +
+ {email} +
+
+ + {/* OTP Inputs with Paste Support */} +
+ +
+ {otp.map((digit, index) => ( + handleOTPChange(index, e.target.value.replace(/\D/g, ''))} + onKeyDown={(e) => handleOTPKeyDown(index, e)} + onPaste={handlePaste} // ← Paste support added here + data-otp-index={index} + className="w-12 h-12 text-center font-poppins font-semibold text-lg bg-gray-300 border-0 rounded-xl focus:bg-white focus:ring-2 focus:ring-gray-800 focus:outline-none transition-all" + /> + ))} +
+ + {countdown > 0 && ( +

+ Resend OTP in {formatCountdown(countdown)} +

+ )} +
+ + {error &&

{error}

} + + + + {countdown === 0 && ( + )}
- - {error &&

{error}

} - - - - {countdown === 0 && ( - - )} -
- )} + )} +
-
- - - )} - + + + ) + } + + setShowRegisterModal(false)} + onLoginClick={() => { + setShowRegisterModal(false); + setStep('email'); + setEmail(''); + }} + /> + ); } \ No newline at end of file diff --git a/src/components/RegisterModal.tsx b/src/components/RegisterModal.tsx new file mode 100644 index 0000000..e690a89 --- /dev/null +++ b/src/components/RegisterModal.tsx @@ -0,0 +1,391 @@ +import { useState, useEffect } from 'react'; +import { motion, AnimatePresence } from 'motion/react'; +import { X } from 'lucide-react'; +import { Button } from './ui/button'; +import { Input } from './ui/input'; +import { Label } from './ui/label'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; +import { useRegisterMutation } from '../Redux/services/auth.service'; +import { toast } from 'sonner'; + +interface RegisterModalProps { + isOpen: boolean; + onClose: () => void; + onLoginClick: () => void; +} + +export function RegisterModal({ isOpen, onClose, onLoginClick }: RegisterModalProps) { + const [formData, setFormData] = useState({ + firstName: '', + lastName: '', + emailAddress: '', + isdCode: '+91', + mobileNumber: '', + address1: '', + address2: '', + city: '', + state: '', + country: 'Australia', + postalCode: '' + }); + const [helperText, setHelperText] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + const [register, { isLoading: isRegistering }] = useRegisterMutation(); + + useEffect(() => { + if (!isOpen) { + setFormData({ + firstName: '', + lastName: '', + emailAddress: '', + isdCode: '+91', + mobileNumber: '', + address1: '', + address2: '', + city: '', + state: '', + country: 'Australia', + postalCode: '' + }); + setHelperText(''); + } + }, [isOpen]); + + const handleInputChange = (field: string, value: string) => { + setFormData(prev => ({ ...prev, [field]: value })); + }; + + const validateForm = () => { + if (!formData.firstName.trim()) { + toast.error('First name is required'); + return false; + } + if (!formData.lastName.trim()) { + toast.error('Last name is required'); + return false; + } + if (!formData.emailAddress.trim() || !formData.emailAddress.includes('@')) { + toast.error('Please enter a valid email address'); + return false; + } + if (!formData.mobileNumber.trim()) { + toast.error('Mobile number is required'); + return false; + } + if (!/^\d+$/.test(formData.mobileNumber.trim())) { + toast.error('Mobile number must contain only digits'); + return false; + } + if (!formData.address1.trim()) { + toast.error('Address is required'); + return false; + } + if (!formData.city.trim()) { + toast.error('City is required'); + return false; + } + if (!formData.state.trim()) { + toast.error('State is required'); + return false; + } + if (!formData.postalCode.trim()) { + toast.error('Postal code is required'); + return false; + } + if (!/^\d+$/.test(formData.postalCode.trim())) { + toast.error('Postal code must contain only digits'); + return false; + } + return true; + }; + + + const handleRegister = async () => { + if (!validateForm()) { + return; + } + + setHelperText(''); + setIsLoading(true); + + try { + const response = await register(formData).unwrap(); + console.log('Registration response:', response); + + toast.success('Registration successful! Please login.'); + setTimeout(() => { + onLoginClick(); + onClose(); + }, 2000); + } catch (error: any) { + console.error('Registration error:', error); + const errorMessage = error?.data?.message || 'Registration failed. Please try again.'; + toast.error(errorMessage); + setHelperText(errorMessage); + } finally { + setIsLoading(false); + } + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault(); + handleRegister(); + } + }; + + return ( + + {isOpen && ( + <> + + + +
+
+ + +

+ Create Account +

+

+ Register to get started with City Cards +

+
+ +
+
+ {/* Personal Information */} +
+

Personal Information

+
+
+ + handleInputChange('firstName', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+ +
+ + handleInputChange('lastName', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+
+ +
+ + handleInputChange('emailAddress', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+ +
+
+ + +
+ +
+ + handleInputChange('mobileNumber', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+
+
+ + {/* Address Information */} +
+

Address Information

+ +
+ + handleInputChange('address1', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+ +
+ + handleInputChange('address2', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+ +
+
+ + handleInputChange('city', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+ +
+ + handleInputChange('state', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+
+ +
+
+ + +
+ +
+ + handleInputChange('postalCode', e.target.value)} + className="font-poppins text-base h-12 bg-gray-50 border-0 rounded-xl placeholder:text-gray-400" + /> +
+
+
+ + {helperText && ( +

+ {helperText} +

+ )} + + + +
+ +
+
+
+
+
+ + )} +
+ ); +} diff --git a/src/global.d.ts b/src/global.d.ts index 903f3f8..eb5a13c 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -32,3 +32,5 @@ declare module '*.mp4' { const src: string; export default src; } + +declare module "*.css"; diff --git a/src/main.tsx b/src/main.tsx index 9cf6d51..6e91c69 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,12 @@ import { createRoot } from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; import App from "./App"; +import "./index.css"; import { Provider } from "react-redux"; import { store } from "./Redux/Store"; import { Toaster } from "sonner"; + createRoot(document.getElementById("root")!).render( From 7c9ec2c28587be408de790a8d38f4766eeb3fb77 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 9 Apr 2026 15:04:27 +0530 Subject: [PATCH 07/14] move the pages from components to pages folder --- src/AppRouter.tsx | 50 ++- src/Redux/Store.tsx | 5 - src/guidelines/Guidelines.md | 345 ------------------ src/{components => pages}/AboutUsPage.tsx | 14 +- .../AttractionDetailsPage.tsx | 8 +- src/{components => pages}/AttractionsPage.tsx | 12 +- src/{components => pages}/BlogDetailsPage.tsx | 14 +- src/{components => pages}/BlogsPage.tsx | 22 +- src/{components => pages}/CheckoutPage.tsx | 24 +- src/{components => pages}/CityCardsPage.tsx | 19 +- src/{components => pages}/ContactUsPage.tsx | 14 +- .../CreateMagicItineraryPage.tsx | 22 +- src/{components => pages}/DiscoverPage.tsx | 8 +- src/{components => pages}/DownloadAppPage.tsx | 12 +- .../HotelDiscountsPage.tsx | 6 +- .../ItineraryViewPage.tsx | 12 +- .../LandingMagicItineraryPage.tsx | 20 +- .../MagicItineraryPage.tsx | 20 +- src/{components => pages}/MelbournePage.tsx | 28 +- src/{components => pages}/OffersPage.tsx | 26 +- src/{components => pages}/PassesPage.tsx | 16 +- src/{components => pages}/PostCardsPage.tsx | 20 +- .../PrivacyPolicyPage.tsx | 12 +- src/{components => pages}/ProfilePage.tsx | 22 +- .../SecureCheckoutPage.tsx | 18 +- .../SuperSavingsPage.tsx | 26 +- src/{components => pages}/WhatsIncluded.tsx | 10 +- 27 files changed, 223 insertions(+), 582 deletions(-) delete mode 100644 src/guidelines/Guidelines.md rename src/{components => pages}/AboutUsPage.tsx (98%) rename src/{components => pages}/AttractionDetailsPage.tsx (98%) rename src/{components => pages}/AttractionsPage.tsx (98%) rename src/{components => pages}/BlogDetailsPage.tsx (98%) rename src/{components => pages}/BlogsPage.tsx (96%) rename src/{components => pages}/CheckoutPage.tsx (97%) rename src/{components => pages}/CityCardsPage.tsx (96%) rename src/{components => pages}/ContactUsPage.tsx (97%) rename src/{components => pages}/CreateMagicItineraryPage.tsx (99%) rename src/{components => pages}/DiscoverPage.tsx (99%) rename src/{components => pages}/DownloadAppPage.tsx (99%) rename src/{components => pages}/HotelDiscountsPage.tsx (98%) rename src/{components => pages}/ItineraryViewPage.tsx (98%) rename src/{components => pages}/LandingMagicItineraryPage.tsx (97%) rename src/{components => pages}/MagicItineraryPage.tsx (97%) rename src/{components => pages}/MelbournePage.tsx (97%) rename src/{components => pages}/OffersPage.tsx (97%) rename src/{components => pages}/PassesPage.tsx (98%) rename src/{components => pages}/PostCardsPage.tsx (93%) rename src/{components => pages}/PrivacyPolicyPage.tsx (97%) rename src/{components => pages}/ProfilePage.tsx (98%) rename src/{components => pages}/SecureCheckoutPage.tsx (97%) rename src/{components => pages}/SuperSavingsPage.tsx (98%) rename src/{components => pages}/WhatsIncluded.tsx (98%) diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 1a3c767..28f26f5 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -2,38 +2,36 @@ import { Routes, Route, useParams, useLocation, useNavigate } from 'react-router import { motion, AnimatePresence } from 'motion/react'; // Import all your pages -import { LoginModal } from './components/LoginModal'; -import { MelbournePage } from './components/MelbournePage'; -import { PassesPage } from './components/PassesPage'; -import { AttractionsPage } from './components/AttractionsPage'; -import { AttractionDetailsPage } from './components/AttractionDetailsPage'; -import { CheckoutPage } from './components/CheckoutPage'; -import { SecureCheckoutPage } from './components/SecureCheckoutPage'; -import { BlogsPage } from './components/BlogsPage'; -import { BlogDetailsPage } from './components/BlogDetailsPage'; +import { MelbournePage } from './pages/MelbournePage'; +import { PassesPage } from './pages/PassesPage'; +import { AttractionsPage } from './pages/AttractionsPage'; +import { AttractionDetailsPage } from './pages/AttractionDetailsPage'; +import { CheckoutPage } from './pages/CheckoutPage'; +import { SecureCheckoutPage } from './pages/SecureCheckoutPage'; +import { BlogsPage } from './pages/BlogsPage'; +import { BlogDetailsPage } from './pages/BlogDetailsPage'; import { HowItWorksPage } from './components/HowItWorksPage'; import { FAQPage } from './components/FAQPage'; -import { PrivacyPolicyPage } from './components/PrivacyPolicyPage'; -import { AboutUsPage } from './components/AboutUsPage'; -import { ProfilePage } from './components/ProfilePage'; -import { CreateMagicItineraryPage } from './components/CreateMagicItineraryPage'; -import { ItineraryViewPage } from './components/ItineraryViewPage'; -import { OffersPage } from './components/OffersPage'; -import { CityCardsPage } from './components/CityCardsPage'; -import { MagicItineraryPage } from './components/MagicItineraryPage'; -import { PostCardsPage } from './components/PostCardsPage'; -import { DownloadAppPage } from './components/DownloadAppPage'; -import { EsimsPage } from './components/EsimsPage'; -import { HotelDiscountsPage } from './components/HotelDiscountsPage'; -import { ContactUsPage } from './components/ContactUsPage'; +import { PrivacyPolicyPage } from './pages/PrivacyPolicyPage'; +import { AboutUsPage } from './pages/AboutUsPage'; +import { ProfilePage } from './pages/ProfilePage'; +import { CreateMagicItineraryPage } from './pages/CreateMagicItineraryPage'; +import { ItineraryViewPage } from './pages/ItineraryViewPage'; +import { OffersPage } from './pages/OffersPage'; +import { CityCardsPage } from './pages/CityCardsPage'; +import { MagicItineraryPage } from './pages/MagicItineraryPage'; +import { PostCardsPage } from './pages/PostCardsPage'; +import { DownloadAppPage } from './pages/DownloadAppPage'; +import { HotelDiscountsPage } from './pages/HotelDiscountsPage'; +import { ContactUsPage } from './pages/ContactUsPage'; import { pageTransition } from './utils/animations'; import { LandingPage } from './pages/landingPage'; import ComingSoonPage from './pages/ComingSoonPage'; -import { SuperSavingsPage } from './components/SuperSavingsPage'; -import { WhatsIncluded } from './components/WhatsIncluded'; -import { LandingMagicItineraryPage } from './components/LandingMagicItineraryPage'; -import { DiscoverPage } from './components/DiscoverPage'; +import { SuperSavingsPage } from './pages/SuperSavingsPage'; +import { WhatsIncluded } from './pages/WhatsIncluded'; +import { LandingMagicItineraryPage } from './pages/LandingMagicItineraryPage'; +import { DiscoverPage } from './pages/DiscoverPage'; // User type definition interface User { diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index 04e0e46..444e72e 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -1,23 +1,18 @@ import { configureStore } from "@reduxjs/toolkit"; -import { fakeApi } from "./services/fakeApi.service"; import { attractionsApi } from "./services/attractions.service"; import { citiesApi } from "./services/cities.service"; import { authApi } from "./services/auth.service"; export const store = configureStore({ reducer: { - [fakeApi.reducerPath]: fakeApi.reducer, [attractionsApi.reducerPath]: attractionsApi.reducer, [citiesApi.reducerPath]: citiesApi.reducer, [authApi.reducerPath]:authApi.reducer }, - middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat( - - fakeApi.middleware, attractionsApi.middleware, citiesApi.middleware, authApi.middleware diff --git a/src/guidelines/Guidelines.md b/src/guidelines/Guidelines.md deleted file mode 100644 index 4a00ca3..0000000 --- a/src/guidelines/Guidelines.md +++ /dev/null @@ -1,345 +0,0 @@ -# Image Reference Guidelines - -**IMPORTANT**: When I provide an image for reference, it is for design reference only. Do NOT use that image inside any image section in the code. The image is provided to help understand the layout, styling, and visual direction - not to be embedded as an actual image in the application. - -# CityCards Typography Guidelines - -**Project**: Typography Guidelines for CityCards Travel Website - -## Font System - -### Primary Font -- **Poppins**: Used for all text including headings (H1–H6), body text, buttons, labels, and forms - Clean, readable, and consistent throughout - -### Font Weight Scale & Usage -- **font-light (300)**: Hero headings only - For creating dynamic contrast in H1/H2 -- **font-normal (400)**: Standard body text - Default weight for paragraphs -- **font-medium (500)**: Buttons, navigation links, subtle emphasis -- **font-semibold (600)**: Section headings, primary buttons -- **font-bold (700)**: Hero keywords, strong emphasis - -## Heading Typography Specifications - -### H1 - Hero/Main Page Headings -- **Font**: Poppins -- **Size**: `text-5xl md:text-6xl lg:text-7xl` (48px/60px/72px - targeting ~64px) -- **Line Height**: `leading-tight` -- **Pattern**: Dynamic multi-weight with gradient/italic accents (max 2 emphasis styles) - -```jsx -

- Discover{' '} - - Melbourne's - {' '} - Best Experiences -

-``` - -### H2 - Section Headings -- **Font**: Poppins -- **Size**: `text-2xl md:text-3xl lg:text-4xl` (24px/36px/48px) -- **Line Height**: `leading-tight` -- **Pattern**: Mixed weights with gradient emphasis - -```jsx -

- Explore{' '} - - Amazing - {' '} - Cities -

-``` - -### H3 - Subsection Headings -- **Font**: Poppins -- **Size**: `text-xl md:text-2xl` (24px/30px) -- **Line Height**: `leading-snug` -- **Weight**: `font-semibold` - -```jsx -

- Feature Title -

-``` - -### H4 - Component Headings -- **Font**: Poppins -- **Size**: `text-lg md:text-xl` (20px/24px) -- **Line Height**: `leading-snug` -- **Weight**: `font-medium` or `font-semibold` - -```jsx -

- Component Heading -

-``` - -### H5 - Card/Item Titles -- **Font**: Poppins -- **Size**: `text-lg` (18px) -- **Line Height**: `leading-snug` -- **Weight**: `font-medium` - -```jsx -
- Card Title -
-``` - -### H6 - Small Headings -- **Font**: Poppins -- **Size**: `text-base` (16px) -- **Line Height**: `leading-snug` -- **Weight**: `font-medium` - -```jsx -
- Small Heading -
-``` - -## Body Typography Specifications - -### Large Body Text -- **Font**: Poppins -- **Size**: `text-xl` (20px) -- **Line Height**: `leading-relaxed` -- **Weight**: `font-normal` - -```jsx -

- Large descriptive text for important sections -

-``` - -### Regular Body Text -- **Font**: Poppins -- **Size**: `text-base` (16px) -- **Line Height**: `leading-relaxed` -- **Weight**: `font-normal` - -```jsx -

- Regular body text content -

-``` - -### Small Body Text -- **Font**: Poppins -- **Size**: `text-sm` (14px) -- **Line Height**: `leading-relaxed` -- **Weight**: `font-normal` or `font-light` - -```jsx -

- Caption or meta information -

-``` - -## Interactive Element Typography - -### Buttons -- **Font**: Poppins -- **Primary Weight**: `font-semibold` -- **Secondary Weight**: `font-medium` -- **Min Size**: 16px - -```jsx -// Primary Button - - -// Secondary Button - -``` - -### Navigation Links -- **Font**: Poppins -- **Weight**: `font-medium` -- **Size**: `text-base` (16px) - -```jsx - - Navigation Link - -``` - -### Form Labels -- **Font**: Poppins -- **Weight**: `font-light` or `font-normal` -- **Size**: `text-sm` or `text-base` (14px/16px) - -```jsx - -``` - -### Form Inputs -- **Font**: Poppins -- **Weight**: `font-normal` -- **Size**: `text-base` (16px) - -```jsx - -``` - -## Accessibility Standards - -### Text Size Requirements -- **Minimum Text Size**: 14px -- **Interactive Minimum Size**: 16px -- **Contrast**: WCAG AA or higher -- **Heading Hierarchy**: Maintain semantic order (H1 → H2 → H3 etc.) - -### Implementation Requirements -```jsx -// Always include explicit font and size classes to override defaults -

- Content with explicit styling -

-``` - -## Typography Rules - -### DO ✅ -- Use Poppins for all text (headings and body) -- Apply max 2 emphasis styles per heading -- Use gradient effects sparingly -- Keep line-heights consistent -- Always specify explicit font classes to override component defaults - -### DON'T ❌ -- Don't use font-light in small text -- Don't mix more than 3 weights in one heading -- Don't go below 14px for captions -- Don't override font sizes without Tailwind classes -- Don't break semantic heading hierarchy - -## Implementation Guidelines - -### Component Styling Override -**IMPORTANT**: Always explicitly set typography classes to override component defaults: - -```jsx -// ✅ CORRECT - Explicit typography classes - - - - Card Title - - - -

- Card content with explicit styling -

-
-
- -// ❌ INCORRECT - Relying on defaults - - - Card Title - - -

Card content without explicit styling

-
-
-``` - -### Dynamic Heading Patterns -```jsx -// Pattern 1: Light → Bold (H1/H2 only) -

- Discover{' '} - - Amazing - {' '} - Destinations -

- -// Pattern 2: Normal → Semibold (H3/H4) -

- Experience{' '} - Melbourne's Culture -

-``` - -### Responsive Typography -```jsx -// Mobile-first responsive scaling -

- Responsive Heading -

- -

- Responsive body text -

-``` - -**Add your own guidelines here** - diff --git a/src/components/AboutUsPage.tsx b/src/pages/AboutUsPage.tsx similarity index 98% rename from src/components/AboutUsPage.tsx rename to src/pages/AboutUsPage.tsx index b68a755..29b87fd 100644 --- a/src/components/AboutUsPage.tsx +++ b/src/pages/AboutUsPage.tsx @@ -1,13 +1,13 @@ import React from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Heart, MapPin, Zap, Globe, Users, Camera, Coffee } from 'lucide-react'; -import { Button } from './ui/button'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { ReviewsSection } from './ReviewsSection'; +// import { Button } from './ui/button'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { ReviewsSection } from '../components/ReviewsSection'; interface User { email: string; diff --git a/src/components/AttractionDetailsPage.tsx b/src/pages/AttractionDetailsPage.tsx similarity index 98% rename from src/components/AttractionDetailsPage.tsx rename to src/pages/AttractionDetailsPage.tsx index d92c3b1..8998f12 100644 --- a/src/components/AttractionDetailsPage.tsx +++ b/src/pages/AttractionDetailsPage.tsx @@ -1,10 +1,10 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Clock, Users, Calendar, MapPin, Star, Check, X, ChevronLeft, ChevronRight } from 'lucide-react'; -import { Button } from './ui/button'; -import { Badge } from './ui/badge'; -import { Card, } from './ui/card'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Badge } from '../components/ui/badge'; +import { Card, } from '../components/ui/card'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { Layout } from '../Layout'; import { useParams } from 'react-router-dom'; import { useGetAttractionDetailsByIdQuery } from '../Redux/services/attractions.service'; diff --git a/src/components/AttractionsPage.tsx b/src/pages/AttractionsPage.tsx similarity index 98% rename from src/components/AttractionsPage.tsx rename to src/pages/AttractionsPage.tsx index 79ec7df..588ea14 100644 --- a/src/components/AttractionsPage.tsx +++ b/src/pages/AttractionsPage.tsx @@ -2,12 +2,12 @@ import { useEffect, useState } from 'react'; import { motion } from 'motion/react'; import { Search, Star, Clock } from 'lucide-react'; import { useNavigate, useParams } from 'react-router-dom'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import { Checkbox } from './ui/checkbox'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { Checkbox } from '../components/ui/checkbox'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { Layout } from '../Layout'; import { useGetAttractionFiltersQuery, useGetCustomerAttractionsQuery } from '../Redux/services/attractions.service'; interface User { diff --git a/src/components/BlogDetailsPage.tsx b/src/pages/BlogDetailsPage.tsx similarity index 98% rename from src/components/BlogDetailsPage.tsx rename to src/pages/BlogDetailsPage.tsx index 675c7de..5c935cc 100644 --- a/src/components/BlogDetailsPage.tsx +++ b/src/pages/BlogDetailsPage.tsx @@ -1,13 +1,13 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Calendar, User, Clock, Share2, BookmarkPlus, ThumbsUp, MessageSquare, Tag, MapPin } from 'lucide-react'; -import { Button } from './ui/button'; -import { Badge } from './ui/badge'; -import { Card, CardContent } from './ui/card'; -import { Separator } from './ui/separator'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Badge } from '../components/ui/badge'; +import { Card, CardContent } from '../components/ui/card'; +import { Separator } from '../components/ui/separator'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; interface User { email: string; diff --git a/src/components/BlogsPage.tsx b/src/pages/BlogsPage.tsx similarity index 96% rename from src/components/BlogsPage.tsx rename to src/pages/BlogsPage.tsx index df21c8b..677c947 100644 --- a/src/components/BlogsPage.tsx +++ b/src/pages/BlogsPage.tsx @@ -1,18 +1,18 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { Calendar, User, Clock, ArrowRight, Search, Tag, CreditCard, MapPin, Check, Smartphone, Star, Heart, Share2 } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card'; -import { Badge } from './ui/badge'; -import { Input } from './ui/input'; -import Navbar from './Navbar'; +import { Button } from '../components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { Input } from '../components/ui/input'; +import Navbar from '../components/Navbar'; // import { CitySubmenu } from './CitySubmenu'; -import { MobileAppSection } from './MobileAppSection'; -import { WhyChooseCityCards } from './WhyChooseCityCards'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { ReviewsSection } from './ReviewsSection'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { WhyChooseCityCards } from '../components/WhyChooseCityCards'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { ReviewsSection } from '../components/ReviewsSection'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import imgFrame1597884939 from "figma:asset/5da1b0444c0d21bc7ee776c49e36e2a8ea4d3e12.png"; // Blog Mobile App Section Component diff --git a/src/components/CheckoutPage.tsx b/src/pages/CheckoutPage.tsx similarity index 97% rename from src/components/CheckoutPage.tsx rename to src/pages/CheckoutPage.tsx index 82e5f68..f34b555 100644 --- a/src/components/CheckoutPage.tsx +++ b/src/pages/CheckoutPage.tsx @@ -1,20 +1,20 @@ import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'motion/react'; import { ArrowLeft, CreditCard, Users, Calendar, MapPin, Shield, Truck, Clock, ChevronRight, Check, ChevronDown, X, Mail, Smartphone } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Label } from './ui/label'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Separator } from './ui/separator'; -import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './ui/dialog'; -import { RadioGroup, RadioGroupItem } from './ui/radio-group'; -import { Checkbox } from './ui/checkbox'; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; -import { Badge } from './ui/badge'; -import { Textarea } from './ui/textarea'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Label } from '../components/ui/label'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Separator } from '../components/ui/separator'; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '../components/ui/dialog'; +import { RadioGroup, RadioGroupItem } from '../components/ui/radio-group'; +import { Checkbox } from '../components/ui/checkbox'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../components/ui/select'; +import { Badge } from '../components/ui/badge'; +import { Textarea } from '../components/ui/textarea'; import Navbar from './Navbar'; import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { Layout } from '../Layout'; interface CheckoutPageProps { diff --git a/src/components/CityCardsPage.tsx b/src/pages/CityCardsPage.tsx similarity index 96% rename from src/components/CityCardsPage.tsx rename to src/pages/CityCardsPage.tsx index 1ae32fa..5a27856 100644 --- a/src/components/CityCardsPage.tsx +++ b/src/pages/CityCardsPage.tsx @@ -1,18 +1,15 @@ import React from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Star, MapPin, Clock, CreditCard, Users, Shield, Smartphone, Check } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -// import SubNavbar from './SubNavbar'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; +import { Button } from '../components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; import { FAQPage } from './FAQPage'; -import { HowItWorks } from './HowItWorks'; -import { WhyChooseCityCards } from './WhyChooseCityCards'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { HowItWorks } from '../components/HowItWorks'; +import { WhyChooseCityCards } from '../components/WhyChooseCityCards'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { Layout } from '../Layout'; interface User { diff --git a/src/components/ContactUsPage.tsx b/src/pages/ContactUsPage.tsx similarity index 97% rename from src/components/ContactUsPage.tsx rename to src/pages/ContactUsPage.tsx index d8f9483..46852a3 100644 --- a/src/components/ContactUsPage.tsx +++ b/src/pages/ContactUsPage.tsx @@ -12,13 +12,13 @@ import { ChevronRight, CheckCircle } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Input } from './ui/input'; -import { Label } from './ui/label'; -import { Textarea } from './ui/textarea'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; +import { Button } from '../components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Input } from '../components/ui/input'; +import { Label } from '../components/ui/label'; +import { Textarea } from '../components/ui/textarea'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; interface ContactUsPageProps { onBackClick: () => void; diff --git a/src/components/CreateMagicItineraryPage.tsx b/src/pages/CreateMagicItineraryPage.tsx similarity index 99% rename from src/components/CreateMagicItineraryPage.tsx rename to src/pages/CreateMagicItineraryPage.tsx index 71c5f21..5735da3 100644 --- a/src/components/CreateMagicItineraryPage.tsx +++ b/src/pages/CreateMagicItineraryPage.tsx @@ -18,17 +18,17 @@ import { ChevronDown, ChevronUp } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import { Progress } from './ui/progress'; -import { Calendar as CalendarComponent } from './ui/calendar'; -import { Input } from './ui/input'; -import { Popover, PopoverContent, PopoverTrigger } from './ui/popover'; -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { Progress } from '../components/ui/progress'; +import { Calendar as CalendarComponent } from '../components/ui/calendar'; +import { Input } from '../components/ui/input'; +import { Popover, PopoverContent, PopoverTrigger } from '../components/ui/popover'; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../components/ui/collapsible'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; interface User { diff --git a/src/components/DiscoverPage.tsx b/src/pages/DiscoverPage.tsx similarity index 99% rename from src/components/DiscoverPage.tsx rename to src/pages/DiscoverPage.tsx index 2ec1d43..73a9ad0 100644 --- a/src/components/DiscoverPage.tsx +++ b/src/pages/DiscoverPage.tsx @@ -2,10 +2,10 @@ import { ArrowRight, Check, CreditCard, DollarSign, MapPin, Palette, Sparkles, T import { AnimatePresence, motion } from 'motion/react'; import { useEffect, useState } from 'react'; import { Layout } from '../Layout'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { MobileAppSection } from './MobileAppSection'; -import { TrustSection } from './TrustSection'; -import { Button } from './ui/button'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { TrustSection } from '../components/TrustSection'; +import { Button } from '../components/ui/button'; interface User { email: string; diff --git a/src/components/DownloadAppPage.tsx b/src/pages/DownloadAppPage.tsx similarity index 99% rename from src/components/DownloadAppPage.tsx rename to src/pages/DownloadAppPage.tsx index 7b0c1e0..fe125a4 100644 --- a/src/components/DownloadAppPage.tsx +++ b/src/pages/DownloadAppPage.tsx @@ -1,12 +1,12 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, ChevronRight, QrCode, CreditCard, Calendar, MapPin, Star, CheckCircle, Sparkles, Users, Clock, Gift, Ticket } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; interface User { email: string; diff --git a/src/components/HotelDiscountsPage.tsx b/src/pages/HotelDiscountsPage.tsx similarity index 98% rename from src/components/HotelDiscountsPage.tsx rename to src/pages/HotelDiscountsPage.tsx index 3811808..798f4f0 100644 --- a/src/components/HotelDiscountsPage.tsx +++ b/src/pages/HotelDiscountsPage.tsx @@ -1,10 +1,6 @@ import { motion } from 'motion/react'; import { BadgePercent, Clock, Crown, Check, ArrowRight } from 'lucide-react'; -import { Button } from './ui/button'; -import Navbar from './Navbar'; -// import { SubNavbar } from './SubNavbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import cityCardsLogo from '../assets/cityLogo.png'; import marriottHotelImage from '../assets/marriott-hotel.png'; import { Layout } from '../Layout'; diff --git a/src/components/ItineraryViewPage.tsx b/src/pages/ItineraryViewPage.tsx similarity index 98% rename from src/components/ItineraryViewPage.tsx rename to src/pages/ItineraryViewPage.tsx index 0f72882..522604a 100644 --- a/src/components/ItineraryViewPage.tsx +++ b/src/pages/ItineraryViewPage.tsx @@ -1,12 +1,12 @@ import React, { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Calendar, Clock, MapPin, Users, Star, Heart, Share2, Download, CheckCircle, Navigation, Cloud, Sun } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; interface ItineraryViewPageProps { onBackClick: () => void; diff --git a/src/components/LandingMagicItineraryPage.tsx b/src/pages/LandingMagicItineraryPage.tsx similarity index 97% rename from src/components/LandingMagicItineraryPage.tsx rename to src/pages/LandingMagicItineraryPage.tsx index 32fa27c..0c7f059 100644 --- a/src/components/LandingMagicItineraryPage.tsx +++ b/src/pages/LandingMagicItineraryPage.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Sparkles, MapPin, Clock, Users, Calendar, Star, Zap, Heart, Camera } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { HowItWorks } from './HowItWorks'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { PersonalizedTourHero } from './PersonalizedTourHero'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { HowItWorks } from '../components/HowItWorks'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { PersonalizedTourHero } from '../components/PersonalizedTourHero'; import { Layout } from '../Layout'; interface User { diff --git a/src/components/MagicItineraryPage.tsx b/src/pages/MagicItineraryPage.tsx similarity index 97% rename from src/components/MagicItineraryPage.tsx rename to src/pages/MagicItineraryPage.tsx index b6501e9..95eacf0 100644 --- a/src/components/MagicItineraryPage.tsx +++ b/src/pages/MagicItineraryPage.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Sparkles, MapPin, Clock, Users, Calendar, Star, Zap, Heart, Camera } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { HowItWorks } from './HowItWorks'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { PersonalizedTourHero } from './PersonalizedTourHero'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { HowItWorks } from '../components/HowItWorks'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { PersonalizedTourHero } from '../components/PersonalizedTourHero'; import { Layout } from '../Layout'; interface User { diff --git a/src/components/MelbournePage.tsx b/src/pages/MelbournePage.tsx similarity index 97% rename from src/components/MelbournePage.tsx rename to src/pages/MelbournePage.tsx index 4960380..a4dbe82 100644 --- a/src/components/MelbournePage.tsx +++ b/src/pages/MelbournePage.tsx @@ -1,22 +1,22 @@ import { motion, useAnimationControls, AnimatePresence } from 'motion/react'; -import { Button } from './ui/button'; +import { Button } from '../components/ui/button'; import { ArrowRight, Calendar, Thermometer, Eye, MapPin, Clock, Users, Ticket, Wand2, Plane, Sparkles } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; -import Navbar from './Navbar'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { MelbourneAttractions } from './MelbourneAttractions'; -import { MelbourneCardComparison } from './MelbourneCardComparison'; -import { MelbourneTourOverview } from './MelbourneTourOverview'; -import { MelbourneBlogs } from './MelbourneBlogs'; -import { CustomPostcards } from './CustomPostcards'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { MobileAppPromotion } from './MobileAppPromotion'; -import { MelbourneFAQ } from './MelbourneFAQ'; -import { Footer } from './Footer'; +import Navbar from '../components/Navbar'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { MelbourneAttractions } from '../components/MelbourneAttractions'; +import { MelbourneCardComparison } from '../components/MelbourneCardComparison'; +import { MelbourneTourOverview } from '../components/MelbourneTourOverview'; +import { MelbourneBlogs } from '../components/MelbourneBlogs'; +import { CustomPostcards } from '../components/CustomPostcards'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { MobileAppPromotion } from '../components/MobileAppPromotion'; +import { MelbourneFAQ } from '../components/MelbourneFAQ'; +import { Footer } from '../components/Footer'; // import { MinimalHeroBanner } from './MinimalHeroBanner'; import { Layout } from '../Layout'; -import { HeroBannerCarousel } from './HeroBannerCarousel'; -import { HotelEsimOffers } from './HotelEsimOffers'; +import { HeroBannerCarousel } from '../components/HeroBannerCarousel'; +import { HotelEsimOffers } from '../components/HotelEsimOffers'; interface User { email: string; diff --git a/src/components/OffersPage.tsx b/src/pages/OffersPage.tsx similarity index 97% rename from src/components/OffersPage.tsx rename to src/pages/OffersPage.tsx index c9c5fb1..4e1a26d 100644 --- a/src/components/OffersPage.tsx +++ b/src/pages/OffersPage.tsx @@ -1,20 +1,20 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Search, Filter, Star, MapPin, Clock, Tag, Heart, Share2, Copy, ChevronDown, ChevronRight, Check, Hotel, Plane, Building2, MapPinned, Home } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Badge } from './ui/badge'; -import { Separator } from './ui/separator'; -import { Checkbox } from './ui/checkbox'; -import Navbar from './Navbar'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { Separator } from '../components/ui/separator'; +import { Checkbox } from '../components/ui/checkbox'; +import Navbar from '../components/Navbar'; // import SubNavbar from './SubNavbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { TrustSection } from './TrustSection'; -import { MobileAppSection } from './MobileAppSection'; -import { ReviewsSection } from './ReviewsSection'; -import { TrustedCompanies } from './TrustedCompanies'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { TrustSection } from '../components/TrustSection'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { ReviewsSection } from '../components/ReviewsSection'; +import { TrustedCompanies } from '../components/TrustedCompanies'; import { Layout } from '../Layout'; interface OffersPageProps { diff --git a/src/components/PassesPage.tsx b/src/pages/PassesPage.tsx similarity index 98% rename from src/components/PassesPage.tsx rename to src/pages/PassesPage.tsx index cb87517..154ac1e 100644 --- a/src/components/PassesPage.tsx +++ b/src/pages/PassesPage.tsx @@ -1,14 +1,14 @@ import { useState } from 'react'; import { Check, X, Star, Shield, Clock, Smartphone, Download, QrCode, Heart, Users, Award, Headphones } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card'; -import { RadioGroup, RadioGroupItem } from './ui/radio-group'; -import { Badge } from './ui/badge'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { ReviewsSection } from './ReviewsSection'; +import { Button } from '../components/ui/button'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; +import { RadioGroup, RadioGroupItem } from '../components/ui/radio-group'; +import { Badge } from '../components/ui/badge'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { ReviewsSection } from '../components/ReviewsSection'; import { Layout } from '../Layout'; -import { LoginModal } from './LoginModal'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { LoginModal } from '../components/LoginModal'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { useAuth } from '../context/AuthContext'; import { useNavigate } from 'react-router-dom'; diff --git a/src/components/PostCardsPage.tsx b/src/pages/PostCardsPage.tsx similarity index 93% rename from src/components/PostCardsPage.tsx rename to src/pages/PostCardsPage.tsx index 8892510..2228d7f 100644 --- a/src/components/PostCardsPage.tsx +++ b/src/pages/PostCardsPage.tsx @@ -1,17 +1,17 @@ import React from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Camera, Edit3, Upload, Heart, Star, Download, Share2 } from 'lucide-react'; -import { Button } from './ui/button'; -import { Card, CardContent } from './ui/card'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; +import { Button } from '../components/ui/button'; +import { Card, CardContent } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; // import SubNavbar from './SubNavbar'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { CustomPostcards } from './CustomPostcards'; -import { HowItWorks } from './HowItWorks'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Footer } from '../components/Footer'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { CustomPostcards } from '../components/CustomPostcards'; +import { HowItWorks } from '../components/HowItWorks'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { Layout } from '../Layout'; // import front from '../assets/front.jpg' diff --git a/src/components/PrivacyPolicyPage.tsx b/src/pages/PrivacyPolicyPage.tsx similarity index 97% rename from src/components/PrivacyPolicyPage.tsx rename to src/pages/PrivacyPolicyPage.tsx index 5117319..9787bc2 100644 --- a/src/components/PrivacyPolicyPage.tsx +++ b/src/pages/PrivacyPolicyPage.tsx @@ -1,13 +1,13 @@ import { useState, useEffect } from 'react'; import { motion, useScroll, useTransform } from 'motion/react'; import { ArrowLeft } from 'lucide-react'; -import Navbar from './Navbar'; +import Navbar from '../components/Navbar'; // import { CitySubmenu } from './CitySubmenu'; -import { Footer } from './Footer'; -import { MobileAppSection } from './MobileAppSection'; -import { WhyChooseCityCards } from './WhyChooseCityCards'; -import { EnhancedTestimonials } from './EnhancedTestimonials'; -import { ReviewsSection } from './ReviewsSection'; +import { Footer } from '../components/Footer'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { WhyChooseCityCards } from '../components/WhyChooseCityCards'; +import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; +import { ReviewsSection } from '../components/ReviewsSection'; interface User { email: string; diff --git a/src/components/ProfilePage.tsx b/src/pages/ProfilePage.tsx similarity index 98% rename from src/components/ProfilePage.tsx rename to src/pages/ProfilePage.tsx index 0cb4dea..b7df501 100644 --- a/src/components/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -15,17 +15,17 @@ import { Badge as BadgeIcon, Camera } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Label } from './ui/label'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Separator } from './ui/separator'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Label } from '../components/ui/label'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Separator } from '../components/ui/separator'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../components/ui/select'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; interface ProfilePageProps { onBackClick: () => void; diff --git a/src/components/SecureCheckoutPage.tsx b/src/pages/SecureCheckoutPage.tsx similarity index 97% rename from src/components/SecureCheckoutPage.tsx rename to src/pages/SecureCheckoutPage.tsx index 2b61d96..e987298 100644 --- a/src/components/SecureCheckoutPage.tsx +++ b/src/pages/SecureCheckoutPage.tsx @@ -1,15 +1,15 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Lock, Shield, CreditCard, Check, X, Tag } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Label } from './ui/label'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'; -import { Separator } from './ui/separator'; -import { Badge } from './ui/badge'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Label } from '../components/ui/label'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'; +import { Separator } from '../components/ui/separator'; +import { Badge } from '../components/ui/badge'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; interface User { email: string; diff --git a/src/components/SuperSavingsPage.tsx b/src/pages/SuperSavingsPage.tsx similarity index 98% rename from src/components/SuperSavingsPage.tsx rename to src/pages/SuperSavingsPage.tsx index 6743d5d..eb8263d 100644 --- a/src/components/SuperSavingsPage.tsx +++ b/src/pages/SuperSavingsPage.tsx @@ -1,19 +1,19 @@ import { useState } from 'react'; import { motion } from 'motion/react'; import { ArrowLeft, Search, Filter, Star, MapPin, Clock, Tag, Heart, Share2, ChevronDown, ChevronRight, Check, Hotel, Plane, Building2, MapPinned, Home, Gift, Percent } from 'lucide-react'; -import { Button } from './ui/button'; -import { Input } from './ui/input'; -import { Card, CardContent, CardHeader, CardTitle } from './ui/card'; -import { Badge } from './ui/badge'; -import { Separator } from './ui/separator'; -import { Checkbox } from './ui/checkbox'; -import Navbar from './Navbar'; -import { Footer } from './Footer'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { TrustSection } from './TrustSection'; -import { MobileAppSection } from './MobileAppSection'; -import { ReviewsSection } from './ReviewsSection'; -import { TrustedCompanies } from './TrustedCompanies'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; +import { Badge } from '../components/ui/badge'; +import { Separator } from '../components/ui/separator'; +import { Checkbox } from '../components/ui/checkbox'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { TrustSection } from '../components/TrustSection'; +import { MobileAppSection } from '../components/MobileAppSection'; +import { ReviewsSection } from '../components/ReviewsSection'; +import { TrustedCompanies } from '../components/TrustedCompanies'; import { Layout } from '../Layout'; interface SuperSavingsPageProps { diff --git a/src/components/WhatsIncluded.tsx b/src/pages/WhatsIncluded.tsx similarity index 98% rename from src/components/WhatsIncluded.tsx rename to src/pages/WhatsIncluded.tsx index a31114f..0bdec15 100644 --- a/src/components/WhatsIncluded.tsx +++ b/src/pages/WhatsIncluded.tsx @@ -1,11 +1,11 @@ import { ArrowRight, Hotel, Mail, MapPin, Sparkles, Ticket, Wifi } from 'lucide-react'; import { motion } from 'motion/react'; import { Layout } from '../Layout'; -import { ImageWithFallback } from './figma/ImageWithFallback'; -import { SmartSaving } from './SmartSaving'; -import { Badge } from './ui/badge'; -import { Button } from './ui/button'; -import { WhatsIncludedHero } from './WhatsIncludedHero'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { SmartSaving } from '../components/SmartSaving'; +import { Badge } from '../components/ui/badge'; +import { Button } from '../components/ui/button'; +import { WhatsIncludedHero } from '../components/WhatsIncludedHero'; interface User { email: string; From 169a29f63c85935c97126e8f78da0f9e2141c570 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 9 Apr 2026 15:29:17 +0530 Subject: [PATCH 08/14] change the route according to cityName instead of id --- src/components/CitySelectionDialog.tsx | 2 +- src/components/Navbar.tsx | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/CitySelectionDialog.tsx b/src/components/CitySelectionDialog.tsx index 203aa72..07f2ff2 100644 --- a/src/components/CitySelectionDialog.tsx +++ b/src/components/CitySelectionDialog.tsx @@ -40,7 +40,7 @@ export function CitySelectionDialog({ // ✅ Call the onCitySelect callback if provided (passing cityId) if (onCitySelect) { - onCitySelect(String(city.id)); + onCitySelect(String(city.cityName)); } else { // ✅ Default behavior: navigate to passes page navigate(`/passes?city=${encodeURIComponent(city.cityName)}`); diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 9374a6a..ca6e863 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -299,11 +299,11 @@ export default function Navbar({ setDialogSource('navbar'); }; - const handleCitySelectFromNavbar = (cityId: string) => { - console.log('City selected from navbar:', cityId); - onCityChange(cityId); + const handleCitySelectFromNavbar = (cityName: string) => { + console.log('City selected from navbar:', cityName); + onCityChange(cityName); - if (cityId.toLowerCase() === '1') { + if (cityName.toLowerCase() === 'melbourne') { setNavigationSource('melbourne'); navigate('/melbourne'); } else { @@ -334,11 +334,11 @@ export default function Navbar({ handleCloseCityDialog(); }; - const handleCitySelect = (cityId: string) => { + const handleCitySelect = (cityName: string) => { if (dialogSource === 'cta') { - handleCitySelectFromCTA(cityId); + handleCitySelectFromCTA(cityName); } else { - handleCitySelectFromNavbar(cityId); + handleCitySelectFromNavbar(cityName); } }; From f3b16e8e1a588b542ecde328d4bba79d7e521c97 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Thu, 9 Apr 2026 16:06:15 +0530 Subject: [PATCH 09/14] change the duration of the toaster to 2s --- src/{imports => components}/AfterLogin.tsx | 0 src/{imports => components}/BeforeLogin.tsx | 0 src/components/CTAButton.tsx | 4 ++-- src/main.tsx | 3 +-- 4 files changed, 3 insertions(+), 4 deletions(-) rename src/{imports => components}/AfterLogin.tsx (100%) rename src/{imports => components}/BeforeLogin.tsx (100%) diff --git a/src/imports/AfterLogin.tsx b/src/components/AfterLogin.tsx similarity index 100% rename from src/imports/AfterLogin.tsx rename to src/components/AfterLogin.tsx diff --git a/src/imports/BeforeLogin.tsx b/src/components/BeforeLogin.tsx similarity index 100% rename from src/imports/BeforeLogin.tsx rename to src/components/BeforeLogin.tsx diff --git a/src/components/CTAButton.tsx b/src/components/CTAButton.tsx index 9b80d9f..0c16431 100644 --- a/src/components/CTAButton.tsx +++ b/src/components/CTAButton.tsx @@ -1,6 +1,6 @@ import { motion } from 'motion/react'; -import BeforeLogin from '../imports/BeforeLogin'; -import AfterLogin from '../imports/AfterLogin'; +import BeforeLogin from './BeforeLogin'; +import AfterLogin from './AfterLogin'; interface User { email: string; diff --git a/src/main.tsx b/src/main.tsx index 6e91c69..b8619fc 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,11 +6,10 @@ import { Provider } from "react-redux"; import { store } from "./Redux/Store"; import { Toaster } from "sonner"; - createRoot(document.getElementById("root")!).render( - + From 439ad4b2640a7485659b4ea870299d2d9b23ec7e Mon Sep 17 00:00:00 2001 From: aryabenade Date: Mon, 13 Apr 2026 16:12:05 +0530 Subject: [PATCH 10/14] send accessToken to the backend after login --- index.html | 2 +- src/Redux/baseQuery.ts | 4 ++-- src/components/LoginModal.tsx | 9 +++++++-- src/context/AuthContext.tsx | 8 +++++++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 000821d..daa01f8 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - CityCards Travel 22-8-2025 + CityCards Customer-web diff --git a/src/Redux/baseQuery.ts b/src/Redux/baseQuery.ts index 7ffc8d8..36c9339 100644 --- a/src/Redux/baseQuery.ts +++ b/src/Redux/baseQuery.ts @@ -8,9 +8,9 @@ export const baseQuery = fetchBaseQuery({ const token = localStorage.getItem("accessToken"); if (token) { headers.set("Authorization", `Bearer ${token}`); - // headers.set("access-token", token); + headers.set("access-token", token); } // headers.set("Content-Type", "application/json"); return headers; }, -}); +}); \ No newline at end of file diff --git a/src/components/LoginModal.tsx b/src/components/LoginModal.tsx index bff54d3..b4378d0 100644 --- a/src/components/LoginModal.tsx +++ b/src/components/LoginModal.tsx @@ -140,8 +140,10 @@ export function LoginModal({ isOpen, onClose }: LoginModalProps) { }).unwrap(); const userData = { + userId:response?.user?.id, email: response?.email || email, name: response?.name || email.split('@')[0].charAt(0).toUpperCase() + email.split('@')[0].slice(1), + accessToken:response?.accessToken, }; login(userData); @@ -285,11 +287,14 @@ export function LoginModal({ isOpen, onClose }: LoginModalProps) { onClick={() => { setStep('email'); setOtp(['', '', '', '', '', '']); + setHelperText("") setError(''); }} - className="w-full text-sm text-gray-600 hover:text-gray-800 font-poppins" + className="w-full text-sm text-gray-600 hover:text-gray-800 font-poppins cursor-pointer" > - Didn't receive OTP? Send again + Didn't receive OTP? + Send again + {/* Send again */} )}
diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx index 8cabeb8..50dba2a 100644 --- a/src/context/AuthContext.tsx +++ b/src/context/AuthContext.tsx @@ -3,7 +3,9 @@ import { useNavigate } from 'react-router-dom'; interface User { email: string; - name: string + name: string; + accessToken:string; + userId:string; } interface AuthContextType { @@ -29,11 +31,15 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const login = (userData: User) => { setUser(userData) localStorage.setItem("user", JSON.stringify(userData)) + localStorage.setItem("accessToken", userData?.accessToken) + localStorage.setItem("userId", userData?.userId) } const logout = () => { setUser(null) localStorage.removeItem("user") + localStorage.removeItem("accessToken") + localStorage.removeItem("userId") navigate("/") } From 0a0cb9f6f13dbe7e2359d5e87f4d5dee445faa3e Mon Sep 17 00:00:00 2001 From: aryabenade Date: Mon, 13 Apr 2026 16:13:09 +0530 Subject: [PATCH 11/14] add loading spinners --- src/Redux/services/fakeApi.service.ts | 19 ------------------- src/components/CitySelectionDialog.tsx | 9 ++++++++- src/components/LandingUpcomingCities.tsx | 11 +++++++++-- src/pages/AttractionDetailsPage.tsx | 17 ++++++++++++----- src/pages/AttractionsPage.tsx | 19 +++++++++++++------ 5 files changed, 42 insertions(+), 33 deletions(-) delete mode 100644 src/Redux/services/fakeApi.service.ts diff --git a/src/Redux/services/fakeApi.service.ts b/src/Redux/services/fakeApi.service.ts deleted file mode 100644 index b5f90ae..0000000 --- a/src/Redux/services/fakeApi.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' - -export const fakeApi = createApi({ - reducerPath: 'fakeApi', - baseQuery: fetchBaseQuery({ - baseUrl: " https://fakestoreapi.com", - - }), - endpoints: (builder) => ({ - getProducts: builder.query({ - query: () => ({ - url: 'products', - method: 'GET', - }), - }), - }), -}) - -export const { useGetProductsQuery} = fakeApi diff --git a/src/components/CitySelectionDialog.tsx b/src/components/CitySelectionDialog.tsx index 07f2ff2..3ede930 100644 --- a/src/components/CitySelectionDialog.tsx +++ b/src/components/CitySelectionDialog.tsx @@ -31,7 +31,14 @@ export function CitySelectionDialog({ const { data: cities, isLoading } = useGetCityListWithBannerQuery({ search }) if (isLoading) { - return
Loading...
+ return ( +
+
+
+

Loading...

+
+
+ ); } diff --git a/src/components/LandingUpcomingCities.tsx b/src/components/LandingUpcomingCities.tsx index 2d724a0..cd15393 100644 --- a/src/components/LandingUpcomingCities.tsx +++ b/src/components/LandingUpcomingCities.tsx @@ -113,8 +113,15 @@ export function LandingUpcomingCities() { const { data, isLoading } = useGetUpcomingCitiesQuery(listType) - if(isLoading){ - return
Loading...
+ if (isLoading) { + return ( +
+
+
+

Loading...

+
+
+ ); } const handleMouseDown = (e: React.MouseEvent) => { diff --git a/src/pages/AttractionDetailsPage.tsx b/src/pages/AttractionDetailsPage.tsx index 8998f12..34fd0d6 100644 --- a/src/pages/AttractionDetailsPage.tsx +++ b/src/pages/AttractionDetailsPage.tsx @@ -31,7 +31,14 @@ export function AttractionDetailsPage({ const { data: attraction, isLoading } = useGetAttractionDetailsByIdQuery(Number(attractionId)); if (isLoading) { - return
loading...
+ return ( +
+
+
+

Loading...

+
+
+ ); } return ( @@ -40,7 +47,7 @@ export function AttractionDetailsPage({ onSignInClick={onSignInClick} onSignOutClick={onSignOutClick} user={user} - // showCitySubmenu={false} + // showCitySubmenu={false} >
{/* Back Button */} @@ -82,7 +89,7 @@ export function AttractionDetailsPage({ {attraction.title} {' '} - Day Trip by {attraction.partner.businessName} + Day Trip by {attraction.partner.businessName}
@@ -99,10 +106,10 @@ export function AttractionDetailsPage({ {/* Gallery images */} - {attraction.attractionGalleries.slice().map((image:any) => ( + {attraction.attractionGalleries.slice().map((image: any) => (
diff --git a/src/pages/AttractionsPage.tsx b/src/pages/AttractionsPage.tsx index 588ea14..4a7d35b 100644 --- a/src/pages/AttractionsPage.tsx +++ b/src/pages/AttractionsPage.tsx @@ -230,7 +230,7 @@ export function AttractionsPage({ const [selectedPassType, setSelectedPassType] = useState(null); const cityId = 1 - + const { data: filterData, isLoading } = useGetAttractionFiltersQuery(cityId) const { data: attractions } = useGetCustomerAttractionsQuery({ cityId, // required @@ -239,9 +239,16 @@ export function AttractionsPage({ cardType: selectedPassType, // optional search, // optional }); - + if (isLoading) { - return
Loading...
+ return ( +
+
+
+

Loading...

+
+
+ ); } const handleAttractionClick = (attractionId: string) => { @@ -254,7 +261,7 @@ export function AttractionsPage({ const showingFrom = 1; const showingTo = Math.min(12, attractions?.length); const totalItems = attractions?.length; - + function handlePassTypeSelection(key: string, checked: boolean) { if (checked) { setSelectedPassType(key); // only keep the newly selected one @@ -403,7 +410,7 @@ export function AttractionsPage({ htmlFor={key} className="font-poppins text-sm text-[#414141] cursor-pointer flex-1 font-normal" > - {key==="selective_pass" ?"Selective":"Unlimited"} ({count as number}) + {key === "selective_pass" ? "Selective" : "Unlimited"} ({count as number})
))} @@ -493,7 +500,7 @@ export function AttractionsPage({ @@ -384,7 +454,7 @@ export function ProfilePage({ // Determine which pass type to show const hasUnlimitedPass = activePasses.some(pass => pass.type === 'Unlimited Pass'); const hasSelectivePass = activePasses.some(pass => pass.type === 'Flexi Pass'); - + if (hasUnlimitedPass) { return ( <> @@ -394,7 +464,7 @@ export function ProfilePage({ Melbourne Unlimited Card

- Unlimited access to 25+ attractions. Visit as many places as you want with one simple card. + Unlimited access to 25+ attractions. Visit as many places as you want with one simple card. Save up to 40% compared to individual tickets.

@@ -423,13 +493,13 @@ export function ProfilePage({ {/* Purchase CTA */}
- -
@@ -478,13 +548,13 @@ export function ProfilePage({ {/* Purchase CTA */}
- -
@@ -535,13 +605,13 @@ export function ProfilePage({ {/* Purchase CTA */}
- -
- +
Attractions: @@ -616,10 +686,10 @@ export function ProfilePage({ ))}
- + {/* Offers Button */}
-
- +
Attractions visited: @@ -689,7 +759,7 @@ export function ProfilePage({ >

My Itineraries

-
- +
@@ -728,8 +798,8 @@ export function ProfilePage({
- diff --git a/src/main.tsx b/src/main.tsx index b8619fc..cfff6d7 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -9,7 +9,7 @@ import { Toaster } from "sonner"; createRoot(document.getElementById("root")!).render( - + diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 91c0d1c..adf6491 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -28,6 +28,7 @@ import { Footer } from '../components/Footer'; import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { useGetUserProfileDetailsQuery, useUpdateUserProfileDetailsMutation } from '../Redux/services/profile.service'; import { toast } from 'sonner'; +import { useNavigate } from 'react-router-dom'; interface ProfilePageProps { onBackClick: () => void; @@ -57,18 +58,6 @@ interface ProfilePageProps { currentPage: string; } -// Mock user data -const mockUserData = { - firstName: 'John', - lastName: 'Doe', - email: 'john.doe@example.com', - phone: '+1 (555) 123-4567', - country: 'us', - address: '123 Main Street', - city: 'New York', - postalCode: '10001' -}; - // Mock passes data const mockPasses = [ { @@ -174,8 +163,11 @@ export function ProfilePage({ postalCode: '' }); + const navigate = useNavigate() const userId = localStorage.getItem("userId") const { data: userDetails, isLoading } = useGetUserProfileDetailsQuery(userId) + const [updateUserProfileDetails, { isLoading: savingChanges }] = useUpdateUserProfileDetailsMutation(); + const { data: passes, isLoading: loadingPasses } = useGetUserProfileDetailsQuery(userId) useEffect(() => { if (userDetails) { @@ -194,7 +186,6 @@ export function ProfilePage({ }, [userDetails]) - const [updateUserProfileDetails] = useUpdateUserProfileDetailsMutation(); const handleInputChange = (field: string, value: string) => { setFormData(prev => ({ ...prev, [field]: value })); @@ -215,7 +206,7 @@ export function ProfilePage({ const activePasses = mockPasses.filter(pass => pass.status === 'active'); const expiredPasses = mockPasses.filter(pass => pass.status === 'expired'); - if (isLoading) { + if (isLoading && loadingPasses) { return (
@@ -259,8 +250,8 @@ export function ProfilePage({
{/* Back Button */} navigate(-1)} + className="flex items-center gap-2 text-gray-600 hover:text-gray-900 mb-6 transition-colors duration-200 cursor-pointer" initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.5 }} @@ -434,7 +425,7 @@ export function ProfilePage({ onClick={handleSaveProfile} className="w-full bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 text-white font-normal py-3 font-poppins cursor-pointer" > - Save Changes + {savingChanges ? "Saving Changes..." : "Save Changes"} From 729f9ffa0d2273b42ff8997bdb6f9ce8701961dc Mon Sep 17 00:00:00 2001 From: aryabenade Date: Mon, 13 Apr 2026 22:04:14 +0530 Subject: [PATCH 14/14] solve errors in tsconfig --- src/pages/ProfilePage.tsx | 21 +++------------------ tsconfig.json | 4 ++-- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index adf6491..d8f91c8 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -222,28 +222,13 @@ export function ProfilePage({ {/* Navbar */} { }} - onHomeClick={onHomeClick} - onMelbourneClick={onMelbourneClick} - onPassesClick={onPassesClick} - onCheckoutClick={onCheckoutClick} onSignInClick={onSignInClick} onSignOutClick={onSignOutClick} - onAttractionsClick={onAttractionsClick} - onBlogsClick={onBlogsClick} - onHowItWorksClick={onHowItWorksClick} - onFAQClick={onFAQClick} - onPrivacyPolicyClick={onPrivacyPolicyClick} - onAboutUsClick={onAboutUsClick} - onProfileClick={onProfileClick} - onCityCardsClick={onCityCardsClick} - onMagicItineraryClick={onMagicItineraryClick} - onPostCardsClick={onPostCardsClick} - onOffersClick={onOffersClick} - currentPage={currentPage} isUserSignedIn={true} user={{ email: "user@example.com", name: "John Doe" }} - /> + onCityChange={function (city: string): void { + throw new Error('Function not implemented.'); + }} /> {/* Header Section */}
diff --git a/tsconfig.json b/tsconfig.json index 3d0a51a..e444793 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,12 +5,12 @@ "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": false, "skipLibCheck": true, - "esModuleInterop": false, + "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true,