feat: update onboarding ui

This commit is contained in:
Liyang Zhu
2022-06-13 00:12:56 +08:00
parent 453a01bead
commit d1e599361b
11 changed files with 401 additions and 192 deletions
-26
View File
@@ -1,26 +0,0 @@
import styled from "styled-components";
import StyledButton from "../../../common/component/styled/Button";
import PlayIcon from "../../../assets/icons/play.svg?url";
const StyledFirstStep = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`;
export default function WelcomeStep({ setStep }) {
return (
<StyledFirstStep>
<span className="primaryText">Welcome to your Rustchat!</span>
<span className="secondaryText">
Everything in this space is owned by you. Lets set up your space!
</span>
<StyledButton className="startButton" onClick={() => setStep((prev) => prev + 1)}>
<img src={PlayIcon} alt="play icon" />
<span>Start</span>
</StyledButton>
</StyledFirstStep>
);
}
@@ -1,44 +0,0 @@
import styled from "styled-components";
import StyledButton from "../../../common/component/styled/Button";
import PlayIcon from "../../../assets/icons/play.svg?url";
const StyledLastStep = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .secondaryText {
margin-bottom: 48px;
}
> .tip {
width: 560px;
font-size: 20px;
line-height: 24px;
text-align: center;
margin-bottom: 96px;
> .strong {
font-weight: 700;
}
}
`;
export default function CompletedStep({ data, setStep }) {
return (
<StyledLastStep>
<span className="primaryText">Welcome to {data.serverName}</span>
<span className="secondaryText">Proudly presented by Rustchat</span>
<span className="tip">
More settings, including domain resolution, privileges, securities, and invites are
available in <span className="strong">Settings</span>
</span>
<StyledButton className="startButton" onClick={() => setStep((prev) => prev + 1)}>
<img src={PlayIcon} alt="play icon" />
<span>Enter</span>
</StyledButton>
</StyledLastStep>
);
}
@@ -12,23 +12,50 @@ import {
import { useLoginMutation } from "../../../app/services/auth";
import { updateInitialized } from "../../../app/slices/auth.data";
const StyledAdminCredentialsStep = styled.div`
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .input:not(:nth-last-child(2)) {
margin-bottom: 20px;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
text-align: center;
font-size: 14px;
line-height: 20px;
margin-bottom: 24px;
}
> .input {
width: 360px;
height: 44px;
font-weight: 400;
font-size: 16px;
line-height: 24px;
border: 1px solid #d0d5dd;
border-radius: 8px;
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
&:not(:nth-last-child(2)) {
margin-bottom: 20px;
}
}
> .button {
width: 360px;
margin-top: 24px;
}
`;
export default function AdminCredentialsStep({ data, setStep }) {
export default function AdminAccount({ serverName, nextStep }) {
const dispatch = useDispatch();
const [createAdmin, { isLoading: isSigningUp, error: signUpError }] = useCreateAdminMutation();
@@ -60,7 +87,7 @@ export default function AdminCredentialsStep({ data, setStep }) {
// Set server name
updateServer({
...serverData,
name: data.serverName
name: serverName
});
}, 0);
}
@@ -69,12 +96,12 @@ export default function AdminCredentialsStep({ data, setStep }) {
// After updated server
useEffect(() => {
if (isUpdatedServer) {
setStep((prev) => prev + 1);
nextStep();
}
}, [isUpdatedServer]);
return (
<StyledAdminCredentialsStep>
<StyledWrapper>
<span className="primaryText">Now lets set up your admin account</span>
<span className="secondaryText">You are the 1st user and admin of your space!</span>
<StyledInput
@@ -126,6 +153,6 @@ export default function AdminCredentialsStep({ data, setStep }) {
>
{!(isSigningUp || isLoggingIn || isUpdatingServer) ? "Sign Up" : "..."}
</StyledButton>
</StyledAdminCredentialsStep>
</StyledWrapper>
);
}
+77
View File
@@ -0,0 +1,77 @@
import styled from "styled-components";
import { useNavigate } from "react-router-dom";
import StyledButton from "../../../common/component/styled/Button";
import PlayIcon from "../../../assets/icons/play.svg?url";
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
text-align: center;
font-weight: 400;
font-size: 14px;
line-height: 20px;
margin-bottom: 48px;
}
> .tip {
width: 588px;
font-size: 20px;
line-height: 24px;
text-align: center;
margin-bottom: 48px;
> .strong {
font-weight: 700;
}
}
> .startButton {
width: 128px;
display: flex;
flex-direction: column;
align-items: center;
padding: 15px 0 12px;
> img {
margin-bottom: 7px;
}
> span {
font-weight: 500;
font-size: 14px;
line-height: 20px;
}
}
`;
export default function DonePage({ serverName }) {
const navigate = useNavigate();
return (
<StyledWrapper>
<span className="primaryText">Welcome to {serverName}</span>
<span className="secondaryText">Proudly presented by Rustchat</span>
<span className="tip">
More settings, including domain resolution, privileges, securities, and invites are
available in <span className="strong">Settings</span>
</span>
<StyledButton className="startButton" onClick={() => navigate("/")}>
<img src={PlayIcon} alt="play icon" />
<span>Enter</span>
</StyledButton>
</StyledWrapper>
);
}
@@ -3,14 +3,25 @@ import StyledInput from "../../../common/component/styled/Input";
import StyledButton from "../../../common/component/styled/Button";
import useInviteLink from "../../../common/hook/useInviteLink";
const StyledInviteLinkStep = styled.div`
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
text-align: center;
font-size: 14px;
line-height: 20px;
margin-bottom: 40px;
}
@@ -47,15 +58,26 @@ const StyledInviteLinkStep = styled.div`
font-size: 14px;
line-height: 20px;
color: #22ccee;
transition: color 150ms ease-in-out;
&:hover {
color: #088ab2;
}
}
}
> .button {
width: 124px;
height: 44px;
margin-top: 24px;
}
`;
export default function InviteLinkStep({ setStep }) {
export default function InviteLink({ nextStep }) {
const { link, linkCopied, copyLink } = useInviteLink();
return (
<StyledInviteLinkStep>
<StyledWrapper>
<span className="primaryText">Last step: invite others!</span>
<span className="secondaryText">Now lets invite others!</span>
<span className="tip">Send invitation link to your future community members:</span>
@@ -65,12 +87,9 @@ export default function InviteLinkStep({ setStep }) {
{linkCopied ? "Copied" : `Copy`}
</StyledButton>
</div>
<StyledButton
className="button border_less ghost"
onClick={() => setStep((prev) => prev + 1)}
>
Skip
<StyledButton className="button" onClick={nextStep}>
Done
</StyledButton>
</StyledInviteLinkStep>
</StyledWrapper>
);
}
@@ -3,25 +3,51 @@ import toast from "react-hot-toast";
import StyledInput from "../../../common/component/styled/Input";
import StyledButton from "../../../common/component/styled/Button";
const StyledSpaceNameStep = styled.div`
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
width: 360px;
text-align: center;
font-size: 14px;
line-height: 20px;
margin-bottom: 24px;
color: #667085;
}
> .input {
width: 360px;
height: 44px;
font-weight: 400;
font-size: 16px;
line-height: 24px;
padding: 10px 14px;
border: 1px solid #d0d5dd;
border-radius: 8px;
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
}
> .button {
width: 360px;
margin-top: 24px;
}
`;
export default function ServerNameStep({ setStep, data, setData }) {
export default function ServerName({ serverName, setServerName, nextStep }) {
return (
<StyledSpaceNameStep>
<StyledWrapper>
<span className="primaryText">Create a new server</span>
<span className="secondaryText">
Servers are shared environments where teams can work on projects and chat.
@@ -29,27 +55,22 @@ export default function ServerNameStep({ setStep, data, setData }) {
<StyledInput
className="input"
placeholder="Enter server name"
value={data.serverName}
onChange={(e) =>
setData({
...data,
serverName: e.target.value
})
}
value={serverName}
onChange={(e) => setServerName(e.target.value)}
/>
<StyledButton
className="button"
onClick={() => {
// Verification for space name
if (data.serverName === "") {
if (serverName === "") {
toast.error("Please enter server name!");
return;
}
setStep((prev) => prev + 1);
nextStep();
}}
>
Create Server
</StyledButton>
</StyledSpaceNameStep>
</StyledWrapper>
);
}
@@ -0,0 +1,59 @@
import styled from "styled-components";
import StyledButton from "../../../common/component/styled/Button";
import PlayIcon from "../../../assets/icons/play.svg?url";
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
text-align: center;
font-size: 14px;
line-height: 20px;
margin-bottom: 24px;
}
> .startButton {
width: 128px;
display: flex;
flex-direction: column;
align-items: center;
padding: 15px 0 12px;
> img {
margin-bottom: 7px;
}
> span {
font-weight: 500;
font-size: 14px;
line-height: 20px;
}
}
`;
export default function WelcomePage({ nextStep }) {
return (
<StyledWrapper>
<span className="primaryText">Welcome to your Rustchat!</span>
<span className="secondaryText">
Everything in this space is owned by you. Lets set up your space!
</span>
<StyledButton className="startButton" onClick={nextStep}>
<img src={PlayIcon} alt="play icon" />
<span>Start</span>
</StyledButton>
</StyledWrapper>
);
}
@@ -1,27 +1,55 @@
import { useState, useEffect } from "react";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import styled from "styled-components";
import StyledRadio from "../../../common/component/styled/Radio";
import StyledButton from "../../../common/component/styled/Button";
import { useGetLoginConfigQuery, useUpdateLoginConfigMutation } from "../../../app/services/server";
const StyledWhoCanSignUpStep = styled.div`
const StyledWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> .primaryText {
text-align: center;
font-weight: 700;
font-size: 24px;
line-height: 30px;
margin-bottom: 8px;
}
> .secondaryText {
text-align: center;
font-size: 14px;
line-height: 20px;
margin-bottom: 24px;
}
> form {
width: 512px;
}
> .button {
width: 124px;
height: 44px;
margin-top: 24px;
}
`;
export default function WhoCanInviteStep({ setStep }) {
export default function WhoCanSignUp({ nextStep }) {
const { data: loginConfig } = useGetLoginConfigQuery();
const [updateLoginConfig, { isSuccess, error }] = useUpdateLoginConfigMutation();
const [value, setValue] = useState("EveryOne");
const [value, setValue] = useState(undefined);
// Sync to `value` when `loginConfig` is fetched
useEffect(() => {
if (loginConfig) {
setValue(loginConfig.who_can_sign_up);
}
}, [loginConfig]);
// Display error
useEffect(() => {
@@ -31,33 +59,33 @@ export default function WhoCanInviteStep({ setStep }) {
// Increment `step` when updating has completed
useEffect(() => {
if (isSuccess) setStep((prev) => prev + 1);
if (isSuccess) nextStep();
}, [isSuccess]);
return (
<StyledWhoCanSignUpStep>
<StyledWrapper>
<span className="primaryText">Last step: invite others!</span>
<span className="secondaryText">Firstly, who can sign up to this server?</span>
<StyledRadio
options={["Everyone", "Invitation link only"]}
values={["EveryOne", "InvitationOnly"]}
value={value}
onChange={(v) => {
setValue(v);
onChange={setValue}
/>
<StyledButton
className="button"
disabled={!value}
onClick={() => {
if (loginConfig !== undefined) {
updateLoginConfig({
...loginConfig,
who_can_sign_up: v
who_can_sign_up: value
});
}
}}
/>
<StyledButton
className="button border_less ghost"
onClick={() => setStep((prev) => prev + 1)}
>
Skip
Confirm
</StyledButton>
</StyledWhoCanSignUpStep>
</StyledWrapper>
);
}