diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx index f4aab57..7d03f11 100644 --- a/src/Redux/Store.tsx +++ b/src/Redux/Store.tsx @@ -1,11 +1,13 @@ import { configureStore } from "@reduxjs/toolkit"; import { fakeApi } from "./services/fakeApi.service"; import { attractionsApi } from "./services/attractions.service"; +import { citiesApi } from "./services/cities.service"; export const store = configureStore({ reducer: { [fakeApi.reducerPath]:fakeApi.reducer, - [attractionsApi.reducerPath]:attractionsApi.reducer + [attractionsApi.reducerPath]:attractionsApi.reducer, + [citiesApi.reducerPath]:citiesApi.reducer }, @@ -14,8 +16,8 @@ export const store = configureStore({ getDefaultMiddleware().concat( fakeApi.middleware, -attractionsApi.middleware - +attractionsApi.middleware, +citiesApi.middleware ), }); export type RootState = ReturnType; diff --git a/src/Redux/services/attractions.service.ts b/src/Redux/services/attractions.service.ts index ac73733..dcbae38 100644 --- a/src/Redux/services/attractions.service.ts +++ b/src/Redux/services/attractions.service.ts @@ -33,7 +33,6 @@ export const attractionsApi = createApi({ query: (id: number) => `/attractions/customer/${id}`, }), - }), }); diff --git a/src/Redux/services/cities.service.ts b/src/Redux/services/cities.service.ts new file mode 100644 index 0000000..44caf81 --- /dev/null +++ b/src/Redux/services/cities.service.ts @@ -0,0 +1,22 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; + +export const citiesApi = createApi({ + reducerPath: 'citiesApi', + baseQuery: fetchBaseQuery({ + baseUrl: 'https://testingapi.citycards.betadelivery.com', + }), + endpoints: (builder) => ({ + + getCityListWithBanner: builder.query({ + query: ({ search }) => { + const params = new URLSearchParams(); + + if (search) params.append('search', search); + + return `/cities/list/customer/cities?${params.toString()}` + } + }) + }), +}); + +export const { useGetCityListWithBannerQuery} = citiesApi; \ No newline at end of file diff --git a/src/components/CitySelectionDialog.tsx b/src/components/CitySelectionDialog.tsx index 4921f9e..ec0efff 100644 --- a/src/components/CitySelectionDialog.tsx +++ b/src/components/CitySelectionDialog.tsx @@ -6,11 +6,12 @@ import { ArrowLeft, Search } from 'lucide-react'; import { Input } from './ui/input'; import { motion, AnimatePresence } from 'motion/react'; import { ImageWithFallback } from './figma/ImageWithFallback'; +import { useGetCityListWithBannerQuery } from '../Redux/services/cities.service'; interface City { - id: string; - name: string; - imageUrl: string; + id: number; + cityName: string; + bannerImage: string; } interface CitySelectionDialogProps { @@ -19,45 +20,47 @@ interface CitySelectionDialogProps { onCitySelect?: (cityId: string) => void; // ✅ Updated to pass cityId } -const cities: City[] = [ - { id: 'melbourne', name: 'Melbourne', imageUrl: 'https://images.unsplash.com/photo-1624341373902-70e3a8dc9acc?...' }, - { id: 'new-york', name: 'New York', imageUrl: 'https://images.unsplash.com/photo-1514565131-fce0801e5785?...' }, - { id: 'abu-dhabi', name: 'Abu Dhabi', imageUrl: 'https://images.unsplash.com/photo-1584551246679-0daf3d275d0f?...' }, - { id: 'dubai', name: 'Dubai', imageUrl: 'https://images.unsplash.com/photo-1518684079-3c830dcef090?...' }, - { id: 'tokyo', name: 'Tokyo', imageUrl: 'https://images.unsplash.com/photo-1613487897980-50cc440ce118?...' }, - { id: 'ontario', name: 'Ontario', imageUrl: 'https://images.unsplash.com/photo-1542704792-e30dac463c90?...' }, - { id: 'mumbai', name: 'Mumbai', imageUrl: 'https://images.unsplash.com/photo-1600867161422-79f8f6e08c84?...' }, - { id: 'louisiana', name: 'Louisiana', imageUrl: 'https://images.unsplash.com/photo-1646508262200-455d62c22182?...' }, -]; - export function CitySelectionDialog({ isOpen, onClose, onCitySelect }: CitySelectionDialogProps) { - const [searchQuery, setSearchQuery] = useState(''); + const [search, setSearch] = useState(''); const navigate = useNavigate(); - const filteredCities = useMemo(() => - cities.filter(city => - city.name.toLowerCase().includes(searchQuery.toLowerCase()) - ), [searchQuery]); + const { data: cities, isLoading } = useGetCityListWithBannerQuery({ search }) + + if (isLoading) { + return
Loading...
+ } const handleCityClick = (city: City) => { - console.log('Selected city:', city.name); + console.log('Selected city:', city.cityName); // ✅ Call the onCitySelect callback if provided (passing cityId) if (onCitySelect) { - onCitySelect(city.id); + onCitySelect(String(city.id)); } else { // ✅ Default behavior: navigate to passes page - navigate(`/passes?city=${encodeURIComponent(city.name)}`); + navigate(`/passes?city=${encodeURIComponent(city.cityName)}`); } onClose(); }; + const handleSearchChange = (e: React.ChangeEvent) => { + setSearch(e.target.value) + } + + const filteredCities = useMemo(() => + cities?.filter((city: City) => + city.cityName.toLowerCase().includes(search.toLowerCase()) + ) ?? [], + [cities, search] + ); + + return ( @@ -85,8 +88,8 @@ export function CitySelectionDialog({ setSearchQuery(e.target.value)} + value={search} + onChange={handleSearchChange} className="pl-10 bg-input border-0 rounded-lg h-11 font-poppins placeholder:text-gray-400" /> @@ -96,7 +99,7 @@ export function CitySelectionDialog({
- {filteredCities.map((city, index) => ( + {filteredCities && filteredCities.map((city: City) => ( handleCityClick(city)} @@ -108,14 +111,14 @@ export function CitySelectionDialog({ className="relative h-28 rounded-2xl overflow-hidden group cursor-pointer" >

- {city.name} + {city.cityName}

@@ -123,10 +126,10 @@ export function CitySelectionDialog({
- {filteredCities.length === 0 && ( + {filteredCities?.length === 0 && (

- No cities found matching "{searchQuery}" + No cities found matching "{search}"

)}