refactor: restyle some components with tailwind

This commit is contained in:
Tristan Yang
2022-11-14 23:52:00 +08:00
parent 126cbc39a2
commit 734c6ce75b
13 changed files with 64 additions and 225 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "vocechat-web", "name": "vocechat-web",
"version": "0.3.15", "version": "0.3.17",
"private": true, "private": true,
"homepage": "https://voce.chat", "homepage": "https://voce.chat",
"dependencies": { "dependencies": {
+1 -1
View File
@@ -65,7 +65,7 @@ export const KEY_TOKEN = "VOCECHAT_TOKEN";
export const KEY_EXPIRE = "VOCECHAT_TOKEN_EXPIRE"; export const KEY_EXPIRE = "VOCECHAT_TOKEN_EXPIRE";
export const KEY_REFRESH_TOKEN = "VOCECHAT_REFRESH_TOKEN"; export const KEY_REFRESH_TOKEN = "VOCECHAT_REFRESH_TOKEN";
export const KEY_UID = "VOCECHAT_CURR_UID"; export const KEY_UID = "VOCECHAT_CURR_UID";
export const KEY_DEVICE_KEY = "VOCECHAT_DEVICE_KEY"; export const KEY_DEVICE_ID = "VOCECHAT_DEVICE_KEY";
export const KEY_USERS_VERSION = "VOCECHAT_USERS_VERSION"; export const KEY_USERS_VERSION = "VOCECHAT_USERS_VERSION";
export const KEY_AFTER_MID = "VOCECHAT_AFTER_MID"; export const KEY_AFTER_MID = "VOCECHAT_AFTER_MID";
export const KEY_PWA_INSTALLED = "VOCECHAT_PWA_INSTALLED"; export const KEY_PWA_INSTALLED = "VOCECHAT_PWA_INSTALLED";
+3 -3
View File
@@ -2,7 +2,7 @@ import { createApi } from "@reduxjs/toolkit/query/react";
import { nanoid } from "@reduxjs/toolkit"; import { nanoid } from "@reduxjs/toolkit";
import baseQuery from "./base.query"; import baseQuery from "./base.query";
import { setAuthData, updateToken, resetAuthData, updateInitialized } from "../slices/auth.data"; import { setAuthData, updateToken, resetAuthData, updateInitialized } from "../slices/auth.data";
import BASE_URL, { KEY_DEVICE_KEY, KEY_LOCAL_MAGIC_TOKEN } from "../config"; import BASE_URL, { KEY_DEVICE_ID, KEY_LOCAL_MAGIC_TOKEN } from "../config";
import { import {
AuthData, AuthData,
CredentialResponse, CredentialResponse,
@@ -12,10 +12,10 @@ import {
} from "../../types/auth"; } from "../../types/auth";
const getDeviceId = () => { const getDeviceId = () => {
let d = localStorage.getItem(KEY_DEVICE_KEY); let d = localStorage.getItem(KEY_DEVICE_ID);
if (!d) { if (!d) {
d = `web:${nanoid()}`; d = `web:${nanoid()}`;
localStorage.setItem(KEY_DEVICE_KEY, d); localStorage.setItem(KEY_DEVICE_ID, d);
} }
return d; return d;
}; };
+24 -78
View File
@@ -1,5 +1,4 @@
import { FC, useState } from "react"; import { FC, useState } from "react";
import styled from "styled-components";
import ChannelModal from "./ChannelModal"; import ChannelModal from "./ChannelModal";
import InviteModal from "./InviteModal"; import InviteModal from "./InviteModal";
import IconChat from "../../assets/icons/placeholder.chat.svg"; import IconChat from "../../assets/icons/placeholder.chat.svg";
@@ -10,67 +9,15 @@ import UsersModal from "./UsersModal";
import usePWAInstallPrompt from "../hook/usePWAInstallPrompt"; import usePWAInstallPrompt from "../hook/usePWAInstallPrompt";
import { useAppSelector } from "../../app/store"; import { useAppSelector } from "../../app/store";
const Styled = styled.div`
margin-top: -50px;
display: flex;
flex-direction: column;
gap: 32px;
.head {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
.title {
font-weight: 700;
font-size: 30px;
line-height: 38px;
color: #344054;
}
.desc {
text-align: center;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #98a2b3;
max-width: 424px;
}
}
.boxes {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 24px;
.box {
cursor: pointer;
width: 200px;
height: 200px;
background: #f9fafb;
border-radius: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
.icon {
width: 40px;
height: 40px;
}
.txt {
padding: 0 21px;
text-align: center;
font-weight: 700;
font-size: 14px;
line-height: 20px;
color: #475467;
}
}
}
`;
interface Props { interface Props {
type?: "chat" | "user"; type?: "chat" | "user";
} }
const classes = {
box: "w-[200px] h-[200px] cursor-pointer bg-[#f9fafb] rounded-3xl flex flex-col justify-center items-center gap-4",
boxIcon: "w-10 h-10",
boxTip: "px-5 text-sm text-[#475467] font-bold text-center"
};
const BlankPlaceholder: FC<Props> = ({ type = "chat" }) => { const BlankPlaceholder: FC<Props> = ({ type = "chat" }) => {
const { showPrompt } = usePWAInstallPrompt(); const { showPrompt } = usePWAInstallPrompt();
const server = useAppSelector((store) => store.server); const server = useAppSelector((store) => store.server);
@@ -89,36 +36,35 @@ const BlankPlaceholder: FC<Props> = ({ type = "chat" }) => {
const chatTip = const chatTip =
type == "chat" ? "Create a Channel to Start a Conversation" : "Send a Direct Message"; type == "chat" ? "Create a Channel to Start a Conversation" : "Send a Direct Message";
const chatHandler = type == "chat" ? toggleChannelModalVisible : toggleUserListVisible; const chatHandler = type == "chat" ? toggleChannelModalVisible : toggleUserListVisible;
return ( return (
<> <>
<Styled> <div className="flex flex-col gap-8 -mt-[50px]">
<div className="head"> <div className="flex flex-col gap-2 items-center">
<h2 className="title">Welcome to {server.name} server</h2> <h2 className="text-3xl text-[#344054] font-bold">Welcome to {server.name} server</h2>
<p className="desc"> <p className="text-sm text-[#98a2b3] max-w-[424px] text-center">
Here are some steps to help you get started. For more, check out our Getting Started Here are some steps to help you get started. For more, check out our Getting Started
guide guide
</p> </p>
</div> </div>
<div className="boxes"> <div className="grid grid-cols-2 grid-rows-2 gap-6">
<div className="box" onClick={toggleInviteModalVisible}> <div className={classes.box} onClick={toggleInviteModalVisible}>
<IconInvite className="icon" /> <IconInvite className={classes.boxIcon} />
<div className="txt">Invite your friends or teammates</div> <div className={classes.boxTip}>Invite your friends or teammates</div>
</div> </div>
<div className="box" onClick={chatHandler}> <button onClick={chatHandler} className={classes.box} >
<IconChat className="icon" /> <IconChat className={classes.boxIcon} />
<div className="txt">{chatTip}</div> <div className={classes.boxTip}>{chatTip}</div>
</div>
<button className="box" onClick={showPrompt}>
<IconDownload className="icon" />
<div className="txt">Download PC and Mobile apps</div>
</button> </button>
<a href={"https://voce.chat"} target={"_blank"} rel="noreferrer" className="box"> <button onClick={showPrompt} className={classes.box} >
<IconAsk className="icon" /> <IconDownload className={classes.boxIcon} />
<div className="txt">Got questions? Visit our help center </div> <div className={classes.boxTip}>Download PC and Mobile apps</div>
</button>
<a href={"https://voce.chat"} target={"_blank"} rel="noreferrer" className={classes.box} >
<IconAsk className={classes.boxIcon} />
<div className={classes.boxTip}>Got questions? Visit our help center</div>
</a> </a>
</div> </div>
</Styled> </div>
{createChannelVisible && ( {createChannelVisible && (
<ChannelModal personal={true} closeModal={toggleChannelModalVisible} /> <ChannelModal personal={true} closeModal={toggleChannelModalVisible} />
)} )}
+2 -9
View File
@@ -1,21 +1,14 @@
import { FC } from "react"; import { FC } from "react";
import styled from "styled-components";
import { useGetServerVersionQuery } from "../../app/services/server"; import { useGetServerVersionQuery } from "../../app/services/server";
const Styled = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
`;
type Props = {}; type Props = {};
const FAQ: FC<Props> = () => { const FAQ: FC<Props> = () => {
const { data: serverVersion } = useGetServerVersionQuery(); const { data: serverVersion } = useGetServerVersionQuery();
return ( return (
<Styled> <div className="flex flex-col gap-3">
<div className="item">Client Version: {process.env.VERSION}</div> <div className="item">Client Version: {process.env.VERSION}</div>
<div className="item">Server Version: {serverVersion}</div> <div className="item">Server Version: {serverVersion}</div>
<div className="item">Build Timestamp: {process.env.REACT_APP_BUILD_TIME}</div> <div className="item">Build Timestamp: {process.env.REACT_APP_BUILD_TIME}</div>
</Styled> </div>
); );
}; };
export default FAQ; export default FAQ;
+6 -2
View File
@@ -49,8 +49,12 @@ const GithubLoginButton: FC<Props> = ({ type = "login", source = "webapp", clien
}, [source]); }, [source]);
const handleGithubLogin = () => { const handleGithubLogin = () => {
window.open(`https://github.com/login/oauth/authorize?client_id=${client_id}&redirect_uri=${location.origin}/github/cb/${source}.html`); const redirectUrl = `https://github.com/login/oauth/authorize?client_id=${client_id}&redirect_uri=${location.origin}/github/cb/${source}.html`;
// location.href = `https://github.com/login/oauth/authorize?client_id=${client_id}`; if (source == "webapp") {
location.href = redirectUrl;
} else {
window.open(redirectUrl);
}
}; };
return ( return (
+4 -19
View File
@@ -1,22 +1,7 @@
import { FC } from "react"; import { FC } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import styled from "styled-components";
import Button from "./styled/Button"; import Button from "./styled/Button";
const Styled = styled.span`
display: flex;
align-items: center;
gap: 8px;
strong {
white-space: nowrap;
font-weight: bold;
}
.btns {
gap: 5px;
display: flex;
}
`;
interface Props { interface Props {
id: string; id: string;
handleUpdate: () => void; handleUpdate: () => void;
@@ -24,9 +9,9 @@ interface Props {
const Index: FC<Props> = ({ id, handleUpdate }) => { const Index: FC<Props> = ({ id, handleUpdate }) => {
return ( return (
<Styled> <div className="flex items-center gap-2">
<strong>New Version</strong> Available <strong className="whitespace-nowrap font-bold">New Version</strong> Available
<div className="btns"> <div className="flex gap-1">
<Button className="mini main" onClick={handleUpdate}> <Button className="mini main" onClick={handleUpdate}>
Update Update
</Button> </Button>
@@ -34,7 +19,7 @@ const Index: FC<Props> = ({ id, handleUpdate }) => {
Dismiss Dismiss
</Button> </Button>
</div> </div>
</Styled> </div>
); );
}; };
+3 -3
View File
@@ -48,9 +48,9 @@ const Profile: FC<Props> = ({ uid, type = "embed", cid }) => {
return ( return (
<StyledWrapper className={type}> <StyledWrapper className={type}>
<Avatar className="avatar" url={avatar} name={name} /> <Avatar className="rounded-full w-20 h-20 object-cover" url={avatar} name={name} />
<h2 className="name">{name}</h2> <h2 className="text-lg select-text font-bold text-[#1c1c1e]">{name}</h2>
<span className="email">{email}</span> <span className="text-sm text-[#98a2b3] select-text">{email}</span>
{/* <p className="intro">{introduction}</p> */} {/* <p className="intro">{introduction}</p> */}
<ul className="icons"> <ul className="icons">
<NavLink to={`/chat/dm/${uid}`}> <NavLink to={`/chat/dm/${uid}`}>
-33
View File
@@ -9,33 +9,6 @@ const StyledWrapper = styled.div`
margin-top: 80px; margin-top: 80px;
width: 432px; width: 432px;
gap: 4px; gap: 4px;
.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.name {
user-select: text;
font-weight: bold;
font-size: 18px;
line-height: 100%;
color: #1c1c1e;
}
.email {
user-select: text;
font-weight: normal;
font-size: 14px;
line-height: 20px;
color: #98a2b3;
}
.intro {
color: #344054;
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 20px;
}
.icons { .icons {
margin-top: 24px; margin-top: 24px;
display: flex; display: flex;
@@ -76,12 +49,6 @@ const StyledWrapper = styled.div`
} }
} }
} }
.line {
width: 100%;
height: 1px;
border: none;
background-color: rgba(0, 0, 0, 0.1);
}
&.card { &.card {
padding: 16px; padding: 16px;
width: 280px; width: 280px;
+7 -16
View File
@@ -1,22 +1,9 @@
import { useEffect, FC } from 'react'; import { useEffect, FC } from 'react';
import styled from 'styled-components';
import { KEY_LOCAL_MAGIC_TOKEN } from "../../app/config"; import { KEY_LOCAL_MAGIC_TOKEN } from "../../app/config";
import { useLoginMutation } from "../../app/services/auth"; import { useLoginMutation } from "../../app/services/auth";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
const Styled = styled.section`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;
.success{
font-size: 30px;
font-weight: bold;
color: green;
}
`;
export type GithubLoginSource = "widget" | "webapp" export type GithubLoginSource = "widget" | "webapp"
type Props = { type Props = {
code: string, from?: GithubLoginSource code: string, from?: GithubLoginSource
@@ -41,6 +28,10 @@ const GithubCallback: FC<Props> = ({ code, from = "webapp" }) => {
if (from == 'widget') { if (from == 'widget') {
localStorage.setItem("widget", `${new Date().getTime()}`); localStorage.setItem("widget", `${new Date().getTime()}`);
} }
// webapp 跳回首页
if (from == 'webapp') {
location.href = "/";
}
} }
}, [isSuccess, from]); }, [isSuccess, from]);
useEffect(() => { useEffect(() => {
@@ -60,10 +51,10 @@ const GithubCallback: FC<Props> = ({ code, from = "webapp" }) => {
} }
}, [error]); }, [error]);
if (error) return <span>Something Error</span>; if (error) return <span>Something Error</span>;
return <Styled> return <section className='flex flex-col gap-3 justify-center items-center'>
{isSuccess && from == 'widget' && <h1>Please close this window and return widget window</h1>} {isSuccess && from == 'widget' && <h1>Please close this window and return widget window</h1>}
<span className='success'>{isLoading ? "Github Logging in..." : "Github Login Success!"}</span> <span className='text-3xl text-green-600 font-bold'>{isLoading ? "Github Logging in..." : "Github Login Success!"}</span>
</Styled>; </section>;
}; };
export default GithubCallback; export default GithubCallback;
+3 -24
View File
@@ -1,26 +1,5 @@
import styled from "styled-components";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
const StyledSignUpLink = styled.p`
text-align: center;
margin: 24px 0 8px;
> span {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
margin-right: 4px;
}
> a {
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #22d3ee;
cursor: pointer;
}
`;
export default function MagicLinkLogin() { export default function MagicLinkLogin() {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -29,9 +8,9 @@ export default function MagicLinkLogin() {
}; };
return ( return (
<StyledSignUpLink> <div className="flex gap-1 mt-7 text-sm text-[#667085] justify-center">
<span>Dont have an account?</span> <span>Dont have an account?</span>
<a onClick={handleSignUp}>Sign up</a> <a className="text-[#22d3ee]" onClick={handleSignUp}>Sign up</a>
</StyledSignUpLink> </div>
); );
} }
+2
View File
@@ -148,10 +148,12 @@ export default function Reg() {
</Button> </Button>
</form> </form>
<hr className="or" /> <hr className="or" />
<div className="flex flex-col gap-3">
{googleLogin && <GoogleLoginButton type="register" clientId={clientId} />} {googleLogin && <GoogleLoginButton type="register" clientId={clientId} />}
{enableGithubLogin && ( {enableGithubLogin && (
<GithubLoginButton type="register" client_id={githubAuthConfig?.client_id} /> <GithubLoginButton type="register" client_id={githubAuthConfig?.client_id} />
)} )}
</div>
<SignInLink token={magicToken} /> <SignInLink token={magicToken} />
</> </>
); );
+3 -31
View File
@@ -1,30 +1,4 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import styled from "styled-components";
const StyledSignInLink = styled.ul`
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 30px;
>.item{
text-align: center;
margin: 0;
> span {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
margin-right: 4px;
}
> a {
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #22d3ee;
cursor: pointer;
}
}
`;
export default function SignInLink({ token }: { token?: string }) { export default function SignInLink({ token }: { token?: string }) {
const handleSignIn = () => { const handleSignIn = () => {
@@ -39,11 +13,9 @@ export default function SignInLink({ token }: { token?: string }) {
}, [token]); }, [token]);
return ( return (
<StyledSignInLink> <div className="flex gap-1 mt-7 text-sm text-[#667085] justify-center">
<li className="item">
<span>Have an account?</span> <span>Have an account?</span>
<a onClick={handleSignIn}>Sign In</a> <a onClick={handleSignIn} className="text-[#22d3ee]">Sign In</a>
</li> </div>
</StyledSignInLink>
); );
} }