ilya_shyian преди 2 години
родител
ревизия
865cfe1dba

+ 4 - 1
src/actions/actionUsersFind.js

@@ -10,7 +10,10 @@ export const actionUsersFind =
                 gql(
                     `query UsersFind($query:String){
                         UserFind(query: $query){
-                            _id username 
+                            _id username acl is_active
+                            avatar{
+                                _id url
+                            }
                         }
                     }`,
                     {

+ 50 - 7
src/components/admin/AdminLayoutPage/index.js

@@ -12,7 +12,14 @@ import {
     actionFeedOrdersFind,
     actionFeedCatsFind,
 } from "../../../reducers";
-import { actionFeedAdd, actionFeedClear, actionFeedGoods, actionFeedOrders, actionFeedUsers } from "../../../reducers/feedReducer";
+import {
+    actionFeedAdd,
+    actionFeedClear,
+    actionFeedGoods,
+    actionFeedOrders,
+    actionFeedUsers,
+    actionFeedUsersFind,
+} from "../../../reducers/feedReducer";
 import { CAdminGoodPage } from "../AdminGoodPage";
 import { AdminGoodsPage } from "../AdminGoodsPage";
 import { AdminCategoriesPage } from "../AdminCategoriesPage";
@@ -79,7 +86,6 @@ const AdminCategoriesPageContainer = ({ cats }) => {
     }, [orderBy]);
 
     useEffect(() => {
-        dispatch(actionFeedCats({ skip: cats?.length || 0, orderBy }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
                 const {
@@ -120,7 +126,6 @@ const AdminCategoriesSearchPageContainer = () => {
     }, [orderBy, text]);
 
     useEffect(() => {
-        dispatch(actionFeedCatsFind({ text, skip: categories?.length || 0, orderBy }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
                 const {
@@ -183,7 +188,6 @@ const AdminGoodsPageContainer = ({ goods }) => {
     }, [orderBy]);
 
     useEffect(() => {
-        dispatch(actionFeedGoods({ skip: goods?.length || 0, orderBy }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
                 const {
@@ -224,7 +228,6 @@ const AdminGoodsSearchPageContainer = () => {
     }, [orderBy, text]);
 
     useEffect(() => {
-        dispatch(actionFeedGoodsFind({ text, skip: goods?.length || 0, orderBy }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
                 const {
@@ -265,7 +268,6 @@ const AdminOrdersPageContainer = ({ orders }) => {
     }, [orderBy, status]);
 
     useEffect(() => {
-        dispatch(actionFeedOrders({ skip: orders?.length || 0, orderBy, status }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
                 const {
@@ -306,7 +308,6 @@ const AdminOrdersSearchPageContainer = () => {
     }, [orderBy, text]);
 
     useEffect(() => {
-        dispatch(actionFeedOrdersFind({ text, skip: orders?.length || 0, orderBy }));
         window.onscroll = (e) => {
             if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 200) {
                 const {
@@ -355,6 +356,47 @@ const AdminOrderPageContainer = () => {
     return <CAdminOrderPage />;
 };
 
+const AdminUsersSearchPageContainer = () => {
+    const dispatch = useDispatch();
+    const users = useSelector((state) => state.promise?.feedUsersFind?.payload || []);
+    const [searchParams] = useSearchParams();
+    const orderBy = searchParams.get("orderBy") || "_id";
+    const text = searchParams.get("text") || "";
+
+    useEffect(() => {
+        dispatch(actionFeedClear());
+        dispatch(actionPromiseClear("feedUsersFind"));
+        dispatch(actionPromiseClear("userUpsert"));
+        dispatch(actionFeedUsersFind({ skip: 0, orderBy, text }));
+    }, [orderBy, text]);
+
+    useEffect(() => {
+        window.onscroll = (e) => {
+            if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
+                const {
+                    feed,
+                    promise: { feedUsersFind },
+                } = store.getState();
+
+                if (feedUsersFind.status !== "PENDING") {
+                    dispatch(actionFeedOrdersFind({ text, skip: feed.payload?.length || 0, orderBy }));
+                }
+            }
+        };
+        return () => {
+            dispatch(actionFeedClear());
+            dispatch(actionPromiseClear("feedUsersFind"));
+            dispatch(actionPromiseClear("userUpsert"));
+            window.onscroll = null;
+        };
+    }, []);
+
+    useEffect(() => {
+        if (users?.length) store.dispatch(actionFeedAdd(users));
+    }, [users]);
+    return <AdminUsersPage orderBy={orderBy} />;
+};
+
 const AdminUsersPageContainer = ({ users }) => {
     const dispatch = useDispatch();
     const [searchParams] = useSearchParams();
@@ -443,6 +485,7 @@ const AdminLayoutPage = () => {
                 <Route path="/orders/search" element={<AdminOrdersSearchPageContainer />} />
                 <Route path="/order/" element={<AdminOrderPageContainer />} />
                 <Route path="/order/:_id" element={<AdminOrderPageContainer />} />
+                <Route path="/users/search" element={<AdminUsersSearchPageContainer />} />
                 <Route path="/users/" element={<CAdminUsersPageContainer />} />
                 <Route path="/user/" element={<AdminUserPageContainer />} />
                 <Route path="/user/:_id" element={<AdminUserPageContainer />} />

+ 1 - 1
src/components/admin/AdminUsersPage/AdminUserList.js

@@ -18,7 +18,7 @@ const CSearchResults = connect((state) => ({ items: state.promise.adminUsersFind
 const AdminUserList = ({ users, orderBy = "_id" }) => {
     const [searchParams, setSearchParams] = useSearchParams();
     const navigate = useNavigate();
-
+    console.log(1);
     return (
         <Box className="AdminUserList">
             <Box className="searchBarWrapper">

+ 1 - 3
src/components/common/SearchBar/SearchCategoryResultItem.js

@@ -1,6 +1,6 @@
 import { Link } from "react-router-dom";
 import { Stack, Typography } from "@mui/material";
-const SearchCategoryResultItem = ({ category, onClick, link = "" } = {}) => {
+export const SearchCategoryResultItem = ({ category, onClick, link = "" } = {}) => {
     const { _id = null, name = "" } = category || {};
 
     return (
@@ -13,5 +13,3 @@ const SearchCategoryResultItem = ({ category, onClick, link = "" } = {}) => {
         </Link>
     );
 };
-
-export default SearchCategoryResultItem;

+ 2 - 3
src/components/common/SearchBar/SearchGoodResultItem.js

@@ -3,7 +3,8 @@ import defaultGoodImage from "../../../images/default-good-image.png";
 
 import { Grid, Box, Typography } from "@mui/material";
 import { backendURL, mediaURL } from "../../../helpers";
-const SearchGoodResultItem = ({ good, onClick, link = "" } = {}) => {
+
+export const SearchGoodResultItem = ({ good, onClick, link = "" } = {}) => {
     const { _id = 0, images = [], name = "", description = "", price = "" } = good || {};
 
     return (
@@ -39,5 +40,3 @@ const SearchGoodResultItem = ({ good, onClick, link = "" } = {}) => {
         </Grid>
     );
 };
-
-export default SearchGoodResultItem;

+ 3 - 4
src/components/common/SearchBar/SearchOrderResultItem.js

@@ -1,8 +1,9 @@
 import { Link } from "react-router-dom";
 import { Stack, Typography } from "@mui/material";
 import { statusNumber } from "../../../helpers";
-const SearchOrderResultItem = ({ order, onClick, link = "" } = {}) => {
-    const { _id = null, owner = null, status = "-" } = order || {};
+
+export const SearchOrderResultItem = ({ order, onClick, link = "" } = {}) => {
+    const { _id = null, owner = null } = order || {};
 
     return (
         <Stack
@@ -20,5 +21,3 @@ const SearchOrderResultItem = ({ order, onClick, link = "" } = {}) => {
         </Stack>
     );
 };
-
-export default SearchOrderResultItem;

+ 14 - 21
src/components/common/SearchBar/SearchResults.js

@@ -1,10 +1,11 @@
 import { connect } from "react-redux";
-import SearchGoodResultItem from "./SearchGoodResultItem";
-import SearchCategoryResultItem from "./SearchCategoryResultItem";
+import { SearchGoodResultItem } from "./SearchGoodResultItem";
+import { SearchCategoryResultItem } from "./SearchCategoryResultItem";
 import { Divider, Paper, Stack } from "@mui/material";
 import { Box } from "@mui/system";
 import { Error } from "../Error";
-import SearchOrderResultItem from "./SearchOrderResultItem";
+import { SearchOrderResultItem } from "./SearchOrderResultItem";
+import { SearchUserResultItem } from "./SearchUserResultItem";
 
 export const SearchResults = ({ items, onItemClick, itemLink = "" }) => {
     return (
@@ -14,36 +15,28 @@ export const SearchResults = ({ items, onItemClick, itemLink = "" }) => {
                     itemLink.match(/.+(good).+/) ? (
                         items.map((good) => (
                             <Box key={good._id}>
-                                <SearchGoodResultItem
-                                    link={itemLink}
-                                    good={good}
-                                    key={good._id}
-                                    onClick={() => onItemClick && onItemClick()}
-                                />
+                                <SearchGoodResultItem link={itemLink} good={good} onClick={() => onItemClick && onItemClick()} />
                                 <Divider sx={{ my: 1 }} />
                             </Box>
                         ))
                     ) : itemLink.match(/.+(category|categories).+/) ? (
                         items.map((cat) => (
                             <Box key={cat._id}>
-                                <SearchCategoryResultItem
-                                    link={itemLink}
-                                    category={cat}
-                                    key={cat._id}
-                                    onClick={() => onItemClick && onItemClick()}
-                                />
+                                <SearchCategoryResultItem link={itemLink} category={cat} onClick={() => onItemClick && onItemClick()} />
                                 <Divider sx={{ my: 1 }} />
                             </Box>
                         ))
                     ) : itemLink.match(/.+(order|orders).+/) ? (
                         items.map((order) => (
                             <Box key={order._id}>
-                                <SearchOrderResultItem
-                                    link={itemLink}
-                                    order={order}
-                                    key={order._id}
-                                    onClick={() => onItemClick && onItemClick()}
-                                />
+                                <SearchOrderResultItem link={itemLink} order={order} onClick={() => onItemClick && onItemClick()} />
+                                <Divider sx={{ my: 1 }} />
+                            </Box>
+                        ))
+                    ) : itemLink.match(/.+(user|users).+/) ? (
+                        items.map((user) => (
+                            <Box key={user._id}>
+                                <SearchUserResultItem link={itemLink} user={user} onClick={() => onItemClick && onItemClick()} />
                                 <Divider sx={{ my: 1 }} />
                             </Box>
                         ))

+ 48 - 0
src/components/common/SearchBar/SearchUserResultItem.js

@@ -0,0 +1,48 @@
+import { Link } from "react-router-dom";
+import { Box, Grid, Stack, Typography } from "@mui/material";
+import { backendURL, mediaURL } from "../../../helpers";
+import defaultAvatarImage from "../../../images/default-avatar-image.png";
+import { AiFillPlusCircle, AiOutlineMinusCircle } from "react-icons/ai";
+
+export const SearchUserResultItem = ({ user, onClick, link = "" } = {}) => {
+    const { _id, username, avatar, is_active, acl } = user || {};
+
+    return (
+        <Grid
+            container
+            component={Link}
+            to={`${link}${_id}/`}
+            className="SearchUserResultItem Link"
+            onClick={() => onClick && onClick()}
+            spacing={1}
+        >
+            <Grid item xs={3}>
+                <Box
+                    component="img"
+                    src={avatar ? `${backendURL}${mediaURL}${avatar?.url}` : defaultAvatarImage}
+                    onError={({ currentTarget }) => {
+                        currentTarget.onerror = null;
+                        currentTarget.src = defaultAvatarImage;
+                    }}
+                />
+            </Grid>
+            <Grid item xs={3}>
+                <Box sx={{ p: 1 }}>
+                    <Typography variant="body1" sx={{ flexGrow: 1 }}>
+                        {username.length > 30 ? `${username.substring(0, 30)}...` : username}
+                    </Typography>
+                </Box>
+            </Grid>
+            <Grid item xs={3} sx={{ display: "flex", alignItems: "center", justifyContent: "flex-end" }}>
+                <Typography variant="body1">
+                    {typeof is_active === "boolean" ? is_active ? <AiFillPlusCircle /> : <AiOutlineMinusCircle /> : "-"}
+                </Typography>
+            </Grid>
+            <Grid item xs={3} sx={{ display: "flex", alignItems: "center", justifyContent: "flex-end" }}>
+                <Typography variant="body1">
+                    {acl ? acl.includes("admin") ? <AiFillPlusCircle /> : <AiOutlineMinusCircle /> : "-"}
+                </Typography>
+            </Grid>
+        </Grid>
+    );
+};

+ 3 - 1
src/index.scss

@@ -313,7 +313,8 @@
                         padding: 10px;
                         z-index: 2;
 
-                        & .SearchGoodResultItem {
+                        & .SearchGoodResultItem,
+                        & .SearchUserResultItem {
                             text-align: left;
                             & img {
                                 width: 100%;
@@ -323,6 +324,7 @@
                                 background: #f1f2f4;
                             }
                         }
+
                         & .SearchOrderResultItem {
                             text-align: left;
                             &:hover {