refactor: use local svg file

This commit is contained in:
zerosoul
2022-03-17 11:12:35 +08:00
parent 46cfda76d0
commit 4bc9932d0f
42 changed files with 469 additions and 386 deletions
+9 -1
View File
@@ -1,4 +1,5 @@
import styled from "styled-components";
import settingIcon from "../../assets/icons/setting.svg?url";
const StyledWrapper = styled.div`
display: flex;
height: 100%;
@@ -68,7 +69,8 @@ const StyledWrapper = styled.div`
display: flex;
width: 16px;
height: 16px;
background-image: url("https://static.nicegoodthings.com/project/rustchat/icon.setting.svg");
background-image: url(${settingIcon});
background-size: 16px;
}
> .badge {
color: #fff;
@@ -161,6 +163,12 @@ const StyledWrapper = styled.div`
font-weight: 900;
font-size: 10px;
line-height: 10px;
&.dot {
min-width: unset;
width: 6px;
height: 6px;
padding: 0;
}
&.mute {
background: #bfbfbf;
}
+5 -10
View File
@@ -1,6 +1,9 @@
// import React from 'react'
import { useDispatch } from "react-redux";
import { toggleSetting } from "../../app/slices/ui";
import settingIcon from "../../assets/icons/setting.svg?url";
import foldIcon from "../../assets/icons/fold.svg?url";
import unfoldIcon from "../../assets/icons/unfold.svg?url";
import styled from "styled-components";
const StyledMenus = styled.ul`
display: flex;
@@ -38,11 +41,7 @@ export default function Menu({ toggle, expand = true }) {
return (
<StyledMenus>
<li className="menu" onClick={handleSetting}>
<img
src="https://static.nicegoodthings.com/project/rustchat/menu.setting.png"
alt="setting icon"
className="icon"
/>
<img src={settingIcon} alt="setting icon" className="icon" />
{expand && (
<span className="txt animate__animated animate__fadeIn">
Settings
@@ -51,11 +50,7 @@ export default function Menu({ toggle, expand = true }) {
</li>
<li className="menu" onClick={toggle}>
<img
src={
expand
? "https://static.nicegoodthings.com/project/rustchat/menu.toggle.collapse.png"
: "https://static.nicegoodthings.com/project/rustchat/menu.toggle.expand.png"
}
src={expand ? foldIcon : unfoldIcon}
alt="expand icon"
className="icon"
/>
+3 -3
View File
@@ -12,8 +12,8 @@ import usePreload from "./usePreload";
import SettingModal from "../../common/component/Setting";
import ChannelSettingModal from "../../common/component/ChannelSetting";
import ChatIcon from "../../assets/icons/chat.svg";
import ContactIcon from "../../assets/icons/contact.svg";
import ChatIcon from "../../assets/icons/chat.svg?url";
import ContactIcon from "../../assets/icons/contact.svg?url";
// import NotificationHub from "../../common/component/NotificationHub";
export default function HomePage() {
@@ -29,7 +29,7 @@ export default function HomePage() {
const toggleExpand = () => {
dispatch(toggleMenuExpand());
};
console.log("index loading", loading, ready);
// console.log("index loading", loading, ready);
if (loading || !ready) {
return <Loading />;
}
+172 -163
View File
@@ -1,168 +1,177 @@
import { useState, useEffect } from 'react';
import StyledWrapper from './styled';
import { useNavigate } from 'react-router-dom';
import toast from 'react-hot-toast';
import { useRegisterMutation } from '../../app/services/contact';
import { useCheckInviteTokenValidMutation } from '../../app/services/auth';
import { useState, useEffect } from "react";
import StyledWrapper from "./styled";
import { useNavigate } from "react-router-dom";
import toast from "react-hot-toast";
import BASE_URL from "../../app/config";
import { useRegisterMutation } from "../../app/services/contact";
import { useCheckInviteTokenValidMutation } from "../../app/services/auth";
export default function InvitePage() {
const [secondPwd, setSecondPwd] = useState('');
const [samePwd, setSamePwd] = useState(true);
const [token, setToken] = useState('');
const [valid, setValid] = useState(false);
// const [sp] = useSearchParams();
const navigateTo = useNavigate();
const [register, { data, isLoading, isSuccess, isError, error }] = useRegisterMutation();
const [checkToken, { data: isValid, isLoading: checkLoading, isSuccess: checkSuccess }] =
useCheckInviteTokenValidMutation();
useEffect(() => {
// console.log(search);
const query = new URLSearchParams(location.search);
setToken(query.get('token'));
}, []);
useEffect(() => {
if (token) {
checkToken(token);
}
}, [token]);
useEffect(() => {
if (checkSuccess) {
console.log({ isValid });
setValid(isValid);
} else {
setValid(false);
}
}, [checkSuccess, isValid]);
const [input, setInput] = useState({
name: '',
email: '',
password: ''
});
const handleReg = (evt) => {
evt.preventDefault();
if (!samePwd) {
toast.error('two passwords not same');
return;
}
console.log('wtf', input);
register({
...input,
magic_token: token,
gender: 1
});
};
const handleInput = (evt) => {
const { type } = evt.target.dataset;
const { value } = evt.target;
console.log(type, value);
setInput((prev) => {
prev[type] = value;
return { ...prev };
});
};
const handleSecondPwdInput = (evt) => {
const { value } = evt.target;
setSecondPwd(value);
};
const handlePwdCheck = () => {
if (secondPwd) {
setSamePwd(secondPwd == input.password);
}
};
useEffect(() => {
if (!samePwd) {
toast.error('two passwords not same');
}
}, [samePwd]);
useEffect(() => {
if (isSuccess && data) {
// 去登录
toast.success('register success, login please');
setTimeout(() => {
navigateTo('/login');
}, 500);
} else if (isError) {
console.log('register failed', error);
switch (error.status) {
case 412:
toast.error('register failed: invalid token or expired');
break;
case 409: {
const tips = {
email_conflict: 'email conflict',
name_conflict: 'name conflict'
};
toast.error(`register failed: ${tips[error.data?.reason]}`);
break;
const [secondPwd, setSecondPwd] = useState("");
const [samePwd, setSamePwd] = useState(true);
const [token, setToken] = useState("");
const [valid, setValid] = useState(false);
// const [sp] = useSearchParams();
const navigateTo = useNavigate();
const [
register,
{ data, isLoading, isSuccess, isError, error },
] = useRegisterMutation();
const [
checkToken,
{ data: isValid, isLoading: checkLoading, isSuccess: checkSuccess },
] = useCheckInviteTokenValidMutation();
useEffect(() => {
// console.log(search);
const query = new URLSearchParams(location.search);
setToken(query.get("token"));
}, []);
useEffect(() => {
if (token) {
checkToken(token);
}
default:
toast.error('register failed');
break;
}
}
}, [data, isSuccess, isError, error]);
}, [token]);
useEffect(() => {
if (checkSuccess) {
console.log({ isValid });
setValid(isValid);
} else {
setValid(false);
}
}, [checkSuccess, isValid]);
const { email, password, name } = input;
if (!token) return 'token not found';
if (checkLoading) return 'checking token valid';
if (!valid) return 'invite token expires or invalid';
return (
<StyledWrapper>
<div className="form animate__animated animate__fadeInDown animate__faster">
<div className="tips">
<img
src="https://static.nicegoodthings.com/project/ext/webrowse.logo.png"
alt="logo"
className="logo"
/>
<h2 className="title">Sign Up to Rustchat</h2>
<span className="desc">Please enter your details.</span>
</div>
<form onSubmit={handleReg}>
<input
name="name"
value={name}
required
placeholder="Enter your name"
data-type="name"
onChange={handleInput}
/>
<input
name="email"
value={email}
required
placeholder="Enter your email"
data-type="email"
onChange={handleInput}
/>
<input
type="password"
value={password}
name="password"
required
data-type="password"
onChange={handleInput}
placeholder="Enter your password"
/>
<input
type="password"
value={secondPwd}
name="password"
required
data-type="password"
onBlur={handlePwdCheck}
onChange={handleSecondPwdInput}
placeholder="Enter your password again"
/>
<button disabled={isLoading || isSuccess} className="btn" type="submit">
Sign Up
</button>
</form>
</div>
</StyledWrapper>
);
const [input, setInput] = useState({
name: "",
email: "",
password: "",
});
const handleReg = (evt) => {
evt.preventDefault();
if (!samePwd) {
toast.error("two passwords not same");
return;
}
console.log("wtf", input);
register({
...input,
magic_token: token,
gender: 1,
});
};
const handleInput = (evt) => {
const { type } = evt.target.dataset;
const { value } = evt.target;
console.log(type, value);
setInput((prev) => {
prev[type] = value;
return { ...prev };
});
};
const handleSecondPwdInput = (evt) => {
const { value } = evt.target;
setSecondPwd(value);
};
const handlePwdCheck = () => {
if (secondPwd) {
setSamePwd(secondPwd == input.password);
}
};
useEffect(() => {
if (!samePwd) {
toast.error("two passwords not same");
}
}, [samePwd]);
useEffect(() => {
if (isSuccess && data) {
// 去登录
toast.success("register success, login please");
setTimeout(() => {
navigateTo("/login");
}, 500);
} else if (isError) {
console.log("register failed", error);
switch (error.status) {
case 412:
toast.error("register failed: invalid token or expired");
break;
case 409: {
const tips = {
email_conflict: "email conflict",
name_conflict: "name conflict",
};
toast.error(`register failed: ${tips[error.data?.reason]}`);
break;
}
default:
toast.error("register failed");
break;
}
}
}, [data, isSuccess, isError, error]);
const { email, password, name } = input;
if (!token) return "token not found";
if (checkLoading) return "checking token valid";
if (!valid) return "invite token expires or invalid";
return (
<StyledWrapper>
<div className="form animate__animated animate__fadeInDown animate__faster">
<div className="tips">
<img
src={`${BASE_URL}/resource/organization/logo`}
alt="logo"
className="logo"
/>
<h2 className="title">Sign Up to Rustchat</h2>
<span className="desc">Please enter your details.</span>
</div>
<form onSubmit={handleReg}>
<input
name="name"
value={name}
required
placeholder="Enter your name"
data-type="name"
onChange={handleInput}
/>
<input
name="email"
value={email}
required
placeholder="Enter your email"
data-type="email"
onChange={handleInput}
/>
<input
type="password"
value={password}
name="password"
required
data-type="password"
onChange={handleInput}
placeholder="Enter your password"
/>
<input
type="password"
value={secondPwd}
name="password"
required
data-type="password"
onBlur={handlePwdCheck}
onChange={handleSecondPwdInput}
placeholder="Enter your password again"
/>
<button
disabled={isLoading || isSuccess}
className="btn"
type="submit"
>
Sign Up
</button>
</form>
</div>
</StyledWrapper>
);
}
+31 -28
View File
@@ -1,31 +1,34 @@
// import { useState, useEffect } from "react";
import { useGoogleLogin } from 'react-google-login';
import { googleClientID } from '../../app/config';
import { useGoogleLogin } from "react-google-login";
import { googleClientID } from "../../app/config";
import googleSvg from "../../assets/icons/google.svg?url";
export default function GoogleLoginButton({ login }) {
const { signIn, loaded } = useGoogleLogin({
clientId: googleClientID,
onSuccess: ({ tokenId, ...rest }) => {
console.log('success', tokenId, rest);
login({
id_token: tokenId,
type: 'google'
});
},
onFailure: (wtf) => {
console.log('failure', wtf);
}
});
const handleGoogleLogin = () => {
signIn();
};
return (
<button disabled={!loaded} onClick={handleGoogleLogin} href="#" className="btn social">
<img
className="icon"
src="https://static.nicegoodthings.com/project/rustchat/google.icon.png"
alt="google icon"
/>
Sign in with Google
</button>
);
const { signIn, loaded } = useGoogleLogin({
clientId: googleClientID,
onSuccess: ({ tokenId, ...rest }) => {
console.log("success", tokenId, rest);
login({
id_token: tokenId,
type: "google",
});
},
onFailure: (wtf) => {
console.log("failure", wtf);
},
});
const handleGoogleLogin = () => {
signIn();
};
return (
<button
disabled={!loaded}
onClick={handleGoogleLogin}
href="#"
className="btn social"
>
<img className="icon" src={googleSvg} alt="google icon" />
Sign in with Google
</button>
);
}
+2 -5
View File
@@ -2,6 +2,7 @@
import { useState, useEffect, useRef } from "react";
import MetaMaskOnboarding from "@metamask/onboarding";
import { useLazyGetMetamaskNonceQuery } from "../../app/services/auth";
import metamaskSvg from "../../assets/icons/metamask.svg?url";
export default function MetamaskLoginButton({ login }) {
const [requesting, setRequesting] = useState(false);
const [getNonce] = useLazyGetMetamaskNonceQuery();
@@ -48,11 +49,7 @@ export default function MetamaskLoginButton({ login }) {
href="#"
className="btn social"
>
<img
className="icon"
src="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjMzIiB2aWV3Qm94PSIwIDAgMzUgMzMiIHdpZHRoPSIzNSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjI1Ij48cGF0aCBkPSJtMzIuOTU4MiAxLTEzLjEzNDEgOS43MTgzIDIuNDQyNC01LjcyNzMxeiIgZmlsbD0iI2UxNzcyNiIgc3Ryb2tlPSIjZTE3NzI2Ii8+PGcgZmlsbD0iI2UyNzYyNSIgc3Ryb2tlPSIjZTI3NjI1Ij48cGF0aCBkPSJtMi42NjI5NiAxIDEzLjAxNzE0IDkuODA5LTIuMzI1NC01LjgxODAyeiIvPjxwYXRoIGQ9Im0yOC4yMjk1IDIzLjUzMzUtMy40OTQ3IDUuMzM4NiA3LjQ4MjkgMi4wNjAzIDIuMTQzNi03LjI4MjN6Ii8+PHBhdGggZD0ibTEuMjcyODEgMjMuNjUwMSAyLjEzMDU1IDcuMjgyMyA3LjQ2OTk0LTIuMDYwMy0zLjQ4MTY2LTUuMzM4NnoiLz48cGF0aCBkPSJtMTAuNDcwNiAxNC41MTQ5LTIuMDc4NiAzLjEzNTggNy40MDUuMzM2OS0uMjQ2OS03Ljk2OXoiLz48cGF0aCBkPSJtMjUuMTUwNSAxNC41MTQ5LTUuMTU3NS00LjU4NzA0LS4xNjg4IDguMDU5NzQgNy40MDQ5LS4zMzY5eiIvPjxwYXRoIGQ9Im0xMC44NzMzIDI4Ljg3MjEgNC40ODE5LTIuMTYzOS0zLjg1ODMtMy4wMDYyeiIvPjxwYXRoIGQ9Im0yMC4yNjU5IDI2LjcwODIgNC40Njg5IDIuMTYzOS0uNjEwNS01LjE3MDF6Ii8+PC9nPjxwYXRoIGQ9Im0yNC43MzQ4IDI4Ljg3MjEtNC40NjktMi4xNjM5LjM2MzggMi45MDI1LS4wMzkgMS4yMzF6IiBmaWxsPSIjZDViZmIyIiBzdHJva2U9IiNkNWJmYjIiLz48cGF0aCBkPSJtMTAuODczMiAyOC44NzIxIDQuMTU3MiAxLjk2OTYtLjAyNi0xLjIzMS4zNTA4LTIuOTAyNXoiIGZpbGw9IiNkNWJmYjIiIHN0cm9rZT0iI2Q1YmZiMiIvPjxwYXRoIGQ9Im0xNS4xMDg0IDIxLjc4NDItMy43MTU1LTEuMDg4NCAyLjYyNDMtMS4yMDUxeiIgZmlsbD0iIzIzMzQ0NyIgc3Ryb2tlPSIjMjMzNDQ3Ii8+PHBhdGggZD0ibTIwLjUxMjYgMjEuNzg0MiAxLjA5MTMtMi4yOTM1IDIuNjM3MiAxLjIwNTF6IiBmaWxsPSIjMjMzNDQ3IiBzdHJva2U9IiMyMzM0NDciLz48cGF0aCBkPSJtMTAuODczMyAyOC44NzIxLjY0OTUtNS4zMzg2LTQuMTMxMTcuMTE2N3oiIGZpbGw9IiNjYzYyMjgiIHN0cm9rZT0iI2NjNjIyOCIvPjxwYXRoIGQ9Im0yNC4wOTgyIDIzLjUzMzUuNjM2NiA1LjMzODYgMy40OTQ2LTUuMjIxOXoiIGZpbGw9IiNjYzYyMjgiIHN0cm9rZT0iI2NjNjIyOCIvPjxwYXRoIGQ9Im0yNy4yMjkxIDE3LjY1MDctNy40MDUuMzM2OS42ODg1IDMuNzk2NiAxLjA5MTMtMi4yOTM1IDIuNjM3MiAxLjIwNTF6IiBmaWxsPSIjY2M2MjI4IiBzdHJva2U9IiNjYzYyMjgiLz48cGF0aCBkPSJtMTEuMzkyOSAyMC42OTU4IDIuNjI0Mi0xLjIwNTEgMS4wOTEzIDIuMjkzNS42ODg1LTMuNzk2Ni03LjQwNDk1LS4zMzY5eiIgZmlsbD0iI2NjNjIyOCIgc3Ryb2tlPSIjY2M2MjI4Ii8+PHBhdGggZD0ibTguMzkyIDE3LjY1MDcgMy4xMDQ5IDYuMDUxMy0uMTAzOS0zLjAwNjJ6IiBmaWxsPSIjZTI3NTI1IiBzdHJva2U9IiNlMjc1MjUiLz48cGF0aCBkPSJtMjQuMjQxMiAyMC42OTU4LS4xMTY5IDMuMDA2MiAzLjEwNDktNi4wNTEzeiIgZmlsbD0iI2UyNzUyNSIgc3Ryb2tlPSIjZTI3NTI1Ii8+PHBhdGggZD0ibTE1Ljc5NyAxNy45ODc2LS42ODg2IDMuNzk2Ny44NzA0IDQuNDgzMy4xOTQ5LTUuOTA4N3oiIGZpbGw9IiNlMjc1MjUiIHN0cm9rZT0iI2UyNzUyNSIvPjxwYXRoIGQ9Im0xOS44MjQyIDE3Ljk4NzYtLjM2MzggMi4zNTg0LjE4MTkgNS45MjE2Ljg3MDQtNC40ODMzeiIgZmlsbD0iI2UyNzUyNSIgc3Ryb2tlPSIjZTI3NTI1Ii8+PHBhdGggZD0ibTIwLjUxMjcgMjEuNzg0Mi0uODcwNCA0LjQ4MzQuNjIzNi40NDA2IDMuODU4NC0zLjAwNjIuMTE2OS0zLjAwNjJ6IiBmaWxsPSIjZjU4NDFmIiBzdHJva2U9IiNmNTg0MWYiLz48cGF0aCBkPSJtMTEuMzkyOSAyMC42OTU4LjEwNCAzLjAwNjIgMy44NTgzIDMuMDA2Mi42MjM2LS40NDA2LS44NzA0LTQuNDgzNHoiIGZpbGw9IiNmNTg0MWYiIHN0cm9rZT0iI2Y1ODQxZiIvPjxwYXRoIGQ9Im0yMC41OTA2IDMwLjg0MTcuMDM5LTEuMjMxLS4zMzc4LS4yODUxaC00Ljk2MjZsLS4zMjQ4LjI4NTEuMDI2IDEuMjMxLTQuMTU3Mi0xLjk2OTYgMS40NTUxIDEuMTkyMSAyLjk0ODkgMi4wMzQ0aDUuMDUzNmwyLjk2Mi0yLjAzNDQgMS40NDItMS4xOTIxeiIgZmlsbD0iI2MwYWM5ZCIgc3Ryb2tlPSIjYzBhYzlkIi8+PHBhdGggZD0ibTIwLjI2NTkgMjYuNzA4Mi0uNjIzNi0uNDQwNmgtMy42NjM1bC0uNjIzNi40NDA2LS4zNTA4IDIuOTAyNS4zMjQ4LS4yODUxaDQuOTYyNmwuMzM3OC4yODUxeiIgZmlsbD0iIzE2MTYxNiIgc3Ryb2tlPSIjMTYxNjE2Ii8+PHBhdGggZD0ibTMzLjUxNjggMTEuMzUzMiAxLjEwNDMtNS4zNjQ0Ny0xLjY2MjktNC45ODg3My0xMi42OTIzIDkuMzk0NCA0Ljg4NDYgNC4xMjA1IDYuODk4MyAyLjAwODUgMS41Mi0xLjc3NTItLjY2MjYtLjQ3OTUgMS4wNTIzLS45NTg4LS44MDU0LS42MjIgMS4wNTIzLS44MDM0eiIgZmlsbD0iIzc2M2UxYSIgc3Ryb2tlPSIjNzYzZTFhIi8+PHBhdGggZD0ibTEgNS45ODg3MyAxLjExNzI0IDUuMzY0NDctLjcxNDUxLjUzMTMgMS4wNjUyNy44MDM0LS44MDU0NS42MjIgMS4wNTIyOC45NTg4LS42NjI1NS40Nzk1IDEuNTE5OTcgMS43NzUyIDYuODk4MzUtMi4wMDg1IDQuODg0Ni00LjEyMDUtMTIuNjkyMzMtOS4zOTQ0eiIgZmlsbD0iIzc2M2UxYSIgc3Ryb2tlPSIjNzYzZTFhIi8+PHBhdGggZD0ibTMyLjA0ODkgMTYuNTIzNC02Ljg5ODMtMi4wMDg1IDIuMDc4NiAzLjEzNTgtMy4xMDQ5IDYuMDUxMyA0LjEwNTItLjA1MTloNi4xMzE4eiIgZmlsbD0iI2Y1ODQxZiIgc3Ryb2tlPSIjZjU4NDFmIi8+PHBhdGggZD0ibTEwLjQ3MDUgMTQuNTE0OS02Ljg5ODI4IDIuMDA4NS0yLjI5OTQ0IDcuMTI2N2g2LjExODgzbDQuMTA1MTkuMDUxOS0zLjEwNDg3LTYuMDUxM3oiIGZpbGw9IiNmNTg0MWYiIHN0cm9rZT0iI2Y1ODQxZiIvPjxwYXRoIGQ9Im0xOS44MjQxIDE3Ljk4NzYuNDQxNy03LjU5MzIgMi4wMDA3LTUuNDAzNGgtOC45MTE5bDIuMDAwNiA1LjQwMzQuNDQxNyA3LjU5MzIuMTY4OSAyLjM4NDIuMDEzIDUuODk1OGgzLjY2MzVsLjAxMy01Ljg5NTh6IiBmaWxsPSIjZjU4NDFmIiBzdHJva2U9IiNmNTg0MWYiLz48L2c+PC9zdmc+"
alt="meta mask icon"
/>
<img className="icon" src={metamaskSvg} alt="meta mask icon" />
Sign in with MetaMask
</button>
);
+2 -5
View File
@@ -1,6 +1,7 @@
/* eslint-disable no-undef */
import { useEffect } from "react";
import { useGetOpenidMutation } from "../../app/services/auth";
import solidSvg from "../../assets/icons/solid.svg?url";
export default function SolidLoginButton() {
const [getOpenId, { data, isLoading, isSuccess }] = useGetOpenidMutation();
@@ -26,11 +27,7 @@ export default function SolidLoginButton() {
href="#"
className="btn social"
>
<img
className="icon"
src="https://solidproject.org/assets/img/solid-emblem.svg"
alt="solid logo icon"
/>
<img src={solidSvg} className="icon" alt="solid icon" />
{isLoading ? `Redirecting...` : `Sign in with Solid`}
</button>
);
+3 -3
View File
@@ -1,11 +1,11 @@
/* eslint-disable no-undef */
import { useState, useEffect } from "react";
import StyledWrapper from "./styled";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import toast from "react-hot-toast";
import BASE_URL from "../../app/config";
// import web3 from "web3";
import StyledWrapper from "./styled";
import MetamaskLoginButton from "./MetamaskLoginButton";
import SolidLoginButton from "./SolidLoginButton";
@@ -88,7 +88,7 @@ export default function LoginPage() {
<div className="form">
<div className="tips">
<img
src="https://static.nicegoodthings.com/project/ext/webrowse.logo.png"
src={`${BASE_URL}/resource/organization/logo`}
alt="logo"
className="logo"
/>
+99 -97
View File
@@ -1,103 +1,105 @@
import styled from 'styled-components';
import styled from "styled-components";
const StyledWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
.form {
padding: 36px 40px 32px 40px;
/* border: 1px solid #eee; */
box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06);
border-radius: 12px;
.tips {
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 24px;
.logo {
width: 56px;
height: 56px;
margin-bottom: 28px;
}
.title {
font-weight: 600;
font-size: 24px;
line-height: 32px;
color: #101828;
margin-bottom: 8px;
}
}
.desc {
font-weight: normal;
font-size: 16px;
line-height: 24px;
color: #667085;
}
form {
display: flex;
flex-direction: column;
gap: 20px;
input {
width: 360px;
background: #ffffff;
border: 1px solid #d0d5dd;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 8px;
padding: 10px 14px;
font-weight: normal;
font-size: 16px;
line-height: 24px;
color: #667085;
}
}
.or {
border: none;
position: relative;
height: 1px;
background-color: #e4e7ec;
margin: 26px 0;
&:after {
padding: 4px;
background-color: #fff;
content: 'OR';
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
font-size: 14px;
line-height: 20px;
color: #667085;
}
}
.btn {
display: inline-block;
text-align: center;
width: 100%;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #ffffff;
padding: 10px;
background: #1fe1f9;
border: 1px solid #1fe1f9;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 8px;
&.social {
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
color: #344054;
border-color: #d0d5dd;
background: none;
.icon {
width: 24px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
.form {
padding: 36px 40px 32px 40px;
/* border: 1px solid #eee; */
box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1),
0px 2px 4px -2px rgba(16, 24, 40, 0.06);
border-radius: 12px;
.tips {
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 24px;
.logo {
width: 56px;
height: 56px;
margin-bottom: 28px;
border-radius: 50%;
}
.title {
font-weight: 600;
font-size: 24px;
line-height: 32px;
color: #101828;
margin-bottom: 8px;
}
}
.desc {
font-weight: normal;
font-size: 16px;
line-height: 24px;
color: #667085;
}
form {
display: flex;
flex-direction: column;
gap: 20px;
input {
width: 360px;
background: #ffffff;
border: 1px solid #d0d5dd;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 8px;
padding: 10px 14px;
font-weight: normal;
font-size: 16px;
line-height: 24px;
color: #667085;
}
}
.or {
border: none;
position: relative;
height: 1px;
background-color: #e4e7ec;
margin: 26px 0;
&:after {
padding: 4px;
background-color: #fff;
content: "OR";
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
font-size: 14px;
line-height: 20px;
color: #667085;
}
}
.btn {
display: inline-block;
text-align: center;
width: 100%;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #ffffff;
padding: 10px;
background: #1fe1f9;
border: 1px solid #1fe1f9;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 8px;
&.social {
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
color: #344054;
border-color: #d0d5dd;
background: none;
.icon {
width: 24px;
height: 24px;
}
}
}
}
}
}
`;
export default StyledWrapper;