changes
This commit is contained in:
@@ -65,7 +65,10 @@
|
||||
|
||||
type DayTemperature = {
|
||||
available: boolean;
|
||||
temperature_low_c: number | null;
|
||||
temperature_high_c: number | null;
|
||||
temperature_c: number | null;
|
||||
is_estimate: boolean;
|
||||
};
|
||||
|
||||
$: days = groupItemsByDay(collection);
|
||||
@@ -653,7 +656,12 @@
|
||||
if (!result?.date) continue;
|
||||
nextMap[result.date] = {
|
||||
available: !!result.available,
|
||||
temperature_c: typeof result.temperature_c === 'number' ? result.temperature_c : null
|
||||
temperature_low_c:
|
||||
typeof result.temperature_low_c === 'number' ? result.temperature_low_c : null,
|
||||
temperature_high_c:
|
||||
typeof result.temperature_high_c === 'number' ? result.temperature_high_c : null,
|
||||
temperature_c: typeof result.temperature_c === 'number' ? result.temperature_c : null,
|
||||
is_estimate: result.is_estimate === true
|
||||
};
|
||||
}
|
||||
|
||||
@@ -993,12 +1001,22 @@
|
||||
|
||||
function formatDayTemperature(day: DayGroup, temps: Record<string, DayTemperature>): string {
|
||||
const temperature = temps[day.date];
|
||||
if (!temperature?.available || temperature.temperature_c === null) {
|
||||
if (
|
||||
!temperature?.available ||
|
||||
temperature.temperature_low_c === null ||
|
||||
temperature.temperature_high_c === null
|
||||
) {
|
||||
return getI18nText('itinerary.temperature_unavailable', 'Temperature unavailable');
|
||||
}
|
||||
|
||||
const rounded = Math.round(temperature.temperature_c);
|
||||
return `${rounded}°C`;
|
||||
const low = Math.round(temperature.temperature_low_c);
|
||||
const high = Math.round(temperature.temperature_high_c);
|
||||
const rangeText = `${low}°–${high}°C`;
|
||||
if (temperature.is_estimate) {
|
||||
return `${rangeText} ${getI18nText('itinerary.temperature_estimated_marker', 'est.')}`;
|
||||
}
|
||||
|
||||
return rangeText;
|
||||
}
|
||||
|
||||
type HardAnchorTiming = {
|
||||
@@ -2624,6 +2642,18 @@
|
||||
displayDate={suggestionModalDisplayDate}
|
||||
on:close={() => (isSuggestionModalOpen = false)}
|
||||
on:addItem={(e) => {
|
||||
if (e.detail.type === 'location' && e.detail.location?.id) {
|
||||
const createdLocation = e.detail.location;
|
||||
const existingLocations = collection.locations || [];
|
||||
collection = {
|
||||
...collection,
|
||||
locations: [
|
||||
createdLocation,
|
||||
...existingLocations.filter((loc) => loc.id !== createdLocation.id)
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
addItineraryItemForObject(
|
||||
e.detail.type,
|
||||
e.detail.itemId,
|
||||
@@ -2917,8 +2947,6 @@
|
||||
<div class="flex-1 min-w-0 space-y-1">
|
||||
<!-- Main date title + optional day name -->
|
||||
<div class="flex items-baseline gap-2 flex-wrap">
|
||||
<h3 class="text-lg md:text-xl font-bold">{day.displayDate}</h3>
|
||||
|
||||
<!-- Day name - inline with date -->
|
||||
{#if canModify}
|
||||
{#if day.dayMetadata?.name}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
location?: string;
|
||||
rating?: number | string | null;
|
||||
price_level?: string | null;
|
||||
latitude?: number | string | null;
|
||||
longitude?: number | string | null;
|
||||
};
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
@@ -46,6 +48,7 @@
|
||||
];
|
||||
|
||||
const supportedApiCategories = ['restaurant', 'activity', 'event', 'lodging'];
|
||||
const LOCATION_MODEL_TEXT_MAX_LENGTH = 200;
|
||||
|
||||
const activityTypes = ['outdoor', 'cultural', 'entertainment', 'other'];
|
||||
const durations = ['few hours', 'half-day', 'full-day'];
|
||||
@@ -131,6 +134,10 @@
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
function truncateToModelSafeLength(value: string): string {
|
||||
return value.slice(0, LOCATION_MODEL_TEXT_MAX_LENGTH);
|
||||
}
|
||||
|
||||
function normalizeRating(value: unknown): number | null {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return value;
|
||||
@@ -146,6 +153,19 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
function normalizeCoordinate(value: unknown): number | null {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
const parsed = Number(value.trim());
|
||||
return Number.isFinite(parsed) ? parsed : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function normalizeSuggestionItem(value: unknown): SuggestionItem | null {
|
||||
const item = asRecord(value);
|
||||
if (!item) return null;
|
||||
@@ -169,6 +189,8 @@
|
||||
normalizeText(item.priceLevel) ||
|
||||
normalizeText(item.price);
|
||||
const rating = normalizeRating(item.rating ?? item.score);
|
||||
const latitude = normalizeCoordinate(item.latitude ?? item.lat);
|
||||
const longitude = normalizeCoordinate(item.longitude ?? item.lon ?? item.lng);
|
||||
|
||||
const finalName = name || location;
|
||||
if (!finalName) return null;
|
||||
@@ -180,30 +202,39 @@
|
||||
category: category || undefined,
|
||||
location: location || undefined,
|
||||
rating,
|
||||
price_level: priceLevel || null
|
||||
price_level: priceLevel || null,
|
||||
latitude,
|
||||
longitude
|
||||
};
|
||||
}
|
||||
|
||||
function buildLocationPayload(suggestion: SuggestionItem) {
|
||||
const name =
|
||||
const resolvedName =
|
||||
normalizeText(suggestion.name) || normalizeText(suggestion.location) || 'Suggestion';
|
||||
const locationText =
|
||||
const name = truncateToModelSafeLength(resolvedName);
|
||||
const resolvedLocation =
|
||||
normalizeText(suggestion.location) ||
|
||||
getCollectionLocation() ||
|
||||
normalizeText(suggestion.name);
|
||||
normalizeText(suggestion.name) ||
|
||||
name;
|
||||
const locationText = truncateToModelSafeLength(resolvedLocation || name);
|
||||
const description =
|
||||
normalizeText(suggestion.description) ||
|
||||
normalizeText(suggestion.why_fits) ||
|
||||
(suggestion.category ? `${suggestion.category} suggestion` : '');
|
||||
const rating = normalizeRating(suggestion.rating);
|
||||
const latitude = normalizeCoordinate(suggestion.latitude);
|
||||
const longitude = normalizeCoordinate(suggestion.longitude);
|
||||
|
||||
return {
|
||||
name,
|
||||
description,
|
||||
location: locationText || name,
|
||||
rating,
|
||||
latitude,
|
||||
longitude,
|
||||
collections: [collection.id],
|
||||
is_public: false
|
||||
is_public: Boolean(collection?.is_public)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -293,7 +324,8 @@
|
||||
dispatch('addItem', {
|
||||
type: 'location',
|
||||
itemId: location.id,
|
||||
updateDate: false
|
||||
updateDate: false,
|
||||
location
|
||||
});
|
||||
} catch (_err) {
|
||||
error = $t('suggestions.error');
|
||||
|
||||
@@ -1193,7 +1193,9 @@
|
||||
"drag_to_reorder": "Drag to reorder",
|
||||
"add_to_day": "Add to day",
|
||||
"optimize": "Optimize",
|
||||
"add_place": "+ Add place"
|
||||
"add_place": "+ Add place",
|
||||
"temperature_unavailable": "Temperature unavailable",
|
||||
"temperature_estimated_marker": "est."
|
||||
},
|
||||
"common": {
|
||||
"show_less": "Hide details",
|
||||
|
||||
Reference in New Issue
Block a user