Initial commit: Holiday Travel App with resort comparison, trip management, and multi-provider search

This commit is contained in:
2025-10-29 16:22:35 -04:00
commit 74f8e268c3
167 changed files with 18721 additions and 0 deletions

362
lib/resorts.ts Normal file
View File

@@ -0,0 +1,362 @@
// Resort database with features and ratings
export type Resort = {
name: string;
destination: string;
country: string;
airportCode: string;
features: {
beach: number;
pool: number;
golf: number;
spa: number;
food: number;
nightlife: number;
shopping: number;
culture: number;
outdoor: number;
family: number;
};
tripAdvisorRating?: number;
tripAdvisorReviews?: number;
priceRange?: string; // $$$, $$$$, etc.
allInclusive: boolean;
};
// Resort database
export const RESORT_DATABASE: Record<string, Resort> = {
"bahia principe luxury sian ka'an": {
name: "Bahia Principe Luxury Sian Ka'an",
destination: "Riviera Maya",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 9,
pool: 8,
golf: 5,
spa: 8,
food: 8,
nightlife: 6,
shopping: 5,
culture: 6,
outdoor: 7,
family: 9
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 8234,
priceRange: "$$$$",
allInclusive: true
},
"catalonia royal tulum": {
name: "Catalonia Royal Tulum",
destination: "Tulum",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 10,
pool: 9,
golf: 4,
spa: 7,
food: 8,
nightlife: 6,
shopping: 4,
culture: 7,
outdoor: 8,
family: 7
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 6421,
priceRange: "$$$$",
allInclusive: true
},
"secrets akumal riviera maya": {
name: "Secrets Akumal Riviera Maya",
destination: "Akumal",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 10,
pool: 9,
golf: 5,
spa: 9,
food: 9,
nightlife: 7,
shopping: 5,
culture: 6,
outdoor: 9,
family: 6
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 9127,
priceRange: "$$$$$",
allInclusive: true
},
"unico 20°87° hotel riviera maya": {
name: "UNICO 20°87° Hotel Riviera Maya",
destination: "Riviera Maya",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 9,
pool: 10,
golf: 6,
spa: 10,
food: 10,
nightlife: 8,
shopping: 6,
culture: 7,
outdoor: 8,
family: 7
},
tripAdvisorRating: 5.0,
tripAdvisorReviews: 3894,
priceRange: "$$$$$",
allInclusive: true
},
"trs yucatán hotel": {
name: "TRS Yucatán Hotel",
destination: "Riviera Maya",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 9,
pool: 9,
golf: 7,
spa: 8,
food: 8,
nightlife: 7,
shopping: 5,
culture: 5,
outdoor: 7,
family: 8
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 5621,
priceRange: "$$$$",
allInclusive: true
},
"barcelo maya riviera": {
name: "Barcelo Maya Riviera",
destination: "Riviera Maya",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 9,
pool: 9,
golf: 8,
spa: 7,
food: 8,
nightlife: 7,
shopping: 6,
culture: 5,
outdoor: 7,
family: 9
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 12453,
priceRange: "$$$",
allInclusive: true
},
"valentin imperial riviera maya": {
name: "Valentin Imperial Riviera Maya",
destination: "Playa del Carmen",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 10,
pool: 8,
golf: 5,
spa: 8,
food: 9,
nightlife: 6,
shopping: 5,
culture: 5,
outdoor: 7,
family: 7
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 8934,
priceRange: "$$$$",
allInclusive: true
},
"grand sirenis riviera maya": {
name: "Grand Sirenis Riviera Maya",
destination: "Riviera Maya",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 8,
pool: 8,
golf: 6,
spa: 7,
food: 7,
nightlife: 6,
shopping: 5,
culture: 5,
outdoor: 7,
family: 9
},
tripAdvisorRating: 4.0,
tripAdvisorReviews: 7821,
priceRange: "$$$",
allInclusive: true
},
"dreams tulum resort & spa": {
name: "Dreams Tulum Resort & Spa",
destination: "Tulum",
country: "Mexico",
airportCode: "CUN",
features: {
beach: 10,
pool: 8,
golf: 4,
spa: 8,
food: 8,
nightlife: 6,
shopping: 4,
culture: 7,
outdoor: 8,
family: 8
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 6754,
priceRange: "$$$$",
allInclusive: true
},
"hyatt zilara cap cana": {
name: "Hyatt Zilara Cap Cana",
destination: "Cap Cana",
country: "Dominican Republic",
airportCode: "PUJ",
features: {
beach: 10,
pool: 9,
golf: 8,
spa: 9,
food: 9,
nightlife: 8,
shopping: 6,
culture: 5,
outdoor: 8,
family: 5
},
tripAdvisorRating: 5.0,
tripAdvisorReviews: 9821,
priceRange: "$$$$$",
allInclusive: true
},
"secrets cap cana": {
name: "Secrets Cap Cana",
destination: "Cap Cana",
country: "Dominican Republic",
airportCode: "PUJ",
features: {
beach: 10,
pool: 9,
golf: 9,
spa: 9,
food: 9,
nightlife: 8,
shopping: 6,
culture: 5,
outdoor: 8,
family: 6
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 8432,
priceRange: "$$$$$",
allInclusive: true
},
"dreams onyx resort & spa": {
name: "Dreams Onyx Resort & Spa",
destination: "Punta Cana",
country: "Dominican Republic",
airportCode: "PUJ",
features: {
beach: 9,
pool: 9,
golf: 6,
spa: 8,
food: 8,
nightlife: 7,
shopping: 6,
culture: 4,
outdoor: 7,
family: 8
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 5643,
priceRange: "$$$$",
allInclusive: true
},
"royalton chic punta cana": {
name: "Royalton CHIC Punta Cana",
destination: "Punta Cana",
country: "Dominican Republic",
airportCode: "PUJ",
features: {
beach: 9,
pool: 9,
golf: 6,
spa: 8,
food: 8,
nightlife: 9,
shopping: 7,
culture: 4,
outdoor: 7,
family: 5
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 7234,
priceRange: "$$$$",
allInclusive: true
},
"iberostar grand bávaro": {
name: "Iberostar Grand Bávaro",
destination: "Bávaro",
country: "Dominican Republic",
airportCode: "PUJ",
features: {
beach: 10,
pool: 8,
golf: 7,
spa: 8,
food: 8,
nightlife: 7,
shopping: 6,
culture: 4,
outdoor: 7,
family: 7
},
tripAdvisorRating: 4.5,
tripAdvisorReviews: 6821,
priceRange: "$$$$",
allInclusive: true
}
};
export function findResort(name: string): Resort | null {
const normalized = name.toLowerCase().trim();
return RESORT_DATABASE[normalized] || null;
}
export function calculateResortScore(resort: Resort, preferences?: Record<string, number>): number {
if (!preferences) return 0;
let score = 0;
let totalWeight = 0;
for (const [feature, userRating] of Object.entries(preferences)) {
if (userRating && userRating > 0) {
const resortRating = resort.features[feature as keyof typeof resort.features] || 5;
score += (userRating * resortRating);
totalWeight += (userRating * 10);
}
}
// Add TripAdvisor bonus
if (resort.tripAdvisorRating) {
score += resort.tripAdvisorRating * 100;
}
return totalWeight > 0 ? Math.round((score / totalWeight) * 1000) : 0;
}