From 9f19912bddef62062fd8c0e80ff00fac74a46656 Mon Sep 17 00:00:00 2001 From: Lukas Bauer Date: Wed, 4 Feb 2026 11:00:00 +0000 Subject: [PATCH] Add LoadingSpinner and API client with auth interceptors --- src/api/client.ts | 23 +++++++++++++++++++++++ src/components/LoadingSpinner.tsx | 14 ++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/api/client.ts create mode 100644 src/components/LoadingSpinner.tsx diff --git a/src/api/client.ts b/src/api/client.ts new file mode 100644 index 0000000..408e66f --- /dev/null +++ b/src/api/client.ts @@ -0,0 +1,23 @@ +import axios from 'axios'; + +export const apiClient = axios.create({ + baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api', + headers: { 'Content-Type': 'application/json' }, +}); + +apiClient.interceptors.request.use((config) => { + const token = localStorage.getItem('access_token'); + if (token) config.headers.Authorization = `Bearer ${token}`; + return config; +}); + +apiClient.interceptors.response.use( + (r) => r, + (err) => { + if (err.response?.status === 401) { + localStorage.removeItem('access_token'); + window.location.href = '/login'; + } + return Promise.reject(err); + }, +); diff --git a/src/components/LoadingSpinner.tsx b/src/components/LoadingSpinner.tsx new file mode 100644 index 0000000..4a54c47 --- /dev/null +++ b/src/components/LoadingSpinner.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +interface Props { size?: number; } + +export const LoadingSpinner: React.FC = ({ size = 32 }) => ( +
+ + + + + + +
+);