fix(reduxSetup)
This commit is contained in:
parent
c60b3a978f
commit
23d349625d
@ -16,6 +16,7 @@
|
|||||||
"@mui/icons-material": "^5.16.6",
|
"@mui/icons-material": "^5.16.6",
|
||||||
"@mui/material": "^5.16.6",
|
"@mui/material": "^5.16.6",
|
||||||
"@mui/material-nextjs": "^5.16.6",
|
"@mui/material-nextjs": "^5.16.6",
|
||||||
|
"@reduxjs/toolkit": "^2.2.7",
|
||||||
"@tanstack/react-table": "^8.20.1",
|
"@tanstack/react-table": "^8.20.1",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
@ -23,6 +24,7 @@
|
|||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "^7.52.2",
|
"react-hook-form": "^7.52.2",
|
||||||
|
"react-redux": "^9.1.2",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
|
@ -16,6 +16,9 @@ import { loginApi } from "@/services/api/loginApi";
|
|||||||
import { FormControl } from '@mui/material';
|
import { FormControl } from '@mui/material';
|
||||||
import CustomTextField from "@/ui/CustomTextField";
|
import CustomTextField from "@/ui/CustomTextField";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { RootState } from "@/services/store";
|
||||||
|
import { setAuthTokens, setUserDetails } from "@/services/store/authSlice";
|
||||||
|
|
||||||
const loginSchema = z.object({
|
const loginSchema = z.object({
|
||||||
username: z.string(),
|
username: z.string(),
|
||||||
@ -29,14 +32,15 @@ export default function LoginPage() {
|
|||||||
const { register, handleSubmit, formState: { errors }, control } = useForm<LoginFormValues>({
|
const { register, handleSubmit, formState: { errors }, control } = useForm<LoginFormValues>({
|
||||||
resolver: zodResolver(loginSchema),
|
resolver: zodResolver(loginSchema),
|
||||||
});
|
});
|
||||||
console.log("errors", errors)
|
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
const dispatch = useDispatch();
|
||||||
const onSubmit = async (data: LoginFormValues) => {
|
const onSubmit = async (data: LoginFormValues) => {
|
||||||
try {
|
try {
|
||||||
const response = await loginApi(data);
|
const response = await loginApi(data);
|
||||||
localStorage.setItem('token', response.token);
|
localStorage.setItem('token', response.token);
|
||||||
localStorage.setItem('refreshToken', response.refreshToken);
|
localStorage.setItem('refreshToken', response.refreshToken);
|
||||||
|
dispatch(setAuthTokens({ token: response.token, refreshToken: response.refreshToken }));
|
||||||
|
dispatch(setUserDetails(response));
|
||||||
|
|
||||||
router.push('/home');
|
router.push('/home');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
"use client"
|
||||||
import { AppRouterCacheProvider } from "@mui/material-nextjs/v13-appRouter";
|
import { AppRouterCacheProvider } from "@mui/material-nextjs/v13-appRouter";
|
||||||
import { ThemeProvider } from "@mui/material/styles";
|
import { ThemeProvider } from "@mui/material/styles";
|
||||||
import theme from "../theme";
|
import theme from "../theme";
|
||||||
import "./globals.scss";
|
import "./globals.scss";
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import store from "@/services/store";
|
||||||
|
|
||||||
interface RootLayoutProps {
|
interface RootLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@ -12,9 +15,11 @@ export default function RootLayout(props: RootLayoutProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body>
|
<body>
|
||||||
<AppRouterCacheProvider>
|
<Provider store={store}>
|
||||||
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
<AppRouterCacheProvider>
|
||||||
</AppRouterCacheProvider>
|
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
||||||
|
</AppRouterCacheProvider>
|
||||||
|
</Provider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// api.ts
|
// api.ts
|
||||||
import axiosInstance from '../axios/axiosInstance';
|
import axiosInstance from '../axios/axiosInstance';
|
||||||
|
|
||||||
interface LoginResponse {
|
export interface LoginResponse {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
57
src/services/store/authSlice.ts
Normal file
57
src/services/store/authSlice.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// store/slices/authSlice.ts
|
||||||
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
import { LoginResponse } from '../api/loginApi';
|
||||||
|
|
||||||
|
interface AuthState {
|
||||||
|
token: string | null;
|
||||||
|
refreshToken: string | null;
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
gender: string;
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: AuthState = {
|
||||||
|
token: null,
|
||||||
|
refreshToken: null,
|
||||||
|
id: 0,
|
||||||
|
username: '',
|
||||||
|
email: '',
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
gender: '',
|
||||||
|
image: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const authSlice = createSlice({
|
||||||
|
name: 'auth',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setAuthTokens: (
|
||||||
|
state,
|
||||||
|
action: PayloadAction<{ token: string; refreshToken: string }>
|
||||||
|
) => {
|
||||||
|
state.token = action.payload.token;
|
||||||
|
state.refreshToken = action.payload.refreshToken;
|
||||||
|
localStorage.setItem('token', action.payload.token);
|
||||||
|
localStorage.setItem('refreshToken', action.payload.refreshToken);
|
||||||
|
},
|
||||||
|
clearAuthTokens: (state) => {
|
||||||
|
state.token = null;
|
||||||
|
state.refreshToken = null;
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
localStorage.removeItem('refreshToken');
|
||||||
|
},
|
||||||
|
setUserDetails: (state, action: PayloadAction<LoginResponse>) => {
|
||||||
|
state = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { setAuthTokens, clearAuthTokens, setUserDetails } =
|
||||||
|
authSlice.actions;
|
||||||
|
|
||||||
|
export default authSlice.reducer;
|
15
src/services/store/index.tsx
Normal file
15
src/services/store/index.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
// store/index.ts
|
||||||
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
|
import authReducer from './authSlice';
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
auth: authReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
|
|
||||||
|
export default store;
|
Loading…
x
Reference in New Issue
Block a user