mirror of
https://github.com/ershisan99/cards-front.git
synced 2025-12-16 20:49:28 +00:00
part 3 extra reducers
This commit is contained in:
1
.env.development
Normal file
1
.env.development
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_BASE_API_URL="http://localhost:7542/2.0/"
|
||||||
1
.env.example
Normal file
1
.env.example
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_BASE_API_URL="http://localhost:7542/2.0/"
|
||||||
1
.env.production
Normal file
1
.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_BASE_API_URL="https://neko-back.herokuapp.com/2.0/"
|
||||||
15
.idea/git_toolbox_prj.xml
generated
Normal file
15
.idea/git_toolbox_prj.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GitToolBoxProjectSettings">
|
||||||
|
<option name="commitMessageIssueKeyValidationOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
<option name="commitMessageValidationEnabledOverride">
|
||||||
|
<BoolValueOverride>
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</BoolValueOverride>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
16
src/App.tsx
16
src/App.tsx
@@ -7,7 +7,7 @@ import { createTheme, ThemeProvider } from "@mui/material"
|
|||||||
import { useAppDispatch, useAppSelector } from "@/app/hooks"
|
import { useAppDispatch, useAppSelector } from "@/app/hooks"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import { appActions } from "@/features/app/app.slice"
|
import { appActions } from "@/features/app/app.slice"
|
||||||
import { instance } from "@/app/instance"
|
import { authThunks } from "@/features/auth/auth.slice"
|
||||||
|
|
||||||
export const Test = () => {
|
export const Test = () => {
|
||||||
const isLoading = useAppSelector((state) => state.app.isLoading)
|
const isLoading = useAppSelector((state) => state.app.isLoading)
|
||||||
@@ -22,12 +22,24 @@ export const Test = () => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(appActions.setIsLoading({ isLoading: false }))
|
dispatch(appActions.setIsLoading({ isLoading: false }))
|
||||||
}, 3000)
|
}, 3000)
|
||||||
instance.get("/ping")
|
|
||||||
}, [dispatch])
|
}, [dispatch])
|
||||||
|
|
||||||
if (isLoading) return <div>loading...</div>
|
if (isLoading) return <div>loading...</div>
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
dispatch(
|
||||||
|
authThunks.login({
|
||||||
|
email: "andres99.dev@gmail.com",
|
||||||
|
password: "123123123",
|
||||||
|
rememberMe: true,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
login
|
||||||
|
</button>
|
||||||
<button onClick={handleErrorButtonClicked}>create error</button>
|
<button onClick={handleErrorButtonClicked}>create error</button>
|
||||||
{!!error && <h2>{error}</h2>}
|
{!!error && <h2>{error}</h2>}
|
||||||
<Counter />
|
<Counter />
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit"
|
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit"
|
||||||
import counterReducer from "../features/counter/counterSlice"
|
import counterReducer from "../features/counter/counterSlice"
|
||||||
import { appReducer } from "@/features/app/app.slice"
|
import { appReducer } from "@/features/app/app.slice"
|
||||||
|
import { authReducer } from "@/features/auth/auth.slice"
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
counter: counterReducer,
|
counter: counterReducer,
|
||||||
app: appReducer,
|
app: appReducer,
|
||||||
|
auth: authReducer,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,38 @@
|
|||||||
import { AuthInstance } from "@/features/auth/auth.instance"
|
import { AuthInstance } from "@/features/auth/auth.instance"
|
||||||
|
|
||||||
export const AuthApi = () => ({
|
export const AuthApi = {
|
||||||
register: (params: any) => {
|
register: (params: RegisterArgs) => {
|
||||||
return AuthInstance.post(params)
|
return AuthInstance.post<RegisterResponse>("register", params)
|
||||||
},
|
},
|
||||||
})
|
login: (params: LoginArgs) => {
|
||||||
|
return AuthInstance.post<User>("login", params)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RegisterResponse = {
|
||||||
|
addedUser: AddedUser
|
||||||
|
}
|
||||||
|
|
||||||
|
type PasswordToPick = {
|
||||||
|
password: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AddedUser = Omit<User, "token" | "tokenDeathTime">
|
||||||
|
export type RegisterArgs = Pick<User, "email"> & PasswordToPick
|
||||||
|
export type LoginArgs = Pick<User, "email" | "rememberMe"> & PasswordToPick
|
||||||
|
export type PartialUser = Partial<User>
|
||||||
|
|
||||||
|
export type User = {
|
||||||
|
_id: string
|
||||||
|
email: string
|
||||||
|
rememberMe: boolean
|
||||||
|
isAdmin: boolean
|
||||||
|
name: string
|
||||||
|
verified: boolean
|
||||||
|
publicCardPacksCount: number
|
||||||
|
created: string
|
||||||
|
updated: string
|
||||||
|
token: string
|
||||||
|
tokenDeathTime: number
|
||||||
|
__v: number
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
|
|
||||||
export const AuthInstance = axios.create({
|
export const AuthInstance = axios.create({
|
||||||
baseURL: import.meta.env.BASE_URL + "auth/",
|
baseURL: import.meta.env.VITE_BASE_API_URL + "auth/",
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
})
|
})
|
||||||
|
|||||||
46
src/features/auth/auth.slice.ts
Normal file
46
src/features/auth/auth.slice.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit"
|
||||||
|
import {
|
||||||
|
AuthApi,
|
||||||
|
LoginArgs,
|
||||||
|
RegisterArgs,
|
||||||
|
User,
|
||||||
|
} from "@/features/auth/auth.api"
|
||||||
|
|
||||||
|
const register = createAsyncThunk("auth/register", (arg: RegisterArgs) => {
|
||||||
|
AuthApi.register(arg)
|
||||||
|
.then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
console.error(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const login = createAsyncThunk("auth/login", async (arg: LoginArgs) => {
|
||||||
|
try {
|
||||||
|
const res = await AuthApi.login(arg)
|
||||||
|
return { user: res.data }
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const slice = createSlice({
|
||||||
|
name: "auth",
|
||||||
|
initialState: { user: null as User | null },
|
||||||
|
reducers: {
|
||||||
|
setUser: (state, action: PayloadAction<{ user: User }>) => {
|
||||||
|
state.user = action.payload.user
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraReducers: (builder) => {
|
||||||
|
builder.addCase(login.fulfilled, (state, action) => {
|
||||||
|
if (action.payload?.user) {
|
||||||
|
state.user = action.payload.user
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const authReducer = slice.reducer
|
||||||
|
export const authThunks = { register, login }
|
||||||
Reference in New Issue
Block a user