diff --git a/src/App.tsx b/src/App.tsx index fe376f4..889db73 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,22 +24,24 @@ function App() { const [offersSource, setOffersSource] = useState<'products' | 'passes'>('products'); const [stickyCardType, setStickyCardType] = useState<'unlimited' | 'selective'>('unlimited'); - // Login state management + // ✅ Authentication state management const [user, setUser] = useState(null); const [showLoginModal, setShowLoginModal] = useState(false); const location = useLocation(); const navigate = useNavigate(); - // Login handlers + // ✅ Login handlers const handleLoginSuccess = (userData: User) => { setUser(userData); setShowLoginModal(false); + console.log('User logged in successfully:', userData); }; const handleSignOut = () => { setUser(null); navigate('/'); + console.log('User signed out'); }; const handleCloseLoginModal = () => { @@ -50,6 +52,13 @@ function App() { setShowLoginModal(true); }; + // ✅ Handle checkout (you can expand this later) + const handleCheckoutClick = () => { + console.log('Proceeding to checkout for user:', user); + // Add your checkout logic here + navigate('/checkout'); + }; + // Detect mobile for optimized animations useEffect(() => { const checkMobile = () => { @@ -108,13 +117,14 @@ function App() { animate={{ opacity: 1 }} transition={{ duration: 0.3, ease: easeOutCubic }} > - diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 3923134..1235e8b 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -45,6 +45,7 @@ interface AppRouterProps { onSignOutClick: () => void; onLoginSuccess: (userData: User) => void; onCloseLoginModal: () => void; + onCheckoutClick?: () => void; offersSource: 'products' | 'passes'; } @@ -55,6 +56,7 @@ export function AppRouter({ onSignOutClick, onLoginSuccess, onCloseLoginModal, + onCheckoutClick, offersSource }: AppRouterProps) { const location = useLocation(); @@ -88,9 +90,13 @@ export function AppRouter({ } /> {/* Passes Route */} - - + } /> diff --git a/src/components/CheckoutPage.tsx b/src/components/CheckoutPage.tsx index c209456..790e565 100644 --- a/src/components/CheckoutPage.tsx +++ b/src/components/CheckoutPage.tsx @@ -18,32 +18,33 @@ import { ImageWithFallback } from './figma/ImageWithFallback'; import { Layout } from '../Layout'; interface CheckoutPageProps { - onBackClick: () => void; - onHomeClick: () => void; - onMelbourneClick: () => void; - onPassesClick: () => void; - onCheckoutClick: () => void; - onSignInClick: () => void; + onBackClick?: () => void; + onHomeClick?: () => void; + onMelbourneClick?: () => void; + onPassesClick?: () => void; + onCheckoutClick?: () => void; + onSignInClick?: () => void; onSignOutClick?: () => void; - onAttractionsClick: () => void; - onBlogsClick: () => void; - onHowItWorksClick: () => void; - onFAQClick: () => void; - onPrivacyPolicyClick: () => void; - onAboutUsClick: () => void; - onProfileClick: () => void; - onCityCardsClick: () => void; - onMagicItineraryClick: () => void; - onPostCardsClick: () => void; - onOffersClick: () => void; + onAttractionsClick?: () => void; + onBlogsClick?: () => void; + onHowItWorksClick?: () => void; + onFAQClick?: () => void; + onPrivacyPolicyClick?: () => void; + onAboutUsClick?: () => void; + onProfileClick?: () => void; + onCityCardsClick?: () => void; + onMagicItineraryClick?: () => void; + onPostCardsClick?: () => void; + onOffersClick?: () => void; onSecureCheckoutClick?: () => void; onContactUsClick?: () => void; onEsimsClick?: () => void; onHotelDiscountsClick?: () => void; - currentPage: string; + currentPage?: string; user?: { email: string; name: string } | null; } + // Mock cart data const mockCartItems = [ { diff --git a/src/components/CitySelectionDialog.tsx b/src/components/CitySelectionDialog.tsx index 72f6365..ab51e1d 100644 --- a/src/components/CitySelectionDialog.tsx +++ b/src/components/CitySelectionDialog.tsx @@ -1,5 +1,6 @@ +// CitySelectionDialog.tsx import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; // ✅ import navigation hook +import { useNavigate } from 'react-router-dom'; import { Dialog, DialogContent, DialogTitle, DialogDescription } from './ui/dialog'; import { ArrowLeft, Search } from 'lucide-react'; import { Input } from './ui/input'; @@ -15,6 +16,7 @@ interface City { interface CitySelectionDialogProps { isOpen: boolean; onClose: () => void; + onCitySelect?: (city: string) => void; // ✅ New prop for city selection callback } const cities: City[] = [ @@ -28,9 +30,13 @@ const cities: City[] = [ { id: 'louisiana', name: 'Louisiana', imageUrl: 'https://images.unsplash.com/photo-1646508262200-455d62c22182?...' }, ]; -export function CitySelectionDialog({ isOpen, onClose }: CitySelectionDialogProps) { +export function CitySelectionDialog({ + isOpen, + onClose, + onCitySelect +}: CitySelectionDialogProps) { const [searchQuery, setSearchQuery] = useState(''); - const navigate = useNavigate(); // ✅ navigation hook + const navigate = useNavigate(); const filteredCities = cities.filter(city => city.name.toLowerCase().includes(searchQuery.toLowerCase()) @@ -38,16 +44,22 @@ export function CitySelectionDialog({ isOpen, onClose }: CitySelectionDialogProp const handleCityClick = (city: City) => { console.log('Selected city:', city.name); + + // ✅ Call the onCitySelect callback if provided + if (onCitySelect) { + onCitySelect(city.id); + } else { + // ✅ Default behavior: navigate to passes page + navigate(`/passes?city=${encodeURIComponent(city.name)}`); + } + onClose(); - - // ✅ navigate to /passes with selected city info (optional query param) - navigate(`/passes?city=${encodeURIComponent(city.name)}`); }; return ( - {/* Accessible Title */} + {/* ... rest of the component remains the same ... */} Select a City Choose from our available cities to explore attractions and experiences @@ -86,7 +98,7 @@ export function CitySelectionDialog({ isOpen, onClose }: CitySelectionDialogProp {filteredCities.map((city, index) => ( handleCityClick(city)} // ✅ navigate on click + onClick={() => handleCityClick(city)} initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.9 }} @@ -111,7 +123,6 @@ export function CitySelectionDialog({ isOpen, onClose }: CitySelectionDialogProp - {/* No Results */} {filteredCities.length === 0 && (

@@ -123,4 +134,4 @@ export function CitySelectionDialog({ isOpen, onClose }: CitySelectionDialogProp

); -} +} \ No newline at end of file diff --git a/src/components/MelbournePage.tsx b/src/components/MelbournePage.tsx index b6094b6..ff44cad 100644 --- a/src/components/MelbournePage.tsx +++ b/src/components/MelbournePage.tsx @@ -242,18 +242,18 @@ function HeroBannerCarousel({ onCheckoutClick, onPassesClick, onEsimsClick, onHo } interface MelbournePageProps { - onBackClick: () => void; - onHomeClick: () => void; - onAttractionsClick: () => void; - onPassesClick: () => void; + onBackClick?: () => void; + onHomeClick?: () => void; + onAttractionsClick?: () => void; + onPassesClick?: () => void; onCheckoutClick?: () => void; - onSignInClick: () => void; + onSignInClick?: () => void; onSignOutClick?: () => void; - onBlogsClick: () => void; - onHowItWorksClick: () => void; - onFAQClick: () => void; - onPrivacyPolicyClick: () => void; - onAboutUsClick: () => void; + onBlogsClick?: () => void; + onHowItWorksClick?: () => void; + onFAQClick?: () => void; + onPrivacyPolicyClick?: () => void; + onAboutUsClick?: () => void; onProfileClick?: () => void; onCityCardsClick?: () => void; onMagicItineraryClick?: () => void; @@ -266,6 +266,7 @@ interface MelbournePageProps { user?: User | null; } + export function MelbournePage({ onBackClick, onHomeClick, diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 27772ba..e09f9d9 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -69,7 +69,7 @@ export default function Navbar({ const location = useLocation(); const navigate = useNavigate(); - const handleOpenCityDialog = () => { + const handleOpenCityDialog = () => { setIsCityDialogOpen(true); }; @@ -77,6 +77,13 @@ export default function Navbar({ setIsCityDialogOpen(false); }; + // ✅ Handle city selection from dialog + const handleCitySelect = (cityId: string) => { + console.log('City selected in navbar:', cityId); + // Navigate to passes page when city is selected + navigate('/passes'); + }; + // Available cities const cities = [ { id: 'melbourne', label: 'Melbourne' }, @@ -85,6 +92,7 @@ export default function Navbar({ { id: 'perth', label: 'Perth' } ]; + // Check if we're on landing page const isLandingPage = location.pathname === '/'; @@ -341,7 +349,6 @@ export default function Navbar({ } className="h-10 w-auto" /> - @@ -359,7 +366,6 @@ export default function Navbar({ }`} > {item.label} - {/* Active indicator */} - {/* Hover background */} ))} - {/* Right Section */}
- {/* City Dropdown */} } /> + {/* Language Dropdown */} - {/* Shopping Cart - UPDATED: using cartDropdownItems */} + {/* Shopping Cart */} setActiveCartDropdown(prev => !prev)} - items={cartDropdownItems} // Using the updated array with navigation + items={cartDropdownItems} title="Shopping Cart" trigger={
@@ -457,64 +461,86 @@ export default function Navbar({
} /> - - {/* City Card Button */} + {/* ✅ UPDATED: City Card Button with Proper Authentication Logic */}
-
- +
+ {isUserSignedIn && user ? ( + // ✅ When user is logged in - show user dropdown + setActiveUserDropdown(prev => !prev)} + items={[ + { + id: 'profile', + label: 'My Profile', + icon: , + action: () => { + navigate('/profile'); + setActiveUserDropdown(false); + } + }, + { + id: 'settings', + label: 'Settings', + icon: , + action: () => { + navigate('/comming-soon'); + setActiveUserDropdown(false); + } + }, + { + id: 'logout', + label: 'Sign Out', + icon: , + action: () => { + if (onSignOutClick) { + onSignOutClick(); + } + setActiveUserDropdown(false); + } + } + ]} + title="Account" + trigger={ +
{ + e.stopPropagation(); + setActiveUserDropdown(prev => !prev); + }} + > + { }} // Empty function since we handle click above + className="hover:scale-105 transition-transform duration-200" + /> +
+ } + /> + ) : ( + // ✅ When user is NOT logged in - show city selection dialog + <> +
+ { }} // Empty function since we handle click above + className="hover:scale-105 transition-transform duration-200" + /> +
- {/* ✅ City Selection Dialog */} - - - {isUserSignedIn && user && ( - setActiveUserDropdown(prev => !prev)} - items={[ - { - id: 'profile', - label: 'My Profile', - icon: , - action: () => { - navigate('/profile'); - setActiveUserDropdown(false); - }, - }, - { - id: 'settings', - label: 'Settings', - icon: , - action: () => { - navigate('/settings'); - setActiveUserDropdown(false); - }, - }, - { - id: 'logout', - label: 'Sign Out', - icon: , - action: () => { - if (onSignOutClick) { - onSignOutClick(); - } - setActiveUserDropdown(false); - }, - }, - ]} - title="Account" - trigger={null} - /> - )} -
+ {/* ✅ City Selection Dialog with navigation to passes */} + + + )} +
@@ -522,6 +548,7 @@ export default function Navbar({ + {/* Mobile Navbar - Enhanced Glassmorphism */}