File size: 2,709 Bytes
3998131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
const API_URL = process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000"

interface ApiRequestOptions {
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
  body?: Record<string, any>
  requiresAuth?: boolean
}

class ApiClient {
  private baseUrl: string

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
  }

  private getAuthToken(): string | null {
    if (typeof window === "undefined") return null
    return localStorage.getItem("access_token")
  }

  async request<T>(endpoint: string, options: ApiRequestOptions = {}): Promise<T> {
    const { method = "GET", body, requiresAuth = false } = options

    const headers: HeadersInit = {
      "Content-Type": "application/json",
    }

    if (requiresAuth) {
      const token = this.getAuthToken()
      if (token) {
        headers["Authorization"] = `Bearer ${token}`
      }
    }

    const config: RequestInit = {
      method,
      headers,
    }

    if (body && method !== "GET") {
      config.body = JSON.stringify(body)
    }

    const url = `${this.baseUrl}${endpoint}`

    try {
      const response = await fetch(url, config)
      const data = await response.json()

      if (!response.ok) {
        throw new Error(data.detail || `API Error: ${response.status}`)
      }

      return data as T
    } catch (error) {
      if (error instanceof Error) {
        throw error
      }
      throw new Error("An unexpected error occurred")
    }
  }

  // Auth endpoints
  async login(email: string, password: string): Promise<{ access_token: string; refresh_token?: string; user: any }> {
    return this.request("/api/v1/auth/login", {
      method: "POST",
      body: { email, password },
    })
  }

  async register(email: string, password: string, full_name: string): Promise<{ access_token: string; refresh_token?: string; user: any }> {
    return this.request("/api/v1/auth/signup", {
      method: "POST",
      body: { email, password, full_name },
    })
  }

  // Protected endpoints
  async get<T>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, {
      method: "GET",
      requiresAuth: true,
    })
  }

  async post<T>(endpoint: string, body: Record<string, any>): Promise<T> {
    return this.request<T>(endpoint, {
      method: "POST",
      body,
      requiresAuth: true,
    })
  }

  async put<T>(endpoint: string, body: Record<string, any>): Promise<T> {
    return this.request<T>(endpoint, {
      method: "PUT",
      body,
      requiresAuth: true,
    })
  }

  async delete<T>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, {
      method: "DELETE",
      requiresAuth: true,
    })
  }
}

export const apiClient = new ApiClient(API_URL)