fix: get onboarding working

This commit is contained in:
Liyang Zhu
2022-06-06 15:07:17 +08:00
parent defacf6b63
commit befe35f3d6
10 changed files with 82 additions and 49 deletions
+1 -2
View File
@@ -18,8 +18,7 @@ const whiteList = [
"getMetamaskNonce", "getMetamaskNonce",
"renew", "renew",
"getInitialized", "getInitialized",
"createAdmin", "createAdmin"
"updateLoginConfig"
]; ];
const baseQuery = fetchBaseQuery({ const baseQuery = fetchBaseQuery({
baseUrl: BASE_URL, baseUrl: BASE_URL,
+1 -1
View File
@@ -178,7 +178,7 @@ export const serverApi = createApi({
}), }),
createAdmin: builder.mutation({ createAdmin: builder.mutation({
query: (data) => ({ query: (data) => ({
url: `/admin/system/createAdmin`, url: `/admin/system/create_admin`,
method: "POST", method: "POST",
body: data body: data
}) })
+1 -1
View File
@@ -1,7 +1,7 @@
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import { useGetInitializedQuery } from "../../app/services/server"; import { useGetInitializedQuery } from "../../app/services/server";
export default function RequireInitialized({ children, redirectTo = "/" }) { export default function RequireInitialized({ children, redirectTo = "/onboarding" }) {
const { data } = useGetInitializedQuery(); const { data } = useGetInitializedQuery();
console.log("initialized?", data); console.log("initialized?", data);
return data === false ? <Navigate to={redirectTo} replace /> : children; return data === false ? <Navigate to={redirectTo} replace /> : children;
+10 -4
View File
@@ -1,7 +1,8 @@
import { useState } from "react"; import { useState } from "react";
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import { Helmet } from "react-helmet";
import WelcomeStep from "./steps/1-welcome"; import WelcomeStep from "./steps/1-welcome";
import SpaceNameStep from "./steps/2-spaceName"; import ServerNameStep from "./steps/2-serverName";
import AdminCredentialsStep from "./steps/3-adminCredentials"; import AdminCredentialsStep from "./steps/3-adminCredentials";
import InviteRuleStep from "./steps/4-inviteRule"; import InviteRuleStep from "./steps/4-inviteRule";
import InviteLinkStep from "./steps/5-inviteLink"; import InviteLinkStep from "./steps/5-inviteLink";
@@ -11,16 +12,20 @@ import StyledOnboardingPage from "./styled";
export default function OnboardingPage() { export default function OnboardingPage() {
const [step, setStep] = useState(0); const [step, setStep] = useState(0);
const [data, setData] = useState({ const [data, setData] = useState({
spaceName: "" serverName: ""
}); });
const props = { step, setStep, data, setData }; const props = { setStep, data, setData };
return ( return (
<>
<Helmet>
<title>Rustchat Setup</title>
</Helmet>
<StyledOnboardingPage> <StyledOnboardingPage>
<div className="horizontalBox"> <div className="horizontalBox">
<div className="verticalBox"> <div className="verticalBox">
{step === 0 && <WelcomeStep {...props} />} {step === 0 && <WelcomeStep {...props} />}
{step === 1 && <SpaceNameStep {...props} />} {step === 1 && <ServerNameStep {...props} />}
{step === 2 && <AdminCredentialsStep {...props} />} {step === 2 && <AdminCredentialsStep {...props} />}
{step === 3 && <InviteRuleStep {...props} />} {step === 3 && <InviteRuleStep {...props} />}
{step === 4 && <InviteLinkStep {...props} />} {step === 4 && <InviteLinkStep {...props} />}
@@ -29,5 +34,6 @@ export default function OnboardingPage() {
</div> </div>
</div> </div>
</StyledOnboardingPage> </StyledOnboardingPage>
</>
); );
} }
+2 -2
View File
@@ -10,14 +10,14 @@ const StyledFirstStep = styled.div`
align-items: center; align-items: center;
`; `;
export default function WelcomeStep({ step, setStep }) { export default function WelcomeStep({ 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. Lets set up your space! Everything in this space is owned by you. Lets set up your space!
</span> </span>
<StyledButton className="startButton" onClick={() => setStep(step + 1)}> <StyledButton className="startButton" onClick={() => setStep((prev) => prev + 1)}>
<img src={PlayIcon} alt="play icon" /> <img src={PlayIcon} alt="play icon" />
<span>Start</span> <span>Start</span>
</StyledButton> </StyledButton>
@@ -19,7 +19,7 @@ const StyledSpaceNameStep = styled.div`
} }
`; `;
export default function SpaceNameStep({ step, setStep, data, setData }) { export default function ServerNameStep({ setStep, data, setData }) {
return ( return (
<StyledSpaceNameStep> <StyledSpaceNameStep>
<span className="primaryText">Create a new server</span> <span className="primaryText">Create a new server</span>
@@ -29,11 +29,11 @@ export default function SpaceNameStep({ step, setStep, data, setData }) {
<StyledInput <StyledInput
className="input" className="input"
placeholder="Enter server name" placeholder="Enter server name"
value={data.spaceName} value={data.serverName}
onChange={(e) => onChange={(e) =>
setData({ setData({
...data, ...data,
spaceName: e.target.value serverName: e.target.value
}) })
} }
/> />
@@ -41,11 +41,11 @@ export default function SpaceNameStep({ step, setStep, data, setData }) {
className="button" className="button"
onClick={() => { onClick={() => {
// Verification for space name // Verification for space name
if (data.spaceName === "") { if (data.serverName === "") {
toast.error("Please enter server name!"); toast.error("Please enter server name!");
return; return;
} }
setStep(step + 1); setStep((prev) => prev + 1);
}} }}
> >
Create Server Create Server
@@ -1,10 +1,17 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import styled from "styled-components"; import styled from "styled-components";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { useDispatch } from "react-redux";
import StyledInput from "../../../common/component/styled/Input"; import StyledInput from "../../../common/component/styled/Input";
import StyledButton from "../../../common/component/styled/Button"; import StyledButton from "../../../common/component/styled/Button";
import { useCreateAdminMutation } from "../../../app/services/server"; import {
useCreateAdminMutation,
useGetInitializedQuery,
useGetServerQuery,
useUpdateServerMutation
} from "../../../app/services/server";
import { useLoginMutation } from "../../../app/services/auth"; import { useLoginMutation } from "../../../app/services/auth";
import { setAuthData } from "../../../app/slices/auth.data";
const StyledAdminCredentialsStep = styled.div` const StyledAdminCredentialsStep = styled.div`
height: 100%; height: 100%;
@@ -22,13 +29,18 @@ const StyledAdminCredentialsStep = styled.div`
} }
`; `;
export default function AdminCredentialsStep({ step, setStep }) { export default function AdminCredentialsStep({ data, setStep }) {
const dispatch = useDispatch();
const [createAdmin, { isLoading: isSigningUp, error: signUpError }] = useCreateAdminMutation();
const [ const [
createAdmin, login,
{ isLoading: isSignUpLoading, isSuccess: isSignUpSuccess, error: signUpError } { isLoading: isLoggingIn, isSuccess: isLoggedIn, error: loginError, data: loginData }
] = useCreateAdminMutation(); ] = useLoginMutation();
const [login, { isLoading: isLoginLoading, isSuccess: isLoginSuccess, error: loginError }] = const { refetch: refetchInitialized } = useGetInitializedQuery();
useLoginMutation(); const { data: serverData } = useGetServerQuery();
const [updateServer, { isLoading: isUpdatingServer, isSuccess: isUpdatedServer }] =
useUpdateServerMutation();
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
@@ -39,16 +51,32 @@ export default function AdminCredentialsStep({ step, setStep }) {
if (signUpError === undefined) return; if (signUpError === undefined) return;
toast.error(`Failed to sign up: ${signUpError.data}`); toast.error(`Failed to sign up: ${signUpError.data}`);
}, [signUpError]); }, [signUpError]);
useEffect(() => { useEffect(() => {
if (loginError === undefined) return; if (loginError === undefined) return;
toast.error(`Login failed: ${loginError.data}`); toast.error(`Login failed: ${loginError.data}`);
}, [loginError]); }, [loginError]);
// Increment `step` when both signing up and logging in have completed // After logged in
useEffect(() => { useEffect(() => {
if (isSignUpSuccess && isLoginSuccess) setStep(step + 1); if (isLoggedIn && loginData) {
}, [isSignUpSuccess, isLoginSuccess]); // Update local auth data
dispatch(setAuthData(loginData));
// Update initialized state
refetchInitialized();
// Set server name
updateServer({
...serverData,
name: data.serverName
});
}
}, [isLoggedIn, loginData]);
// After updated server
useEffect(() => {
if (isUpdatedServer) {
setStep((prev) => prev + 1);
}
}, [isUpdatedServer]);
return ( return (
<StyledAdminCredentialsStep> <StyledAdminCredentialsStep>
@@ -101,7 +129,7 @@ export default function AdminCredentialsStep({ step, setStep }) {
}); });
}} }}
> >
{!(isSignUpLoading || isLoginLoading) ? "Sign Up" : "..."} {!(isSigningUp || isLoggingIn || isUpdatingServer) ? "Sign Up" : "..."}
</StyledButton> </StyledButton>
</StyledAdminCredentialsStep> </StyledAdminCredentialsStep>
); );
+6 -6
View File
@@ -17,11 +17,11 @@ const StyledInviteRuleStep = styled.div`
} }
`; `;
export default function InviteRuleStep({ step, setStep }) { export default function InviteRuleStep({ setStep }) {
const { data: loginConfig } = useGetLoginConfigQuery(); const { data: loginConfig } = useGetLoginConfigQuery();
const [updateLoginConfig, { isSuccess, error }] = useUpdateLoginConfigMutation(); const [updateLoginConfig, { isSuccess, error }] = useUpdateLoginConfigMutation();
const [value, setValue] = useState(null); const [value, setValue] = useState(0);
// Display error // Display error
useEffect(() => { useEffect(() => {
@@ -31,7 +31,7 @@ export default function InviteRuleStep({ step, setStep }) {
// Increment `step` when updating has completed // Increment `step` when updating has completed
useEffect(() => { useEffect(() => {
if (isSuccess) setStep(step + 1); if (isSuccess) setStep((prev) => prev + 1);
}, [isSuccess]); }, [isSuccess]);
return ( return (
@@ -41,18 +41,18 @@ export default function InviteRuleStep({ step, setStep }) {
<StyledRadio <StyledRadio
options={["Everyone", "Invitation link only"]} options={["Everyone", "Invitation link only"]}
value={value} value={value}
onChange={(v) => { onChange={async (v) => {
setValue(v); setValue(v);
if (loginConfig !== undefined) { if (loginConfig !== undefined) {
const whoCanSignUp = ["EveryOne", "InvitationOnly"][v]; const whoCanSignUp = ["EveryOne", "InvitationOnly"][v];
updateLoginConfig({ await updateLoginConfig({
...loginConfig, ...loginConfig,
who_can_sign_up: whoCanSignUp who_can_sign_up: whoCanSignUp
}); });
} }
}} }}
/> />
<StyledButton className="button border_less ghost" onClick={() => setStep(step + 1)}> <StyledButton className="button border_less ghost" onClick={() => setStep((prev) => prev + 1)}>
Skip Skip
</StyledButton> </StyledButton>
</StyledInviteRuleStep> </StyledInviteRuleStep>
+2 -2
View File
@@ -51,7 +51,7 @@ const StyledInviteLinkStep = styled.div`
} }
`; `;
export default function InviteLinkStep({ step, setStep }) { export default function InviteLinkStep({ setStep }) {
const { link, linkCopied, copyLink } = useInviteLink(); const { link, linkCopied, copyLink } = useInviteLink();
return ( return (
@@ -65,7 +65,7 @@ export default function InviteLinkStep({ step, setStep }) {
{linkCopied ? "Copied" : `Copy`} {linkCopied ? "Copied" : `Copy`}
</StyledButton> </StyledButton>
</div> </div>
<StyledButton className="button border_less ghost" onClick={() => setStep(step + 1)}> <StyledButton className="button border_less ghost" onClick={() => setStep((prev) => prev + 1)}>
Skip Skip
</StyledButton> </StyledButton>
</StyledInviteLinkStep> </StyledInviteLinkStep>
+3 -3
View File
@@ -26,16 +26,16 @@ const StyledLastStep = styled.div`
} }
`; `;
export default function CompletedStep({ data, step, setStep }) { export default function CompletedStep({ data, setStep }) {
return ( return (
<StyledLastStep> <StyledLastStep>
<span className="primaryText">Welcome to {data.spaceName}</span> <span className="primaryText">Welcome to {data.serverName}</span>
<span className="secondaryText">Proudly presented by Rustchat</span> <span className="secondaryText">Proudly presented by Rustchat</span>
<span className="tip"> <span className="tip">
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={() => setStep(step + 1)}> <StyledButton className="startButton" onClick={() => setStep((prev) => prev + 1)}>
<img src={PlayIcon} alt="play icon" /> <img src={PlayIcon} alt="play icon" />
<span>Start</span> <span>Start</span>
</StyledButton> </StyledButton>