From 138acd28e800a7419ea1aebaa6004dbe15f26b69 Mon Sep 17 00:00:00 2001 From: Vladyslav Matsiiako Date: Sat, 10 Dec 2022 10:18:57 -0500 Subject: [PATCH] Updated Infisical onboarding guide --- frontend/components/basic/Layout.tsx | 220 +++++++-------- .../utilities/checks/OnboardingCheck.ts | 71 +++++ frontend/pages/home/[id].tsx | 252 ++++++++++++------ frontend/public/images/progress-71.svg | 5 + 4 files changed, 342 insertions(+), 206 deletions(-) create mode 100644 frontend/components/utilities/checks/OnboardingCheck.ts create mode 100644 frontend/public/images/progress-71.svg diff --git a/frontend/components/basic/Layout.tsx b/frontend/components/basic/Layout.tsx index 819a87db0..5057f70ce 100644 --- a/frontend/components/basic/Layout.tsx +++ b/frontend/components/basic/Layout.tsx @@ -1,37 +1,38 @@ /* eslint-disable no-unexpected-multiline */ /* eslint-disable react-hooks/exhaustive-deps */ -import { useEffect, useState } from "react"; -import Link from "next/link"; -import { useRouter } from "next/router"; +import { useEffect, useState } from 'react'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; import { faBookOpen, faGear, faKey, faMobile, faPlug, - faUser, -} from "@fortawesome/free-solid-svg-icons"; -import { faPlus } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + faUser +} from '@fortawesome/free-solid-svg-icons'; +import { faPlus } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import getOrganizations from "~/pages/api/organization/getOrgs"; -import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProjects"; -import getOrganizationUsers from "~/pages/api/organization/GetOrgUsers"; -import addUserToWorkspace from "~/pages/api/workspace/addUserToWorkspace"; -import createWorkspace from "~/pages/api/workspace/createWorkspace"; -import getWorkspaces from "~/pages/api/workspace/getWorkspaces"; -import uploadKeys from "~/pages/api/workspace/uploadKeys"; -import checkUserAction from "~/pages/api/userActions/checkUserAction"; +import getOrganizations from '~/pages/api/organization/getOrgs'; +import getOrganizationUserProjects from '~/pages/api/organization/GetOrgUserProjects'; +import getOrganizationUsers from '~/pages/api/organization/GetOrgUsers'; +import checkUserAction from '~/pages/api/userActions/checkUserAction'; +import addUserToWorkspace from '~/pages/api/workspace/addUserToWorkspace'; +import createWorkspace from '~/pages/api/workspace/createWorkspace'; +import getWorkspaces from '~/pages/api/workspace/getWorkspaces'; +import uploadKeys from '~/pages/api/workspace/uploadKeys'; -import NavBarDashboard from "../navigation/NavBarDashboard"; -import { tempLocalStorage } from "../utilities/checks/tempLocalStorage"; +import NavBarDashboard from '../navigation/NavBarDashboard'; +import onboardingCheck from '../utilities/checks/OnboardingCheck'; +import { tempLocalStorage } from '../utilities/checks/tempLocalStorage'; import { decryptAssymmetric, - encryptAssymmetric, -} from "../utilities/cryptography/crypto"; -import Button from "./buttons/Button"; -import AddWorkspaceDialog from "./dialog/AddWorkspaceDialog"; -import Listbox from "./Listbox"; + encryptAssymmetric +} from '../utilities/cryptography/crypto'; +import Button from './buttons/Button'; +import AddWorkspaceDialog from './dialog/AddWorkspaceDialog'; +import Listbox from './Listbox'; interface LayoutProps { children: React.ReactNode; @@ -41,16 +42,13 @@ export default function Layout({ children }: LayoutProps) { const router = useRouter(); const [workspaceList, setWorkspaceList] = useState([]); const [workspaceMapping, setWorkspaceMapping] = useState([{ 1: 2 }]); - const [workspaceSelected, setWorkspaceSelected] = useState("∞"); - const [newWorkspaceName, setNewWorkspaceName] = useState(""); + const [workspaceSelected, setWorkspaceSelected] = useState('∞'); + const [newWorkspaceName, setNewWorkspaceName] = useState(''); const [isOpen, setIsOpen] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); - const [hasUserClickedSlack, setHasUserClickedSlack] = useState(false); - const [hasUserClickedIntro, setHasUserClickedIntro] = useState(false); - const [hasUserStarred, setHasUserStarred] = useState(false); - const [usersInOrg, setUsersInOrg] = useState(false); - const [totalOnboardingActionsDone, setTotalOnboardingActionsDone] = useState(0); + const [totalOnboardingActionsDone, setTotalOnboardingActionsDone] = + useState(0); function closeModal() { setIsOpen(false); @@ -77,35 +75,35 @@ export default function Layout({ children }: LayoutProps) { if (!currentWorkspaces.includes(workspaceName)) { const newWorkspace = await createWorkspace({ workspaceName, - organizationId: tempLocalStorage("orgData.id"), + organizationId: tempLocalStorage('orgData.id') }); const newWorkspaceId = newWorkspace._id; if (addAllUsers) { const orgUsers = await getOrganizationUsers({ - orgId: tempLocalStorage("orgData.id"), + orgId: tempLocalStorage('orgData.id') }); orgUsers.map(async (user: any) => { - if (user.status == "accepted") { + if (user.status == 'accepted') { const result = await addUserToWorkspace( user.user.email, newWorkspaceId ); if (result?.invitee && result?.latestKey) { - const PRIVATE_KEY = tempLocalStorage("PRIVATE_KEY"); + const PRIVATE_KEY = tempLocalStorage('PRIVATE_KEY'); // assymmetrically decrypt symmetric key with local private key const key = decryptAssymmetric({ ciphertext: result.latestKey.encryptedKey, nonce: result.latestKey.nonce, publicKey: result.latestKey.sender.publicKey, - privateKey: PRIVATE_KEY, + privateKey: PRIVATE_KEY }); const { ciphertext, nonce } = encryptAssymmetric({ plaintext: key, publicKey: result.invitee.publicKey, - privateKey: PRIVATE_KEY, + privateKey: PRIVATE_KEY }) as { ciphertext: string; nonce: string }; uploadKeys( @@ -118,11 +116,11 @@ export default function Layout({ children }: LayoutProps) { } }); } - router.push("/dashboard/" + newWorkspaceId + "?Development"); + router.push('/dashboard/' + newWorkspaceId + '?Development'); setIsOpen(false); - setNewWorkspaceName(""); + setNewWorkspaceName(''); } else { - console.error("A project with this name already exists."); + console.error('A project with this name already exists.'); setError(true); setLoading(false); } @@ -136,59 +134,59 @@ export default function Layout({ children }: LayoutProps) { const menuItems = [ { href: - "/dashboard/" + + '/dashboard/' + workspaceMapping[workspaceSelected as any] + - "?Development", - title: "Secrets", - emoji: , + '?Development', + title: 'Secrets', + emoji: }, { - href: "/users/" + workspaceMapping[workspaceSelected as any], - title: "Members", - emoji: , + href: '/users/' + workspaceMapping[workspaceSelected as any], + title: 'Members', + emoji: }, { - href: "/integrations/" + workspaceMapping[workspaceSelected as any], - title: "Integrations", - emoji: , + href: '/integrations/' + workspaceMapping[workspaceSelected as any], + title: 'Integrations', + emoji: }, { - href: "/settings/project/" + workspaceMapping[workspaceSelected as any], - title: "Project Settings", - emoji: , - }, + href: '/settings/project/' + workspaceMapping[workspaceSelected as any], + title: 'Project Settings', + emoji: + } ]; useEffect(() => { // Put a user in a workspace if they're not in one yet const putUserInWorkSpace = async () => { - if (tempLocalStorage("orgData.id") === "") { + if (tempLocalStorage('orgData.id') === '') { const userOrgs = await getOrganizations(); - localStorage.setItem("orgData.id", userOrgs[0]._id); + localStorage.setItem('orgData.id', userOrgs[0]._id); } const orgUserProjects = await getOrganizationUserProjects({ - orgId: tempLocalStorage("orgData.id"), + orgId: tempLocalStorage('orgData.id') }); const userWorkspaces = orgUserProjects; if ( userWorkspaces.length == 0 && - router.asPath != "/noprojects" && - !router.asPath.includes("settings") + router.asPath != '/noprojects' && + !router.asPath.includes('settings') ) { - router.push("/noprojects"); - } else if (router.asPath != "/noprojects") { + router.push('/noprojects'); + } else if (router.asPath != '/noprojects') { const intendedWorkspaceId = router.asPath - .split("/") - [router.asPath.split("/").length - 1].split("?")[0]; + .split('/') + [router.asPath.split('/').length - 1].split('?')[0]; // If a user is not a member of a workspace they are trying to access, just push them to one of theirs if ( - intendedWorkspaceId != "heroku" && + intendedWorkspaceId != 'heroku' && !userWorkspaces .map((workspace: { _id: string }) => workspace._id) .includes(intendedWorkspaceId) ) { - router.push("/dashboard/" + userWorkspaces[0]._id + "?Development"); + router.push('/dashboard/' + userWorkspaces[0]._id + '?Development'); } else { setWorkspaceList( userWorkspaces.map((workspace: any) => workspace.name) @@ -197,7 +195,7 @@ export default function Layout({ children }: LayoutProps) { Object.fromEntries( userWorkspaces.map((workspace: any) => [ workspace.name, - workspace._id, + workspace._id ]) ) as any ); @@ -205,58 +203,19 @@ export default function Layout({ children }: LayoutProps) { Object.fromEntries( userWorkspaces.map((workspace: any) => [ workspace._id, - workspace.name, + workspace.name ]) )[ router.asPath - .split("/") - [router.asPath.split("/").length - 1].split("?")[0] + .split('/') + [router.asPath.split('/').length - 1].split('?')[0] ] ); } } }; putUserInWorkSpace(); - - const checkUserActionsFunction = async () => { - let countActions = 0; - const userActionSlack = await checkUserAction({ - action: "slack_cta_clicked", - }); - setHasUserClickedSlack(userActionSlack ? true : false); - if (userActionSlack) { - countActions = countActions + 1; - } - - const userActionIntro = await checkUserAction({ - action: "intro_cta_clicked", - }); - setHasUserClickedIntro(userActionIntro ? true : false); - if (userActionIntro) { - countActions = countActions + 1; - } - - const userActionStar = await checkUserAction({ - action: "star_cta_clicked", - }); - setHasUserStarred(userActionStar ? true : false); - if (userActionStar) { - countActions = countActions + 1; - } - - const orgId = localStorage.getItem("orgData.id"); - const orgUsers = await getOrganizationUsers({ - orgId: orgId ? orgId : "", - }); - setUsersInOrg(orgUsers.length > 1) - if (orgUsers.length > 1) { - countActions = countActions + 1; - } - console.log(123, countActions) - setTotalOnboardingActionsDone(countActions); - }; - console.log(`images/progress-${totalOnboardingActionsDone == 0 ? "0" : ""}${totalOnboardingActionsDone == 1 ? "14" : ""}${totalOnboardingActionsDone == 1 ? "28" : ""}${totalOnboardingActionsDone == 3 ? "43" : ""}${totalOnboardingActionsDone == 4 ? "57" : ""}.svg`) - checkUserActionsFunction(); + onboardingCheck({ setTotalOnboardingActionsDone }); }, []); useEffect(() => { @@ -265,16 +224,16 @@ export default function Layout({ children }: LayoutProps) { workspaceMapping[Number(workspaceSelected)] && `${workspaceMapping[Number(workspaceSelected)]}` !== router.asPath - .split("/") - [router.asPath.split("/").length - 1].split("?")[0] + .split('/') + [router.asPath.split('/').length - 1].split('?')[0] ) { router.push( - "/dashboard/" + + '/dashboard/' + workspaceMapping[Number(workspaceSelected)] + - "?Development" + '?Development' ); localStorage.setItem( - "projectData.id", + 'projectData.id', `${workspaceMapping[Number(workspaceSelected)]}` ); } @@ -286,7 +245,10 @@ export default function Layout({ children }: LayoutProps) { return ( <>
- +