Show trip dates on option cards
This commit is contained in:
@@ -1678,6 +1678,8 @@
|
|||||||
budgetScenarios: [],
|
budgetScenarios: [],
|
||||||
priceUpdatedAt: '',
|
priceUpdatedAt: '',
|
||||||
priceHistoryRunCount: 0,
|
priceHistoryRunCount: 0,
|
||||||
|
tripCheckIn: '',
|
||||||
|
tripCheckOut: '',
|
||||||
sortMode: localStorage.getItem('cabo_sort_mode') || 'vote-desc',
|
sortMode: localStorage.getItem('cabo_sort_mode') || 'vote-desc',
|
||||||
budgetGuestCount: Number(localStorage.getItem('cabo_budget_guest_count') || 0),
|
budgetGuestCount: Number(localStorage.getItem('cabo_budget_guest_count') || 0),
|
||||||
priceSourceSelections: (() => {
|
priceSourceSelections: (() => {
|
||||||
@@ -1894,6 +1896,8 @@
|
|||||||
const msg = JSON.parse(event.data);
|
const msg = JSON.parse(event.data);
|
||||||
if (msg.type === 'init') {
|
if (msg.type === 'init') {
|
||||||
state.categories = msg.categories;
|
state.categories = msg.categories;
|
||||||
|
state.tripCheckIn = msg.tripCheckIn || '';
|
||||||
|
state.tripCheckOut = msg.tripCheckOut || '';
|
||||||
state.guestRoster = msg.guestRoster || [];
|
state.guestRoster = msg.guestRoster || [];
|
||||||
state.options = msg.options;
|
state.options = msg.options;
|
||||||
state.budgetScenarios = msg.budgetScenarios || [];
|
state.budgetScenarios = msg.budgetScenarios || [];
|
||||||
@@ -2021,6 +2025,21 @@
|
|||||||
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTripDate(value) {
|
||||||
|
if (!value) return '';
|
||||||
|
const date = new Date(`${value}T00:00:00Z`);
|
||||||
|
if (Number.isNaN(date.getTime())) return '';
|
||||||
|
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTripDateRange(checkIn, checkOut) {
|
||||||
|
const start = formatTripDate(checkIn);
|
||||||
|
const end = formatTripDate(checkOut);
|
||||||
|
if (!start && !end) return '';
|
||||||
|
if (start && end) return `${start} to ${end}`;
|
||||||
|
return start || end;
|
||||||
|
}
|
||||||
|
|
||||||
function formatBookingType(bookingType, priceBasis) {
|
function formatBookingType(bookingType, priceBasis) {
|
||||||
const typeLabels = {
|
const typeLabels = {
|
||||||
package: 'Package',
|
package: 'Package',
|
||||||
@@ -2340,10 +2359,11 @@
|
|||||||
|
|
||||||
function getPointContext(point) {
|
function getPointContext(point) {
|
||||||
if (!point) return '';
|
if (!point) return '';
|
||||||
|
const tripDates = formatTripDateRange(point.tripCheckIn, point.tripCheckOut);
|
||||||
const unitContext = point.tripNights && point.unitPrice
|
const unitContext = point.tripNights && point.unitPrice
|
||||||
? `${formatCurrency(point.unitPrice, point.currency || 'USD')} x ${point.tripNights} nights`
|
? `${formatCurrency(point.unitPrice, point.currency || 'USD')} x ${point.tripNights} nights`
|
||||||
: '';
|
: '';
|
||||||
return [unitContext, point.unitDisplayPrice || point.displayPrice || point.decisionNote || '']
|
return [tripDates ? `Dates: ${tripDates}` : '', unitContext, point.unitDisplayPrice || point.displayPrice || point.decisionNote || '']
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' · ');
|
.join(' · ');
|
||||||
}
|
}
|
||||||
@@ -2386,6 +2406,9 @@
|
|||||||
const selectedSeries = getOptionSourceSeries(opt, selectedSourceKey, tabId);
|
const selectedSeries = getOptionSourceSeries(opt, selectedSourceKey, tabId);
|
||||||
const selectedMeta = getOptionSourceMeta(opt, selectedSourceKey, tabId);
|
const selectedMeta = getOptionSourceMeta(opt, selectedSourceKey, tabId);
|
||||||
const selectedPoint = selectedSeries.at(-1) || ((tabId === BUNDLE_TAB_ID || !isStandaloneComponentTab(tabId)) ? opt.latestPricePoint : null);
|
const selectedPoint = selectedSeries.at(-1) || ((tabId === BUNDLE_TAB_ID || !isStandaloneComponentTab(tabId)) ? opt.latestPricePoint : null);
|
||||||
|
const tripCheckIn = selectedPoint?.tripCheckIn || opt.latestPricePoint?.tripCheckIn || state.tripCheckIn || '';
|
||||||
|
const tripCheckOut = selectedPoint?.tripCheckOut || opt.latestPricePoint?.tripCheckOut || state.tripCheckOut || '';
|
||||||
|
const tripDates = formatTripDateRange(tripCheckIn, tripCheckOut);
|
||||||
const insights = selectedPoint ? {
|
const insights = selectedPoint ? {
|
||||||
source: selectedMeta?.sourceLabel || selectedPoint.source || 'Automation feed',
|
source: selectedMeta?.sourceLabel || selectedPoint.source || 'Automation feed',
|
||||||
sourceUrl: selectedMeta?.sourceUrl || selectedPoint.sourceUrl || null,
|
sourceUrl: selectedMeta?.sourceUrl || selectedPoint.sourceUrl || null,
|
||||||
@@ -2456,6 +2479,10 @@
|
|||||||
<span class="option-fact-label">Status</span>
|
<span class="option-fact-label">Status</span>
|
||||||
<div class="option-fact-value">${escapeHtml(statusLabel)}</div>
|
<div class="option-fact-value">${escapeHtml(statusLabel)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="option-fact">
|
||||||
|
<span class="option-fact-label">Dates</span>
|
||||||
|
<div class="option-fact-value">${escapeHtml(tripDates || 'Not specified')}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|||||||
@@ -691,6 +691,8 @@ function buildRealtimeSnapshot() {
|
|||||||
type: 'init',
|
type: 'init',
|
||||||
pollsOpen: data.pollsOpen,
|
pollsOpen: data.pollsOpen,
|
||||||
categories: data.categories,
|
categories: data.categories,
|
||||||
|
tripCheckIn: TRIP_CHECK_IN,
|
||||||
|
tripCheckOut: TRIP_CHECK_OUT,
|
||||||
guestRoster: getGuestRoster().map((guest) => ({
|
guestRoster: getGuestRoster().map((guest) => ({
|
||||||
name: guest.name,
|
name: guest.name,
|
||||||
role: guest.role || 'guest',
|
role: guest.role || 'guest',
|
||||||
|
|||||||
Reference in New Issue
Block a user