| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import { API_BASE_URL } from '../utils/constants';
- interface ApiResponse<T = any> {
- data: T;
- status: number;
- }
- class ApiClient {
- private baseURL: string;
- constructor(baseURL: string) {
- this.baseURL = baseURL;
- }
- private getAuthHeaders(): Record<string, string> {
- const token = localStorage.getItem('authToken') || localStorage.getItem('token');
- const language = localStorage.getItem('userLanguage') || 'ja';
- // console.log('API 呼び出し token:', token ? token.substring(0, 10) + '...' : 'null');
- return {
- 'Content-Type': 'application/json',
- 'x-user-language': language,
- ...(token && { Authorization: `Bearer ${token}` }),
- };
- }
- // 新しい API 呼び出し方法、{ data, status } を返す
- async get<T = any>(url: string): Promise<ApiResponse<T>> {
- const response = await fetch(`${this.baseURL}${url}`, {
- method: 'GET',
- headers: this.getAuthHeaders(),
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(errorData.message || 'Request failed');
- }
- const data = await response.json();
- return { data, status: response.status };
- }
- async post<T = any>(url: string, body?: any): Promise<ApiResponse<T>> {
- const response = await fetch(`${this.baseURL}${url}`, {
- method: 'POST',
- headers: this.getAuthHeaders(),
- body: body ? JSON.stringify(body) : undefined,
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(errorData.message || 'Request failed');
- }
- const data = await response.json();
- return { data, status: response.status };
- }
- async put<T = any>(url: string, body?: any): Promise<ApiResponse<T>> {
- const response = await fetch(`${this.baseURL}${url}`, {
- method: 'PUT',
- headers: this.getAuthHeaders(),
- body: body ? JSON.stringify(body) : undefined,
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(errorData.message || 'Request failed');
- }
- const data = await response.json();
- return { data, status: response.status };
- }
- async delete<T = any>(url: string): Promise<ApiResponse<T>> {
- const response = await fetch(`${this.baseURL}${url}`, {
- method: 'DELETE',
- headers: this.getAuthHeaders(),
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(errorData.message || 'Request failed');
- }
- const data = await response.json();
- return { data, status: response.status };
- }
- // 既存の API 互換性方法を維持、パスとオプションパラメータを受け取り、元の Response を返す
- async request(path: string, options: RequestInit = {}): Promise<Response> {
- const token = localStorage.getItem('authToken');
- const headers = new Headers(options.headers);
- if (token) {
- headers.set('Authorization', `Bearer ${token}`);
- }
- const language = localStorage.getItem('userLanguage') || 'ja';
- headers.set('x-user-language', language);
- // 完全な URL を構築
- let url = path;
- if (!path.startsWith('http')) {
- const cleanPath = path.startsWith('/') ? path : `/${path}`;
- url = `${this.baseURL}${cleanPath}`;
- }
- const response = await fetch(url, {
- ...options,
- headers,
- });
- if (response.status === 401) {
- localStorage.removeItem('authToken');
- window.location.reload();
- throw new Error('Unauthorized');
- }
- return response;
- }
- }
- export const apiClient = new ApiClient(API_BASE_URL);
|