diff --git a/frontend/public/Logos/hippa.svg b/frontend/public/Logos/hippa.svg new file mode 100644 index 0000000000..2a1b74b818 --- /dev/null +++ b/frontend/public/Logos/hippa.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/Logos/signoz-brand-logo-new.svg b/frontend/public/Logos/signoz-brand-logo-new.svg new file mode 100644 index 0000000000..f57d3c5def --- /dev/null +++ b/frontend/public/Logos/signoz-brand-logo-new.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/Logos/soc2.svg b/frontend/public/Logos/soc2.svg new file mode 100644 index 0000000000..234321c95c --- /dev/null +++ b/frontend/public/Logos/soc2.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/fonts/Satoshi-Regular.woff2 b/frontend/public/fonts/Satoshi-Regular.woff2 new file mode 100644 index 0000000000..81c40ab08a Binary files /dev/null and b/frontend/public/fonts/Satoshi-Regular.woff2 differ diff --git a/frontend/src/container/AppLayout/AppLayout.styles.scss b/frontend/src/container/AppLayout/AppLayout.styles.scss index 2ae1531c79..f939583e5f 100644 --- a/frontend/src/container/AppLayout/AppLayout.styles.scss +++ b/frontend/src/container/AppLayout/AppLayout.styles.scss @@ -7,6 +7,8 @@ width: calc(100% - 64px); z-index: 0; + margin: 0 auto; + .content-container { position: relative; margin: 0 1rem; diff --git a/frontend/src/container/OnboardingQuestionaire/AboutSigNozQuestions/AboutSigNozQuestions.tsx b/frontend/src/container/OnboardingQuestionaire/AboutSigNozQuestions/AboutSigNozQuestions.tsx new file mode 100644 index 0000000000..09ca867e5f --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/AboutSigNozQuestions/AboutSigNozQuestions.tsx @@ -0,0 +1,202 @@ +/* eslint-disable sonarjs/cognitive-complexity */ +import '../OnboardingQuestionaire.styles.scss'; + +import { Button, Typography } from 'antd'; +import { ArrowLeft, ArrowRight } from 'lucide-react'; +import { useEffect, useState } from 'react'; + +interface AboutSigNozQuestionsProps { + onNext: () => void; + onBack: () => void; +} + +export function AboutSigNozQuestions({ + onNext, + onBack, +}: AboutSigNozQuestionsProps): JSX.Element { + const [hearAboutSignoz, setHearAboutSignoz] = useState(null); + const [otherAboutSignoz, setOtherAboutSignoz] = useState(''); + const [interestedSignoz, setInterestedSignoz] = useState(null); + const [otherInterest, setOtherInterest] = useState(''); + const [isNextDisabled, setIsNextDisabled] = useState(true); + + useEffect((): void => { + if ( + hearAboutSignoz !== null && + (hearAboutSignoz !== 'Others' || otherAboutSignoz !== '') && + interestedSignoz !== null && + (interestedSignoz !== 'Others' || otherInterest !== '') + ) { + setIsNextDisabled(false); + } else { + setIsNextDisabled(true); + } + }, [hearAboutSignoz, otherAboutSignoz, interestedSignoz, otherInterest]); + + return ( +
+ + Tell Us About Your Interest in SigNoz + + + We'd love to know a little bit about you and your interest in SigNoz + + +
+
+
+
Where did you hear about SigNoz?
+
+ + + + + + + + {hearAboutSignoz === 'Others' ? ( + setOtherAboutSignoz(e.target.value)} + /> + ) : ( + + )} +
+
+ +
+
+ What are you interested in doing with SigNoz? +
+
+ + + + + {interestedSignoz === 'Others' ? ( + setOtherInterest(e.target.value)} + /> + ) : ( + + )} +
+
+
+ +
+ + + +
+
+
+ ); +} diff --git a/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx b/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx new file mode 100644 index 0000000000..e531e586a6 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx @@ -0,0 +1,82 @@ +import { Button, Input, Select, Typography } from 'antd'; +import { ArrowLeft, ArrowRight } from 'lucide-react'; + +interface InviteTeamMembersProps { + onNext: () => void; + onBack: () => void; +} + +const userRolesOptions = ( + +); + +function InviteTeamMembers({ + onNext, + onBack, +}: InviteTeamMembersProps): JSX.Element { + return ( +
+ + Observability made collaborative + + + The more your team uses SigNoz, the stronger your observability. Share + dashboards, collaborate on alerts, and troubleshoot faster together. + + +
+
+
+
+ Collaborate with your team +
+ Invite your team to the SigNoz workspace +
+
+ +
+ + + + + +
+
+
+ +
+ + + +
+ +
+ +
+
+
+ ); +} + +export default InviteTeamMembers; diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.styles.scss b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.styles.scss new file mode 100644 index 0000000000..beddf2441e --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.styles.scss @@ -0,0 +1,46 @@ +.footer-main-container { + display: flex; + justify-content: center; + box-sizing: border-box; +} + +.footer-container { + display: inline-flex; + height: 36px; + padding: 12px; + justify-content: center; + align-items: center; + gap: 32px; + flex-shrink: 0; + border-radius: 4px; + border: 1px solid var(--Greyscale-Slate-500, #161922); + background: var(--Ink-400, #121317); +} + +.footer-container .footer-content { + display: flex; + align-items: center; + gap: 10px; +} + +.footer-container .footer-link { + display: flex; + align-items: center; + gap: 6px; + color: #c0c1c3; +} + +.footer-container .footer-text { + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: 0.2px; +} + +.footer-container .footer-dot { + width: 4px; + height: 4px; + fill: var(--Greyscale-Slate-200, #2c3140); +} diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.tsx b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.tsx new file mode 100644 index 0000000000..25482e2436 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.tsx @@ -0,0 +1,55 @@ +import './OnboardingFooter.styles.scss'; + +import { ArrowUpRight, Dot } from 'lucide-react'; + +export function OnboardingFooter(): JSX.Element { + return ( +
+ +
+ ); +} diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/index.ts b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/index.ts new file mode 100644 index 0000000000..cc029cb359 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingFooter/index.ts @@ -0,0 +1 @@ +export { OnboardingFooter } from './OnboardingFooter'; diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.styles.scss b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.styles.scss new file mode 100644 index 0000000000..0b2cecaac6 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.styles.scss @@ -0,0 +1,58 @@ +.header-container { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0px; + + box-sizing: border-box; +} + +.header-container .logo-container { + display: flex; + align-items: center; + gap: 10px; +} + +.header-container .logo-container img { + height: 17.5px; + width: 17.5px; +} + +.header-container .logo-text { + font-family: 'Satoshi', sans-serif; + color: #fff; + font-size: 15.4px; + font-style: normal; + font-weight: 500; + line-height: 17.5px; +} + +.header-container .get-help-container { + display: flex; + width: 113px; + height: 32px; + padding: 6px; + justify-content: center; + align-items: center; + gap: 6px; + flex-shrink: 0; + border-radius: 2px; + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + background: var(--Ink-300, #16181d); +} + +.header-container .get-help-container img { + width: 12px; + height: 12px; + flex-shrink: 0; +} + +.header-container .get-help-text { + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 10px; + letter-spacing: 0.12px; +} diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.tsx b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.tsx new file mode 100644 index 0000000000..76801d7620 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.tsx @@ -0,0 +1,19 @@ +import './OnboardingHeader.styles.scss'; + +import { Color } from '@signozhq/design-tokens'; +import { LifeBuoy } from 'lucide-react'; + +export function OnboardingHeader(): JSX.Element { + return ( +
+
+ SigNoz + SigNoz +
+
+ + Get Help +
+
+ ); +} diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/index.ts b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/index.ts new file mode 100644 index 0000000000..644a6d9b84 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingHeader/index.ts @@ -0,0 +1 @@ +export { OnboardingHeader } from './OnboardingHeader'; diff --git a/frontend/src/container/OnboardingQuestionaire/OnboardingQuestionaire.styles.scss b/frontend/src/container/OnboardingQuestionaire/OnboardingQuestionaire.styles.scss new file mode 100644 index 0000000000..df07b47f27 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OnboardingQuestionaire.styles.scss @@ -0,0 +1,278 @@ +.onboarding-questionaire-container { + width: 100%; + display: flex; + margin: 0 auto; + align-items: center; + flex-direction: column; + height: 100vh; + max-width: 1176px; + + .onboarding-questionaire-header { + width: 100%; + display: flex; + justify-content: center; + align-items: center; + + height: 56px; + } + + .onboarding-questionaire-content { + height: calc(100vh - 56px - 60px); + width: 100%; + display: flex; + flex-direction: column; + overflow-y: auto; + + .questions-container { + color: var(--Vanilla-100, #fff); + font-family: Inter; + font-size: 24px; + font-style: normal; + font-weight: 600; + line-height: 32px; + max-width: 600px; + margin: 0 auto; + border-radius: 8px; + max-height: 100%; + } + + .title { + color: var(--Vanilla-100, #fff) !important; + font-size: 24px !important; + line-height: 32px !important; + margin-bottom: 8px !important; + } + + .sub-title { + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)) !important; + font-size: 14px !important; + font-style: normal; + font-weight: 400 !important; + line-height: 24px !important; + margin-top: 0px !important; + margin-bottom: 24px !important; + } + + .questions-form-container { + max-width: 600px; + width: 600px; + margin: 0 auto; + } + + .questions-form { + width: 100%; + display: flex; + min-height: 420px; + padding: 20px 24px 24px 24px; + flex-direction: column; + align-items: center; + gap: 24px; + border-radius: 4px; + border: 1px solid var(--Greyscale-Slate-500, #161922); + background: var(--Ink-400, #121317); + + .ant-form-item { + margin-bottom: 0px !important; + + .ant-form-item-label { + label { + color: var(--Vanilla-100, #fff) !important; + font-size: 13px !important; + font-weight: 500; + line-height: 20px; + } + } + } + } + + .invite-team-members-container { + display: flex; + width: 100%; + flex-direction: column; + gap: 12px; + + .ant-input-group { + width: 100%; + + .ant-input { + font-size: 12px; + + height: 32px; + background: var(--Ink-300, #16181d); + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + } + + .ant-input-group-addon { + font-size: 11px; + height: 32px; + min-width: 80px; + background: var(--Ink-300, #16181d); + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + border-left: 0px; + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + } + } + } + + .question-label { + color: var(--Vanilla-100, #fff); + font-size: 13px; + font-style: normal; + font-weight: 500; + line-height: 20px; + } + + .question-sub-label { + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + font-size: 11px; + font-style: normal; + font-weight: 400; + line-height: 16px; + } + + .next-prev-container { + display: flex; + justify-content: space-between; + align-items: center; + gap: 10px; + margin-bottom: 24px; + + .ant-btn { + flex: 1; + } + } + + .form-group { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; + } + + .slider-container { + width: 100%; + + .ant-slider .ant-slider-mark { + font-size: 10px; + } + } + + .do-later-container { + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-top: 24px; + } + + .question { + color: var(--Vanilla-100, #fff); + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 20px; + } + + input[type='text'] { + width: 100%; + padding: 12px; + border-radius: 2px; + font-size: 14px; + height: 40px; + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + background: var(--Ink-300, #16181d); + color: #fff; + + &:focus-visible { + outline: none; + } + } + + .radio-group, + .grid, + .tool-grid { + display: flex; + align-items: flex-start; + align-content: flex-start; + gap: 10px; + align-self: stretch; + flex-wrap: wrap; + } + + .radio-button, + .grid-button, + .tool-button { + border-radius: 4px; + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + background: var(--Ink-300, #16181d); + padding: 12px; + color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3)); + font-size: 14px; + font-style: normal; + text-align: left; + font-weight: 400; + transition: background-color 0.3s ease; + min-width: 258px; + cursor: pointer; + } + + .radio-button.active, + .grid-button.active, + .tool-button.active, + .radio-button:hover, + .grid-button:hover, + .tool-button:hover { + border: 1px solid rgba(78, 116, 248, 0.4); + background: rgba(78, 116, 248, 0.2); + } + + .tool-grid { + grid-template-columns: repeat(4, 1fr); + } + + .input-field { + flex: 0; + padding: 12px; + border: 1px solid var(--Greyscale-Slate-400, #1d212d); + background: var(--Ink-300, #16181d); + color: #fff; + border-radius: 4px; + font-size: 14px; + min-width: 258px; + } + + .next-button { + display: flex; + height: 40px; + padding: 8px 12px 8px 16px; + justify-content: center; + align-items: center; + gap: 6px; + align-self: stretch; + border: 0px; + border-radius: 50px; + margin-top: 24px; + cursor: pointer; + } + + .next-button.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; + } + + .arrow { + font-size: 18px; + color: #fff; + } + } + + .onboarding-questionaire-footer { + width: 100%; + height: 60px; + padding: 12px 24px; + box-sizing: border-box; + } +} diff --git a/frontend/src/container/OnboardingQuestionaire/OptimiseSignozNeeds/OptimiseSignozNeeds.tsx b/frontend/src/container/OnboardingQuestionaire/OptimiseSignozNeeds/OptimiseSignozNeeds.tsx new file mode 100644 index 0000000000..52f45ca0b5 --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OptimiseSignozNeeds/OptimiseSignozNeeds.tsx @@ -0,0 +1,127 @@ +import { Button, Slider, SliderSingleProps, Typography } from 'antd'; +import { ArrowLeft, ArrowRight, Minus } from 'lucide-react'; + +interface OptimiseSignozNeedsProps { + onNext: () => void; + onBack: () => void; +} + +const logMarks: SliderSingleProps['marks'] = { + 0: '2 GB', + 25: '25 GB', + 50: '50 GB', + 100: '100 GB', +}; + +const hostMarks: SliderSingleProps['marks'] = { + 0: '0', + 20: '20', + 40: '40', + 60: '60', + 80: '80', + 100: '100', +}; + +const serviceMarks: SliderSingleProps['marks'] = { + 0: '0', + 20: '20', + 40: '40', + 60: '60', + 80: '80', + 100: '100', +}; + +function OptimiseSignozNeeds({ + onNext, + onBack, +}: OptimiseSignozNeedsProps): JSX.Element { + return ( +
+ + Optimize SigNoz for Your Needs + + + Give us a quick sense of your scale so SigNoz can keep up! + + +
+
+ + What does your scale approximately look like? + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ + + +
+ +
+ +
+
+
+ ); +} + +export default OptimiseSignozNeeds; diff --git a/frontend/src/container/OnboardingQuestionaire/OrgQuestions/OrgQuestions.styles.scss b/frontend/src/container/OnboardingQuestionaire/OrgQuestions/OrgQuestions.styles.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/container/OnboardingQuestionaire/OrgQuestions/OrgQuestions.tsx b/frontend/src/container/OnboardingQuestionaire/OrgQuestions/OrgQuestions.tsx new file mode 100644 index 0000000000..9988c9e97c --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/OrgQuestions/OrgQuestions.tsx @@ -0,0 +1,257 @@ +/* eslint-disable sonarjs/cognitive-complexity */ +import '../OnboardingQuestionaire.styles.scss'; + +import { Button, Typography } from 'antd'; +import { ArrowRight } from 'lucide-react'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import { AppState } from 'store/reducers'; +import AppReducer from 'types/reducer/app'; + +interface OrgQuestionsProps { + onNext: () => void; +} + +function OrgQuestions({ onNext }: OrgQuestionsProps): JSX.Element { + const [organisationName, setOrganisationName] = useState(''); + const [usesObservability, setUsesObservability] = useState( + null, + ); + const [observabilityTool, setObservabilityTool] = useState( + null, + ); + const [otherTool, setOtherTool] = useState(''); + const [familiarity, setFamiliarity] = useState(null); + const [isNextDisabled, setIsNextDisabled] = useState(true); + + const { user } = useSelector((state) => state.app); + + useEffect(() => { + if ( + organisationName !== '' && + usesObservability !== null && + familiarity !== null && + (observabilityTool !== 'Others' || (usesObservability && otherTool !== '')) + ) { + setIsNextDisabled(false); + } else { + setIsNextDisabled(true); + } + }, [ + organisationName, + usesObservability, + familiarity, + observabilityTool, + otherTool, + ]); + + return ( +
+ + Welcome, {user?.name}! + + + We'll help you get the most out of SigNoz, whether you're new to + observability or a seasoned pro. + + +
+
+
+ + setOrganisationName(e.target.value)} + /> +
+ +
+ + +
+ + +
+
+ + {usesObservability && ( +
+ +
+ + + + + + + + + {observabilityTool === 'Others' ? ( + setOtherTool(e.target.value)} + /> + ) : ( + + )} +
+
+ )} + +
+
+ Are you familiar with observability (o11y)? +
+
+ + + + +
+
+
+ +
+ +
+
+
+ ); +} + +export default OrgQuestions; diff --git a/frontend/src/container/OnboardingQuestionaire/index.tsx b/frontend/src/container/OnboardingQuestionaire/index.tsx new file mode 100644 index 0000000000..719da996fc --- /dev/null +++ b/frontend/src/container/OnboardingQuestionaire/index.tsx @@ -0,0 +1,55 @@ +import './OnboardingQuestionaire.styles.scss'; + +import { useState } from 'react'; + +import { AboutSigNozQuestions } from './AboutSigNozQuestions/AboutSigNozQuestions'; +import InviteTeamMembers from './InviteTeamMembers/InviteTeamMembers'; +import { OnboardingFooter } from './OnboardingFooter/OnboardingFooter'; +import { OnboardingHeader } from './OnboardingHeader/OnboardingHeader'; +import OptimiseSignozNeeds from './OptimiseSignozNeeds/OptimiseSignozNeeds'; +import OrgQuestions from './OrgQuestions/OrgQuestions'; + +function OnboardingQuestionaire(): JSX.Element { + const [currentStep, setCurrentStep] = useState(1); + + return ( +
+
+ +
+ +
+ {currentStep === 1 && ( + setCurrentStep(2)} /> + )} + + {currentStep === 2 && ( + setCurrentStep(1)} + onNext={(): void => setCurrentStep(3)} + /> + )} + + {currentStep === 3 && ( + setCurrentStep(2)} + onNext={(): void => setCurrentStep(4)} + /> + )} + + {currentStep === 4 && ( + setCurrentStep(3)} + onNext={(): void => setCurrentStep(5)} + /> + )} +
+ +
+ +
+
+ ); +} + +export default OnboardingQuestionaire; diff --git a/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx b/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx index ccdc0226f8..7100894a41 100644 --- a/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx +++ b/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx @@ -1,9 +1,9 @@ -import { Typography } from 'antd'; +import OnboardingQuestionaire from 'container/OnboardingQuestionaire'; function OnboardingPageV2(): JSX.Element { return (
- Onboarding V2 +
); }