diff --git a/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.spec.tsx b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.spec.tsx new file mode 100644 index 0000000000..ea0ea30c62 --- /dev/null +++ b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.spec.tsx @@ -0,0 +1,21 @@ +import ReactDOM from 'react-dom'; + +import LoaderPage from './LoaderPage'; + +const subtitles = [ + 'Bringing rocket to launch position', + 'Loading rocket propellant', + 'Performing final go/no go poll with flight crew', + 'All systems nominal, switching to internal computer', + 'Beginning countdown, 5...4...3...2...1', + 'Transitioning to liftoff', +]; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render( + , + div + ); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.stories.tsx b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.stories.tsx new file mode 100644 index 0000000000..e1262d4b1b --- /dev/null +++ b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.stories.tsx @@ -0,0 +1,33 @@ +import type { Story, Meta } from '@storybook/react'; +import type { ComponentProps } from 'react'; + +import LoaderPage from './LoaderPage'; + +const subtitles = [ + 'Bringing rocket to launch position1 🚀', + 'Loading rocket propellant 🚀', + 'Performing final go/no go poll with flight crew 🚀', + 'All systems nominal, switching to internal computer 🚀', + 'Beginning countdown, 5...4...3...2...1 🚀', + 'Transitioning to liftoff 🚀', +]; + +type Args = ComponentProps; + +export default { + title: 'pages/LoaderPage', + component: LoaderPage, + parameters: { + actions: { argTypesRegex: '^on.*' }, + layout: 'fullscreen', + }, + args: { + title: 'Launching Kapai...', + subtitles, + isReady: false, + loadingSeconds: 15, + }, +} as Meta; + +export const _LoaderPage: Story = (args) => ; +_LoaderPage.storyName = 'LoaderPage'; diff --git a/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.tsx b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.tsx new file mode 100644 index 0000000000..22f9999270 --- /dev/null +++ b/packages/onboarding-ui/src/pages/LoaderPage/LoaderPage.tsx @@ -0,0 +1,70 @@ +import { Box, Margins, ProgressBar } from '@rocket.chat/fuselage'; +import type { ReactElement } from 'react'; +import { useEffect, useState } from 'react'; + +import BackgroundLayer from '../../common/BackgroundLayer'; +import { OnboardingLogo } from '../../common/OnboardingLogo'; + +type LoaderPageProps = { + title: string; + subtitles: string[]; + isReady: boolean; + loadingSeconds?: number; +}; + +const LoaderPage = ({ + title, + subtitles, + isReady = false, + loadingSeconds = 90, +}: LoaderPageProps): ReactElement => { + const timeFraction = 100 / subtitles.length; + + const [percentage, setPercentage] = useState(0); + const [subtitleIndex, setSubtitleIndex] = useState(0); + + const progressHandler = () => { + const interval = (loadingSeconds * 1000) / 100; + setInterval(() => { + setPercentage((prev) => (prev === 99 ? 99 : prev + 1)); + }, interval); + }; + + useEffect(() => { + if (isReady) setPercentage(100); + else progressHandler(); + }, [isReady]); + + useEffect(() => { + // Change subtitle according to percentage + const index = Math.floor(percentage / timeFraction); + if (index !== subtitleIndex) setSubtitleIndex(index); + }, [percentage]); + + return ( + + + + + + {title} + + {subtitles[subtitleIndex]} + + + + + + ); +}; + +export default LoaderPage; diff --git a/packages/onboarding-ui/src/pages/LoaderPage/index.ts b/packages/onboarding-ui/src/pages/LoaderPage/index.ts new file mode 100644 index 0000000000..7445f87f72 --- /dev/null +++ b/packages/onboarding-ui/src/pages/LoaderPage/index.ts @@ -0,0 +1 @@ +export { default } from './LoaderPage';