написал store, authslice и асинхронную функцию запрроса для авторизации
This commit is contained in:
Generated
+1132
-2
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,11 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.9.2",
|
||||||
|
"antd": "^5.27.6",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
"react-router": "^7.9.4",
|
"react-router": "^7.9.4",
|
||||||
"react-router-dom": "^7.9.4"
|
"react-router-dom": "^7.9.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import type {TypedUseSelectorHook} from 'react-redux';
|
||||||
|
import type { RootState, AppDispatch } from './store';
|
||||||
|
|
||||||
|
export const useAppDispatch: () => AppDispatch = useDispatch;
|
||||||
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import authReducer from "../features/auth/authSlice";
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
auth: authReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
import type {PayloadAction} from "@reduxjs/toolkit";
|
||||||
|
import { loginThunk } from "./authThunks";
|
||||||
|
|
||||||
|
interface AuthState {
|
||||||
|
token: string | null;
|
||||||
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: AuthState = {
|
||||||
|
token: null,
|
||||||
|
loading: false,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const authSlice = createSlice({
|
||||||
|
name: "auth",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
logout(state) {
|
||||||
|
state.token = null;
|
||||||
|
state.error = null;
|
||||||
|
localStorage.removeItem("token");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extraReducers: builder => {
|
||||||
|
builder
|
||||||
|
.addCase(loginThunk.pending, state => {
|
||||||
|
state.loading = true;
|
||||||
|
state.error = null;
|
||||||
|
})
|
||||||
|
.addCase(loginThunk.fulfilled, (state, action) => {
|
||||||
|
state.loading = false;
|
||||||
|
state.token = action.payload.token;
|
||||||
|
state.error = null;
|
||||||
|
})
|
||||||
|
.addCase(loginThunk.rejected, (state, action) => {
|
||||||
|
state.loading = false;
|
||||||
|
state.error = action.payload ?? "Ошибка авторизации";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { logout } = authSlice.actions;
|
||||||
|
export default authSlice.reducer;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
export const loginThunk = createAsyncThunk<
|
||||||
|
{ token: string; user: { id: string; name: string; role: string} },
|
||||||
|
{ email: string; password: string },
|
||||||
|
{ rejectValue: string }
|
||||||
|
>(
|
||||||
|
"auth/login",
|
||||||
|
async ({ email, password }, thunkAPI) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/auth/login", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ email, password })
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
return thunkAPI.rejectWithValue(data.message || "Ошибка авторизации");
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return { token: data.token, user: {
|
||||||
|
id: data.user.id,
|
||||||
|
name: data.user.name,
|
||||||
|
role: data.user.role
|
||||||
|
} };
|
||||||
|
} catch (err) {
|
||||||
|
return thunkAPI.rejectWithValue("Ошибка сети");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -4,11 +4,15 @@ import './index.css'
|
|||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
import { BrowserRouter } from 'react-router'
|
import { BrowserRouter } from 'react-router'
|
||||||
import AppRoutes from './app/routes.tsx'
|
import AppRoutes from './app/routes.tsx'
|
||||||
|
import { Provider } from 'react-redux'
|
||||||
|
import { store } from './app/store.ts'
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
<Provider store={store}>
|
||||||
<AppRoutes />
|
<AppRoutes />
|
||||||
|
</Provider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user