TypeScript · 3101 bytes Raw Blame History
1 import axios from 'axios';
2
3 const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
4
5 // Create axios instance with default config
6 export const api = axios.create({
7 baseURL: `${API_URL}/api`,
8 headers: {
9 'Content-Type': 'application/json',
10 },
11 });
12
13 // Types
14 export interface Restaurant {
15 id: number;
16 place_id: string;
17 name: string;
18 address: string;
19 latitude: number;
20 longitude: number;
21 average_rating: number | null;
22 total_ratings: number;
23 created_at: string;
24 has_toast: boolean | null;
25 distance?: number;
26 }
27
28 export interface Rating {
29 id: number;
30 rating: number;
31 review: string;
32 created_at: string;
33 }
34
35 export interface RestaurantDetail extends Restaurant {
36 recent_ratings: Rating[];
37 }
38
39 export interface PlaceSearchResult {
40 place_id: string;
41 name: string;
42 address: string;
43 latitude: number;
44 longitude: number;
45 category?: string;
46 cuisine?: string;
47 confidence?: string;
48 distance?: number;
49 source?: string;
50 restaurant_id?: number;
51 has_toast?: boolean | null;
52 }
53
54 export interface CreateRatingData {
55 rating: number;
56 review: string;
57 }
58
59 // API functions
60 export const restaurantApi = {
61 // Get nearby restaurants
62 getNearby: async (lat: number, lng: number, radius: number = 5) => {
63 const response = await api.get<Restaurant[]>('/restaurants/nearby/', {
64 params: { lat, lng, radius }
65 });
66 return response.data;
67 },
68
69 // Get restaurant details
70 getById: async (id: number) => {
71 const response = await api.get<RestaurantDetail>(`/restaurants/${id}/`);
72 return response.data;
73 },
74
75 // Create restaurant
76 create: async (data: Omit<Restaurant, 'id' | 'average_rating' | 'total_ratings' | 'created_at'>) => {
77 const response = await api.post<Restaurant>('/restaurants/', data);
78 return response.data;
79 },
80
81 // Add rating
82 addRating: async (restaurantId: number, data: CreateRatingData) => {
83 const response = await api.post(`/restaurants/${restaurantId}/ratings/`, data);
84 return response.data;
85 },
86
87 // Update toast status
88 updateToastStatus: async (restaurantId: number, hasToast: boolean) => {
89 const response = await api.patch(`/restaurants/${restaurantId}/toast-status/`, { has_toast: hasToast });
90 return response.data;
91 },
92
93 // Search places - FIXED to handle 404 with data
94 searchPlaces: async (lat: number, lng: number, radius: number = 1000) => {
95 try {
96 const response = await api.get<PlaceSearchResult[]>('/search/places/', {
97 params: { lat, lng, radius }
98 });
99 return response.data;
100 } catch (error) {
101 // Handle the bizarre 404-with-data issue from Railway
102 if (axios.isAxiosError(error)) {
103 if (error.response?.status === 404 && Array.isArray(error.response?.data)) {
104 console.warn('Got 404 with valid data - returning data anyway');
105 return error.response.data as PlaceSearchResult[];
106 }
107 }
108 throw error;
109 }
110 },
111
112 // Seed data
113 seedData: async (lat: number, lng: number) => {
114 const response = await api.post('/seed/', { lat, lng });
115 return response.data;
116 }
117 };