Initial commit: Vuelato - buscador de vuelos
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Nuxt 4 + Supabase + Flightics API. Incluye búsqueda de vuelos, inspiraciones, watchlist, tracking de precios y mapa interactivo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
64
server/api/destination-image.get.ts
Normal file
64
server/api/destination-image.get.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { serverSupabaseServiceRole } from '#supabase/server'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { city } = getQuery(event)
|
||||
if (!city || typeof city !== 'string') {
|
||||
throw createError({ statusCode: 400, message: 'city is required' })
|
||||
}
|
||||
|
||||
const cityKey = city.trim().toLowerCase()
|
||||
const client = serverSupabaseServiceRole(event)
|
||||
|
||||
// Check cache first
|
||||
const { data: cached } = await client
|
||||
.from('destination_images')
|
||||
.select('*')
|
||||
.eq('city_name', cityKey)
|
||||
.single()
|
||||
|
||||
if (cached) {
|
||||
// Refresh if older than 30 days
|
||||
const age = Date.now() - new Date(cached.cached_at).getTime()
|
||||
if (age < 30 * 24 * 60 * 60 * 1000) {
|
||||
return cached
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch from Unsplash
|
||||
const accessKey = process.env.UNSPLASH_ACCESS_KEY
|
||||
if (!accessKey) {
|
||||
throw createError({ statusCode: 500, message: 'UNSPLASH_ACCESS_KEY not configured' })
|
||||
}
|
||||
|
||||
const result = await $fetch<{ results: { urls: { regular: string; small: string }; user: { name: string; links: { html: string } } }[] }>('https://api.unsplash.com/search/photos', {
|
||||
query: {
|
||||
query: `${city} city travel`,
|
||||
per_page: 1,
|
||||
orientation: 'landscape',
|
||||
},
|
||||
headers: {
|
||||
Authorization: `Client-ID ${accessKey}`,
|
||||
},
|
||||
}).catch(() => null)
|
||||
|
||||
if (!result?.results?.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const photo = result.results[0]
|
||||
const row = {
|
||||
city_name: cityKey,
|
||||
image_url: photo.urls.regular,
|
||||
thumb_url: photo.urls.small,
|
||||
photographer: photo.user.name,
|
||||
photographer_url: photo.user.links.html,
|
||||
cached_at: new Date().toISOString(),
|
||||
}
|
||||
|
||||
// Upsert cache
|
||||
await client
|
||||
.from('destination_images')
|
||||
.upsert(row, { onConflict: 'city_name' })
|
||||
|
||||
return row
|
||||
})
|
||||
Reference in New Issue
Block a user