diff --git a/bro.config.js b/bro.config.js
index aa1862d..0990dc2 100644
--- a/bro.config.js
+++ b/bro.config.js
@@ -26,6 +26,6 @@ module.exports = {
},
},
config: {
- "dry-wash.api.url": "/api"
+ "nav2.api": "/api"
},
}
diff --git a/src/__data__/actions/users.ts b/src/__data__/actions/users.ts
index 55a1b57..3e920eb 100644
--- a/src/__data__/actions/users.ts
+++ b/src/__data__/actions/users.ts
@@ -1,4 +1,5 @@
import * as types from '../const'
+import { starsSlice } from '../slices/stars'
import { setStars } from './stars'
@@ -20,7 +21,7 @@ export const getUsers = () => async (dispatch, getState) => {
dispatch(success(data))
Object.keys(data).forEach(userId => {
- dispatch(setStars({ id: userId, value: data[userId].rated }))
+ dispatch(starsSlice.actions.setStars({ id: userId, value: data[userId].rated }))
})
} else {
throw 'Что-то пошло не так'
@@ -29,4 +30,4 @@ export const getUsers = () => async (dispatch, getState) => {
} catch (e) {
dispatch(error('Что-то пошло не так'))
}
-}
\ No newline at end of file
+}
diff --git a/src/__data__/model/index.ts b/src/__data__/model/index.ts
new file mode 100644
index 0000000..ab035f5
--- /dev/null
+++ b/src/__data__/model/index.ts
@@ -0,0 +1,15 @@
+export interface BaseResponse
{
+ success: boolean;
+ body: Body;
+}
+
+export interface User {
+ id: string;
+ name: string;
+ age: number;
+ surname: null;
+ email: null;
+ rated: number;
+ avatar: string;
+ friends: User[];
+}
diff --git a/src/__data__/reducers/users.ts b/src/__data__/reducers/users.ts
index 0f2c223..b4ed9bb 100644
--- a/src/__data__/reducers/users.ts
+++ b/src/__data__/reducers/users.ts
@@ -47,4 +47,4 @@ export const reducer = createReducer(initialState, {
[types.USER_FETCH_SUCCESS]: fetchSuccess,
[types.USER_FETCH_ERROR]: fetchError,
[types.USER_FETCH_RESET]: reset,
-})
\ No newline at end of file
+})
diff --git a/src/__data__/service/main.ts b/src/__data__/service/main.ts
new file mode 100644
index 0000000..3134762
--- /dev/null
+++ b/src/__data__/service/main.ts
@@ -0,0 +1,32 @@
+import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
+import { getConfigValue } from '@brojs/cli'
+import { BaseResponse, User } from '../model'
+
+export const api = createApi({
+ reducerPath: 'api',
+ baseQuery: fetchBaseQuery({
+ baseUrl: getConfigValue('nav2.api'),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ }),
+ tagTypes: ['Users'],
+ endpoints: (builder) => ({
+ users: builder.query, void>({
+ query: () => ({
+ url: '/users',
+ }),
+ providesTags: ['Users'],
+ transformResponse: (response: BaseResponse) =>
+ response.body.reduce((acc, user) => ({ ...acc, [user.id]: user }), {}),
+ }),
+ updateRating: builder.mutation({
+ query: ({ userId, rating }) => ({
+ url: `/user/rate/${userId}`,
+ method: 'POST',
+ body: { rating },
+ }),
+ invalidatesTags: ['Users'],
+ }),
+ }),
+})
diff --git a/src/__data__/slices/stars.ts b/src/__data__/slices/stars.ts
new file mode 100644
index 0000000..6e3357e
--- /dev/null
+++ b/src/__data__/slices/stars.ts
@@ -0,0 +1,23 @@
+import { type PayloadAction, createSlice } from '@reduxjs/toolkit'
+
+const initialState = {
+ friends: {} as Record,
+ user: {},
+}
+
+export const starsSlice = createSlice({
+ name: 'stars',
+ initialState,
+ reducers: {
+ setStars(state, action) {
+ state.friends[action.payload.id] = action.payload.value
+ },
+ increment(state, action: PayloadAction<{ id: string }>) {
+ state.friends[action.payload.id] += 1
+ },
+ decrement(state, action) {
+ state.friends[action.payload.id] -= 1
+ },
+ },
+})
+
diff --git a/src/__data__/store.ts b/src/__data__/store.ts
index e1f93c0..a91da31 100644
--- a/src/__data__/store.ts
+++ b/src/__data__/store.ts
@@ -1,18 +1,21 @@
import { configureStore } from '@reduxjs/toolkit'
import { useSelector } from 'react-redux'
-import { starsReducer } from './reducers/stars'
import { reducer as usersFetchReducer } from './reducers/users'
+import { starsSlice } from './slices/stars'
+import { api } from './service/main'
export const store = configureStore({
reducer: {
- stars: starsReducer,
user: usersFetchReducer,
+ [starsSlice.reducerPath]: starsSlice.reducer,
+ [api.reducerPath]: api.reducer,
},
devTools: {
name: 'stars',
},
- middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware()
+ .concat(api.middleware),
})
export type StoreType = ReturnType
diff --git a/src/app.tsx b/src/app.tsx
index e0dc98f..87e73b4 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -2,11 +2,13 @@ import React, { useCallback, useState } from 'react'
import { BrowserRouter } from 'react-router-dom'
import { ChakraProvider } from '@chakra-ui/react'
import { Provider } from 'react-redux'
+import { ApiProvider } from '@reduxjs/toolkit/query/react'
import { Dashboard } from './dashboard'
import { stars as starsContext } from './__data__/context'
import { users } from './__data__/users'
import { store } from './__data__/store'
+import { api } from './__data__/service/main'
const App = () => {
const [stars, setStar] = useState(
@@ -31,7 +33,9 @@ const App = () => {
+ {/* */}
+ {/* */}
diff --git a/src/components/profile/profile.tsx b/src/components/profile/profile.tsx
index dd90322..030ced3 100644
--- a/src/components/profile/profile.tsx
+++ b/src/components/profile/profile.tsx
@@ -22,15 +22,10 @@ import { stars as starsContext } from '../../__data__/context'
import { useUsers } from '../../hooks'
import { useDispatch, useSelector } from 'react-redux'
import { decrementStars, incrementStars } from '../../__data__/actions/stars'
-
-type User = Record & {
- id: string
- name: string
- age: number
- avatar?: string
- rated: number
- friends?: User[]
-}
+import { useAppSelector } from '../../__data__/store'
+import { starsSlice } from '../../__data__/slices/stars'
+import { User } from '../../__data__/model'
+import { api } from '../../__data__/service/main'
const features = getFeatures('nav2')
@@ -172,16 +167,22 @@ const Counter = ({
userId: string
}) => {
// const { rate, setUserRate } = useUsers((state) => state[userId].rated)
- const rate = useSelector((store) => store.stars.friends[userId]) ?? 0
+ // const rate = useSelector((store) => store.stars.friends)
+ const { data, error, isLoading } = api.useUsersQuery()
+
const dispatch = useDispatch()
+ const handleIncrement = () => {
+ dispatch(starsSlice.actions.increment({ id: userId }))
+ }
+
return (
- {rate}
+ {data?.[userId]?.rated}
-
-
+
+
)
diff --git a/src/components/stars.tsx b/src/components/stars.tsx
index 3f74eac..9c2299f 100644
--- a/src/components/stars.tsx
+++ b/src/components/stars.tsx
@@ -1,4 +1,4 @@
-import { HStack, Icon } from '@chakra-ui/react'
+import { HStack, Icon, transform } from '@chakra-ui/react'
import { FaRegStar, FaStar } from 'react-icons/fa6'
import React, { useMemo, useState } from 'react'
import { getConfigValue } from '@brojs/cli'
@@ -7,6 +7,7 @@ import { useDispatch, useSelector } from 'react-redux'
import { stars } from '../__data__/context'
import { useUsers } from '../hooks'
import { setStars } from '../__data__/actions/stars'
+import { api } from '../__data__/service/main'
const useStars = (currentRated, starsCount) => {
@@ -39,11 +40,16 @@ export const Stars = ({
// setRated: starsSetRated
// } = useStars(rated, count)
// const { setUserRate } = useUsers(state => state[userId].rated)
- const rate = useSelector((store) => store.stars.friends[userId]) ?? 0
+ // const rate = useSelector((store) => store.stars.friends[userId as '2']) ?? 0
const dispatch = useDispatch()
+ const { data, error, isLoading } = api.useUsersQuery(void 0)
+ const [updateRating, updateRatingRequest] = api.useUpdateRatingMutation()
+
+ const rate = data?.[userId]?.rated ?? 0
const handleStarsClick = (value: number) => {
- dispatch(setStars({ id: userId, value }))
+ // dispatch(setStars({ id: userId, value }))
+ updateRating({ userId, rating: value })
// setUserRate(userId, stars)
// fetch(getConfigValue('dry-wash.api.url') + '/user-rate', {
// method: 'POST',
diff --git a/src/pages/friends.tsx b/src/pages/friends.tsx
index 07fcfa5..89a713b 100644
--- a/src/pages/friends.tsx
+++ b/src/pages/friends.tsx
@@ -11,21 +11,23 @@ import { UnknownAction } from 'redux'
import { useAppSelector } from '../__data__/store'
import { Statuses } from '../__data__/reducers/users'
import { userSelectors } from '../__data__/selectors'
+import { api } from '../__data__/service/main'
export const Friends = memo(() => {
// const [isLoading, setIsLoading] = useState(false)
// const [data, setData] = useState(null)
// const [error, setError] = useState(null)
- const dispatch = useDispatch()
+ // const dispatch = useDispatch()
const [showModal, setShowModal] = useState(false)
+ const { data, error, isLoading } = api.useUsersQuery({})
- const isLoading = useAppSelector(userSelectors.isLoading)
- const data = useAppSelector(userSelectors.data)
- const error = useAppSelector(userSelectors.error)
+ // const isLoading = useAppSelector(userSelectors.isLoading)
+ // const data = useAppSelector(userSelectors.data)
+ // const error = useAppSelector(userSelectors.error)
- useEffect(() => {
- dispatch(getUsers() as unknown as UnknownAction)
- }, [])
+ // useEffect(() => {
+ // dispatch(getUsers() as unknown as UnknownAction)
+ // }, [])
if(!data || isLoading) return loading...
diff --git a/stubs/api/index.js b/stubs/api/index.js
index f4ce897..6a5a439 100644
--- a/stubs/api/index.js
+++ b/stubs/api/index.js
@@ -19,7 +19,6 @@ timer.fast = timer(300)
router.post('/user-rate', (req, res) => {
res.status(500).send({ ok: false })
})
-
router.use('/admin', router2)
router.get('/users',
@@ -27,17 +26,18 @@ router.get('/users',
res.status(stubs.users.includes('error') ? 400 : 200).send(require(`../json/users/${stubs.users}.json`))
})
+router.post('/user/rate/:userId', (req, res) => {
+ stubs.users = 'success-incremented'
+
+ res.send({ ok: true })
+})
+
router2.get('/', (req, res) => {
res.send(`
Users
-
- Users
-
-
+
`)
diff --git a/stubs/json/users/success-incremented.json b/stubs/json/users/success-incremented.json
new file mode 100644
index 0000000..814ccc6
--- /dev/null
+++ b/stubs/json/users/success-incremented.json
@@ -0,0 +1,43 @@
+{
+ "success": false,
+ "body": [
+ {
+ "id": "some-user-id",
+ "name": "alexandr",
+ "age": 38,
+ "surname": null,
+ "email": null,
+ "rated": 5,
+ "avatar": "https://www.gravatar.com/avatar/6529e885535ef67a3fad810ad71167c2c03f79480936e9b3a714731753cbb47e?d=robohash",
+ "friends": [
+ {
+ "id": "2",
+ "name": "not alexandr",
+ "surname": null,
+ "email": null,
+ "rated": 2,
+ "avatar": "https://www.gravatar.com/avatar/6e?d=robohash"
+ }
+ ]
+ },
+ {
+ "id": "2",
+ "name": "not alexandr",
+ "surname": null,
+ "email": null,
+ "age": 24,
+ "rated": 2,
+ "avatar": "https://www.gravatar.com/avatar/6e?d=robohash",
+ "friends": [
+ {
+ "id": "some-user-id",
+ "name": "alexandr",
+ "surname": null,
+ "email": null,
+ "rated": 3,
+ "avatar": "https://www.gravatar.com/avatar/6529e885535ef67a3fad810ad71167c2c03f79480936e9b3a714731753cbb47e?d=robohash"
+ }
+ ]
+ }
+ ]
+}
diff --git a/stubs/json/users/success.json b/stubs/json/users/success.json
index e6898ba..3509ad5 100644
--- a/stubs/json/users/success.json
+++ b/stubs/json/users/success.json
@@ -1,7 +1,7 @@
{
"success": false,
- "body": {
- "some-user-id": {
+ "body": [
+ {
"id": "some-user-id",
"name": "alexandr",
"age": 38,
@@ -20,7 +20,7 @@
}
]
},
- "2": {
+ {
"id": "2",
"name": "not alexandr",
"surname": null,
@@ -39,5 +39,5 @@
}
]
}
- }
+ ]
}