import { arSA, da, de, enGB, es, fr, is, it, nl, nb, pl, pt, sv, ja } from 'date-fns/locale'; import { format as formatDateFns } from 'date-fns'; export const languages = [ 'ar-SA', 'da-DK', 'de-DE', 'en-GB', 'es-ES', 'fr-BE', 'fr-FR', 'is-IS', 'it-IT', 'nl-BE', 'nl-NL', 'no-NO', 'pl-PL', 'pt-PT', 'sv-SE', 'ja-JP' ]; export const defaultLanguage = 'nl-BE'; export const formatPrice = (price: number, currencyCode: string, locale: string = 'nl-BE') => { const priceFormat = Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode ? currencyCode : 'EUR', minimumFractionDigits: 2, useGrouping: true }); return priceFormat.format(price); }; import arJson from '../translations/ar-SA.json'; import daJson from '../translations/da-DK.json'; import deJson from '../translations/de-DE.json'; import enJson from '../translations/en-GB.json'; import esJson from '../translations/es-ES.json'; import frBeJson from '../translations/fr-BE.json'; import frFrJson from '../translations/fr-FR.json'; import isJson from '../translations/is-IS.json'; import itJson from '../translations/it-IT.json'; import nlBeJson from '../translations/nl-BE.json'; import nlNlJson from '../translations/nl-NL.json'; import noJson from '../translations/no-NO.json'; import plJson from '../translations/pl-PL.json'; import ptJson from '../translations/pt-PT.json'; import svJson from '../translations/sv-SE.json'; import jaJson from '../translations/ja-JP.json'; import { DateStruct } from '@qite/tide-client'; import { DepartureRange } from '../types'; import { SortByType } from '../../search-results/types'; export const getTranslations = (language: string) => { switch (language) { case 'ar-SA': return arJson; case 'da-DK': return daJson; case 'de-DE': return deJson; case 'en-GB': return enJson; case 'es-ES': return esJson; case 'fr-BE': return frBeJson; case 'fr-FR': return frFrJson; case 'is-IS': return isJson; case 'it-IT': return itJson; case 'nl-BE': return nlBeJson; case 'nl-NL': return nlNlJson; case 'no-NO': return noJson; case 'pl-PL': return plJson; case 'pt-PT': return ptJson; case 'sv-SE': return svJson; case 'ja-JP': return jaJson; default: throw new Error(`The language '${language}' is not yet supported.`); } }; export const locales = { 'ar-SA': arSA, 'da-DK': da, 'de-DE': de, 'en-GB': enGB, 'es-ES': es, 'fr-BE': fr, 'fr-FR': fr, 'is-IS': is, 'it-IT': it, 'nl-BE': nl, 'nl-NL': nl, 'no-NO': nb, 'pl-PL': pl, 'pt-PT': pt, 'sv-SE': sv, 'ja-JP': ja }; export function getLocale(code: string) { switch (code) { case 'ar-SA': return locales[code]; case 'da-DK': return locales[code]; case 'de-DE': return locales[code]; case 'en-GB': return locales[code]; case 'es-ES': return locales[code]; case 'fr-BE': return locales[code]; case 'fr-FR': return locales[code]; case 'is-IS': return locales[code]; case 'it-IT': return locales[code]; case 'nl-BE': return locales[code]; case 'nl-NL': return locales[code]; case 'no-NO': return locales[code]; case 'pl-PL': return locales[code]; case 'pt-PT': return locales[code]; case 'sv-SE': return locales[code]; case 'ja-JP': return locales[code]; default: return locales['nl-BE']; } } export const getPriceDifferenceText = (price: number, currencyCode: string) => { return price > 0 ? `+ ${formatPrice(Math.abs(price), currencyCode)}` : `- ${formatPrice(Math.abs(price), currencyCode)}`; }; export function format(text: string, args: any[]) { return text.replace(/{([0-9]+)}/g, function (match, index) { return typeof args[index] == 'undefined' ? match : args[index]; }); } export const formatTime = (date: Date) => new Intl.DateTimeFormat('nl-BE', { hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(date)); export const formatDate = (date: Date) => new Intl.DateTimeFormat('nl-BE', { weekday: 'short', day: '2-digit', month: 'short', year: '2-digit' }).format(new Date(date)); export const dateToDateStruct = (date: Date | undefined): DateStruct => { if (date === undefined) { return { year: 0, month: 0, day: 0 }; } return { year: date.getFullYear(), month: date.getMonth() + 1, // Months are 0-based in JS day: date.getDate() }; }; export const timeFromDateTime = (dateTime: Date | undefined): string => { if (!dateTime) { return ''; } const date = new Date(dateTime); const hours = date.getUTCHours(); const minutes = date.getUTCMinutes(); return `${hours}:${minutes < 10 ? '0' : ''}${minutes}`; }; export const longFormatDate = (dateTime: Date | undefined, language: string): string => { if (!dateTime) { return ''; } const locale = getLocale(language); const formattedDate = formatDateFns(new Date(dateTime), 'eee dd MMM yy', { locale }); return formattedDate; }; export const durationTicksInHoursString = (durationInTicks: number): string => { const totalMinutes = Math.floor(durationInTicks / 10_000 / 1000 / 60); return minutesToHoursString(totalMinutes); }; export const durationInTicksInMinutes = (durationInTicks: number): number => { const totalMinutes = Math.floor(durationInTicks / 10_000 / 1000 / 60); return totalMinutes; }; export const minutesToHoursString = (totalMinutes: number): string => { const hours = Math.floor(totalMinutes / 60); const minutes = totalMinutes % 60; const paddedMinutes = minutes.toString().padStart(2, '0'); return `${hours.toString()} h ${paddedMinutes}`; }; export const rangeFromDateTimeInMinutes = (dateTime: Date | undefined): DepartureRange => { if (!dateTime) { return DepartureRange.Morning; } const date = new Date(dateTime); const hours = date.getHours(); const minutes = hours * 60 + date.getMinutes(); switch (true) { case minutes >= 300 && minutes < 720: return DepartureRange.Morning; case minutes >= 720 && minutes < 1080: return DepartureRange.Afternoon; case minutes >= 1080 && minutes < 1440: return DepartureRange.Evening; default: return DepartureRange.Night; } }; export const calculateNights = (fromDate: Date, toDate: Date): number => { const from = new Date(fromDate); const to = new Date(toDate); // Normalize to midnight to avoid time issues from.setHours(0, 0, 0, 0); to.setHours(0, 0, 0, 0); const diffTime = to.getTime() - from.getTime(); return Math.round(diffTime / (1000 * 60 * 60 * 24)); }; export const calculateDays = (fromDate: Date, toDate: Date): number => { return calculateNights(fromDate, toDate) + 1; }; export const getSortingName = (translations: any, sortByType: SortByType): string => { switch (sortByType.label) { case 'price': return sortByType.direction === 'asc' ? translations.SRP.PRICE_ASC : translations.SRP.PRICE_DESC; case 'departureTime': return sortByType.direction === 'asc' ? translations.SRP.DEPARTURE_TIME_ASC : translations.SRP.DEPARTURE_TIME_DESC; case 'durationInTicks': return sortByType.direction === 'asc' ? translations.SRP.DURATION_ASC : translations.SRP.DURATION_DESC; default: return sortByType.label; } }; export const findSortByType = (sortByTypes: SortByType[], sortKey: string, direction: string) => { return sortByTypes.find((s) => s.label === sortKey && s.direction === direction) || sortByTypes[0]; }; export const getDatesBetween = (fromDate: string, toDate: string): Date[] => { const dates: Date[] = []; const current = new Date(fromDate); const end = new Date(toDate); while (current < end) { dates.push(new Date(current)); current.setUTCDate(current.getUTCDate() + 1); } return dates; }; export const getDateOnlyTime = (date?: string | Date | null) => { if (!date) return 0; const parsedDate = new Date(date); return new Date(parsedDate.getFullYear(), parsedDate.getMonth(), parsedDate.getDate()).getTime(); };