← back to Costa Rica App
src/api.ts
55 lines
// API client for the costa-rica backend. Token persisted in SecureStore.
import Constants from 'expo-constants';
import * as SecureStore from 'expo-secure-store';
const BASE = (Constants.expoConfig?.extra as any)?.apiBase || 'https://costarica.agentabrams.com';
let _token: string | null = null;
export async function loadToken() {
_token = await SecureStore.getItemAsync('cr_token');
return _token;
}
export async function setToken(t: string | null) {
_token = t;
if (t) await SecureStore.setItemAsync('cr_token', t);
else await SecureStore.deleteItemAsync('cr_token');
}
export function isAuthed() { return !!_token; }
async function req(path: string, opts: RequestInit = {}) {
const headers: any = { 'Content-Type': 'application/json', ...(opts.headers || {}) };
if (_token) headers.Authorization = `Bearer ${_token}`;
const res = await fetch(`${BASE}/api/app${path}`, { ...opts, headers });
const j = await res.json().catch(() => ({}));
if (!res.ok || j.ok === false) throw new Error(j.error || `HTTP ${res.status}`);
return j;
}
export const api = {
register: (b: any) => req('/auth/register', { method: 'POST', body: JSON.stringify(b) }),
login: (email: string, password: string) => req('/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }),
apple: (identity_token: string, full_name?: string) => req('/auth/apple', { method: 'POST', body: JSON.stringify({ identity_token, full_name }) }),
me: () => req('/me'),
listings: (q: Record<string, string> = {}) => req('/listings?' + new URLSearchParams(q).toString()),
listing: (slug: string) => req(`/listings/${slug}`),
contact: (slug: string) => req(`/listings/${slug}/contact`),
message: (slug: string, body: string) => req(`/listings/${slug}/message`, { method: 'POST', body: JSON.stringify({ body }) }),
threads: () => req('/threads'),
thread: (id: number) => req(`/threads/${id}`),
availability: (slug: string, from?: string, to?: string) =>
req(`/listings/${slug}/availability?` + new URLSearchParams({ ...(from && { from }), ...(to && { to }) } as any)),
createBooking: (b: any) => req('/bookings', { method: 'POST', body: JSON.stringify(b) }),
myBookings: () => req('/bookings'),
booking: (code: string) => req(`/bookings/${code}`),
pay: (code: string, method: string) => req(`/bookings/${code}/pay`, { method: 'POST', body: JSON.stringify({ method }) }),
payment: (id: string) => req(`/payments/${id}`),
// host
hostApply: (b: any) => req('/host/apply', { method: 'POST', body: JSON.stringify(b) }),
hostListing: (b: any) => req('/host/listings', { method: 'POST', body: JSON.stringify(b) }),
addPayoutMethod: (b: any) => req('/host/payout-methods', { method: 'POST', body: JSON.stringify(b) }),
plaidLinkToken: () => req('/host/plaid/link-token', { method: 'POST', body: '{}' }),
plaidExchange: (public_token: string) => req('/host/plaid/exchange', { method: 'POST', body: JSON.stringify({ public_token }) }),
};
export const money = (minor: number, cur: string) => `${cur} ${(minor / 100).toFixed(2)}`;