mirror of
https://github.com/velocitatem/PHANTOM.git
synced 2026-05-31 08:33:36 +00:00
* 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
88 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
}
|