diff --git a/src/App.tsx b/src/App.tsx
index 3574907..21dc42f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,6 +1,7 @@
-import { ClerkProvider } from '@clerk/clerk-react';
+import { ClerkProvider, useAuth } from '@clerk/clerk-react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import { useEffect } from 'react';
// Import Leaflet CSS
import 'leaflet/dist/leaflet.css';
@@ -24,6 +25,10 @@ import {
WhyCleanPage
} from './pages';
+// Services
+import { apiClient } from './services/api';
+import { reportService } from './services/reportService';
+
const queryClient = new QueryClient({
defaultOptions: {
queries: {
@@ -39,11 +44,26 @@ if (!clerkPubKey) {
throw new Error('Missing Clerk Publishable Key');
}
+// Component to initialize API clients with auth token
+function ApiInitializer({ children }: { children: React.ReactNode }) {
+ const { getToken } = useAuth();
+
+ useEffect(() => {
+ // Set up token getter for API clients
+ const tokenGetter = () => getToken();
+ apiClient.setTokenGetter(tokenGetter);
+ reportService.setTokenGetter(tokenGetter);
+ }, [getToken]);
+
+ return <>{children}>;
+}
+
function App() {
return (
-
+
+
{/* Public routes */}
} />
@@ -134,6 +154,7 @@ function App() {
/>
+
);
diff --git a/src/services/api.ts b/src/services/api.ts
index d4565f7..f55ab78 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -1,4 +1,5 @@
// API service configuration and base client
+import { useAuth } from '@clerk/clerk-react';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api';
@@ -11,21 +12,30 @@ export interface ApiError {
export class ApiClient {
private baseUrl: string;
+ private getToken?: () => Promise;
constructor(baseUrl: string = API_BASE_URL) {
this.baseUrl = baseUrl;
}
+ setTokenGetter(getToken: () => Promise) {
+ this.getToken = getToken;
+ }
+
private async request(
endpoint: string,
options: RequestInit = {}
): Promise {
const url = `${this.baseUrl}${endpoint}`;
+ // Get auth token if available
+ const token = this.getToken ? await this.getToken() : null;
+
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
...options.headers,
},
});
diff --git a/src/services/reportService.ts b/src/services/reportService.ts
index 7ff5bda..4650bca 100644
--- a/src/services/reportService.ts
+++ b/src/services/reportService.ts
@@ -24,6 +24,12 @@ export interface UploadPhotoResponse {
}
class ReportService {
+ private getToken?: () => Promise;
+
+ setTokenGetter(getToken: () => Promise) {
+ this.getToken = getToken;
+ }
+
/**
* Upload a photo to the server
*/
@@ -31,8 +37,14 @@ class ReportService {
const formData = new FormData();
formData.append('photo', file);
+ // Get auth token
+ const token = this.getToken ? await this.getToken() : null;
+
const response = await fetch(`${import.meta.env.VITE_API_BASE_URL || 'http://localhost:3005/api'}/reports/upload`, {
method: 'POST',
+ headers: {
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ },
body: formData,
});