Files
PHANTOM/web/src/components/feats/airline/AirlineCard.tsx
Daniel Alves Rösel 37b2099ee0 2 nextjs scaffold with store mode shop and admin session experiment wiring event emission v1 (#17)
* chore: cleaning gitignore

* formating and env documentation

* feat: context switching of hotel/airline depndent on env var via middleware

* fixed alignment and building

* wrong file

* prods

* fixed applying style

* better session cookie management

* tentative session storage with maybe using airtable

* migrated api of ingestion

* events and products apge

* fixing build

* 13 create outline for research paper draft (#18)

* updated outline for paper from issue

* extra paper sections and some formalization of series data

* algorithms and acknowledgements

* updated outline for paper from issue

* upadted text formating

* event unification

* refactor tracking to ues callbacks instead of refs

* implement a pricing display api with session passing

* moved middleware to proxy according to new changes in Nextjs

* refactoed kafka ingestion to go via backend not web-db

* Refactor docker-compose services to use individual Dockerfiles (#20)

* Initial plan

* Refactor services into individual Dockerfiles

Co-authored-by: velocitatem <60182044+velocitatem@users.noreply.github.com>

* Add EXPOSE directives to all Dockerfiles with port documentation

Co-authored-by: velocitatem <60182044+velocitatem@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: velocitatem <60182044+velocitatem@users.noreply.github.com>

* fixing small bugs and adding exepriments to tracking

* added some doc
2025-11-13 18:07:27 +01:00

88 lines
2.9 KiB
TypeScript

'use client';
import type { EventName } from '@/lib/events';
import { useHoverTracking } from '@/hooks/useHoverTracking';
import PriceDisplay from '@/components/ui/PriceDisplay';
const dispatchInteraction = (eventName: EventName, productId?: string, metadata?: Record<string, unknown>) => {
const e = new CustomEvent('definedInteraction', {
detail: { eventName, productId, metadata },
});
document.dispatchEvent(e);
};
type CabinClass = 'economy' | 'premium' | 'business' | 'first';
type FareRule = 'flexible' | 'standard' | 'basic';
interface Flight {
id: string;
departure: { time: string; airport: string };
arrival: { time: string; airport: string };
duration: string;
stops: number;
cabinClass: CabinClass;
fareRule: FareRule;
refundable: boolean;
basePrice: number;
}
export default function AirlineCard({ flight }: { flight: Flight }) {
const durationRef = useHoverTracking({
eventName: 'hover_over_title',
productId: flight.id,
metadata: { elementText: flight.duration },
});
const priceRef = useHoverTracking({
eventName: 'hover_over_paragraph',
productId: flight.id,
metadata: { elementText: 'price' },
});
const handleCardClick = () => {
dispatchInteraction('view_item_page', flight.id, {
cabinClass: flight.cabinClass,
fareRule: flight.fareRule,
price: flight.basePrice,
});
};
return (
<div
className="flight-card cursor-pointer"
onClick={handleCardClick}
>
<div className="flight-timing">
<div className="flight-time">{flight.departure.time}</div>
<div className="flight-airport">{flight.departure.airport}</div>
</div>
<div className="flight-route">
<div ref={durationRef} className="flight-duration">{flight.duration}</div>
<div className="flight-stops">
{flight.stops === 0 ? 'Direct' : `${flight.stops} stop${flight.stops > 1 ? 's' : ''}`}
</div>
</div>
<div className="flight-timing">
<div className="flight-time">{flight.arrival.time}</div>
<div className="flight-airport">{flight.arrival.airport}</div>
</div>
<div className="flight-pricing">
<div className="fare-class capitalize mb-2">{flight.cabinClass}</div>
<div className="text-sm text-[var(--text-secondary)] mb-2 capitalize">{flight.fareRule}</div>
{flight.refundable && (
<div className="badge-value text-xs mb-2">Refundable</div>
)}
<div ref={priceRef}>
<PriceDisplay
productId={flight.id}
className="fare-price"
/>
</div>
</div>
</div>
);
}