import { apiClient } from './api-client'; /* -------------------------------------------------------------------------- */ /* Types */ /* -------------------------------------------------------------------------- */ export type PoiCategory = | 'SCHOOL_PRIMARY' | 'SCHOOL_SECONDARY' | 'UNIVERSITY' | 'HOSPITAL' | 'CLINIC' | 'PHARMACY' | 'MARKET' | 'SUPERMARKET' | 'MALL' | 'CONVENIENCE' | 'BANK' | 'ATM' | 'PARK' | 'GAS_STATION' | 'POLICE' | 'POST_OFFICE' | 'METRO_STATION' | 'RAILWAY_STATION' | 'BUS_STATION' | 'AIRPORT'; /** Vietnamese display labels for each POI category. */ export const POI_LABELS: Record = { SCHOOL_PRIMARY: 'Trường tiểu học', SCHOOL_SECONDARY: 'Trường THCS / THPT', UNIVERSITY: 'Đại học / Cao đẳng', HOSPITAL: 'Bệnh viện', CLINIC: 'Phòng khám', PHARMACY: 'Nhà thuốc', MARKET: 'Chợ', SUPERMARKET: 'Siêu thị', MALL: 'TTTM', CONVENIENCE: 'Cửa hàng tiện lợi', BANK: 'Ngân hàng', ATM: 'ATM', PARK: 'Công viên', GAS_STATION: 'Cây xăng', POLICE: 'Công an', POST_OFFICE: 'Bưu điện', METRO_STATION: 'Ga Metro', RAILWAY_STATION: 'Ga tàu', BUS_STATION: 'Bến xe', AIRPORT: 'Sân bay', }; /** Single-emoji icon for chips / map markers (no extra image dep needed). */ export const POI_ICONS: Record = { SCHOOL_PRIMARY: '🏫', SCHOOL_SECONDARY: '🎒', UNIVERSITY: '🎓', HOSPITAL: '🏥', CLINIC: '⚕️', PHARMACY: '💊', MARKET: '🛒', SUPERMARKET: '🏪', MALL: '🛍️', CONVENIENCE: '🏬', BANK: '🏦', ATM: '🏧', PARK: '🌳', GAS_STATION: '⛽', POLICE: '👮', POST_OFFICE: '📮', METRO_STATION: '🚇', RAILWAY_STATION: '🚉', BUS_STATION: '🚌', AIRPORT: '✈️', }; /** Tailwind colour class per category — keep marker coding consistent. */ export const POI_COLORS: Record = { SCHOOL_PRIMARY: '#3b82f6', SCHOOL_SECONDARY: '#2563eb', UNIVERSITY: '#1d4ed8', HOSPITAL: '#ef4444', CLINIC: '#f87171', PHARMACY: '#fb7185', MARKET: '#f59e0b', SUPERMARKET: '#fbbf24', MALL: '#fcd34d', CONVENIENCE: '#fde68a', BANK: '#8b5cf6', ATM: '#a78bfa', PARK: '#22c55e', GAS_STATION: '#64748b', POLICE: '#0f172a', POST_OFFICE: '#be185d', METRO_STATION: '#0ea5e9', RAILWAY_STATION: '#0284c7', BUS_STATION: '#0369a1', AIRPORT: '#075985', }; export interface NearbyPoi { id: string; name: string; category: PoiCategory; distanceM: number; lat: number; lng: number; address: string | null; } export interface NearbyPoiResult { byCategory: Partial>; all: NearbyPoi[]; meta: { radiusMeters: number; totalCount: number; requestedCategories: PoiCategory[] | null }; } export interface PoiBboxFeatureCollection { type: 'FeatureCollection'; features: { type: 'Feature'; id: string; geometry: { type: 'Point'; coordinates: [number, number] }; properties: { id: string; name: string; category: PoiCategory; provinceCode: string | null; districtCode: string | null; }; }[]; meta: { count: number; truncated: boolean; categories: PoiCategory[] }; } /* -------------------------------------------------------------------------- */ /* API */ /* -------------------------------------------------------------------------- */ export const poiApi = { /** * Fetch nearest N POI (per category) within `radius` metres of the given * point. Drives the "tiện ích xung quanh" sidebar. */ nearby: (params: { lat: number; lng: number; radius: number; categories?: PoiCategory[]; limitPerCategory?: number; }): Promise => { const q = new URLSearchParams({ lat: String(params.lat), lng: String(params.lng), radius: String(params.radius), }); if (params.categories?.length) q.set('categories', params.categories.join(',')); if (params.limitPerCategory) q.set('limitPerCategory', String(params.limitPerCategory)); return apiClient.get(`/poi/nearby?${q.toString()}`); }, /** GeoJSON for map overlays. Used by the listing detail mini-map and KCN page. */ byBbox: (params: { south: number; west: number; north: number; east: number; categories?: PoiCategory[]; limit?: number; }): Promise => { const q = new URLSearchParams({ south: String(params.south), west: String(params.west), north: String(params.north), east: String(params.east), }); if (params.categories?.length) q.set('categories', params.categories.join(',')); if (params.limit) q.set('limit', String(params.limit)); return apiClient.get(`/poi/by-bbox?${q.toString()}`); }, };