diff --git a/.env.example b/.env.example index de0f388..3805e7a 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ VITE_API_DOMAIN=http://localhost:3000 +VITE_MOCK_MODE=false diff --git a/package.json b/package.json index f8d2074..166f157 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "type": "module", "scripts": { "dev": "vite", + "dev:mock": "VITE_MOCK_MODE=true vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" diff --git a/src/api/client.ts b/src/api/client.ts index 6acd721..9a9a763 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import { useStore } from '../store/useStore'; import type { Profile, ApiResponse } from '../types/api'; +import { mockApi } from './mock'; const getClient = () => { const { apiDomain, apiKey } = useStore.getState(); @@ -14,11 +15,17 @@ const getClient = () => { export const api = { getProfile: async () => { + if (useStore.getState().isMockMode) { + return mockApi.getProfile(); + } const client = getClient(); const response = await client.get>('/v1/profile'); return response.data.data; }, checkHealth: async () => { + if (useStore.getState().isMockMode) { + return mockApi.checkHealth(); + } const client = getClient(); const response = await client.get('/v1/health'); return response.data; diff --git a/src/api/mock.ts b/src/api/mock.ts new file mode 100644 index 0000000..637da4e --- /dev/null +++ b/src/api/mock.ts @@ -0,0 +1,26 @@ +import type { Profile } from '../types/api'; + +export const mockProfile: Profile = { + fullName: 'Иванов Иван Иванович', + group: 'ИКПИ-11', + faculty: 'Инфокоммуникационных сетей и систем', + studentId: '2210000', + email: 'ivanov.ii@example.com', + raw: { + 'Дата рождения': '01.01.2004', + 'Статус': 'Студент', + }, +}; + +export const mockApi = { + getProfile: async (): Promise => { + return new Promise((resolve) => { + setTimeout(() => resolve(mockProfile), 500); + }); + }, + checkHealth: async (): Promise => { + return new Promise((resolve) => { + setTimeout(() => resolve({ status: 'ok', mock: true }), 300); + }); + }, +}; diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 5867265..b353229 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom'; import { api } from '../api/client'; export const Login: React.FC = () => { - const { apiDomain, apiKey, setApiDomain, setApiKey } = useStore(); + const { apiDomain, apiKey, isMockMode, setApiDomain, setApiKey, setMockMode } = useStore(); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const navigate = useNavigate(); @@ -16,10 +16,14 @@ export const Login: React.FC = () => { try { // Basic validation - if (!apiDomain || !apiKey) { + if (!isMockMode && (!apiDomain || !apiKey)) { throw new Error('Please fill all fields'); } + if (isMockMode && !apiKey) { + setApiKey('mock-session'); + } + // Check health await api.checkHealth(); @@ -44,6 +48,7 @@ export const Login: React.FC = () => { placeholder="API Domain (e.g. https://api.example.com)" value={apiDomain} onChange={(e) => setApiDomain(e.target.value)} + disabled={isMockMode} /> { placeholder="API Key" value={apiKey} onChange={(e) => setApiKey(e.target.value)} + disabled={isMockMode} /> + +
+ setMockMode(e.target.checked)} + style={{ marginRight: '8px' }} + /> + +
+ {error && (

{error} diff --git a/src/store/useStore.ts b/src/store/useStore.ts index c79a52d..2ec3a38 100644 --- a/src/store/useStore.ts +++ b/src/store/useStore.ts @@ -4,8 +4,10 @@ import { persist } from 'zustand/middleware'; interface AppState { apiDomain: string; apiKey: string; + isMockMode: boolean; setApiDomain: (domain: string) => void; setApiKey: (key: string) => void; + setMockMode: (isMock: boolean) => void; reset: () => void; } @@ -14,8 +16,10 @@ export const useStore = create()( (set) => ({ apiDomain: import.meta.env.VITE_API_DOMAIN || '', apiKey: '', + isMockMode: import.meta.env.VITE_MOCK_MODE === 'true', setApiDomain: (apiDomain) => set({ apiDomain }), setApiKey: (apiKey) => set({ apiKey }), + setMockMode: (isMockMode) => set({ isMockMode }), reset: () => set({ apiKey: '' }), }), {