feat: user search
This commit is contained in:
@@ -61,7 +61,7 @@ const User: FC<Props> = ({
|
|||||||
<Avatar url={curr.avatar} name={curr.name} alt="avatar" />
|
<Avatar url={curr.avatar} name={curr.name} alt="avatar" />
|
||||||
<div className={`status ${online ? "online" : "offline"}`}></div>
|
<div className={`status ${online ? "online" : "offline"}`}></div>
|
||||||
</div>
|
</div>
|
||||||
{!compact && <span className="name">{curr?.name}</span>}
|
{!compact && <span className="name" title={curr?.name}>{curr?.name}</span>}
|
||||||
{owner && <IconOwner />}
|
{owner && <IconOwner />}
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
@@ -91,7 +91,7 @@ const User: FC<Props> = ({
|
|||||||
<Avatar url={curr.avatar} name={curr.name} alt="avatar" />
|
<Avatar url={curr.avatar} name={curr.name} alt="avatar" />
|
||||||
<div className={`status ${online ? "online" : "offline"}`}></div>
|
<div className={`status ${online ? "online" : "offline"}`}></div>
|
||||||
</div>
|
</div>
|
||||||
{!compact && <span className="name">{curr?.name}</span>}
|
{!compact && <span className="name" title={curr?.name}>{curr?.name}</span>}
|
||||||
{owner && <IconOwner />}
|
{owner && <IconOwner />}
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
</Tippy>
|
</Tippy>
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ const StyledWrapper = styled.div`
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: #52525b;
|
color: #52525b;
|
||||||
|
max-width: 190px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
/* session nav */
|
/* session nav */
|
||||||
&.compact {
|
&.compact {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import styled from "styled-components";
|
|||||||
import Tippy from "@tippyjs/react";
|
import Tippy from "@tippyjs/react";
|
||||||
import searchIcon from "../../assets/icons/search.svg?url";
|
import searchIcon from "../../assets/icons/search.svg?url";
|
||||||
import addIcon from "../../assets/icons/add.svg?url";
|
import addIcon from "../../assets/icons/add.svg?url";
|
||||||
import AddEntriesMenu from "./AddEntriesMenu";
|
import AddEntriesMenu from "../../common/component/AddEntriesMenu";
|
||||||
import Tooltip from "./Tooltip";
|
import Tooltip from "../../common/component/Tooltip";
|
||||||
import { FC } from "react";
|
import { FC, ChangeEvent } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
@@ -30,22 +30,25 @@ const StyledWrapper = styled.div`
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.add {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
type Props = {};
|
type Props = {
|
||||||
const Search: FC<Props> = () => {
|
input: string,
|
||||||
|
updateInput: (input: string) => void
|
||||||
|
};
|
||||||
|
const Search: FC<Props> = ({ input, updateInput }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const handleInput = (evt: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
updateInput(evt.target.value);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
<div className="search">
|
<div className="search">
|
||||||
<img src={searchIcon} alt="search icon" />
|
<img src={searchIcon} alt="search icon" />
|
||||||
<input placeholder={`${t("action.search")}...`} className="input" />
|
<input value={input} placeholder={`${t("action.search")}...`} className="input" onChange={handleInput} />
|
||||||
</div>
|
</div>
|
||||||
<Tooltip tip={t("more")} placement="bottom">
|
<Tooltip tip={t("more")} placement="bottom">
|
||||||
<Tippy interactive placement="bottom-end" trigger="click" content={<AddEntriesMenu />}>
|
<Tippy interactive placement="bottom-end" trigger="click" content={<AddEntriesMenu />}>
|
||||||
<img src={addIcon} alt="add icon" className="add" />
|
<img src={addIcon} alt="add icon" className="cursor-pointer" />
|
||||||
</Tippy>
|
</Tippy>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
@@ -1,22 +1,21 @@
|
|||||||
import { memo, useEffect } from "react";
|
import { memo, useEffect } from "react";
|
||||||
import { NavLink, useParams, useLocation } from "react-router-dom";
|
import { NavLink, useParams, useLocation } from "react-router-dom";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import _ from "lodash";
|
|
||||||
import { updateRememberedNavs } from "../../app/slices/ui";
|
import { updateRememberedNavs } from "../../app/slices/ui";
|
||||||
import Search from "../../common/component/Search";
|
import Search from "./Search";
|
||||||
import User from "../../common/component/User";
|
import User from "../../common/component/User";
|
||||||
import Profile from "../../common/component/Profile";
|
import Profile from "../../common/component/Profile";
|
||||||
|
|
||||||
import StyledWrapper from "./styled";
|
import StyledWrapper from "./styled";
|
||||||
import BlankPlaceholder from "../../common/component/BlankPlaceholder";
|
import BlankPlaceholder from "../../common/component/BlankPlaceholder";
|
||||||
import { useAppSelector } from "../../app/store";
|
import useFilteredUsers from "../../common/hook/useFilteredUsers";
|
||||||
|
|
||||||
function UsersPage() {
|
function UsersPage() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
const { input, updateInput, users } = useFilteredUsers();
|
||||||
const { user_id } = useParams();
|
const { user_id } = useParams();
|
||||||
const userIds = useAppSelector((store) => store.users.ids, _.isEqual);
|
// 记住路由
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(updateRememberedNavs({ key: "user" }));
|
dispatch(updateRememberedNavs({ key: "user" }));
|
||||||
return () => {
|
return () => {
|
||||||
@@ -24,14 +23,14 @@ function UsersPage() {
|
|||||||
};
|
};
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
||||||
if (!userIds) return null;
|
if (!users) return null;
|
||||||
return (
|
return (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
<div className="left">
|
<div className="left">
|
||||||
<Search />
|
<Search input={input} updateInput={updateInput} />
|
||||||
<div className="list">
|
<div className="list">
|
||||||
<nav className="nav">
|
<nav className="nav">
|
||||||
{userIds.map((uid: number) => {
|
{users.map(({ uid }) => {
|
||||||
return (
|
return (
|
||||||
<NavLink key={uid} className="session" to={`/users/${uid}`}>
|
<NavLink key={uid} className="session" to={`/users/${uid}`}>
|
||||||
<User uid={uid} enableContextMenu={true} />
|
<User uid={uid} enableContextMenu={true} />
|
||||||
|
|||||||
Reference in New Issue
Block a user