mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 21:25:53 +08:00
feat: maintain state and add log events
This commit is contained in:
parent
438cbcef87
commit
6664e1bc02
@ -1,23 +1,52 @@
|
|||||||
/* eslint-disable sonarjs/cognitive-complexity */
|
/* eslint-disable sonarjs/cognitive-complexity */
|
||||||
import '../OnboardingQuestionaire.styles.scss';
|
import '../OnboardingQuestionaire.styles.scss';
|
||||||
|
|
||||||
import { Button, Typography } from 'antd';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
import { Button, Input, Typography } from 'antd';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { ArrowLeft, ArrowRight, CheckCircle } from 'lucide-react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
interface AboutSigNozQuestionsProps {
|
interface AboutSigNozQuestionsProps {
|
||||||
|
signozDetails: any;
|
||||||
|
setSignozDetails: (details: any) => void;
|
||||||
onNext: () => void;
|
onNext: () => void;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hearAboutSignozOptions: Record<string, string> = {
|
||||||
|
blog: 'Blog',
|
||||||
|
hackerNews: 'Hacker News',
|
||||||
|
linkedin: 'LinkedIn',
|
||||||
|
twitter: 'Twitter',
|
||||||
|
reddit: 'Reddit',
|
||||||
|
colleaguesFriends: 'Colleagues / Friends',
|
||||||
|
};
|
||||||
|
|
||||||
|
const interestedInOptions: Record<string, string> = {
|
||||||
|
savingCosts: 'Saving costs',
|
||||||
|
otelNativeStack: 'Interested in Otel-native stack',
|
||||||
|
allInOne: 'All in one',
|
||||||
|
};
|
||||||
|
|
||||||
export function AboutSigNozQuestions({
|
export function AboutSigNozQuestions({
|
||||||
|
signozDetails,
|
||||||
|
setSignozDetails,
|
||||||
onNext,
|
onNext,
|
||||||
onBack,
|
onBack,
|
||||||
}: AboutSigNozQuestionsProps): JSX.Element {
|
}: AboutSigNozQuestionsProps): JSX.Element {
|
||||||
const [hearAboutSignoz, setHearAboutSignoz] = useState<string | null>(null);
|
const [hearAboutSignoz, setHearAboutSignoz] = useState<string | null>(
|
||||||
const [otherAboutSignoz, setOtherAboutSignoz] = useState<string>('');
|
signozDetails?.hearAboutSignoz || null,
|
||||||
const [interestedSignoz, setInterestedSignoz] = useState<string | null>(null);
|
);
|
||||||
const [otherInterest, setOtherInterest] = useState<string>('');
|
const [otherAboutSignoz, setOtherAboutSignoz] = useState<string>(
|
||||||
|
signozDetails?.otherAboutSignoz || '',
|
||||||
|
);
|
||||||
|
const [interestedSignoz, setInterestedSignoz] = useState<string | null>(
|
||||||
|
signozDetails?.interestedSignoz || null,
|
||||||
|
);
|
||||||
|
const [otherInterest, setOtherInterest] = useState<string>(
|
||||||
|
signozDetails?.otherInterest || '',
|
||||||
|
);
|
||||||
const [isNextDisabled, setIsNextDisabled] = useState<boolean>(true);
|
const [isNextDisabled, setIsNextDisabled] = useState<boolean>(true);
|
||||||
|
|
||||||
useEffect((): void => {
|
useEffect((): void => {
|
||||||
@ -33,6 +62,42 @@ export function AboutSigNozQuestions({
|
|||||||
}
|
}
|
||||||
}, [hearAboutSignoz, otherAboutSignoz, interestedSignoz, otherInterest]);
|
}, [hearAboutSignoz, otherAboutSignoz, interestedSignoz, otherInterest]);
|
||||||
|
|
||||||
|
const handleOnNext = (): void => {
|
||||||
|
setSignozDetails({
|
||||||
|
hearAboutSignoz,
|
||||||
|
otherAboutSignoz,
|
||||||
|
interestedSignoz,
|
||||||
|
otherInterest,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: SigNoz Questions: Next', {
|
||||||
|
hearAboutSignoz,
|
||||||
|
otherAboutSignoz,
|
||||||
|
interestedSignoz,
|
||||||
|
otherInterest,
|
||||||
|
});
|
||||||
|
|
||||||
|
onNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnBack = (): void => {
|
||||||
|
setSignozDetails({
|
||||||
|
hearAboutSignoz,
|
||||||
|
otherAboutSignoz,
|
||||||
|
interestedSignoz,
|
||||||
|
otherInterest,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: SigNoz Questions: Back', {
|
||||||
|
hearAboutSignoz,
|
||||||
|
otherAboutSignoz,
|
||||||
|
interestedSignoz,
|
||||||
|
otherInterest,
|
||||||
|
});
|
||||||
|
|
||||||
|
onBack();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="questions-container">
|
<div className="questions-container">
|
||||||
<Typography.Title level={3} className="title">
|
<Typography.Title level={3} className="title">
|
||||||
@ -46,78 +111,49 @@ export function AboutSigNozQuestions({
|
|||||||
<div className="questions-form">
|
<div className="questions-form">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<div className="question">Where did you hear about SigNoz?</div>
|
<div className="question">Where did you hear about SigNoz?</div>
|
||||||
<div className="tool-grid">
|
<div className="two-column-grid">
|
||||||
<button
|
{Object.keys(hearAboutSignozOptions).map((option: string) => (
|
||||||
type="button"
|
<Button
|
||||||
className={`tool-button ${hearAboutSignoz === 'Blog' ? 'active' : ''}`}
|
key={option}
|
||||||
onClick={(): void => setHearAboutSignoz('Blog')}
|
type="primary"
|
||||||
>
|
className={`onboarding-questionaire-button ${
|
||||||
Blog
|
hearAboutSignoz === option ? 'active' : ''
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
hearAboutSignoz === 'Hacker News' ? 'active' : ''
|
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setHearAboutSignoz('Hacker News')}
|
onClick={(): void => setHearAboutSignoz(option)}
|
||||||
>
|
>
|
||||||
Hacker News
|
{hearAboutSignozOptions[option]}
|
||||||
</button>
|
{hearAboutSignoz === option && (
|
||||||
<button
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
type="button"
|
)}
|
||||||
className={`tool-button ${
|
</Button>
|
||||||
hearAboutSignoz === 'LinkedIn' ? 'active' : ''
|
))}
|
||||||
}`}
|
|
||||||
onClick={(): void => setHearAboutSignoz('LinkedIn')}
|
|
||||||
>
|
|
||||||
LinkedIn
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
hearAboutSignoz === 'Twitter' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setHearAboutSignoz('Twitter')}
|
|
||||||
>
|
|
||||||
Twitter
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
hearAboutSignoz === 'Reddit' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setHearAboutSignoz('Reddit')}
|
|
||||||
>
|
|
||||||
Reddit
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
hearAboutSignoz === 'colleagues/friends' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setHearAboutSignoz('colleagues/friends')}
|
|
||||||
>
|
|
||||||
Colleagues / Friends
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{hearAboutSignoz === 'Others' ? (
|
{hearAboutSignoz === 'Others' ? (
|
||||||
<input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
className="tool-button input-field"
|
className="onboarding-questionaire-other-input"
|
||||||
placeholder="Please specify where you heard about SigNoz"
|
placeholder="Please specify your interest"
|
||||||
value={otherAboutSignoz}
|
value={otherAboutSignoz}
|
||||||
|
autoFocus
|
||||||
|
addonAfter={
|
||||||
|
otherAboutSignoz !== '' ? (
|
||||||
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
onChange={(e): void => setOtherAboutSignoz(e.target.value)}
|
onChange={(e): void => setOtherAboutSignoz(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="primary"
|
||||||
className={`tool-button ${
|
className={`onboarding-questionaire-button ${
|
||||||
hearAboutSignoz === 'Others' ? 'active' : ''
|
hearAboutSignoz === 'Others' ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setHearAboutSignoz('Others')}
|
onClick={(): void => setHearAboutSignoz('Others')}
|
||||||
>
|
>
|
||||||
Others
|
Others
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -126,62 +162,56 @@ export function AboutSigNozQuestions({
|
|||||||
<div className="question">
|
<div className="question">
|
||||||
What are you interested in doing with SigNoz?
|
What are you interested in doing with SigNoz?
|
||||||
</div>
|
</div>
|
||||||
<div className="grid">
|
<div className="two-column-grid">
|
||||||
<button
|
{Object.keys(interestedInOptions).map((option: string) => (
|
||||||
type="button"
|
<Button
|
||||||
className={`grid-button ${
|
key={option}
|
||||||
interestedSignoz === 'Saving costs' ? 'active' : ''
|
type="primary"
|
||||||
|
className={`onboarding-questionaire-button ${
|
||||||
|
interestedSignoz === option ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setInterestedSignoz('Saving costs')}
|
onClick={(): void => setInterestedSignoz(option)}
|
||||||
>
|
>
|
||||||
Saving costs
|
{interestedInOptions[option]}
|
||||||
</button>
|
{interestedSignoz === option && (
|
||||||
<button
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
type="button"
|
)}
|
||||||
className={`grid-button ${
|
</Button>
|
||||||
interestedSignoz === 'Interested in Otel-native stack' ? 'active' : ''
|
))}
|
||||||
}`}
|
|
||||||
onClick={(): void =>
|
|
||||||
setInterestedSignoz('Interested in Otel-native stack')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Interested in Otel-native stack
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`grid-button ${
|
|
||||||
interestedSignoz === 'All-in-one' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setInterestedSignoz('All-in-one')}
|
|
||||||
>
|
|
||||||
All-in-one
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{interestedSignoz === 'Others' ? (
|
{interestedSignoz === 'Others' ? (
|
||||||
<input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
className="tool-button input-field"
|
className="onboarding-questionaire-other-input"
|
||||||
placeholder="Please specify your interest"
|
placeholder="Please specify your interest"
|
||||||
value={otherInterest}
|
value={otherInterest}
|
||||||
|
autoFocus
|
||||||
|
addonAfter={
|
||||||
|
otherInterest !== '' ? (
|
||||||
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
onChange={(e): void => setOtherInterest(e.target.value)}
|
onChange={(e): void => setOtherInterest(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="primary"
|
||||||
className={`tool-button ${
|
className={`onboarding-questionaire-button ${
|
||||||
interestedSignoz === 'Others' ? 'active' : ''
|
interestedSignoz === 'Others' ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setInterestedSignoz('Others')}
|
onClick={(): void => setInterestedSignoz('Others')}
|
||||||
>
|
>
|
||||||
Others
|
Others
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="next-prev-container">
|
<div className="next-prev-container">
|
||||||
<Button type="default" className="next-button" onClick={onBack}>
|
<Button type="default" className="next-button" onClick={handleOnBack}>
|
||||||
<ArrowLeft size={14} />
|
<ArrowLeft size={14} />
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
@ -189,7 +219,7 @@ export function AboutSigNozQuestions({
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
className={`next-button ${isNextDisabled ? 'disabled' : ''}`}
|
className={`next-button ${isNextDisabled ? 'disabled' : ''}`}
|
||||||
onClick={onNext}
|
onClick={handleOnNext}
|
||||||
disabled={isNextDisabled}
|
disabled={isNextDisabled}
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button, Input, Select, Typography } from 'antd';
|
import { Button, Input, Select, Typography } from 'antd';
|
||||||
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
import {
|
||||||
|
ArrowLeft,
|
||||||
|
ArrowRight,
|
||||||
|
CheckCircle,
|
||||||
|
Plus,
|
||||||
|
TriangleAlert,
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
interface InviteTeamMembersProps {
|
interface InviteTeamMembersProps {
|
||||||
|
teamMembers: string[];
|
||||||
|
setTeamMembers: (teamMembers: string[]) => void;
|
||||||
onNext: () => void;
|
onNext: () => void;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
}
|
}
|
||||||
@ -15,9 +25,39 @@ const userRolesOptions = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
function InviteTeamMembers({
|
function InviteTeamMembers({
|
||||||
|
teamMembers,
|
||||||
|
setTeamMembers,
|
||||||
onNext,
|
onNext,
|
||||||
onBack,
|
onBack,
|
||||||
}: InviteTeamMembersProps): JSX.Element {
|
}: InviteTeamMembersProps): JSX.Element {
|
||||||
|
const [teamMembersToInvite, setTeamMembersToInvite] = useState<string[]>(
|
||||||
|
teamMembers || [''],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAddTeamMember = (): void => {
|
||||||
|
setTeamMembersToInvite([...teamMembersToInvite, '']);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = (): void => {
|
||||||
|
console.log(teamMembersToInvite);
|
||||||
|
setTeamMembers(teamMembersToInvite);
|
||||||
|
onNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnChange = (
|
||||||
|
e: React.ChangeEvent<HTMLInputElement>,
|
||||||
|
index: number,
|
||||||
|
): void => {
|
||||||
|
const newTeamMembers = [...teamMembersToInvite];
|
||||||
|
newTeamMembers[index] = e.target.value;
|
||||||
|
setTeamMembersToInvite(newTeamMembers);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isValidEmail = (email: string): boolean => {
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
return emailRegex.test(email);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="questions-container">
|
<div className="questions-container">
|
||||||
<Typography.Title level={3} className="title">
|
<Typography.Title level={3} className="title">
|
||||||
@ -39,20 +79,44 @@ function InviteTeamMembers({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="invite-team-members-container">
|
<div className="invite-team-members-container">
|
||||||
|
{teamMembersToInvite.map((member, index) => (
|
||||||
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
<div className="team-member-container" key={`${member}-${index}`}>
|
||||||
<Input
|
<Input
|
||||||
addonAfter={userRolesOptions}
|
addonBefore={userRolesOptions}
|
||||||
|
addonAfter={
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
member.length > 0 ? (
|
||||||
|
isValidEmail(member) ? (
|
||||||
|
<CheckCircle size={14} color={Color.BG_FOREST_500} />
|
||||||
|
) : (
|
||||||
|
<TriangleAlert size={14} color={Color.BG_SIENNA_500} />
|
||||||
|
)
|
||||||
|
) : null
|
||||||
|
}
|
||||||
placeholder="your-teammate@org.com"
|
placeholder="your-teammate@org.com"
|
||||||
|
value={member}
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
autoFocus
|
||||||
|
autoComplete="off"
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>): void =>
|
||||||
|
handleOnChange(e, index)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Input
|
<div className="invite-team-members-add-another-member-container">
|
||||||
addonAfter={userRolesOptions}
|
<Button
|
||||||
placeholder="your-teammate@org.com"
|
type="primary"
|
||||||
/>
|
className="add-another-member-button"
|
||||||
|
icon={<Plus size={14} />}
|
||||||
<Input
|
onClick={handleAddTeamMember}
|
||||||
addonAfter={userRolesOptions}
|
>
|
||||||
placeholder="your-teammate@org.com"
|
Member
|
||||||
/>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,7 +127,7 @@ function InviteTeamMembers({
|
|||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button type="primary" className="next-button" onClick={onNext}>
|
<Button type="primary" className="next-button" onClick={handleNext}>
|
||||||
Send Invites
|
Send Invites
|
||||||
<ArrowRight size={14} />
|
<ArrowRight size={14} />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -216,6 +216,7 @@
|
|||||||
transition: background-color 0.3s ease;
|
transition: background-color 0.3s ease;
|
||||||
min-width: 258px;
|
min-width: 258px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-button.active,
|
.radio-button.active,
|
||||||
@ -228,6 +229,61 @@
|
|||||||
background: rgba(78, 116, 248, 0.2);
|
background: rgba(78, 116, 248, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.two-column-grid {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr; /* Two equal columns */
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-questionaire-button,
|
||||||
|
.add-another-member-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid var(--Greyscale-Slate-400, #1d212d);
|
||||||
|
background: var(--Ink-300, #16181d);
|
||||||
|
color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3));
|
||||||
|
box-shadow: none;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid rgba(78, 116, 248, 0.4);
|
||||||
|
background: rgba(78, 116, 248, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border: 1px solid rgba(78, 116, 248, 0.4);
|
||||||
|
background: rgba(78, 116, 248, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-another-member-button {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-questionaire-other-input {
|
||||||
|
.ant-input-group {
|
||||||
|
.ant-input {
|
||||||
|
border-top-right-radius: 0px !important;
|
||||||
|
border-bottom-right-radius: 0px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tool-grid {
|
.tool-grid {
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
}
|
}
|
||||||
@ -275,4 +331,12 @@
|
|||||||
padding: 12px 24px;
|
padding: 12px 24px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.invite-team-members-add-another-member-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { Button, Slider, SliderSingleProps, Typography } from 'antd';
|
import { Button, Slider, SliderSingleProps, Typography } from 'antd';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
import { ArrowLeft, ArrowRight, Minus } from 'lucide-react';
|
import { ArrowLeft, ArrowRight, Minus } from 'lucide-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
interface OptimiseSignozNeedsProps {
|
interface OptimiseSignozNeedsProps {
|
||||||
|
optimiseSignozDetails: Record<string, number> | null;
|
||||||
|
setOptimiseSignozDetails: (details: Record<string, number> | null) => void;
|
||||||
onNext: () => void;
|
onNext: () => void;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
}
|
}
|
||||||
@ -32,9 +36,69 @@ const serviceMarks: SliderSingleProps['marks'] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function OptimiseSignozNeeds({
|
function OptimiseSignozNeeds({
|
||||||
|
optimiseSignozDetails,
|
||||||
|
setOptimiseSignozDetails,
|
||||||
onNext,
|
onNext,
|
||||||
onBack,
|
onBack,
|
||||||
}: OptimiseSignozNeedsProps): JSX.Element {
|
}: OptimiseSignozNeedsProps): JSX.Element {
|
||||||
|
const [logsPerDay, setLogsPerDay] = useState<number>(
|
||||||
|
optimiseSignozDetails?.logsPerDay || 25,
|
||||||
|
);
|
||||||
|
const [hostsPerDay, setHostsPerDay] = useState<number>(
|
||||||
|
optimiseSignozDetails?.hostsPerDay || 40,
|
||||||
|
);
|
||||||
|
const [services, setServices] = useState<number>(
|
||||||
|
optimiseSignozDetails?.services || 10,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOnNext = (): void => {
|
||||||
|
setOptimiseSignozDetails({
|
||||||
|
logsPerDay,
|
||||||
|
hostsPerDay,
|
||||||
|
services,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: Optimise SigNoz Needs: Next', {
|
||||||
|
logsPerDay,
|
||||||
|
hostsPerDay,
|
||||||
|
services,
|
||||||
|
});
|
||||||
|
|
||||||
|
onNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnBack = (): void => {
|
||||||
|
setOptimiseSignozDetails({
|
||||||
|
logsPerDay,
|
||||||
|
hostsPerDay,
|
||||||
|
services,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: Optimise SigNoz Needs: Back', {
|
||||||
|
logsPerDay,
|
||||||
|
hostsPerDay,
|
||||||
|
services,
|
||||||
|
});
|
||||||
|
|
||||||
|
onBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWillDoLater = (): void => {
|
||||||
|
setOptimiseSignozDetails({
|
||||||
|
logsPerDay: 0,
|
||||||
|
hostsPerDay: 0,
|
||||||
|
services: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: Optimise SigNoz Needs: Will do later', {
|
||||||
|
logsPerDay: 0,
|
||||||
|
hostsPerDay: 0,
|
||||||
|
services: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
onNext();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="questions-container">
|
<div className="questions-container">
|
||||||
<Typography.Title level={3} className="title">
|
<Typography.Title level={3} className="title">
|
||||||
@ -57,7 +121,8 @@ function OptimiseSignozNeeds({
|
|||||||
<div className="slider-container">
|
<div className="slider-container">
|
||||||
<Slider
|
<Slider
|
||||||
marks={logMarks}
|
marks={logMarks}
|
||||||
defaultValue={25}
|
defaultValue={logsPerDay}
|
||||||
|
onChange={(value): void => setLogsPerDay(value)}
|
||||||
styles={{
|
styles={{
|
||||||
track: {
|
track: {
|
||||||
background: '#4E74F8',
|
background: '#4E74F8',
|
||||||
@ -69,12 +134,13 @@ function OptimiseSignozNeeds({
|
|||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="question" htmlFor="organisationName">
|
<label className="question" htmlFor="organisationName">
|
||||||
Metrics <Minus size={14} /> Number of Hosts / Day
|
Metrics <Minus size={14} /> Number of Hosts
|
||||||
</label>
|
</label>
|
||||||
<div className="slider-container">
|
<div className="slider-container">
|
||||||
<Slider
|
<Slider
|
||||||
marks={hostMarks}
|
marks={hostMarks}
|
||||||
defaultValue={40}
|
defaultValue={hostsPerDay}
|
||||||
|
onChange={(value): void => setHostsPerDay(value)}
|
||||||
styles={{
|
styles={{
|
||||||
track: {
|
track: {
|
||||||
background: '#4E74F8',
|
background: '#4E74F8',
|
||||||
@ -91,7 +157,8 @@ function OptimiseSignozNeeds({
|
|||||||
<div className="slider-container">
|
<div className="slider-container">
|
||||||
<Slider
|
<Slider
|
||||||
marks={serviceMarks}
|
marks={serviceMarks}
|
||||||
defaultValue={10}
|
defaultValue={services}
|
||||||
|
onChange={(value): void => setServices(value)}
|
||||||
styles={{
|
styles={{
|
||||||
track: {
|
track: {
|
||||||
background: '#4E74F8',
|
background: '#4E74F8',
|
||||||
@ -103,19 +170,19 @@ function OptimiseSignozNeeds({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="next-prev-container">
|
<div className="next-prev-container">
|
||||||
<Button type="default" className="next-button" onClick={onBack}>
|
<Button type="default" className="next-button" onClick={handleOnBack}>
|
||||||
<ArrowLeft size={14} />
|
<ArrowLeft size={14} />
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button type="primary" className="next-button" onClick={onNext}>
|
<Button type="primary" className="next-button" onClick={handleOnNext}>
|
||||||
Next
|
Next
|
||||||
<ArrowRight size={14} />
|
<ArrowRight size={14} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="do-later-container">
|
<div className="do-later-container">
|
||||||
<Button type="link" onClick={onNext}>
|
<Button type="link" onClick={handleWillDoLater}>
|
||||||
I'll do this later
|
I'll do this later
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,27 +1,58 @@
|
|||||||
/* eslint-disable sonarjs/cognitive-complexity */
|
/* eslint-disable sonarjs/cognitive-complexity */
|
||||||
import '../OnboardingQuestionaire.styles.scss';
|
import '../OnboardingQuestionaire.styles.scss';
|
||||||
|
|
||||||
import { Button, Typography } from 'antd';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { ArrowRight } from 'lucide-react';
|
import { Button, Input, Typography } from 'antd';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
|
import { ArrowRight, CheckCircle } from 'lucide-react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
|
||||||
interface OrgQuestionsProps {
|
interface OrgQuestionsProps {
|
||||||
|
orgDetails: any;
|
||||||
|
setOrgDetails: (details: any) => void;
|
||||||
onNext: () => void;
|
onNext: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
const observabilityTools = [
|
||||||
const [organisationName, setOrganisationName] = useState<string>('');
|
'AWS Cloudwatch',
|
||||||
|
'DataDog',
|
||||||
|
'New Relic',
|
||||||
|
'Grafana / Prometheus',
|
||||||
|
'Azure App Monitor',
|
||||||
|
'GCP-native o11y tools',
|
||||||
|
'Honeycomb',
|
||||||
|
];
|
||||||
|
|
||||||
|
const o11yFamiliarityOptions: Record<string, string> = {
|
||||||
|
new: "I'm completely new",
|
||||||
|
builtStack: "I've built a stack before",
|
||||||
|
experienced: 'I have some experience',
|
||||||
|
dontKnow: "I don't know what it is",
|
||||||
|
};
|
||||||
|
|
||||||
|
function OrgQuestions({
|
||||||
|
orgDetails,
|
||||||
|
setOrgDetails,
|
||||||
|
onNext,
|
||||||
|
}: OrgQuestionsProps): JSX.Element {
|
||||||
|
const [organisationName, setOrganisationName] = useState<string>(
|
||||||
|
orgDetails?.organisationName || '',
|
||||||
|
);
|
||||||
const [usesObservability, setUsesObservability] = useState<boolean | null>(
|
const [usesObservability, setUsesObservability] = useState<boolean | null>(
|
||||||
null,
|
orgDetails?.usesObservability || null,
|
||||||
);
|
);
|
||||||
const [observabilityTool, setObservabilityTool] = useState<string | null>(
|
const [observabilityTool, setObservabilityTool] = useState<string | null>(
|
||||||
null,
|
orgDetails?.observabilityTool || null,
|
||||||
|
);
|
||||||
|
const [otherTool, setOtherTool] = useState<string>(
|
||||||
|
orgDetails?.otherTool || '',
|
||||||
|
);
|
||||||
|
const [familiarity, setFamiliarity] = useState<string | null>(
|
||||||
|
orgDetails?.familiarity || null,
|
||||||
);
|
);
|
||||||
const [otherTool, setOtherTool] = useState<string>('');
|
|
||||||
const [familiarity, setFamiliarity] = useState<string | null>(null);
|
|
||||||
const [isNextDisabled, setIsNextDisabled] = useState<boolean>(true);
|
const [isNextDisabled, setIsNextDisabled] = useState<boolean>(true);
|
||||||
|
|
||||||
const { user } = useSelector<AppState, AppReducer>((state) => state.app);
|
const { user } = useSelector<AppState, AppReducer>((state) => state.app);
|
||||||
@ -45,6 +76,26 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
otherTool,
|
otherTool,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const handleOnNext = (): void => {
|
||||||
|
setOrgDetails({
|
||||||
|
organisationName,
|
||||||
|
usesObservability,
|
||||||
|
observabilityTool,
|
||||||
|
otherTool,
|
||||||
|
familiarity,
|
||||||
|
});
|
||||||
|
|
||||||
|
logEvent('Onboarding: Org Questions: Next', {
|
||||||
|
organisationName,
|
||||||
|
usesObservability,
|
||||||
|
observabilityTool,
|
||||||
|
otherTool,
|
||||||
|
familiarity,
|
||||||
|
});
|
||||||
|
|
||||||
|
onNext();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="questions-container">
|
<div className="questions-container">
|
||||||
<Typography.Title level={3} className="title">
|
<Typography.Title level={3} className="title">
|
||||||
@ -77,20 +128,25 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
Do you currently use any observability/monitoring tool?
|
Do you currently use any observability/monitoring tool?
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div className="radio-group">
|
<div className="two-column-grid">
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="primary"
|
||||||
name="usesObservability"
|
name="usesObservability"
|
||||||
className={`radio-button ${usesObservability === true ? 'active' : ''}`}
|
className={`onboarding-questionaire-button ${
|
||||||
|
usesObservability === true ? 'active' : ''
|
||||||
|
}`}
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
setUsesObservability(true);
|
setUsesObservability(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Yes
|
Yes{' '}
|
||||||
</button>
|
{usesObservability === true && (
|
||||||
<button
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
type="button"
|
)}
|
||||||
className={`radio-button ${
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
className={`onboarding-questionaire-button ${
|
||||||
usesObservability === false ? 'active' : ''
|
usesObservability === false ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
@ -99,8 +155,11 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
setOtherTool('');
|
setOtherTool('');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
No
|
No{' '}
|
||||||
</button>
|
{usesObservability === false && (
|
||||||
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -109,83 +168,44 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
<label className="question" htmlFor="observabilityTool">
|
<label className="question" htmlFor="observabilityTool">
|
||||||
Which observability tool do you currently use?
|
Which observability tool do you currently use?
|
||||||
</label>
|
</label>
|
||||||
<div className="tool-grid">
|
<div className="two-column-grid">
|
||||||
<button
|
{observabilityTools.map((tool) => (
|
||||||
type="button"
|
<Button
|
||||||
className={`tool-button ${
|
key={tool}
|
||||||
observabilityTool === 'AWS Cloudwatch' ? 'active' : ''
|
type="primary"
|
||||||
|
className={`onboarding-questionaire-button ${
|
||||||
|
observabilityTool === tool ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setObservabilityTool('AWS Cloudwatch')}
|
onClick={(): void => setObservabilityTool(tool)}
|
||||||
>
|
>
|
||||||
AWS Cloudwatch
|
{tool}
|
||||||
</button>
|
|
||||||
<button
|
{observabilityTool === tool && (
|
||||||
type="button"
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
className={`tool-button ${
|
)}
|
||||||
observabilityTool === 'DataDog' ? 'active' : ''
|
</Button>
|
||||||
}`}
|
))}
|
||||||
onClick={(): void => setObservabilityTool('DataDog')}
|
|
||||||
>
|
|
||||||
DataDog
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
observabilityTool === 'New Relic' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setObservabilityTool('New Relic')}
|
|
||||||
>
|
|
||||||
New Relic
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
observabilityTool === 'Grafana / Prometheus' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setObservabilityTool('Grafana / Prometheus')}
|
|
||||||
>
|
|
||||||
Grafana / Prometheus
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
observabilityTool === 'Azure App Monitor' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setObservabilityTool('Azure App Monitor')}
|
|
||||||
>
|
|
||||||
Azure App Monitor
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
observabilityTool === 'GCP-native o11y tools' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setObservabilityTool('GCP-native o11y tools')}
|
|
||||||
>
|
|
||||||
GCP-native o11y tools
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`tool-button ${
|
|
||||||
observabilityTool === 'Honeycomb' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
onClick={(): void => setObservabilityTool('Honeycomb')}
|
|
||||||
>
|
|
||||||
Honeycomb
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{observabilityTool === 'Others' ? (
|
{observabilityTool === 'Others' ? (
|
||||||
<input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
className="tool-button input-field"
|
className="onboarding-questionaire-other-input"
|
||||||
placeholder="Please specify the tool"
|
placeholder="Please specify the tool"
|
||||||
value={otherTool}
|
value={otherTool}
|
||||||
|
autoFocus
|
||||||
|
addonAfter={
|
||||||
|
otherTool !== '' ? (
|
||||||
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)
|
||||||
|
}
|
||||||
onChange={(e): void => setOtherTool(e.target.value)}
|
onChange={(e): void => setOtherTool(e.target.value)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`tool-button ${
|
className={`onboarding-questionaire-button ${
|
||||||
observabilityTool === 'Others' ? 'active' : ''
|
observabilityTool === 'Others' ? 'active' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setObservabilityTool('Others')}
|
onClick={(): void => setObservabilityTool('Others')}
|
||||||
@ -201,39 +221,22 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
<div className="question">
|
<div className="question">
|
||||||
Are you familiar with observability (o11y)?
|
Are you familiar with observability (o11y)?
|
||||||
</div>
|
</div>
|
||||||
<div className="grid">
|
<div className="two-column-grid">
|
||||||
<button
|
{Object.keys(o11yFamiliarityOptions).map((option: string) => (
|
||||||
type="button"
|
<Button
|
||||||
className={`grid-button ${familiarity === 'new' ? 'active' : ''}`}
|
key={option}
|
||||||
onClick={(): void => setFamiliarity('new')}
|
type="primary"
|
||||||
>
|
className={`onboarding-questionaire-button ${
|
||||||
I'm completely new
|
familiarity === option ? 'active' : ''
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`grid-button ${
|
|
||||||
familiarity === 'built-stack' ? 'active' : ''
|
|
||||||
}`}
|
}`}
|
||||||
onClick={(): void => setFamiliarity('built-stack')}
|
onClick={(): void => setFamiliarity(option)}
|
||||||
>
|
>
|
||||||
I've built a stack before
|
{o11yFamiliarityOptions[option]}
|
||||||
</button>
|
{familiarity === option && (
|
||||||
<button
|
<CheckCircle size={12} color={Color.BG_FOREST_500} />
|
||||||
type="button"
|
)}
|
||||||
className={`grid-button ${
|
</Button>
|
||||||
familiarity === 'experienced' ? 'active' : ''
|
))}
|
||||||
}`}
|
|
||||||
onClick={(): void => setFamiliarity('experienced')}
|
|
||||||
>
|
|
||||||
I have some experience
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`grid-button ${familiarity === 'dont-know' ? 'active' : ''}`}
|
|
||||||
onClick={(): void => setFamiliarity('dont-know')}
|
|
||||||
>
|
|
||||||
I don't know what it is
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -242,7 +245,7 @@ function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
className={`next-button ${isNextDisabled ? 'disabled' : ''}`}
|
className={`next-button ${isNextDisabled ? 'disabled' : ''}`}
|
||||||
onClick={onNext}
|
onClick={handleOnNext}
|
||||||
disabled={isNextDisabled}
|
disabled={isNextDisabled}
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
|
@ -12,6 +12,20 @@ import OrgQuestions from './OrgQuestions/OrgQuestions';
|
|||||||
function OnboardingQuestionaire(): JSX.Element {
|
function OnboardingQuestionaire(): JSX.Element {
|
||||||
const [currentStep, setCurrentStep] = useState<number>(1);
|
const [currentStep, setCurrentStep] = useState<number>(1);
|
||||||
|
|
||||||
|
const [orgDetails, setOrgDetails] = useState<Record<string, string> | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
const [signozDetails, setSignozDetails] = useState<Record<
|
||||||
|
string,
|
||||||
|
string
|
||||||
|
> | null>(null);
|
||||||
|
const [optimiseSignozDetails, setOptimiseSignozDetails] = useState<Record<
|
||||||
|
string,
|
||||||
|
number
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
|
const [teamMembers, setTeamMembers] = useState<string[]>(['']);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="onboarding-questionaire-container">
|
<div className="onboarding-questionaire-container">
|
||||||
<div className="onboarding-questionaire-header">
|
<div className="onboarding-questionaire-header">
|
||||||
@ -20,11 +34,17 @@ function OnboardingQuestionaire(): JSX.Element {
|
|||||||
|
|
||||||
<div className="onboarding-questionaire-content">
|
<div className="onboarding-questionaire-content">
|
||||||
{currentStep === 1 && (
|
{currentStep === 1 && (
|
||||||
<OrgQuestions onNext={(): void => setCurrentStep(2)} />
|
<OrgQuestions
|
||||||
|
orgDetails={orgDetails}
|
||||||
|
setOrgDetails={setOrgDetails}
|
||||||
|
onNext={(): void => setCurrentStep(2)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{currentStep === 2 && (
|
{currentStep === 2 && (
|
||||||
<AboutSigNozQuestions
|
<AboutSigNozQuestions
|
||||||
|
signozDetails={signozDetails}
|
||||||
|
setSignozDetails={setSignozDetails}
|
||||||
onBack={(): void => setCurrentStep(1)}
|
onBack={(): void => setCurrentStep(1)}
|
||||||
onNext={(): void => setCurrentStep(3)}
|
onNext={(): void => setCurrentStep(3)}
|
||||||
/>
|
/>
|
||||||
@ -32,6 +52,8 @@ function OnboardingQuestionaire(): JSX.Element {
|
|||||||
|
|
||||||
{currentStep === 3 && (
|
{currentStep === 3 && (
|
||||||
<OptimiseSignozNeeds
|
<OptimiseSignozNeeds
|
||||||
|
optimiseSignozDetails={optimiseSignozDetails}
|
||||||
|
setOptimiseSignozDetails={setOptimiseSignozDetails}
|
||||||
onBack={(): void => setCurrentStep(2)}
|
onBack={(): void => setCurrentStep(2)}
|
||||||
onNext={(): void => setCurrentStep(4)}
|
onNext={(): void => setCurrentStep(4)}
|
||||||
/>
|
/>
|
||||||
@ -39,6 +61,8 @@ function OnboardingQuestionaire(): JSX.Element {
|
|||||||
|
|
||||||
{currentStep === 4 && (
|
{currentStep === 4 && (
|
||||||
<InviteTeamMembers
|
<InviteTeamMembers
|
||||||
|
teamMembers={teamMembers}
|
||||||
|
setTeamMembers={setTeamMembers}
|
||||||
onBack={(): void => setCurrentStep(3)}
|
onBack={(): void => setCurrentStep(3)}
|
||||||
onNext={(): void => setCurrentStep(5)}
|
onNext={(): void => setCurrentStep(5)}
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user