feat: update onboarding ui
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import { Navigate } from "react-router-dom";
|
||||||
import StyledButton from "../../common/component/styled/Button";
|
import WelcomeStep from "./steps/1-welcome";
|
||||||
import FirstStep from "./steps/first";
|
import SpaceNameStep from "./steps/2-spaceName";
|
||||||
import SpaceNameStep from "./steps/spaceName";
|
import AdminCredentialsStep from "./steps/3-adminCredentials";
|
||||||
import AdminCredentialsStep from "./steps/adminCredentials";
|
import InviteRuleStep from "./steps/4-inviteRule";
|
||||||
import InviteRuleStep from "./steps/inviteRule";
|
import InviteLinkStep from "./steps/5-inviteLink";
|
||||||
import InviteLinkStep from "./steps/inviteLink";
|
import CompletedStep from "./steps/6-completed";
|
||||||
import LastStep from "./steps/last";
|
|
||||||
import StyledOnboardingPage from "./styled";
|
import StyledOnboardingPage from "./styled";
|
||||||
|
|
||||||
export default function OnboardingPage() {
|
export default function OnboardingPage() {
|
||||||
@@ -18,70 +17,19 @@ export default function OnboardingPage() {
|
|||||||
adminPassword2: "",
|
adminPassword2: "",
|
||||||
inviteRule: null
|
inviteRule: null
|
||||||
});
|
});
|
||||||
|
const props = { step, setStep, data, setData };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledOnboardingPage>
|
<StyledOnboardingPage>
|
||||||
<div className="horizontalBox">
|
<div className="horizontalBox">
|
||||||
<div className="verticalBox">
|
<div className="verticalBox">
|
||||||
{step > 0 && step < 5 && (
|
{step === 0 && <WelcomeStep {...props} />}
|
||||||
<>
|
{step === 1 && <SpaceNameStep {...props} />}
|
||||||
<StyledButton className="buttonBack ghost border_less" onClick={() => setStep(step - 1)}>
|
{step === 2 && <AdminCredentialsStep {...props} />}
|
||||||
Back
|
{step === 3 && <InviteRuleStep {...props} />}
|
||||||
</StyledButton>
|
{step === 4 && <InviteLinkStep {...props} />}
|
||||||
<StyledButton
|
{step === 5 && <CompletedStep {...props} />}
|
||||||
className="buttonNext"
|
{step === 6 && <Navigate replace to="/" />}
|
||||||
onClick={() => {
|
|
||||||
if (step === 1) {
|
|
||||||
// Verification for space name
|
|
||||||
if (data.spaceName === "") {
|
|
||||||
toast.error("Please enter space name!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStep(step + 1);
|
|
||||||
} else if (step === 2) {
|
|
||||||
// Verification for admin credentials
|
|
||||||
if (data.adminEmail === "") {
|
|
||||||
toast.error("Please enter admin email!");
|
|
||||||
return;
|
|
||||||
} else if (data.adminPassword === "") {
|
|
||||||
toast.error("Please enter admin password!");
|
|
||||||
return;
|
|
||||||
} else if (data.adminPassword !== data.adminPassword2) {
|
|
||||||
toast.error("Two passwords do not match!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStep(step + 1);
|
|
||||||
} else if (step === 3) {
|
|
||||||
// Verification for invitation rule
|
|
||||||
if (data.inviteRule === null) {
|
|
||||||
toast.error("Please choose one option!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setStep(step + 1);
|
|
||||||
} else if (step === 4) {
|
|
||||||
// Verification for invitation link
|
|
||||||
setStep(step + 1);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</StyledButton>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{step === 0 && <FirstStep onButtonClick={() => setStep(step + 1)} />}
|
|
||||||
{step === 1 && <SpaceNameStep data={data} setData={setData} />}
|
|
||||||
{step === 2 && <AdminCredentialsStep data={data} setData={setData} />}
|
|
||||||
{step === 3 && <InviteRuleStep data={data} setData={setData} />}
|
|
||||||
{step === 4 && <InviteLinkStep />}
|
|
||||||
{step === 5 && (
|
|
||||||
<LastStep
|
|
||||||
data={data}
|
|
||||||
onButtonClick={() => {
|
|
||||||
// TODO: finish it
|
|
||||||
console.log("onboarding steps completed:", data);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</StyledOnboardingPage>
|
</StyledOnboardingPage>
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ const StyledFirstStep = styled.div`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function FirstStep({ onButtonClick }) {
|
export default function WelcomeStep({ step, setStep }) {
|
||||||
return (
|
return (
|
||||||
<StyledFirstStep>
|
<StyledFirstStep>
|
||||||
<span className="primaryText">Welcome to your Rustchat!</span>
|
<span className="primaryText">Welcome to your Rustchat!</span>
|
||||||
<span className="secondaryText">
|
<span className="secondaryText">
|
||||||
Everything in this space is owned by you. Let’s set up your space!
|
Everything in this space is owned by you. Let’s set up your space!
|
||||||
</span>
|
</span>
|
||||||
<StyledButton className="startButton" onClick={onButtonClick}>
|
<StyledButton className="startButton" onClick={() => setStep(step + 1)}>
|
||||||
<img src={PlayIcon} alt="play icon" />
|
<img src={PlayIcon} alt="play icon" />
|
||||||
<span>Start</span>
|
<span>Start</span>
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import StyledInput from "../../../common/component/styled/Input";
|
||||||
|
import StyledButton from "../../../common/component/styled/Button";
|
||||||
|
|
||||||
|
const StyledSpaceNameStep = styled.div`
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> .secondaryText {
|
||||||
|
color: #667085;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .button {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function SpaceNameStep({ step, setStep, data, setData }) {
|
||||||
|
return (
|
||||||
|
<StyledSpaceNameStep>
|
||||||
|
<span className="primaryText">Create a new server</span>
|
||||||
|
<span className="secondaryText">
|
||||||
|
Servers are shared environments where teams can work on projects and chat.
|
||||||
|
</span>
|
||||||
|
<StyledInput
|
||||||
|
className="input"
|
||||||
|
placeholder="Enter server name"
|
||||||
|
value={data.spaceName}
|
||||||
|
onChange={(e) =>
|
||||||
|
setData({
|
||||||
|
...data,
|
||||||
|
spaceName: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledButton
|
||||||
|
className="button"
|
||||||
|
onClick={() => {
|
||||||
|
// Verification for space name
|
||||||
|
if (data.spaceName === "") {
|
||||||
|
toast.error("Please enter server name!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStep(step + 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Create Server
|
||||||
|
</StyledButton>
|
||||||
|
</StyledSpaceNameStep>
|
||||||
|
);
|
||||||
|
}
|
||||||
+27
-2
@@ -1,5 +1,7 @@
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import StyledInput from "../../../common/component/styled/Input";
|
import StyledInput from "../../../common/component/styled/Input";
|
||||||
|
import StyledButton from "../../../common/component/styled/Button";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
|
||||||
const StyledAdminCredentialsStep = styled.div`
|
const StyledAdminCredentialsStep = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -8,12 +10,16 @@ const StyledAdminCredentialsStep = styled.div`
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> .input:not(:last-child) {
|
> .input:not(:nth-last-child(2)) {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .button {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function AdminCredentialsStep({ data, setData }) {
|
export default function AdminCredentialsStep({ step, setStep, data, setData }) {
|
||||||
return (
|
return (
|
||||||
<StyledAdminCredentialsStep>
|
<StyledAdminCredentialsStep>
|
||||||
<span className="primaryText">Now let’s set up your admin account</span>
|
<span className="primaryText">Now let’s set up your admin account</span>
|
||||||
@@ -53,6 +59,25 @@ export default function AdminCredentialsStep({ data, setData }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<StyledButton
|
||||||
|
className="button"
|
||||||
|
onClick={() => {
|
||||||
|
// Verification for admin credentials
|
||||||
|
if (data.adminEmail === "") {
|
||||||
|
toast.error("Please enter admin email!");
|
||||||
|
return;
|
||||||
|
} else if (data.adminPassword === "") {
|
||||||
|
toast.error("Please enter admin password!");
|
||||||
|
return;
|
||||||
|
} else if (data.adminPassword !== data.adminPassword2) {
|
||||||
|
toast.error("Two passwords do not match!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStep(step + 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</StyledButton>
|
||||||
</StyledAdminCredentialsStep>
|
</StyledAdminCredentialsStep>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+12
-5
@@ -1,5 +1,6 @@
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import StyledRadio from "../../../common/component/styled/Radio";
|
import StyledRadio from "../../../common/component/styled/Radio";
|
||||||
|
import StyledButton from "../../../common/component/styled/Button";
|
||||||
|
|
||||||
const StyledInviteRuleStep = styled.div`
|
const StyledInviteRuleStep = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -8,12 +9,12 @@ const StyledInviteRuleStep = styled.div`
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> .input:not(:last-child) {
|
> .input:not(:nth-last-child(2)) {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function InviteRuleStep({ data, setData }) {
|
export default function InviteRuleStep({ step, setStep, data, setData }) {
|
||||||
return (
|
return (
|
||||||
<StyledInviteRuleStep>
|
<StyledInviteRuleStep>
|
||||||
<span className="primaryText">Last step: invite others!</span>
|
<span className="primaryText">Last step: invite others!</span>
|
||||||
@@ -21,13 +22,19 @@ export default function InviteRuleStep({ data, setData }) {
|
|||||||
<StyledRadio
|
<StyledRadio
|
||||||
options={["Everyone", "Invitation link only"]}
|
options={["Everyone", "Invitation link only"]}
|
||||||
value={data.inviteRule}
|
value={data.inviteRule}
|
||||||
onChange={(v) =>
|
onChange={(v) => {
|
||||||
setData({
|
setData({
|
||||||
...data,
|
...data,
|
||||||
inviteRule: v
|
inviteRule: v
|
||||||
})
|
});
|
||||||
}
|
setTimeout(() => {
|
||||||
|
setStep(step + 1);
|
||||||
|
}, 750);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
<StyledButton className="button border_less ghost" onClick={() => setStep(step + 1)}>
|
||||||
|
Skip
|
||||||
|
</StyledButton>
|
||||||
</StyledInviteRuleStep>
|
</StyledInviteRuleStep>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+4
-1
@@ -51,7 +51,7 @@ const StyledInviteLinkStep = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function InviteLinkStep() {
|
export default function InviteLinkStep({ step, setStep }) {
|
||||||
const { link, linkCopied, copyLink } = useInviteLink();
|
const { link, linkCopied, copyLink } = useInviteLink();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -65,6 +65,9 @@ export default function InviteLinkStep() {
|
|||||||
{linkCopied ? "Copied" : `Copy`}
|
{linkCopied ? "Copied" : `Copy`}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</div>
|
</div>
|
||||||
|
<StyledButton className="button border_less ghost" onClick={() => setStep(step + 1)}>
|
||||||
|
Skip
|
||||||
|
</StyledButton>
|
||||||
</StyledInviteLinkStep>
|
</StyledInviteLinkStep>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ const StyledLastStep = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
> .tip {
|
> .tip {
|
||||||
width: 588px;
|
width: 560px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -26,7 +26,7 @@ const StyledLastStep = styled.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function LastStep({ data, onButtonClick }) {
|
export default function CompletedStep({ data, step, setStep }) {
|
||||||
return (
|
return (
|
||||||
<StyledLastStep>
|
<StyledLastStep>
|
||||||
<span className="primaryText">Welcome to {data.spaceName}</span>
|
<span className="primaryText">Welcome to {data.spaceName}</span>
|
||||||
@@ -35,7 +35,7 @@ export default function LastStep({ data, onButtonClick }) {
|
|||||||
More settings, including domain resolution, privileges, securities, and invites are available in{" "}
|
More settings, including domain resolution, privileges, securities, and invites are available in{" "}
|
||||||
<span className="strong">Settings</span>
|
<span className="strong">Settings</span>
|
||||||
</span>
|
</span>
|
||||||
<StyledButton className="startButton" onClick={onButtonClick}>
|
<StyledButton className="startButton" onClick={() => setStep(step + 1)}>
|
||||||
<img src={PlayIcon} alt="play icon" />
|
<img src={PlayIcon} alt="play icon" />
|
||||||
<span>Start</span>
|
<span>Start</span>
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import styled from "styled-components";
|
|
||||||
import StyledInput from "../../../common/component/styled/Input";
|
|
||||||
|
|
||||||
const StyledSpaceNameStep = styled.div`
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> .secondaryText {
|
|
||||||
color: #667085;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default function SpaceNameStep({ data, setData }) {
|
|
||||||
return (
|
|
||||||
<StyledSpaceNameStep>
|
|
||||||
<span className="primaryText">Let’s start with name:</span>
|
|
||||||
<span className="secondaryText">This space is called: </span>
|
|
||||||
<StyledInput
|
|
||||||
className="input"
|
|
||||||
placeholder="Enter space name"
|
|
||||||
value={data.spaceName}
|
|
||||||
onChange={(e) =>
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
spaceName: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</StyledSpaceNameStep>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -16,21 +16,6 @@ const StyledOnboardingPage = styled.div`
|
|||||||
border: 1px solid #f2f4f7;
|
border: 1px solid #f2f4f7;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06);
|
box-shadow: 0 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06);
|
||||||
|
|
||||||
> .buttonBack,
|
|
||||||
> .buttonNext {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .buttonBack {
|
|
||||||
left: 30px;
|
|
||||||
color: #98a2b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .buttonNext {
|
|
||||||
right: 30px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,8 +69,21 @@ const StyledOnboardingPage = styled.div`
|
|||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
padding: 10px 14px;
|
padding: 10px 14px;
|
||||||
border: 1px solid #d0d5dd;
|
border: 1px solid #d0d5dd;
|
||||||
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
width: 360px;
|
||||||
|
|
||||||
|
&.ghost.border_less {
|
||||||
|
width: fit-content;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #98a2b3;
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user