6 catalog data and mode mappers (#25)

* supabase product proxy and rendering

* minor pipeline refactor

* refactoring and demand estimation

* trackion of date index searching

* fixing changes of imports

* data seeding

* chore: airline basic refactor

* feat: huge push of product changes and item review with cart

* refactored design

* chore: moving route elsewhere and align

* fix: build of web/

* chore: fixing paper build

* fixing chars
This commit is contained in:
Daniel Alves Rösel
2025-11-25 11:00:31 +01:00
committed by GitHub
parent 894ce87a5d
commit 8b76d24ade
29 changed files with 1390 additions and 1237 deletions

View File

@@ -0,0 +1,75 @@
export interface AirlineProduct {
id: string;
flight_type: string;
date_index: number;
metadata: {
departure: { time: string; airport: string };
arrival: { time: string; airport: string };
duration: string;
stops: number;
cabin_class: string;
fare_rule: string;
refundable: boolean;
total?: number;
base_price: number;
};
availability: number;
}
export interface Flight {
id: string;
flightType: string;
departure: { time: string; airport: string };
arrival: { time: string; airport: string };
duration: string;
stops: number;
cabinClass: string;
fareRule: string;
refundable: boolean;
basePrice: number;
dateIndex: number;
availability: number;
}
const EPOCH = new Date(0);
export const transformProduct = (p: AirlineProduct): Flight => {
const { id, flight_type, date_index, metadata, availability } = p;
return {
id,
flightType: flight_type,
departure: metadata.departure,
arrival: metadata.arrival,
duration: metadata.duration,
stops: metadata.stops,
cabinClass: metadata.cabin_class,
fareRule: metadata.fare_rule,
refundable: metadata.refundable,
basePrice: metadata.base_price,
dateIndex: date_index,
availability,
};
};
// convert date string to days from today
export const dateToDaysFromToday = (dateStr: string): number => {
const target = new Date(dateStr);
target.setHours(0, 0, 0, 0);
const today = new Date();
today.setHours(0, 0, 0, 0);
return Math.floor((target.getTime() - today.getTime()) / 86400000);
};
// convert date string to date_index (days since epoch)
export const dateToIndex = (dateStr: string): number => {
const d = new Date(dateStr);
return Math.floor((d.getTime() - EPOCH.getTime()) / 86400000);
};
// get current date_index
export const todayIndex = (): number => {
const now = new Date();
now.setHours(0, 0, 0, 0);
return Math.floor((now.getTime() - EPOCH.getTime()) / 86400000);
};

View File

@@ -0,0 +1,71 @@
export interface HotelProduct {
id: string;
room_type: string;
date_index: number;
metadata: {
amenities?: string[];
total?: number;
image_url?: string;
base_price?: number;
name?: string;
refundable?: boolean;
};
availability: number;
}
export interface Hotel {
id: string;
name: string;
roomType: string;
checkIn: string;
checkOut: string;
dateIndex: number;
amenities: string[];
refundable: boolean;
pricePerNight: number;
nights: number;
}
const EPOCH = new Date(0);
export const transformProduct = (p: HotelProduct): Hotel => {
const { id, room_type, date_index, metadata } = p;
const checkIn = new Date(EPOCH.getTime() + date_index * 86400000);
const nights = 1;
const checkOut = new Date(checkIn.getTime() + nights * 86400000);
return {
id,
name: metadata?.name || room_type,
roomType: room_type,
checkIn: checkIn.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
checkOut: checkOut.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
dateIndex: date_index,
amenities: metadata?.amenities || [],
refundable: metadata?.refundable || false,
pricePerNight: metadata?.base_price || 100,
nights,
};
};
// convert date string to days from today
export const dateToDaysFromToday = (dateStr: string): number => {
const target = new Date(dateStr);
target.setHours(0, 0, 0, 0);
const today = new Date();
today.setHours(0, 0, 0, 0);
return Math.floor((target.getTime() - today.getTime()) / 86400000);
};
// convert date string to date_index (days since epoch)
export const dateToIndex = (dateStr: string): number => {
const d = new Date(dateStr);
return Math.floor((d.getTime() - EPOCH.getTime()) / 86400000);
};
// get current date_index
export const todayIndex = (): number => {
const now = new Date();
now.setHours(0, 0, 0, 0);
return Math.floor((now.getTime() - EPOCH.getTime()) / 86400000);
};

View File

@@ -0,0 +1,25 @@
import { HotelProduct, Hotel, transformProduct as transformHotel } from './hotel-utils';
import { AirlineProduct, Flight, transformProduct as transformFlight } from './airline-utils';
export type Product = Hotel | Flight;
export type ProductRaw = HotelProduct | AirlineProduct;
export const isHotelProduct = (p: ProductRaw): p is HotelProduct => {
return 'room_type' in p;
};
export const isAirlineProduct = (p: ProductRaw): p is AirlineProduct => {
return 'flight_type' in p;
};
export const transformProduct = (p: ProductRaw): Product => {
if (isHotelProduct(p)) {
return transformHotel(p);
}
return transformFlight(p);
};
export const getProductType = (p: Product): 'hotel' | 'airline' => {
if ('roomType' in p) return 'hotel';
return 'airline';
};