chore: continue new layout
This commit is contained in:
@@ -139,7 +139,7 @@ export const {
|
|||||||
useGetAgoraConfigQuery,
|
useGetAgoraConfigQuery,
|
||||||
useUpdateAgoraConfigMutation,
|
useUpdateAgoraConfigMutation,
|
||||||
useGetServerQuery,
|
useGetServerQuery,
|
||||||
useLazyGetMetricsQuery,
|
useGetMetricsQuery,
|
||||||
useLazyGetServerQuery,
|
useLazyGetServerQuery,
|
||||||
useUpdateServerMutation,
|
useUpdateServerMutation,
|
||||||
useUpdateLogoMutation,
|
useUpdateLogoMutation,
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import Tippy from "@tippyjs/react";
|
||||||
|
import { hideAll } from "tippy.js";
|
||||||
|
import { useGetMetricsQuery } from "../../app/services/server";
|
||||||
|
import addIcon from "../../assets/icons/add.svg?url";
|
||||||
|
import mailIcon from "../../assets/icons/mail.svg?url";
|
||||||
|
import Tooltip from "./Tooltip";
|
||||||
|
import ChannelIcon from "./ChannelIcon";
|
||||||
|
import ChannelModal from "./ChannelModal";
|
||||||
|
import ContactsModal from "./ContactsModal";
|
||||||
|
|
||||||
|
const StyledWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
padding: 15px 15px 15px 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
/* margin-bottom: 10px; */
|
||||||
|
.server {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
.logo {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
.name {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 100%;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 100%;
|
||||||
|
color: #78787c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.add {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.popup {
|
||||||
|
z-index: 999;
|
||||||
|
user-select: none;
|
||||||
|
box-shadow: 0px 20px 25px rgba(31, 41, 55, 0.1),
|
||||||
|
0px 10px 10px rgba(31, 41, 55, 0.04);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #616161;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 4px;
|
||||||
|
.item {
|
||||||
|
border-radius: 3px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px 8px;
|
||||||
|
&:hover {
|
||||||
|
background: rgba(116, 127, 141, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export default function Server() {
|
||||||
|
const { data } = useGetMetricsQuery();
|
||||||
|
const { currentUser, server } = useSelector((store) => {
|
||||||
|
return {
|
||||||
|
currentUser: store.contacts.byId[store.authData.uid],
|
||||||
|
server: store.server,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const [channelModalVisible, setChannelModalVisible] = useState(false);
|
||||||
|
const [contactsModalVisible, setContactsModalVisible] = useState(false);
|
||||||
|
const [isPrivate, setIsPrivate] = useState(false);
|
||||||
|
const toggleContactsModalVisible = () => {
|
||||||
|
setContactsModalVisible((prevVisible) => {
|
||||||
|
if (!prevVisible) {
|
||||||
|
hideAll();
|
||||||
|
}
|
||||||
|
return !prevVisible;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleOpenChannelModal = (isPrivate) => {
|
||||||
|
setIsPrivate(isPrivate);
|
||||||
|
setChannelModalVisible(true);
|
||||||
|
hideAll();
|
||||||
|
};
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
setChannelModalVisible(false);
|
||||||
|
};
|
||||||
|
console.log("server info", server, data);
|
||||||
|
const { name, description, logo } = server;
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
{channelModalVisible && (
|
||||||
|
<ChannelModal personal={isPrivate} closeModal={handleCloseModal} />
|
||||||
|
)}
|
||||||
|
{contactsModalVisible && (
|
||||||
|
<ContactsModal closeModal={toggleContactsModalVisible} />
|
||||||
|
)}
|
||||||
|
<div className="server">
|
||||||
|
<div className="logo">
|
||||||
|
<img src={logo} />
|
||||||
|
</div>
|
||||||
|
<div className="info">
|
||||||
|
<h3 className="name" title={description}>
|
||||||
|
{name}
|
||||||
|
</h3>
|
||||||
|
<span className="desc">{data?.user_count} members</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Tooltip tip="More" placement="bottom">
|
||||||
|
<Tippy
|
||||||
|
interactive
|
||||||
|
placement="bottom-end"
|
||||||
|
trigger="click"
|
||||||
|
content={
|
||||||
|
<ul className="popup">
|
||||||
|
{currentUser?.is_admin && (
|
||||||
|
<li
|
||||||
|
className="item"
|
||||||
|
onClick={handleOpenChannelModal.bind(null, false)}
|
||||||
|
>
|
||||||
|
<ChannelIcon />
|
||||||
|
New Channel
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
<li
|
||||||
|
className="item"
|
||||||
|
onClick={handleOpenChannelModal.bind(null, true)}
|
||||||
|
>
|
||||||
|
<ChannelIcon personal={true} />
|
||||||
|
New Private Channel
|
||||||
|
</li>
|
||||||
|
<li className="item" onClick={toggleContactsModalVisible}>
|
||||||
|
<img src={mailIcon} alt="icon mail" />
|
||||||
|
New Message
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<img src={addIcon} alt="add icon" className="add" />
|
||||||
|
</Tippy>
|
||||||
|
</Tooltip>
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import { AiOutlineCaretDown } from "react-icons/ai";
|
|||||||
|
|
||||||
import StyledWrapper from "./styled";
|
import StyledWrapper from "./styled";
|
||||||
import AddIcon from "../../assets/icons/add.svg";
|
import AddIcon from "../../assets/icons/add.svg";
|
||||||
import Search from "../../common/component/Search";
|
import Server from "../../common/component/Server";
|
||||||
import Tooltip from "../../common/component/Tooltip";
|
import Tooltip from "../../common/component/Tooltip";
|
||||||
// import Contact from "../../common/component/Contact";
|
// import Contact from "../../common/component/Contact";
|
||||||
import CurrentUser from "../../common/component/CurrentUser";
|
import CurrentUser from "../../common/component/CurrentUser";
|
||||||
@@ -53,7 +53,7 @@ export default function ChatPage() {
|
|||||||
)}
|
)}
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
<div className="left">
|
<div className="left">
|
||||||
<Search />
|
<Server />
|
||||||
<div className="list channels">
|
<div className="list channels">
|
||||||
<h3 className="title">
|
<h3 className="title">
|
||||||
<span className="txt" onClick={handleToggleExpand}>
|
<span className="txt" onClick={handleToggleExpand}>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import styled from "styled-components";
|
|||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 12px 48px 10px 0;
|
padding: 8px 48px 10px 0;
|
||||||
> .left {
|
> .left {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import styled from "styled-components";
|
|||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 12px 48px 10px 0;
|
padding: 8px 48px 10px 0;
|
||||||
> .left {
|
> .left {
|
||||||
border-radius: 16px 0 0 16px;
|
border-radius: 16px 0 0 16px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// import React from 'react';
|
||||||
|
import styled from "styled-components";
|
||||||
|
import Avatar from "../../common/component/Avatar";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
const StyledWrapper = styled.div`
|
||||||
|
padding: 10px 12px;
|
||||||
|
.avatar {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
img {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export default function ServerDropList({ uid = null }) {
|
||||||
|
const user = useSelector((store) => store.contacts.byId[uid]);
|
||||||
|
if (!user) return null;
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
<div className="avatar">
|
||||||
|
<Avatar url={user.avatar} name={user.name} />
|
||||||
|
</div>
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
import { Outlet, NavLink, useLocation } from "react-router-dom";
|
import { Outlet, NavLink, useLocation } from "react-router-dom";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import StyledWrapper from "./styled";
|
import StyledWrapper from "./styled";
|
||||||
import ServerDropList from "./ServerDropList";
|
import User from "./User";
|
||||||
// import Tools from "./Tools";
|
// import Tools from "./Tools";
|
||||||
import Loading from "./Loading";
|
import Loading from "./Loading";
|
||||||
import Menu from "./Menu";
|
import Menu from "./Menu";
|
||||||
@@ -18,10 +18,12 @@ import FolderIcon from "../../assets/icons/folder.svg?url";
|
|||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const {
|
const {
|
||||||
|
loginUid,
|
||||||
ui: { ready },
|
ui: { ready },
|
||||||
} = useSelector((store) => {
|
} = useSelector((store) => {
|
||||||
return {
|
return {
|
||||||
ui: store.ui,
|
ui: store.ui,
|
||||||
|
loginUid: store.authData.uid,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const { data, loading } = usePreload();
|
const { data, loading } = usePreload();
|
||||||
@@ -43,11 +45,7 @@ export default function HomePage() {
|
|||||||
<Notification />
|
<Notification />
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
<div className={`col left`}>
|
<div className={`col left`}>
|
||||||
<ServerDropList
|
<User uid={loginUid} />
|
||||||
data={data?.server}
|
|
||||||
memberCount={data.contacts?.length}
|
|
||||||
expand={false}
|
|
||||||
/>
|
|
||||||
<nav className="nav">
|
<nav className="nav">
|
||||||
<NavLink className="link" to={"/chat"}>
|
<NavLink className="link" to={"/chat"}>
|
||||||
<Tooltip tip="Chat">
|
<Tooltip tip="Chat">
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ const Styled = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 8px 24px 10px 0;
|
||||||
|
border-radius: 16px;
|
||||||
.opts {
|
.opts {
|
||||||
padding: 20px 16px;
|
padding: 20px 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user