refactor: more tailwind

This commit is contained in:
Tristan Yang
2023-02-07 09:25:05 +08:00
parent 07ddfbf12b
commit c5669f8bc4
48 changed files with 447 additions and 1314 deletions
+12 -13
View File
@@ -21,7 +21,6 @@ import IconPin from "../../../assets/icons/pin.svg";
import IconHeadphone from "../../../assets/icons/headphone.svg";
import addIcon from "../../../assets/icons/add.svg?url";
import { StyledUsers, StyledChannelChat } from "./styled";
import InviteModal from "../../../common/component/InviteModal";
import LoadMore from "../LoadMore";
import { useAppSelector } from "../../../app/store";
@@ -151,11 +150,11 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
</header>
}
users={
<StyledUsers className={membersVisible ? "flex" : "hidden"}>
<div className={`flex-col gap-1 w-[226px] h-[calc(100vh_-_56px_-_22px)] overflow-y-scroll p-2 shadow-[inset_1px_0px_0px_rgba(0,_0,_0,_0.1)] ${membersVisible ? "flex" : "hidden"}`}>
{addVisible && (
<div className="add" onClick={toggleAddVisible}>
<img className="icon" src={addIcon} />
<div className="txt dark:!text-gray-50">{t("add_channel_members")}</div>
<div className="cursor-pointer flex items-center justify-start gap-1 select-none rounded-lg p-2.5 hover:bg-gray-500/10" onClick={toggleAddVisible}>
<img className="w-6 h-6" src={addIcon} />
<div className="font-semibold text-sm text-gray-600 dark:text-gray-50">{t("add_channel_members")}</div>
</div>
)}
{memberIds.map((uid: number) => {
@@ -171,19 +170,19 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
/>
);
})}
</StyledUsers>
</div>
}
>
<StyledChannelChat id={`VOCECHAT_FEED_channel_${cid}`}>
<article className="py-4.5 px-4 w-full h-full overflow-x-hidden overflow-y-auto" id={`VOCECHAT_FEED_channel_${cid}`}>
{hasMore ? (
<LoadMore pullUp={pullUp} pulling={pulling} />
) : (
<div className="info">
<h2 className="title dark:text-white">{t("welcome_channel", { name })}</h2>
<p className="desc dark:!text-gray-300">{t("welcome_desc", { name })} </p>
<div className="pt-14 flex flex-col items-start gap-2">
<h2 className="font-bold text-4xl dark:text-white">{t("welcome_channel", { name })}</h2>
<p className="text-gray-600 dark:text-gray-300">{t("welcome_desc", { name })} </p>
{loginUser?.is_admin && (
<NavLink to={`/setting/channel/${cid}?f=${pathname}`} className="edit">
<EditIcon className="icon" />
<NavLink to={`/setting/channel/${cid}?f=${pathname}`} className="flex items-center gap-1 bg-clip-text text-fill-transparent bg-gradient-to-r from-[#3c8ce7] to-primary-400 ">
<EditIcon className="w-4 h-4 fill-[#3c8ce7]" />
{t("edit_channel")}
</NavLink>
)}
@@ -205,7 +204,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
context: "channel"
});
})}
</StyledChannelChat>
</article>
</Layout>
</>
);
-85
View File
@@ -1,85 +0,0 @@
import styled from "styled-components";
export const StyledUsers = styled.div`
/* display: flex; */
flex-direction: column;
gap: 5px;
/* todo */
width: 226px;
height: calc(100vh - 56px - 22px);
overflow-y: scroll;
padding: 8px;
box-shadow: inset 1px 0px 0px rgba(0, 0, 0, 0.1);
> .add {
cursor: pointer;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 4px;
padding: 10px;
border-radius: 8px;
user-select: none;
&:hover {
background: rgba(116, 127, 141, 0.1);
}
.icon {
width: 24px;
height: 24px;
}
.txt {
font-weight: 600;
font-size: 14px;
line-height: 20px;
color: #52525b;
}
}
`;
export const StyledChannelChat = styled.article`
padding: 18px 16px;
width: 100%;
height: 100%;
height: -webkit-fill-available;
overflow-x: hidden;
overflow-y: auto;
overflow-anchor: auto;
> .info {
padding-top: 62px;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
.title {
font-weight: bold;
font-size: 36px;
line-height: 44px;
}
.desc {
color: #78787c;
font-weight: 500;
font-size: 16px;
line-height: 24px;
}
.edit {
display: flex;
align-items: center;
gap: 4px;
.icon {
width: 16px;
height: 16px;
path {
fill: #3c8ce7;
}
}
padding: 0;
font-style: normal;
font-weight: 500;
font-size: 16px;
line-height: 24px;
background: linear-gradient(135deg, #3c8ce7 0%, #00eaff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
}
`;
+5 -2
View File
@@ -13,6 +13,7 @@ import useLicense from "../../../common/hook/useLicense";
import LicenseUpgradeTip from "./LicenseOutdatedTip";
// import { useTranslation } from "react-i18next";
import DnDTip from "./DnDTip";
import clsx from "clsx";
interface Props {
readonly?: boolean;
@@ -112,13 +113,15 @@ const Layout: FC<Props> = ({
<main className="main" ref={messagesContainer}>
<div className="chat">
{children}
<div className={`send ${selects ? "selecting" : ""}`}>
<div className={`p-4 pt-0 ${selects ? "selecting" : ""}`}>
{readonly ? (
<LoginTip />
) : reachLimit ? (
<LicenseUpgradeTip />
) : (
<Send key={to} id={to} context={context} />
<div className={clsx(`flex justify-center`, selects && "hidden")}>
<Send key={to} id={to} context={context} />
</div>
)}
{selects && <Operations context={context} id={to} />}
</div>
+1 -14
View File
@@ -24,15 +24,6 @@ const Styled = styled.article`
flex-direction: column;
padding: 0;
height: calc(100vh - 56px - 18px);
> .send {
padding: 0 16px 16px 16px;
&.selecting {
padding: 0;
> .send {
display: none;
}
}
}
}
.members {
box-shadow: inset 0px 10px 2px -10px rgba(0, 0, 0, 0.1);
@@ -52,8 +43,7 @@ const Styled = styled.article`
height: 1px;
margin: 18px auto;
}
.tools,
.apps {
.tools {
display: flex;
flex-direction: column;
}
@@ -93,9 +83,6 @@ const Styled = styled.article`
}
}
}
.apps {
gap: 15px;
}
}
}
+35 -23
View File
@@ -2,7 +2,6 @@ import { memo } from "react";
import { Outlet, NavLink, useLocation, useMatch } from "react-router-dom";
import { useTranslation } from "react-i18next";
import StyledWrapper from "./styled";
import User from "./User";
import Loading from "../../common/component/Loading";
import Menu from "./Menu";
@@ -52,49 +51,62 @@ function HomePage() {
// 有点绕
const chatNav = isChatHomePath ? "/chat" : chatPath || "/chat";
const userNav = userPath || "/users";
const linkClass = `flex items-center gap-2.5 px-3 py-2 font-semibold text-sm text-gray-600 rounded-lg hover:bg-black/10`;
return (
<>
<Manifest />
{!guest && <Notification />}
<StyledWrapper className={`dark:!bg-[#121926] ${guest ? "guest" : ""}`}>
<div className={`flex w-screen h-screen dark:bg-[#121926]`}>
{!guest && (
<div className={`col left`}>
<div className={`h-full flex flex-col items-center relative w-16 transition-all`}>
{loginUid && <User uid={loginUid} />}
<nav className="link_navs">
<nav className="flex flex-col gap-1 px-3 py-6">
<NavLink
className={() => {
return `link ${isChattingPage ? "active" : ""}`;
return `${linkClass} ${isChattingPage ? "bg-primary-400" : ""}`;
}}
to={chatNav}
>
<Tooltip tip={t("chat")}>
<ChatIcon />
</Tooltip>
{({ isActive }) => {
return <Tooltip tip={t("chat")}>
<ChatIcon className={isActive ? "fill-white" : ""} />
</Tooltip>;
}}
</NavLink>
<NavLink className="link" to={userNav}>
<Tooltip tip={t("members")}>
<UserIcon />
</Tooltip>
<NavLink className={({ isActive }) => `${linkClass} ${isActive ? 'bg-primary-400' : ""}`} to={userNav}>
{({ isActive }) => {
return <Tooltip tip={t("members")}>
<UserIcon className={isActive ? "fill-white" : ""} />
</Tooltip>;
}}
</NavLink>
<NavLink className="link" to={"/favs"}>
<Tooltip tip={t("favs")}>
<FavIcon />
</Tooltip>
<NavLink className={({ isActive }) => `${linkClass} ${isActive ? 'bg-primary-400' : ""}`} to={"/favs"}>
{({ isActive }) => {
return <Tooltip tip={t("favs")}>
<FavIcon className={isActive ? "fill-white" : ""} />
</Tooltip>;
}}
</NavLink>
<NavLink className="link" to={"/files"}>
<Tooltip tip={t("files")}>
<FolderIcon />
</Tooltip>
<NavLink className={({ isActive }) => `${linkClass} ${isActive ? 'bg-primary-400' : ""}`} to={"/files"}>
{({ isActive }) => {
return <Tooltip tip={t("files")}>
<FolderIcon className={isActive ? "fill-white" : ""} />
</Tooltip>;
}}
</NavLink>
</nav>
<Menu />
</div>
)}
<div className="col right">
<div className="h-full flex flex-col w-full">
<Outlet />
</div>
</StyledWrapper>
</div>
</>
);
}
-66
View File
@@ -1,66 +0,0 @@
import styled from "styled-components";
const StyledWrapper = styled.div`
display: flex;
width: 100vw;
height: 100vh;
background: var(---navs-bg);
&.guest {
background: none;
}
> .col {
height: 100%;
display: flex;
flex-direction: column;
&.left {
align-items: center;
position: relative;
background: transparent;
width: 64px;
transition: all 0.5s ease-in;
> .divider {
width: -webkit-fill-available;
height: 1px;
background-color: #d4d4d4;
margin: 8px 16px;
}
&.expand {
width: 140px;
}
}
&.right {
width: 100%;
}
.link_navs {
display: flex;
flex-direction: column;
gap: 4px;
padding: 24px 12px;
.link {
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
padding: 8px 12px;
font-weight: 600;
font-size: 14px;
line-height: 20px;
color: #4b5563;
border-radius: 8px;
&:hover {
background-color: rgba(0, 0, 0, 0.08);
}
&.active {
background-color: #55c7ec;
svg path {
fill: #fff;
}
}
}
}
}
&.guest > .col.right {
margin: 0 8px;
}
`;
export default StyledWrapper;
+1 -1
View File
@@ -37,7 +37,7 @@ export default function APIConfig() {
<div className="max-w-[500px] flex flex-col gap-4 items-start">
<Toggle
onClick={handleToggle.bind(null, { third_party: !thirdParty })}
data-checked={thirdParty}
checked={thirdParty}
/>
<div className="w-full flex flex-col items-start gap-2">
<label htmlFor="secret" className="text-sm text-gray-500 dark:text-gray-100"> {t("third_app.key")}:</label>
+1 -1
View File
@@ -41,7 +41,7 @@ const LogoutConfirmModal: FC<Props> = ({ closeModal }) => {
description={t("logout.desc")}
buttons={
<>
<Button onClick={closeModal}>{ct("action.cancel")}</Button>
<Button className="cancel" onClick={closeModal}>{ct("action.cancel")}</Button>
<Button onClick={handleLogout} className="danger">
{exiting ? "Logging out" : ct("action.logout")}
</Button>
+2 -2
View File
@@ -7,7 +7,7 @@ import useConfig from "../../../common/hook/useConfig";
import Server from './server';
import Language from './Language';
import FrontendURL from "./FrontendURL";
// import DarkMode from "./DarkMode";
import DarkMode from "./DarkMode";
import ServerVersionChecker from "../../../common/component/ServerVersionChecker";
export default function Overview() {
@@ -67,7 +67,7 @@ export default function Overview() {
</>
)}
<Language />
{/* <DarkMode /> */}
<DarkMode />
</div>
);
}
+1 -1
View File
@@ -66,7 +66,7 @@ const ProfileBasicEditModal: FC<Props> = ({
}
>
<form ref={formRef} className="flex flex-col gap-2 w-full" action="/">
<label htmlFor={valueKey} className="text-sm text-[#6b7280]">{label}</label>
<label htmlFor={valueKey} className="text-sm text-left text-gray-500">{label}</label>
<Input name={valueKey} value={input} onChange={handleChange} type={type} required></Input>
</form>
</StyledModal>
+3 -4
View File
@@ -1,4 +1,3 @@
import StyledContainer from "./StyledContainer";
import Input from "../../../common/component/styled/Input";
import Textarea from "../../../common/component/styled/Textarea";
import Label from "../../../common/component/styled/Label";
@@ -35,11 +34,11 @@ export default function ConfigAgora() {
} = values as AgoraConfig;
return (
<StyledContainer>
<div className="setting-container">
<div className="inputs">
<div className="input row">
<Label>Enable</Label>
<Toggle onClick={toggleEnable} data-checked={enabled}></Toggle>
<Toggle onClick={toggleEnable} checked={enabled}></Toggle>
</div>
<div className="input">
<Label htmlFor="url">Agora Url</Label>
@@ -111,6 +110,6 @@ export default function ConfigAgora() {
</div>
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
{/* <button onClick={handleUpdate} className="btn">update</button> */}
</StyledContainer>
</div>
);
}
+2 -3
View File
@@ -1,5 +1,4 @@
import { ChangeEvent } from "react";
import StyledContainer from "./StyledContainer";
import Input from "../../../common/component/styled/Input";
import Textarea from "../../../common/component/styled/Textarea";
import Label from "../../../common/component/styled/Label";
@@ -78,7 +77,7 @@ export default function ConfigFirebase() {
client_email,
} = values as FirebaseConfig;
return (
<StyledContainer>
<div className="setting-container">
<StyledRadio
options={Object.values(Options)}
values={Object.keys(Options)}
@@ -131,6 +130,6 @@ export default function ConfigFirebase() {
</fieldset>
}
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={handleReset} />}
</StyledContainer>
</div>
);
}
@@ -57,7 +57,7 @@ const IssuerList: FC<Props> = ({ issuers = [], onChange }) => {
</div>
<div className="w-14 flex justify-end">
<Toggle
data-checked={enable}
checked={enable}
onClick={() => {
onChange(
issuers.map((issuer) => ({
+7 -8
View File
@@ -1,6 +1,5 @@
import { ChangeEvent } from "react";
import toast from "react-hot-toast";
import StyledContainer from "./StyledContainer";
import Toggle from "../../../common/component/styled/Toggle";
import Label from "../../../common/component/styled/Label";
import Input from "../../../common/component/styled/Input";
@@ -71,7 +70,7 @@ export default function Logins() {
const valuesChanged = clientIdChanged || changed || githubChanged;
return (
<StyledContainer>
<div className="setting-container">
<div className="inputs">
<div className="input">
<div className="row">
@@ -83,7 +82,7 @@ export default function Logins() {
</div>
<Toggle
onClick={handleToggle.bind(null, { password: !password })}
data-checked={password}
checked={password}
></Toggle>
</div>
</div>
@@ -97,7 +96,7 @@ export default function Logins() {
</div>
<Toggle
onClick={handleToggle.bind(null, { magic_link: !magic_link })}
data-checked={magic_link}
checked={magic_link}
></Toggle>
</div>
</div>
@@ -112,7 +111,7 @@ export default function Logins() {
</div>
<Toggle
onClick={handleToggle.bind(null, { google: !google })}
data-checked={google}
checked={google}
></Toggle>
</div>
<div className="row">
@@ -135,7 +134,7 @@ export default function Logins() {
</div>
<Toggle
onClick={handleToggle.bind(null, { github: !github })}
data-checked={github}
checked={github}
></Toggle>
</div>
<div className="row inputs">
@@ -166,7 +165,7 @@ export default function Logins() {
</div>
<Toggle
onClick={handleToggle.bind(null, { metamask: !metamask })}
data-checked={metamask}
checked={metamask}
></Toggle>
</div>
</div>
@@ -194,6 +193,6 @@ export default function Logins() {
</div>
</div>
{valuesChanged && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
</StyledContainer>
</div>
);
}
+5 -6
View File
@@ -1,17 +1,16 @@
import { useState, useEffect, ChangeEvent } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { useSendTestEmailMutation } from "../../../app/services/server";
import iconQuestion from "../../../assets/icons/question.svg?url";
import useConfig from "../../../common/hook/useConfig";
import StyledContainer from "./StyledContainer";
import Input from "../../../common/component/styled/Input";
import Button from "../../../common/component/styled/Button";
import Toggle from "../../../common/component/styled/Toggle";
import Label from "../../../common/component/styled/Label";
import SaveTip from "../../../common/component/SaveTip";
import toast from "react-hot-toast";
import { SMTPConfig } from "../../../types/server";
import { useTranslation } from "react-i18next";
export default function ConfigSMTP() {
const { t } = useTranslation("setting", { keyPrefix: "smtp" });
@@ -54,11 +53,11 @@ export default function ConfigSMTP() {
if (!values) return null;
const { host, port, from, username, password, enabled = false } = values as SMTPConfig;
return (
<StyledContainer>
<div className="setting-container">
<div className="inputs">
<div className="input row">
<Label className="dark:text-gray-200">{t("enable")}</Label>
<Toggle onClick={toggleEnable} data-checked={enabled}></Toggle>
<Toggle onClick={toggleEnable} checked={enabled}></Toggle>
</div>
<div className="input">
<Label className="dark:text-gray-200" htmlFor="name">{t("host")}</Label>
@@ -144,6 +143,6 @@ export default function ConfigSMTP() {
</div>
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
{/* <button onClick={handleUpdate} className="btn">update</button> */}
</StyledContainer>
</div>
);
}
@@ -1,67 +0,0 @@
import styled from "styled-components";
const StyledContainer = styled.div`
position: relative;
width: 512px;
height: 100%;
display: flex;
flex-direction: column;
gap: 24px;
.inputs {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 32px;
.input {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
.row {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
&.inputs {
flex-direction: column;
gap: 8px;
}
.title {
display: flex;
flex-direction: column;
align-items: flex-start;
.txt {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
.icon {
cursor: pointer;
}
}
.desc {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
}
}
}
}
}
.tip {
display: flex;
gap: 8px;
align-items: center;
.link {
font-weight: 600;
font-size: 14px;
line-height: 20px;
color: #06b6d4;
}
}
`;
export default StyledContainer;
+8 -8
View File
@@ -6,7 +6,6 @@ import Search from "./Search";
import User from "../../common/component/User";
import Profile from "../../common/component/Profile";
import StyledWrapper from "./styled";
import BlankPlaceholder from "../../common/component/BlankPlaceholder";
import useFilteredUsers from "../../common/hook/useFilteredUsers";
@@ -24,15 +23,16 @@ function UsersPage() {
}, [pathname]);
if (!users) return null;
return (
<StyledWrapper>
<div className="left dark:!bg-[#1F2A37]">
<div className="flex h-full pt-2 pr-12 pb-2.5">
<div className="rounded-l-2xl bg-white dark:bg-[#1F2A37] relative flex flex-col min-w-[268px] shadow-[inset_-1px_0px_0px_rgba(0,_0,_0,_0.1)]">
<Search input={input} updateInput={updateInput} />
<div className="list">
<nav className="nav">
<div className="px-2 py-3 overflow-scroll pb-[50px]">
<nav className="flex flex-col gap-1">
{users.map(({ uid }) => {
return (
<NavLink key={uid} className="session" to={`/users/${uid}`}>
<NavLink key={uid} className={({ isActive }) => `rounded-md hover:bg-gray-500/10 ${isActive ? "bg-gray-500/10" : ""}`} to={`/users/${uid}`}>
<User uid={uid} enableContextMenu={true} />
</NavLink>
);
@@ -40,10 +40,10 @@ function UsersPage() {
</nav>
</div>
</div>
<div className={`right ${!user_id ? "placeholder" : ""} dark:!bg-[#384250]`}>
<div className={`rounded-r-2xl bg-white w-full flex justify-center items-start ${!user_id ? "h-full items-center" : ""} dark:bg-[#384250]`}>
{user_id ? <Profile uid={+user_id} /> : <BlankPlaceholder type="user" />}
</div>
</StyledWrapper>
</div>
);
}
export default memo(UsersPage);
-50
View File
@@ -1,50 +0,0 @@
import styled from "styled-components";
const StyledWrapper = styled.div`
display: flex;
height: 100%;
padding: 8px 48px 10px 0;
> .left {
border-radius: 16px 0 0 16px;
background-color: #fff;
position: relative;
display: flex;
flex-direction: column;
min-width: 268px;
box-shadow: inset -1px 0px 0px rgba(0, 0, 0, 0.1);
.list {
padding: 12px 8px;
overflow: scroll;
padding-bottom: 50px;
> .nav {
display: flex;
flex-direction: column;
gap: 4px;
a {
border-radius: 6px;
text-decoration: none;
}
.session {
&:hover,
&.active {
background: rgba(116, 127, 141, 0.1);
}
}
}
}
}
.right {
border-radius: 0 16px 16px 0;
background-color: #fff;
/* height: 100vh; */
width: 100%;
display: flex;
justify-content: center;
align-items: flex-start;
&.placeholder {
height: 100%;
align-items: center;
}
}
`;
export default StyledWrapper;