diff --git a/web/src/app/airline/products/[id]/page.tsx b/web/src/app/airline/products/[id]/page.tsx index 001a0fe..c8470ed 100644 --- a/web/src/app/airline/products/[id]/page.tsx +++ b/web/src/app/airline/products/[id]/page.tsx @@ -9,98 +9,98 @@ import { transformProduct, type Flight, type AirlineProduct } from '@/lib/airlin import type { EventName } from '@/lib/events'; const dispatchInteraction = (eventName: EventName, productId?: string, metadata?: Record) => { - const e = new CustomEvent('definedInteraction', { - detail: { eventName, productId, metadata }, - }); - document.dispatchEvent(e); + const e = new CustomEvent('definedInteraction', { + detail: { eventName, productId, metadata }, + }); + document.dispatchEvent(e); }; export default function AirlineProductPage() { - const params = useParams(); - const router = useRouter(); - const { addItem } = useCart(); - const [product, setProduct] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [added, setAdded] = useState(false); + const params = useParams(); + const router = useRouter(); + const { addItem } = useCart(); + const [product, setProduct] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [added, setAdded] = useState(false); - const productId = params.id as string; + const productId = params.id as string; - useEffect(() => { - const fetchProduct = async () => { - try { - const res = await fetch(`/api/products/${productId}`); - if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`); - const json = await res.json(); - const transformed = transformProduct(json.data as AirlineProduct); - setProduct(transformed); + useEffect(() => { + const fetchProduct = async () => { + try { + const res = await fetch(`/api/products/${productId}`); + if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`); + const json = await res.json(); + const transformed = transformProduct(json.data as AirlineProduct); + setProduct(transformed); - // fire learn_more_about_item event when product loads - dispatchInteraction('learn_more_about_item', productId, { - type: 'airline', - dateIndex: transformed.dateIndex, - flightType: transformed.flightType, + // fire learn_more_about_item event when product loads + dispatchInteraction('learn_more_about_item', productId, { + type: 'airline', + dateIndex: transformed.dateIndex, + flightType: transformed.flightType, + }); + } catch (e) { + setError(e instanceof Error ? e.message : 'Failed to load product'); + console.error('[FETCH_FLIGHT_ERROR]', e); + } finally { + setLoading(false); + } + }; + fetchProduct(); + }, [productId]); + + const handleAddToCart = () => { + if (!product) return; + + addItem({ + id: productId, + type: 'airline', + name: product.flightType, + price: product.basePrice, + metadata: { + departure: product.departure, + arrival: product.arrival, + duration: product.duration, + cabinClass: product.cabinClass, + }, + dateIndex: product.dateIndex, }); - } catch (e) { - setError(e instanceof Error ? e.message : 'Failed to load product'); - console.error('[FETCH_FLIGHT_ERROR]', e); - } finally { - setLoading(false); - } + + dispatchInteraction('add_item_to_cart', productId, { + type: 'airline', + price: product.basePrice, + }); + + setAdded(true); + setTimeout(() => setAdded(false), 2000); }; - fetchProduct(); - }, [productId]); - const handleAddToCart = () => { - if (!product) return; + return ( + <> + +
+ {loading &&
Loading flight details...
} + {error &&
{error}
} - addItem({ - id: productId, - type: 'airline', - name: product.flightType, - price: product.basePrice, - metadata: { - departure: product.departure, - arrival: product.arrival, - duration: product.duration, - cabinClass: product.cabinClass, - }, - dateIndex: product.dateIndex, - }); + {!loading && !error && product && ( + <> + + - dispatchInteraction('add_item_to_cart', productId, { - type: 'airline', - price: product.basePrice, - }); - - setAdded(true); - setTimeout(() => setAdded(false), 2000); - }; - - return ( - <> - -
- {loading &&
Loading flight details...
} - {error &&
{error}
} - - {!loading && !error && product && ( - <> - - - - - )} -
- - ); + + )} +
+ + ); } diff --git a/web/src/app/hotel/products/[id]/page.tsx b/web/src/app/hotel/products/[id]/page.tsx index d39b504..c166ba5 100644 --- a/web/src/app/hotel/products/[id]/page.tsx +++ b/web/src/app/hotel/products/[id]/page.tsx @@ -9,98 +9,98 @@ import { transformProduct, type Hotel, type HotelProduct } from '@/lib/hotel-uti import type { EventName } from '@/lib/events'; const dispatchInteraction = (eventName: EventName, productId?: string, metadata?: Record) => { - const e = new CustomEvent('definedInteraction', { - detail: { eventName, productId, metadata }, - }); - document.dispatchEvent(e); + const e = new CustomEvent('definedInteraction', { + detail: { eventName, productId, metadata }, + }); + document.dispatchEvent(e); }; export default function HotelProductPage() { - const params = useParams(); - const router = useRouter(); - const { addItem } = useCart(); - const [product, setProduct] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [added, setAdded] = useState(false); + const params = useParams(); + const router = useRouter(); + const { addItem } = useCart(); + const [product, setProduct] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [added, setAdded] = useState(false); - const productId = params.id as string; + const productId = params.id as string; - useEffect(() => { - const fetchProduct = async () => { - try { - const res = await fetch(`/api/products/${productId}`); - if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`); - const json = await res.json(); - const transformed = transformProduct(json.data as HotelProduct); - setProduct(transformed); + useEffect(() => { + const fetchProduct = async () => { + try { + const res = await fetch(`/api/products/${productId}`); + if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`); + const json = await res.json(); + const transformed = transformProduct(json.data as HotelProduct); + setProduct(transformed); - // fire learn_more_about_item event when product loads - dispatchInteraction('learn_more_about_item', productId, { - type: 'hotel', - dateIndex: transformed.dateIndex, - roomType: transformed.roomType, + // fire learn_more_about_item event when product loads + dispatchInteraction('learn_more_about_item', productId, { + type: 'hotel', + dateIndex: transformed.dateIndex, + roomType: transformed.roomType, + }); + } catch (e) { + setError(e instanceof Error ? e.message : 'Failed to load product'); + console.error('[FETCH_HOTEL_ERROR]', e); + } finally { + setLoading(false); + } + }; + fetchProduct(); + }, [productId]); + + const handleAddToCart = () => { + if (!product) return; + + addItem({ + id: productId, + type: 'hotel', + name: product.name, + price: product.pricePerNight, + metadata: { + roomType: product.roomType, + nights: product.nights, + checkIn: product.checkIn, + checkOut: product.checkOut, + }, + dateIndex: product.dateIndex, }); - } catch (e) { - setError(e instanceof Error ? e.message : 'Failed to load product'); - console.error('[FETCH_HOTEL_ERROR]', e); - } finally { - setLoading(false); - } + + dispatchInteraction('add_item_to_cart', productId, { + type: 'hotel', + price: product.pricePerNight, + }); + + setAdded(true); + setTimeout(() => setAdded(false), 2000); }; - fetchProduct(); - }, [productId]); - const handleAddToCart = () => { - if (!product) return; + return ( + <> + +
+ {loading &&
Loading hotel details...
} + {error &&
{error}
} - addItem({ - id: productId, - type: 'hotel', - name: product.name, - price: product.pricePerNight, - metadata: { - roomType: product.roomType, - nights: product.nights, - checkIn: product.checkIn, - checkOut: product.checkOut, - }, - dateIndex: product.dateIndex, - }); + {!loading && !error && product && ( + <> + + - dispatchInteraction('add_item_to_cart', productId, { - type: 'hotel', - price: product.pricePerNight, - }); - - setAdded(true); - setTimeout(() => setAdded(false), 2000); - }; - - return ( - <> - -
- {loading &&
Loading hotel details...
} - {error &&
{error}
} - - {!loading && !error && product && ( - <> - - - - - )} -
- - ); + + )} +
+ + ); }